From 75f6b8b417fe8caf9b42b53c918b89f7d756f1f2 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Thu, 16 Jul 2026 10:41:39 +0100 Subject: [PATCH 01/99] Move... --- .gitignore | 11 +- .gitmodules | 2 +- README.md | 4 +- build.gradle | 333 ++++- buildSrc/build.gradle | 2 - .../gradle/helpers/ProjectConstants.groovy | 6 - .../helpers/tasks/BytecodeFinder.groovy | 61 - .../tasks/CheckAccessTransformers.groovy | 231 ---- .../gradle/helpers/tasks/CheckExcs.groovy | 95 -- .../gradle/helpers/tasks/CheckPatches.groovy | 218 ---- .../gradle/helpers/tasks/CheckSAS.groovy | 64 - .../gradle/helpers/tasks/ClosureHelper.groovy | 31 - .../helpers/tasks/CreateMMCPackTask.groovy | 138 --- .../gradle/helpers/tasks/CrowdinTask.groovy | 65 - .../tasks/DownloadLibrariesTask.groovy | 43 - .../helpers/tasks/FieldCompareFinder.groovy | 108 -- .../helpers/tasks/GenVersionTask.groovy | 2 +- .../gradle/helpers/tasks/ObjectTarget.groovy | 31 - .../gradle/helpers/tasks/Util.groovy | 212 +--- gradle.properties | 21 +- mmcpack-template/.packignore | 1 - mmcpack-template/cleanroom.png | Bin 47513 -> 0 bytes mmcpack-template/instance.cfg | 17 - mmcpack-template/mmc-pack.json | 38 - mmcpack-template/patches/net.minecraft.json | 259 ---- .../patches/net.minecraftforge.json | 17 - mmcpack-template/patches/org.lwjgl3.json | 10 - .../main/java/com/cleanroommc/boot/Main.java | 0 .../java/com/cleanroommc/boot/MainClient.java | 0 .../java/com/cleanroommc/boot/MainServer.java | 0 .../cleanroommc/client/ICU4JInstances.java | 0 .../com/cleanroommc/client/IMEHandler.java | 0 .../cleanroommc/client/LoadingTracker.java | 0 .../client/ime/DummyIMEHandler.java | 0 .../client/ime/WaylandIMEhandler.java | 0 .../client/ime/WindowsIMEHandler.java | 0 .../cleanroommc/client/ime/X11IMEHandler.java | 0 .../cleanroommc/client/windows/DwmApi.java | 0 .../com/cleanroommc/client/windows/NtDll.java | 0 .../client/windows/TaskbarApi.java | 0 .../client/windows/WindowsProperties.java | 0 .../client/windows/WindowsTheme.java | 0 .../common/CleanroomContainer.java | 0 .../common/ConfigAnytimeContainer.java | 0 .../cleanroommc/common/MixinContainer.java | 0 .../common/PatchModPresentChecker.java | 0 .../configanytime/ConfigAnytime.java | 0 .../com/cleanroommc/hackery/Reflection.java | 0 .../hackery/ReflectionHackery.java | 0 .../hackery/enums/EnumHackery.java | 0 .../loader/LanguageAdapterRegistry.java | 0 .../cleanroommc/loader/javafix/UUIDFix.java | 0 .../CleanroomScriptEngineManager.java | 0 .../cleanroommc/hackery/EnumHackeryTest.java | 0 .../forge/src}/main/java/ibxm/Channel.java | 0 .../forge/src}/main/java/ibxm/Envelope.java | 0 .../src}/main/java/ibxm/FastTracker2.java | 0 .../forge/src}/main/java/ibxm/IBXM.java | 0 .../forge/src}/main/java/ibxm/Instrument.java | 0 .../forge/src}/main/java/ibxm/LogTable.java | 0 .../forge/src}/main/java/ibxm/Module.java | 0 .../forge/src}/main/java/ibxm/Pattern.java | 0 .../forge/src}/main/java/ibxm/Player.java | 0 .../forge/src}/main/java/ibxm/ProTracker.java | 0 .../forge/src}/main/java/ibxm/Sample.java | 0 .../src}/main/java/ibxm/ScreamTracker3.java | 0 .../critereon/ItemPredicates.java | 0 .../critereon/OredictItemPredicate.java | 0 .../classloading/FMLForgePlugin.java | 0 .../client/ClientCommandHandler.java | 0 .../minecraftforge/client/CloudRenderer.java | 0 .../client/EnumHelperClient.java | 0 .../client/FluidContainerColorer.java | 0 .../client/ForgeClientHandler.java | 0 .../client/ForgeHooksClient.java | 0 .../minecraftforge/client/GuiIngameForge.java | 0 .../minecraftforge/client/IClientCommand.java | 0 .../client/IRenderContextHandler.java | 0 .../minecraftforge/client/IRenderHandler.java | 0 .../client/ItemModelMesherForge.java | 0 .../client/MinecraftForgeClient.java | 0 .../client/event/ClientChatEvent.java | 0 .../client/event/ClientChatReceivedEvent.java | 0 .../client/event/ColorHandlerEvent.java | 0 .../client/event/DrawBlockHighlightEvent.java | 0 .../client/event/EntityViewRenderEvent.java | 0 .../client/event/FOVUpdateEvent.java | 0 .../client/event/GuiContainerEvent.java | 0 .../client/event/GuiOpenEvent.java | 0 .../client/event/GuiScreenEvent.java | 0 .../client/event/InputUpdateEvent.java | 0 .../client/event/ModelBakeEvent.java | 0 .../client/event/ModelRegistryEvent.java | 0 .../client/event/MouseEvent.java | 0 .../event/PlayerSPPushOutOfBlocksEvent.java | 0 .../client/event/RenderArmEvent.java | 0 .../client/event/RenderBlockOverlayEvent.java | 0 .../client/event/RenderGameOverlayEvent.java | 0 .../client/event/RenderHandEvent.java | 0 .../client/event/RenderItemInFrameEvent.java | 0 .../client/event/RenderLivingEvent.java | 0 .../client/event/RenderPlayerEvent.java | 0 .../client/event/RenderSpecificHandEvent.java | 0 .../client/event/RenderTooltipEvent.java | 0 .../client/event/RenderWorldLastEvent.java | 0 .../client/event/ScreenshotEvent.java | 0 .../client/event/TextureStitchEvent.java | 0 .../client/event/sound/PlaySoundEvent.java | 0 .../event/sound/PlaySoundSourceEvent.java | 0 .../event/sound/PlayStreamingSourceEvent.java | 0 .../client/event/sound/SoundEvent.java | 0 .../client/event/sound/SoundLoadEvent.java | 0 .../client/event/sound/SoundSetupEvent.java | 0 .../client/gui/ForgeGuiFactory.java | 0 .../gui/NotificationModUpdateScreen.java | 0 .../client/model/Attributes.java | 0 .../client/model/BakedItemModel.java | 0 .../client/model/BakedModelWrapper.java | 0 .../client/model/BlockStateLoader.java | 0 .../client/model/FancyMissingModel.java | 0 .../client/model/ForgeBlockStateV1.java | 0 .../client/model/ICustomModelLoader.java | 0 .../minecraftforge/client/model/IModel.java | 0 .../client/model/ISmartVariant.java | 0 .../client/model/ItemLayerModel.java | 0 .../model/ItemTextureQuadConverter.java | 0 .../client/model/MapModelState.java | 0 .../client/model/ModelDynBucket.java | 0 .../client/model/ModelFluid.java | 0 .../client/model/ModelLoader.java | 0 .../client/model/ModelLoaderRegistry.java | 0 .../client/model/ModelStateComposition.java | 0 .../client/model/MultiLayerModel.java | 0 .../client/model/MultiModel.java | 0 .../client/model/MultiModelState.java | 0 .../client/model/PerspectiveMapWrapper.java | 0 .../client/model/SimpleModelFontRenderer.java | 0 .../client/model/SimpleModelState.java | 0 .../client/model/animation/Animation.java | 0 .../animation/AnimationItemOverrideList.java | 0 .../model/animation/AnimationModelBase.java | 0 .../client/model/animation/AnimationTESR.java | 0 .../client/model/animation/FastTESR.java | 0 .../model/animation/ModelBlockAnimation.java | 0 .../client/model/animation/package-info.java | 0 .../client/model/b3d/B3DClip.java | 0 .../client/model/b3d/B3DLoader.java | 0 .../client/model/b3d/B3DModel.java | 0 .../client/model/b3d/package-info.java | 0 .../client/model/obj/OBJLoader.java | 0 .../client/model/obj/OBJModel.java | 0 .../client/model/obj/package-info.java | 0 .../client/model/package-info.java | 0 .../client/model/pipeline/BlockInfo.java | 0 .../pipeline/ForgeBlockModelRenderer.java | 0 .../model/pipeline/IVertexConsumer.java | 0 .../model/pipeline/IVertexProducer.java | 0 .../client/model/pipeline/LightUtil.java | 0 .../pipeline/QuadGatheringTransformer.java | 0 .../model/pipeline/TRSRTransformer.java | 0 .../model/pipeline/TransformerConsumer.java | 0 .../model/pipeline/UnpackedBakedQuad.java | 0 .../model/pipeline/VertexBufferConsumer.java | 0 .../model/pipeline/VertexLighterFlat.java | 0 .../model/pipeline/VertexLighterSmoothAo.java | 0 .../model/pipeline/VertexTransformer.java | 0 .../client/model/pipeline/package-info.java | 0 .../client/resource/IResourceType.java | 0 .../ISelectiveResourceReloadListener.java | 0 .../client/resource/ReloadRequirements.java | 0 .../resource/SelectiveReloadStateHandler.java | 0 .../client/resource/VanillaResourceType.java | 0 .../client/resource/package-info.java | 0 .../client/settings/IKeyConflictContext.java | 0 .../client/settings/KeyBindingMap.java | 0 .../client/settings/KeyConflictContext.java | 0 .../client/settings/KeyModifier.java | 0 .../common/BiomeDictionary.java | 0 .../minecraftforge/common/BiomeManager.java | 0 .../common/DimensionManager.java | 0 .../minecraftforge/common/DungeonHooks.java | 0 .../minecraftforge/common/EnumPlantType.java | 0 .../common/FarmlandWaterManager.java | 0 .../common/ForgeChunkManager.java | 0 .../common/ForgeEarlyConfig.java | 0 .../net/minecraftforge/common/ForgeHooks.java | 0 .../common/ForgeInternalHandler.java | 0 .../common/ForgeModContainer.java | 0 .../minecraftforge/common/ForgeVersion.java | 0 .../common/IMinecartCollisionHandler.java | 0 .../net/minecraftforge/common/IPlantable.java | 0 .../net/minecraftforge/common/IRarity.java | 0 .../net/minecraftforge/common/IShearable.java | 0 .../minecraftforge/common/ISpecialArmor.java | 0 .../minecraftforge/common/MinecraftForge.java | 0 .../minecraftforge/common/UsernameCache.java | 0 .../common/WorldSpecificSaveHandler.java | 0 .../common/WorldWorkerManager.java | 0 .../common/animation/Event.java | 0 .../common/animation/IEventHandler.java | 0 .../common/animation/ITimeValue.java | 0 .../common/animation/TimeValues.java | 0 .../common/brewing/AbstractBrewingRecipe.java | 0 .../common/brewing/BrewingOreRecipe.java | 0 .../common/brewing/BrewingRecipe.java | 0 .../common/brewing/BrewingRecipeRegistry.java | 0 .../common/brewing/IBrewingRecipe.java | 0 .../common/brewing/VanillaBrewingRecipe.java | 0 .../common/capabilities/Capability.java | 0 .../capabilities/CapabilityDispatcher.java | 0 .../common/capabilities/CapabilityInject.java | 0 .../capabilities/CapabilityManager.java | 0 .../capabilities/ICapabilityProvider.java | 0 .../capabilities/ICapabilitySerializable.java | 0 .../common/chunkio/ChunkIOExecutor.java | 0 .../common/chunkio/ChunkIOProvider.java | 0 .../chunkio/ChunkIOThreadPoolExecutor.java | 0 .../common/chunkio/QueuedChunk.java | 0 .../common/command/SelectorHandler.java | 0 .../command/SelectorHandlerManager.java | 0 .../minecraftforge/common/config/Config.java | 0 .../common/config/ConfigCategory.java | 0 .../common/config/ConfigElement.java | 0 .../common/config/ConfigManager.java | 0 .../common/config/Configuration.java | 0 .../common/config/FieldWrapper.java | 0 .../common/config/IFieldWrapper.java | 0 .../common/config/ITypeAdapter.java | 0 .../common/config/Property.java | 0 .../common/config/TypeAdapters.java | 0 .../common/crafting/CompoundIngredient.java | 0 .../common/crafting/CraftingHelper.java | 0 .../common/crafting/IConditionFactory.java | 0 .../common/crafting/IIngredientFactory.java | 0 .../common/crafting/IRecipeContainer.java | 0 .../common/crafting/IRecipeFactory.java | 0 .../common/crafting/IShapedRecipe.java | 0 .../common/crafting/IngredientNBT.java | 0 .../common/crafting/JsonContext.java | 0 .../common/model/HiddenModelPart.java | 0 .../common/model/IModelPart.java | 0 .../common/model/IModelState.java | 0 .../common/model/ITransformation.java | 0 .../minecraftforge/common/model/Models.java | 0 .../common/model/TRSRTransformation.java | 0 .../animation/AnimationStateMachine.java | 0 .../model/animation/CapabilityAnimation.java | 0 .../common/model/animation/Clips.java | 0 .../animation/IAnimationStateMachine.java | 0 .../common/model/animation/IClip.java | 0 .../common/model/animation/IJoint.java | 0 .../common/model/animation/IJointClip.java | 0 .../common/model/animation/JointClips.java | 0 .../network/DimensionMessageHandler.java | 0 .../FluidIdRegistryMessageHandler.java | 0 .../common/network/ForgeMessage.java | 0 .../common/network/ForgeNetworkHandler.java | 0 .../common/network/ForgeRuntimeCodec.java | 0 ...rToClientConnectionEstablishedHandler.java | 0 .../common/property/ExtendedBlockState.java | 0 .../common/property/IExtendedBlockState.java | 0 .../common/property/IUnlistedProperty.java | 0 .../common/property/Properties.java | 0 .../common/property/PropertyFloat.java | 0 .../common/ticket/AABBTicket.java | 0 .../common/ticket/ChunkTicketManager.java | 0 .../common/ticket/ITicketGetter.java | 0 .../common/ticket/ITicketManager.java | 0 .../common/ticket/MultiTicketManager.java | 0 .../common/ticket/SimpleTicket.java | 0 .../common/util/BlockSnapshot.java | 0 .../common/util/ChunkCoordComparator.java | 0 .../common/util/CompoundDataFixer.java | 0 .../minecraftforge/common/util/Constants.java | 0 .../common/util/EnumHelper.java | 0 .../common/util/FakePlayer.java | 0 .../common/util/FakePlayerFactory.java | 0 .../common/util/IDataFixerData.java | 0 .../common/util/INBTSerializable.java | 0 .../common/util/ITeleporter.java | 0 .../minecraftforge/common/util/JsonUtils.java | 0 .../minecraftforge/common/util/ModFixs.java | 0 .../common/util/PacketUtil.java | 0 .../common/util/RecipeMatcher.java | 0 .../minecraftforge/common/util/TextTable.java | 0 .../common/util/WorldCapabilityData.java | 0 .../energy/CapabilityEnergy.java | 0 .../minecraftforge/energy/EnergyStorage.java | 0 .../minecraftforge/energy/IEnergyStorage.java | 0 .../event/AnvilUpdateEvent.java | 0 .../event/AttachCapabilitiesEvent.java | 0 .../minecraftforge/event/CommandEvent.java | 0 .../event/DifficultyChangeEvent.java | 0 .../event/ForgeEventFactory.java | 0 .../event/GameRuleChangeEvent.java | 0 .../event/LootTableLoadEvent.java | 0 .../minecraftforge/event/RegistryEvent.java | 0 .../minecraftforge/event/ServerChatEvent.java | 0 .../brewing/PlayerBrewedPotionEvent.java | 0 .../event/brewing/PotionBrewEvent.java | 0 .../enchanting/EnchantmentLevelSetEvent.java | 0 .../event/entity/EntityEvent.java | 0 .../event/entity/EntityJoinWorldEvent.java | 0 .../event/entity/EntityMobGriefingEvent.java | 0 .../event/entity/EntityMountEvent.java | 0 .../entity/EntityStruckByLightningEvent.java | 0 .../entity/EntityTravelToDimensionEvent.java | 0 .../event/entity/PlaySoundAtEntityEvent.java | 0 .../event/entity/ProjectileImpactEvent.java | 0 .../event/entity/ThrowableImpactEvent.java | 0 .../event/entity/item/ItemEvent.java | 0 .../event/entity/item/ItemExpireEvent.java | 0 .../event/entity/item/ItemTossEvent.java | 0 .../event/entity/living/AnimalTameEvent.java | 0 .../entity/living/BabyEntitySpawnEvent.java | 0 .../entity/living/EnderTeleportEvent.java | 0 .../entity/living/LivingAttackEvent.java | 0 .../entity/living/LivingDamageEvent.java | 0 .../event/entity/living/LivingDeathEvent.java | 0 .../living/LivingDestroyBlockEvent.java | 0 .../event/entity/living/LivingDropsEvent.java | 0 .../living/LivingEntityUseItemEvent.java | 0 .../living/LivingEquipmentChangeEvent.java | 0 .../event/entity/living/LivingEvent.java | 0 .../living/LivingExperienceDropEvent.java | 0 .../event/entity/living/LivingFallEvent.java | 0 .../event/entity/living/LivingHealEvent.java | 0 .../event/entity/living/LivingHurtEvent.java | 0 .../entity/living/LivingKnockBackEvent.java | 0 .../entity/living/LivingPackSizeEvent.java | 0 .../living/LivingSetAttackTargetEvent.java | 0 .../event/entity/living/LivingSpawnEvent.java | 0 .../entity/living/LootingLevelEvent.java | 0 .../living/PotionColorCalculationEvent.java | 0 .../event/entity/living/PotionEvent.java | 0 .../event/entity/living/ZombieEvent.java | 0 .../minecart/MinecartCollisionEvent.java | 0 .../event/entity/minecart/MinecartEvent.java | 0 .../minecart/MinecartInteractEvent.java | 0 .../entity/minecart/MinecartUpdateEvent.java | 0 .../event/entity/player/AdvancementEvent.java | 0 .../event/entity/player/AnvilRepairEvent.java | 0 .../event/entity/player/ArrowLooseEvent.java | 0 .../event/entity/player/ArrowNockEvent.java | 0 .../entity/player/AttackEntityEvent.java | 0 .../event/entity/player/BonemealEvent.java | 0 .../event/entity/player/CriticalHitEvent.java | 0 .../entity/player/EntityItemPickupEvent.java | 0 .../event/entity/player/FillBucketEvent.java | 0 .../event/entity/player/ItemFishedEvent.java | 0 .../event/entity/player/ItemTooltipEvent.java | 0 .../entity/player/PlayerContainerEvent.java | 0 .../entity/player/PlayerDestroyItemEvent.java | 0 .../event/entity/player/PlayerDropsEvent.java | 0 .../event/entity/player/PlayerEvent.java | 0 .../entity/player/PlayerFlyableFallEvent.java | 0 .../entity/player/PlayerInteractEvent.java | 0 .../entity/player/PlayerPickupXpEvent.java | 0 .../entity/player/PlayerSetSpawnEvent.java | 0 .../entity/player/PlayerSleepInBedEvent.java | 0 .../entity/player/PlayerWakeUpEvent.java | 0 .../player/SleepingLocationCheckEvent.java | 0 .../entity/player/SleepingTimeCheckEvent.java | 0 .../event/entity/player/UseHoeEvent.java | 0 .../furnace/FurnaceFuelBurnTimeEvent.java | 0 .../event/terraingen/BiomeEvent.java | 0 .../event/terraingen/ChunkGeneratorEvent.java | 0 .../event/terraingen/DecorateBiomeEvent.java | 0 .../terraingen/DeferredBiomeDecorator.java | 0 .../event/terraingen/InitMapGenEvent.java | 0 .../event/terraingen/InitNoiseGensEvent.java | 0 .../event/terraingen/OreGenEvent.java | 0 .../event/terraingen/PopulateChunkEvent.java | 0 .../terraingen/SaplingGrowTreeEvent.java | 0 .../event/terraingen/TerrainGen.java | 0 .../event/terraingen/WorldTypeEvent.java | 0 .../village/MerchantTradeOffersEvent.java | 0 .../event/village/VillageSiegeEvent.java | 0 .../event/world/BlockEvent.java | 0 .../event/world/ChunkDataEvent.java | 0 .../event/world/ChunkEvent.java | 0 .../event/world/ChunkWatchEvent.java | 0 .../event/world/ExplosionEvent.java | 0 .../event/world/GetCollisionBoxesEvent.java | 0 .../event/world/NoteBlockEvent.java | 0 .../event/world/WorldEvent.java | 0 .../minecraftforge/fluids/BlockFluidBase.java | 0 .../fluids/BlockFluidClassic.java | 0 .../fluids/BlockFluidFinite.java | 0 .../fluids/DispenseFluidContainer.java | 0 .../java/net/minecraftforge/fluids/Fluid.java | 0 .../fluids/FluidActionResult.java | 0 .../net/minecraftforge/fluids/FluidEvent.java | 0 .../minecraftforge/fluids/FluidRegistry.java | 0 .../net/minecraftforge/fluids/FluidStack.java | 0 .../net/minecraftforge/fluids/FluidTank.java | 0 .../minecraftforge/fluids/FluidTankInfo.java | 0 .../net/minecraftforge/fluids/FluidUtil.java | 0 .../minecraftforge/fluids/IFluidBlock.java | 0 .../net/minecraftforge/fluids/IFluidTank.java | 0 .../fluids/UniversalBucket.java | 0 .../capability/CapabilityFluidHandler.java | 0 .../capability/FluidTankProperties.java | 0 .../FluidTankPropertiesWrapper.java | 0 .../fluids/capability/IFluidHandler.java | 0 .../fluids/capability/IFluidHandlerItem.java | 0 .../capability/IFluidTankProperties.java | 0 .../fluids/capability/ItemFluidContainer.java | 0 .../fluids/capability/TileFluidHandler.java | 0 .../templates/EmptyFluidHandler.java | 0 .../templates/FluidHandlerConcatenate.java | 0 .../templates/FluidHandlerFluidMap.java | 0 .../templates/FluidHandlerItemStack.java | 0 .../FluidHandlerItemStackSimple.java | 0 .../templates/VoidFluidHandler.java | 0 .../wrappers/BlockLiquidWrapper.java | 0 .../capability/wrappers/BlockWrapper.java | 0 .../wrappers/FluidBlockWrapper.java | 0 .../wrappers/FluidBucketWrapper.java | 0 ...CustomModLoadingErrorDisplayException.java | 0 .../fml/client/DefaultGuiFactory.java | 0 .../fml/client/ExtendedServerListData.java | 0 .../fml/client/FMLClientHandler.java | 0 .../fml/client/FMLConfigGuiFactory.java | 0 .../fml/client/FMLFileResourcePack.java | 0 .../fml/client/FMLFolderResourcePack.java | 0 .../fml/client/GuiAccessDenied.java | 0 .../fml/client/GuiBackupFailed.java | 0 .../fml/client/GuiConfirmation.java | 0 .../GuiCustomModLoadingErrorScreen.java | 0 .../fml/client/GuiDupesFound.java | 0 .../fml/client/GuiErrorBase.java | 0 .../minecraftforge/fml/client/GuiModList.java | 0 .../fml/client/GuiModsMissing.java | 0 .../fml/client/GuiModsMissingForServer.java | 0 .../fml/client/GuiMultipleModsErrored.java | 0 .../fml/client/GuiNotification.java | 0 .../fml/client/GuiOldSaveLoadConfirm.java | 0 .../fml/client/GuiScrollingList.java | 0 .../fml/client/GuiSlotModList.java | 0 .../fml/client/GuiSortingProblem.java | 0 .../fml/client/GuiWrongMinecraft.java | 0 .../fml/client/IDisplayableError.java | 0 .../fml/client/IModGuiFactory.java | 0 .../fml/client/SplashProgress.java | 0 .../fml/client/config/ConfigGuiType.java | 0 .../fml/client/config/DummyConfigElement.java | 0 .../fml/client/config/GuiButtonExt.java | 0 .../fml/client/config/GuiCheckBox.java | 0 .../fml/client/config/GuiConfig.java | 0 .../fml/client/config/GuiConfigEntries.java | 0 .../fml/client/config/GuiEditArray.java | 0 .../client/config/GuiEditArrayEntries.java | 0 .../fml/client/config/GuiMessageDialog.java | 0 .../fml/client/config/GuiSelectString.java | 0 .../client/config/GuiSelectStringEntries.java | 0 .../fml/client/config/GuiSlider.java | 0 .../client/config/GuiUnicodeGlyphButton.java | 0 .../fml/client/config/GuiUtils.java | 0 .../fml/client/config/HoverChecker.java | 0 .../fml/client/config/IConfigElement.java | 0 .../fml/client/event/ConfigChangedEvent.java | 0 .../fml/client/registry/ClientRegistry.java | 0 .../fml/client/registry/IRenderFactory.java | 0 .../client/registry/RenderingRegistry.java | 0 .../net/minecraftforge/fml/common/API.java | 0 .../fml/common/AutomaticEventSubscriber.java | 0 .../fml/common/CertificateHelper.java | 0 .../fml/common/ClassNameUtils.java | 0 .../fml/common/DummyModContainer.java | 0 .../common/DuplicateModsFoundException.java | 0 .../fml/common/EnhancedRuntimeException.java | 0 .../fml/common/FMLCommonHandler.java | 0 .../fml/common/FMLContainer.java | 0 .../fml/common/FMLContainerHolder.java | 0 .../fml/common/FMLContextQuery.java | 0 .../net/minecraftforge/fml/common/FMLLog.java | 0 .../fml/common/FMLModContainer.java | 0 .../fml/common/ICrashCallable.java | 0 .../fml/common/IEntitySelectorFactory.java | 0 .../fml/common/IFMLHandledException.java | 0 .../fml/common/IFMLSidedHandler.java | 0 .../fml/common/IFuelHandler.java | 0 .../fml/common/ILanguageAdapter.java | 0 .../fml/common/IWorldGenerator.java | 0 .../fml/common/InjectedModContainer.java | 0 .../fml/common/LoadController.java | 0 .../net/minecraftforge/fml/common/Loader.java | 0 .../fml/common/LoaderException.java | 0 .../fml/common/LoaderExceptionModCrash.java | 0 .../fml/common/LoaderState.java | 0 .../fml/common/MCPDummyContainer.java | 0 .../fml/common/MetadataCollection.java | 0 .../fml/common/MinecraftDummyContainer.java | 0 .../fml/common/MissingModsException.java | 0 .../net/minecraftforge/fml/common/Mod.java | 0 .../fml/common/ModAPIManager.java | 0 .../fml/common/ModClassLoader.java | 0 .../fml/common/ModContainer.java | 0 .../fml/common/ModContainerFactory.java | 0 .../fml/common/ModMetadata.java | 0 .../fml/common/MultipleModsErrored.java | 0 .../common/ObfuscationReflectionHelper.java | 0 .../minecraftforge/fml/common/Optional.java | 0 .../fml/common/ProgressManager.java | 0 .../fml/common/ProxyInjector.java | 0 .../fml/common/SaveInspectionHandler.java | 0 .../minecraftforge/fml/common/SidedProxy.java | 0 .../fml/common/StartupQuery.java | 0 .../fml/common/TracingPrintStream.java | 0 .../fml/common/WorldAccessContainer.java | 0 .../WrongMinecraftVersionException.java | 0 .../minecraftforge/fml/common/ZipperUtil.java | 0 .../fml/common/asm/ASMTransformerWrapper.java | 0 .../fml/common/asm/FMLSanityChecker.java | 0 .../fml/common/asm/ReobfuscationMarker.java | 0 .../asm/transformers/AccessTransformer.java | 0 .../DeobfuscationTransformer.java | 0 .../EventSubscriberTransformer.java | 0 .../EventSubscriptionTransformer.java | 0 .../FieldRedirectTransformer.java | 0 .../ItemBlockSpecialTransformer.java | 0 .../transformers/ItemBlockTransformer.java | 0 .../transformers/ItemStackTransformer.java | 0 .../asm/transformers/LWJGLTransformer.java | 0 .../asm/transformers/MarkerTransformer.java | 0 .../asm/transformers/ModAPITransformer.java | 0 .../transformers/ModAccessTransformer.java | 0 .../asm/transformers/PatchingTransformer.java | 0 .../transformers/PotionEffectTransformer.java | 0 .../asm/transformers/SideTransformer.java | 0 .../SoundEngineFixTransformer.java | 0 .../asm/transformers/TerminalTransformer.java | 0 .../deobf/FMLDeobfuscatingRemapper.java | 0 .../deobf/FMLRemappingAdapter.java | 0 .../transformers/deobf/LZMAInputSupplier.java | 0 .../fml/common/discovery/ASMDataTable.java | 0 .../fml/common/discovery/ContainerType.java | 0 .../common/discovery/DirectoryDiscoverer.java | 0 .../fml/common/discovery/ITypeDiscoverer.java | 0 .../fml/common/discovery/JarDiscoverer.java | 0 .../fml/common/discovery/ModCandidate.java | 0 .../fml/common/discovery/ModDiscoverer.java | 0 .../common/discovery/asm/ASMModParser.java | 0 .../common/discovery/asm/ModAnnotation.java | 0 .../discovery/asm/ModAnnotationVisitor.java | 0 .../common/discovery/asm/ModClassVisitor.java | 0 .../common/discovery/asm/ModFieldVisitor.java | 0 .../discovery/asm/ModMethodVisitor.java | 0 .../fml/common/discovery/json/ASMInfo.java | 0 .../discovery/json/JsonAnnotationLoader.java | 0 .../common/event/FMLConstructionEvent.java | 0 .../fml/common/event/FMLEvent.java | 0 .../event/FMLFingerprintViolationEvent.java | 0 .../common/event/FMLInitializationEvent.java | 0 .../fml/common/event/FMLInterModComms.java | 0 .../common/event/FMLLoadCompleteEvent.java | 0 .../fml/common/event/FMLLoadEvent.java | 0 .../fml/common/event/FMLModDisabledEvent.java | 0 .../common/event/FMLModIdMappingEvent.java | 0 .../event/FMLPostInitializationEvent.java | 0 .../event/FMLPreInitializationEvent.java | 0 .../event/FMLServerAboutToStartEvent.java | 0 .../common/event/FMLServerStartedEvent.java | 0 .../common/event/FMLServerStartingEvent.java | 0 .../common/event/FMLServerStoppedEvent.java | 0 .../common/event/FMLServerStoppingEvent.java | 0 .../fml/common/event/FMLStateEvent.java | 0 .../common/eventhandler/ASMEventHandler.java | 0 .../fml/common/eventhandler/Cancelable.java | 0 .../fml/common/eventhandler/Event.java | 0 .../fml/common/eventhandler/EventBus.java | 0 .../eventhandler/EventListenerFactory.java | 0 .../common/eventhandler/EventPriority.java | 0 .../eventhandler/FMLThrowingEventBus.java | 0 .../fml/common/eventhandler/GenericEvent.java | 0 .../common/eventhandler/IContextSetter.java | 0 .../eventhandler/IEventExceptionHandler.java | 0 .../common/eventhandler/IEventListener.java | 0 .../common/eventhandler/IGenericEvent.java | 0 .../fml/common/eventhandler/ListenerList.java | 0 .../common/eventhandler/SubscribeEvent.java | 0 .../fml/common/gameevent/InputEvent.java | 0 .../fml/common/gameevent/PlayerEvent.java | 0 .../fml/common/gameevent/TickEvent.java | 0 .../fml/common/launcher/FMLDeobfTweaker.java | 0 .../FMLInjectionAndSortingTweaker.java | 0 .../fml/common/launcher/FMLServerTweaker.java | 0 .../fml/common/launcher/FMLTweaker.java | 0 .../fml/common/launcher/Yggdrasil.java | 0 .../fml/common/network/ByteBufUtils.java | 0 .../common/network/FMLEmbeddedChannel.java | 0 .../fml/common/network/FMLEventChannel.java | 0 .../FMLIndexedMessageToMessageCodec.java | 0 .../fml/common/network/FMLNetworkEvent.java | 0 .../common/network/FMLNetworkException.java | 0 .../common/network/FMLOutboundHandler.java | 0 .../fml/common/network/IGuiHandler.java | 0 .../common/network/NetworkCheckHandler.java | 0 .../network/NetworkEventFiringHandler.java | 0 .../network/NetworkHandshakeEstablished.java | 0 .../fml/common/network/NetworkRegistry.java | 0 .../common/network/PacketLoggingHandler.java | 0 .../handshake/ChannelRegistrationHandler.java | 0 .../handshake/FMLHandshakeClientState.java | 0 .../network/handshake/FMLHandshakeCodec.java | 0 .../handshake/FMLHandshakeMessage.java | 0 .../handshake/FMLHandshakeServerState.java | 0 .../network/handshake/HandshakeInjector.java | 0 .../handshake/HandshakeMessageHandler.java | 0 .../network/handshake/IHandshakeState.java | 0 .../network/handshake/NetworkDispatcher.java | 0 .../network/internal/EntitySpawnHandler.java | 0 .../common/network/internal/FMLMessage.java | 0 .../network/internal/FMLNetworkHandler.java | 0 .../network/internal/FMLProxyPacket.java | 0 .../network/internal/FMLRuntimeCodec.java | 0 .../internal/HandshakeCompletionHandler.java | 0 .../network/internal/NetworkModHolder.java | 0 .../network/internal/OpenGuiHandler.java | 0 .../common/network/simpleimpl/IMessage.java | 0 .../network/simpleimpl/IMessageHandler.java | 0 .../network/simpleimpl/MessageContext.java | 0 .../SimpleChannelHandlerWrapper.java | 0 .../simpleimpl/SimpleIndexedCodec.java | 0 .../simpleimpl/SimpleNetworkWrapper.java | 0 .../fml/common/patcher/ClassPatch.java | 0 .../fml/common/patcher/ClassPatchManager.java | 0 .../fml/common/patcher/GenDiffSet.java | 0 .../fml/common/registry/EntityEntry.java | 0 .../common/registry/EntityEntryBuilder.java | 0 .../fml/common/registry/EntityRegistry.java | 0 .../ExistingSubstitutionException.java | 0 .../fml/common/registry/ForgeRegistries.java | 0 .../fml/common/registry/GameRegistry.java | 0 .../registry/IEntityAdditionalSpawnData.java | 0 .../fml/common/registry/IThrowableEntity.java | 0 .../registry/ItemStackHolderInjector.java | 0 .../common/registry/ItemStackHolderRef.java | 0 .../fml/common/registry/VillagerRegistry.java | 0 .../fml/common/thread/SidedThreadGroup.java | 0 .../fml/common/thread/SidedThreadGroups.java | 0 .../fml/common/toposort/ModSorter.java | 0 .../common/toposort/ModSortingException.java | 0 .../fml/common/toposort/TopologicalSort.java | 0 .../common/versioning/ArtifactVersion.java | 0 .../common/versioning/ComparableVersion.java | 0 .../versioning/DefaultArtifactVersion.java | 0 .../common/versioning/DependencyParser.java | 0 .../InvalidVersionSpecificationException.java | 0 .../fml/common/versioning/Restriction.java | 0 .../fml/common/versioning/VersionParser.java | 0 .../fml/common/versioning/VersionRange.java | 0 .../fml/relauncher/CoreModManager.java | 0 .../fml/relauncher/FMLCorePlugin.java | 0 .../fml/relauncher/FMLInjectionData.java | 0 .../fml/relauncher/FMLLaunchHandler.java | 0 .../fml/relauncher/FMLRelaunchLog.java | 0 .../fml/relauncher/FileListHelper.java | 0 .../fml/relauncher/IFMLCallHook.java | 0 .../fml/relauncher/IFMLLoadingPlugin.java | 0 .../fml/relauncher/MixinBooterPlugin.java | 0 .../fml/relauncher/ReflectionHelper.java | 0 .../fml/relauncher/ServerLaunchWrapper.java | 0 .../minecraftforge/fml/relauncher/Side.java | 0 .../fml/relauncher/SideOnly.java | 0 .../fml/relauncher/libraries/Artifact.java | 0 .../relauncher/libraries/LibraryManager.java | 0 .../relauncher/libraries/LinkRepository.java | 0 .../relauncher/libraries/MemoryModList.java | 0 .../fml/relauncher/libraries/ModList.java | 0 .../fml/relauncher/libraries/Repository.java | 0 .../relauncher/libraries/SnapshotJson.java | 0 .../delta/ByteBufferSeekableSource.java | 0 .../repackage/com/nothome/delta/Checksum.java | 0 .../com/nothome/delta/DebugDiffWriter.java | 0 .../repackage/com/nothome/delta/Delta.java | 0 .../com/nothome/delta/DiffWriter.java | 0 .../com/nothome/delta/GDiffPatcher.java | 0 .../com/nothome/delta/GDiffWriter.java | 0 .../com/nothome/delta/PatchException.java | 0 .../delta/RandomAccessFileSeekableSource.java | 0 .../com/nothome/delta/SeekableSource.java | 0 .../fml/server/FMLServerHandler.java | 0 .../items/CapabilityItemHandler.java | 0 .../minecraftforge/items/IItemHandler.java | 0 .../items/IItemHandlerModifiable.java | 0 .../items/ItemHandlerHelper.java | 0 .../items/ItemStackHandler.java | 0 .../minecraftforge/items/SlotItemHandler.java | 0 .../items/VanillaDoubleChestItemHandler.java | 0 .../items/VanillaHopperItemHandler.java | 0 .../items/VanillaInventoryCodeHooks.java | 0 .../items/wrapper/CombinedInvWrapper.java | 0 .../items/wrapper/EmptyHandler.java | 0 .../items/wrapper/EntityArmorInvWrapper.java | 0 .../wrapper/EntityEquipmentInvWrapper.java | 0 .../items/wrapper/EntityHandsInvWrapper.java | 0 .../items/wrapper/InvWrapper.java | 0 .../items/wrapper/PlayerArmorInvWrapper.java | 0 .../items/wrapper/PlayerInvWrapper.java | 0 .../items/wrapper/PlayerMainInvWrapper.java | 0 .../wrapper/PlayerOffhandInvWrapper.java | 0 .../items/wrapper/RangedWrapper.java | 0 .../items/wrapper/SidedInvWrapper.java | 0 .../net/minecraftforge/oredict/DyeUtils.java | 0 .../minecraftforge/oredict/OreDictionary.java | 0 .../minecraftforge/oredict/OreIngredient.java | 0 .../minecraftforge/oredict/RecipeSorter.java | 0 .../oredict/ShapedOreRecipe.java | 0 .../oredict/ShapelessOreRecipe.java | 0 .../registries/DataSerializerEntry.java | 0 .../registries/ForgeRegistry.java | 0 .../minecraftforge/registries/GameData.java | 0 .../registries/IForgeRegistry.java | 0 .../registries/IForgeRegistryEntry.java | 0 .../registries/IForgeRegistryInternal.java | 0 .../registries/IForgeRegistryModifiable.java | 0 .../registries/ILockableRegistry.java | 0 .../registries/IRegistryDelegate.java | 0 .../NamespacedDefaultedWrapper.java | 0 .../registries/NamespacedWrapper.java | 0 .../registries/ObjectHolderRef.java | 0 .../registries/ObjectHolderRegistry.java | 0 .../registries/RegistryBuilder.java | 0 .../registries/RegistryDelegate.java | 0 .../registries/RegistryManager.java | 0 .../server/ForgeTimeTracker.java | 0 .../server/command/ChunkGenWorker.java | 0 .../server/command/CommandDimensions.java | 0 .../server/command/CommandEntity.java | 0 .../server/command/CommandGenerate.java | 0 .../server/command/CommandSetDimension.java | 0 .../server/command/CommandTps.java | 0 .../server/command/CommandTrack.java | 0 .../server/command/CommandTreeBase.java | 0 .../server/command/CommandTreeHelp.java | 0 .../server/command/ForgeCommand.java | 0 .../server/command/TextComponentHelper.java | 0 .../server/command/package-info.java | 0 .../console/ConsoleCommandCompleter.java | 0 .../server/console/TerminalHandler.java | 0 .../permission/DefaultPermissionHandler.java | 0 .../permission/DefaultPermissionLevel.java | 0 .../server/permission/IPermissionHandler.java | 0 .../server/permission/PermissionAPI.java | 0 .../permission/context/AreaContext.java | 0 .../permission/context/BlockPosContext.java | 0 .../server/permission/context/Context.java | 0 .../server/permission/context/ContextKey.java | 0 .../permission/context/ContextKeys.java | 0 .../server/permission/context/IContext.java | 0 .../permission/context/PlayerContext.java | 0 .../permission/context/TargetContext.java | 0 .../permission/context/WorldContext.java | 0 .../permission/context/package-info.java | 0 .../server/permission/package-info.java | 0 .../HighlightErrorConverter.java | 0 .../MinecraftFormattingConverter.java | 0 .../TerminalConsoleAppender.java | 0 .../server/terminalconsole/package-info.java | 0 .../util/LoggerNamePatternSelector.java | 0 .../terminalconsole/util/package-info.java | 0 .../server/timings/ForgeTimings.java | 0 .../server/timings/TimeTracker.java | 0 .../paulscode/sound/codecs/CodecIBXM.java | 0 .../core/config/plugins/Log4j2Plugins.dat | Bin .../assets/fml/textures/gui/forge.png | Bin .../assets/fml/textures/gui/icons.png | Bin .../assets/forge/blockstates/dynbucket.json | 0 .../resources/assets/forge/lang/README.txt | 0 .../resources/assets/forge/lang/en_pt.lang | 0 .../resources/assets/forge/lang/en_us.lang | 0 .../resources/assets/forge/lang/es_es.lang | 0 .../resources/assets/forge/lang/fr_fr.lang | 0 .../resources/assets/forge/lang/ja_jp.lang | 0 .../resources/assets/forge/lang/ko_kr.lang | 0 .../resources/assets/forge/lang/ru_ru.lang | 0 .../resources/assets/forge/lang/zh_cn.lang | 0 .../resources/assets/forge/lang/zh_tw.lang | 0 .../assets/forge/models/item/bucket.json | 0 .../assets/forge/models/item/bucket_milk.json | 0 .../textures/gui/version_check_icons.png | Bin .../forge/textures/items/bucket_fluid.png | Bin .../items/vanilla_bucket_cover_mask.png | Bin .../forge/src}/main/resources/forge.exc | 0 .../forge/src}/main/resources/forge.srg | 0 .../forge/src}/main/resources/forge_at.cfg | 0 .../forge/src}/main/resources/forge_logo.png | Bin .../forge/src}/main/resources/log4j2.xml | 0 .../src}/main/resources/log4j2_server.xml | 0 .../src}/main/resources/logging.properties | 0 .../forge/src}/main/resources/mcplogo.png | Bin .../forge/src}/main/resources/mcpmod.info | 0 .../forge/src}/main/resources/pack.mcmeta | 0 .../forge/src}/main/resources/url.png | Bin .../minecraftforge/debug/PotionEventTest.java | 0 .../debug/block/BasePlaceEventTest.java | 0 .../debug/block/FarmlandTrampleEventTest.java | 0 .../debug/block/FarmlandWaterTest.java | 0 .../debug/block/MaterialFogColorTest.java | 0 .../debug/block/NeighborNotifyEventTest.java | 0 .../debug/block/ParticleEffectsTest.java | 0 .../debug/block/PathNodeTypeTest.java | 0 .../debug/block/PlaceEventTest.java | 0 .../debug/block/PortalSpawnEventTest.java | 0 .../debug/block/SlipperinessTest.java | 0 .../debug/block/StickyBlockTest.java | 0 .../debug/block/package-info.java | 0 .../debug/chat/ClientChatEventTest.java | 0 .../debug/chat/ClientCommandTest.java | 0 .../debug/chat/CommandTreeBaseTest.java | 0 .../debug/chat/EntitySelectorFactoryTest.java | 0 .../debug/chat/package-info.java | 0 .../client/CustomTextureAtlasSpriteTest.java | 0 .../debug/client/FOVModifierEventTest.java | 0 .../client/SearchableCreativeTabTest.java | 0 .../gui/ContainerDrawForegroundEventTest.java | 0 .../client/gui/TooltipColorEventTest.java | 0 .../debug/client/model/AnimatedModelTest.java | 0 .../client/model/BlockstateRetextureTest.java | 0 .../model/ForgeBlockStatesLoaderTest.java | 0 .../client/model/ItemLayerModelTest.java | 0 .../client/model/ItemModelConflictTest.java | 0 .../client/model/ItemModelGenerationTest.java | 0 .../client/model/ModelBakeEventTest.java | 0 .../debug/client/model/ModelFluidTest.java | 0 .../client/model/ModelLoaderRegistryTest.java | 0 .../client/model/MultiLayerModelTest.java | 0 .../debug/client/model/package-info.java | 0 .../debug/client/package-info.java | 0 .../rendering/FastTESRTransparentTest.java | 0 .../debug/client/rendering/ItemTESRTest.java | 0 .../rendering/VertexBufferNormalTest.java | 0 .../debug/client/rendering/package-info.java | 0 .../debug/entity/BlockEntityUpdateTest.java | 0 .../EntityTravelToDimensionEventTest.java | 0 .../entity/GetCollisionBoxesEventTest.java | 0 .../entity/ProjectileImpactEventTest.java | 0 .../entity/living/AnimalTameEventTest.java | 0 .../debug/entity/living/AttackEventTest.java | 0 .../living/BabyEntitySpawnEventTest.java | 0 .../entity/living/CheckSpawnEventTest.java | 0 .../living/CustomSpawnPlacementTest.java | 0 .../debug/entity/living/DamageEventTest.java | 0 .../living/EquipmentChangeEventTest.java | 0 .../entity/living/KnockBackEventTest.java | 0 .../entity/living/MobGriefingEventTest.java | 0 .../debug/entity/living/SpecialSpawnTest.java | 0 .../entity/living/VillagerProfessionTest.java | 0 .../debug/entity/living/package-info.java | 0 .../debug/entity/package-info.java | 0 .../entity/player/CriticalHitEventTest.java | 0 .../debug/entity/player/DamageReworkTest.java | 0 .../entity/player/ItemPickupEventTest.java | 0 .../player/PlayerInteractEventTest.java | 0 .../entity/player/PlayerSetSpawnTest.java | 0 .../player/ReachDistanceAttributeTest.java | 0 .../entity/player/SwimSpeedAttributeTest.java | 0 .../debug/entity/player/package-info.java | 0 .../debug/fluid/ColoredFluidTest.java | 0 .../fluid/CreateFluidSourceEventTest.java | 0 .../debug/fluid/DynBucketTest.java | 0 .../debug/fluid/FluidPlaceBlockEventTest.java | 0 .../debug/fluid/FluidPlacementTest.java | 0 .../debug/fluid/ItemFluidHandlerTest.java | 0 .../debug/fluid/package-info.java | 0 .../debug/gameplay/AnytimeSleepingTest.java | 0 .../gameplay/BrewingRecipeRegistryTest.java | 0 .../debug/gameplay/ConstantLoadingTest.java | 0 .../debug/gameplay/CraftingSystemTest.java | 0 .../gameplay/DifficultyChangeEventTest.java | 0 .../debug/gameplay/DynamicBannerTest.java | 0 .../EnchantmentLevelSetEventTest.java | 0 .../FurnaceFuelBurnTimeEventTest.java | 0 .../debug/gameplay/GiveItemToPlayerTest.java | 0 .../debug/gameplay/InputUpdateEventTest.java | 0 .../debug/gameplay/NoBedSleepingTest.java | 0 .../debug/gameplay/PotionRegistryTest.java | 0 .../debug/gameplay/RecipeMatchingTest.java | 0 .../advancement/AdvancementCriterionTest.java | 0 .../advancement/AdvancementEventTest.java | 0 .../AdvancementsPaginationTest.java | 0 .../advancement/OredictTriggerTest.java | 0 .../gameplay/advancement/package-info.java | 0 .../gameplay/loot/LootContextTweaksTest.java | 0 .../gameplay/loot/LootTableLoadEventTest.java | 0 .../debug/gameplay/loot/LootTableTest.java | 0 .../debug/gameplay/loot/package-info.java | 0 .../debug/gameplay/package-info.java | 0 .../debug/item/BonemealEventTest.java | 0 .../item/CanApplyAtEnchantingTableTest.java | 0 .../item/CanDestroyBlocksInCreativeTest.java | 0 .../debug/item/ContinuousUseItemTest.java | 0 .../debug/item/CustomRarityTest.java | 0 .../debug/item/HorseArmorTest.java | 0 .../debug/item/IsBookEnchantableTest.java | 0 .../debug/item/ItemFishedEventTest.java | 0 .../debug/item/MapDataTest.java | 0 .../debug/item/MendingRepairTest.java | 0 .../debug/item/NBTShareTagTest.java | 0 .../debug/item/OnItemUseFirstTest.java | 0 .../debug/item/PotionCurabilityTest.java | 0 .../debug/item/PotionShouldRenderTest.java | 0 .../minecraftforge/debug/item/ShieldTest.java | 0 .../debug/item/package-info.java | 0 .../debug/misc/EnumPlantTypeTest.java | 0 .../debug/misc/package-info.java | 0 .../debug/mod/CapabilityTest.java | 0 .../debug/mod/ClientLoadingExceptionTest.java | 0 .../debug/mod/ConfigAnnotationTest.java | 0 .../debug/mod/ObjectHolderAnnotationTest.java | 0 .../debug/mod/PermissionTest.java | 0 .../debug/mod/RegistryOverrideTest.java | 0 .../debug/mod/package-info.java | 0 .../debug/network/BigNetworkMessageTest.java | 0 .../debug/network/TrackingTargetTest.java | 0 .../debug/network/package-info.java | 0 .../minecraftforge/debug/package-info.java | 0 .../debug/util/ModNameTooltip.java | 0 .../debug/util/RotatingWrench.java | 0 .../debug/util/TextureDumper.java | 0 .../debug/util/package-info.java | 0 .../village/MerchantTradeOffersEventTest.java | 0 .../debug/village/VillageSiegeEventTest.java | 0 .../debug/world/ChunkCapabilityTest.java | 0 .../debug/world/ChunkWatchEventTest.java | 0 .../debug/world/DecorateEventDebug.java | 0 .../debug/world/SpawnDimensionTest.java | 0 .../debug/world/TileEntityLoadingTest.java | 0 .../debug/world/WorldCapabilityTest.java | 0 .../world/WorldProviderCanSleepAtTest.java | 0 .../debug/world/package-info.java | 0 .../fml/common/eventhandler/EventBusTest.java | 0 .../eventhandler/impl/AbnormalListeners.java | 0 .../eventhandler/impl/ExampleEvent.java | 0 .../eventhandler/impl/InstanceListeners.java | 0 .../eventhandler/impl/StaticListeners.java | 0 .../registry/BlockStateMappingsTest.java | 0 .../registry/DummyBlockReplacementTest.java | 0 .../fml/common/registry/ForgeTestRunner.java | 0 .../fml/common/registry/FreezingTests.java | 0 ...temBlockSubstitutionRemoveRestoreTest.java | 0 .../common/registry/RegistryTestSuite.java | 0 .../registry/SubstitutionInjectionTest.java | 0 .../SubstitutionRemoveRestoreTest.java | 0 .../common/registry/VanillaRegistryTests.java | 0 .../fml/debug/FaultyCoreMod.java | 0 .../fml/test/DependencyParserTest.java | 0 .../fml/test/ForgeNetworkTestMod.java | 0 .../fml/test/SpecialSpawnEventTest.java | 0 .../minecraftforge/fml/test/TestNetStuff.java | 0 .../TestNetworkHandshake.java | 0 .../fml/test/simplenet/SimpleNetHandler1.java | 0 .../fml/test/simplenet/SimpleNetHandler2.java | 0 .../test/simplenet/SimpleNetTestMessage1.java | 0 .../test/simplenet/SimpleNetTestMessage2.java | 0 .../fml/test/simplenet/SimpleNetTester.java | 0 .../test/BiomeSpawnableListTest.java | 0 .../test/BufferBuilderExpansionTest.java | 0 .../test/ConfigurationTest.java | 0 .../minecraftforge/test/EnumHelperTest.java | 0 .../test/SelectorHandlerTest.java | 0 .../test/SliderConfigElementTest.java | 0 .../test/TestAnnotationParser.java | 0 .../minecraftforge/test/TextTableTest.java | 0 .../net/minecraftforge/test/package-info.java | 0 .../advancements/root.json | 0 .../advancements/a1/root.json | 0 .../advancements/a10/root.json | 0 .../advancements/a11/root.json | 0 .../advancements/a12/root.json | 0 .../advancements/a13/root.json | 0 .../advancements/a14/root.json | 0 .../advancements/a15/root.json | 0 .../advancements/a16/root.json | 0 .../advancements/a17/root.json | 0 .../advancements/a18/root.json | 0 .../advancements/a19/root.json | 0 .../advancements/a2/root.json | 0 .../advancements/a20/root.json | 0 .../advancements/a21/root.json | 0 .../advancements/a22/root.json | 0 .../advancements/a23/root.json | 0 .../advancements/a24/root.json | 0 .../advancements/a25/root.json | 0 .../advancements/a26/root.json | 0 .../advancements/a27/root.json | 0 .../advancements/a28/root.json | 0 .../advancements/a29/root.json | 0 .../advancements/a3/root.json | 0 .../advancements/a30/root.json | 0 .../advancements/a31/root.json | 0 .../advancements/a32/root.json | 0 .../advancements/a33/root.json | 0 .../advancements/a34/root.json | 0 .../advancements/a35/root.json | 0 .../advancements/a36/root.json | 0 .../advancements/a37/root.json | 0 .../advancements/a38/root.json | 0 .../advancements/a39/root.json | 0 .../advancements/a4/root.json | 0 .../advancements/a40/root.json | 0 .../advancements/a41/root.json | 0 .../advancements/a42/root.json | 0 .../advancements/a43/root.json | 0 .../advancements/a44/root.json | 0 .../advancements/a45/root.json | 0 .../advancements/a46/root.json | 0 .../advancements/a47/root.json | 0 .../advancements/a48/root.json | 0 .../advancements/a49/root.json | 0 .../advancements/a5/root.json | 0 .../advancements/a50/root.json | 0 .../advancements/a51/root.json | 0 .../advancements/a52/root.json | 0 .../advancements/a53/root.json | 0 .../advancements/a54/root.json | 0 .../advancements/a55/root.json | 0 .../advancements/a56/root.json | 0 .../advancements/a57/root.json | 0 .../advancements/a58/root.json | 0 .../advancements/a59/root.json | 0 .../advancements/a6/root.json | 0 .../advancements/a60/root.json | 0 .../advancements/a61/root.json | 0 .../advancements/a62/root.json | 0 .../advancements/a63/root.json | 0 .../advancements/a64/root.json | 0 .../advancements/a7/root.json | 0 .../advancements/a8/root.json | 0 .../advancements/a9/root.json | 0 .../blockstates/box_block.json | 0 .../assets/config_test/lang/en_US.lang | 0 .../constantloadingtest/test/_constants.json | 0 .../recipes/_factories.json | 0 .../conditions_property_not_array.json | 0 .../recipes/oak_planks_from_logs.json | 0 .../blockstates/custom_sprite_block.json | 0 .../models/block/custom_sprite_block.json | 0 .../dynbuckettest/blockstates/simpletank.json | 0 .../blockstates/test_block.json | 0 .../blockstates/slime.json | 0 .../textures/slime_flow.png | Bin .../textures/slime_flow.png.mcmeta | 0 .../textures/slime_overlay.png | Bin .../textures/slime_still.png | Bin .../textures/slime_still.png.mcmeta | 0 .../blockstates/slime.json | 0 .../fogcolorinsidematerialtest/pack.mcmeta | 0 .../test_fluid.json | 0 .../textures/slime_flow.png | Bin .../textures/slime_flow.png.mcmeta | 0 .../textures/slime_overlay.png | Bin .../textures/slime_still.png | Bin .../textures/slime_still.png.mcmeta | 0 .../assets/forge/blockstates/dynbottle.json | 0 .../assets/forge/recipes/_constants.json | 0 .../assets/forge/recipes/ore_shaped.json | 0 .../assets/forge/recipes/shapeless.json | 0 .../forge/recipes/shapeless_constant.json | 0 .../forge/recipes/shapeless_damageable.json | 0 .../assets/forge/recipes/shapeless_ore.json | 0 .../forge/recipes/shapeless_wildcard.json | 0 .../forge/textures/blocks/milk_flow.png | Bin .../textures/blocks/milk_flow.png.mcmeta | 0 .../forge/textures/blocks/milk_still.png | Bin .../textures/blocks/milk_still.png.mcmeta | 0 .../blockstates/cobblestone_wall.json | 0 .../blockstates/mossy_cobblestone_wall.json | 0 .../models/block/wall_connect.json | 0 .../blockstates/custom_slime_block.json | 0 .../lang/en_US.lang | 0 .../models/block/blue_slime_block.json | 0 .../models/block/obsidian_slime_block.json | 0 .../models/item/blue_slime_block.json | 0 .../models/item/obsidian_slime_block.json | 0 .../textures/blocks/blue_slime_block.png | Bin .../textures/blocks/obsidian_slime_block.png | Bin .../blockstates/finite_fluid_block.json | 0 .../blockstates/test_item.json | 0 .../blockstates/custom_model_block.json | 0 .../armatures/block/engine_ring.json | 0 .../armatures/block/rotatest.json | 0 .../asms/block/chest.json | 0 .../asms/block/engine.json | 0 .../asms/block/engine2.json | 0 .../asms/block/rotatest.json | 0 .../blockstates/rotatest.json | 0 .../blockstates/test_animation_block.json | 0 .../models/block/engine.json | 0 .../models/block/engine_ring.json | 0 .../models/block/rotatest.json | 0 .../blockstates/test_fluid_block.json | 0 .../blockstates/custom_model_block.json | 0 .../blockstates/obj_custom_data_block.json | 0 .../blockstates/obj_direction_block.json | 0 .../blockstates/obj_direction_eye.json | 0 .../blockstates/obj_dynamic_eye.json | 0 .../blockstates/obj_tesseract_block.json | 0 .../blockstates/obj_vertex_coloring1.json | 0 .../blockstates/obj_vertex_coloring2.json | 0 .../models/block/chest.b3d | Bin .../models/block/direction_test.mtl | 0 .../models/block/direction_test.obj | 0 .../models/block/eye.mtl | 0 .../models/block/eye.obj | 0 .../models/block/fancy_fence.mtl | 0 .../models/block/fancy_fence.obj | 0 .../models/block/tesseract.mtl | 0 .../models/block/tesseract.obj | 0 .../models/block/untitled2.b3d | Bin .../models/block/vertex_coloring.mtl | 0 .../models/block/vertex_coloring.obj | 0 .../textures/direction_test_arrow.png | Bin .../textures/direction_test_arrow_top.png | Bin .../textures/direction_test_back.png | Bin .../textures/direction_test_front.png | Bin .../textures/eye.png | Bin .../textures/eye128.png | Bin .../textures/texture.png | Bin .../blockstates/test_layer_block.json | 0 .../models/item/sleeping_pill.json | 0 .../models/item/flammable_gold_shovel.json | 0 .../models/item/unburnable_wood_shovel.json | 0 .../assets/horse_armor_test/lang/en_US.lang | 0 .../models/item/test_armor.json | 0 .../textures/entity/horse/armor/test.png | Bin .../textures/items/test_armor.png | Bin .../models/item/item_test.json | 0 .../blockstates/test.json | 0 .../models/block/test.json | 0 .../models/item/test.json | 0 .../models/item/animation_test.json | 0 .../models/item/intersection_test.json | 0 .../models/item/opacity_test.json | 0 .../models/item/overlap_test.json | 0 .../models/item/pattern_test.json | 0 .../textures/items/animation_test.png | Bin .../textures/items/animation_test.png.mcmeta | 0 .../textures/items/intersection_test.png | Bin .../textures/items/opacity_test.png | Bin .../textures/items/overlap_test.png | Bin .../textures/items/pattern_test.png | Bin .../advancements/test/root.json | 0 .../chests/custom_spawn_bonus_chest.json | 0 .../models/item/nbt_share_tag_item.json | 0 .../models/item/test_item.json | 0 .../advancements/recipes/wood_unlock_tnt.json | 0 .../textures/entity/test_villager.png | Bin .../textures/entity/zombie_test_villager.png | Bin .../recipetest/recipes/tool_complex.json | 0 .../recipetest/recipes/tool_simple.json | 0 .../assets/shield_test/lang/en_US.lang | 0 .../models/item/diamond_shield.json | 0 .../models/item/diamond_shield_blocking.json | 0 .../models/item/test_wrench.json | 0 .../textures/items/test_wrench.png | Bin .../forge/src}/test/resources/mcmod.info | 0 {projects => module}/kirino | 0 .../java/zone/rong/mixinbooter/Context.java | 0 .../rong/mixinbooter/IEarlyMixinLoader.java | 0 .../rong/mixinbooter/ILateMixinLoader.java | 0 .../mixinbooter/IMixinConfigHijacker.java | 0 projects/cleanroom/build.gradle | 1083 ----------------- projects/mcp/build.gradle | 16 - projects/minecraft/build.gradle | 58 - settings.gradle | 26 +- 1168 files changed, 326 insertions(+), 2877 deletions(-) delete mode 100644 buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/BytecodeFinder.groovy delete mode 100644 buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CheckAccessTransformers.groovy delete mode 100644 buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CheckExcs.groovy delete mode 100644 buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CheckPatches.groovy delete mode 100644 buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CheckSAS.groovy delete mode 100644 buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/ClosureHelper.groovy delete mode 100644 buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CreateMMCPackTask.groovy delete mode 100644 buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CrowdinTask.groovy delete mode 100644 buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/DownloadLibrariesTask.groovy delete mode 100644 buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/FieldCompareFinder.groovy delete mode 100644 buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/ObjectTarget.groovy delete mode 100644 mmcpack-template/.packignore delete mode 100644 mmcpack-template/cleanroom.png delete mode 100644 mmcpack-template/instance.cfg delete mode 100644 mmcpack-template/mmc-pack.json delete mode 100644 mmcpack-template/patches/net.minecraft.json delete mode 100644 mmcpack-template/patches/net.minecraftforge.json delete mode 100644 mmcpack-template/patches/org.lwjgl3.json rename {src => module/cleanroom/src}/main/java/com/cleanroommc/boot/Main.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/boot/MainClient.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/boot/MainServer.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/ICU4JInstances.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/IMEHandler.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/LoadingTracker.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/ime/DummyIMEHandler.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/ime/WaylandIMEhandler.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/ime/WindowsIMEHandler.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/ime/X11IMEHandler.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/windows/DwmApi.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/windows/NtDll.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/windows/TaskbarApi.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/windows/WindowsProperties.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/windows/WindowsTheme.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/common/CleanroomContainer.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/common/ConfigAnytimeContainer.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/common/MixinContainer.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/common/PatchModPresentChecker.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/configanytime/ConfigAnytime.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/hackery/Reflection.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/hackery/ReflectionHackery.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/hackery/enums/EnumHackery.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/loader/LanguageAdapterRegistry.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/loader/javafix/UUIDFix.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/loader/scripting/CleanroomScriptEngineManager.java (100%) rename {src => module/cleanroom/src}/test/java/com/cleanroommc/hackery/EnumHackeryTest.java (100%) rename {src => module/forge/src}/main/java/ibxm/Channel.java (100%) rename {src => module/forge/src}/main/java/ibxm/Envelope.java (100%) rename {src => module/forge/src}/main/java/ibxm/FastTracker2.java (100%) rename {src => module/forge/src}/main/java/ibxm/IBXM.java (100%) rename {src => module/forge/src}/main/java/ibxm/Instrument.java (100%) rename {src => module/forge/src}/main/java/ibxm/LogTable.java (100%) rename {src => module/forge/src}/main/java/ibxm/Module.java (100%) rename {src => module/forge/src}/main/java/ibxm/Pattern.java (100%) rename {src => module/forge/src}/main/java/ibxm/Player.java (100%) rename {src => module/forge/src}/main/java/ibxm/ProTracker.java (100%) rename {src => module/forge/src}/main/java/ibxm/Sample.java (100%) rename {src => module/forge/src}/main/java/ibxm/ScreamTracker3.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/advancements/critereon/ItemPredicates.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/advancements/critereon/OredictItemPredicate.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/classloading/FMLForgePlugin.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/ClientCommandHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/CloudRenderer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/EnumHelperClient.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/FluidContainerColorer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/ForgeClientHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/ForgeHooksClient.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/GuiIngameForge.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/IClientCommand.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/IRenderContextHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/IRenderHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/ItemModelMesherForge.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/MinecraftForgeClient.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/ClientChatEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/ClientChatReceivedEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/ColorHandlerEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/DrawBlockHighlightEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/EntityViewRenderEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/FOVUpdateEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/GuiContainerEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/GuiOpenEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/GuiScreenEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/InputUpdateEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/ModelBakeEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/ModelRegistryEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/MouseEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/PlayerSPPushOutOfBlocksEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/RenderArmEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/RenderBlockOverlayEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/RenderGameOverlayEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/RenderHandEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/RenderItemInFrameEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/RenderLivingEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/RenderPlayerEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/RenderSpecificHandEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/RenderTooltipEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/RenderWorldLastEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/ScreenshotEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/TextureStitchEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/sound/PlaySoundEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/sound/PlaySoundSourceEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/sound/PlayStreamingSourceEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/sound/SoundEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/sound/SoundLoadEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/sound/SoundSetupEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/gui/ForgeGuiFactory.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/gui/NotificationModUpdateScreen.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/Attributes.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/BakedItemModel.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/BakedModelWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/BlockStateLoader.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/FancyMissingModel.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/ForgeBlockStateV1.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/ICustomModelLoader.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/IModel.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/ISmartVariant.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/ItemLayerModel.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/ItemTextureQuadConverter.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/MapModelState.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/ModelDynBucket.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/ModelFluid.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/ModelLoader.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/ModelLoaderRegistry.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/ModelStateComposition.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/MultiLayerModel.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/MultiModel.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/MultiModelState.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/PerspectiveMapWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/SimpleModelFontRenderer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/SimpleModelState.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/animation/Animation.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/animation/AnimationItemOverrideList.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/animation/AnimationModelBase.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/animation/AnimationTESR.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/animation/FastTESR.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/animation/ModelBlockAnimation.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/animation/package-info.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/b3d/B3DClip.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/b3d/B3DLoader.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/b3d/B3DModel.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/b3d/package-info.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/obj/OBJLoader.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/obj/OBJModel.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/obj/package-info.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/package-info.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/pipeline/BlockInfo.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/pipeline/ForgeBlockModelRenderer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/pipeline/IVertexConsumer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/pipeline/IVertexProducer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/pipeline/LightUtil.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/pipeline/QuadGatheringTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/pipeline/TRSRTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/pipeline/TransformerConsumer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/pipeline/UnpackedBakedQuad.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/pipeline/VertexBufferConsumer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/pipeline/VertexLighterFlat.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/pipeline/VertexLighterSmoothAo.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/pipeline/VertexTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/pipeline/package-info.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/resource/IResourceType.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/resource/ISelectiveResourceReloadListener.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/resource/ReloadRequirements.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/resource/SelectiveReloadStateHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/resource/VanillaResourceType.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/resource/package-info.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/settings/IKeyConflictContext.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/settings/KeyBindingMap.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/settings/KeyConflictContext.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/settings/KeyModifier.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/BiomeDictionary.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/BiomeManager.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/DimensionManager.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/DungeonHooks.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/EnumPlantType.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/FarmlandWaterManager.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/ForgeChunkManager.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/ForgeEarlyConfig.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/ForgeHooks.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/ForgeInternalHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/ForgeModContainer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/ForgeVersion.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/IMinecartCollisionHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/IPlantable.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/IRarity.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/IShearable.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/ISpecialArmor.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/MinecraftForge.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/UsernameCache.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/WorldSpecificSaveHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/WorldWorkerManager.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/animation/Event.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/animation/IEventHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/animation/ITimeValue.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/animation/TimeValues.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/brewing/AbstractBrewingRecipe.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/brewing/BrewingOreRecipe.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/brewing/BrewingRecipe.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/brewing/BrewingRecipeRegistry.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/brewing/IBrewingRecipe.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/brewing/VanillaBrewingRecipe.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/capabilities/Capability.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/capabilities/CapabilityDispatcher.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/capabilities/CapabilityInject.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/capabilities/CapabilityManager.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/capabilities/ICapabilityProvider.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/capabilities/ICapabilitySerializable.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/chunkio/ChunkIOExecutor.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/chunkio/ChunkIOProvider.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/chunkio/ChunkIOThreadPoolExecutor.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/chunkio/QueuedChunk.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/command/SelectorHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/command/SelectorHandlerManager.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/config/Config.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/config/ConfigCategory.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/config/ConfigElement.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/config/ConfigManager.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/config/Configuration.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/config/FieldWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/config/IFieldWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/config/ITypeAdapter.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/config/Property.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/config/TypeAdapters.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/crafting/CompoundIngredient.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/crafting/CraftingHelper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/crafting/IConditionFactory.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/crafting/IIngredientFactory.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/crafting/IRecipeContainer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/crafting/IRecipeFactory.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/crafting/IShapedRecipe.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/crafting/IngredientNBT.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/crafting/JsonContext.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/model/HiddenModelPart.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/model/IModelPart.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/model/IModelState.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/model/ITransformation.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/model/Models.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/model/TRSRTransformation.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/model/animation/AnimationStateMachine.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/model/animation/CapabilityAnimation.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/model/animation/Clips.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/model/animation/IAnimationStateMachine.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/model/animation/IClip.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/model/animation/IJoint.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/model/animation/IJointClip.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/model/animation/JointClips.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/network/DimensionMessageHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/network/FluidIdRegistryMessageHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/network/ForgeMessage.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/network/ForgeNetworkHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/network/ForgeRuntimeCodec.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/network/ServerToClientConnectionEstablishedHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/property/ExtendedBlockState.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/property/IExtendedBlockState.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/property/IUnlistedProperty.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/property/Properties.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/property/PropertyFloat.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/ticket/AABBTicket.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/ticket/ChunkTicketManager.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/ticket/ITicketGetter.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/ticket/ITicketManager.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/ticket/MultiTicketManager.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/ticket/SimpleTicket.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/util/BlockSnapshot.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/util/ChunkCoordComparator.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/util/CompoundDataFixer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/util/Constants.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/util/EnumHelper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/util/FakePlayer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/util/FakePlayerFactory.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/util/IDataFixerData.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/util/INBTSerializable.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/util/ITeleporter.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/util/JsonUtils.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/util/ModFixs.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/util/PacketUtil.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/util/RecipeMatcher.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/util/TextTable.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/util/WorldCapabilityData.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/energy/CapabilityEnergy.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/energy/EnergyStorage.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/energy/IEnergyStorage.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/AnvilUpdateEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/AttachCapabilitiesEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/CommandEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/DifficultyChangeEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/ForgeEventFactory.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/GameRuleChangeEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/LootTableLoadEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/RegistryEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/ServerChatEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/brewing/PlayerBrewedPotionEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/brewing/PotionBrewEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/enchanting/EnchantmentLevelSetEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/EntityEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/EntityJoinWorldEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/EntityMobGriefingEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/EntityMountEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/EntityStruckByLightningEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/EntityTravelToDimensionEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/PlaySoundAtEntityEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/ProjectileImpactEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/ThrowableImpactEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/item/ItemEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/item/ItemExpireEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/item/ItemTossEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/AnimalTameEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/BabyEntitySpawnEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/EnderTeleportEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/LivingAttackEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/LivingDamageEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/LivingDeathEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/LivingDestroyBlockEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/LivingDropsEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/LivingEntityUseItemEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/LivingEquipmentChangeEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/LivingEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/LivingExperienceDropEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/LivingFallEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/LivingHealEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/LivingHurtEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/LivingKnockBackEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/LivingPackSizeEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/LivingSetAttackTargetEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/LivingSpawnEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/LootingLevelEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/PotionColorCalculationEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/PotionEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/ZombieEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/minecart/MinecartCollisionEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/minecart/MinecartEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/minecart/MinecartInteractEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/minecart/MinecartUpdateEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/AdvancementEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/AnvilRepairEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/ArrowLooseEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/ArrowNockEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/AttackEntityEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/BonemealEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/CriticalHitEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/EntityItemPickupEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/FillBucketEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/ItemFishedEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/ItemTooltipEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/PlayerContainerEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/PlayerDestroyItemEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/PlayerDropsEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/PlayerEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/PlayerFlyableFallEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/PlayerInteractEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/PlayerPickupXpEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/PlayerSetSpawnEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/PlayerSleepInBedEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/PlayerWakeUpEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/SleepingLocationCheckEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/SleepingTimeCheckEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/UseHoeEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/furnace/FurnaceFuelBurnTimeEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/terraingen/BiomeEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/terraingen/ChunkGeneratorEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/terraingen/DecorateBiomeEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/terraingen/DeferredBiomeDecorator.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/terraingen/InitMapGenEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/terraingen/InitNoiseGensEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/terraingen/OreGenEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/terraingen/PopulateChunkEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/terraingen/SaplingGrowTreeEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/terraingen/TerrainGen.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/terraingen/WorldTypeEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/village/MerchantTradeOffersEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/village/VillageSiegeEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/world/BlockEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/world/ChunkDataEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/world/ChunkEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/world/ChunkWatchEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/world/ExplosionEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/world/GetCollisionBoxesEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/world/NoteBlockEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/world/WorldEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/BlockFluidBase.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/BlockFluidClassic.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/BlockFluidFinite.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/DispenseFluidContainer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/Fluid.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/FluidActionResult.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/FluidEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/FluidRegistry.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/FluidStack.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/FluidTank.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/FluidTankInfo.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/FluidUtil.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/IFluidBlock.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/IFluidTank.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/UniversalBucket.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/CapabilityFluidHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/FluidTankProperties.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/FluidTankPropertiesWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/IFluidHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/IFluidHandlerItem.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/IFluidTankProperties.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/ItemFluidContainer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/TileFluidHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/templates/EmptyFluidHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerConcatenate.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerFluidMap.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerItemStack.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerItemStackSimple.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/templates/VoidFluidHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/wrappers/BlockLiquidWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/wrappers/BlockWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/wrappers/FluidBlockWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/wrappers/FluidBucketWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/CustomModLoadingErrorDisplayException.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/DefaultGuiFactory.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/ExtendedServerListData.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/FMLClientHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/FMLConfigGuiFactory.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/FMLFileResourcePack.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/FMLFolderResourcePack.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/GuiAccessDenied.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/GuiBackupFailed.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/GuiConfirmation.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/GuiCustomModLoadingErrorScreen.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/GuiDupesFound.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/GuiErrorBase.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/GuiModList.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/GuiModsMissing.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/GuiModsMissingForServer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/GuiMultipleModsErrored.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/GuiNotification.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/GuiOldSaveLoadConfirm.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/GuiScrollingList.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/GuiSlotModList.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/GuiSortingProblem.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/GuiWrongMinecraft.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/IDisplayableError.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/IModGuiFactory.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/SplashProgress.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/config/ConfigGuiType.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/config/DummyConfigElement.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/config/GuiButtonExt.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/config/GuiCheckBox.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/config/GuiConfig.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/config/GuiConfigEntries.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/config/GuiEditArray.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/config/GuiEditArrayEntries.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/config/GuiMessageDialog.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/config/GuiSelectString.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/config/GuiSelectStringEntries.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/config/GuiSlider.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/config/GuiUnicodeGlyphButton.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/config/GuiUtils.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/config/HoverChecker.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/config/IConfigElement.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/event/ConfigChangedEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/registry/ClientRegistry.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/registry/IRenderFactory.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/registry/RenderingRegistry.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/API.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/AutomaticEventSubscriber.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/CertificateHelper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/ClassNameUtils.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/DummyModContainer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/DuplicateModsFoundException.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/EnhancedRuntimeException.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/FMLCommonHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/FMLContainer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/FMLContainerHolder.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/FMLContextQuery.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/FMLLog.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/FMLModContainer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/ICrashCallable.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/IEntitySelectorFactory.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/IFMLHandledException.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/IFMLSidedHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/IFuelHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/ILanguageAdapter.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/IWorldGenerator.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/InjectedModContainer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/LoadController.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/Loader.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/LoaderException.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/LoaderExceptionModCrash.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/LoaderState.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/MCPDummyContainer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/MetadataCollection.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/MinecraftDummyContainer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/MissingModsException.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/Mod.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/ModAPIManager.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/ModClassLoader.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/ModContainer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/ModContainerFactory.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/ModMetadata.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/MultipleModsErrored.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/ObfuscationReflectionHelper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/Optional.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/ProgressManager.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/ProxyInjector.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/SaveInspectionHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/SidedProxy.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/StartupQuery.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/TracingPrintStream.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/WorldAccessContainer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/WrongMinecraftVersionException.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/ZipperUtil.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/ASMTransformerWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/FMLSanityChecker.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/ReobfuscationMarker.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/AccessTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/DeobfuscationTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/EventSubscriberTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/EventSubscriptionTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/FieldRedirectTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/ItemBlockSpecialTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/ItemBlockTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/ItemStackTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/LWJGLTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/MarkerTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/ModAPITransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/ModAccessTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/PatchingTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/PotionEffectTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/SideTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/SoundEngineFixTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/TerminalTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/deobf/FMLRemappingAdapter.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/deobf/LZMAInputSupplier.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/discovery/ASMDataTable.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/discovery/ContainerType.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/discovery/DirectoryDiscoverer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/discovery/ITypeDiscoverer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/discovery/JarDiscoverer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/discovery/ModCandidate.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/discovery/ModDiscoverer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/discovery/asm/ASMModParser.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/discovery/asm/ModAnnotation.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/discovery/asm/ModAnnotationVisitor.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/discovery/asm/ModClassVisitor.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/discovery/asm/ModFieldVisitor.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/discovery/asm/ModMethodVisitor.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/discovery/json/ASMInfo.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/discovery/json/JsonAnnotationLoader.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/event/FMLConstructionEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/event/FMLEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/event/FMLFingerprintViolationEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/event/FMLInitializationEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/event/FMLInterModComms.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/event/FMLLoadCompleteEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/event/FMLLoadEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/event/FMLModDisabledEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/event/FMLModIdMappingEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/event/FMLPostInitializationEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/event/FMLPreInitializationEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/event/FMLServerAboutToStartEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/event/FMLServerStartedEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/event/FMLServerStartingEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/event/FMLServerStoppedEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/event/FMLServerStoppingEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/event/FMLStateEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/eventhandler/ASMEventHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/eventhandler/Cancelable.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/eventhandler/Event.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/eventhandler/EventBus.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/eventhandler/EventListenerFactory.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/eventhandler/EventPriority.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/eventhandler/FMLThrowingEventBus.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/eventhandler/GenericEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/eventhandler/IContextSetter.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/eventhandler/IEventExceptionHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/eventhandler/IEventListener.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/eventhandler/IGenericEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/eventhandler/ListenerList.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/eventhandler/SubscribeEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/gameevent/InputEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/gameevent/PlayerEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/gameevent/TickEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/launcher/FMLDeobfTweaker.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/launcher/FMLInjectionAndSortingTweaker.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/launcher/FMLServerTweaker.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/launcher/FMLTweaker.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/launcher/Yggdrasil.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/ByteBufUtils.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/FMLEmbeddedChannel.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/FMLEventChannel.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/FMLIndexedMessageToMessageCodec.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/FMLNetworkEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/FMLNetworkException.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/FMLOutboundHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/IGuiHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/NetworkCheckHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/NetworkEventFiringHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/NetworkHandshakeEstablished.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/NetworkRegistry.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/PacketLoggingHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/handshake/ChannelRegistrationHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeClientState.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeCodec.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeMessage.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeServerState.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/handshake/HandshakeInjector.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/handshake/HandshakeMessageHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/handshake/IHandshakeState.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/handshake/NetworkDispatcher.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/internal/EntitySpawnHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/internal/FMLMessage.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/internal/FMLNetworkHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/internal/FMLProxyPacket.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/internal/FMLRuntimeCodec.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/internal/HandshakeCompletionHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/internal/NetworkModHolder.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/internal/OpenGuiHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/simpleimpl/IMessage.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/simpleimpl/IMessageHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/simpleimpl/MessageContext.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleChannelHandlerWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleIndexedCodec.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleNetworkWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/patcher/ClassPatch.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/patcher/ClassPatchManager.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/patcher/GenDiffSet.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/registry/EntityEntry.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/registry/EntityEntryBuilder.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/registry/EntityRegistry.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/registry/ExistingSubstitutionException.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/registry/ForgeRegistries.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/registry/GameRegistry.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/registry/IEntityAdditionalSpawnData.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/registry/IThrowableEntity.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/registry/ItemStackHolderInjector.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/registry/ItemStackHolderRef.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/registry/VillagerRegistry.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/thread/SidedThreadGroup.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/thread/SidedThreadGroups.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/toposort/ModSorter.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/toposort/ModSortingException.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/toposort/TopologicalSort.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/versioning/ArtifactVersion.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/versioning/ComparableVersion.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/versioning/DefaultArtifactVersion.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/versioning/DependencyParser.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/versioning/InvalidVersionSpecificationException.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/versioning/Restriction.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/versioning/VersionParser.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/versioning/VersionRange.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/CoreModManager.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/FMLCorePlugin.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/FMLInjectionData.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/FMLLaunchHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/FMLRelaunchLog.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/FileListHelper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/IFMLCallHook.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/IFMLLoadingPlugin.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/MixinBooterPlugin.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/ReflectionHelper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/ServerLaunchWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/Side.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/SideOnly.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/libraries/Artifact.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/libraries/LibraryManager.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/libraries/LinkRepository.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/libraries/MemoryModList.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/libraries/ModList.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/libraries/Repository.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/libraries/SnapshotJson.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/ByteBufferSeekableSource.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/Checksum.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/DebugDiffWriter.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/Delta.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/DiffWriter.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/GDiffPatcher.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/GDiffWriter.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/PatchException.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/RandomAccessFileSeekableSource.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/SeekableSource.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/server/FMLServerHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/CapabilityItemHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/IItemHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/IItemHandlerModifiable.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/ItemHandlerHelper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/ItemStackHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/SlotItemHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/VanillaDoubleChestItemHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/VanillaHopperItemHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/VanillaInventoryCodeHooks.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/wrapper/CombinedInvWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/wrapper/EmptyHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/wrapper/EntityArmorInvWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/wrapper/EntityEquipmentInvWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/wrapper/EntityHandsInvWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/wrapper/InvWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/wrapper/PlayerArmorInvWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/wrapper/PlayerInvWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/wrapper/PlayerMainInvWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/wrapper/PlayerOffhandInvWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/wrapper/RangedWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/wrapper/SidedInvWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/oredict/DyeUtils.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/oredict/OreDictionary.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/oredict/OreIngredient.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/oredict/RecipeSorter.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/oredict/ShapedOreRecipe.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/oredict/ShapelessOreRecipe.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/registries/DataSerializerEntry.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/registries/ForgeRegistry.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/registries/GameData.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/registries/IForgeRegistry.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/registries/IForgeRegistryEntry.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/registries/IForgeRegistryInternal.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/registries/IForgeRegistryModifiable.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/registries/ILockableRegistry.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/registries/IRegistryDelegate.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/registries/NamespacedDefaultedWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/registries/NamespacedWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/registries/ObjectHolderRef.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/registries/ObjectHolderRegistry.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/registries/RegistryBuilder.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/registries/RegistryDelegate.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/registries/RegistryManager.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/ForgeTimeTracker.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/command/ChunkGenWorker.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/command/CommandDimensions.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/command/CommandEntity.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/command/CommandGenerate.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/command/CommandSetDimension.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/command/CommandTps.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/command/CommandTrack.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/command/CommandTreeBase.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/command/CommandTreeHelp.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/command/ForgeCommand.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/command/TextComponentHelper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/command/package-info.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/console/ConsoleCommandCompleter.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/console/TerminalHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/permission/DefaultPermissionHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/permission/DefaultPermissionLevel.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/permission/IPermissionHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/permission/PermissionAPI.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/permission/context/AreaContext.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/permission/context/BlockPosContext.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/permission/context/Context.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/permission/context/ContextKey.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/permission/context/ContextKeys.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/permission/context/IContext.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/permission/context/PlayerContext.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/permission/context/TargetContext.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/permission/context/WorldContext.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/permission/context/package-info.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/permission/package-info.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/terminalconsole/HighlightErrorConverter.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/terminalconsole/MinecraftFormattingConverter.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/terminalconsole/TerminalConsoleAppender.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/terminalconsole/package-info.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/terminalconsole/util/LoggerNamePatternSelector.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/terminalconsole/util/package-info.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/timings/ForgeTimings.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/timings/TimeTracker.java (100%) rename {src => module/forge/src}/main/java/paulscode/sound/codecs/CodecIBXM.java (100%) rename {src => module/forge/src}/main/resources/META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat (100%) rename {src => module/forge/src}/main/resources/assets/fml/textures/gui/forge.png (100%) rename {src => module/forge/src}/main/resources/assets/fml/textures/gui/icons.png (100%) rename {src => module/forge/src}/main/resources/assets/forge/blockstates/dynbucket.json (100%) rename {src => module/forge/src}/main/resources/assets/forge/lang/README.txt (100%) rename {src => module/forge/src}/main/resources/assets/forge/lang/en_pt.lang (100%) rename {src => module/forge/src}/main/resources/assets/forge/lang/en_us.lang (100%) rename {src => module/forge/src}/main/resources/assets/forge/lang/es_es.lang (100%) rename {src => module/forge/src}/main/resources/assets/forge/lang/fr_fr.lang (100%) rename {src => module/forge/src}/main/resources/assets/forge/lang/ja_jp.lang (100%) rename {src => module/forge/src}/main/resources/assets/forge/lang/ko_kr.lang (100%) rename {src => module/forge/src}/main/resources/assets/forge/lang/ru_ru.lang (100%) rename {src => module/forge/src}/main/resources/assets/forge/lang/zh_cn.lang (100%) rename {src => module/forge/src}/main/resources/assets/forge/lang/zh_tw.lang (100%) rename {src => module/forge/src}/main/resources/assets/forge/models/item/bucket.json (100%) rename {src => module/forge/src}/main/resources/assets/forge/models/item/bucket_milk.json (100%) rename {src => module/forge/src}/main/resources/assets/forge/textures/gui/version_check_icons.png (100%) rename {src => module/forge/src}/main/resources/assets/forge/textures/items/bucket_fluid.png (100%) rename {src => module/forge/src}/main/resources/assets/forge/textures/items/vanilla_bucket_cover_mask.png (100%) rename {src => module/forge/src}/main/resources/forge.exc (100%) rename {src => module/forge/src}/main/resources/forge.srg (100%) rename {src => module/forge/src}/main/resources/forge_at.cfg (100%) rename {src => module/forge/src}/main/resources/forge_logo.png (100%) rename {src => module/forge/src}/main/resources/log4j2.xml (100%) rename {src => module/forge/src}/main/resources/log4j2_server.xml (100%) rename {src => module/forge/src}/main/resources/logging.properties (100%) rename {src => module/forge/src}/main/resources/mcplogo.png (100%) rename {src => module/forge/src}/main/resources/mcpmod.info (100%) rename {src => module/forge/src}/main/resources/pack.mcmeta (100%) rename {src => module/forge/src}/main/resources/url.png (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/PotionEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/block/BasePlaceEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/block/FarmlandTrampleEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/block/FarmlandWaterTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/block/MaterialFogColorTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/block/NeighborNotifyEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/block/ParticleEffectsTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/block/PathNodeTypeTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/block/PlaceEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/block/PortalSpawnEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/block/SlipperinessTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/block/StickyBlockTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/block/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/chat/ClientChatEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/chat/ClientCommandTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/chat/CommandTreeBaseTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/chat/EntitySelectorFactoryTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/chat/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/CustomTextureAtlasSpriteTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/FOVModifierEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/SearchableCreativeTabTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/gui/ContainerDrawForegroundEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/gui/TooltipColorEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/model/AnimatedModelTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/model/BlockstateRetextureTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/model/ForgeBlockStatesLoaderTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/model/ItemLayerModelTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/model/ItemModelConflictTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/model/ItemModelGenerationTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/model/ModelBakeEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/model/ModelFluidTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/model/ModelLoaderRegistryTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/model/MultiLayerModelTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/model/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/rendering/FastTESRTransparentTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/rendering/ItemTESRTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/rendering/VertexBufferNormalTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/rendering/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/BlockEntityUpdateTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/EntityTravelToDimensionEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/GetCollisionBoxesEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/ProjectileImpactEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/living/AnimalTameEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/living/AttackEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/living/BabyEntitySpawnEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/living/CheckSpawnEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/living/CustomSpawnPlacementTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/living/DamageEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/living/EquipmentChangeEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/living/KnockBackEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/living/MobGriefingEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/living/SpecialSpawnTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/living/VillagerProfessionTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/living/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/player/CriticalHitEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/player/DamageReworkTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/player/ItemPickupEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/player/PlayerInteractEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/player/PlayerSetSpawnTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/player/ReachDistanceAttributeTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/player/SwimSpeedAttributeTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/player/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/fluid/ColoredFluidTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/fluid/CreateFluidSourceEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/fluid/DynBucketTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/fluid/FluidPlaceBlockEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/fluid/FluidPlacementTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/fluid/ItemFluidHandlerTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/fluid/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/AnytimeSleepingTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/BrewingRecipeRegistryTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/ConstantLoadingTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/CraftingSystemTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/DifficultyChangeEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/DynamicBannerTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/EnchantmentLevelSetEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/FurnaceFuelBurnTimeEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/GiveItemToPlayerTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/InputUpdateEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/NoBedSleepingTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/PotionRegistryTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/RecipeMatchingTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/advancement/AdvancementCriterionTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/advancement/AdvancementEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/advancement/AdvancementsPaginationTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/advancement/OredictTriggerTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/advancement/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/loot/LootContextTweaksTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/loot/LootTableLoadEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/loot/LootTableTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/loot/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/item/BonemealEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/item/CanApplyAtEnchantingTableTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/item/CanDestroyBlocksInCreativeTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/item/ContinuousUseItemTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/item/CustomRarityTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/item/HorseArmorTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/item/IsBookEnchantableTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/item/ItemFishedEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/item/MapDataTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/item/MendingRepairTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/item/NBTShareTagTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/item/OnItemUseFirstTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/item/PotionCurabilityTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/item/PotionShouldRenderTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/item/ShieldTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/item/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/misc/EnumPlantTypeTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/misc/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/mod/CapabilityTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/mod/ClientLoadingExceptionTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/mod/ConfigAnnotationTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/mod/ObjectHolderAnnotationTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/mod/PermissionTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/mod/RegistryOverrideTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/mod/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/network/BigNetworkMessageTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/network/TrackingTargetTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/network/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/util/ModNameTooltip.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/util/RotatingWrench.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/util/TextureDumper.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/util/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/village/MerchantTradeOffersEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/village/VillageSiegeEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/world/ChunkCapabilityTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/world/ChunkWatchEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/world/DecorateEventDebug.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/world/SpawnDimensionTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/world/TileEntityLoadingTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/world/WorldCapabilityTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/world/WorldProviderCanSleepAtTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/world/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/common/eventhandler/EventBusTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/common/eventhandler/impl/AbnormalListeners.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/common/eventhandler/impl/ExampleEvent.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/common/eventhandler/impl/InstanceListeners.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/common/eventhandler/impl/StaticListeners.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/common/registry/BlockStateMappingsTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/common/registry/DummyBlockReplacementTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/common/registry/ForgeTestRunner.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/common/registry/FreezingTests.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/common/registry/ItemBlockSubstitutionRemoveRestoreTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/common/registry/RegistryTestSuite.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/common/registry/SubstitutionInjectionTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/common/registry/SubstitutionRemoveRestoreTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/common/registry/VanillaRegistryTests.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/debug/FaultyCoreMod.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/test/DependencyParserTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/test/ForgeNetworkTestMod.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/test/SpecialSpawnEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/test/TestNetStuff.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/test/networkhandshake/TestNetworkHandshake.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetHandler1.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetHandler2.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetTestMessage1.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetTestMessage2.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetTester.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/test/BiomeSpawnableListTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/test/BufferBuilderExpansionTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/test/ConfigurationTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/test/EnumHelperTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/test/SelectorHandlerTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/test/SliderConfigElementTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/test/TestAnnotationParser.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/test/TextTableTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/test/package-info.java (100%) rename {src => module/forge/src}/test/resources/assets/advancementcriteriontest/advancements/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a1/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a10/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a11/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a12/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a13/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a14/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a15/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a16/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a17/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a18/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a19/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a2/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a20/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a21/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a22/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a23/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a24/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a25/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a26/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a27/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a28/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a29/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a3/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a30/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a31/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a32/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a33/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a34/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a35/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a36/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a37/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a38/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a39/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a4/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a40/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a41/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a42/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a43/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a44/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a45/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a46/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a47/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a48/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a49/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a5/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a50/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a51/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a52/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a53/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a54/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a55/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a56/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a57/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a58/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a59/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a6/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a60/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a61/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a62/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a63/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a64/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a7/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a8/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a9/root.json (100%) rename {src => module/forge/src}/test/resources/assets/collisionboxexeventtest/blockstates/box_block.json (100%) rename {src => module/forge/src}/test/resources/assets/config_test/lang/en_US.lang (100%) rename {src => module/forge/src}/test/resources/assets/constantloadingtest/test/_constants.json (100%) rename {src => module/forge/src}/test/resources/assets/crafting_system_test/recipes/_factories.json (100%) rename {src => module/forge/src}/test/resources/assets/crafting_system_test/recipes/conditions_property_not_array.json (100%) rename {src => module/forge/src}/test/resources/assets/crafting_system_test/recipes/oak_planks_from_logs.json (100%) rename {src => module/forge/src}/test/resources/assets/custom_sprite_test/blockstates/custom_sprite_block.json (100%) rename {src => module/forge/src}/test/resources/assets/custom_sprite_test/models/block/custom_sprite_block.json (100%) rename {src => module/forge/src}/test/resources/assets/dynbuckettest/blockstates/simpletank.json (100%) rename {src => module/forge/src}/test/resources/assets/farmlandwatertest/blockstates/test_block.json (100%) rename {src => module/forge/src}/test/resources/assets/fluidadditionalfields/blockstates/slime.json (100%) rename {src => module/forge/src}/test/resources/assets/fluidadditionalfields/textures/slime_flow.png (100%) rename {src => module/forge/src}/test/resources/assets/fluidadditionalfields/textures/slime_flow.png.mcmeta (100%) rename {src => module/forge/src}/test/resources/assets/fluidadditionalfields/textures/slime_overlay.png (100%) rename {src => module/forge/src}/test/resources/assets/fluidadditionalfields/textures/slime_still.png (100%) rename {src => module/forge/src}/test/resources/assets/fluidadditionalfields/textures/slime_still.png.mcmeta (100%) rename {src => module/forge/src}/test/resources/assets/fogcolorinsidematerialtest/blockstates/slime.json (100%) rename {src => module/forge/src}/test/resources/assets/fogcolorinsidematerialtest/pack.mcmeta (100%) rename {src => module/forge/src}/test/resources/assets/fogcolorinsidematerialtest/test_fluid.json (100%) rename {src => module/forge/src}/test/resources/assets/fogcolorinsidematerialtest/textures/slime_flow.png (100%) rename {src => module/forge/src}/test/resources/assets/fogcolorinsidematerialtest/textures/slime_flow.png.mcmeta (100%) rename {src => module/forge/src}/test/resources/assets/fogcolorinsidematerialtest/textures/slime_overlay.png (100%) rename {src => module/forge/src}/test/resources/assets/fogcolorinsidematerialtest/textures/slime_still.png (100%) rename {src => module/forge/src}/test/resources/assets/fogcolorinsidematerialtest/textures/slime_still.png.mcmeta (100%) rename {src => module/forge/src}/test/resources/assets/forge/blockstates/dynbottle.json (100%) rename {src => module/forge/src}/test/resources/assets/forge/recipes/_constants.json (100%) rename {src => module/forge/src}/test/resources/assets/forge/recipes/ore_shaped.json (100%) rename {src => module/forge/src}/test/resources/assets/forge/recipes/shapeless.json (100%) rename {src => module/forge/src}/test/resources/assets/forge/recipes/shapeless_constant.json (100%) rename {src => module/forge/src}/test/resources/assets/forge/recipes/shapeless_damageable.json (100%) rename {src => module/forge/src}/test/resources/assets/forge/recipes/shapeless_ore.json (100%) rename {src => module/forge/src}/test/resources/assets/forge/recipes/shapeless_wildcard.json (100%) rename {src => module/forge/src}/test/resources/assets/forge/textures/blocks/milk_flow.png (100%) rename {src => module/forge/src}/test/resources/assets/forge/textures/blocks/milk_flow.png.mcmeta (100%) rename {src => module/forge/src}/test/resources/assets/forge/textures/blocks/milk_still.png (100%) rename {src => module/forge/src}/test/resources/assets/forge/textures/blocks/milk_still.png.mcmeta (100%) rename {src => module/forge/src}/test/resources/assets/forgeblockstatesloader/blockstates/cobblestone_wall.json (100%) rename {src => module/forge/src}/test/resources/assets/forgeblockstatesloader/blockstates/mossy_cobblestone_wall.json (100%) rename {src => module/forge/src}/test/resources/assets/forgeblockstatesloader/models/block/wall_connect.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugcustomslimeblock/blockstates/custom_slime_block.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugcustomslimeblock/lang/en_US.lang (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugcustomslimeblock/models/block/blue_slime_block.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugcustomslimeblock/models/block/obsidian_slime_block.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugcustomslimeblock/models/item/blue_slime_block.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugcustomslimeblock/models/item/obsidian_slime_block.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugcustomslimeblock/textures/blocks/blue_slime_block.png (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugcustomslimeblock/textures/blocks/obsidian_slime_block.png (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugfluidplacement/blockstates/finite_fluid_block.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugitemlayermodel/blockstates/test_item.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugitemtile/blockstates/custom_model_block.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelanimation/armatures/block/engine_ring.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelanimation/armatures/block/rotatest.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelanimation/asms/block/chest.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelanimation/asms/block/engine.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelanimation/asms/block/engine2.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelanimation/asms/block/rotatest.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelanimation/blockstates/rotatest.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelanimation/blockstates/test_animation_block.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelanimation/models/block/engine.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelanimation/models/block/engine_ring.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelanimation/models/block/rotatest.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelfluid/blockstates/test_fluid_block.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/blockstates/custom_model_block.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_custom_data_block.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_direction_block.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_direction_eye.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_dynamic_eye.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_tesseract_block.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_vertex_coloring1.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_vertex_coloring2.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/models/block/chest.b3d (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/models/block/direction_test.mtl (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/models/block/direction_test.obj (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/models/block/eye.mtl (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/models/block/eye.obj (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/models/block/fancy_fence.mtl (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/models/block/fancy_fence.obj (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/models/block/tesseract.mtl (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/models/block/tesseract.obj (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/models/block/untitled2.b3d (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/models/block/vertex_coloring.mtl (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/models/block/vertex_coloring.obj (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_arrow.png (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_arrow_top.png (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_back.png (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_front.png (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/textures/eye.png (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/textures/eye128.png (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/textures/texture.png (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmultilayermodel/blockstates/test_layer_block.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugnobedsleeping/models/item/sleeping_pill.json (100%) rename {src => module/forge/src}/test/resources/assets/furnacefuelburntimeeventtest/models/item/flammable_gold_shovel.json (100%) rename {src => module/forge/src}/test/resources/assets/furnacefuelburntimeeventtest/models/item/unburnable_wood_shovel.json (100%) rename {src => module/forge/src}/test/resources/assets/horse_armor_test/lang/en_US.lang (100%) rename {src => module/forge/src}/test/resources/assets/horse_armor_test/models/item/test_armor.json (100%) rename {src => module/forge/src}/test/resources/assets/horse_armor_test/textures/entity/horse/armor/test.png (100%) rename {src => module/forge/src}/test/resources/assets/horse_armor_test/textures/items/test_armor.png (100%) rename {src => module/forge/src}/test/resources/assets/item_can_destroy_blocks_in_creative_test/models/item/item_test.json (100%) rename {src => module/forge/src}/test/resources/assets/item_model_conflict_test/blockstates/test.json (100%) rename {src => module/forge/src}/test/resources/assets/item_model_conflict_test/models/block/test.json (100%) rename {src => module/forge/src}/test/resources/assets/item_model_conflict_test/models/item/test.json (100%) rename {src => module/forge/src}/test/resources/assets/item_model_generation_test/models/item/animation_test.json (100%) rename {src => module/forge/src}/test/resources/assets/item_model_generation_test/models/item/intersection_test.json (100%) rename {src => module/forge/src}/test/resources/assets/item_model_generation_test/models/item/opacity_test.json (100%) rename {src => module/forge/src}/test/resources/assets/item_model_generation_test/models/item/overlap_test.json (100%) rename {src => module/forge/src}/test/resources/assets/item_model_generation_test/models/item/pattern_test.json (100%) rename {src => module/forge/src}/test/resources/assets/item_model_generation_test/textures/items/animation_test.png (100%) rename {src => module/forge/src}/test/resources/assets/item_model_generation_test/textures/items/animation_test.png.mcmeta (100%) rename {src => module/forge/src}/test/resources/assets/item_model_generation_test/textures/items/intersection_test.png (100%) rename {src => module/forge/src}/test/resources/assets/item_model_generation_test/textures/items/opacity_test.png (100%) rename {src => module/forge/src}/test/resources/assets/item_model_generation_test/textures/items/overlap_test.png (100%) rename {src => module/forge/src}/test/resources/assets/item_model_generation_test/textures/items/pattern_test.png (100%) rename {src => module/forge/src}/test/resources/assets/loot_context_tweaks_test/advancements/test/root.json (100%) rename {src => module/forge/src}/test/resources/assets/loottable_load_event_test/loot_tables/chests/custom_spawn_bonus_chest.json (100%) rename {src => module/forge/src}/test/resources/assets/nbtsharetagitemtest/models/item/nbt_share_tag_item.json (100%) rename {src => module/forge/src}/test/resources/assets/onitemusefirsttest/models/item/test_item.json (100%) rename {src => module/forge/src}/test/resources/assets/oredict_predicate/advancements/recipes/wood_unlock_tnt.json (100%) rename {src => module/forge/src}/test/resources/assets/professiontest/textures/entity/test_villager.png (100%) rename {src => module/forge/src}/test/resources/assets/professiontest/textures/entity/zombie_test_villager.png (100%) rename {src => module/forge/src}/test/resources/assets/recipetest/recipes/tool_complex.json (100%) rename {src => module/forge/src}/test/resources/assets/recipetest/recipes/tool_simple.json (100%) rename {src => module/forge/src}/test/resources/assets/shield_test/lang/en_US.lang (100%) rename {src => module/forge/src}/test/resources/assets/shield_test/models/item/diamond_shield.json (100%) rename {src => module/forge/src}/test/resources/assets/shield_test/models/item/diamond_shield_blocking.json (100%) rename {src => module/forge/src}/test/resources/assets/wrenchrotatedebug/models/item/test_wrench.json (100%) rename {src => module/forge/src}/test/resources/assets/wrenchrotatedebug/textures/items/test_wrench.png (100%) rename {src => module/forge/src}/test/resources/mcmod.info (100%) rename {projects => module}/kirino (100%) rename {src => module/mixinbooter/src}/main/java/zone/rong/mixinbooter/Context.java (100%) rename {src => module/mixinbooter/src}/main/java/zone/rong/mixinbooter/IEarlyMixinLoader.java (100%) rename {src => module/mixinbooter/src}/main/java/zone/rong/mixinbooter/ILateMixinLoader.java (100%) rename {src => module/mixinbooter/src}/main/java/zone/rong/mixinbooter/IMixinConfigHijacker.java (100%) delete mode 100644 projects/cleanroom/build.gradle delete mode 100644 projects/mcp/build.gradle delete mode 100644 projects/minecraft/build.gradle diff --git a/.gitignore b/.gitignore index 7032bab06..3b84fb0a4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,18 +1,15 @@ /.idea/* /.run/ /.gradle/ -/projects/cleanroom/** -/projects/minecraft/** -/projects/mcp/** -/projects/cleanroom/!build.gradle -/projects/minecraft/!build.gradle -/projects/mcp/!build.gradle +/run/ +# Patched Minecraft source +/module/minecraft/ /buildSrc/.gradle/ /buildSrc/build/ /buildSrc/out/ /logs/ build/ version.txt -src/main/java/com/cleanroommc/common/CleanroomVersion.java +module/cleanroom/src/main/java/com/cleanroommc/common/CleanroomVersion.java !/.idea/icon.svg diff --git a/.gitmodules b/.gitmodules index 9d48f6ed7..65e31ed30 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "projects/kirino"] - path = projects/kirino + path = module/kirino url = https://github.com/CleanroomMC/Kirino-Engine.git diff --git a/README.md b/README.md index ed409d1a2..a0d7351d3 100644 --- a/README.md +++ b/README.md @@ -81,9 +81,9 @@ Some mods are obsoleted or need extra handle. See [wiki](https://cleanroommc.com ## Development Tips: -- Only modify `projects/cleanroom/src/` directory if you want to change vanilla +- Only modify `module/minecraft/src/main/java/` directory if you want to change vanilla - Run `gradlew genPatches` before commit, or the changes won't exist -- Modifications on `src/` doesn't need generating patches +- Modifications on the other `module/` directories don't need generating patches - [Tips from Forge](https://github.com/MinecraftForge/MinecraftForge/wiki/If-you-want-to-contribute-to-Forge) are still apply, keep the patches clean! - The current patches is full of useless hunks after we switched to VineFlower, we encourage contributors to clean up these patches manually. diff --git a/build.gradle b/build.gradle index 0b50d6861..043f81331 100644 --- a/build.gradle +++ b/build.gradle @@ -1,31 +1,16 @@ -buildscript { - repositories { - mavenLocal() - maven { - name = "Outlands" - url = 'https://maven.outlands.top/releases/' - } - mavenCentral() - gradlePluginPortal() - } - dependencies { - classpath 'top.outlands.gradle:ForgeGradle:6.0.55' - classpath('top.outlands:artifactural:3.0.4') { - transitive = false - } - } -} - -plugins { - id "org.jetbrains.gradle.plugin.idea-ext" version "1.3" - //id "com.palantir.git-version" version "4.2.0" -} -apply plugin: 'com.palantir.git-version' // Declared in buildSrc/build.gradle - import com.cleanroommc.gradle.helpers.ProjectConstants import com.cleanroommc.gradle.helpers.tasks.Util import com.palantir.gradle.gitversion.VersionDetails +plugins { + id 'java-library' + id 'idea' + id 'maven-publish' + id 'com.cleanroommc.gradle' version '0.0.1' +} + +// buildSrc path +apply plugin: 'com.palantir.git-version' def props = project.properties def sysProps = System.getProperties() @@ -48,28 +33,302 @@ println "Setting up Cleanroom $version" if (project.hasProperty('run_number')) println("On GitHub runs #${props.run_number}") println "Java: ${ -> sysProps['java.version']} | JVM: ${ -> sysProps['java.vm.version']} | Vendor: ${ -> sysProps['java.vendor']} | Architecture: ${ -> sysProps['os.arch']}" -// Initialize buildSrc -Util.init() +java { + toolchain.languageVersion = JavaLanguageVersion.of(25) +} tasks.withType(JavaCompile).configureEach { - options.compilerArgs = options.compilerArgs + ProjectConstants.COMPILER_JVM_ARGUMENTS + options.compilerArgs += ProjectConstants.COMPILER_JVM_ARGUMENTS options.encoding = 'UTF-8' } -idea.project.settings.compiler.javac.javacAdditionalOptions = ProjectConstants.COMPILER_JVM_ARGUMENTS.join(' ') +sourceSets { + main { + java { + srcDirs = [ + "$rootDir/module/cleanroom/src/main/java", + "$rootDir/module/forge/src/main/java", + "$rootDir/module/mixinbooter/src/main/java", + "$rootDir/module/minecraft/src/main/java", + "$rootDir/module/kirino/src/main/java" + ] + } + resources { + srcDirs = [ + // module/cleanroom has no resources yet; Gradle ignores missing dirs. + "$rootDir/module/cleanroom/src/main/resources", + "$rootDir/module/forge/src/main/resources", + "$rootDir/module/kirino/src/main/resources" + ] + } + } + test { + compileClasspath += sourceSets.main.runtimeClasspath + runtimeClasspath += sourceSets.main.runtimeClasspath + java { + srcDirs = [ + "$rootDir/module/cleanroom/src/test/java", + "$rootDir/module/forge/src/test/java", + "$rootDir/module/kirino/src/test/java" + ] + } + resources { + srcDirs = [ + "$rootDir/module/cleanroom/src/test/resources", + "$rootDir/module/forge/src/test/resources" + ] + } + } +} + +cleanroom { + patchDev { + minecraft { + source.set(cleanroom.localCacheDirectory.map { it.dir('sourceSets/mcp/sources').asFile }) + dependsOn 'remapSrg2Mcp' + } + } +} + +afterEvaluate { + def patchedSrc = file('module/minecraft/src/main/java') + + sourceSets.named('minecraftPatchDev') { + java.srcDirs = [patchedSrc] + } + + // TODO + // The patch-dev source set only feeds diff/copy tasks and can't compile standalone + tasks.named('compileMinecraftPatchDevJava') { enabled = false } + tasks.named('minecraftPatchDevClasses') { enabled = false } + tasks.named('processMinecraftPatchDevResources') { enabled = false } + + tasks.named('copyMinecraftToSourceSet') { + onlyIf { + !patchedSrc.exists() || (patchedSrc.listFiles()?.length ?: 0) == 0 + } + } +} + +repositories { + mavenCentral() + maven { + name = 'Cleanroom Maven' + url = 'https://repo.cleanroommc.com/releases/' + } + maven { + url = 'https://maven.arcseekers.com/releases/' + } + maven { + name = 'Outlands' + url = 'https://maven.outlands.top/releases' + } +} + +// TODO: fix on CG side +def mojangRepo = repositories.findByName('Mojang') +if (mojangRepo != null) { + repositories.remove(mojangRepo) + repositories.add(mojangRepo) +} + +ext { + lwjglArch = Util.getCurrentArch() + // Do not change the order unless it is required so + lwjglLibraries = [ + [ + 'lwjgl-glfw', 'lwjgl-jemalloc', 'lwjgl-openal', + 'lwjgl-opengl', 'lwjgl-stb', 'lwjgl-tinyfd', 'lwjgl' + ], + + [ + 'natives-linux-arm64', 'natives-linux-arm32', 'natives-linux', + 'natives-macos-arm64', 'natives-macos', + 'natives-windows-arm64', 'natives-windows-x86', 'natives-windows' + ] + ] +} + +configurations { + configureEach { // LWJGL2 isn't friendly with us, so pye pye + exclude group: 'org.lwjgl.lwjgl' + exclude group: 'com.ibm.icu', module: 'icu4j-core-mojang' + } + + // Don't pull all libraries, if we're missing something, add it to the installer list so the installer knows to download it + installer { + transitive = false + } + api.extendsFrom(installer) + + lwjglNatives { + transitive = false + } + + // Make the joint `main` compile see the Minecraft libraries resolved by CleanroomGradle + implementation.extendsFrom(vanilla) +} + +// TODO: entire dep tree needs to be re-evaluated +dependencies { + mcpConfig 'de.oceanlabs.mcp:mcp_config:1.12.2-20260220.202731' + + // TODO + // LWJGL + compileOnly "com.cleanroommc:lwjglx:1.0.0" + installer "com.cleanroommc:lwjglxx:1.1.21" + lwjglLibraries[0].each { + if (it == 'lwjgl') { + installer "org.lwjgl:$it:$props.lwjgl_version:unsafe" + } + else { + installer "org.lwjgl:$it:$props.lwjgl_version" + } + runtimeOnly "org.lwjgl:$it::$lwjglArch" + + lwjglLibraries[1].each { arch -> + lwjglNatives "org.lwjgl:$it:$props.lwjgl_version:$arch" + } + } + + // ASM + installer "org.ow2.asm:asm:$props.asm_version" + installer "org.ow2.asm:asm-commons:$props.asm_version" + installer "org.ow2.asm:asm-tree:$props.asm_version" + installer "org.ow2.asm:asm-util:$props.asm_version" + installer "org.ow2.asm:asm-analysis:$props.asm_version" + // Added back deprecated features for mods to load up properly, hosted on outlands + installer "org.ow2.asm:asm-deprecated:$props.asm_deprecated" + + // Hacks + installer "top.outlands:foundation:0.19.8" + installer 'net.lenni0451:Reflect:1.6.4' + installer 'net.lenni0451.commons:unchecked:1.9.2' + installer 'org.javassist:javassist:3.30.2-GA' + + // Regular deps + installer 'com.ibm.icu:icu4j:78.3' + installer 'org.jline:jline:4.1.3' + installer 'org.jline:jline-native:4.1.3' + installer 'net.java.jinput:jinput:2.0.10' + + installer 'lzma:lzma:0.0.1' + installer 'java3d:vecmath:1.5.2' + installer 'net.sf.trove4j:core:3.1.0' + installer 'net.sf.trove4j:experimental:3.1.0' + + installer 'net.sf.jopt-simple:jopt-simple:5.0.4' + + installer 'com.github.oshi:oshi-core-ffm:7.3.2' + installer 'com.github.oshi:oshi-common:7.3.2' + installer 'net.java.dev.jna:jna:5.19.1' + installer 'net.java.dev.jna:jna-platform:5.19.1' + + installer 'it.unimi.dsi:fastutil:8.5.18' + + installer 'com.google.guava:guava:33.6.0-jre' + installer 'com.google.guava:failureaccess:1.0.2' + installer 'com.google.code.gson:gson:2.14.0' + + installer 'org.apache.commons:commons-lang3:3.20.0' + installer 'org.apache.commons:commons-compress:1.28.0' + installer 'commons-codec:commons-codec:1.22.0' + installer 'commons-io:commons-io:2.22.0' + installer 'commons-logging:commons-logging:1.4.0' + installer 'org.apache.maven:maven-artifact:3.9.16' + installer 'org.apache.commons:commons-text:1.15.0' // Some old classes in lang3 moved to here, wtf + + // xz in common-compress need this to work + installer 'org.tukaani:xz:1.12' + + installer 'com.google.code.findbugs:jsr305:3.0.2' + installer 'org.jspecify:jspecify:1.0.0' + + // Apache HTTP, 4 and 5 + installer 'org.apache.httpcomponents.core5:httpcore5:5.4.3' + installer 'org.apache.httpcomponents.core5:httpcore5-h2:5.4.3' + installer 'org.apache.httpcomponents.client5:httpclient5:5.6.1' + + installer 'org.apache.httpcomponents:httpclient:4.5.14' + installer 'org.apache.httpcomponents:httpcore:4.4.16' + + // Netty + installer "io.netty:netty-codec-base:$props.netty_version" + installer "io.netty:netty-buffer:$props.netty_version" + installer "io.netty:netty-common:$props.netty_version" + installer "io.netty:netty-handler:$props.netty_version" + installer "io.netty:netty-resolver:$props.netty_version" + installer "io.netty:netty-transport:$props.netty_version" + installer "io.netty:netty-transport-native-unix-common:$props.netty_version:linux-x86_64" + installer "io.netty:netty-transport-classes-epoll:$props.netty_version" + installer "io.netty:netty-transport-native-epoll:$props.netty_version:linux-x86_64" + installer "io.netty:netty-codec-http:$props.netty_version" + installer "io.netty:netty-codec-http2:$props.netty_version" + installer "io.netty:netty-codec-dns:$props.netty_version" + installer "io.netty:netty-codec-compression:$props.netty_version" + installer "io.netty:netty-resolver-dns:$props.netty_version" + + // Jakarta (javax in Java 8) + installer 'jakarta.xml.ws:jakarta.xml.ws-api:4.0.3' + installer 'jakarta.activation:jakarta.activation-api:2.1.4' + installer 'jakarta.annotation:jakarta.annotation-api:3.0.0' + installer 'jakarta.xml.bind:jakarta.xml.bind-api:4.0.5' + installer 'jakarta.inject:jakarta.inject-api:2.0.1' + + // Logging + installer 'org.apache.logging.log4j:log4j-api:2.26.0' + installer 'org.apache.logging.log4j:log4j-core:2.26.0' + installer 'org.apache.logging.log4j:log4j-slf4j2-impl:2.26.0' + installer 'org.slf4j:slf4j-api:2.0.18' + + // Scripts + installer 'org.glassfish.jaxb:jaxb-runtime:4.0.9' + installer 'org.glassfish.jaxb:jaxb-core:4.0.9' + installer 'com.sun.istack:istack-commons-runtime:4.2.0' + installer 'org.glassfish.corba:glassfish-corba-omgapi:5.0.2' + installer 'org.openjdk.nashorn:nashorn-core:15.7' + + // Mac + installer 'ca.weblite:java-objc-bridge:1.2' + + // Kirino Engine + installer 'org.joml:joml:1.10.9' + installer 'io.github.classgraph:classgraph:4.8.184' + + // Mixin + installer 'com.cleanroommc:sponge-mixin:0.20.12+mixin.0.8.7' + installer annotationProcessor('io.github.llamalad7:mixinextras-common:0.5.4') + + testImplementation platform('org.junit:junit-bom:6.1.0') + testImplementation 'org.junit.jupiter:junit-jupiter' + testImplementation 'org.junit.vintage:junit-vintage-engine' + testRuntimeOnly 'org.junit.platform:junit-platform-launcher' +} + +tasks.register("genVersion", com.cleanroommc.gradle.helpers.tasks.GenVersionTask) + +tasks.named('compileJava') { + dependsOn tasks.named('genVersion') +} tasks.register('setup') { group = 'setup' - // These must be strings so that we can do lazy resolution. Else we need evaluationDependsOnChildren above - dependsOn ':minecraft:extractMapped' - dependsOn ':cleanroom:extractMapped' + description = 'Materializes the patched Minecraft source base (fresh clones) and generates the version class.' + dependsOn 'copyMinecraftToSourceSet' + dependsOn 'genVersion' + // TODO: move to CG + more robust way to see if setup is needed as switching between branches will be a pain + // Keeps `setup` a no-op once the source base exists; copy task self-guards too. + onlyIf { + def patchedSrc = file('module/minecraft/src/main/java') + !patchedSrc.exists() || (patchedSrc.listFiles()?.length ?: 0) == 0 + } } -subprojects { - tasks.withType(JavaCompile).tap { - configureEach { - options.compilerArgs += ProjectConstants.COMPILER_JVM_ARGUMENTS - options.encoding = 'UTF-8' - } +test { + maxParallelForks = 1 + useJUnitPlatform() + testLogging { + events 'passed', 'skipped', 'failed' } + jvmArgs ProjectConstants.JVM_ARGUMENTS + ProjectConstants.COMPILER_JVM_ARGUMENTS } diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index a1b33044a..cb9d07752 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -4,7 +4,5 @@ repositories { } dependencies { - implementation 'org.ow2.asm:asm:9.9' - implementation 'org.ow2.asm:asm-tree:9.9' implementation 'com.palantir.gradle.gitversion:gradle-git-version:4.3.0' } diff --git a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/ProjectConstants.groovy b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/ProjectConstants.groovy index 5119e4f4f..83dac7fe1 100644 --- a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/ProjectConstants.groovy +++ b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/ProjectConstants.groovy @@ -12,10 +12,4 @@ interface ProjectConstants { '--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED', '--add-exports=java.base/jdk.internal.reflect=ALL-UNNAMED' ] - - Map PATCHER_POST_PROCESSOR = [ - tool: 'net.minecraftforge:mcpcleanup:2.3.2:fatjar', - repo: 'https://maven.minecraftforge.net/', - args: ['--input', '{input}', '--output', '{output}'] - ] } \ No newline at end of file diff --git a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/BytecodeFinder.groovy b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/BytecodeFinder.groovy deleted file mode 100644 index f779b3e92..000000000 --- a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/BytecodeFinder.groovy +++ /dev/null @@ -1,61 +0,0 @@ -package com.cleanroommc.gradle.helpers.tasks - -import groovy.json.JsonBuilder - -import org.gradle.api.DefaultTask -import org.gradle.api.tasks.InputFile -import org.gradle.api.tasks.OutputFile -import org.gradle.api.tasks.TaskAction - -import org.objectweb.asm.ClassReader -import org.objectweb.asm.Opcodes -import org.objectweb.asm.Type -import org.objectweb.asm.tree.ClassNode -import org.objectweb.asm.tree.FieldNode -import org.objectweb.asm.tree.MethodNode - -import java.util.zip.ZipEntry -import java.util.zip.ZipInputStream - -public abstract class BytecodeFinder extends DefaultTask { - @InputFile File jar - @OutputFile output = project.file("build/${name}/output.json") - - @TaskAction - protected void exec() { - Util.init() - - if (output.exists()) - output.delete() - - pre() - - jar.withInputStream { i -> - new ZipInputStream(i).withCloseable { zin -> - ZipEntry zein - while ((zein = zin.nextEntry) != null) { - if (zein.name.endsWith('.class')) { - def node = new ClassNode(Opcodes.ASM7) - new ClassReader(zin).accept(node, 0) - process(node) - } - } - } - } - - post() - output.text = new JsonBuilder(getData()).toPrettyString() - } - - - protected process(ClassNode node) { - if (node.fields != null) node.fields.each { process(node, it) } - if (node.methods != null) node.methods.each { process(node, it) } - } - - protected pre() {} - protected process(ClassNode parent, FieldNode node) {} - protected process(ClassNode parent, MethodNode node) {} - protected post() {} - protected abstract Object getData() -} diff --git a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CheckAccessTransformers.groovy b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CheckAccessTransformers.groovy deleted file mode 100644 index a3dbfe056..000000000 --- a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CheckAccessTransformers.groovy +++ /dev/null @@ -1,231 +0,0 @@ -package com.cleanroommc.gradle.helpers.tasks - -import java.util.ArrayList -import java.util.TreeMap - -import org.gradle.api.DefaultTask -import org.gradle.api.tasks.InputFile -import org.gradle.api.tasks.InputFiles -import org.gradle.api.tasks.TaskAction -import org.objectweb.asm.Opcodes - -public class CheckAccessTransformers extends DefaultTask { - @InputFile File inheritance - @InputFiles File[] ats - - @TaskAction - protected void exec() { - Util.init() - def parse = { line -> - def idx = line.indexOf('#') - def comment = idx == -1 ? null : line.substring(idx) - if (idx != -1) line = line.substring(0, idx - 1) - def (modifier, cls, desc) = (line.trim() + ' ').split(' ', -1) - def key = cls + (desc.isEmpty() ? '' : ' ' + desc) - return [modifier, cls, desc, comment, key] - } - def accessLevel = { access -> - if ((access & Opcodes.ACC_PUBLIC) != 0) return 3 - if ((access & Opcodes.ACC_PROTECTED) != 0) return 2 - if ((access & Opcodes.ACC_PRIVATE) != 0) return 0 - return 1 - } - def accessStr = { access -> - if (access.endsWith('-f') || access.endsWith('+f')) - return 4 - switch (access.toLowerCase()) { - case 'public': return 3 - case 'protected': return 2 - case 'default': return 1 - case 'private': return 0 - default: return -1 - } - } - def json = inheritance.json() - - ats.each { f -> - TreeMap lines = [:] - def group = null - for (def line : f.readLines()) { - if (line.isEmpty()) continue - if (line.startsWith('#group ')) { - def (modifier, cls, desc, comment, key) = parse.call(line.substring(7)) - - if (!desc.equals('*') && !desc.equals('*()') && !desc.equals('')) - throw new IllegalStateException('Invalid group: ' + line) - - group = [modifier: modifier, cls: cls, desc: desc, comment: comment, - 'existing': [] as Set, - 'children': [] as TreeSet, - group: true - ] - if (lines.containsKey(key)) - throw new IllegalStateException('Duplicate group: ' + line) - - lines[key] = group - } else if (group != null) { - if (line.startsWith('#endgroup')) { - group = null - } else { - def (modifier, cls, desc, comment, key) = parse.call(line) - group['existing'].add(key) - } - } else if (line.startsWith('#endgroup')) { - throw new IllegalStateException('Invalid group ending: ' + line) - } else if (line.startsWith('#')) { - //Nom - } else { - def (modifier, cls, desc, comment, key) = parse.call(line) - if (lines.containsKey(key)) { - println('Duplicate: ' + line) - continue - } - lines[key] = [modifier: modifier, cls: cls, desc: desc, comment: comment, group: false] - } - } - - // Process Groups, this will remove any entries outside the group that is covered by the group - for (def key : new ArrayList<>(lines.keySet())) { - def entry = lines.get(key) - if (entry != null && entry['group']) { - def cls = entry['cls'] - def jcls = json.get(cls.replaceAll('\\.', '/')) - if (jcls == null) { - lines.remove(key) - println('Invalid Group: ' + key) - } else if ('*'.equals(entry['desc'])) { - if (!jcls.containsKey('fields')) { - lines.remove(key) - println('Invalid Group, Class has no fields: ' + key) - } else { - jcls['fields'].each { field, value -> - def fkey = cls + ' ' + field - if (accessLevel.call(value['access']) < accessStr.call(entry['modifier'])) { - if (lines.containsKey(fkey)) { - lines.remove(fkey) - } else if (!entry['existing'].contains(fkey)) { - println('Added: ' + fkey) - } - entry['children'].add(fkey) - } else if (lines.containsKey(fkey)) { - lines.remove(fkey) - println('Removed: ' + fkey) - } - } - entry['existing'].stream().findAll{ !entry['children'].contains(it) }.each{ println('Removed: ' + it) } - } - } else if ('*()'.equals(entry['desc'])) { - if (!jcls.containsKey('methods')) { - lines.remove(key) - println('Invalid Group, Class has no methods: ' + key) - } else { - jcls['methods'].each{ mtd, value -> - if (mtd.startsWith('')) - return - key = cls + ' ' + mtd.replace(' ', '') - if (accessLevel.call(value['access']) < accessStr.call(entry['modifier'])) { - if (lines.containsKey(key)) { - lines.remove(key) - } else if (!entry['existing'].contains(key)) { - println('Added: ' + key) - } - entry['children'].add(key) - } else if (lines.containsKey(key)) { - lines.remove(key) - println('Removed: ' + key) - } - } - entry['existing'].stream().findAll{ !entry['children'].contains(it) }.each{ println('Removed: ' + it) } - } - } else if (''.equals(entry['desc'])) { //Make all public non-abstract subclasses - json.each{ tcls,value -> - if (!value.containsKey('methods') || ((value['access'] & Opcodes.ACC_ABSTRACT) != 0)) - return - def parents = [] as Set - def parent = tcls - while (parent != null && json.containsKey(parent)) { - parents.add(parent) - def p = json[parent] - parent = p == null ? null : p['superName'] - } - if (parents.contains(cls.replaceAll('\\.', '/'))) { - value['methods'].each{ mtd, v -> - if (mtd.startsWith('')) { - def child = tcls.replaceAll('/', '\\.') + ' ' + mtd.replace(' ', '') - if (accessLevel.call(v['access']) < 3) { - if (lines.containsKey(child)) { - lines.remove(child) - } else if (!entry['existing'].contains(child)) { - println('Added: ' + child) - } - entry['children'].add(child) - } else if (lines.containsKey(child)) { - lines.remove(child) - println('Removed: ' + child) - } - } - } - } - } - entry['existing'].stream().findAll{ !entry['children'].contains(it) }.each{ println('Removed: ' + it) } - } - } - } - - // Process normal lines, remove invalid and remove narrowing - for (def key : new ArrayList<>(lines.keySet())) { - def entry = lines.get(key) - if (entry != null && !entry['group']) { - def cls = entry['cls'] - def jcls = json.get(cls.replaceAll('\\.', '/')) - if (jcls == null) { - lines.remove(key) - println('Invalid: ' + key) - } else if (entry['desc'] == '') { - if (accessLevel.call(jcls['access']) >= accessStr.call(entry['modifier']) && (entry.comment == null || !entry.comment.startsWith('#force '))) { - lines.remove(key) - println('Invalid Narrowing: ' + key) - } - } else if (!entry['desc'].contains('(')) { - if (!jcls.containsKey('fields') || !jcls['fields'].containsKey(entry['desc'])) { - lines.remove(key) - println('Invalid: ' + key) - } else { - def value = jcls['fields'][entry['desc']] - if (accessLevel.call(value['access']) >= accessStr.call(entry['modifier']) && (entry.comment == null || !entry.comment.startsWith('#force '))) { - lines.remove(key) - println('Invalid Narrowing: ' + key) - println(entry.comment) - } - } - } else { - def jdesc = entry['desc'].replace('(', ' (') - if (!jcls.containsKey('methods') || !jcls['methods'].containsKey(jdesc)) { - lines.remove(key) - println('Invalid: ' + key) - } else { - def value = jcls['methods'][jdesc] - if (accessLevel.call(value['access']) >= accessStr.call(entry['modifier']) && (entry.comment == null || !entry.comment.startsWith('#force '))) { - lines.remove(key) - println('Invalid Narrowing: ' + key) - } - } - } - } - } - - - def data = [] - lines.each { key,value -> - if (!value.group) { - data.add(value.modifier + ' ' + key + (value.comment == null ? '' : ' ' + value.comment)) - } else { - data.add('#group ' + value.modifier + ' ' + key + (value.comment == null ? '' : ' ' + value.comment)) - value.children.each{ data.add(value.modifier + ' ' + it) } - data.add('#endgroup') - } - } - f.text = data.join('\n') - } - } -} diff --git a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CheckExcs.groovy b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CheckExcs.groovy deleted file mode 100644 index e1b482374..000000000 --- a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CheckExcs.groovy +++ /dev/null @@ -1,95 +0,0 @@ -package com.cleanroommc.gradle.helpers.tasks - -import java.util.ArrayList -import java.util.TreeMap - -import org.gradle.api.DefaultTask -import org.gradle.api.tasks.InputFile -import org.gradle.api.tasks.InputFiles -import org.gradle.api.tasks.TaskAction - -import org.objectweb.asm.ClassReader -import org.objectweb.asm.ClassVisitor -import org.objectweb.asm.MethodVisitor -import org.objectweb.asm.Opcodes -import org.objectweb.asm.Type - -import java.util.zip.ZipEntry -import java.util.zip.ZipInputStream - -public class CheckExcs extends DefaultTask { - @InputFile File binary - @InputFiles File[] excs - - @TaskAction - protected void exec() { - Util.init() - def known = [] - binary.withInputStream { i -> - new ZipInputStream(i).withCloseable { zin -> - def visitor = new ClassVisitor(Opcodes.ASM7) { - private String cls - @Override - public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { - this.cls = name - } - - @Override - public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { - known.add(this.cls + '.' + name + descriptor) - super.visitMethod(access, name, descriptor, signature, exceptions) - } - } - ZipEntry zein - while ((zein = zin.nextEntry) != null) { - if (zein.name.endsWith('.class')) { - ClassReader reader = new ClassReader(zin) - reader.accept(visitor, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES) - } - } - } - } - - excs.each { f -> - def lines = [] - f.eachLine { line -> - def idx = line.indexOf('#') - if (idx == 0 || line.isEmpty()) { - return - } - - def comment = idx == -1 ? null : line.substring(idx) - if (idx != -1) line = line.substring(0, idx - 1) - - if (!line.contains('=')) { - println('Invalid: ' + line) - return - } - - def (key, value) = line.split('=', 2) - if (!known.contains(key)) { - println(key) - println('Invalid: ' + line) - return - } - - def (cls, desc) = key.split('\\.', 2) - if (!desc.contains('(')) { - println('Invalid: ' + line) - return - } - def name = desc.split('\\(', 2)[0] - desc = '(' + desc.split('\\(', 2)[1] - - def (exceptions, args) = value.contains('|') ? value.split('|', 2) : [value, ''] - - if (args.split(',').length != Type.getArgumentTypes(desc).length) { - println('Invalid: ' + line) - return - } - lines.add(line) - } - f.text = lines.sort().join('\n') - } - } -} diff --git a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CheckPatches.groovy b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CheckPatches.groovy deleted file mode 100644 index 071de8837..000000000 --- a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CheckPatches.groovy +++ /dev/null @@ -1,218 +0,0 @@ -package com.cleanroommc.gradle.helpers.tasks - -import org.gradle.api.DefaultTask -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.InputDirectory -import org.gradle.api.tasks.TaskAction - -import java.nio.file.Files -import java.nio.file.Paths -import java.util.regex.Pattern - -public class CheckPatches extends DefaultTask { - @InputDirectory File patchDir - @Input boolean autoFix = false - - @TaskAction - protected void exec() { - def hasS2SArtifact = [ - Paths.get("patches/minecraft/net/minecraft/client/renderer/ViewFrustum.java.patch"), - Paths.get("patches/minecraft/net/minecraft/data/BlockModelDefinition.java.patch") - ] - - def verified = true; - project.fileTree(patchDir).each { patch -> - def patchPath = project.rootDir.toPath().relativize(patch.toPath()) - verified &= verifyPatch(patch, autoFix, patchPath.toString(), hasS2SArtifact.contains(patchPath)) - } - - if (!verified) - throw new RuntimeException('One or more patches failed verification. Check the log for errors.') - } - - def verifyPatch(patch, fix, patchPath, hasS2SArtifact) { - def hunk_start_pattern = Pattern.compile('^@@ -[0-9,]* \\+[0-9,]* @@$') - def white_space_pattern = Pattern.compile('^[+\\-]\\s*$') - def import_pattern = Pattern.compile('^[+\\-]\\s*import.*') - def field_pattern = Pattern.compile('^[+\\-][\\s]*((public|protected|private)[\\s]*)?(static[\\s]*)?(final)?([^=;]*)(=.*)?;\\s*$') - def method_pattern = Pattern.compile('^[+\\-][\\s]*((public|protected|private)[\\s]*)?(static[\\s]*)?(final)?([^(]*)[(]([^)]*)?[)]\\s*[{]\\s*$') - def class_pattern = Pattern.compile('^[+\\-][\\s]*((public|protected|private)[\\s]*)?(static[\\s]*)?(final[\\s]*)?(class|interface)([^{]*)[{]\\s*$') - - def accessMap = [("private"):0, (null):1, ("protected"):2, ("public"):3] - - def hasProblem = false; - def lines = patch.readLines() - - def hunksStart = 0 - def onlyWhiteSpace = false - - def didFix = false - def newLines = [] - def whiteSpaceErrors = [] - - // First two lines are file name ++/-- and we do not care - newLines.add(lines[0] + '\n') - newLines.add(lines[1] + '\n') - - int i = 2 - for (; i < lines.size(); ++i) { - def line = lines[i] - newLines.add(line + '\n') - - if (hunk_start_pattern.matcher(line).find()) { - if (onlyWhiteSpace) { - if (fix || hasS2SArtifact) { - logger.lifecycle("Removing white space hunk starting at line {}, file: {}", hunksStart + 1, patchPath) - def toRemove = i - hunksStart; - while (toRemove-- > 0) - newLines.remove(newLines.size() - 1) - didFix = true - } - else { - logger.lifecycle("Patch contains only white space hunk starting at line {}, file: {}", hunksStart + 1, patchPath) - hasProblem = true - } - } - else { - if (!whiteSpaceErrors.empty) - hasProblem = true - whiteSpaceErrors.each { error -> logger.lifecycle(error) } - whiteSpaceErrors.clear() - } - hunksStart = i - onlyWhiteSpace = true - continue - } - - if (line.startsWithAny('+','-')) { - def prefixChange = false - def prevLine = lines[i - 1] - - if (line.charAt(0) == (char)'+' && prevLine.charAt(0) == (char)'-') { - def prevTrim = prevLine.substring(1).replaceAll("\\s", "") - def currTrim = line.substring(1).replaceAll("\\s", "") - - if (prevTrim.equals(currTrim)) { - prefixChange = true - } - - def pMatcher = field_pattern.matcher(prevLine) - def cMatcher = field_pattern.matcher(line) - - if (pMatcher.find() && cMatcher.find() && - pMatcher.group(6) == cMatcher.group(6) && // = ... - pMatcher.group(5) == cMatcher.group(5) && // field name - pMatcher.group(3) == cMatcher.group(3) && // static - (accessMap[pMatcher.group(2)] < accessMap[cMatcher.group(2)] || pMatcher.group(4) != cMatcher.group(4))) { - logger.lifecycle("Patch contains access changes or final removal at line {}, file: {}", i + 1, patchPath) - hasProblem = true - } - - pMatcher = method_pattern.matcher(prevLine) - cMatcher = method_pattern.matcher(line) - - if (pMatcher.find() && cMatcher.find() && - pMatcher.group(6) == cMatcher.group(6) && // params - pMatcher.group(5) == cMatcher.group(5) && // void name - pMatcher.group(3) == cMatcher.group(3) && // static - (accessMap[pMatcher.group(2)] < accessMap[cMatcher.group(2)] || pMatcher.group(4) != cMatcher.group(4))) { - logger.lifecycle("Patch contains access changes or final removal at line {}, file: {}", i + 1, patchPath) - hasProblem = true - } - - pMatcher = class_pattern.matcher(prevLine) - cMatcher = class_pattern.matcher(line) - - if (pMatcher.find() && cMatcher.find() && - pMatcher.group(6) == cMatcher.group(6) && // ClassName<> extends ... - pMatcher.group(5) == cMatcher.group(5) && // class | interface - pMatcher.group(3) == cMatcher.group(3) && // static - (accessMap[pMatcher.group(2)] < accessMap[cMatcher.group(2)] || pMatcher.group(4) != cMatcher.group(4))) { - logger.lifecycle("Patch contains access changes or final removal at line {}, file: {}", i + 1, patchPath) - hasProblem = true - } - } - - if (line.charAt(0) == (char)'-' && i + 1 < lines.size()) { - def nextLine = lines[i + 1] - if (nextLine.charAt(0) == (char)'+') { - def nextTrim = nextLine.substring(1).replaceAll("\\s", "") - def currTrim = line.substring(1).replaceAll("\\s", "") - - if (nextTrim.equals(currTrim)) { - prefixChange = true - } - } - } - - def isWhiteSpaceChange = white_space_pattern.matcher(line).find() - - if (!prefixChange && !isWhiteSpaceChange) { - onlyWhiteSpace = hasS2SArtifact && import_pattern.matcher(line).find() - } - else if (isWhiteSpaceChange) { - def prevLineChange = prevLine.startsWithAny('+','-') - def nextLineChange = i + 1 < lines.size() && lines[i + 1].startsWithAny('+','-') - - if (!prevLineChange && !nextLineChange) { - whiteSpaceErrors.add(String.format("Patch contains white space change in valid hunk at line %d (cannot auto fix), file: %s", i + 1, patchPath)) - } - } - - if (line.contains("\t")) { - if (!fix) { - logger.lifecycle("Patch contains tabs on line {}, file: {}", i + 1, patchPath) - hasProblem = true - } - else { - logger.lifecycle("Fixing tabs on line {}, file: {}", i + 1, patchPath) - line = line.replaceAll('\t', ' ') - newLines.remove(newLines.size() - 1) - newLines.add(line + '\n') - didFix = true - } - } - - if (import_pattern.matcher(line).find() && !hasS2SArtifact) { - logger.lifecycle("Patch contains import change on line {}, file: {}", i + 1, patchPath) - hasProblem = true - } - } - } - - if (onlyWhiteSpace) { - if (fix || hasS2SArtifact) { - logger.lifecycle("Removing white space hunk starting at line {}, file: {}", hunksStart + 1, patchPath) - def toRemove = i - hunksStart; - while (toRemove-- > 0) - newLines.remove(newLines.size() - 1) - didFix = true - } - else { - logger.lifecycle("Patch contains only white space hunk starting at line {}, file: {}", hunksStart + 1, patchPath) - hasProblem = true - } - } - else { - if (!whiteSpaceErrors.empty) - hasProblem = true - whiteSpaceErrors.each { error -> logger.lifecycle(error) } - } - - if (didFix) { - if (newLines.size() <= 2) { - logger.lifecycle("Patch is now empty removing, file: {}", patchPath) - Files.delete(patch.toPath()) - } - else { - if (!hasS2SArtifact) - logger.lifecycle("*** Updating patch file. Please run setup then genPatches again. ***") - patch.withWriter('UTF-8') { writer -> - newLines.each { l -> writer.write(l) } - } - } - } - - return !hasProblem - } -} diff --git a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CheckSAS.groovy b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CheckSAS.groovy deleted file mode 100644 index d5c585a23..000000000 --- a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CheckSAS.groovy +++ /dev/null @@ -1,64 +0,0 @@ -package com.cleanroommc.gradle.helpers.tasks - -import java.util.ArrayList -import java.util.TreeMap - -import org.gradle.api.DefaultTask -import org.gradle.api.tasks.InputFile -import org.gradle.api.tasks.InputFiles -import org.gradle.api.tasks.TaskAction -import org.objectweb.asm.Opcodes - -public class CheckSAS extends DefaultTask { - @InputFile File inheritance - @InputFiles File[] sass - - @TaskAction - protected void exec() { - Util.init() - def json = inheritance.json() - - sass.each { f -> - def lines = [] - f.eachLine { line -> - if (line[0] == '\t') return //Skip any tabbed lines, those are ones we add - def idx = line.indexOf('#') - if (idx == 0 || line.isEmpty()) { - lines.add(line) - return - } - def comment = idx == -1 ? null : line.substring(idx) - if (idx != -1) line = line.substring(0, idx - 1) - def (cls, desc) = (line.trim() + ' ').split(' ', -1) - cls = cls.replaceAll('\\.', '/') - desc = desc.replace('(', ' (') - - if (json[cls] == null || (!desc.isEmpty() && (json[cls]['methods'] == null || json[cls]['methods'][desc] == null))) { - println('Invalid: ' + line) - return - } - - //Class SAS - if (desc.isEmpty()) { - lines.add(cls + (comment == null ? '' : ' ' + comment)) - if (json[cls]['methods'] != null) - (json[cls]['methods'] as TreeMap).each { - findChildMethods(json, cls, it.key).each { lines.add('\t' + it) } - } - return - } - - //Method SAS - lines.add(cls + ' ' + desc.replace(' ', '') + (comment == null ? '' : ' ' + comment)) - findChildMethods(json, cls, desc).each { lines.add('\t' + it) } - } - f.text = lines.join('\n') - } - } - - protected static findChildMethods(json, cls, desc) - { - return json.values().findAll{ it.methods != null && it.methods[desc] != null && it.methods[desc].override == cls} - .collect { it.name + ' ' + desc.replace(' ', '') } as TreeSet - } -} diff --git a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/ClosureHelper.groovy b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/ClosureHelper.groovy deleted file mode 100644 index 13f5cca6d..000000000 --- a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/ClosureHelper.groovy +++ /dev/null @@ -1,31 +0,0 @@ -package com.cleanroommc.gradle.helpers.tasks - -import java.util.function.BiConsumer - -public class ClosureHelper { - BiConsumer callback - - public ClosureHelper(Closure cl, BiConsumer callback) { - this.callback = callback - apply(this, cl) - } - - - def methodMissing(String name, Object args) { - if (!args.class.isArray()) return - Object[] aargs = (Object[])args - - if (aargs.length == 1 && aargs[0] instanceof Closure) { - this.callback.accept(name, (Closure)aargs[0]) - } else { - throw new IllegalArgumentException('Unknown method: "' + name + '" with arguments ' + args + ' for ' + this) - } - } - - static def apply(def obj, Closure cl) { - cl.delegate = obj - cl.resolveStrategy = Closure.DELEGATE_FIRST - cl() - return obj - } -} \ No newline at end of file diff --git a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CreateMMCPackTask.groovy b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CreateMMCPackTask.groovy deleted file mode 100644 index ccba9f944..000000000 --- a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CreateMMCPackTask.groovy +++ /dev/null @@ -1,138 +0,0 @@ -package com.cleanroommc.gradle.helpers.tasks - -import groovy.json.JsonSlurper -import groovy.json.JsonOutput -import org.gradle.api.DefaultTask -import org.gradle.api.file.RegularFileProperty -import org.gradle.api.file.DirectoryProperty -import org.gradle.api.provider.Property -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.InputDirectory -import org.gradle.api.tasks.InputFile -import org.gradle.api.tasks.OutputFile -import org.gradle.api.tasks.TaskAction - -abstract class CreateMMCPackTask extends DefaultTask { - @InputFile - abstract RegularFileProperty getVersionJson() - - @InputDirectory - abstract DirectoryProperty getTemplateDir() - - @InputFile - abstract RegularFileProperty getUniversalJarFile() - - @Input - abstract Property getCleanroomVersion() - - @Input - abstract Property getIsRelease() - - @OutputFile - abstract RegularFileProperty getOutputZip() - - @TaskAction - void create() { - def versionJsonFile = getVersionJson().get().asFile - def templateDir = getTemplateDir().get().asFile - def jarFile = getUniversalJarFile().get().asFile - def version = getCleanroomVersion().get() - def isRelease = getIsRelease().get() - - def outputDir = new File(getTemporaryDir(), 'mmc-output') - outputDir.deleteDir() - outputDir.mkdirs() - - project.copy { - from(templateDir) { - exclude 'patches/net.minecraft.json' - } - into outputDir - } - project.copy { - from new File(templateDir, 'patches/net.minecraft.json') - into new File(outputDir, 'patches') - } - - def versionJson = new JsonSlurper().parse(versionJsonFile) - def libraries = versionJson.libraries - def mainClass = versionJson.mainClass - def lwjglVersion = '' - def forgeLibraries = [] - def lwjglLibraries = [] - - libraries.each { lib -> - def libName = lib.name as String - if (libName.contains('org.lwjgl:')) { - if (!lwjglVersion) { - lwjglVersion = libName.split(':')[2] - } - if (libName.contains('-arm64')) { - def rules = lib.rules - if (rules && rules[0] && rules[0].os) { - def arm64Rule = [action: 'allow', os: [name: rules[0].os.name + '-arm64']] - ((List) rules).add(arm64Rule) - } - } - lwjglLibraries.add(lib) - } else { - def parts = libName.split(':') - if (parts.length >= 2 && parts[1] == 'cleanroom') { - if (isRelease) { - lib.downloads.artifact.url = "https://repo.cleanroommc.com/releases/com/cleanroommc/cleanroom/${version}/cleanroom-${version}-universal.jar" - forgeLibraries.add(lib) - } else { - forgeLibraries.add([ - name: "com.cleanroommc:cleanroom:${version}-universal", - 'MMC-hint': 'local' - ]) - } - } else { - forgeLibraries.add(lib) - } - } - } - - def forgePatchTemplate = new JsonSlurper().parse(new File(templateDir, 'patches/net.minecraftforge.json')) - forgePatchTemplate.libraries = forgeLibraries - forgePatchTemplate.mainClass = mainClass - forgePatchTemplate.version = version - new File(outputDir, 'patches/net.minecraftforge.json').text = JsonOutput.prettyPrint(JsonOutput.toJson(forgePatchTemplate)) - - def lwjglPatchTemplate = new JsonSlurper().parse(new File(templateDir, 'patches/org.lwjgl3.json')) - lwjglPatchTemplate.libraries = lwjglLibraries - lwjglPatchTemplate.version = lwjglVersion - new File(outputDir, 'patches/org.lwjgl3.json').text = JsonOutput.prettyPrint(JsonOutput.toJson(lwjglPatchTemplate)) - - def mmcPackFile = new File(outputDir, 'mmc-pack.json') - def mmcPack = new JsonSlurper().parse(mmcPackFile) - mmcPack.components.each { component -> - if (component.uid == 'org.lwjgl3') { - component.version = lwjglVersion - component.cachedVersion = lwjglVersion - } - if (component.uid == 'net.minecraft' && component.cachedRequires) { - component.cachedRequires[0].suggests = lwjglVersion - } - if (component.uid == 'net.minecraftforge') { - component.version = version - component.cachedVersion = version - } - } - mmcPackFile.text = JsonOutput.prettyPrint(JsonOutput.toJson(mmcPack)) - - if (!isRelease) { - def libsDir = new File(outputDir, 'libraries') - libsDir.mkdirs() - project.copy { - from jarFile - into libsDir - rename { "cleanroom-${version}-universal.jar" } - } - } - - def zipFile = getOutputZip().get().asFile - zipFile.parentFile.mkdirs() - project.ant.zip(destfile: zipFile.absolutePath, basedir: outputDir.absolutePath) - } -} diff --git a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CrowdinTask.groovy b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CrowdinTask.groovy deleted file mode 100644 index f1c4b36c5..000000000 --- a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CrowdinTask.groovy +++ /dev/null @@ -1,65 +0,0 @@ -package com.cleanroommc.gradle.helpers.tasks - -import org.gradle.api.DefaultTask -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.TaskAction -import org.gradle.api.tasks.Optional -import org.gradle.api.tasks.OutputFile - -import java.util.zip.ZipEntry -import java.util.zip.ZipInputStream -import java.util.zip.ZipOutputStream -import java.net.URL - -public class CrowdinTask extends DefaultTask { - @Input String id = 'minecraft-forge' - @Input @Optional String key - @Input boolean json = true - @OutputFile output = project.file("build/${name}/output.zip") - @OutputFile export = project.file("build/${name}/export.json") - - CrowdinTask() { - outputs.upToDateWhen{ false } - } - - @TaskAction - def run() { - if (output.exists()) - output.delete() - - if (key == null) - return - - // Force an export - new URL("https://api.crowdin.com/api/project/${id}/export?key=${key}").withInputStream { i -> - export.withOutputStream { it << i } - } - - if (!export.text.contains('success')) { - throw new RuntimeException("Crowdin export failed, see ${export} for more info") - } - - new URL("https://api.crowdin.com/api/project/${id}/download/all.zip?key=${key}").withInputStream { i -> - new ZipInputStream(i).withCloseable { zin -> - output.withOutputStream { out -> - new ZipOutputStream(out).withCloseable { zout -> - ZipEntry zein - while ((zein = zin.nextEntry) != null) { - if (zein.isDirectory()) { - zout.putNextEntry(new ZipEntry(zein.name)) - } else { - // 1.13+ uses json - if (zein.name.endsWith('.json') == json) { - ZipEntry zeout = new ZipEntry(json ? zein.name.toLowerCase() : zein.name) - zeout.time = 1 - zout.putNextEntry(zeout) - zout << zin - } - } - } - } - } - } - } - } -} diff --git a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/DownloadLibrariesTask.groovy b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/DownloadLibrariesTask.groovy deleted file mode 100644 index 257458ee9..000000000 --- a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/DownloadLibrariesTask.groovy +++ /dev/null @@ -1,43 +0,0 @@ -package com.cleanroommc.gradle.helpers.tasks - -import org.gradle.api.DefaultTask -import org.gradle.api.tasks.InputFile -import org.gradle.api.tasks.TaskAction -import org.gradle.api.tasks.OutputDirectory - -import java.io.File -import java.util.HashSet -import java.util.Set -import java.net.URL - -public class DownloadLibrariesTask extends DefaultTask { - @InputFile File input - @OutputDirectory File output = project.file("build/${name}/") - Set libraries = new HashSet<>() - - @TaskAction - def run() { - Util.init() - - def json = input.json().libraries.each { lib -> - //TODO: Thread? - def artifacts = [lib.downloads.artifact] + lib.downloads.get('classifiers', [:]).values() - artifacts.each{ art -> - def target = new File(output, art.path) - libraries.add(target) - if (!target.exists() || !art.sha1.equals(target.sha1())) { - project.logger.lifecycle("Downloading ${art.url}") - if (!target.parentFile.exists()) { - target.parentFile.mkdirs() - } - new URL(art.url).withInputStream { i -> - target.withOutputStream { it << i } - } - if (!art.sha1.equals(target.sha1())) { - throw new IllegalStateException("Failed to download ${art.url} to ${target.canonicalPath} SHA Mismatch") - } - } - } - } - } -} diff --git a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/FieldCompareFinder.groovy b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/FieldCompareFinder.groovy deleted file mode 100644 index 2ecba7484..000000000 --- a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/FieldCompareFinder.groovy +++ /dev/null @@ -1,108 +0,0 @@ -package com.cleanroommc.gradle.helpers.tasks - -import groovy.transform.EqualsAndHashCode - -import java.util.ArrayList -import java.util.HashMap -import java.util.TreeMap -import java.util.TreeSet -import java.util.function.BiConsumer - -import org.gradle.api.DefaultTask -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.Nested -import org.gradle.api.tasks.Optional - -import org.objectweb.asm.Opcodes -import org.objectweb.asm.Type -import org.objectweb.asm.tree.ClassNode -import org.objectweb.asm.tree.FieldNode -import org.objectweb.asm.tree.MethodNode - -import static org.objectweb.asm.Opcodes.* - -public class FieldCompareFinder extends BytecodeFinder { - @Nested - Map fields = [:] as HashMap - Map fieldsReverse = [:] as HashMap - Map> targets = [:] as TreeMap - - @Override - protected pre() { - //fields.each{ k,v -> logger.lifecycle("Fields: " + k + ' ' + v) } - } - - @Override - protected process(ClassNode parent, MethodNode node) { - def last = null - def parentInstance = new ObjectTarget(owner: parent.name, name: '', desc: '') - for (int x = 0; x < node.instructions.size(); x++) { - def current = node.instructions.get(x) - if (current.opcode == IF_ACMPEQ || current.opcode == IF_ACMPNE) { - if (last != null && (last.opcode == GETSTATIC || last.opcode == GETFIELD)) { - def target = new Search(cls: last.owner, name: last.name) - def wanted = fieldsReverse.get(target) - def original = fields.get(wanted) - def instance = new ObjectTarget(owner: parent.name, name: node.name, desc: node.desc) - if (wanted != null && (original.blacklist == null || (!original.blacklist.contains(instance) && !original.blacklist.contains(parentInstance)))) { - targets.computeIfAbsent(wanted, { k -> new TreeSet() }).add(instance) - } - } - } - last = current - } - } - - @Override - protected Object getData() { - def ret = [:] as HashMap - targets.forEach{ k, v -> - def e = fields.get(k) - ret[k] = [ - cls: e.cls, - name: e.name, - replacement: e.replacement, - targets: v - ] - } - return ret - } - - @EqualsAndHashCode(excludes = ['replacement', 'blacklist']) - public static class Search { - @Input - String cls - - @Input - String name - - @Input - String replacement - - @Nested - @Optional - Set blacklist - - @Override - String toString() { - return cls + '.' + name - } - - def blacklist(def owner, def name, def desc) { - if (blacklist == null) - blacklist = new HashSet() - blacklist.add(new ObjectTarget(owner: owner, name: name, desc: desc)) - } - def blacklist(def owner) { - blacklist(owner, '', '') - } - } - - def fields(Closure cl) { - new ClosureHelper(cl, {name, ccl -> - def search = ClosureHelper.apply(new Search(), ccl) - this.fields.put(name, search) - this.fieldsReverse.put(search, name) - }) - } -} diff --git a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/GenVersionTask.groovy b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/GenVersionTask.groovy index 564574a17..fbbad3059 100644 --- a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/GenVersionTask.groovy +++ b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/GenVersionTask.groovy @@ -14,7 +14,7 @@ abstract class GenVersionTask extends DefaultTask { @InputFile final File template = new File("${getProject().rootProject.projectDir}/templates/CleanroomVersion.java") @OutputFile - final File versionClass = new File("${getProject().rootProject.projectDir}/src/main/java/com/cleanroommc/common/CleanroomVersion.java") + final File versionClass = new File("${getProject().rootProject.projectDir}/module/cleanroom/src/main/java/com/cleanroommc/common/CleanroomVersion.java") @TaskAction void action() { versionClass.withWriter { def writer -> diff --git a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/ObjectTarget.groovy b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/ObjectTarget.groovy deleted file mode 100644 index c9b95c30a..000000000 --- a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/ObjectTarget.groovy +++ /dev/null @@ -1,31 +0,0 @@ -package com.cleanroommc.gradle.helpers.tasks - -import groovy.transform.EqualsAndHashCode - -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.Optional - -@EqualsAndHashCode -public class ObjectTarget implements Comparable { - @Input - String owner - - @Input - String name - - @Input - @Optional - String desc - - @Override - String toString() { - if (desc == null) - return owner + '.' + name - return owner + '.' + name + desc - } - - @Override - int compareTo(ObjectTarget o) { - return toString().compareTo(o.toString()) - } -} diff --git a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/Util.groovy b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/Util.groovy index 783989b18..575f7b81e 100644 --- a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/Util.groovy +++ b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/Util.groovy @@ -1,179 +1,6 @@ package com.cleanroommc.gradle.helpers.tasks -import groovy.json.JsonSlurper -import org.gradle.api.GradleException -import org.gradle.api.artifacts.Configuration - -import java.security.MessageDigest -import java.text.SimpleDateFormat - class Util { - static void init() { - File.metaClass.sha1 = { -> - MessageDigest md = MessageDigest.getInstance('SHA-1') - delegate.eachByte 4096, {byte[] bytes, int size -> - md.update(bytes, 0, size) - } - return md.digest().collect {String.format "%02x", it}.join() - } - - File.metaClass.json = { -> new JsonSlurper().parseText(delegate.text as String) } - - Date.metaClass.iso8601 = { -> - def format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") - def result = format.format(delegate) - return result[0..21] + ':' + result[22..-1] - } - - String.metaClass.rsplit = { String del, int limit = -1 -> - def lst = new ArrayList() - def x = 0, idx - def tmp = delegate - while ((idx = tmp.lastIndexOf(del)) != -1 && (limit == -1 || x++ < limit)) { - lst.add(0, tmp.substring(idx + del.length(), tmp.length())) - tmp = tmp.substring(0, idx) - } - lst.add(0, tmp) - return lst - } - } - - static String[] getClasspath(project, libs, artifact) { - def ret = [] - artifactTree(project, artifact).each { key, lib -> - libs[lib.name] = lib - if (lib.name != artifact) - ret.add(lib.name) - } - return ret - } - - static def getArtifacts(Configuration config, boolean classifiers) { - def ret = [:] - config.resolvedConfiguration.resolvedArtifacts.each { - def art = [ - group: it.moduleVersion.id.group, - name: it.moduleVersion.id.name, - version: it.moduleVersion.id.version, - classifier: it.classifier, - extension: it.extension, - file: it.file - ] - def key = art.group + ':' + art.name - def folder = "${art.group.replace('.', '/')}/${art.name}/${art.version}/" - def filename = "${art.name}-${art.version}" - if (art.classifier != null) - filename += "-${art.classifier}" - filename += ".${art.extension}" - def path = "${folder}${filename}" - def url = getNativeURL(path, filename) - //TODO remove when Mojang launcher is updated - if (!classifiers && art.classifier != null) { - // Mojang launcher doesn't currently support classifiers, so... move it to part of the version, and force the extension to 'jar' - // However, keep the path normal so that our mirror system works. - art.version = "${art.version}-${art.classifier}" - art.classifier = null - art.extension = 'jar' - path = "${art.group.replace('.', '/')}/${art.name}/${art.version}/${art.name}-${art.version}.jar" - } - ret[key] = [ - name: "${art.group}:${art.name}:${art.version}" + (art.classifier == null ? '' : ":${art.classifier}") + (art.extension == 'jar' ? '' : "@${art.extension}"), - downloads: [ - artifact: [ - path: path, - url: url, - sha1: sha1(art.file as File), - size: art.file.length() - ] - ] - ] - } - return ret - } - - static def getLWJGLNatives(nativeConfig, compileConfig, natives, arch) { - def ret = [:] - def data = [ '' : [:]] - nativeConfig.resolvedConfiguration.resolvedArtifacts.each { - data.putIfAbsent(it.moduleVersion.id.name, [ - group : it.moduleVersion.id.group, - version : it.moduleVersion.id.version, - extension: it.extension, - ]) - } - compileConfig.files.each {file -> - try { - def name = natives.stream().filter(it -> file.getName().contains(it)).findFirst().get() - def classifier = arch.stream().filter(it -> file.getName().contains(it)).findFirst().get() - def art = [ - name : name, - group : data.get(name).get("group"), - version : data.get(name).get("version"), - extension : data.get(name).get("extension"), - classifier: classifier - ] - def key = art.group + ':' + art.name + ':' + art.classifier - def folder = "${art.group.replace('.', '/')}/${art.name}/${art.version}/" - def filename = "${art.name}-${art.version}" - if (art.classifier != null) - filename += "-${art.classifier}" - filename += ".${art.extension}" - def path = "${folder}${filename}" - def url = getNativeURL(path, filename) - ret[key] = [ - name: "${art.group}:${art.name}:${art.version}" + ":${art.classifier}" + (art.extension == 'jar' ? '' : "@${art.extension}"), - downloads: [ - artifact: [ - path: path, - url : url, - sha1: sha1(file as File), - size: file.length() - ] - ], - rules : [ - [ - action: "allow", - os : [ - name: getOSName(art.classifier) - ] - ] - ] - ] - } catch (ignored) {} - } - return ret - } - - // TODO: Change to standard maven - static def getNativeURL(path, filename) { - def urlList = [ - "https://repo.maven.apache.org/maven2/", - "https://libraries.minecraft.net/", - "https://repo.cleanroommc.com/releases/", - "https://maven.arcseekers.com/releases/", - "https://maven.minecraftforge.net/", - ] - try { - return urlList.stream().map(original -> original + path) - .filter((String it) -> this::checkExists(it)).findFirst().get() - } catch (NoSuchElementException ignored) { - throw new GradleException("Can't find " + filename + " from defined repositories.\n" - + "Please check and make sure all repositories are setup properly.\n" - + "At: com.cleanroommc.gradle.helpers.tasks.Util#getNativeURL(String, String)\n" - + "Current defined repositories: (Sort by order)\n" - + String.join("\n" , urlList) as String) - } - } - - static def getOSName(nativeClassifier) { - if (nativeClassifier.contains('natives-linux')) { - return 'linux' - } else if (nativeClassifier.contains('natives-macos')) { - return 'osx' - } else if (nativeClassifier.contains('natives-windows')) { - return 'windows' - } - } static def getCurrentArch() { def osName = System.getProperty("os.name").toLowerCase(); @@ -194,41 +21,4 @@ class Util { } } - static def iso8601Now() { - new Date().iso8601() - } - - static def sha1(File file) { - MessageDigest md = MessageDigest.getInstance('SHA-1') - file.eachByte 4096, {byte[] bytes, int size -> - md.update(bytes, 0, size) - } - return md.digest().collect {String.format "%02x", it}.join() - } - - private static def artifactTree(project, artifact) { - if (!project.ext.has('tree_resolver')) - project.ext.tree_resolver = 1 - def cfg = project.configurations.create('tree_resolver_' + project.ext.tree_resolver++) - def dep = project.dependencies.create(artifact) - cfg.dependencies.add(dep) - def files = cfg.resolve() - return getArtifacts(cfg, true) - } - - private static boolean checkExists(String url) { - try { - def code = new URI(url).toURL().openConnection().with { - requestMethod = 'HEAD' - connect() - responseCode - } - return code == 200 - } catch (Exception e) { - if (e.toString().contains('unable to find valid certification path to requested target')) - throw new RuntimeException('Failed to connect to ' + url + ': Missing certificate root authority, try updating java') - throw e - } - } - -} \ No newline at end of file +} diff --git a/gradle.properties b/gradle.properties index 0576f7263..ca37b3415 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,20 +1,6 @@ title = Cleanroom vendor = CleanroomMC -last_forge_version = 14.23.5.2864 - -# Minecraft & Mappings -mapping_channel = stable -mapping_version = 39-1.12 -minecraft_version = 1.12.2 -mcp_version = 20260220.202731 - -# Related Tooling -special_source = net.md-5:SpecialSource:1.9.0 -special_source_mcp = net.md-5:SpecialSource:1.8.5 -binary_patcher = net.minecraftforge:binarypatcher:1.1.1:fatjar -installer_tools_version = 1.4.5 - # Libraries asm_version = 9.10.1 asm_deprecated = 7.1 @@ -36,7 +22,8 @@ org.gradle.jvmargs = -Xmx4G org.gradle.parallel=true # Allow Gradle to cache build to avoid recompiling classes that did not change. org.gradle.caching=true +# Configuration cache: speeds up configuration by reusing the task graph. +org.gradle.configuration-cache=true +org.gradle.configuration-cache.problems=warn # Set java home when gradle refuse to respect IDE setting -# org.gradle.java.home=/usr/lib/jvm/java-1.17.0-openjdk-amd64 -# Daemon -org.gradle.daemon=false \ No newline at end of file +# org.gradle.java.home=/usr/lib/jvm/java-1.17.0-openjdk-amd64 \ No newline at end of file diff --git a/mmcpack-template/.packignore b/mmcpack-template/.packignore deleted file mode 100644 index cd4a8cd2b..000000000 --- a/mmcpack-template/.packignore +++ /dev/null @@ -1 +0,0 @@ -.minecraft \ No newline at end of file diff --git a/mmcpack-template/cleanroom.png b/mmcpack-template/cleanroom.png deleted file mode 100644 index a8ee31b3551bb10ae204191ceb65454732a69557..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47513 zcmcG#1wd5YyDz*c9ZE`4VutSS2I&@QC5NHAha8ZWR!StqK%`5$lm-DoMMOeU7?AF| z8{YT-o^$Va&OPV5-*-oWnZ4I~*0Y}YJ+ars>FKBv;?dv%06?g&rlb!5nBZGX0CEHT zvlsB?1pI^Rp=Rn00Qh8AKN!HX=TrcIXYXiW;$xz%B?)(T<+ZkTw?Xg*xO#x20YF+V zz{48ujPQZlAnYC8WEeM_+Zmybwla*yBHH}g9(NHAj%tBki2H#$2Jk>=3|6j5Aku9VN|$U5Ne{W2fgd=g@B6k^7Fv? z`GueY0;0UOws0{UxG*yBJ|2>MeE$Cay#7MG?q2qM0umAueEfoZf`UBY2p(^wn~!w>kDE8szbGgnyy0Gs z9zKrlZqO@=);8|GJ~E6TuYYaA)#D$sZr*NXJnf}F?w~s#J-$e7@m<|sAXR?QbyN|oKgZqCXgnw@TPonT~wEIsMyt?y0 z4MhYv{wG7P?))>t|2+Yr zWbK2HVFV3HkcVHCM^M~=UszH^TvCLei(f#JpZ~9++MsdTTKic4`@v#7{2~Sd0+J%& zc;WwPu)D3J9rC{%Y73XNbN6z!1{LS%YHg3;^Ki4jUQJtDQr*ql$Jz~!P*;*+1X<;E zbhMSUwc!^M7nBg=u@wgyMFw=1g!bt);4zhB6k0pujCH*y)vq+`G0ws ztvei~@sBnnMMUiQh3v#_c*I1kMR?$FVOt(?ei42iaRgk#MvNbBCjz(q7d2fkN6^Ww zUH(1QE3RxoiUJaXHgJRuoJUwp$d(5I7nb0$;kOk7$=X;83kV8}SPMxoLjP^uyY4RT zUfS-qpv;9Bp;y|L1j&P}T3`8>45Pr`7fr5A)y4O(i(-QO;EPY->i6IGP5+Dg|90EZ z%@Gu_AS3k3UL>#AzYl^J$bhJbh>*zN*Yz9&5H2Q4j-b@MuNe^$_}7%{Tc-cZtt&LU z@=-}OM{m&Tkbk4ieT3)V?_3lDhIzZ&`S@FVAr$OE8UL4l!S|mr?``e(zh_;{MnGIt$i|MxP6%$xBPbwj$73xd zV8bISYQryXV=aiVy;9wO#=3~4ps1v<;J>`+|Ah6wX~P|?-Ru!yAmU^EKi`ayjWq&c zCv3xGYa?OJBg`+%&toGl2yVs(fv~nkhzY|H@c(Et{~;v&U)~Jd-OUf-_3sSJ!`jOl z45kP#Zy82AFLzg{wTFj`BmCOG`25^#|Bg`qxFpoa9r|wo^q&gN7UAXi?`+`TuksHI z(ElIT`!6l-zlVqaPmBA%tR%jx6yYxz;QL<@;;+w2e@Rm1N;lV`SMoo?g8!}!g0WZ< z1owa7{{I~?|FypR|5t#&vYP9S|GQl2UzflH?CR}5xgYr9pX?Fg270O&m>W`VD_a9V z`FC|C1%rU+8|TO@W@98vLjIjbd)L;I2W4*ig>=lYT0oJskGlsou^rvHP}O@QC_&)6 z5FCHVCZXd-+@~JygEQHnGl7GIm6~vj1dQZP?jKDhEVb@sGtGfz3*kemjVDEYh*B9M{YSf(Cm@mZAmG0-&MP6atY5{nKY8T(ez_L8vW@d@APvx zUMYYg2Oa^M7mv*OfTtR-eStqa(wi$XBPCI@LA{=O+!VjWZvnI*4;{YKBdhUWZB0n{ z#eK7GaRF919Z;(*{YyzT6QS*7%%g%8WcxgFM(xKbJq2cDiakclxbO5O`Fj!x%4yd` zt>5CA)}$C8_qew{-~lEWR+8MuL>9SM`y2pfR**C90eSV&2QqAtP$~*&B#L+kg1THo z&d6~PQaw_|Gs4c=nDsHi0Js3HXqL;)Vm|p|15V(m)vf;Y*2u2tUSO-zR4EmH6lQ$4 zjnyfDx?D%jw5t<{ku^=R(GW~2wMwIDB2P>3jDQY2;E4b?rj@axCETnni1#UR> z-2{4i6*)sb?Iu=l0y13bGs+YhjQdz|u5wI6sGyk+|6@Gh9h^gOC1q3`RrJgy|C6v{ zgFxkqiRQuG7E0`{3V0S%ZH#;l@lJcCxayp3d3cw+e@=!!!N*FMk;tG7v1`q~v8L(^ zqe5e#^o#dwW)J1ST|Jf_8Em}}SBmVAhAp~RHaJ-sIa`hDa(*0@8mXb5KIC%$OUjS5 z&vWjpf)jlbH%}S7%@3ER-6r~*Lur&Uh(v*4ijE-Zkq4u6Ie$dmr~-c@zq~w^T_U{Z zSG{u4U5Bn?C-j`*PxC9A%lrxRnbKUN1&w z6?7SR7IT2U)XiJb{>^;RvX%%5SH(EXlx`D}e`IaeWd95p{Up>x;(q~$!)X{zak&5^ z3GU;S%`nIIi&@Jb6=5NjL9_gu=ETYlt566m2sm?_nWc_>M2_LK2F^r=FG-hO`DK$p zAEwpl8QaE$9D!mSB@9+@E`?=H@G&7U`vP(F`IAUBEKv5EsocuN{QOH$$(qw{heR(= z_lbTW-zus>_A=Upwx%T8g#Z&0Xi1BU9P+N=&%bAoU4A*W_)&3rH*du}VZIb z1UKApKNn*>^IO>sk`#ZJ>!IdUwwN@L-!)&4l?1lVfck6})jAVI$J(UC$;J2i-?*TE z?2TO;VsDkA3^Kjk4SM&LlbKT)kP7CWEgYaT%~k1TwG}E$pu=JIbB8h`QbkM|3M3eB zAh^>%Z8QkfD=`5h;CBQ$;C0TsF>#4I;p>hMPFt0`^-=508he)7kT-~*G?}~ADy2dPDeh@7Ib(%Uy{?Dr9NUt z5e4Q=^h;5UE2H9%v`h{waw=@Efv5nBm2|b>IBBZFGGmiDOX-Zes?QD1s5l2sK_3mH zR;PZg-6p9XQ5DlIzIJ4&I|1Wy$==ACKd8>+rt;I8X}9`}g9`%5p!uRs!3eq>bZFdWa+QrZ|=ng?|^`ObW{814L>%A8A@saq7w_e>W(ql zs3-u{3xQpJ-EFC0$9KbhgTU}1(#~ot3g@_%>>}>8ty8=^O@3$SdEQFv$K96w+ReDt zMLEc;eC!`VdhEABoUhvRWI@bQQ@!^LvdI6qcOEHijRTYdefSw?t7lhQc>tQ$q4~u0 zhn>(Yjf+QGC+Y=_d@$G?nPOW^_eK=kZW5DwzNG%<`-ze3=pb)Vi3y#u9}7J%4BchV z&(zJ3)S47m-S@wtr8$kJsux4jM{>mG%^n>!yipteh=($aP+-cEUf@aBxGbOA2p!#R z88nHL`{Zu1WO#BPnY>G1k`!z|#|4CHegkPd<7QjCp9vZLq+Bf@ME{ql_#Ij=Th1~x zUK<|YPTDR#K^xwc9*Lu0+2){m!tT?RCuV>bp0!DE#zJvO(swr8 z!N2zdc}BP!*)EN)zncHH2b$W>IlJU_tPkSca?>B@LeP&nkBPXp(Q7!Wk-(MYeyp=r z5TJ^4D6-9rNv}=noq!sq{QFt2#uma3^K$gXs}*F(={{QR91XoxfL@6Iruum6J>{(s z`#Gkz&Dq?8T#P4Uvq*EH`;qbLzEyv@0O=#eFV*K6gG;^_^OPr{!@Dg`V?ufUe3F|( zodu*}v^zgidD+QGFtfpZBhEsJu~7*-$YTQ#*ue0lQTl%764Wxop7drWm^c*4Onub4 z_^5PtZ?TF)yCE2gnGxAh1I&QfJo~QPIEEp^>rrSqD~J##7zLyy$^iE1eo)@w9Z)T{ zGUFdLE>}l+O9-`>Ul|Je>?IwlC2lz>>vJ823-C(9&jy#gIuFmKnx_9u znNJutS+=k4;uv8akIz`9M^d@)5de`XtpMm{)9#wZ{4aFK5dp#3!oTiC<+ofLwqBGq z1<-AiDxS3aAa7;*7jnifLpwM+@yr-&TlIw*WYmqdmKi&vU1+YUe9Qlak1fW|Z6m++ zOKB})K<9m2RFnjJ=3x6z^!}|{voc*DNjlb@m2j4@U3th0N&obTqN$C-X}6EN((|Vm zJZ+nDpod*Hg7DP8Hh6fxB!`Ts)0sgR@0{I8KhqBX1Q5WYs}3!BGcV2Sr_NK*O_|G$ zt`%|MhPbxb6uQ5Ql!R27JiHhNP!+_Ap;Nxok2u%TR@ss#FH2;;GN>HUva+%Yt5id{ zfN0{6%)r3Xjx#8i{D$%%?fR*uBm}YkW$7YAOS2L2-jhe=KE4hP1=^6~S>U1u-2^Ii zRJj!S>5SoN2$n4)m)o^g@d)ApwOv!*OfWDWO6!UzwR{_0G1a-bO{SROkg`itzueDD ztoVUCd`=3>zoA@;$1F2Jkb6mcwKZpJh$UQ1^e-xXtkKdzm!M6Xfi^v}>SM8tw8#(d zZw;ef+&pa)_z1j73869IH7DDkyE%o=hroUonbHny@lN={+l5lUrzx9)nVWGaAx`RV*1K$&`rvdo>>p0dt-QaGEFPq ziK^B^3MNsU%-A|4in1+x>-grx(<>}a6+e>yNTyj`VPi_7g8HQ~XZn8IX4qBI;%i?2 zjx!0|Z|!Q(OyDka7`5-J!-M&?A!ke)SB+`U=at0bijc;d@zr1z!-tGZyEB>cnc`nC zu0^Fqpt#xokT)6Yr~uT-)y`hLWUF{L+|qMqsEBy*(n~N$Yu0+oD(DvrtTLZ?=Vq=B z+kq4oqi=P_goK^k&=Z`O*I?fl*^gPEU;HI_HVh0F?k^@QELCVh?NV}#C|)p9-}p>r zAn!Nz(i*R?W-dUsa)(ktb)AS9X_hp(Mow32}i1f?NHR!7Oz_nWgGlh{)?xtVp;;ja_1! zdTrw}`kDPD-d z7Uk-vTpeer`HgIZ^%KcAl{2M-*i76Bqi$!xSmv!uFm1Z>7L2d0phZ=GIy`R%&15SJ{YZ_hVO6o& zg&4b@f=-hXYQQ=UH1XGbM0t#n!I8u}pZ%JrwYf6w`DFQCSjTU2Ul%8~^63EN0KMrW zDTi)y6OqQ{D`)%gAel2Lb*J<_BYKtRxae*sL{FyKQdx@x=HbI}C*>p;<9=Llir@|D zzswu8-qWgIoPc$-07iPva9v`60!;Ty{dSB+h)~^OGv0ubveMC^mCy^Y zEI1@noSAZ~zqBOZANx>#+vKkRNYLjrclUJvvI*U^z&#SZdgpBGd$o?fuqWvpG%bv( zTD|wnURVa9`*AFBz?H9U_?-@#E-B3uSBaIiXk2ed3HCA^EDSEeGQVwlx5c;feJkez zp7L$3DVUR9@=&U+qL(|h@hyQEroXFxMIlTQ8>%Z+i5 zGaVCFd6pY)R6>55i;*gB;)-1NJ${OFjZEzGtc$NFZ@e|&Y+q~o6ZCLmnqqy1tt9h# zuXqT(%z|_@;n3jN|MLrZjE1pUvmJL~Be$9>-zKl$%y!Oa&5VgvToH<7<&I<5=8LGds zs(Zx-7I<@ij7rj*EW>`jYH3*Dp3{Eu_-Q8f6Q|2}tQc$1%ePkgxY>hCO6bob&H2mX zC7ZFtCeX+;LfB$bR8&+=b`sT^@C#Z#+i&()!9p*}sV*=VETx_6%<8MwCm3$hwdy^| zI9fHsW1rVt!tRjnmnF!S>5^u{cy}A97P{TG`O%XWY{@Kb5`bcy1%7^Zsyk^D>Uh9b zQl`OxJR$rG(e8Y8+7}G-Y`-vWEPpVkJsSh#1Ofv0S$Vd{>wd^jga}a=GRli8WXoRY z!k^ThurXo}OC;@b0GsZ0X1U)npYCse-}#Q-QOCd5HMc>@SJ&$#@PqF(qdTX}Ey;}I z?Kfkl1Mg@>iDiuM|H&q}6r9SEUIDUXFGkQ(Cl5066<<`Ib;1<;I28L-f#BM&PQJS| zy9_<#nAgB|4J<~55 zSD&t!y)9_6(Hck}MAl~+EoZ*aD$VSuxS7|ZQU|E*klA8^iD;-|Ul1h)g-yFq2We&; z!tgo)?ud7)GusWhJO|C^Q#m?me0@eN786xpI?&+LRS-m7ux`(`X~3)NZXBIBupVAI z6#h0JbY>UF?vBiW^L}2ok`~TuKX$lRW`y6i*$#&ImT6z`pIc^-cF>pr#iE2tnKMNw zedxH0Z<^fZ=uMuT-=DYB~o=MAH9AQrHBEr()AusgZATIb+S0>h9 zHQ{PK-b`FDG=iDRgiet+#^9e2VZx(ITp-V@2}j;+({lge^J@?DobV&y?5F|LOI*yixyU@21QAgpz(UA1S|}T##dc5 zr&{^Y^q>W{ln@5EI^y2z4QP!ue`Yf1yz@%K5@UyU@N4?TNOixnpPW1OJx@|n%)wde zto;1V(_wj<8-_q-*L8Lsdl&S`$=By6{zV%zs`%uX@?SDJYR<48WaPbn*9ZtkV`$Nx zCMzyS${GcwlWi#tzM;!pHCFax{6P)E8VC!(s4wkG2^hscjf^m;5vCQ=Qy&zj+{?ep z1)x_9Gl3yo7wiUs0ZzKlsqbYkGH9>#z;l=M1`LsZsE0~|(R^KGkgtR2iQKdzhRCjp zrO&gi9%{TMg@nIf5Wkd%9OoV%A9G}6RTrf78XUjBig-tD$)J~(Y@Yhpo0Z)$pGaSm zD;6*okb_nrF(ms#h_O4MU>%S}QmzR6hUz_A;Fd)spO1eBvrYV@h2T68+;?|(?RRM@ z1_mh!OM#9x62NmpqQ$Zu-K1eQ^*ivSVL`fgY#mt*c_cb+8RhyzPibZs*y+Q}%EHhS zk>xYXm~gi+#rV+#f&EI5-^va5A08PQu{Y`~?`4%F8TV_@rH{T0=3pp&+YuijQ(8)o{%C8(pjAXmnlOSWShkCXR0xG4s6 zhcQeZ?AoUG3`>^Bs~IMr53Wtu9Nh}#yNzcJ^N1(*%3KilANlmj7mlz0jq7EClL-c@ zlNczRVEdFz9|@u zV@t#{N^2j-#E6{)avcups%?{CQNW*>5A=u{Y}C3l=xn_h!B_5Y(>$#+U6Ehs_LZ>K z1*7AcLZ5eWuDUFOu%BRo6PR8NBVj;lZ)r+qOnAh;9kHp31FR?1@<{ zW)qV4mJuMI4CsXne|4(6F?SBeX&w*^q7KoShKB_ZU}oo$@VFdbzBDGvzQKVCM?Q~i zIv_Yl{2+hAL;2_CYkk~w4Mey9jpdaUvUVZ)2kpFF-F2bofrP20U8DFY>5&SvG75~A z5|CfNqH)tZGw+Q>=V?|Oywh_dD6>~bY^2nL&UbgRd$TV1lP(_*-659AK)m!?pRJ{r z9jUTfwR)ikz!nvHJwyH7-2PlvpN!yh3xKjfV#==|L9m<`AC{8L)tL=FZ-PA%wjIXr z3!-a{ZH)uj6@26P1j8_CVdr49W?hSZR#&QL%`(P8tp+!=!hrMb1R4O_IDb58SLnRG zy$^dQmvKIylmb9AFiPis8w@ZYC|)RlHGUJUh9r{(FsZru1|OgZqAt0ql@r^Km*;Qt zw99aRPI+x9?(tWK5+b^Vi`r0J)1O)n>X1F!-sASj6#t=5pJWst5D^(1*I@$vnDYJ) zP2U=o$f3dTKeh4x>G_Ev%=ImF)6>x`ztFdjl%RCsH|sFYToolxW>gD~yajgm!UJ*z z^pIrVR<^HnALOWQmghE}B}-&W*`y1-nr~Kki$pITz>Nn?3se@Em0et=IGcB`Nlm^U5pMcitz#spftKF?6YT>(dE10dy4@_*`-D$AY;(T zS`djbVT&7|?7TVOLlLb=um}YbRqi^U*Mj%!kK4i~K75GSJ3sLak5O}ovskf}Gnd_^ z7t}*08Xf^Vbe9txfWZ)T!Lj*)?^r6Gb*o<_@fRl%15R>cMX-&O?@zmO`0UfNX-2?~ zym%7f9Z`n_TM{F{*6OOS2;$EJFiQ@-|B4J+qsm%xZzQNk65n)CV>YKD&`JaXO5X?r z+FV~c##a_HLw%DzpELNhji}cXEXgGl`z$4sc8Be1Bq|=QRIh=_{4yR21h%Nn(|m{e zsS5C?adRTy*V0yWt!4F8I4BoWzE1akG}NH{ZHgf;9*LrToiPWnvo3SYEZEK%rZ%`$!gp#2J&FX~bZBfe*XtAv^13YfyhWOz0=sO)dG_()bng zSCo9uPDUO8eOUx--bYLo&hIqlSm=@=;aEuvEk&OlAYt|>N)S%+0TVE-#{!{b;>X4T z)rjwC$i^7dJ64`TJ*pz}mf)KzF^LB$wlCrA@+?ZrxP4g#tdCM0lOG>+A-XwFf7<@M z2|&VBqbN)#8ug1o0Th~WfADa>&>ZT zm0}T4z)=zL({W&NI%wp9-l7C;0Uqc5OGm$Vf;Ty1aBRPFfaIs|n(nI1hY}eP+{VKJ zv&@18@%AYPVK6%?0FyVU97biW<>e;##zZ@ZV|(cI#9fN9Xox{VO-)7-i`1kk*7(?A z_4#Vv5+9!7sz1#gx@?Tkr6_KjVXmOmm4`THQ%-g9si`Eu7F}=Sgy(aAVVcC#x4GV6 z&b7z{%pag9LS`g8?+SZP40chkH$f~i#J59EaG!r<1q?_V9PeTY4&U|FmEA;Qdx|pJ zB!6uKONkKsf=L(I4+bQ6rSFKj8T@*NdzS}z_jPTgu{_AWXnazJyZI33P;Vq>628 z;=@yS5_>`|!qm4xY;DAZif5XY9Y}&tgKSd{(IZWKg4igv3Jc~N_b}wAG(|ndp(Bk% zZ|t!Ge$dYd%uC~1ypko^(Us)oqL}n%4(NXPEH}X(&m{P!qT*G{?Zen;hv&DftNzgu zw!HpOo!Q2Fiwb}LlCMoK#_v_HJ|W$j!6GLVA>yb`8t#TXTxl4*6n0eA4 zJVUZ3Hy9O~SS`B+XZ)c7?>s()VIXhhE0Cz!w1Gp1_yTH5Z5jfRZ zfN2R`{|nE%ha!X>Q@b$ucL3w_bm+eAddXxU$W(qw|*WQdo*)8_ESwQ9hII zwT-8t{&2TW?Pc8yWiaP4E4u-#;6;5X!i8<-im(UrI;v$FU7V0Yp{*|!lN$y|-RDs-EU zbnI|j@@ekZWCz+>(a&0u>Ov;cVB}Thgl}mn z=CVJ_z7;w#UFN9l>d|lKNKv@pygwiaN$Sn#Zs$C=J&u>+9jnQd`NsF-Pv#)vi&Gug zmYxB<^&-fO`dZ6i5%cLVZjRO~zs$SxQ7C}bFHki7S6)^4>7 zqxH$pXHT2YOwCB%%{`2iGt2R45mYm#n7sAD11KxIB>%C-=ZG%R8{byJMQOZN1ha%(zvf)9+9vhM zf6Q(&Z~WDyCJk?-62<_&vK@^@B3+&;$3QZGhq#^xB^2P(@R5ggPQlM}{oh^S*r zii}FEeSB_r9B&eUDxJ9rI`3Qy@b;^d`>Ky**yyScFW$Ahvy@>>7q6n9`9HUKMc_R7 zdr`?qe?SPQ{7J2EJnFX)=gz}E+V)J>9I;OObfLsWggHa@M10-3K__KtZrzn$J>IT} z57&e2ZaCGwTa?1$9_0ldPMjkreC0;n>it#YEd5;yN9o#!W}Xk+7TkOenBK)i+T;6Z zA3d&l-5M>tzbJvB8U0o-HI0Hr*i^=Y>@0R~#t`9S0&6C$m_SoeQ)9qhp~Z)d>A;fa zwf?V*VHA6O6X&h)qc+R!Kv_u(V`|5DEAwXy!)`U>fo!foXus)J>ifN#`FK4jvfnL6>Ad(k*9(1A)sdcO;tuX?qpv*|My>exAMO638XqNl0tzzm1`l+K!!P~QHmL#9~ zB<%011nFcD%-gW4N0F&TJd+%QJnfF|&g-`96CEy3W>!DSU#YO4-AA9gCmbd;J#iu1 zSir^|mQ$%k%m-tu?RP`o^hy=m_c`oF(B1JEe@)rdkSTU6&sXa!F*d%fcFO(Kd#Q$D z^h-#Ry)!KE3Cqz{ej^^IbE_5~0DkWWipvPatg7Indz>29=JENZ>QPKZc5{B z!j(Prlc$*?NnO9qACoD1TtZBLNbe^_M2b8%53KwVLu7)yQ6gpo?_CC3|^ zhPNYGSOT^RXvuHpN56>rays3)sb3RgmdQn=6Gl4>NC&*Hjx=Jtr@E%Qk=Xm4?c~<_ zM=Nn-M6&P0z-ME;@hh$mVkj+}Or_r}aW3W7^-;Zds_M{JQNf$-@(i?yTp5qFyTlUL zJ;TtVP7=}pfX9i5isq*z4(}`7YNJ;+e@3kKNGIjxk&t2z^jQde=JLQx379R-4zJXN zD*ge;su6&9?YW8zfPQ6^`q zeng^^>Ry~u@|HyHd`WwG&a(lMgOBqS%B2Sv=buMyj%ZYMsQocDedLgRo226@b?ld1 z2PO!~&TL30wp;Vshqe&b$oYFIUYQ)kJ|u{5XHn8C`ms;RIP$+NB)_M2Z1W|;$>IWR z#@<@gKYlW<{XCn;>SF-m#Cj8P(TIrW`Z{+zF;&-I$Wgl^*?9F?%4j{bXBHRc2N3Bd7(Dk?PK!2Nz-WQ`+m>;}8sUeobK1hyB+_ zbfCDvbl2)6rl`&rkNx2?ao_Ur;+mS@ugw=Ret(U5&e@4qm?j{dBKSrp2UmB$pPk}l zZHQ{O2sV+<3iH+d8kL04`E5Imp{-OyPuofSw(lOozWSv)&LMn=ALen|BXBnQb?R-u zCC=y3Z(Jbx(KLZ;oKUo>oSyZohM`e>v9&3!7Zh+JlWJztw$Gu1@oz zOBZ6TvwxFc8ykc|?%3SiKYThA(xLCe?+f9$JilV(rMRab1>2jPV4~Mee-1lN67Dz^ zm{OcR8D$Y9ynZ^w*C!SjH)vy1@3mm`dc09?M%H$ET# z+n4QU=<0q;meeeMBi_5*vETdYodm4=t;>wa7%$kzB2jY20y8D<;N#IDD> z3s$!xMh1;EKr)>%ewmd|+#melfNpB(Rmf$s9Sgmov7Itk?_`FtX`HLo(n<3(DRR z(R6%FaIhLTtth4fPL5LJzBj+=Hxibb5uIZ)JfTEVU=A=xr0xmbF_?`3p&-ys z9a5Uz@r}^gWATgd@bEA`c2o7ONxigI%T&%J+JiV^GI`NA&wX+4$~VuKA~Dh`7Y z3Lcu%wJ)L!H`j zlwbPXJY}3q`Fm2%Ev#`k_wtdqtd+p$FnSdeV96d8cvhODlg)}bLdvSngEWUncCdBAHd;i9w2VFiJ=fshHraX3FDk?cPQQh;? zw3^VgHO%6}Hvt9y{&KJq2Mu4pn0u;UV}IA>=w%Q+*q%T+G0V?%<1IsICC258O}du% zojrf`)QNlTaN9jABloL@O~Z#80&8WLxhN@Z*M$Mm9W$T1Mrjy40x=ib(_sI6PdKv% zhr=|UTW)YNVKl(w2XDk;Oos3#*}kBK|3{rK1Luo; zC7JAFWUr}rGt)_|I-w&Sl;k#^eoJ1|`+;;|N3yZE!l~jy0en!F#SD-_qxSAMcB}UK zdLGr*vtx^v_A1{A5)Yo|wp%vq$Kfc5_-!cvt*f&O_YrMi)6W8CvNS~MN9 zgJ7`K3lza_ln;_yuMD-`X2ho0=;RHpp>YNRN3;7PrRjYA;sg`xBcT4t2K$$aVMaC*RTPSVbiWgiT^|d6!zI zCkxLfr%7wt$D}uC!%mo~Sb!bYbMd`1`X6pYF(blyycC|laPCxnI`r7;G8JB#T0U6& zxG>>KJjv~FEEfScdQo1qbwi6|aY%8Elpf@6MPY`rU>m6nq+(+81wSn~XPk<+~OPXW_Hg=hwn58Ro9gYdJ? z({!b?mK2d~-NPd}s}z8E@=R6PJak00d0~EQ)%59OWtXWI+*d2V=Dtu1KcG9%@Xpdq zY3g<}BB~qtS)>au8uGYlW7l|pr7!al$)$ySU(y3^rD=hqIH{$Ad%ts-sXVi!ml>+f z-$DHf?M|q^r;)^6%JGTkA38P0PMEiok!ddG_lnCU5`Hp~E4ggx7g)P%blx;_l~saI z_l`~Ydn(c#v@gaO2*Ff*E$5>r5n_k|64~*B1?I8+4Sy8fBrfbr;q9piy;(@ zG+|VZTwKf@G09HFS6pE^s|++I?%Ger+F{%3^uQBSGfNHg?qaEzaA{hTrbO4k^i zI=G?6bm5_!E5bxvrs%@fn<%qf5N+;n-uW{rFVc*@3zM&MQLCVL< zU(own^OjY|Mz>;_e97WuaaACIqMDsEr`Ab)UQFKXM@5jSB58vG<%iYhiVeA;r*WksE>Jo-{DL;gSuzs&|VFrl{|c2%JEiZk$4%(^TpVvddO#7OcwEs^rhR*~bE;n0eQ-k^6^ zDX7qigXl-1MgzhaNEAzrE1&o1SSdB7g9% z_tCYB^qKQw5<*r9Kmn_5`68;#Gow4919VTr_y(s5Wrty&xw$XdV6tSGSbt z6FDf+Ty{fpTsZAo36Ag|A&4=y8f7-zFt&v!Cx$iX~B(Nm^fsKvVYRfpB&> zxfJ0WqpVxhUF|01okZp#Bz`Whn8MN>L(`XRb#5*0!{80_U!O-+f+s9cfvs(Yy_=_x zbB>4=BQw|gBh|Zj@OvOA1OA`)b8YjZL5(&V-Ml%q64mkZ=b4QP>afH>kZlGU9-KuN zrAA($;n;h#`e?H)9rzU&VR{RznlM_TP%~oQB_A9Ge^Xyv=flI@2qonCFQEO>33h zK19mV-??w~9w^YkQwxOHHmEmmUd-Eef}G*I674(T8gI-*t9ajv(Rr>=pQ)F%Vy(eg zi!EroPp&CX+Cv+@cbffma5H~<*ni`sOYytzHJ!B~^XM?I=6nWAcQC zD?`P9@+O8`s}~nE_7kTf+5gm@bO)x zTU#)Gd5Z&&cVkO$iQ(b8DVj1)CYc-Gm9C|0q~=BPP{sMS*3lg$Di}~LiaD^W8Q#cv z+quHu0+L`f7;y2La$$XlJ1OtEZ2mIbM|Yel`8@HpKZ9#9@JqlI^FpO`QwmF9@)3Cu zTmDb zt6>jc5|Pkbd~SMP{Ok)`b1wsN<1iAab-YlZ#Q1@OdYXv35w|Bairyd1+ANs#5-=;9 ze>Xkl;r2f6Wzn1Q`zN?58FaC`OEs=A+N0P5vzLW0+MlWELO&=K*L>5%wi+ce&Rg zB_^MtmnI+v!&8K;?Msqx*SPdOG0+iFf`lqljO)DstEH~+_#+lstaoCvzc|o`!NSW^ zS4U^{$9Rxe=C#xI5Sa5G)4SrdD3Nl|TpH2CA~J zTP>kUV4*Ap|d+ork8+;XOf`{Um_!#LR359kOahhB7ENN3)9gTN_NWKW+n z&eO@)wxlJQ{hU=;5K2aMr_|ZsrHimxOd!4gmO|)eW_NyqfmDSY`L3YtF+@$Gq?ZrA zB72YFS6;yFM;bGNAdafB*z3%Qdg`Jaw1gw9UK4xp8ANN+6 z;hv@M!r>{Alpb!(5d|*Tt z($zyPL{Ilc^>M5fFc!2>wTo?ZCI(|7HuimHB~PFbJ;KGrRp~-@;hxa}WL1k7e}GB~ zc&yf!Cg@R=|9F3kugyg$3Xu>NE?{poB^;D$jcv*pB{n^B2Mb-P@GyDyaAfmmFV?;J zOc<@n!~xqemGD(9-W9POikI4^(b{puJsKYlei1Im+1hWWv#XD)+)OBG+}_^9CNP6T zI^$CiY0ZjfBFV??ROd*1@v zn#gyFMxzsOtsiXA$6w}cUQ9k@|75=|fioGAaD$N>)23Y-!Ys#kdtUi>O-FcpmbW%H z<#0xq7M>P4l)CB_UGw?}k%s*Ne2gOlTzbQrOQh>=o(a3)vCfj7{Ilc+dbz=n6oI&8 zme+h(A653$`BeeEnUU~WGAIpMw@}8u$a@5A)CK$=VQIF>qeS$#xy5X6aqn^xuiLW^ zw8l8998YiC=tA70bl+|7snJ?1$+bMO@EzDuu6&n2lV*xL6WZ4dN{z4A zSaLr7UZSgY+}pIuR`R{pHv<*R^~6?JBEe%uJMf2GThf-?`Jy#;UTKGo-s&$sTXoVJ zEYBsO;O^tZkHgvvM=whF^beYfX-M_b$*ovCGSUf47xsh;HnydbYHTVlgkul35JmgO zntT@6D)_*CQOx+qcfYaeGm%Ge_3>*D<8kAM_h8~BJ*q>0vmS2}5f2Td5lU#=87Vic1RHuoQSDl!iv8aY8r=x*Svgl;yw zn`y*syzJQD4-#Jnbc;;AYV~7GtmPgXslE@x3mAC!{Fq_yD13J@Tjiqk72V-IdQ;8w z4=XhL#Wpti3F|0ae()<&Gi0cDw{Q`SQJAl(AVsfF*A7AgG!;8MXKInP6@>&iY!@~3NA)|Nefj<| zJ6uhoEB$ds;u*yXQ(*mk@C{MQ@;jX+<>t(nEq7#1pIq)xX^wCfNy?g?dL++!KJO9; zP2CR4*4$G%S0212i5x@;V9Mic=QOaPQlKeN?3VJF@kCxc9gG|?H;^;>q;rX0Z}a-LlbI{S}b9VowWvUzAm!HAyJ z6G^bb1fR(WieaVcoH+hr{&_zm5v3TVkJi0I0c1p?z=XqPvIX~nG-a=jE}WMc+lZLJ z{Uz;v(PFk|YCkXpl$9V)9Mq^)3P1xrmlEOvn?ISxx1fms!O>MlMb$;oVd(DemXK5$ zhDHQLr9tVG5|QrimJ&$`5s*eex;q4uHn0UYq9);bD8(vz31$+&)(;eA`x(5 z2`GCPzxncOlKc6W?BKNwl7v?4uW3q=u;G;C96gi(oTc$4n{e2_rB{8QE37)W-P`N} zwQ)fzIA%0<7phk_I=wRcw`f{*QaEg8EQ~C#*j)nyhF2wZ zDQFGqNmH4tFMPzUv0J42RYJ>(@2H-bEqup+v8ti|UP z9(48<@WdhHUp4#6k0&xoC@8-sqQw0v6k}vi^3zil8;x!Y9vHwSzD6L4#?x zDtrv?70RTnG#@p@uYlkY8CJdZo~3)HP;BOB#geH)l|`il0i?%|L+H;lIYlVC6n7;8 z(kKL~p~0m%JZysTmwKx&3EF)khOtnb9&6XjGRT*6OjO8FVYD|UU;%~`PxCqI^@r%b zpnaPI3!Yixow90%h})7WPEbomcCUVjgZb}Hw(Mj2lf5&Eh2*$veq=&>wQ*?O z<;gOrpg^Kz+YUTL1n1>)myK^i0O1&=-5c|`rNj0&N==%8&D!apZ*|YP2HPa2WB*_x zDTX-i57yh3=hiwz@`qacO#x}Au!D*8k8y0f7Jx^m{q~%}Z&s2`Po87X{W5J|3)!jn zw;dpN=#MAfl*=qts*}ODS29u*KpM&iUgL%$r1#MluToY%ue9p&RXcDpGB7~>yFZ$g zPj{yGBofRtQaTjHfM=ISO9Y)v59sTX%E>kk;NDNi)0c=E;cMJ1ZKZ zJi0@u%6xhMY={8GsV9K{3}(o+<}!UKUG^sDpJ*1ojBjVkR+Wf0OmBTONo%>Eu7ao) zGkXvBMlgavhdP=J!Wj-5EeKdpK|HF0YRXCnVn9Z)1B|VgSEK53CJcu#J^~>We=%>x z;Pbl+apl8gE5@f>kTDBXA~tfKU%Dn)Eo;WcUz*?W^@t`OdKB`7<1m(9(gKDxczUS< znK>C@**+->+zZf}{4%DJw$GRt;jNmS7C+Xuln(|MvV`qlNYA0cp0tL=r8BUp?rjvc z15=i*5hUpxYD|XmNtQtarR(w;DFHuITUhIpC(FFp0kq`yGJrU#)R=hx_Gk7tq(=U0 zoIs16<^#_=ps|@^*rR(tPLuc=%FD&Z zD?R;N*y+jTG@p#&*#zHb@H3W|zry*V*sVQe?6-*~PdHy%Dl?-~_PPr+8v-izIV!D^ zQIli9=nx1t{~$2DxJvZ5yy4-!xa{oW6`MEgR`Q0YQOC35aaWmq0#Mri`#9u88HP7W zjKdM^f65qu@(XwiC${r6ADM2Qmqk$q5L+#~$jLIWZe)e`c?aa%$!e=-$=|DGAmYy9 zJ_A}P98#%Qz9BOaHhrd3inrAXmqWccqQO4sE$<2x;Mw0&*A}g+HgV%R%xEm4yI^&$piKdzo(7w-urnY-^duM^C(F`la^ zu3k=PpyzE?oNGB~HAJHBFSL-Bg?P}2KgBKI>yEZ}27KGVS%m+QA7vHP$%)U3ZPgTV zEr4H~js)@L%?)_5GpiJ`4!{4(UVD1~yx4!*5OBasoK98=*l^&Qu{F(pmRY(ET(dw3 z4mw0DA|qJT<1y}41Ncm{VF@~}#$%{Ku1E}3xD|D@5RY3yDP|^{yPT#9fWxq*#`ez1 zLj0!{igi0i4#@LrEBwJ3{4w+4$?-%3gti^ZXnkRL$`(> zU3z;pl5mQf92^yG28`CxEY}uk*&(0wi%%j%W-?HZE?ipqpqR*j0&EQ)vLj~Rg#cVe zxOyr3`+~}ZBvEw#pE|tG(XgG1dOAPIT;`3g#!bq)jxgw-6=NdxgiTFad2#&6Tgz#? z3`m}gmhNCo5vZ)=_WdgPx;3mJHtcml=%8DSiHR?sM$u^Aw1IL}6soDO+>pI$8g{&V zj;0iHMlc1LU!Hmf+w8;_6-!DydL*piWvyw4&cX=&!m{au%vNG-L*ZFmc} z!L^;Nt|qHK&wYt5ckcf!v^MmLW!LcokICaIqL$JEpCBCHaYY?AmrM53!xukw=;-Oy zV-#42h#*ycM$5Bg>FRBba?5I|hW_OL=K2irmDE+ce{)dHzu*1sL_;78=m9=q;V{eU zbX~*lSaXm44`eFWRF+l~pVXNHC#tb8;aOW_$DWnFPO+}Sgs0oHwnmKa``6t%OdlOjs3T^1-<2!?>@I>HUq!f1MH*ic zxOS_&C?xWYz3Pv)D`m<@-UFQ)?;+_N1CfPpR-5zSjv%Kw^8P#O+f^1C*SIO9 z73yO`)X@2;Ua_pkWw011MG6R3K6umavwQcA*WF10XXM3w^L>aXR6mrNR@Or99bg6jYJVsy(APU+*;z9WrEiSnY)=+MwexqN)uDT2gMGVMqO z`m}%c-)X}H6#T>07*HTNFCUp>AyG5fmyW0yVCBvv}{?dsDZ283*GecEpM)R(fYBT$}L$>+an}~ zpxb0Z*p`44=QK_8B@3*vhfrbf+=o7ED}W$SHg`-|iJ`>qjfBm4sk~Z-z7;98@`kmY z#qhd=OXKChU*xoOTPv+EzPe8clqmxy1wIj93+$;~_o2WkK-tMq*)O zC-W&n!hMmY(=PQQt!6*8YzYMWM^@fQRFSLz0mW9k)0Y-eD3Ic*%Bu<@=wlcM*&WlZ z@v~isjJ0XF`9pv=_HuU}>5ENG;+?`;-gy=Tl`>$c%Es&_x{F@81)tlp0-z-D^Vyz! z$qUXx2NN=jSnANFV1~SAbasSbWp@zR@hgP*^AIu!A`^NCiu7Ti$RWolA_G&5rj)!O zGIu&OD;lcSP+z4dWqlYheR5pugYNXsm9Y$d*_*0u9)7xO!=7UKsc0DGbhgJ5`?|js z=xg;$at%vNS`Jozsb_YrDLp4Zo`5?D|y zt*k05Dk>zr+f@G445I2;%@nB}eT_-7x@71lhn#vZQ{&TiBna*}bFIGXPue!yTc?$J zMh$&-Os#bLBG+HPHd4PiR=c;edGt%iS0&437jS7fWJ4qnfj%Sm=a5cS+Y!rz0!E#N z&FnvhJ?{goY1_yA*F+wXVChy{4o5~yFT8GVbELBVeJ@ar%p?bC8oUjxy1zamq>&J% z7I{`@0bkG|G~!pJuaWdgiEdjRy=yIJ@ckKelPwye6g$*b+vUig!>0}jPizgPMLJnP zdRdD>LDGf!aO{BSwP%Ddhw%-i3J&s7;h_gcCR)@e(vf2vZD+NHpb5I_S-Misx^=<4QdSX5rpqQNkZ0C6ny1%Vhr|STLcgB0VhJO1 zE1xoA6DVq8$cLfj^>N+te*T`?JP1sGmk8qC54e%F9aBJTGvJ_ z;%#ClFzgG-ry)vsnV9G@I>K?w@d*g4(_RTLSix&qjCW^ZfQA(_B=^b|52B~30(Zol zPZq-R)Uval%a|Z4k}+`7)0yo+A{8fe9I(X)uCKs&8_wi!A^zNfR+$S$A3(yJUPmOk zZ@2Ay1H%^FeOMNm-|?2JfMvJP;&sPxu-{J#)q{e#8&Hcz=j=ix3W@``I6Kcb! zmk2`75>2;DI{K9u!)sxIrmNg~2t57w%S6XNxxp3^t-9->o@;>G=3cFdgZrPz$vDuw&^svA8``rW*E@ecAwU^H! zQoqqtdM<6BMn^~I&F`(ObWXS*wdoDHf$J&d0a6P2z9ouP^%B9aF@v@f*-f|KNeG)Z z8W(xM2q`#CK&|aGkDm`80aPO6;^@Ul(g89gOI$R{QPPv7Mtqzz`F-Fh>#%_2J1;0` z{<5xK9QUo*NVvbJa<*50q=+3Q6Y>hmKuUFv9*>8{XdH?0GDgCcKKf+GBPz!CW0mpO zacN)(q{-IFye2<$y8K9d4-e|xR+!BeI2+YuE0I99PThQ!9Fu}g=vThAHqN|NaoF|{ z{7dK_8frx3jDE!7Ff6KO({PMFX6!a(y$(h(CF8|Lm+g;Y)=#LwznW)}Bezy(3BhX< z&X?Cg=r{d-mG2AvI4piI@N;)3tp-8P^l6#DMs?j^j#H{ixuL0n<;fs8M39JORzKyg zZ0)e^*Da-rMg$$%Mf(FV+Wm|CzByXi4%5WkaH;f2 zi%3#|*5p{TWSUP*ATkSI!ovIu~@(^WxcmUhI#fJ5@-X3=;n{GfmB8{K|0MLXl#5 z78e`afqpbO$$d^I5;g1baF=ZObRaAYmF?rIw>B<)1kl1L|0ij6ME+#J5%2QWJu3|O zHvu8>yx=!GiuJ@r>CQbw8ERtL5>&n~>5uBRkyh7QKm7JXTy|ieO}5^yRfffv>~{zE zt2@BF79A7Qj(&8ii43l0b;0|70T&xP$`?p5bX&38+BWoEmy=jfR4MTKs2fLx>o=Wb z!N7ssacgdTT$X}E3ws3d`4oT);BHy-d`#R6PshzRmpij7{IrGocvh+NTUhx0EHUoB zHdb&aziFXa(z-uTj?1jd9&9+pU&`@8JWEZwTrXe{7#sbgY}f1)J)XA>4s z9ugbId+32zeR41(me|6QcDh1+J&-PYP;S)Ke2A=4j5uapUGl4nkVGFbZnOc3JP;kY z?kLt@AR=2)rKLX*BUR-zzF3^aO=(;cfKI&wwFEX-Fk}zjmM_xbtFN-|=ircVYvz_? zDM7Ba4F6I=F9Y@s5S4mEMl&5u4-wTO6LuH#`ntL=JGqe<8j?ojZ}VKL9quwT6lH}g zBRje@pQ7jXWrdMwS14R~Cu|8l1)R@thhxyI95m+Iwp7>lkHQ)8!dk9=avLlKj zKOH3i`X~ax>Gz&^47{@~5zg$l@KIPkp^^=w&URKpTfo;pO;J#vfko%QP zr3gZ^rdyA3YUUDbD z-yWhlmvBQXvIKcqw=Y-}%7FH~9~OsK-%;il7Ne?=vfu9?EsEnr3GRI8)s@GSjA2q) z2HQ=)OWmJaYkT-~9mhKjC%vY-hg{ht-}2rfh5YMEynj~~`oDxTnAvKxVyl7U%a@It zcV9z76vP0Z0u(fUaxk>~cj?(YevP?a)?oI@|8pByC-+=H?6P1a$l^|`dkvZ+r{45S zx9uiC9*9G)d-aI*?3Vf7>X~X;#VC9*IN0m;+uh^T0Sg*Q@wnzuHIsKe;HZT>r{IFP z_w>cE+*{ufDL^!)L~)SQBn;`LH_zMkFdmqj9K&)m2L~R0W=JqQ3iJU?NVu5_-Hod~ zKUPX*RgANe?iZ$Ex-SQ&*6BTvqeP^d{n6<}1B;!pD=k2(0uoFl0&GI)v>F0QKpv9B zg^ckOe_KMGGLVq~3M}JFii+S_089vmRo319q!$mhDzqf?!=@emGP!kQ7l>4RgJu!9 zHKJLfHEH|w6Bns!rU46L?P2$S2uXlSdmb9C{6wlxIVlK-B+DTQcy1S3Ju(k^`s2y` zQ7U>=_i7aZh5*!r@#u~{cCDY;>c(qt{Pf;5{?4f@Q>Ek3#v;Gt;+5X+u}(_3-=Ue3 z(??IKU!`C^!bb`Yh^fgoSo#8?j;+_p{_({B-!+oY4P`JOY@p1{%+^8~X&D)vlIk>_ zona%~WH{guYf=3q@^?M=*~bfnm#e2;s*luETts{o@&5mAzW`i*{*Sm(k0|3mnF!s~ zz;p=h+N}p>SQEP`m_xHM930urq^P8Hd^t&To~`#qcr40$PS}AWr~KUbHKPTNR7~45 zu570!{bFw7`(j0EuWXS}Ijc>9=X$!j>qu)T(%kNz_f)O;42=`?IhL8N|DODcytcTW zbg`Eh4chW>KkXA;xH(nU++%+9spLrP@e^v?)4+P!V+*zIHBsVpDi!G07s|w07V@rV3(&kjQK}cnh?mq_KaD3KmJDAZF0vlW<+=K8=U{M*WsdxD|J+IjJ)K%u(&d(><*aXfgQtGW!=*` z=%$|!*`-*FiGFv5k}?A8Hrr_Cmu_Ktv8J?5qtAu(5?t+L(v`aM#hS8}LRdvLX@u57 z)LY7;wiN!Rzm_NA92lOrK>0CoLhF4$&an@BYL$(Q9fi~eynU2r_mre#^g1(taOYzE zJgk_|(yj3_9hPmA&`0Brd)v_^gjrA`SwAT%zWO#felYZP*80=}MfU=-EYtAtrH?bv z1y6YXdF-QPNzT%2-#nNp2m+$nxH22(g=ki&G4ogb=FnMG{0m86qR}rEU5+OF;h-LT z7BF&%GPZwFu8V>Lb;_Xm`dyU#)jaXm=J7@|`m#%E%GE2w*ySrHah^ATywVhdDdoIT z_*s2Pxw_Gq(z2SmA$9EjX!CVLbV5RRSu`~^T}!k4ZSgF~1=wHt__=cEQ@?a)h|(Xi~EiJi=}QV+K?RKK%1pc8ClWRz-Z2v$MVT3gXWCSCj#w zN(x=-Rw`hpQ>pi$?d;8`NLJ0~tfyFC-w(K)&P5r~ziIIE&wh5f;+C(=X_9Yfw2)iz zf9cqfq=9?tc|KcPK|uyAGwwYrC*PxbmI!_(F*WZ_iOIZoZ3*ICXr;%d<((ISQspk+ zNQq^Rz{jKuH04Jr12ld-#tLWQvba6B7t*s0%xkbiq>BUHw@>@f<7* zhpxp2Og7gsk|Px|kB%ZNb7wysccY(wo&AsuBbICpb1jOAotJ6QR0PXTQ+DfGpe&x# zY<`YO&PEtSvR|^bZ*M=^6sK#sAF`2fvLk!@kl*B@v=|}szwgJZ7U=IIE-N}AmNKMQ zydNbVZc1AEVFfuEM*oFR4Nz-I*J=iDMd!Wz@pV3{_f2)>3?K^l1;ir9#|gPVHr883 zTuT1GVq5?*#3OdYYATsLVe2Y@N@JIgvS#Zqpa44VZk&G1YSX+N$TgJ5_!RX%laPe- zX}kmVLkx8BtiPYFcHf`bze>gg6JX>X)_I+)uQFreuN4(L-I+?~j%Q_Qpvv?rIp@?% zO8sxr1UHJ2L7@)(zJ#d60P@X&#h$r|bNQz2CrESbacUE( zgzh2&gL7LWAXGw;*&%RM8_TI${fQE`3%JYjuQ>Y7uVJIF=QAoejr$uyLb^G7zU!hc zcWz~sk~{cYl-(GWbui-E;yk^oqQbZv3@jV^c`Y@MARJ6}#K#hU-MO#XGv-&v|+ZDL}Af%Y20!sP5i(hcYM z+mo1A$^lS=6hH`QOYYlzo-MpZ7YFEm#p(N2*}?z`KcNuBO_&u^}LRm*)6cP z@}M%KZ8p+!88|Olo3o=RUs3z{wnf*^PnydQzq{8o<66Azt^Qr^Qb{e~Qgox{WS5BJtqci9E8e6F^I<8JHD#&e1az=R}9%Emotq3LwvieYcP_I_MetdB8 zG8N-L&uq3xJi8|Za%Yq%h6GW_u$RA$hFHsWR=3DXnPJrdqNwso6$YL;`6dm^6nX1RuA^|@d zoXq~TS193s)DD>Kbvq%@$e_OZU;RnQ3h`EGy;iNd%xRT;tE45Rdgqm0(_9ZNvdr2k0tiQ7A3CgNB9$Qb?$s&Y|u2A4A54uRGo z0VIknwH@NiA&0%>w#l>mAOX5;VRx&GtydQn{sdLuvpBGw`E@BFlw)UqEhcT@c5sjeNk@1ud*wo6^2n)u;f&j5iM1pg zY{f4^ecdsc8yd*wr+0tqeV2LGXkRc{CGaAHR>@Gr2MWzEkY2LZ5VDOpy$q@fTGXZ z@zCP~)`f&$qbKD)hN-UFy zrwTbT1sv6t(RbSZn2!xi@(uD{>itP4*%)|Ry&I0m`pBa<9ois8D37X8*l=)VpsV}P zWPpT6LHwPC{9cPwZatUH82DAnUrA%1;?GRB8OL3aJj^i9S6504{A#TfsO(;i0~c8$ zv4E#kE*Hn+zDSh4WI0>b*fXtXv#Bt5G%=CEW=4fDut5Xi{xelAq%O)Ryd0Ha2t_dT z(CG(0?<>;@dD`+;U-ai8C+pdt5Uuw+#4{HQ9ED=$`&^6#+*51uOq?R#`nkp+j-PTu z^r-LCpx=iByq_`p=^K1b%RfU*1k0_r?)7k9R#Lm>z2-F6Za8evs6X7{D4baxi6~LZ zJ{ONMqLgL47B9$DJ`4pVD`G4QN%!xMC%H=Mk_~Z8)D_k#heQxUcs{)Sb!aF=^Blp! z|B835*Kr}_od@ex?-_z#^ds7m*R5_T{l8;xEcyX^jUUyt_dhEt;*k!Z#;EQJ($8l_ zjQqtI+oqNa;lB*wR*Wi?&G+N)Fkx4DZ@=kO(GRo7zF0GeqkFrfMwT0Oxk9sL)&HDj z4p&!usG~!c9yIs->oKIguSEP5{fnk~U&kV;4qmf#@xOk&%5GSL%{=wG@BlE_m#OqL zg+}u{oH!rjid8<0N~E@RbeLM3WI-TZ^3pHqj-{ggBmY`}q%jG@)q8np_ZL3lUAqSE?MYBre9xU`dQ|uq+PONPZ}c@cS$gZpgc-A3-F>`kMW4 zBi$ya_UR5SNaB2GmX;7`e)L|L0_1EAB8zymg@YmYC#@6@ZdJ^+-!vDHL zE6w5fp7+3-ehfg>vWr(Sf7eu|LyF9&NM)Z{bgRO^E0CD6u_=IeFXBt!w{*7iE6jUE zS4mA{>-WioeyXCZNeCvPQZBkk)W8P~M#glsdF)2E1NX8D{(jgVYdp-BhSJ9M&r-TQ zs|B06x)=Z%x{@I8LMWLS{0D~pKD?u_7?LMvyXVdpczv(TvV|Ng_rKu<_@f13e*_op z)}k&XL2ZED5U;wBw|14gWHAI+uifZ-HgoI;K*OVGA_zp`In25jK8N~}$b27NdLt_3 zc4A+oFI$0z0Q%r3$3wDlbPhM`yHW$T?i$f*n zc8f^i5?@9y?Y|_fCPr1@QHFFAJ+PEejHi|n!DW(OXRT8myG}8EeHhz#5z9x_ZA7% zWa(7}2J$~NtxuQ4-hC{7o4Em>%y=7sw!X#v?rIHl)e&^0z_;pcxDq;fsqmcdlO;St zOfa;5$;RHMJ9fhx+%k+ILdYi$pYbcC)0Ic>_|u7y(GvVh2WMm}dmWnAp-u0ndw_Le z41jwWD9Z$6v>O>M91VNcVLbCVUUQLqolP`sdbOR9PucM9qC4cryNUefFE0cGAB*0?So|P%!lh}SQGr#KBcY0)TI-oxtH;7 z@wmom%<;SGgqmm41^cKBd|B#d)h>&VeAj`SjA@@fb>r&aTJO=!O7%y{t1n*noEYA- zDevmDM|cG3=InwWf=>`=YCyDv{F%ApQS<|HY;AICw2+|d>T*39)04;7du}w0N zBJkFWVh)Lq%Qcrz3slp&4)1!W6pnvcUmFg*gMiJYg$eRbTl@h2Puqnh$nQxJP6oux z2Y~~kaF5!(Y(SgK&l=wQBRMvOCO$ zRO)*a*r>+A8;Gkfd*s4W#WT3&vna&bb-QJE9TS$)d$06H5}4QulaaNN!AA828?`tC z@|gPZof;!b2cJDJL^}FZW3W1fkl{hZl`VC&*^oh=O(a1{g4G`9Mn65EUjKM=Sg z#|G)&&2-V)rN9Q~iasN&Q|Fv6hslqQY3s#Z5g{jbtKwZnI2BedgMEsh;$}BUnl2p} zNCXO-@-Rh4f^%v#q<%Z|iPiYu)Mh&o0-usaIru~jIYrzTamC-a%lm8`Q@~-Of^iSM z3B#YMH0p2el;yL~^n!ah$zJ=8W=`7N0eVxHyZspwB!;_AvO8d_3fi?bhnBa5|`M;$& z?V@=jr9ZXH%6A(63fvW^3pUDctxk2WU%Hh>r#@+o1+`EYLJ_?z>Y*YYJWO!bgg>d{GH!{Xu`yg4PbwIK;`O|CxJ!_%cOy@1 zBIW_OLIXK)(g)H3pn8qZ7mB_&S~&zwNegK{%DZRi?#C7xP6x5LT=u5_wB`>$CWVDn z57!Y~37*YNw2fz2rJtrcB+5*3}?tZA%n_Lto3-PZXdP?4AOOCFb?n9@}a0W;3|M z+Kzkc3sFh*3^;_L=sg&aWp8AKDFb|A<471XckMLG=gp#1xnE2S@7#vFsgDu|h0ALq znD0RroArWdOq}dfq7D3QK6Uaiyis-gD4%Jbu{+TLE}0OZ5v05r`ibd#icsuNL6x}V ztatMCBwhFr9f!A32IWmhO==xSs-WTXkZ}6a3%%h*+v)6gJd+vf-wk?>WM2CmE8d>X z{{_@EDl+i5e|ALTQ-eoQ^N1MfN}*6|6t9hbvRJd@U2H=8Y2-uL_xtJdMqbIK-f4QV zU}Scy;@u=!gpcK^`N%uoOz+fKix)J}SCWKP2Oyqmvx4=EBka7t95$C+UmLv%dPd}{ zgR(ivjF{~u*;Bm&eBf^FUozBf4p zZ<=}fixJ#6k8PEX8bK0T7D<=mU-E;C&`Ev#{N2zHzNLrt=+i)41TSgcdb$jvM)I1) zK)ihnux+T|xqi3s4>Y`-Tluxf746_@b0T&^OiIiX9oCLY8)rX1_Ro`F4(sA$NrB-*6UA@qHzeCQaXA zXY9I?)AzI|^AUMmgzmAhio&vkVzfz& z^DZEE46o7OUzDa%!MTalDzYg!)_NTlBHk6p>ve;U(Xy91jaj)t@GZw6Yj>9{qAJHU zk5Ra|2m|+jNZ9evU}w)#2$tUEYrm4^BFx+<*Jt3Xt7OVo*OL0^UaH*zG8^{U^K*N@ z)xIY!cYO)Te{FWjS?_U})Ju{g*Ezxn(!6$v?DbM`;5hgN2nP_Nz!V_}M7IHl@1Og( zTA~5Gt~(e`w-F*L@bfKd1U+OonaTII@Ga0V|Bkwn%97-d^7FWS&v_+C2pc|*$9;NL zjfeR%9v0_klT#L`y|7LT_Heg!I|fokbWV)v!j{pTonMH3ezb+Z#0k{<@>_D$O}e#H~Z-yGY3r`#6RpeRbmLz z>hH_q%^h4lxWNRQP2hwjnunnpzZ6s{B(+_=kQU6 zsZz6=!Bx|}RQYYqoW|yll=O4gj~~i!kma5jAeCE})C)oO%bB^c!2HW=bDYTE(T}I- z>v&0NZntB^E1jBB-gxg^XNw4fbR-J-Ij<7!$k5+9YVQ{Flb*M>{4j}Q^XZv8Ipc~;W2HZ@CPoOZ&a6fzkbgF+jOd^GjcNV|GyVZ^{~xB96(z@ci)92&IE*2Bl6NFV<5j4# zN1w?Jqs#UbR}bXYVgHv*u&}!61w%sp#Z?d}gz1in~c71}W zd6>Wtofp;9O3#&@Do-bECay~5WEPxpO36TeI|FmZP%wmFKyPl9tgcJQFg$?D9k%G* zP4>p;_&PbvOk1}`jIQPVlJC%vMLbNY9QJsmW(D&3x?$oH)2Z+}kKl=B%ru2J(23{DTame_4wJ4ifiRf!)w(R7hPFjjMio4;;3MP#O0qa^n!&~ z3mGCi;#ZzUAn18rnxhZzTd}&>#C#~Zh8jIv;=Hn@ka`)5r!&}I%sDGpsVqXpI)$Uu zwT-IwZTzg7@dWN-qbFaMKOsH{#U)prtTd7EfZN z9{XAtNPikZo7u^{r*lFhrmHawv-SPF#bvFIVL?qSGCQ^V1ba&?NY%eRLowM$hSzjp zcjcEQKM@2xZ>U>8^vmLc{!8%64FaA$<$rV)`9&};j@wJ$uO#BOx{Z^}`ZmH+|M$N3 zpjQgJs~uIR-_5X&acK%-7&j_eL`pKw=zl;ST3Gm13bGNVJX zY#^(40{n?GNG&HYAb`!F9wf@XDSdp%#TMkLJJJj>jad2 zp0-#u9#``=qqN?9o!-GSTRu9<6}%j7y~QIFJ6__-4e;Sj1fvx(%+k93OBqrBz)M{= zW;L`kJ4QK~nUmFtQ{Nfrb>fii9&we|6SX2bN2h6f+Dw+5i;n-a-ty>Y{`mJYza!Xf zLIjCGk!E~{BB@A*reQETxi`+vD_su9ro}uF7T1gePnCh!v<`~lW1qRt+m^ReJN{C2 zqd*Qr&ytK-Lin}(x}5!hHuKj{44|8FLp!Q|_<|-CQ>xm(C&%BonG*|B4^)J%1~1>H zRD_GO%{l8NdsMtcUb=AVRX2>wuD413_Yw{7Lc#^wdZM!wHh-{#r$ABI6a{SmcJj*U zAvJ0Z91vJU2?IjnHNvJ>mCcWAT-nRV+9&*vMFM@tMKZzi9n6o|(C0vC_!TZ)%gLqF z?R0BH*mIN_HwJ1sc8IR=@ArYvxW5aaRC%S^bd_Y>TKu84Qex&Y$9L-Ev~3ToxoB7> z@V;DHiZ=MMkjGfn-qR}KP2%Q_kUI6WgiQn;jo6SwRQGxs#)WvL>b>&JVy+p9(ZYUid=T_E=5wiIu0;?U+Dm#FdBCG>xNjt-v@mgWcOgk zBnmbEffEx}XRSIWArCsi%v-%(b4kCfYwm4Ec&yGK>g{a#V(6BmQPHEumG0CFx~?09 zFMeL?g4F!!gB&AZb3;Ied!5nH-MgfM^x&*$s@s5PkUb8j@AWD$IpMm9*3vj;IFG(+ z>7?=uO!#igsgTQ<3Ih#NZdaZp?J}U zK7Xfo10$#qtHOq{V4$CKnH$B?)uBYpulrHC=iY;!c&gqPX!;Nw0nH~u-@}b8%3&pT zb54uvqrWqB7)9jw1S@6q59+P&9wFeu4!w=zkq?{5@2-sfxVT(0QRQtX{2z!oVxQ_9 z`Xr3Bk#Yks6~c9eu1>m`4UEV9x0<-M(ZN8I*wMS|1B#NAk6{AuFBgRAd#zfJ)Bf?H zp#g^jC1HO_2X_+-lR(fue&Pc*Q{4jfWjZu`P`>`YMM)|V^~9$?J+p`>M{BM zOPu)mlK7pKvAcxv6Fl0*W58SKi6kJJcPAWP`ZJ{Q?dT7y?f&N}?V7D2jlc5nQLf}s zGw^O#ubJb(OzNYe`(vToqER2OM|G{k#Pm0CeBe!}w;QCwvdyYvo>y-@I{YcQXzl2C zVrv*ro5uvMuj+N1iA?;4ASYeoev*9XZjVM6%yzaZJiG3P3AGvg;<;Qg7=l> z!kLQj8m-@%aIZ_4bdbSEEQnbsM7}*~vrx@!P<3UZtJ~m3cRa-YjX>;4 z^xg@MT$((>W7@_G5frq1<`sN&u)KTljyYN0!T@zG)**=H&Ck#Gw0s`T%L5KLhrBf$w6~rd<9^D-n zb)rzcv9e~QUHx~_^bA0Kf{UZQtnFT8E!?t!N}m(~kC`+Eti;#|B7XHu3D=Y(bad{E zT^%DQ)=hmL#A=3XaYl$pbQW^FkoK@3kK^j4WSL{KQ^io`OM5}Pb>6S3Je+)`6nyxl z_Bs@;ca643p$0r!1j(RpcaG!F4Obpy2#&**HM1VLl!_|bH3^cykUB`?hU-YW`FEEe z-nbG<$Hvc|H=Pvyc%Yo`_eB|oi@JA#xh#jMFsZrpQZoj1aHupqzu6@ThW|04mAlfC z5&ip*r;Kfxj_!n;^K^)f73Sx=6%@V{k|=zt;dpv|))cyT6$Fh#mDYp;BfIVJ%TFun z+GsMCnNN!SR1mw2C$#E8YXtv4w9P?buCiWJcQ6+fg}1-rscKcfVOLS42ho!*9#4sK zGl9M@Q-+%-FVKjmrkAFhEWA~%%L@yO0`^Z-&38ok}_^Y>GS=8_5)i%miQt*NHct?)%ePIM@ zikP*LwHEI$Zo*svacPxX&VI=~4`b0D1GdLff0x|vz$p5t6H5XewZ{flGhYGVft_ z0HTb~$>96(>sO1px;Pl1xb1{Pt7L0Z%Og)a&%fKtS3^sC&68l*npOndSLKE%hvTTW zyO;Y0hM^#oxP+PWLx3j$hs!*lSiy_4$tB|Y2|rgn`BfB=a2zf6Re6)JHVcke-i7B) z=qv9{U|5?Qk1P!5Mg!%lzs!r?;^$oO>zCv6R<*>(Nv>bm&Dt_7#*`7?Jx@$vL6<-D zz9`K(`}C(^dS8Q&TGxJZ)+7sh7$;KJ{({=bg7xuVI^kh@(q*;7!G8x~_6i5!>w;HQ z><)VV)AgyG>Af5A#FOagHhnLBBPHcHFXp|gxBOTm*4&sI`!wT;Aql>{vw;hckvJ`jx3`-ZOt=q!Z@n@^w zM+hn`iQpA$tg!SAb1Y0f$*UT((ldP%V>Zpdsr0Q*=-_BdoyH{%fNjqWJfeBeQwgeW z@3*lNSTLaCq=Ag(Jpzv7IVvoDbbCd`ZZG??ds8lGxQC>(E_TTsnn{N1qF{Hsoefhq zCOlvVysCI|YEl`mCG;-CQfW;cr7;v$_rPLqLt&Z80=#Nde@UYCWYQ#o{^Q>u;Z`{3 zQ0<%Bd&D8}oM{CgvLY6QY+KdjL^c$>2#77AHMXh{kFk%*FWt0VmQJ-1;pn$mYhCx| zw)_xQB2I!G17NzUCx@nt@XE=jR0Ra5=N*#;dc>{8FltUrzbubx%Vsd-@Y-$K?8n9m zR}#8QnAw9Ru8pDdbOlK(U)_vL4C(P`v`p5z6y#zNx*QcM!Qw4Fwc%6m& zdY&|9$_e8iq9EfqPlb1kA~}Qyq<~i}%`Z!Nzl1*?rk`Ct8>A+-70v9Tr`h7jKKCL6 zvB>(IrGmKscd6pG=f#Qa>-~bjAlO~9!TW>QGf^e;TBk?TJ}OPKLc z&Q84yT6=Q#O@!w+7aa>cj(AXy!klTXC!WZQ%zC6;pJ#cZ)s-5wZ`7n@^eB+NqPFG8 zDljKmg-UD3y{(PocItzBrKo4ALTxEk5M%=F*MA?l`2}!1X)}6A6fI1^tBd1tNMlNN zv!qngCBk79E21OMmusZ-%qCX`6I)T+mh>S0wO>hZyUSZ?$bXcn#13@G1HrGVP5y6B zIOjyTgp@)Us=Uu26QV7)SILkAG%wi_?<sx%{ZD z=WbY5q9#V-u~Ufyw?!m|7G+@5v&=u_w&mG{hO>dPDZB~JM72LDxW5s&%?n4b3Of2y z{)yJizpmxO1`ANs$Y;wNGc`Mtf_*M#e*H=Br>axiyWX{+Fln2;Pg>dU0@|JF$b#^v z^fFa`sxE7^dSZjgs1`1|+aZKd;~8p>bY9N5mz3t>T9W44txab;On!guB12|hE-FW? z?jGzNM;LiR>bz3bpi;ZQ@NyXfOuhW?dDGciSsQMD%{=1$r~=o5 zF8`HjuPa}_TB!FT{)e~_{;E0lf}AYTc_0aL~7xeG@N&A8?Dn#Ay{cUa60+ z4ASD7yl!m3G@Zwn%e+k(vCQ|*dt}!S^O?M6^!j6_wJjW_%6$KRU~<~&!wb(Z&^o)W z_O8A*ecZb?n0SBG!SXw9b!yr$_yTcy#-NRigByKI5kC|<)J2Xt=8V@QD>JFME^^3E zC7zz=zXejL@EPULoS>ZxUYezcK993KK0RVJ=o(rTkH!qPO-DXXfVD?b1bBa9xgRMd z78$H`!`#Y=8{VF?5LYj<uGVWzdxIHIf2y_aq}~KfP)E}^x<d&s{^O?_co^$TAJoo)LhGN9Yym_RkiK>)W$Fu&BleRNT z-FLL`I%^t}+MmYD2W%6WO0`?Hs57k5_8t+BWh7`p{Z=L&DSes8Xn&i|nCkaGK`}kY z>DM6PhtY}&;U7Os-ulK1$}r|!Fa#Gv?7sBSej#c<_iN@`1G5oa;WuL6m;pdjZpUbL z-}%z?pu$Xac3y!AyRj~B2{nC~l8EAs))MNjW$z|=Bh_n-jvo|CEwNk8<(9#7&Roq8 z&)DY~FIRkab?EcetxhqT7&eA7-PqbOtBmi;*XVbT*~g(u$v8Zjp(Cdq*deM9{sAVl z4Gavz1eIJD7eM+}yw!zcE;Q({%n>ACNW{K~@Jt1kMF`#klOZQObTyf#wRUq}PDyU3 zs*eNphSx+a=1opnUep3k{WO$NfQS&TZdt;Ow7B>0x4rUk!-i6^V{r3cd!*o1>c>`* zDqO?RWbC{_%>EETXMLkj0pCTBuL-H=PdQ)Q(-$A&kshc|8+r)Leg1`tl2br~%>v4X z1x_Q1#U`g|0|i#X(y^VxaJ6SI;(METN&Rg*#p@aRwT7lZAU^7BvBk*4@v;xaymVZ>@jGOYCFR2(BKk{7?%#u9WG#I(F#2 zKFJyO<)k}-zk5sJ#wlE%qOUv&E7P)WW-XqKzKXrfvKrYj=X)wvF* zjJ}G8jmK4YW`@t0otixo^`8pdO<`a`@d^qyZ*SsV7J9SnLWNYekAf6;^DFhgJB9d< z^FMMtdNe)Bk~MBIGKGux7j9`Ui+=Pk!*yMqk=zX4F6Q-`6QMpDF^1h@Qr*lcGyi1y zJ?0z_3WE9l_RrUkn>#wP<8gVdLEI8T3h>f8r=mL?B8kXxRCBe6U$r|v%3j*9*WMB2 z5$R|TMuSwuukIFlo5Zo2)==+Li_1NB6ulPFf8Jir`f%nXn-Ey5_KCjo0A;dU>h=1j zCZ_(}y8)A}VYKy#qnEdd$iSH2JqfYK!VVYuCe)d;eh&l^7m6IMiNEaeRv{?17)pR} zr8Zh%52sV5H8=en(0$?s9u#}i$Q6$j(ERKFY8w0u-~Sg3ErsA(RRv#Ji3MdsLWWZ# zv%hn!gx8*El1}4@vHBR#%ySmy;Zt0<5E}!qh+eA0;jl%I-}0 zy+k66kH>c2sq;}W$&JBIwMB%1MD;`X#(Vt3`S^D2WmrB+=X^#BMTkUgG(xujQB23G z@hJPP!2O46e0b_AgPK1IXN3D8;$bv3OxUMEt{N|qx2IYDkL2U}>(E(*X}3Fy0~a1o zwN=5lExnnwVXxk%J`h?GAjw~-sWFhETU9UD_2tEv@9O5Qo^N9*#$kAIEZaGeBEfLh z_*G4BYHzUXgkWCPr8mxOXW63>2p%JLxRnHAf|G3#M^6!vEJB*mHCtkBqMn9)jD|Jd zHzqh2H7zHWQiH?M!5^-laC)v8^6E(3RWgHhYxETUuyfTxXP@clUke4}kp3V^^#$QB z@0VZ%Ue4)Hph4y}Jwa73@_zUN9q_XH?u#f94c)eli&heyDQ^_D9B*xIuZvAqKa1>2V(V5Ha#q;N?uq7JV{_##QZNv=@L%#%VS;o`=>yd!}(9B!!7o48>kT!ASuu&KDVprHR^=|(7 zd~&s>?fBeIExKxaWW9@1aLbuSB=@Fnm@xBek{Uf12hJi^<%7k(ALJ@na;<{N{244`3WQpu^ILk!5tGIi*e}x z(g61Z_q}Qs9J=40bm?F>xu9)t<++%X|H*~W-cIg-4jpc4Y6|_I>)$Ol`?^=u)va-UjLG0 zA^uZIs{2LvhlL#(f=2Oc@<|kTe2no=_0yU|9DJ(ALlMPx?`L_NS6e}qad5A&*UBqT z((=+#+NV;bMd^9o{aXpXsRs~WIBm)La0w`e!<9ownY{eCqPpgu6!r~Lrfb50=Q$-P zaDV?}S?T1f6J2jmOXch@8?Ua3N22qtSOj&7VgjGa-S;YL60y9jv7ESx2AwA?Xr^t! zgQz?Crg^xu<$9Yz8z3kr1fR`8Od#)xz28Xv!gd#KEau_pKK4>t&vX1&(<)WCca8?J zZ2g^D%z?+rjLGF%KMl3KWt#Scgj^Aj35<)LGQ`N=UbCwp)e?p`s0g)Vscl|)MT-Y( zhv{2)9i%JQ+uPgCfVHReu>LS!zo>_GiBav-MREV*RdK25eg;2m*AKfAMyWzw>#Fna zqntanU5OVW1ntaxFUrLS4g|J*%=R&@*)6w{A;jwX<4b(iIc|-0qEIk28Xm?-o|~Go zRtgOVwfQ%+qK)z2S5%hcw5K>>%uVydwxwdIADzkL?b~tk>SPxvchWNXsX!Y2k_S;3@zhG7wE>(wkaIrTnCnr2DM#s=sYo5OrAntoAx0Vg zA?1!N#tY-?IvbnV|4<7Ez6T{P?kA(06+Pkc46xdzu`> zZG_~@nHCU^{&KgB1FlgA0O0fhdA*rP9VzV*4Yf-(Cn@t{RLNoGo3o-WbE3PStYiv> zdt{V->-VuPE6k1b=h1&qPyyz0ctU~mz|J0 z(&_Y)F3enD(a2mp{7^vg>D+pP+{0~QP)vRJ6+hau}^4F@~-~Y_xWhY^mZzr1nZ9JjatLXOMp& zhFlRiCgJZDgnZlzPnndp7FycM90Y-|H_|${t|x}^fbW?w?`ZxQlm>)6a076vJt`?a zKHiNmTC>wwV@A*b>DR}3xSX79qf+$Xem`xMZAt$4LBwtT{_S<-QCU^ZE6M_m4-V~t zM|JEVY5@xhM#0~|CrJ#7N9zYaM0!#!;3BIoqBG>Ezqz$F6DU(i=qEb@XGQHM?91OF z4Yk{Qa=(pg-pnkB(pypVpt?6}vJFSg`eikBS?0VXUu4;mLQN&Xx?`zJ%|*m*n*-SX zt+*GdNJR1e8$$AaNZ*2jvtY314<05BRMI7B%*hSDt>^jeyZ#rXK)D|J0tG*Nivb=|$$pN;-&Sc~~v0QLNb1T!JY)hBlB zLU-Ty(MUIjB^fzAc8iJH1)oKI49Fco!I0kMdr5otKkKYv;3YM!;sLfGg{O1f$slta zYv!{xod)wK?wC)_aaim{zM3Bs@k;F!K#=hoekv;^D=)CCI9SH^K5ad;kn!4|(# z5=Wm9qd2ns3f~P&oEAl9VI~AcFvG@38}hw;l-L;l?E1*1=^n1@(X5@vtEw?H4Nev7 zAoN~Q&jM27E-!1(zpz%UJx!V8Tq6c#l*?x&R9wzQ1YBbNV zioe+t<+-IieV&VE-|Di=yi)Lqx~)aKwtZTvwoi@1aJvN2wmzeY&xU|e?S5`%W`>e> zIm~C`myR^`Y1y#18(rgF<3)>nUdWe1nTZ=qNAt|k`T~#+-?Oq6ZFt?V!=4~>G48*@ ziL;61e@fQ~Y_;=Pt?lza$go?Mcg> zQdNtM5brfW1wPh$tm}`4+J9T?i8^MVq!%t9dbu``FDL2#hUZ3iZIOHZyB4|qg;uhO z{l#r0AZXGn;yMovsH0J3?>EJ2P|$blQac7k#DL9J{PpyW!z57K*o9I$%-x_)5N|Ue}q)+C*{`-~Q!eH*@C6JburT|c}cX4r1`kwoAbgw7N zN^ee1S=Y@nZI#JB^8?M{|T|(QILkN ztAkH1@jDPrRtjqJvx*^4TN<*wC{N(Rg~zMyT7bUn7fhYd-?wrawwHbTg(X(?52%lp!1~kFZDSe-F6t76eniWfQrID;-%6ih;BG^|1yh87 z6%`j~D}NhP$|v5OQeAQv!U-`dyX-%i)wy=83MW0Okh?!P$&qQ3qY8OPuPLmVx;<6{ z3uD7CQq*XgXdTKzy=;zG9P)O&G1eM)>L&D)fFA(gpR3?Qc|Mz!ne5>P8meZwx6#uI zKb6Du={e`gUA)NFg_h!i&}t;T#aVsrPGDn`5M{Y}?8&<38^ z+3jQ4D%uU|{|(nZ@tc-Qg`=n6V}s2&ht@=i?i!xVYCK+JiTaGez3oRZD_eil^El+_ zhpT^9h2Sm>_LK$^#qOL8X0(%wdIwoPiY4})yKyL1m;VTp&+D4QDNKe-0pH!!d!^DA z*LI%-6&GuLe&HW=Cw>NXT(eR7%BF!rL<;3sFPv{4YiiP5=>t8l_;}3o z-Sre2-Rlp|KlK?Pd1pI@U1100+*Noso@}#II2W+sATeodQKF9@$ryh(sUZB{N&y_N z5k-GTLPMDk|Y z$-5?=d`!yhkl!ltuzS8%bK^H>S@rY}uX`piI|2cG?&55s;_`XcMJeLsqyuB-1k{xjG94R1vQm?yj`7k?q*M*&YUp6wM`IvN$6n;|npx z^=IOR_0gQX+HDB2s=Z(<6*zpK7XFsjwydk48b!u?{(hXVqFx*OoKu|MvE8?ms;DWv zf4CB0LDFit`#r&zg8Nq`1ohYdd7~I|mj-xZjbrw6M282ibXQCd=U(JTRvsSPxwv~z ze(b%6tEu`uPkAd0Q0Ev|e7}KQDo%RX$ZUm5dCm4TW#`2K8W=ns-=w2<%j+f=wSv&w zSUArxt$5}?#Ws@+biX1isxw7c75r!K#>NIeX2th#wVVC?xP#Xl6{cG?_W&ttyQ~aM z@4wAeZ+E5TgUW?d*jMThIEMQV#0;a?zo9i>!c+tluQ>cUO-&j#l$I;J!9T>8oyqKtyr)TD4p$56aC-rnnz}G|aCD zp`G~$YuDD&_GL6>W+%13B!?-6uD3#r?+OSZ7cJfyF7M;8VnPraMXE*-Cp}TswVIYl zRNU2c-`u-pmOeg0Vd!1*nA2D-l>k|a4~S?tFQY_EQchyT`(xemFjIs4?@}3sR_-0% z6GS_Rnvz1K#3d#=1|Pt#NO&k`=|-9k{c~AAiQ8LnR_7|YWPa6&5;L|w7UbaY1Eml7 zkA%F2c(to<=DAdovZ_ol1*!Olfa&)K=UIq53U2n)%Xv_F4@{shvuuf>rjEkb|L0O} zAB9;P!Eh=vuJ=mLgYIu~5d7)IK8W8+P(<`0u$is+Rw;MwTn8pBKr*08o=}ZHcXk?# zu9qNU%gp?ed_wU=gAWy}aN)v*D9srQjJDXdsEM*Bv={FYh7Xg>_=5*z7I?h5B!Ht& zRW;OaFQ?qK6jf?JKCfrneU__T|ooALX&12G#4FP6cY-By-y zDaTkMLz|oL2VtL^CnCPNTDSgJ&f)mkK%U8a!(Tm^8!~v@@;H$y?c|IB946p0vkz8g#tcbs|D^A=t_KKHv z7dA9k3#*;-Hd@fnf|9+DL z4yfVMhm919vXBq?Z{0}66T2B9#xDi?i_|{6`uRFsOLB#UZG^8xIY_wPtkq>yy9$FX z#--Q@mrUxBU_}o0w}=n7ehl%mMR^DHN)NI0U3t~%$pUqO z^U7!6Us)*hZqL@gtx|ZCtSC;(7UN@`B7UA!AhZwVp+i@IlxanD{giWdgj=Id@Jg_F zCnmY}TgZQeiu`x!CH(ySjZisxv@+iC(~nb?JPLwGHMeuT>7|>;DSFW8a5%Q7Fy#hU zeoLg*KE*Mc{@GLQF~7QsK<|F<7%49(5)10tJ5fZlR>5HI{VrlcZpyg=KPt4#<^B+1 zwn21H_){yxjX8VseXHv+=S%LHUuJ258Xn!WAri~~GwlSY%K3k${h-7j>ewOe2l-9d zHLN~w3$PPbg^&4r0f&;e;sDGd&8i+(frP>sH>fTEgM4D_9)4M;o}_-e{mCmbX;NVz z-$En*>7#}3@#mbqdVPeF zI(56z#)b=!h*(uI_FQ6u?8IzAnR!4DqZ*H{lb6j_r-tL_2Y0|{XXqv5)6HgUDymCY zU%zg-S=wiHKe&#`CD*$hu*F1oHYVd|^D8#{bj5bN3!a2ddO?O8QR7LHYivEe8a#M+ z#mf9YwV`~5kfiU5dz+1trA2{D*OKdQsbfRsGyKY2TG%oms*34j((dg!P~GkpViY}_ zRhp_LRBOGlyxxKI$M;;Mu#@WM6@Frn>bsAiU~sNyO_ovQtL{cQ5QYe`e?nYe?Y22@ zA}%+h_-jO_Q)1BQ!7*e%1IAfU3T9f*OKAAli$Y3zakff9&0#2dsGkimq>^vuELIus)c}XAdL8w=;l~F zo!xiRb#dS&fM{j%xF5C(DtC4Kf`ZiC+d0nyX5F(qS@K(AN%@G=x&o>nvUFT|)HaL6 zBgiW7n7yc}5%}*a2T$uCMMQRpZD|Mh0nzReIJ6N56BZTqR$|NYs?AKeWQ6$m8kR?@ z&Yn9ri3SvuQoY*3kDhcNt%4HgXg_|lKd?n2ZS`;#CS8~dBdRH-!^DnUbz?p0mI#O++OHIsk_n0SDMG|$zsYqYgw zz9`GgQ*cJDiBr9;?n3C3R#?6cxG{I+9V$NEx#O_~{9cUg)rjuZN9~Iiv-1JXMrJjb zQ4barxC6Rb8qkB#SskznQ+YyM9K?-0 z?mP{T`z$bX=f_mnIra~D`KVttmE{If8|4hhfm<%!Y||^`q>Cchi?&sa@yO0UAGW zo!$3k^Py~4SF>2yx$E@w=|&k?&1WJK86+(Y-+i?|?1zo zF!^_f*kC#}fhbV4xOQ-hXB(!>+Wdo5JODWTl<6K?Z%MzYyj2_4({tmV$9#HRaxzgE zOIg*gB{xfR5Rv3ur?RTsh9iD6r*e{IBaKju)sEdG8vmxPUNj7H{&X^&( z<)kv?z9@Rf_a5zPbT%0TjQGEC-*FbKkl@{}WA-?9*4<4?Qj&5t566Fl%kLy6qvai` z1^ux}xX>Q38$AJ9@}W{{C7C%dvArlheCb(IrS~fFxy?n_JapdK=HfzsBorD{$&^R` zOuK42=C0~o<+3SMm(fc*K3ca0PEw|(PlbNBXHo5qis4}kJKb0`Y%-Kbt8uOK@xk!; z(UXU)p6h+xHt8~kz4lkVWvFupSwyGzhz`TP(OZ(O!dNe;_8T}?E|m_C;+)FRwZ#Ey z7A28&j$<;oT^%u>Dh&FV{rRiG6CvGaq)S#7qZB{E$BC6x1{Z=@XlOxZ4nQd&}FH zo%1ahq7b#iAXjkKZZq0W`mT*+p_We8t#4X~P5ndoA#nbd4~>T8GofYQMR*b@a+I?;oJ3nFDyhH_@?y)e_fA$hCFSQbt~Vh zmBVqUn3bNC#3d!w5N)JA2fL&tCI8G3aPi>>W;bKc+$K?JU! z@FShxT3s>>dk>R)Rt2m#&7wlv1J8GI>Zt%l{#1{8 z>WTpz!>Y3)*cg)R)t|<$E(ON~^-r}v4z0#rX&SXuu&73yDKI*(Tl<^^ZF23BuFRE` zbX6WSJ#Rl`bnj(micjSeLJg_b+0k)v!lPz4(?9%zfq%j^jIwV;2K&)fG&dNO@Z>^4 zlQWR+9xLW#nA$wU@nG^~RrM8bWg8n-h|a6q`v|C&UIYE}^fqVdUFVujKd833ax(O6 zKP8)p-khq%ACuY}svr>LIiq zzR^QB_(#1YW%o5bY3x>KED5>dT_;lYvzq#83s*zH29ouW>dU1&o55R!cSd-x0MdWi z-=onP#k;18=Ju!-^#P7Usp=JVdO3{~O<6fd_vF;2vN0cxoW75v8uh&n<`cCv)C4CH zPg{YwF#ErV;)^Ofpyz@ffu|ThlN455^{tZ@06*!@j<_^jW(T=&|FCl%)ew#%J)v(> zVbTpWz2u!;M%_Os4{be3)Ku8wzr!v0jrTZ%`Gd3zZMAFSlNO@1GueF$YeI~k#Ko-^ zC~ua)+jv5cNZictGseWyNLx;)7Q{QpiopLF^myo@cE4C@1EpRnH%x8((n!FSF}!Xt z8l8UL@%~ZLtu5A_Y#hEET20-KaxOF~i8cb8T2LME;$K;3r9X4u$(vNkXN}7^eL7uf z^%++_^A*bg%p+qTy>%_m&>n|xo)4dQ1ohf4oR58_fPvhroU+z=Rz+oL48jLiPEoPa z3M_+@?bWy9H`}+!kOiZMtzo1Me@0jJqZmTv?udQ=554M_y z6yo*3FecVi_#MB-0 z3AShjLdB8&6Cztjdd=!|G2$#I)LG~`|0W(c8F5)CUJ;N>f>RxpNGcg#3Il&p&8!A{ z<=%8{xHAmpJX5J|L+}13(c7xF#q6gdeh;LxG7n*YCmO|s0B|$_ZnJt#--vmg*TRDF zobk1~Z-e@cV)Rn4-x<{y2fyYqvoZfWkCrODoytG7uB+$gK2^TC?EG_%ZKu*id|Q7&E}!J=gm0~ zGM69xOBYvOocB3owd)^l$ATgxz=nCritA7)L>{mQ%R_4Yo!q-eb5sqyd-_2^Y1VuH zed=7fv@*ThUGYTXYxUYy<(2w9W8_g%t=m#lQxiW7HTg&d9GHmIRSy7T*Bc{ALkuR& zrV(U+q|9x78f;E_@@uvDaWU>1&sL|G?PSE-?-8Wy6kmaON zPug)69Z! zn}$8^ih9O&;o0`hG*Kcwp1U+3`WMf=H+s-joBemuvz5zAv$L~f{Y$R6jyI=t6D6az zjx#kBPbxqx_acMWj^h+=6Lq395^hpL=PV3x#< zHsk~bU0l2N)tPRYRj#L#A@y!qoopR*-B~Kbc0U_|;(%-h1*liGFA3J)cVrNWSoFp%;(Y>M$AwLPXV4U{tZ>WQcdU)T9=RT;l{(x?a1p?D;yw zs~?JR@cpblz;gfZ2kTZdgN!*iOg2??_3YwcQCaPRVcyNc07Sm><$CDhh9K8=NF#1z zoX@G6Nl4uA497xvbH8Of!l()6D z{pvk^3bO^;4(o1}U#oO(dqY;(>5@2B2Np$`42qhe(Kll4)hc8C2J?Uz7+i&q?pu|1 zqZ+eTXs5n`uOiN2IPcL=Xly53mP z0HFDN^8hX-262n4y(@*_{WRL0mBu8D4ZLQA&({uw(nR*XCTK&biJ1TyVn0s z{*`3V(^tXs=H@QJhJW^p;Cpd#$-96YIo(h#OJrj)dh5U7VAt$c|@{oS=Pq*6j z(x9Lq9Vig05)`f}S$dX3a`2k46N{zojM2O{2Cw3qe-B*3>MQCWQrWGS%DHxAK&Y^e7XyS3}L_iZ+e^st;y>7=sd4!PniB{WvI@-e%vb&xwcC1 xAyqkD7oS@V?(Nd}F5^itb}hv@7Ywb^_PTshi)jC~au5N3+FI8%zp9)2{vXHA5cU87 diff --git a/mmcpack-template/instance.cfg b/mmcpack-template/instance.cfg deleted file mode 100644 index 5dd423dfd..000000000 --- a/mmcpack-template/instance.cfg +++ /dev/null @@ -1,17 +0,0 @@ -IgnoreJavaCompatibility=true -InstanceType=OneSix -JavaPath=Replace this with your java path -LogPrePostOutput=true -MCLaunchMethod=LauncherPart -ManagedPack=false -ManagedPackID= -ManagedPackName= -ManagedPackType= -ManagedPackVersionID= -ManagedPackVersionName= -iconKey=cleanroom -lastLaunchTime=0 -lastTimePlayed=0 -name=Cleanroom -notes= -totalTimePlayed=0 diff --git a/mmcpack-template/mmc-pack.json b/mmcpack-template/mmc-pack.json deleted file mode 100644 index e0826d759..000000000 --- a/mmcpack-template/mmc-pack.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "components": [ - { - "cachedName": "LWJGL 3", - "cachedVersion": "3.3.1", - "cachedVolatile": true, - "dependencyOnly": true, - "uid": "org.lwjgl3", - "version": "3.3.1" - }, - { - "cachedName": "Minecraft", - "cachedRequires": [ - { - "suggests": "3.3.1", - "uid": "org.lwjgl3" - } - ], - "cachedVersion": "1.12.2", - "important": true, - "uid": "net.minecraft", - "version": "1.12.2" - }, - { - "cachedName": "Cleanroom", - "cachedRequires": [ - { - "equals": "1.12.2", - "uid": "net.minecraft" - } - ], - "cachedVersion": "0.0.0.0", - "uid": "net.minecraftforge", - "version": "0.0.0.0" - } - ], - "formatVersion": 1 -} diff --git a/mmcpack-template/patches/net.minecraft.json b/mmcpack-template/patches/net.minecraft.json deleted file mode 100644 index 094716ea4..000000000 --- a/mmcpack-template/patches/net.minecraft.json +++ /dev/null @@ -1,259 +0,0 @@ -{ - "assetIndex": { - "id": "1.12", - "sha1": "a21e1ded1a24ea1548dd8db0cf30b6acb02655a9", - "size": 143136, - "totalSize": 129843781, - "url": "https://piston-meta.mojang.com/v1/packages/a21e1ded1a24ea1548dd8db0cf30b6acb02655a9/1.12.json" - }, - "compatibleJavaMajors": [ - 25, - 26 - ], - "formatVersion": 1, - "libraries": [ - { - "downloads": { - "artifact": { - "sha1": "c73b5636faf089d9f00e8732a829577de25237ee", - "size": 103871, - "url": "https://libraries.minecraft.net/com/paulscode/codecjorbis/20101023/codecjorbis-20101023.jar" - } - }, - "name": "com.paulscode:codecjorbis:20101023" - }, - { - "downloads": { - "artifact": { - "sha1": "12f031cfe88fef5c1dd36c563c0a3a69bd7261da", - "size": 5618, - "url": "https://libraries.minecraft.net/com/paulscode/codecwav/20101023/codecwav-20101023.jar" - } - }, - "name": "com.paulscode:codecwav:20101023" - }, - { - "downloads": { - "artifact": { - "sha1": "5c5e304366f75f9eaa2e8cca546a1fb6109348b3", - "size": 21679, - "url": "https://libraries.minecraft.net/com/paulscode/libraryjavasound/20101123/libraryjavasound-20101123.jar" - } - }, - "name": "com.paulscode:libraryjavasound:20101123" - }, - { - "downloads": { - "artifact": { - "sha1": "73e80d0794c39665aec3f62eee88ca91676674ef", - "size": 18981, - "url": "https://libraries.minecraft.net/com/paulscode/librarylwjglopenal/20100824/librarylwjglopenal-20100824.jar" - } - }, - "name": "com.paulscode:librarylwjglopenal:20100824" - }, - { - "downloads": { - "artifact": { - "sha1": "419c05fe9be71f792b2d76cfc9b67f1ed0fec7f6", - "size": 65020, - "url": "https://libraries.minecraft.net/com/paulscode/soundsystem/20120107/soundsystem-20120107.jar" - } - }, - "name": "com.paulscode:soundsystem:20120107" - }, - { - "downloads": { - "artifact": { - "sha1": "9834cdf236c22e84b946bba989e2f94ef5897c3c", - "size": 65621, - "url": "https://libraries.minecraft.net/com/mojang/authlib/1.5.25/authlib-1.5.25.jar" - } - }, - "name": "com.mojang:authlib:1.5.25" - }, - { - "downloads": { - "artifact": { - "sha1": "bd0dccebdf3744c75f1ca20063f16e8f7d5e663f", - "size": 7135057, - "url": "https://libraries.minecraft.net/com/mojang/realms/1.10.22/realms-1.10.22.jar" - } - }, - "name": "com.mojang:realms:1.10.22" - }, - { - "downloads": { - "artifact": { - "sha1": "48fd510879dff266c3815947de66e3d4809f8668", - "size": 11055, - "url": "https://libraries.minecraft.net/com/mojang/text2speech/1.10.3/text2speech-1.10.3.jar" - } - }, - "name": "com.mojang:text2speech:1.10.3", - "rules": [ - { - "action": "allow" - }, - { - "action": "disallow", - "os": { - "name": "osx-arm64" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "48fd510879dff266c3815947de66e3d4809f8668", - "size": 11055, - "url": "https://libraries.minecraft.net/com/mojang/text2speech/1.10.3/text2speech-1.10.3.jar" - }, - "classifiers": { - "natives-linux": { - "sha1": "ab7896aec3b3dd272b06194357f2d98f832c0cfc", - "size": 7833, - "url": "https://libraries.minecraft.net/com/mojang/text2speech/1.10.3/text2speech-1.10.3-natives-linux.jar" - }, - "natives-windows": { - "sha1": "84a4b856389cc4f485275b1f63497a95a857a443", - "size": 81217, - "url": "https://libraries.minecraft.net/com/mojang/text2speech/1.10.3/text2speech-1.10.3-natives-windows.jar" - } - } - }, - "extract": { - "exclude": [ - "META-INF/" - ] - }, - "name": "com.mojang:text2speech:1.10.3", - "natives": { - "linux": "natives-linux", - "windows": "natives-windows" - }, - "rules": [ - { - "action": "allow" - }, - { - "action": "disallow", - "os": { - "name": "osx-arm64" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "6ef160c3133a78de015830860197602ca1c855d3", - "size": 40502, - "url": "https://libraries.minecraft.net/ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0.jar" - }, - "classifiers": { - "natives-osx": { - "sha1": "08befab4894d55875f33c3d300f4f71e6e828f64", - "size": 5629, - "url": "https://libraries.minecraft.net/ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0-natives-osx.jar" - } - } - }, - "extract": { - "exclude": [ - "META-INF/" - ] - }, - "name": "ca.weblite:java-objc-bridge:1.0.0", - "natives": { - "osx": "natives-osx" - }, - "rules": [ - { - "action": "allow", - "os": { - "name": "osx" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "6ef160c3133a78de015830860197602ca1c855d3", - "size": 40502, - "url": "https://libraries.minecraft.net/ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0.jar" - } - }, - "name": "ca.weblite:java-objc-bridge:1.0.0", - "rules": [ - { - "action": "allow", - "os": { - "name": "osx" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "f378f889797edd7df8d32272c06ca80a1b6b0f58", - "size": 13164, - "url": "https://libraries.minecraft.net/com/mojang/text2speech/1.11.3/text2speech-1.11.3.jar" - } - }, - "name": "com.mojang:text2speech:1.11.3", - "rules": [ - { - "action": "allow", - "os": { - "name": "osx-arm64" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "369a83621e3c65496348491e533cb97fe5f2f37d", - "size": 91947, - "url": "https://github.com/MinecraftMachina/Java-Objective-C-Bridge/releases/download/1.1.0-mmachina.1/java-objc-bridge-1.1.jar" - } - }, - "name": "ca.weblite:java-objc-bridge:1.1.0-mmachina.1", - "rules": [ - { - "action": "allow", - "os": { - "name": "osx-arm64" - } - } - ] - } - ], - "mainClass": "net.minecraft.client.main.Main", - "mainJar": { - "downloads": { - "artifact": { - "sha1": "0f275bc1547d01fa5f56ba34bdc87d981ee12daf", - "size": 10180113, - "url": "https://piston-data.mojang.com/v1/objects/0f275bc1547d01fa5f56ba34bdc87d981ee12daf/client.jar" - } - }, - "name": "com.mojang:minecraft:1.12.2:client" - }, - "minecraftArguments": "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} --assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} --accessToken ${auth_access_token} --userType ${user_type} --versionType ${version_type}", - "name": "Minecraft", - "releaseTime": "2017-09-18T08:39:46+00:00", - "requires": [ - { - "suggests": "3.3.1", - "uid": "org.lwjgl3" - } - ], - "type": "release", - "uid": "net.minecraft", - "version": "1.12.2" -} diff --git a/mmcpack-template/patches/net.minecraftforge.json b/mmcpack-template/patches/net.minecraftforge.json deleted file mode 100644 index 2ab0ae634..000000000 --- a/mmcpack-template/patches/net.minecraftforge.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "+tweakers": ["net.minecraftforge.fml.common.launcher.FMLTweaker"], - "+jvmArgs": ["-Dfile.encoding=UTF-8"], - "formatVersion": 1, - "libraries": [], - "mainClass": "com.cleanroommc.bouncepad.Bouncepad", - "name": "Cleanroom", - "releaseTime": "2021-12-13T04:40:03+00:00", - "requires": [ - { - "equals": "1.12.2", - "uid": "net.minecraft" - } - ], - "uid": "net.minecraftforge", - "version": "0" -} diff --git a/mmcpack-template/patches/org.lwjgl3.json b/mmcpack-template/patches/org.lwjgl3.json deleted file mode 100644 index 50326adcf..000000000 --- a/mmcpack-template/patches/org.lwjgl3.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "formatVersion": 1, - "libraries": [], - "name": "LWJGL 3", - "releaseTime": "2017-04-05T13:58:01+00:00", - "type": "release", - "uid": "org.lwjgl3", - "version": "0", - "volatile": true -} diff --git a/src/main/java/com/cleanroommc/boot/Main.java b/module/cleanroom/src/main/java/com/cleanroommc/boot/Main.java similarity index 100% rename from src/main/java/com/cleanroommc/boot/Main.java rename to module/cleanroom/src/main/java/com/cleanroommc/boot/Main.java diff --git a/src/main/java/com/cleanroommc/boot/MainClient.java b/module/cleanroom/src/main/java/com/cleanroommc/boot/MainClient.java similarity index 100% rename from src/main/java/com/cleanroommc/boot/MainClient.java rename to module/cleanroom/src/main/java/com/cleanroommc/boot/MainClient.java diff --git a/src/main/java/com/cleanroommc/boot/MainServer.java b/module/cleanroom/src/main/java/com/cleanroommc/boot/MainServer.java similarity index 100% rename from src/main/java/com/cleanroommc/boot/MainServer.java rename to module/cleanroom/src/main/java/com/cleanroommc/boot/MainServer.java diff --git a/src/main/java/com/cleanroommc/client/ICU4JInstances.java b/module/cleanroom/src/main/java/com/cleanroommc/client/ICU4JInstances.java similarity index 100% rename from src/main/java/com/cleanroommc/client/ICU4JInstances.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/ICU4JInstances.java diff --git a/src/main/java/com/cleanroommc/client/IMEHandler.java b/module/cleanroom/src/main/java/com/cleanroommc/client/IMEHandler.java similarity index 100% rename from src/main/java/com/cleanroommc/client/IMEHandler.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/IMEHandler.java diff --git a/src/main/java/com/cleanroommc/client/LoadingTracker.java b/module/cleanroom/src/main/java/com/cleanroommc/client/LoadingTracker.java similarity index 100% rename from src/main/java/com/cleanroommc/client/LoadingTracker.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/LoadingTracker.java diff --git a/src/main/java/com/cleanroommc/client/ime/DummyIMEHandler.java b/module/cleanroom/src/main/java/com/cleanroommc/client/ime/DummyIMEHandler.java similarity index 100% rename from src/main/java/com/cleanroommc/client/ime/DummyIMEHandler.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/ime/DummyIMEHandler.java diff --git a/src/main/java/com/cleanroommc/client/ime/WaylandIMEhandler.java b/module/cleanroom/src/main/java/com/cleanroommc/client/ime/WaylandIMEhandler.java similarity index 100% rename from src/main/java/com/cleanroommc/client/ime/WaylandIMEhandler.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/ime/WaylandIMEhandler.java diff --git a/src/main/java/com/cleanroommc/client/ime/WindowsIMEHandler.java b/module/cleanroom/src/main/java/com/cleanroommc/client/ime/WindowsIMEHandler.java similarity index 100% rename from src/main/java/com/cleanroommc/client/ime/WindowsIMEHandler.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/ime/WindowsIMEHandler.java diff --git a/src/main/java/com/cleanroommc/client/ime/X11IMEHandler.java b/module/cleanroom/src/main/java/com/cleanroommc/client/ime/X11IMEHandler.java similarity index 100% rename from src/main/java/com/cleanroommc/client/ime/X11IMEHandler.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/ime/X11IMEHandler.java diff --git a/src/main/java/com/cleanroommc/client/windows/DwmApi.java b/module/cleanroom/src/main/java/com/cleanroommc/client/windows/DwmApi.java similarity index 100% rename from src/main/java/com/cleanroommc/client/windows/DwmApi.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/windows/DwmApi.java diff --git a/src/main/java/com/cleanroommc/client/windows/NtDll.java b/module/cleanroom/src/main/java/com/cleanroommc/client/windows/NtDll.java similarity index 100% rename from src/main/java/com/cleanroommc/client/windows/NtDll.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/windows/NtDll.java diff --git a/src/main/java/com/cleanroommc/client/windows/TaskbarApi.java b/module/cleanroom/src/main/java/com/cleanroommc/client/windows/TaskbarApi.java similarity index 100% rename from src/main/java/com/cleanroommc/client/windows/TaskbarApi.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/windows/TaskbarApi.java diff --git a/src/main/java/com/cleanroommc/client/windows/WindowsProperties.java b/module/cleanroom/src/main/java/com/cleanroommc/client/windows/WindowsProperties.java similarity index 100% rename from src/main/java/com/cleanroommc/client/windows/WindowsProperties.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/windows/WindowsProperties.java diff --git a/src/main/java/com/cleanroommc/client/windows/WindowsTheme.java b/module/cleanroom/src/main/java/com/cleanroommc/client/windows/WindowsTheme.java similarity index 100% rename from src/main/java/com/cleanroommc/client/windows/WindowsTheme.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/windows/WindowsTheme.java diff --git a/src/main/java/com/cleanroommc/common/CleanroomContainer.java b/module/cleanroom/src/main/java/com/cleanroommc/common/CleanroomContainer.java similarity index 100% rename from src/main/java/com/cleanroommc/common/CleanroomContainer.java rename to module/cleanroom/src/main/java/com/cleanroommc/common/CleanroomContainer.java diff --git a/src/main/java/com/cleanroommc/common/ConfigAnytimeContainer.java b/module/cleanroom/src/main/java/com/cleanroommc/common/ConfigAnytimeContainer.java similarity index 100% rename from src/main/java/com/cleanroommc/common/ConfigAnytimeContainer.java rename to module/cleanroom/src/main/java/com/cleanroommc/common/ConfigAnytimeContainer.java diff --git a/src/main/java/com/cleanroommc/common/MixinContainer.java b/module/cleanroom/src/main/java/com/cleanroommc/common/MixinContainer.java similarity index 100% rename from src/main/java/com/cleanroommc/common/MixinContainer.java rename to module/cleanroom/src/main/java/com/cleanroommc/common/MixinContainer.java diff --git a/src/main/java/com/cleanroommc/common/PatchModPresentChecker.java b/module/cleanroom/src/main/java/com/cleanroommc/common/PatchModPresentChecker.java similarity index 100% rename from src/main/java/com/cleanroommc/common/PatchModPresentChecker.java rename to module/cleanroom/src/main/java/com/cleanroommc/common/PatchModPresentChecker.java diff --git a/src/main/java/com/cleanroommc/configanytime/ConfigAnytime.java b/module/cleanroom/src/main/java/com/cleanroommc/configanytime/ConfigAnytime.java similarity index 100% rename from src/main/java/com/cleanroommc/configanytime/ConfigAnytime.java rename to module/cleanroom/src/main/java/com/cleanroommc/configanytime/ConfigAnytime.java diff --git a/src/main/java/com/cleanroommc/hackery/Reflection.java b/module/cleanroom/src/main/java/com/cleanroommc/hackery/Reflection.java similarity index 100% rename from src/main/java/com/cleanroommc/hackery/Reflection.java rename to module/cleanroom/src/main/java/com/cleanroommc/hackery/Reflection.java diff --git a/src/main/java/com/cleanroommc/hackery/ReflectionHackery.java b/module/cleanroom/src/main/java/com/cleanroommc/hackery/ReflectionHackery.java similarity index 100% rename from src/main/java/com/cleanroommc/hackery/ReflectionHackery.java rename to module/cleanroom/src/main/java/com/cleanroommc/hackery/ReflectionHackery.java diff --git a/src/main/java/com/cleanroommc/hackery/enums/EnumHackery.java b/module/cleanroom/src/main/java/com/cleanroommc/hackery/enums/EnumHackery.java similarity index 100% rename from src/main/java/com/cleanroommc/hackery/enums/EnumHackery.java rename to module/cleanroom/src/main/java/com/cleanroommc/hackery/enums/EnumHackery.java diff --git a/src/main/java/com/cleanroommc/loader/LanguageAdapterRegistry.java b/module/cleanroom/src/main/java/com/cleanroommc/loader/LanguageAdapterRegistry.java similarity index 100% rename from src/main/java/com/cleanroommc/loader/LanguageAdapterRegistry.java rename to module/cleanroom/src/main/java/com/cleanroommc/loader/LanguageAdapterRegistry.java diff --git a/src/main/java/com/cleanroommc/loader/javafix/UUIDFix.java b/module/cleanroom/src/main/java/com/cleanroommc/loader/javafix/UUIDFix.java similarity index 100% rename from src/main/java/com/cleanroommc/loader/javafix/UUIDFix.java rename to module/cleanroom/src/main/java/com/cleanroommc/loader/javafix/UUIDFix.java diff --git a/src/main/java/com/cleanroommc/loader/scripting/CleanroomScriptEngineManager.java b/module/cleanroom/src/main/java/com/cleanroommc/loader/scripting/CleanroomScriptEngineManager.java similarity index 100% rename from src/main/java/com/cleanroommc/loader/scripting/CleanroomScriptEngineManager.java rename to module/cleanroom/src/main/java/com/cleanroommc/loader/scripting/CleanroomScriptEngineManager.java diff --git a/src/test/java/com/cleanroommc/hackery/EnumHackeryTest.java b/module/cleanroom/src/test/java/com/cleanroommc/hackery/EnumHackeryTest.java similarity index 100% rename from src/test/java/com/cleanroommc/hackery/EnumHackeryTest.java rename to module/cleanroom/src/test/java/com/cleanroommc/hackery/EnumHackeryTest.java diff --git a/src/main/java/ibxm/Channel.java b/module/forge/src/main/java/ibxm/Channel.java similarity index 100% rename from src/main/java/ibxm/Channel.java rename to module/forge/src/main/java/ibxm/Channel.java diff --git a/src/main/java/ibxm/Envelope.java b/module/forge/src/main/java/ibxm/Envelope.java similarity index 100% rename from src/main/java/ibxm/Envelope.java rename to module/forge/src/main/java/ibxm/Envelope.java diff --git a/src/main/java/ibxm/FastTracker2.java b/module/forge/src/main/java/ibxm/FastTracker2.java similarity index 100% rename from src/main/java/ibxm/FastTracker2.java rename to module/forge/src/main/java/ibxm/FastTracker2.java diff --git a/src/main/java/ibxm/IBXM.java b/module/forge/src/main/java/ibxm/IBXM.java similarity index 100% rename from src/main/java/ibxm/IBXM.java rename to module/forge/src/main/java/ibxm/IBXM.java diff --git a/src/main/java/ibxm/Instrument.java b/module/forge/src/main/java/ibxm/Instrument.java similarity index 100% rename from src/main/java/ibxm/Instrument.java rename to module/forge/src/main/java/ibxm/Instrument.java diff --git a/src/main/java/ibxm/LogTable.java b/module/forge/src/main/java/ibxm/LogTable.java similarity index 100% rename from src/main/java/ibxm/LogTable.java rename to module/forge/src/main/java/ibxm/LogTable.java diff --git a/src/main/java/ibxm/Module.java b/module/forge/src/main/java/ibxm/Module.java similarity index 100% rename from src/main/java/ibxm/Module.java rename to module/forge/src/main/java/ibxm/Module.java diff --git a/src/main/java/ibxm/Pattern.java b/module/forge/src/main/java/ibxm/Pattern.java similarity index 100% rename from src/main/java/ibxm/Pattern.java rename to module/forge/src/main/java/ibxm/Pattern.java diff --git a/src/main/java/ibxm/Player.java b/module/forge/src/main/java/ibxm/Player.java similarity index 100% rename from src/main/java/ibxm/Player.java rename to module/forge/src/main/java/ibxm/Player.java diff --git a/src/main/java/ibxm/ProTracker.java b/module/forge/src/main/java/ibxm/ProTracker.java similarity index 100% rename from src/main/java/ibxm/ProTracker.java rename to module/forge/src/main/java/ibxm/ProTracker.java diff --git a/src/main/java/ibxm/Sample.java b/module/forge/src/main/java/ibxm/Sample.java similarity index 100% rename from src/main/java/ibxm/Sample.java rename to module/forge/src/main/java/ibxm/Sample.java diff --git a/src/main/java/ibxm/ScreamTracker3.java b/module/forge/src/main/java/ibxm/ScreamTracker3.java similarity index 100% rename from src/main/java/ibxm/ScreamTracker3.java rename to module/forge/src/main/java/ibxm/ScreamTracker3.java diff --git a/src/main/java/net/minecraftforge/advancements/critereon/ItemPredicates.java b/module/forge/src/main/java/net/minecraftforge/advancements/critereon/ItemPredicates.java similarity index 100% rename from src/main/java/net/minecraftforge/advancements/critereon/ItemPredicates.java rename to module/forge/src/main/java/net/minecraftforge/advancements/critereon/ItemPredicates.java diff --git a/src/main/java/net/minecraftforge/advancements/critereon/OredictItemPredicate.java b/module/forge/src/main/java/net/minecraftforge/advancements/critereon/OredictItemPredicate.java similarity index 100% rename from src/main/java/net/minecraftforge/advancements/critereon/OredictItemPredicate.java rename to module/forge/src/main/java/net/minecraftforge/advancements/critereon/OredictItemPredicate.java diff --git a/src/main/java/net/minecraftforge/classloading/FMLForgePlugin.java b/module/forge/src/main/java/net/minecraftforge/classloading/FMLForgePlugin.java similarity index 100% rename from src/main/java/net/minecraftforge/classloading/FMLForgePlugin.java rename to module/forge/src/main/java/net/minecraftforge/classloading/FMLForgePlugin.java diff --git a/src/main/java/net/minecraftforge/client/ClientCommandHandler.java b/module/forge/src/main/java/net/minecraftforge/client/ClientCommandHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/client/ClientCommandHandler.java rename to module/forge/src/main/java/net/minecraftforge/client/ClientCommandHandler.java diff --git a/src/main/java/net/minecraftforge/client/CloudRenderer.java b/module/forge/src/main/java/net/minecraftforge/client/CloudRenderer.java similarity index 100% rename from src/main/java/net/minecraftforge/client/CloudRenderer.java rename to module/forge/src/main/java/net/minecraftforge/client/CloudRenderer.java diff --git a/src/main/java/net/minecraftforge/client/EnumHelperClient.java b/module/forge/src/main/java/net/minecraftforge/client/EnumHelperClient.java similarity index 100% rename from src/main/java/net/minecraftforge/client/EnumHelperClient.java rename to module/forge/src/main/java/net/minecraftforge/client/EnumHelperClient.java diff --git a/src/main/java/net/minecraftforge/client/FluidContainerColorer.java b/module/forge/src/main/java/net/minecraftforge/client/FluidContainerColorer.java similarity index 100% rename from src/main/java/net/minecraftforge/client/FluidContainerColorer.java rename to module/forge/src/main/java/net/minecraftforge/client/FluidContainerColorer.java diff --git a/src/main/java/net/minecraftforge/client/ForgeClientHandler.java b/module/forge/src/main/java/net/minecraftforge/client/ForgeClientHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/client/ForgeClientHandler.java rename to module/forge/src/main/java/net/minecraftforge/client/ForgeClientHandler.java diff --git a/src/main/java/net/minecraftforge/client/ForgeHooksClient.java b/module/forge/src/main/java/net/minecraftforge/client/ForgeHooksClient.java similarity index 100% rename from src/main/java/net/minecraftforge/client/ForgeHooksClient.java rename to module/forge/src/main/java/net/minecraftforge/client/ForgeHooksClient.java diff --git a/src/main/java/net/minecraftforge/client/GuiIngameForge.java b/module/forge/src/main/java/net/minecraftforge/client/GuiIngameForge.java similarity index 100% rename from src/main/java/net/minecraftforge/client/GuiIngameForge.java rename to module/forge/src/main/java/net/minecraftforge/client/GuiIngameForge.java diff --git a/src/main/java/net/minecraftforge/client/IClientCommand.java b/module/forge/src/main/java/net/minecraftforge/client/IClientCommand.java similarity index 100% rename from src/main/java/net/minecraftforge/client/IClientCommand.java rename to module/forge/src/main/java/net/minecraftforge/client/IClientCommand.java diff --git a/src/main/java/net/minecraftforge/client/IRenderContextHandler.java b/module/forge/src/main/java/net/minecraftforge/client/IRenderContextHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/client/IRenderContextHandler.java rename to module/forge/src/main/java/net/minecraftforge/client/IRenderContextHandler.java diff --git a/src/main/java/net/minecraftforge/client/IRenderHandler.java b/module/forge/src/main/java/net/minecraftforge/client/IRenderHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/client/IRenderHandler.java rename to module/forge/src/main/java/net/minecraftforge/client/IRenderHandler.java diff --git a/src/main/java/net/minecraftforge/client/ItemModelMesherForge.java b/module/forge/src/main/java/net/minecraftforge/client/ItemModelMesherForge.java similarity index 100% rename from src/main/java/net/minecraftforge/client/ItemModelMesherForge.java rename to module/forge/src/main/java/net/minecraftforge/client/ItemModelMesherForge.java diff --git a/src/main/java/net/minecraftforge/client/MinecraftForgeClient.java b/module/forge/src/main/java/net/minecraftforge/client/MinecraftForgeClient.java similarity index 100% rename from src/main/java/net/minecraftforge/client/MinecraftForgeClient.java rename to module/forge/src/main/java/net/minecraftforge/client/MinecraftForgeClient.java diff --git a/src/main/java/net/minecraftforge/client/event/ClientChatEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/ClientChatEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/ClientChatEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/ClientChatEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/ClientChatReceivedEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/ClientChatReceivedEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/ClientChatReceivedEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/ClientChatReceivedEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/ColorHandlerEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/ColorHandlerEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/ColorHandlerEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/ColorHandlerEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/DrawBlockHighlightEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/DrawBlockHighlightEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/DrawBlockHighlightEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/DrawBlockHighlightEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/EntityViewRenderEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/EntityViewRenderEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/EntityViewRenderEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/EntityViewRenderEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/FOVUpdateEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/FOVUpdateEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/FOVUpdateEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/FOVUpdateEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/GuiContainerEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/GuiContainerEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/GuiContainerEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/GuiContainerEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/GuiOpenEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/GuiOpenEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/GuiOpenEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/GuiOpenEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/GuiScreenEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/GuiScreenEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/GuiScreenEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/GuiScreenEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/InputUpdateEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/InputUpdateEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/InputUpdateEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/InputUpdateEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/ModelBakeEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/ModelBakeEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/ModelBakeEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/ModelBakeEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/ModelRegistryEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/ModelRegistryEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/ModelRegistryEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/ModelRegistryEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/MouseEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/MouseEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/MouseEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/MouseEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/PlayerSPPushOutOfBlocksEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/PlayerSPPushOutOfBlocksEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/PlayerSPPushOutOfBlocksEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/PlayerSPPushOutOfBlocksEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/RenderArmEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/RenderArmEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/RenderArmEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/RenderArmEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/RenderBlockOverlayEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/RenderBlockOverlayEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/RenderBlockOverlayEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/RenderBlockOverlayEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/RenderGameOverlayEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/RenderGameOverlayEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/RenderGameOverlayEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/RenderGameOverlayEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/RenderHandEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/RenderHandEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/RenderHandEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/RenderHandEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/RenderItemInFrameEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/RenderItemInFrameEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/RenderItemInFrameEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/RenderItemInFrameEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/RenderLivingEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/RenderLivingEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/RenderLivingEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/RenderLivingEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/RenderPlayerEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/RenderPlayerEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/RenderPlayerEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/RenderPlayerEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/RenderSpecificHandEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/RenderSpecificHandEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/RenderSpecificHandEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/RenderSpecificHandEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/RenderTooltipEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/RenderTooltipEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/RenderTooltipEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/RenderTooltipEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/RenderWorldLastEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/RenderWorldLastEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/RenderWorldLastEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/RenderWorldLastEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/ScreenshotEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/ScreenshotEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/ScreenshotEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/ScreenshotEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/TextureStitchEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/TextureStitchEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/TextureStitchEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/TextureStitchEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/sound/PlaySoundEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/sound/PlaySoundEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/sound/PlaySoundEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/sound/PlaySoundEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/sound/PlaySoundSourceEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/sound/PlaySoundSourceEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/sound/PlaySoundSourceEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/sound/PlaySoundSourceEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/sound/PlayStreamingSourceEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/sound/PlayStreamingSourceEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/sound/PlayStreamingSourceEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/sound/PlayStreamingSourceEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/sound/SoundEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/sound/SoundEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/sound/SoundEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/sound/SoundEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/sound/SoundLoadEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/sound/SoundLoadEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/sound/SoundLoadEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/sound/SoundLoadEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/sound/SoundSetupEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/sound/SoundSetupEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/sound/SoundSetupEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/sound/SoundSetupEvent.java diff --git a/src/main/java/net/minecraftforge/client/gui/ForgeGuiFactory.java b/module/forge/src/main/java/net/minecraftforge/client/gui/ForgeGuiFactory.java similarity index 100% rename from src/main/java/net/minecraftforge/client/gui/ForgeGuiFactory.java rename to module/forge/src/main/java/net/minecraftforge/client/gui/ForgeGuiFactory.java diff --git a/src/main/java/net/minecraftforge/client/gui/NotificationModUpdateScreen.java b/module/forge/src/main/java/net/minecraftforge/client/gui/NotificationModUpdateScreen.java similarity index 100% rename from src/main/java/net/minecraftforge/client/gui/NotificationModUpdateScreen.java rename to module/forge/src/main/java/net/minecraftforge/client/gui/NotificationModUpdateScreen.java diff --git a/src/main/java/net/minecraftforge/client/model/Attributes.java b/module/forge/src/main/java/net/minecraftforge/client/model/Attributes.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/Attributes.java rename to module/forge/src/main/java/net/minecraftforge/client/model/Attributes.java diff --git a/src/main/java/net/minecraftforge/client/model/BakedItemModel.java b/module/forge/src/main/java/net/minecraftforge/client/model/BakedItemModel.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/BakedItemModel.java rename to module/forge/src/main/java/net/minecraftforge/client/model/BakedItemModel.java diff --git a/src/main/java/net/minecraftforge/client/model/BakedModelWrapper.java b/module/forge/src/main/java/net/minecraftforge/client/model/BakedModelWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/BakedModelWrapper.java rename to module/forge/src/main/java/net/minecraftforge/client/model/BakedModelWrapper.java diff --git a/src/main/java/net/minecraftforge/client/model/BlockStateLoader.java b/module/forge/src/main/java/net/minecraftforge/client/model/BlockStateLoader.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/BlockStateLoader.java rename to module/forge/src/main/java/net/minecraftforge/client/model/BlockStateLoader.java diff --git a/src/main/java/net/minecraftforge/client/model/FancyMissingModel.java b/module/forge/src/main/java/net/minecraftforge/client/model/FancyMissingModel.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/FancyMissingModel.java rename to module/forge/src/main/java/net/minecraftforge/client/model/FancyMissingModel.java diff --git a/src/main/java/net/minecraftforge/client/model/ForgeBlockStateV1.java b/module/forge/src/main/java/net/minecraftforge/client/model/ForgeBlockStateV1.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/ForgeBlockStateV1.java rename to module/forge/src/main/java/net/minecraftforge/client/model/ForgeBlockStateV1.java diff --git a/src/main/java/net/minecraftforge/client/model/ICustomModelLoader.java b/module/forge/src/main/java/net/minecraftforge/client/model/ICustomModelLoader.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/ICustomModelLoader.java rename to module/forge/src/main/java/net/minecraftforge/client/model/ICustomModelLoader.java diff --git a/src/main/java/net/minecraftforge/client/model/IModel.java b/module/forge/src/main/java/net/minecraftforge/client/model/IModel.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/IModel.java rename to module/forge/src/main/java/net/minecraftforge/client/model/IModel.java diff --git a/src/main/java/net/minecraftforge/client/model/ISmartVariant.java b/module/forge/src/main/java/net/minecraftforge/client/model/ISmartVariant.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/ISmartVariant.java rename to module/forge/src/main/java/net/minecraftforge/client/model/ISmartVariant.java diff --git a/src/main/java/net/minecraftforge/client/model/ItemLayerModel.java b/module/forge/src/main/java/net/minecraftforge/client/model/ItemLayerModel.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/ItemLayerModel.java rename to module/forge/src/main/java/net/minecraftforge/client/model/ItemLayerModel.java diff --git a/src/main/java/net/minecraftforge/client/model/ItemTextureQuadConverter.java b/module/forge/src/main/java/net/minecraftforge/client/model/ItemTextureQuadConverter.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/ItemTextureQuadConverter.java rename to module/forge/src/main/java/net/minecraftforge/client/model/ItemTextureQuadConverter.java diff --git a/src/main/java/net/minecraftforge/client/model/MapModelState.java b/module/forge/src/main/java/net/minecraftforge/client/model/MapModelState.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/MapModelState.java rename to module/forge/src/main/java/net/minecraftforge/client/model/MapModelState.java diff --git a/src/main/java/net/minecraftforge/client/model/ModelDynBucket.java b/module/forge/src/main/java/net/minecraftforge/client/model/ModelDynBucket.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/ModelDynBucket.java rename to module/forge/src/main/java/net/minecraftforge/client/model/ModelDynBucket.java diff --git a/src/main/java/net/minecraftforge/client/model/ModelFluid.java b/module/forge/src/main/java/net/minecraftforge/client/model/ModelFluid.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/ModelFluid.java rename to module/forge/src/main/java/net/minecraftforge/client/model/ModelFluid.java diff --git a/src/main/java/net/minecraftforge/client/model/ModelLoader.java b/module/forge/src/main/java/net/minecraftforge/client/model/ModelLoader.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/ModelLoader.java rename to module/forge/src/main/java/net/minecraftforge/client/model/ModelLoader.java diff --git a/src/main/java/net/minecraftforge/client/model/ModelLoaderRegistry.java b/module/forge/src/main/java/net/minecraftforge/client/model/ModelLoaderRegistry.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/ModelLoaderRegistry.java rename to module/forge/src/main/java/net/minecraftforge/client/model/ModelLoaderRegistry.java diff --git a/src/main/java/net/minecraftforge/client/model/ModelStateComposition.java b/module/forge/src/main/java/net/minecraftforge/client/model/ModelStateComposition.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/ModelStateComposition.java rename to module/forge/src/main/java/net/minecraftforge/client/model/ModelStateComposition.java diff --git a/src/main/java/net/minecraftforge/client/model/MultiLayerModel.java b/module/forge/src/main/java/net/minecraftforge/client/model/MultiLayerModel.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/MultiLayerModel.java rename to module/forge/src/main/java/net/minecraftforge/client/model/MultiLayerModel.java diff --git a/src/main/java/net/minecraftforge/client/model/MultiModel.java b/module/forge/src/main/java/net/minecraftforge/client/model/MultiModel.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/MultiModel.java rename to module/forge/src/main/java/net/minecraftforge/client/model/MultiModel.java diff --git a/src/main/java/net/minecraftforge/client/model/MultiModelState.java b/module/forge/src/main/java/net/minecraftforge/client/model/MultiModelState.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/MultiModelState.java rename to module/forge/src/main/java/net/minecraftforge/client/model/MultiModelState.java diff --git a/src/main/java/net/minecraftforge/client/model/PerspectiveMapWrapper.java b/module/forge/src/main/java/net/minecraftforge/client/model/PerspectiveMapWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/PerspectiveMapWrapper.java rename to module/forge/src/main/java/net/minecraftforge/client/model/PerspectiveMapWrapper.java diff --git a/src/main/java/net/minecraftforge/client/model/SimpleModelFontRenderer.java b/module/forge/src/main/java/net/minecraftforge/client/model/SimpleModelFontRenderer.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/SimpleModelFontRenderer.java rename to module/forge/src/main/java/net/minecraftforge/client/model/SimpleModelFontRenderer.java diff --git a/src/main/java/net/minecraftforge/client/model/SimpleModelState.java b/module/forge/src/main/java/net/minecraftforge/client/model/SimpleModelState.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/SimpleModelState.java rename to module/forge/src/main/java/net/minecraftforge/client/model/SimpleModelState.java diff --git a/src/main/java/net/minecraftforge/client/model/animation/Animation.java b/module/forge/src/main/java/net/minecraftforge/client/model/animation/Animation.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/animation/Animation.java rename to module/forge/src/main/java/net/minecraftforge/client/model/animation/Animation.java diff --git a/src/main/java/net/minecraftforge/client/model/animation/AnimationItemOverrideList.java b/module/forge/src/main/java/net/minecraftforge/client/model/animation/AnimationItemOverrideList.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/animation/AnimationItemOverrideList.java rename to module/forge/src/main/java/net/minecraftforge/client/model/animation/AnimationItemOverrideList.java diff --git a/src/main/java/net/minecraftforge/client/model/animation/AnimationModelBase.java b/module/forge/src/main/java/net/minecraftforge/client/model/animation/AnimationModelBase.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/animation/AnimationModelBase.java rename to module/forge/src/main/java/net/minecraftforge/client/model/animation/AnimationModelBase.java diff --git a/src/main/java/net/minecraftforge/client/model/animation/AnimationTESR.java b/module/forge/src/main/java/net/minecraftforge/client/model/animation/AnimationTESR.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/animation/AnimationTESR.java rename to module/forge/src/main/java/net/minecraftforge/client/model/animation/AnimationTESR.java diff --git a/src/main/java/net/minecraftforge/client/model/animation/FastTESR.java b/module/forge/src/main/java/net/minecraftforge/client/model/animation/FastTESR.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/animation/FastTESR.java rename to module/forge/src/main/java/net/minecraftforge/client/model/animation/FastTESR.java diff --git a/src/main/java/net/minecraftforge/client/model/animation/ModelBlockAnimation.java b/module/forge/src/main/java/net/minecraftforge/client/model/animation/ModelBlockAnimation.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/animation/ModelBlockAnimation.java rename to module/forge/src/main/java/net/minecraftforge/client/model/animation/ModelBlockAnimation.java diff --git a/src/main/java/net/minecraftforge/client/model/animation/package-info.java b/module/forge/src/main/java/net/minecraftforge/client/model/animation/package-info.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/animation/package-info.java rename to module/forge/src/main/java/net/minecraftforge/client/model/animation/package-info.java diff --git a/src/main/java/net/minecraftforge/client/model/b3d/B3DClip.java b/module/forge/src/main/java/net/minecraftforge/client/model/b3d/B3DClip.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/b3d/B3DClip.java rename to module/forge/src/main/java/net/minecraftforge/client/model/b3d/B3DClip.java diff --git a/src/main/java/net/minecraftforge/client/model/b3d/B3DLoader.java b/module/forge/src/main/java/net/minecraftforge/client/model/b3d/B3DLoader.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/b3d/B3DLoader.java rename to module/forge/src/main/java/net/minecraftforge/client/model/b3d/B3DLoader.java diff --git a/src/main/java/net/minecraftforge/client/model/b3d/B3DModel.java b/module/forge/src/main/java/net/minecraftforge/client/model/b3d/B3DModel.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/b3d/B3DModel.java rename to module/forge/src/main/java/net/minecraftforge/client/model/b3d/B3DModel.java diff --git a/src/main/java/net/minecraftforge/client/model/b3d/package-info.java b/module/forge/src/main/java/net/minecraftforge/client/model/b3d/package-info.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/b3d/package-info.java rename to module/forge/src/main/java/net/minecraftforge/client/model/b3d/package-info.java diff --git a/src/main/java/net/minecraftforge/client/model/obj/OBJLoader.java b/module/forge/src/main/java/net/minecraftforge/client/model/obj/OBJLoader.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/obj/OBJLoader.java rename to module/forge/src/main/java/net/minecraftforge/client/model/obj/OBJLoader.java diff --git a/src/main/java/net/minecraftforge/client/model/obj/OBJModel.java b/module/forge/src/main/java/net/minecraftforge/client/model/obj/OBJModel.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/obj/OBJModel.java rename to module/forge/src/main/java/net/minecraftforge/client/model/obj/OBJModel.java diff --git a/src/main/java/net/minecraftforge/client/model/obj/package-info.java b/module/forge/src/main/java/net/minecraftforge/client/model/obj/package-info.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/obj/package-info.java rename to module/forge/src/main/java/net/minecraftforge/client/model/obj/package-info.java diff --git a/src/main/java/net/minecraftforge/client/model/package-info.java b/module/forge/src/main/java/net/minecraftforge/client/model/package-info.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/package-info.java rename to module/forge/src/main/java/net/minecraftforge/client/model/package-info.java diff --git a/src/main/java/net/minecraftforge/client/model/pipeline/BlockInfo.java b/module/forge/src/main/java/net/minecraftforge/client/model/pipeline/BlockInfo.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/pipeline/BlockInfo.java rename to module/forge/src/main/java/net/minecraftforge/client/model/pipeline/BlockInfo.java diff --git a/src/main/java/net/minecraftforge/client/model/pipeline/ForgeBlockModelRenderer.java b/module/forge/src/main/java/net/minecraftforge/client/model/pipeline/ForgeBlockModelRenderer.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/pipeline/ForgeBlockModelRenderer.java rename to module/forge/src/main/java/net/minecraftforge/client/model/pipeline/ForgeBlockModelRenderer.java diff --git a/src/main/java/net/minecraftforge/client/model/pipeline/IVertexConsumer.java b/module/forge/src/main/java/net/minecraftforge/client/model/pipeline/IVertexConsumer.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/pipeline/IVertexConsumer.java rename to module/forge/src/main/java/net/minecraftforge/client/model/pipeline/IVertexConsumer.java diff --git a/src/main/java/net/minecraftforge/client/model/pipeline/IVertexProducer.java b/module/forge/src/main/java/net/minecraftforge/client/model/pipeline/IVertexProducer.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/pipeline/IVertexProducer.java rename to module/forge/src/main/java/net/minecraftforge/client/model/pipeline/IVertexProducer.java diff --git a/src/main/java/net/minecraftforge/client/model/pipeline/LightUtil.java b/module/forge/src/main/java/net/minecraftforge/client/model/pipeline/LightUtil.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/pipeline/LightUtil.java rename to module/forge/src/main/java/net/minecraftforge/client/model/pipeline/LightUtil.java diff --git a/src/main/java/net/minecraftforge/client/model/pipeline/QuadGatheringTransformer.java b/module/forge/src/main/java/net/minecraftforge/client/model/pipeline/QuadGatheringTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/pipeline/QuadGatheringTransformer.java rename to module/forge/src/main/java/net/minecraftforge/client/model/pipeline/QuadGatheringTransformer.java diff --git a/src/main/java/net/minecraftforge/client/model/pipeline/TRSRTransformer.java b/module/forge/src/main/java/net/minecraftforge/client/model/pipeline/TRSRTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/pipeline/TRSRTransformer.java rename to module/forge/src/main/java/net/minecraftforge/client/model/pipeline/TRSRTransformer.java diff --git a/src/main/java/net/minecraftforge/client/model/pipeline/TransformerConsumer.java b/module/forge/src/main/java/net/minecraftforge/client/model/pipeline/TransformerConsumer.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/pipeline/TransformerConsumer.java rename to module/forge/src/main/java/net/minecraftforge/client/model/pipeline/TransformerConsumer.java diff --git a/src/main/java/net/minecraftforge/client/model/pipeline/UnpackedBakedQuad.java b/module/forge/src/main/java/net/minecraftforge/client/model/pipeline/UnpackedBakedQuad.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/pipeline/UnpackedBakedQuad.java rename to module/forge/src/main/java/net/minecraftforge/client/model/pipeline/UnpackedBakedQuad.java diff --git a/src/main/java/net/minecraftforge/client/model/pipeline/VertexBufferConsumer.java b/module/forge/src/main/java/net/minecraftforge/client/model/pipeline/VertexBufferConsumer.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/pipeline/VertexBufferConsumer.java rename to module/forge/src/main/java/net/minecraftforge/client/model/pipeline/VertexBufferConsumer.java diff --git a/src/main/java/net/minecraftforge/client/model/pipeline/VertexLighterFlat.java b/module/forge/src/main/java/net/minecraftforge/client/model/pipeline/VertexLighterFlat.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/pipeline/VertexLighterFlat.java rename to module/forge/src/main/java/net/minecraftforge/client/model/pipeline/VertexLighterFlat.java diff --git a/src/main/java/net/minecraftforge/client/model/pipeline/VertexLighterSmoothAo.java b/module/forge/src/main/java/net/minecraftforge/client/model/pipeline/VertexLighterSmoothAo.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/pipeline/VertexLighterSmoothAo.java rename to module/forge/src/main/java/net/minecraftforge/client/model/pipeline/VertexLighterSmoothAo.java diff --git a/src/main/java/net/minecraftforge/client/model/pipeline/VertexTransformer.java b/module/forge/src/main/java/net/minecraftforge/client/model/pipeline/VertexTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/pipeline/VertexTransformer.java rename to module/forge/src/main/java/net/minecraftforge/client/model/pipeline/VertexTransformer.java diff --git a/src/main/java/net/minecraftforge/client/model/pipeline/package-info.java b/module/forge/src/main/java/net/minecraftforge/client/model/pipeline/package-info.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/pipeline/package-info.java rename to module/forge/src/main/java/net/minecraftforge/client/model/pipeline/package-info.java diff --git a/src/main/java/net/minecraftforge/client/resource/IResourceType.java b/module/forge/src/main/java/net/minecraftforge/client/resource/IResourceType.java similarity index 100% rename from src/main/java/net/minecraftforge/client/resource/IResourceType.java rename to module/forge/src/main/java/net/minecraftforge/client/resource/IResourceType.java diff --git a/src/main/java/net/minecraftforge/client/resource/ISelectiveResourceReloadListener.java b/module/forge/src/main/java/net/minecraftforge/client/resource/ISelectiveResourceReloadListener.java similarity index 100% rename from src/main/java/net/minecraftforge/client/resource/ISelectiveResourceReloadListener.java rename to module/forge/src/main/java/net/minecraftforge/client/resource/ISelectiveResourceReloadListener.java diff --git a/src/main/java/net/minecraftforge/client/resource/ReloadRequirements.java b/module/forge/src/main/java/net/minecraftforge/client/resource/ReloadRequirements.java similarity index 100% rename from src/main/java/net/minecraftforge/client/resource/ReloadRequirements.java rename to module/forge/src/main/java/net/minecraftforge/client/resource/ReloadRequirements.java diff --git a/src/main/java/net/minecraftforge/client/resource/SelectiveReloadStateHandler.java b/module/forge/src/main/java/net/minecraftforge/client/resource/SelectiveReloadStateHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/client/resource/SelectiveReloadStateHandler.java rename to module/forge/src/main/java/net/minecraftforge/client/resource/SelectiveReloadStateHandler.java diff --git a/src/main/java/net/minecraftforge/client/resource/VanillaResourceType.java b/module/forge/src/main/java/net/minecraftforge/client/resource/VanillaResourceType.java similarity index 100% rename from src/main/java/net/minecraftforge/client/resource/VanillaResourceType.java rename to module/forge/src/main/java/net/minecraftforge/client/resource/VanillaResourceType.java diff --git a/src/main/java/net/minecraftforge/client/resource/package-info.java b/module/forge/src/main/java/net/minecraftforge/client/resource/package-info.java similarity index 100% rename from src/main/java/net/minecraftforge/client/resource/package-info.java rename to module/forge/src/main/java/net/minecraftforge/client/resource/package-info.java diff --git a/src/main/java/net/minecraftforge/client/settings/IKeyConflictContext.java b/module/forge/src/main/java/net/minecraftforge/client/settings/IKeyConflictContext.java similarity index 100% rename from src/main/java/net/minecraftforge/client/settings/IKeyConflictContext.java rename to module/forge/src/main/java/net/minecraftforge/client/settings/IKeyConflictContext.java diff --git a/src/main/java/net/minecraftforge/client/settings/KeyBindingMap.java b/module/forge/src/main/java/net/minecraftforge/client/settings/KeyBindingMap.java similarity index 100% rename from src/main/java/net/minecraftforge/client/settings/KeyBindingMap.java rename to module/forge/src/main/java/net/minecraftforge/client/settings/KeyBindingMap.java diff --git a/src/main/java/net/minecraftforge/client/settings/KeyConflictContext.java b/module/forge/src/main/java/net/minecraftforge/client/settings/KeyConflictContext.java similarity index 100% rename from src/main/java/net/minecraftforge/client/settings/KeyConflictContext.java rename to module/forge/src/main/java/net/minecraftforge/client/settings/KeyConflictContext.java diff --git a/src/main/java/net/minecraftforge/client/settings/KeyModifier.java b/module/forge/src/main/java/net/minecraftforge/client/settings/KeyModifier.java similarity index 100% rename from src/main/java/net/minecraftforge/client/settings/KeyModifier.java rename to module/forge/src/main/java/net/minecraftforge/client/settings/KeyModifier.java diff --git a/src/main/java/net/minecraftforge/common/BiomeDictionary.java b/module/forge/src/main/java/net/minecraftforge/common/BiomeDictionary.java similarity index 100% rename from src/main/java/net/minecraftforge/common/BiomeDictionary.java rename to module/forge/src/main/java/net/minecraftforge/common/BiomeDictionary.java diff --git a/src/main/java/net/minecraftforge/common/BiomeManager.java b/module/forge/src/main/java/net/minecraftforge/common/BiomeManager.java similarity index 100% rename from src/main/java/net/minecraftforge/common/BiomeManager.java rename to module/forge/src/main/java/net/minecraftforge/common/BiomeManager.java diff --git a/src/main/java/net/minecraftforge/common/DimensionManager.java b/module/forge/src/main/java/net/minecraftforge/common/DimensionManager.java similarity index 100% rename from src/main/java/net/minecraftforge/common/DimensionManager.java rename to module/forge/src/main/java/net/minecraftforge/common/DimensionManager.java diff --git a/src/main/java/net/minecraftforge/common/DungeonHooks.java b/module/forge/src/main/java/net/minecraftforge/common/DungeonHooks.java similarity index 100% rename from src/main/java/net/minecraftforge/common/DungeonHooks.java rename to module/forge/src/main/java/net/minecraftforge/common/DungeonHooks.java diff --git a/src/main/java/net/minecraftforge/common/EnumPlantType.java b/module/forge/src/main/java/net/minecraftforge/common/EnumPlantType.java similarity index 100% rename from src/main/java/net/minecraftforge/common/EnumPlantType.java rename to module/forge/src/main/java/net/minecraftforge/common/EnumPlantType.java diff --git a/src/main/java/net/minecraftforge/common/FarmlandWaterManager.java b/module/forge/src/main/java/net/minecraftforge/common/FarmlandWaterManager.java similarity index 100% rename from src/main/java/net/minecraftforge/common/FarmlandWaterManager.java rename to module/forge/src/main/java/net/minecraftforge/common/FarmlandWaterManager.java diff --git a/src/main/java/net/minecraftforge/common/ForgeChunkManager.java b/module/forge/src/main/java/net/minecraftforge/common/ForgeChunkManager.java similarity index 100% rename from src/main/java/net/minecraftforge/common/ForgeChunkManager.java rename to module/forge/src/main/java/net/minecraftforge/common/ForgeChunkManager.java diff --git a/src/main/java/net/minecraftforge/common/ForgeEarlyConfig.java b/module/forge/src/main/java/net/minecraftforge/common/ForgeEarlyConfig.java similarity index 100% rename from src/main/java/net/minecraftforge/common/ForgeEarlyConfig.java rename to module/forge/src/main/java/net/minecraftforge/common/ForgeEarlyConfig.java diff --git a/src/main/java/net/minecraftforge/common/ForgeHooks.java b/module/forge/src/main/java/net/minecraftforge/common/ForgeHooks.java similarity index 100% rename from src/main/java/net/minecraftforge/common/ForgeHooks.java rename to module/forge/src/main/java/net/minecraftforge/common/ForgeHooks.java diff --git a/src/main/java/net/minecraftforge/common/ForgeInternalHandler.java b/module/forge/src/main/java/net/minecraftforge/common/ForgeInternalHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/common/ForgeInternalHandler.java rename to module/forge/src/main/java/net/minecraftforge/common/ForgeInternalHandler.java diff --git a/src/main/java/net/minecraftforge/common/ForgeModContainer.java b/module/forge/src/main/java/net/minecraftforge/common/ForgeModContainer.java similarity index 100% rename from src/main/java/net/minecraftforge/common/ForgeModContainer.java rename to module/forge/src/main/java/net/minecraftforge/common/ForgeModContainer.java diff --git a/src/main/java/net/minecraftforge/common/ForgeVersion.java b/module/forge/src/main/java/net/minecraftforge/common/ForgeVersion.java similarity index 100% rename from src/main/java/net/minecraftforge/common/ForgeVersion.java rename to module/forge/src/main/java/net/minecraftforge/common/ForgeVersion.java diff --git a/src/main/java/net/minecraftforge/common/IMinecartCollisionHandler.java b/module/forge/src/main/java/net/minecraftforge/common/IMinecartCollisionHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/common/IMinecartCollisionHandler.java rename to module/forge/src/main/java/net/minecraftforge/common/IMinecartCollisionHandler.java diff --git a/src/main/java/net/minecraftforge/common/IPlantable.java b/module/forge/src/main/java/net/minecraftforge/common/IPlantable.java similarity index 100% rename from src/main/java/net/minecraftforge/common/IPlantable.java rename to module/forge/src/main/java/net/minecraftforge/common/IPlantable.java diff --git a/src/main/java/net/minecraftforge/common/IRarity.java b/module/forge/src/main/java/net/minecraftforge/common/IRarity.java similarity index 100% rename from src/main/java/net/minecraftforge/common/IRarity.java rename to module/forge/src/main/java/net/minecraftforge/common/IRarity.java diff --git a/src/main/java/net/minecraftforge/common/IShearable.java b/module/forge/src/main/java/net/minecraftforge/common/IShearable.java similarity index 100% rename from src/main/java/net/minecraftforge/common/IShearable.java rename to module/forge/src/main/java/net/minecraftforge/common/IShearable.java diff --git a/src/main/java/net/minecraftforge/common/ISpecialArmor.java b/module/forge/src/main/java/net/minecraftforge/common/ISpecialArmor.java similarity index 100% rename from src/main/java/net/minecraftforge/common/ISpecialArmor.java rename to module/forge/src/main/java/net/minecraftforge/common/ISpecialArmor.java diff --git a/src/main/java/net/minecraftforge/common/MinecraftForge.java b/module/forge/src/main/java/net/minecraftforge/common/MinecraftForge.java similarity index 100% rename from src/main/java/net/minecraftforge/common/MinecraftForge.java rename to module/forge/src/main/java/net/minecraftforge/common/MinecraftForge.java diff --git a/src/main/java/net/minecraftforge/common/UsernameCache.java b/module/forge/src/main/java/net/minecraftforge/common/UsernameCache.java similarity index 100% rename from src/main/java/net/minecraftforge/common/UsernameCache.java rename to module/forge/src/main/java/net/minecraftforge/common/UsernameCache.java diff --git a/src/main/java/net/minecraftforge/common/WorldSpecificSaveHandler.java b/module/forge/src/main/java/net/minecraftforge/common/WorldSpecificSaveHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/common/WorldSpecificSaveHandler.java rename to module/forge/src/main/java/net/minecraftforge/common/WorldSpecificSaveHandler.java diff --git a/src/main/java/net/minecraftforge/common/WorldWorkerManager.java b/module/forge/src/main/java/net/minecraftforge/common/WorldWorkerManager.java similarity index 100% rename from src/main/java/net/minecraftforge/common/WorldWorkerManager.java rename to module/forge/src/main/java/net/minecraftforge/common/WorldWorkerManager.java diff --git a/src/main/java/net/minecraftforge/common/animation/Event.java b/module/forge/src/main/java/net/minecraftforge/common/animation/Event.java similarity index 100% rename from src/main/java/net/minecraftforge/common/animation/Event.java rename to module/forge/src/main/java/net/minecraftforge/common/animation/Event.java diff --git a/src/main/java/net/minecraftforge/common/animation/IEventHandler.java b/module/forge/src/main/java/net/minecraftforge/common/animation/IEventHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/common/animation/IEventHandler.java rename to module/forge/src/main/java/net/minecraftforge/common/animation/IEventHandler.java diff --git a/src/main/java/net/minecraftforge/common/animation/ITimeValue.java b/module/forge/src/main/java/net/minecraftforge/common/animation/ITimeValue.java similarity index 100% rename from src/main/java/net/minecraftforge/common/animation/ITimeValue.java rename to module/forge/src/main/java/net/minecraftforge/common/animation/ITimeValue.java diff --git a/src/main/java/net/minecraftforge/common/animation/TimeValues.java b/module/forge/src/main/java/net/minecraftforge/common/animation/TimeValues.java similarity index 100% rename from src/main/java/net/minecraftforge/common/animation/TimeValues.java rename to module/forge/src/main/java/net/minecraftforge/common/animation/TimeValues.java diff --git a/src/main/java/net/minecraftforge/common/brewing/AbstractBrewingRecipe.java b/module/forge/src/main/java/net/minecraftforge/common/brewing/AbstractBrewingRecipe.java similarity index 100% rename from src/main/java/net/minecraftforge/common/brewing/AbstractBrewingRecipe.java rename to module/forge/src/main/java/net/minecraftforge/common/brewing/AbstractBrewingRecipe.java diff --git a/src/main/java/net/minecraftforge/common/brewing/BrewingOreRecipe.java b/module/forge/src/main/java/net/minecraftforge/common/brewing/BrewingOreRecipe.java similarity index 100% rename from src/main/java/net/minecraftforge/common/brewing/BrewingOreRecipe.java rename to module/forge/src/main/java/net/minecraftforge/common/brewing/BrewingOreRecipe.java diff --git a/src/main/java/net/minecraftforge/common/brewing/BrewingRecipe.java b/module/forge/src/main/java/net/minecraftforge/common/brewing/BrewingRecipe.java similarity index 100% rename from src/main/java/net/minecraftforge/common/brewing/BrewingRecipe.java rename to module/forge/src/main/java/net/minecraftforge/common/brewing/BrewingRecipe.java diff --git a/src/main/java/net/minecraftforge/common/brewing/BrewingRecipeRegistry.java b/module/forge/src/main/java/net/minecraftforge/common/brewing/BrewingRecipeRegistry.java similarity index 100% rename from src/main/java/net/minecraftforge/common/brewing/BrewingRecipeRegistry.java rename to module/forge/src/main/java/net/minecraftforge/common/brewing/BrewingRecipeRegistry.java diff --git a/src/main/java/net/minecraftforge/common/brewing/IBrewingRecipe.java b/module/forge/src/main/java/net/minecraftforge/common/brewing/IBrewingRecipe.java similarity index 100% rename from src/main/java/net/minecraftforge/common/brewing/IBrewingRecipe.java rename to module/forge/src/main/java/net/minecraftforge/common/brewing/IBrewingRecipe.java diff --git a/src/main/java/net/minecraftforge/common/brewing/VanillaBrewingRecipe.java b/module/forge/src/main/java/net/minecraftforge/common/brewing/VanillaBrewingRecipe.java similarity index 100% rename from src/main/java/net/minecraftforge/common/brewing/VanillaBrewingRecipe.java rename to module/forge/src/main/java/net/minecraftforge/common/brewing/VanillaBrewingRecipe.java diff --git a/src/main/java/net/minecraftforge/common/capabilities/Capability.java b/module/forge/src/main/java/net/minecraftforge/common/capabilities/Capability.java similarity index 100% rename from src/main/java/net/minecraftforge/common/capabilities/Capability.java rename to module/forge/src/main/java/net/minecraftforge/common/capabilities/Capability.java diff --git a/src/main/java/net/minecraftforge/common/capabilities/CapabilityDispatcher.java b/module/forge/src/main/java/net/minecraftforge/common/capabilities/CapabilityDispatcher.java similarity index 100% rename from src/main/java/net/minecraftforge/common/capabilities/CapabilityDispatcher.java rename to module/forge/src/main/java/net/minecraftforge/common/capabilities/CapabilityDispatcher.java diff --git a/src/main/java/net/minecraftforge/common/capabilities/CapabilityInject.java b/module/forge/src/main/java/net/minecraftforge/common/capabilities/CapabilityInject.java similarity index 100% rename from src/main/java/net/minecraftforge/common/capabilities/CapabilityInject.java rename to module/forge/src/main/java/net/minecraftforge/common/capabilities/CapabilityInject.java diff --git a/src/main/java/net/minecraftforge/common/capabilities/CapabilityManager.java b/module/forge/src/main/java/net/minecraftforge/common/capabilities/CapabilityManager.java similarity index 100% rename from src/main/java/net/minecraftforge/common/capabilities/CapabilityManager.java rename to module/forge/src/main/java/net/minecraftforge/common/capabilities/CapabilityManager.java diff --git a/src/main/java/net/minecraftforge/common/capabilities/ICapabilityProvider.java b/module/forge/src/main/java/net/minecraftforge/common/capabilities/ICapabilityProvider.java similarity index 100% rename from src/main/java/net/minecraftforge/common/capabilities/ICapabilityProvider.java rename to module/forge/src/main/java/net/minecraftforge/common/capabilities/ICapabilityProvider.java diff --git a/src/main/java/net/minecraftforge/common/capabilities/ICapabilitySerializable.java b/module/forge/src/main/java/net/minecraftforge/common/capabilities/ICapabilitySerializable.java similarity index 100% rename from src/main/java/net/minecraftforge/common/capabilities/ICapabilitySerializable.java rename to module/forge/src/main/java/net/minecraftforge/common/capabilities/ICapabilitySerializable.java diff --git a/src/main/java/net/minecraftforge/common/chunkio/ChunkIOExecutor.java b/module/forge/src/main/java/net/minecraftforge/common/chunkio/ChunkIOExecutor.java similarity index 100% rename from src/main/java/net/minecraftforge/common/chunkio/ChunkIOExecutor.java rename to module/forge/src/main/java/net/minecraftforge/common/chunkio/ChunkIOExecutor.java diff --git a/src/main/java/net/minecraftforge/common/chunkio/ChunkIOProvider.java b/module/forge/src/main/java/net/minecraftforge/common/chunkio/ChunkIOProvider.java similarity index 100% rename from src/main/java/net/minecraftforge/common/chunkio/ChunkIOProvider.java rename to module/forge/src/main/java/net/minecraftforge/common/chunkio/ChunkIOProvider.java diff --git a/src/main/java/net/minecraftforge/common/chunkio/ChunkIOThreadPoolExecutor.java b/module/forge/src/main/java/net/minecraftforge/common/chunkio/ChunkIOThreadPoolExecutor.java similarity index 100% rename from src/main/java/net/minecraftforge/common/chunkio/ChunkIOThreadPoolExecutor.java rename to module/forge/src/main/java/net/minecraftforge/common/chunkio/ChunkIOThreadPoolExecutor.java diff --git a/src/main/java/net/minecraftforge/common/chunkio/QueuedChunk.java b/module/forge/src/main/java/net/minecraftforge/common/chunkio/QueuedChunk.java similarity index 100% rename from src/main/java/net/minecraftforge/common/chunkio/QueuedChunk.java rename to module/forge/src/main/java/net/minecraftforge/common/chunkio/QueuedChunk.java diff --git a/src/main/java/net/minecraftforge/common/command/SelectorHandler.java b/module/forge/src/main/java/net/minecraftforge/common/command/SelectorHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/common/command/SelectorHandler.java rename to module/forge/src/main/java/net/minecraftforge/common/command/SelectorHandler.java diff --git a/src/main/java/net/minecraftforge/common/command/SelectorHandlerManager.java b/module/forge/src/main/java/net/minecraftforge/common/command/SelectorHandlerManager.java similarity index 100% rename from src/main/java/net/minecraftforge/common/command/SelectorHandlerManager.java rename to module/forge/src/main/java/net/minecraftforge/common/command/SelectorHandlerManager.java diff --git a/src/main/java/net/minecraftforge/common/config/Config.java b/module/forge/src/main/java/net/minecraftforge/common/config/Config.java similarity index 100% rename from src/main/java/net/minecraftforge/common/config/Config.java rename to module/forge/src/main/java/net/minecraftforge/common/config/Config.java diff --git a/src/main/java/net/minecraftforge/common/config/ConfigCategory.java b/module/forge/src/main/java/net/minecraftforge/common/config/ConfigCategory.java similarity index 100% rename from src/main/java/net/minecraftforge/common/config/ConfigCategory.java rename to module/forge/src/main/java/net/minecraftforge/common/config/ConfigCategory.java diff --git a/src/main/java/net/minecraftforge/common/config/ConfigElement.java b/module/forge/src/main/java/net/minecraftforge/common/config/ConfigElement.java similarity index 100% rename from src/main/java/net/minecraftforge/common/config/ConfigElement.java rename to module/forge/src/main/java/net/minecraftforge/common/config/ConfigElement.java diff --git a/src/main/java/net/minecraftforge/common/config/ConfigManager.java b/module/forge/src/main/java/net/minecraftforge/common/config/ConfigManager.java similarity index 100% rename from src/main/java/net/minecraftforge/common/config/ConfigManager.java rename to module/forge/src/main/java/net/minecraftforge/common/config/ConfigManager.java diff --git a/src/main/java/net/minecraftforge/common/config/Configuration.java b/module/forge/src/main/java/net/minecraftforge/common/config/Configuration.java similarity index 100% rename from src/main/java/net/minecraftforge/common/config/Configuration.java rename to module/forge/src/main/java/net/minecraftforge/common/config/Configuration.java diff --git a/src/main/java/net/minecraftforge/common/config/FieldWrapper.java b/module/forge/src/main/java/net/minecraftforge/common/config/FieldWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/common/config/FieldWrapper.java rename to module/forge/src/main/java/net/minecraftforge/common/config/FieldWrapper.java diff --git a/src/main/java/net/minecraftforge/common/config/IFieldWrapper.java b/module/forge/src/main/java/net/minecraftforge/common/config/IFieldWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/common/config/IFieldWrapper.java rename to module/forge/src/main/java/net/minecraftforge/common/config/IFieldWrapper.java diff --git a/src/main/java/net/minecraftforge/common/config/ITypeAdapter.java b/module/forge/src/main/java/net/minecraftforge/common/config/ITypeAdapter.java similarity index 100% rename from src/main/java/net/minecraftforge/common/config/ITypeAdapter.java rename to module/forge/src/main/java/net/minecraftforge/common/config/ITypeAdapter.java diff --git a/src/main/java/net/minecraftforge/common/config/Property.java b/module/forge/src/main/java/net/minecraftforge/common/config/Property.java similarity index 100% rename from src/main/java/net/minecraftforge/common/config/Property.java rename to module/forge/src/main/java/net/minecraftforge/common/config/Property.java diff --git a/src/main/java/net/minecraftforge/common/config/TypeAdapters.java b/module/forge/src/main/java/net/minecraftforge/common/config/TypeAdapters.java similarity index 100% rename from src/main/java/net/minecraftforge/common/config/TypeAdapters.java rename to module/forge/src/main/java/net/minecraftforge/common/config/TypeAdapters.java diff --git a/src/main/java/net/minecraftforge/common/crafting/CompoundIngredient.java b/module/forge/src/main/java/net/minecraftforge/common/crafting/CompoundIngredient.java similarity index 100% rename from src/main/java/net/minecraftforge/common/crafting/CompoundIngredient.java rename to module/forge/src/main/java/net/minecraftforge/common/crafting/CompoundIngredient.java diff --git a/src/main/java/net/minecraftforge/common/crafting/CraftingHelper.java b/module/forge/src/main/java/net/minecraftforge/common/crafting/CraftingHelper.java similarity index 100% rename from src/main/java/net/minecraftforge/common/crafting/CraftingHelper.java rename to module/forge/src/main/java/net/minecraftforge/common/crafting/CraftingHelper.java diff --git a/src/main/java/net/minecraftforge/common/crafting/IConditionFactory.java b/module/forge/src/main/java/net/minecraftforge/common/crafting/IConditionFactory.java similarity index 100% rename from src/main/java/net/minecraftforge/common/crafting/IConditionFactory.java rename to module/forge/src/main/java/net/minecraftforge/common/crafting/IConditionFactory.java diff --git a/src/main/java/net/minecraftforge/common/crafting/IIngredientFactory.java b/module/forge/src/main/java/net/minecraftforge/common/crafting/IIngredientFactory.java similarity index 100% rename from src/main/java/net/minecraftforge/common/crafting/IIngredientFactory.java rename to module/forge/src/main/java/net/minecraftforge/common/crafting/IIngredientFactory.java diff --git a/src/main/java/net/minecraftforge/common/crafting/IRecipeContainer.java b/module/forge/src/main/java/net/minecraftforge/common/crafting/IRecipeContainer.java similarity index 100% rename from src/main/java/net/minecraftforge/common/crafting/IRecipeContainer.java rename to module/forge/src/main/java/net/minecraftforge/common/crafting/IRecipeContainer.java diff --git a/src/main/java/net/minecraftforge/common/crafting/IRecipeFactory.java b/module/forge/src/main/java/net/minecraftforge/common/crafting/IRecipeFactory.java similarity index 100% rename from src/main/java/net/minecraftforge/common/crafting/IRecipeFactory.java rename to module/forge/src/main/java/net/minecraftforge/common/crafting/IRecipeFactory.java diff --git a/src/main/java/net/minecraftforge/common/crafting/IShapedRecipe.java b/module/forge/src/main/java/net/minecraftforge/common/crafting/IShapedRecipe.java similarity index 100% rename from src/main/java/net/minecraftforge/common/crafting/IShapedRecipe.java rename to module/forge/src/main/java/net/minecraftforge/common/crafting/IShapedRecipe.java diff --git a/src/main/java/net/minecraftforge/common/crafting/IngredientNBT.java b/module/forge/src/main/java/net/minecraftforge/common/crafting/IngredientNBT.java similarity index 100% rename from src/main/java/net/minecraftforge/common/crafting/IngredientNBT.java rename to module/forge/src/main/java/net/minecraftforge/common/crafting/IngredientNBT.java diff --git a/src/main/java/net/minecraftforge/common/crafting/JsonContext.java b/module/forge/src/main/java/net/minecraftforge/common/crafting/JsonContext.java similarity index 100% rename from src/main/java/net/minecraftforge/common/crafting/JsonContext.java rename to module/forge/src/main/java/net/minecraftforge/common/crafting/JsonContext.java diff --git a/src/main/java/net/minecraftforge/common/model/HiddenModelPart.java b/module/forge/src/main/java/net/minecraftforge/common/model/HiddenModelPart.java similarity index 100% rename from src/main/java/net/minecraftforge/common/model/HiddenModelPart.java rename to module/forge/src/main/java/net/minecraftforge/common/model/HiddenModelPart.java diff --git a/src/main/java/net/minecraftforge/common/model/IModelPart.java b/module/forge/src/main/java/net/minecraftforge/common/model/IModelPart.java similarity index 100% rename from src/main/java/net/minecraftforge/common/model/IModelPart.java rename to module/forge/src/main/java/net/minecraftforge/common/model/IModelPart.java diff --git a/src/main/java/net/minecraftforge/common/model/IModelState.java b/module/forge/src/main/java/net/minecraftforge/common/model/IModelState.java similarity index 100% rename from src/main/java/net/minecraftforge/common/model/IModelState.java rename to module/forge/src/main/java/net/minecraftforge/common/model/IModelState.java diff --git a/src/main/java/net/minecraftforge/common/model/ITransformation.java b/module/forge/src/main/java/net/minecraftforge/common/model/ITransformation.java similarity index 100% rename from src/main/java/net/minecraftforge/common/model/ITransformation.java rename to module/forge/src/main/java/net/minecraftforge/common/model/ITransformation.java diff --git a/src/main/java/net/minecraftforge/common/model/Models.java b/module/forge/src/main/java/net/minecraftforge/common/model/Models.java similarity index 100% rename from src/main/java/net/minecraftforge/common/model/Models.java rename to module/forge/src/main/java/net/minecraftforge/common/model/Models.java diff --git a/src/main/java/net/minecraftforge/common/model/TRSRTransformation.java b/module/forge/src/main/java/net/minecraftforge/common/model/TRSRTransformation.java similarity index 100% rename from src/main/java/net/minecraftforge/common/model/TRSRTransformation.java rename to module/forge/src/main/java/net/minecraftforge/common/model/TRSRTransformation.java diff --git a/src/main/java/net/minecraftforge/common/model/animation/AnimationStateMachine.java b/module/forge/src/main/java/net/minecraftforge/common/model/animation/AnimationStateMachine.java similarity index 100% rename from src/main/java/net/minecraftforge/common/model/animation/AnimationStateMachine.java rename to module/forge/src/main/java/net/minecraftforge/common/model/animation/AnimationStateMachine.java diff --git a/src/main/java/net/minecraftforge/common/model/animation/CapabilityAnimation.java b/module/forge/src/main/java/net/minecraftforge/common/model/animation/CapabilityAnimation.java similarity index 100% rename from src/main/java/net/minecraftforge/common/model/animation/CapabilityAnimation.java rename to module/forge/src/main/java/net/minecraftforge/common/model/animation/CapabilityAnimation.java diff --git a/src/main/java/net/minecraftforge/common/model/animation/Clips.java b/module/forge/src/main/java/net/minecraftforge/common/model/animation/Clips.java similarity index 100% rename from src/main/java/net/minecraftforge/common/model/animation/Clips.java rename to module/forge/src/main/java/net/minecraftforge/common/model/animation/Clips.java diff --git a/src/main/java/net/minecraftforge/common/model/animation/IAnimationStateMachine.java b/module/forge/src/main/java/net/minecraftforge/common/model/animation/IAnimationStateMachine.java similarity index 100% rename from src/main/java/net/minecraftforge/common/model/animation/IAnimationStateMachine.java rename to module/forge/src/main/java/net/minecraftforge/common/model/animation/IAnimationStateMachine.java diff --git a/src/main/java/net/minecraftforge/common/model/animation/IClip.java b/module/forge/src/main/java/net/minecraftforge/common/model/animation/IClip.java similarity index 100% rename from src/main/java/net/minecraftforge/common/model/animation/IClip.java rename to module/forge/src/main/java/net/minecraftforge/common/model/animation/IClip.java diff --git a/src/main/java/net/minecraftforge/common/model/animation/IJoint.java b/module/forge/src/main/java/net/minecraftforge/common/model/animation/IJoint.java similarity index 100% rename from src/main/java/net/minecraftforge/common/model/animation/IJoint.java rename to module/forge/src/main/java/net/minecraftforge/common/model/animation/IJoint.java diff --git a/src/main/java/net/minecraftforge/common/model/animation/IJointClip.java b/module/forge/src/main/java/net/minecraftforge/common/model/animation/IJointClip.java similarity index 100% rename from src/main/java/net/minecraftforge/common/model/animation/IJointClip.java rename to module/forge/src/main/java/net/minecraftforge/common/model/animation/IJointClip.java diff --git a/src/main/java/net/minecraftforge/common/model/animation/JointClips.java b/module/forge/src/main/java/net/minecraftforge/common/model/animation/JointClips.java similarity index 100% rename from src/main/java/net/minecraftforge/common/model/animation/JointClips.java rename to module/forge/src/main/java/net/minecraftforge/common/model/animation/JointClips.java diff --git a/src/main/java/net/minecraftforge/common/network/DimensionMessageHandler.java b/module/forge/src/main/java/net/minecraftforge/common/network/DimensionMessageHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/common/network/DimensionMessageHandler.java rename to module/forge/src/main/java/net/minecraftforge/common/network/DimensionMessageHandler.java diff --git a/src/main/java/net/minecraftforge/common/network/FluidIdRegistryMessageHandler.java b/module/forge/src/main/java/net/minecraftforge/common/network/FluidIdRegistryMessageHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/common/network/FluidIdRegistryMessageHandler.java rename to module/forge/src/main/java/net/minecraftforge/common/network/FluidIdRegistryMessageHandler.java diff --git a/src/main/java/net/minecraftforge/common/network/ForgeMessage.java b/module/forge/src/main/java/net/minecraftforge/common/network/ForgeMessage.java similarity index 100% rename from src/main/java/net/minecraftforge/common/network/ForgeMessage.java rename to module/forge/src/main/java/net/minecraftforge/common/network/ForgeMessage.java diff --git a/src/main/java/net/minecraftforge/common/network/ForgeNetworkHandler.java b/module/forge/src/main/java/net/minecraftforge/common/network/ForgeNetworkHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/common/network/ForgeNetworkHandler.java rename to module/forge/src/main/java/net/minecraftforge/common/network/ForgeNetworkHandler.java diff --git a/src/main/java/net/minecraftforge/common/network/ForgeRuntimeCodec.java b/module/forge/src/main/java/net/minecraftforge/common/network/ForgeRuntimeCodec.java similarity index 100% rename from src/main/java/net/minecraftforge/common/network/ForgeRuntimeCodec.java rename to module/forge/src/main/java/net/minecraftforge/common/network/ForgeRuntimeCodec.java diff --git a/src/main/java/net/minecraftforge/common/network/ServerToClientConnectionEstablishedHandler.java b/module/forge/src/main/java/net/minecraftforge/common/network/ServerToClientConnectionEstablishedHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/common/network/ServerToClientConnectionEstablishedHandler.java rename to module/forge/src/main/java/net/minecraftforge/common/network/ServerToClientConnectionEstablishedHandler.java diff --git a/src/main/java/net/minecraftforge/common/property/ExtendedBlockState.java b/module/forge/src/main/java/net/minecraftforge/common/property/ExtendedBlockState.java similarity index 100% rename from src/main/java/net/minecraftforge/common/property/ExtendedBlockState.java rename to module/forge/src/main/java/net/minecraftforge/common/property/ExtendedBlockState.java diff --git a/src/main/java/net/minecraftforge/common/property/IExtendedBlockState.java b/module/forge/src/main/java/net/minecraftforge/common/property/IExtendedBlockState.java similarity index 100% rename from src/main/java/net/minecraftforge/common/property/IExtendedBlockState.java rename to module/forge/src/main/java/net/minecraftforge/common/property/IExtendedBlockState.java diff --git a/src/main/java/net/minecraftforge/common/property/IUnlistedProperty.java b/module/forge/src/main/java/net/minecraftforge/common/property/IUnlistedProperty.java similarity index 100% rename from src/main/java/net/minecraftforge/common/property/IUnlistedProperty.java rename to module/forge/src/main/java/net/minecraftforge/common/property/IUnlistedProperty.java diff --git a/src/main/java/net/minecraftforge/common/property/Properties.java b/module/forge/src/main/java/net/minecraftforge/common/property/Properties.java similarity index 100% rename from src/main/java/net/minecraftforge/common/property/Properties.java rename to module/forge/src/main/java/net/minecraftforge/common/property/Properties.java diff --git a/src/main/java/net/minecraftforge/common/property/PropertyFloat.java b/module/forge/src/main/java/net/minecraftforge/common/property/PropertyFloat.java similarity index 100% rename from src/main/java/net/minecraftforge/common/property/PropertyFloat.java rename to module/forge/src/main/java/net/minecraftforge/common/property/PropertyFloat.java diff --git a/src/main/java/net/minecraftforge/common/ticket/AABBTicket.java b/module/forge/src/main/java/net/minecraftforge/common/ticket/AABBTicket.java similarity index 100% rename from src/main/java/net/minecraftforge/common/ticket/AABBTicket.java rename to module/forge/src/main/java/net/minecraftforge/common/ticket/AABBTicket.java diff --git a/src/main/java/net/minecraftforge/common/ticket/ChunkTicketManager.java b/module/forge/src/main/java/net/minecraftforge/common/ticket/ChunkTicketManager.java similarity index 100% rename from src/main/java/net/minecraftforge/common/ticket/ChunkTicketManager.java rename to module/forge/src/main/java/net/minecraftforge/common/ticket/ChunkTicketManager.java diff --git a/src/main/java/net/minecraftforge/common/ticket/ITicketGetter.java b/module/forge/src/main/java/net/minecraftforge/common/ticket/ITicketGetter.java similarity index 100% rename from src/main/java/net/minecraftforge/common/ticket/ITicketGetter.java rename to module/forge/src/main/java/net/minecraftforge/common/ticket/ITicketGetter.java diff --git a/src/main/java/net/minecraftforge/common/ticket/ITicketManager.java b/module/forge/src/main/java/net/minecraftforge/common/ticket/ITicketManager.java similarity index 100% rename from src/main/java/net/minecraftforge/common/ticket/ITicketManager.java rename to module/forge/src/main/java/net/minecraftforge/common/ticket/ITicketManager.java diff --git a/src/main/java/net/minecraftforge/common/ticket/MultiTicketManager.java b/module/forge/src/main/java/net/minecraftforge/common/ticket/MultiTicketManager.java similarity index 100% rename from src/main/java/net/minecraftforge/common/ticket/MultiTicketManager.java rename to module/forge/src/main/java/net/minecraftforge/common/ticket/MultiTicketManager.java diff --git a/src/main/java/net/minecraftforge/common/ticket/SimpleTicket.java b/module/forge/src/main/java/net/minecraftforge/common/ticket/SimpleTicket.java similarity index 100% rename from src/main/java/net/minecraftforge/common/ticket/SimpleTicket.java rename to module/forge/src/main/java/net/minecraftforge/common/ticket/SimpleTicket.java diff --git a/src/main/java/net/minecraftforge/common/util/BlockSnapshot.java b/module/forge/src/main/java/net/minecraftforge/common/util/BlockSnapshot.java similarity index 100% rename from src/main/java/net/minecraftforge/common/util/BlockSnapshot.java rename to module/forge/src/main/java/net/minecraftforge/common/util/BlockSnapshot.java diff --git a/src/main/java/net/minecraftforge/common/util/ChunkCoordComparator.java b/module/forge/src/main/java/net/minecraftforge/common/util/ChunkCoordComparator.java similarity index 100% rename from src/main/java/net/minecraftforge/common/util/ChunkCoordComparator.java rename to module/forge/src/main/java/net/minecraftforge/common/util/ChunkCoordComparator.java diff --git a/src/main/java/net/minecraftforge/common/util/CompoundDataFixer.java b/module/forge/src/main/java/net/minecraftforge/common/util/CompoundDataFixer.java similarity index 100% rename from src/main/java/net/minecraftforge/common/util/CompoundDataFixer.java rename to module/forge/src/main/java/net/minecraftforge/common/util/CompoundDataFixer.java diff --git a/src/main/java/net/minecraftforge/common/util/Constants.java b/module/forge/src/main/java/net/minecraftforge/common/util/Constants.java similarity index 100% rename from src/main/java/net/minecraftforge/common/util/Constants.java rename to module/forge/src/main/java/net/minecraftforge/common/util/Constants.java diff --git a/src/main/java/net/minecraftforge/common/util/EnumHelper.java b/module/forge/src/main/java/net/minecraftforge/common/util/EnumHelper.java similarity index 100% rename from src/main/java/net/minecraftforge/common/util/EnumHelper.java rename to module/forge/src/main/java/net/minecraftforge/common/util/EnumHelper.java diff --git a/src/main/java/net/minecraftforge/common/util/FakePlayer.java b/module/forge/src/main/java/net/minecraftforge/common/util/FakePlayer.java similarity index 100% rename from src/main/java/net/minecraftforge/common/util/FakePlayer.java rename to module/forge/src/main/java/net/minecraftforge/common/util/FakePlayer.java diff --git a/src/main/java/net/minecraftforge/common/util/FakePlayerFactory.java b/module/forge/src/main/java/net/minecraftforge/common/util/FakePlayerFactory.java similarity index 100% rename from src/main/java/net/minecraftforge/common/util/FakePlayerFactory.java rename to module/forge/src/main/java/net/minecraftforge/common/util/FakePlayerFactory.java diff --git a/src/main/java/net/minecraftforge/common/util/IDataFixerData.java b/module/forge/src/main/java/net/minecraftforge/common/util/IDataFixerData.java similarity index 100% rename from src/main/java/net/minecraftforge/common/util/IDataFixerData.java rename to module/forge/src/main/java/net/minecraftforge/common/util/IDataFixerData.java diff --git a/src/main/java/net/minecraftforge/common/util/INBTSerializable.java b/module/forge/src/main/java/net/minecraftforge/common/util/INBTSerializable.java similarity index 100% rename from src/main/java/net/minecraftforge/common/util/INBTSerializable.java rename to module/forge/src/main/java/net/minecraftforge/common/util/INBTSerializable.java diff --git a/src/main/java/net/minecraftforge/common/util/ITeleporter.java b/module/forge/src/main/java/net/minecraftforge/common/util/ITeleporter.java similarity index 100% rename from src/main/java/net/minecraftforge/common/util/ITeleporter.java rename to module/forge/src/main/java/net/minecraftforge/common/util/ITeleporter.java diff --git a/src/main/java/net/minecraftforge/common/util/JsonUtils.java b/module/forge/src/main/java/net/minecraftforge/common/util/JsonUtils.java similarity index 100% rename from src/main/java/net/minecraftforge/common/util/JsonUtils.java rename to module/forge/src/main/java/net/minecraftforge/common/util/JsonUtils.java diff --git a/src/main/java/net/minecraftforge/common/util/ModFixs.java b/module/forge/src/main/java/net/minecraftforge/common/util/ModFixs.java similarity index 100% rename from src/main/java/net/minecraftforge/common/util/ModFixs.java rename to module/forge/src/main/java/net/minecraftforge/common/util/ModFixs.java diff --git a/src/main/java/net/minecraftforge/common/util/PacketUtil.java b/module/forge/src/main/java/net/minecraftforge/common/util/PacketUtil.java similarity index 100% rename from src/main/java/net/minecraftforge/common/util/PacketUtil.java rename to module/forge/src/main/java/net/minecraftforge/common/util/PacketUtil.java diff --git a/src/main/java/net/minecraftforge/common/util/RecipeMatcher.java b/module/forge/src/main/java/net/minecraftforge/common/util/RecipeMatcher.java similarity index 100% rename from src/main/java/net/minecraftforge/common/util/RecipeMatcher.java rename to module/forge/src/main/java/net/minecraftforge/common/util/RecipeMatcher.java diff --git a/src/main/java/net/minecraftforge/common/util/TextTable.java b/module/forge/src/main/java/net/minecraftforge/common/util/TextTable.java similarity index 100% rename from src/main/java/net/minecraftforge/common/util/TextTable.java rename to module/forge/src/main/java/net/minecraftforge/common/util/TextTable.java diff --git a/src/main/java/net/minecraftforge/common/util/WorldCapabilityData.java b/module/forge/src/main/java/net/minecraftforge/common/util/WorldCapabilityData.java similarity index 100% rename from src/main/java/net/minecraftforge/common/util/WorldCapabilityData.java rename to module/forge/src/main/java/net/minecraftforge/common/util/WorldCapabilityData.java diff --git a/src/main/java/net/minecraftforge/energy/CapabilityEnergy.java b/module/forge/src/main/java/net/minecraftforge/energy/CapabilityEnergy.java similarity index 100% rename from src/main/java/net/minecraftforge/energy/CapabilityEnergy.java rename to module/forge/src/main/java/net/minecraftforge/energy/CapabilityEnergy.java diff --git a/src/main/java/net/minecraftforge/energy/EnergyStorage.java b/module/forge/src/main/java/net/minecraftforge/energy/EnergyStorage.java similarity index 100% rename from src/main/java/net/minecraftforge/energy/EnergyStorage.java rename to module/forge/src/main/java/net/minecraftforge/energy/EnergyStorage.java diff --git a/src/main/java/net/minecraftforge/energy/IEnergyStorage.java b/module/forge/src/main/java/net/minecraftforge/energy/IEnergyStorage.java similarity index 100% rename from src/main/java/net/minecraftforge/energy/IEnergyStorage.java rename to module/forge/src/main/java/net/minecraftforge/energy/IEnergyStorage.java diff --git a/src/main/java/net/minecraftforge/event/AnvilUpdateEvent.java b/module/forge/src/main/java/net/minecraftforge/event/AnvilUpdateEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/AnvilUpdateEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/AnvilUpdateEvent.java diff --git a/src/main/java/net/minecraftforge/event/AttachCapabilitiesEvent.java b/module/forge/src/main/java/net/minecraftforge/event/AttachCapabilitiesEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/AttachCapabilitiesEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/AttachCapabilitiesEvent.java diff --git a/src/main/java/net/minecraftforge/event/CommandEvent.java b/module/forge/src/main/java/net/minecraftforge/event/CommandEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/CommandEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/CommandEvent.java diff --git a/src/main/java/net/minecraftforge/event/DifficultyChangeEvent.java b/module/forge/src/main/java/net/minecraftforge/event/DifficultyChangeEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/DifficultyChangeEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/DifficultyChangeEvent.java diff --git a/src/main/java/net/minecraftforge/event/ForgeEventFactory.java b/module/forge/src/main/java/net/minecraftforge/event/ForgeEventFactory.java similarity index 100% rename from src/main/java/net/minecraftforge/event/ForgeEventFactory.java rename to module/forge/src/main/java/net/minecraftforge/event/ForgeEventFactory.java diff --git a/src/main/java/net/minecraftforge/event/GameRuleChangeEvent.java b/module/forge/src/main/java/net/minecraftforge/event/GameRuleChangeEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/GameRuleChangeEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/GameRuleChangeEvent.java diff --git a/src/main/java/net/minecraftforge/event/LootTableLoadEvent.java b/module/forge/src/main/java/net/minecraftforge/event/LootTableLoadEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/LootTableLoadEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/LootTableLoadEvent.java diff --git a/src/main/java/net/minecraftforge/event/RegistryEvent.java b/module/forge/src/main/java/net/minecraftforge/event/RegistryEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/RegistryEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/RegistryEvent.java diff --git a/src/main/java/net/minecraftforge/event/ServerChatEvent.java b/module/forge/src/main/java/net/minecraftforge/event/ServerChatEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/ServerChatEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/ServerChatEvent.java diff --git a/src/main/java/net/minecraftforge/event/brewing/PlayerBrewedPotionEvent.java b/module/forge/src/main/java/net/minecraftforge/event/brewing/PlayerBrewedPotionEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/brewing/PlayerBrewedPotionEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/brewing/PlayerBrewedPotionEvent.java diff --git a/src/main/java/net/minecraftforge/event/brewing/PotionBrewEvent.java b/module/forge/src/main/java/net/minecraftforge/event/brewing/PotionBrewEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/brewing/PotionBrewEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/brewing/PotionBrewEvent.java diff --git a/src/main/java/net/minecraftforge/event/enchanting/EnchantmentLevelSetEvent.java b/module/forge/src/main/java/net/minecraftforge/event/enchanting/EnchantmentLevelSetEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/enchanting/EnchantmentLevelSetEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/enchanting/EnchantmentLevelSetEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/EntityEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/EntityEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/EntityEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/EntityEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/EntityJoinWorldEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/EntityJoinWorldEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/EntityJoinWorldEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/EntityJoinWorldEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/EntityMobGriefingEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/EntityMobGriefingEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/EntityMobGriefingEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/EntityMobGriefingEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/EntityMountEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/EntityMountEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/EntityMountEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/EntityMountEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/EntityStruckByLightningEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/EntityStruckByLightningEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/EntityStruckByLightningEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/EntityStruckByLightningEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/EntityTravelToDimensionEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/EntityTravelToDimensionEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/EntityTravelToDimensionEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/EntityTravelToDimensionEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/PlaySoundAtEntityEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/PlaySoundAtEntityEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/PlaySoundAtEntityEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/PlaySoundAtEntityEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/ProjectileImpactEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/ProjectileImpactEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/ProjectileImpactEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/ProjectileImpactEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/ThrowableImpactEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/ThrowableImpactEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/ThrowableImpactEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/ThrowableImpactEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/item/ItemEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/item/ItemEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/item/ItemEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/item/ItemEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/item/ItemExpireEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/item/ItemExpireEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/item/ItemExpireEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/item/ItemExpireEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/item/ItemTossEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/item/ItemTossEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/item/ItemTossEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/item/ItemTossEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/AnimalTameEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/AnimalTameEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/AnimalTameEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/AnimalTameEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/BabyEntitySpawnEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/BabyEntitySpawnEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/BabyEntitySpawnEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/BabyEntitySpawnEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/EnderTeleportEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/EnderTeleportEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/EnderTeleportEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/EnderTeleportEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingAttackEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingAttackEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/LivingAttackEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingAttackEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingDamageEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingDamageEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/LivingDamageEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingDamageEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingDeathEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingDeathEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/LivingDeathEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingDeathEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingDestroyBlockEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingDestroyBlockEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/LivingDestroyBlockEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingDestroyBlockEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingDropsEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingDropsEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/LivingDropsEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingDropsEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingEntityUseItemEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingEntityUseItemEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/LivingEntityUseItemEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingEntityUseItemEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingEquipmentChangeEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingEquipmentChangeEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/LivingEquipmentChangeEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingEquipmentChangeEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/LivingEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingExperienceDropEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingExperienceDropEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/LivingExperienceDropEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingExperienceDropEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingFallEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingFallEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/LivingFallEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingFallEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingHealEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingHealEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/LivingHealEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingHealEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingHurtEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingHurtEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/LivingHurtEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingHurtEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingKnockBackEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingKnockBackEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/LivingKnockBackEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingKnockBackEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingPackSizeEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingPackSizeEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/LivingPackSizeEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingPackSizeEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingSetAttackTargetEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingSetAttackTargetEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/LivingSetAttackTargetEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingSetAttackTargetEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingSpawnEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingSpawnEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/LivingSpawnEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingSpawnEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/LootingLevelEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/LootingLevelEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/LootingLevelEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/LootingLevelEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/PotionColorCalculationEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/PotionColorCalculationEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/PotionColorCalculationEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/PotionColorCalculationEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/PotionEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/PotionEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/PotionEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/PotionEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/ZombieEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/ZombieEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/ZombieEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/ZombieEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/minecart/MinecartCollisionEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/minecart/MinecartCollisionEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/minecart/MinecartCollisionEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/minecart/MinecartCollisionEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/minecart/MinecartEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/minecart/MinecartEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/minecart/MinecartEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/minecart/MinecartEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/minecart/MinecartInteractEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/minecart/MinecartInteractEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/minecart/MinecartInteractEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/minecart/MinecartInteractEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/minecart/MinecartUpdateEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/minecart/MinecartUpdateEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/minecart/MinecartUpdateEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/minecart/MinecartUpdateEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/AdvancementEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/AdvancementEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/AdvancementEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/AdvancementEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/AnvilRepairEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/AnvilRepairEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/AnvilRepairEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/AnvilRepairEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/ArrowLooseEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/ArrowLooseEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/ArrowLooseEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/ArrowLooseEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/ArrowNockEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/ArrowNockEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/ArrowNockEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/ArrowNockEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/AttackEntityEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/AttackEntityEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/AttackEntityEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/AttackEntityEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/BonemealEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/BonemealEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/BonemealEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/BonemealEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/CriticalHitEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/CriticalHitEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/CriticalHitEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/CriticalHitEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/EntityItemPickupEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/EntityItemPickupEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/EntityItemPickupEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/EntityItemPickupEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/FillBucketEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/FillBucketEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/FillBucketEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/FillBucketEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/ItemFishedEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/ItemFishedEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/ItemFishedEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/ItemFishedEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/ItemTooltipEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/ItemTooltipEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/ItemTooltipEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/ItemTooltipEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/PlayerContainerEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerContainerEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/PlayerContainerEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerContainerEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/PlayerDestroyItemEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerDestroyItemEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/PlayerDestroyItemEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerDestroyItemEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/PlayerDropsEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerDropsEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/PlayerDropsEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerDropsEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/PlayerEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/PlayerEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/PlayerFlyableFallEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerFlyableFallEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/PlayerFlyableFallEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerFlyableFallEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/PlayerInteractEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerInteractEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/PlayerInteractEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerInteractEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/PlayerPickupXpEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerPickupXpEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/PlayerPickupXpEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerPickupXpEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/PlayerSetSpawnEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerSetSpawnEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/PlayerSetSpawnEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerSetSpawnEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/PlayerSleepInBedEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerSleepInBedEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/PlayerSleepInBedEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerSleepInBedEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/PlayerWakeUpEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerWakeUpEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/PlayerWakeUpEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerWakeUpEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/SleepingLocationCheckEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/SleepingLocationCheckEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/SleepingLocationCheckEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/SleepingLocationCheckEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/SleepingTimeCheckEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/SleepingTimeCheckEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/SleepingTimeCheckEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/SleepingTimeCheckEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/UseHoeEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/UseHoeEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/UseHoeEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/UseHoeEvent.java diff --git a/src/main/java/net/minecraftforge/event/furnace/FurnaceFuelBurnTimeEvent.java b/module/forge/src/main/java/net/minecraftforge/event/furnace/FurnaceFuelBurnTimeEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/furnace/FurnaceFuelBurnTimeEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/furnace/FurnaceFuelBurnTimeEvent.java diff --git a/src/main/java/net/minecraftforge/event/terraingen/BiomeEvent.java b/module/forge/src/main/java/net/minecraftforge/event/terraingen/BiomeEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/terraingen/BiomeEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/terraingen/BiomeEvent.java diff --git a/src/main/java/net/minecraftforge/event/terraingen/ChunkGeneratorEvent.java b/module/forge/src/main/java/net/minecraftforge/event/terraingen/ChunkGeneratorEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/terraingen/ChunkGeneratorEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/terraingen/ChunkGeneratorEvent.java diff --git a/src/main/java/net/minecraftforge/event/terraingen/DecorateBiomeEvent.java b/module/forge/src/main/java/net/minecraftforge/event/terraingen/DecorateBiomeEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/terraingen/DecorateBiomeEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/terraingen/DecorateBiomeEvent.java diff --git a/src/main/java/net/minecraftforge/event/terraingen/DeferredBiomeDecorator.java b/module/forge/src/main/java/net/minecraftforge/event/terraingen/DeferredBiomeDecorator.java similarity index 100% rename from src/main/java/net/minecraftforge/event/terraingen/DeferredBiomeDecorator.java rename to module/forge/src/main/java/net/minecraftforge/event/terraingen/DeferredBiomeDecorator.java diff --git a/src/main/java/net/minecraftforge/event/terraingen/InitMapGenEvent.java b/module/forge/src/main/java/net/minecraftforge/event/terraingen/InitMapGenEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/terraingen/InitMapGenEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/terraingen/InitMapGenEvent.java diff --git a/src/main/java/net/minecraftforge/event/terraingen/InitNoiseGensEvent.java b/module/forge/src/main/java/net/minecraftforge/event/terraingen/InitNoiseGensEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/terraingen/InitNoiseGensEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/terraingen/InitNoiseGensEvent.java diff --git a/src/main/java/net/minecraftforge/event/terraingen/OreGenEvent.java b/module/forge/src/main/java/net/minecraftforge/event/terraingen/OreGenEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/terraingen/OreGenEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/terraingen/OreGenEvent.java diff --git a/src/main/java/net/minecraftforge/event/terraingen/PopulateChunkEvent.java b/module/forge/src/main/java/net/minecraftforge/event/terraingen/PopulateChunkEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/terraingen/PopulateChunkEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/terraingen/PopulateChunkEvent.java diff --git a/src/main/java/net/minecraftforge/event/terraingen/SaplingGrowTreeEvent.java b/module/forge/src/main/java/net/minecraftforge/event/terraingen/SaplingGrowTreeEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/terraingen/SaplingGrowTreeEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/terraingen/SaplingGrowTreeEvent.java diff --git a/src/main/java/net/minecraftforge/event/terraingen/TerrainGen.java b/module/forge/src/main/java/net/minecraftforge/event/terraingen/TerrainGen.java similarity index 100% rename from src/main/java/net/minecraftforge/event/terraingen/TerrainGen.java rename to module/forge/src/main/java/net/minecraftforge/event/terraingen/TerrainGen.java diff --git a/src/main/java/net/minecraftforge/event/terraingen/WorldTypeEvent.java b/module/forge/src/main/java/net/minecraftforge/event/terraingen/WorldTypeEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/terraingen/WorldTypeEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/terraingen/WorldTypeEvent.java diff --git a/src/main/java/net/minecraftforge/event/village/MerchantTradeOffersEvent.java b/module/forge/src/main/java/net/minecraftforge/event/village/MerchantTradeOffersEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/village/MerchantTradeOffersEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/village/MerchantTradeOffersEvent.java diff --git a/src/main/java/net/minecraftforge/event/village/VillageSiegeEvent.java b/module/forge/src/main/java/net/minecraftforge/event/village/VillageSiegeEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/village/VillageSiegeEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/village/VillageSiegeEvent.java diff --git a/src/main/java/net/minecraftforge/event/world/BlockEvent.java b/module/forge/src/main/java/net/minecraftforge/event/world/BlockEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/world/BlockEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/world/BlockEvent.java diff --git a/src/main/java/net/minecraftforge/event/world/ChunkDataEvent.java b/module/forge/src/main/java/net/minecraftforge/event/world/ChunkDataEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/world/ChunkDataEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/world/ChunkDataEvent.java diff --git a/src/main/java/net/minecraftforge/event/world/ChunkEvent.java b/module/forge/src/main/java/net/minecraftforge/event/world/ChunkEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/world/ChunkEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/world/ChunkEvent.java diff --git a/src/main/java/net/minecraftforge/event/world/ChunkWatchEvent.java b/module/forge/src/main/java/net/minecraftforge/event/world/ChunkWatchEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/world/ChunkWatchEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/world/ChunkWatchEvent.java diff --git a/src/main/java/net/minecraftforge/event/world/ExplosionEvent.java b/module/forge/src/main/java/net/minecraftforge/event/world/ExplosionEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/world/ExplosionEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/world/ExplosionEvent.java diff --git a/src/main/java/net/minecraftforge/event/world/GetCollisionBoxesEvent.java b/module/forge/src/main/java/net/minecraftforge/event/world/GetCollisionBoxesEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/world/GetCollisionBoxesEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/world/GetCollisionBoxesEvent.java diff --git a/src/main/java/net/minecraftforge/event/world/NoteBlockEvent.java b/module/forge/src/main/java/net/minecraftforge/event/world/NoteBlockEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/world/NoteBlockEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/world/NoteBlockEvent.java diff --git a/src/main/java/net/minecraftforge/event/world/WorldEvent.java b/module/forge/src/main/java/net/minecraftforge/event/world/WorldEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/world/WorldEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/world/WorldEvent.java diff --git a/src/main/java/net/minecraftforge/fluids/BlockFluidBase.java b/module/forge/src/main/java/net/minecraftforge/fluids/BlockFluidBase.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/BlockFluidBase.java rename to module/forge/src/main/java/net/minecraftforge/fluids/BlockFluidBase.java diff --git a/src/main/java/net/minecraftforge/fluids/BlockFluidClassic.java b/module/forge/src/main/java/net/minecraftforge/fluids/BlockFluidClassic.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/BlockFluidClassic.java rename to module/forge/src/main/java/net/minecraftforge/fluids/BlockFluidClassic.java diff --git a/src/main/java/net/minecraftforge/fluids/BlockFluidFinite.java b/module/forge/src/main/java/net/minecraftforge/fluids/BlockFluidFinite.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/BlockFluidFinite.java rename to module/forge/src/main/java/net/minecraftforge/fluids/BlockFluidFinite.java diff --git a/src/main/java/net/minecraftforge/fluids/DispenseFluidContainer.java b/module/forge/src/main/java/net/minecraftforge/fluids/DispenseFluidContainer.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/DispenseFluidContainer.java rename to module/forge/src/main/java/net/minecraftforge/fluids/DispenseFluidContainer.java diff --git a/src/main/java/net/minecraftforge/fluids/Fluid.java b/module/forge/src/main/java/net/minecraftforge/fluids/Fluid.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/Fluid.java rename to module/forge/src/main/java/net/minecraftforge/fluids/Fluid.java diff --git a/src/main/java/net/minecraftforge/fluids/FluidActionResult.java b/module/forge/src/main/java/net/minecraftforge/fluids/FluidActionResult.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/FluidActionResult.java rename to module/forge/src/main/java/net/minecraftforge/fluids/FluidActionResult.java diff --git a/src/main/java/net/minecraftforge/fluids/FluidEvent.java b/module/forge/src/main/java/net/minecraftforge/fluids/FluidEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/FluidEvent.java rename to module/forge/src/main/java/net/minecraftforge/fluids/FluidEvent.java diff --git a/src/main/java/net/minecraftforge/fluids/FluidRegistry.java b/module/forge/src/main/java/net/minecraftforge/fluids/FluidRegistry.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/FluidRegistry.java rename to module/forge/src/main/java/net/minecraftforge/fluids/FluidRegistry.java diff --git a/src/main/java/net/minecraftforge/fluids/FluidStack.java b/module/forge/src/main/java/net/minecraftforge/fluids/FluidStack.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/FluidStack.java rename to module/forge/src/main/java/net/minecraftforge/fluids/FluidStack.java diff --git a/src/main/java/net/minecraftforge/fluids/FluidTank.java b/module/forge/src/main/java/net/minecraftforge/fluids/FluidTank.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/FluidTank.java rename to module/forge/src/main/java/net/minecraftforge/fluids/FluidTank.java diff --git a/src/main/java/net/minecraftforge/fluids/FluidTankInfo.java b/module/forge/src/main/java/net/minecraftforge/fluids/FluidTankInfo.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/FluidTankInfo.java rename to module/forge/src/main/java/net/minecraftforge/fluids/FluidTankInfo.java diff --git a/src/main/java/net/minecraftforge/fluids/FluidUtil.java b/module/forge/src/main/java/net/minecraftforge/fluids/FluidUtil.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/FluidUtil.java rename to module/forge/src/main/java/net/minecraftforge/fluids/FluidUtil.java diff --git a/src/main/java/net/minecraftforge/fluids/IFluidBlock.java b/module/forge/src/main/java/net/minecraftforge/fluids/IFluidBlock.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/IFluidBlock.java rename to module/forge/src/main/java/net/minecraftforge/fluids/IFluidBlock.java diff --git a/src/main/java/net/minecraftforge/fluids/IFluidTank.java b/module/forge/src/main/java/net/minecraftforge/fluids/IFluidTank.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/IFluidTank.java rename to module/forge/src/main/java/net/minecraftforge/fluids/IFluidTank.java diff --git a/src/main/java/net/minecraftforge/fluids/UniversalBucket.java b/module/forge/src/main/java/net/minecraftforge/fluids/UniversalBucket.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/UniversalBucket.java rename to module/forge/src/main/java/net/minecraftforge/fluids/UniversalBucket.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/CapabilityFluidHandler.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/CapabilityFluidHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/CapabilityFluidHandler.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/CapabilityFluidHandler.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/FluidTankProperties.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/FluidTankProperties.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/FluidTankProperties.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/FluidTankProperties.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/FluidTankPropertiesWrapper.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/FluidTankPropertiesWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/FluidTankPropertiesWrapper.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/FluidTankPropertiesWrapper.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/IFluidHandler.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/IFluidHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/IFluidHandler.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/IFluidHandler.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/IFluidHandlerItem.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/IFluidHandlerItem.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/IFluidHandlerItem.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/IFluidHandlerItem.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/IFluidTankProperties.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/IFluidTankProperties.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/IFluidTankProperties.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/IFluidTankProperties.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/ItemFluidContainer.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/ItemFluidContainer.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/ItemFluidContainer.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/ItemFluidContainer.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/TileFluidHandler.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/TileFluidHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/TileFluidHandler.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/TileFluidHandler.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/templates/EmptyFluidHandler.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/templates/EmptyFluidHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/templates/EmptyFluidHandler.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/templates/EmptyFluidHandler.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerConcatenate.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerConcatenate.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerConcatenate.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerConcatenate.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerFluidMap.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerFluidMap.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerFluidMap.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerFluidMap.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerItemStack.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerItemStack.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerItemStack.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerItemStack.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerItemStackSimple.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerItemStackSimple.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerItemStackSimple.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerItemStackSimple.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/templates/VoidFluidHandler.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/templates/VoidFluidHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/templates/VoidFluidHandler.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/templates/VoidFluidHandler.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/wrappers/BlockLiquidWrapper.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/wrappers/BlockLiquidWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/wrappers/BlockLiquidWrapper.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/wrappers/BlockLiquidWrapper.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/wrappers/BlockWrapper.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/wrappers/BlockWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/wrappers/BlockWrapper.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/wrappers/BlockWrapper.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/wrappers/FluidBlockWrapper.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/wrappers/FluidBlockWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/wrappers/FluidBlockWrapper.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/wrappers/FluidBlockWrapper.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/wrappers/FluidBucketWrapper.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/wrappers/FluidBucketWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/wrappers/FluidBucketWrapper.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/wrappers/FluidBucketWrapper.java diff --git a/src/main/java/net/minecraftforge/fml/client/CustomModLoadingErrorDisplayException.java b/module/forge/src/main/java/net/minecraftforge/fml/client/CustomModLoadingErrorDisplayException.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/CustomModLoadingErrorDisplayException.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/CustomModLoadingErrorDisplayException.java diff --git a/src/main/java/net/minecraftforge/fml/client/DefaultGuiFactory.java b/module/forge/src/main/java/net/minecraftforge/fml/client/DefaultGuiFactory.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/DefaultGuiFactory.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/DefaultGuiFactory.java diff --git a/src/main/java/net/minecraftforge/fml/client/ExtendedServerListData.java b/module/forge/src/main/java/net/minecraftforge/fml/client/ExtendedServerListData.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/ExtendedServerListData.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/ExtendedServerListData.java diff --git a/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java diff --git a/src/main/java/net/minecraftforge/fml/client/FMLConfigGuiFactory.java b/module/forge/src/main/java/net/minecraftforge/fml/client/FMLConfigGuiFactory.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/FMLConfigGuiFactory.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/FMLConfigGuiFactory.java diff --git a/src/main/java/net/minecraftforge/fml/client/FMLFileResourcePack.java b/module/forge/src/main/java/net/minecraftforge/fml/client/FMLFileResourcePack.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/FMLFileResourcePack.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/FMLFileResourcePack.java diff --git a/src/main/java/net/minecraftforge/fml/client/FMLFolderResourcePack.java b/module/forge/src/main/java/net/minecraftforge/fml/client/FMLFolderResourcePack.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/FMLFolderResourcePack.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/FMLFolderResourcePack.java diff --git a/src/main/java/net/minecraftforge/fml/client/GuiAccessDenied.java b/module/forge/src/main/java/net/minecraftforge/fml/client/GuiAccessDenied.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/GuiAccessDenied.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/GuiAccessDenied.java diff --git a/src/main/java/net/minecraftforge/fml/client/GuiBackupFailed.java b/module/forge/src/main/java/net/minecraftforge/fml/client/GuiBackupFailed.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/GuiBackupFailed.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/GuiBackupFailed.java diff --git a/src/main/java/net/minecraftforge/fml/client/GuiConfirmation.java b/module/forge/src/main/java/net/minecraftforge/fml/client/GuiConfirmation.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/GuiConfirmation.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/GuiConfirmation.java diff --git a/src/main/java/net/minecraftforge/fml/client/GuiCustomModLoadingErrorScreen.java b/module/forge/src/main/java/net/minecraftforge/fml/client/GuiCustomModLoadingErrorScreen.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/GuiCustomModLoadingErrorScreen.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/GuiCustomModLoadingErrorScreen.java diff --git a/src/main/java/net/minecraftforge/fml/client/GuiDupesFound.java b/module/forge/src/main/java/net/minecraftforge/fml/client/GuiDupesFound.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/GuiDupesFound.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/GuiDupesFound.java diff --git a/src/main/java/net/minecraftforge/fml/client/GuiErrorBase.java b/module/forge/src/main/java/net/minecraftforge/fml/client/GuiErrorBase.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/GuiErrorBase.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/GuiErrorBase.java diff --git a/src/main/java/net/minecraftforge/fml/client/GuiModList.java b/module/forge/src/main/java/net/minecraftforge/fml/client/GuiModList.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/GuiModList.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/GuiModList.java diff --git a/src/main/java/net/minecraftforge/fml/client/GuiModsMissing.java b/module/forge/src/main/java/net/minecraftforge/fml/client/GuiModsMissing.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/GuiModsMissing.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/GuiModsMissing.java diff --git a/src/main/java/net/minecraftforge/fml/client/GuiModsMissingForServer.java b/module/forge/src/main/java/net/minecraftforge/fml/client/GuiModsMissingForServer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/GuiModsMissingForServer.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/GuiModsMissingForServer.java diff --git a/src/main/java/net/minecraftforge/fml/client/GuiMultipleModsErrored.java b/module/forge/src/main/java/net/minecraftforge/fml/client/GuiMultipleModsErrored.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/GuiMultipleModsErrored.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/GuiMultipleModsErrored.java diff --git a/src/main/java/net/minecraftforge/fml/client/GuiNotification.java b/module/forge/src/main/java/net/minecraftforge/fml/client/GuiNotification.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/GuiNotification.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/GuiNotification.java diff --git a/src/main/java/net/minecraftforge/fml/client/GuiOldSaveLoadConfirm.java b/module/forge/src/main/java/net/minecraftforge/fml/client/GuiOldSaveLoadConfirm.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/GuiOldSaveLoadConfirm.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/GuiOldSaveLoadConfirm.java diff --git a/src/main/java/net/minecraftforge/fml/client/GuiScrollingList.java b/module/forge/src/main/java/net/minecraftforge/fml/client/GuiScrollingList.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/GuiScrollingList.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/GuiScrollingList.java diff --git a/src/main/java/net/minecraftforge/fml/client/GuiSlotModList.java b/module/forge/src/main/java/net/minecraftforge/fml/client/GuiSlotModList.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/GuiSlotModList.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/GuiSlotModList.java diff --git a/src/main/java/net/minecraftforge/fml/client/GuiSortingProblem.java b/module/forge/src/main/java/net/minecraftforge/fml/client/GuiSortingProblem.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/GuiSortingProblem.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/GuiSortingProblem.java diff --git a/src/main/java/net/minecraftforge/fml/client/GuiWrongMinecraft.java b/module/forge/src/main/java/net/minecraftforge/fml/client/GuiWrongMinecraft.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/GuiWrongMinecraft.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/GuiWrongMinecraft.java diff --git a/src/main/java/net/minecraftforge/fml/client/IDisplayableError.java b/module/forge/src/main/java/net/minecraftforge/fml/client/IDisplayableError.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/IDisplayableError.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/IDisplayableError.java diff --git a/src/main/java/net/minecraftforge/fml/client/IModGuiFactory.java b/module/forge/src/main/java/net/minecraftforge/fml/client/IModGuiFactory.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/IModGuiFactory.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/IModGuiFactory.java diff --git a/src/main/java/net/minecraftforge/fml/client/SplashProgress.java b/module/forge/src/main/java/net/minecraftforge/fml/client/SplashProgress.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/SplashProgress.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/SplashProgress.java diff --git a/src/main/java/net/minecraftforge/fml/client/config/ConfigGuiType.java b/module/forge/src/main/java/net/minecraftforge/fml/client/config/ConfigGuiType.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/config/ConfigGuiType.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/config/ConfigGuiType.java diff --git a/src/main/java/net/minecraftforge/fml/client/config/DummyConfigElement.java b/module/forge/src/main/java/net/minecraftforge/fml/client/config/DummyConfigElement.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/config/DummyConfigElement.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/config/DummyConfigElement.java diff --git a/src/main/java/net/minecraftforge/fml/client/config/GuiButtonExt.java b/module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiButtonExt.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/config/GuiButtonExt.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiButtonExt.java diff --git a/src/main/java/net/minecraftforge/fml/client/config/GuiCheckBox.java b/module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiCheckBox.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/config/GuiCheckBox.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiCheckBox.java diff --git a/src/main/java/net/minecraftforge/fml/client/config/GuiConfig.java b/module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiConfig.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/config/GuiConfig.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiConfig.java diff --git a/src/main/java/net/minecraftforge/fml/client/config/GuiConfigEntries.java b/module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiConfigEntries.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/config/GuiConfigEntries.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiConfigEntries.java diff --git a/src/main/java/net/minecraftforge/fml/client/config/GuiEditArray.java b/module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiEditArray.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/config/GuiEditArray.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiEditArray.java diff --git a/src/main/java/net/minecraftforge/fml/client/config/GuiEditArrayEntries.java b/module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiEditArrayEntries.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/config/GuiEditArrayEntries.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiEditArrayEntries.java diff --git a/src/main/java/net/minecraftforge/fml/client/config/GuiMessageDialog.java b/module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiMessageDialog.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/config/GuiMessageDialog.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiMessageDialog.java diff --git a/src/main/java/net/minecraftforge/fml/client/config/GuiSelectString.java b/module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiSelectString.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/config/GuiSelectString.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiSelectString.java diff --git a/src/main/java/net/minecraftforge/fml/client/config/GuiSelectStringEntries.java b/module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiSelectStringEntries.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/config/GuiSelectStringEntries.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiSelectStringEntries.java diff --git a/src/main/java/net/minecraftforge/fml/client/config/GuiSlider.java b/module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiSlider.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/config/GuiSlider.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiSlider.java diff --git a/src/main/java/net/minecraftforge/fml/client/config/GuiUnicodeGlyphButton.java b/module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiUnicodeGlyphButton.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/config/GuiUnicodeGlyphButton.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiUnicodeGlyphButton.java diff --git a/src/main/java/net/minecraftforge/fml/client/config/GuiUtils.java b/module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiUtils.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/config/GuiUtils.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiUtils.java diff --git a/src/main/java/net/minecraftforge/fml/client/config/HoverChecker.java b/module/forge/src/main/java/net/minecraftforge/fml/client/config/HoverChecker.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/config/HoverChecker.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/config/HoverChecker.java diff --git a/src/main/java/net/minecraftforge/fml/client/config/IConfigElement.java b/module/forge/src/main/java/net/minecraftforge/fml/client/config/IConfigElement.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/config/IConfigElement.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/config/IConfigElement.java diff --git a/src/main/java/net/minecraftforge/fml/client/event/ConfigChangedEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/client/event/ConfigChangedEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/event/ConfigChangedEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/event/ConfigChangedEvent.java diff --git a/src/main/java/net/minecraftforge/fml/client/registry/ClientRegistry.java b/module/forge/src/main/java/net/minecraftforge/fml/client/registry/ClientRegistry.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/registry/ClientRegistry.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/registry/ClientRegistry.java diff --git a/src/main/java/net/minecraftforge/fml/client/registry/IRenderFactory.java b/module/forge/src/main/java/net/minecraftforge/fml/client/registry/IRenderFactory.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/registry/IRenderFactory.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/registry/IRenderFactory.java diff --git a/src/main/java/net/minecraftforge/fml/client/registry/RenderingRegistry.java b/module/forge/src/main/java/net/minecraftforge/fml/client/registry/RenderingRegistry.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/registry/RenderingRegistry.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/registry/RenderingRegistry.java diff --git a/src/main/java/net/minecraftforge/fml/common/API.java b/module/forge/src/main/java/net/minecraftforge/fml/common/API.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/API.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/API.java diff --git a/src/main/java/net/minecraftforge/fml/common/AutomaticEventSubscriber.java b/module/forge/src/main/java/net/minecraftforge/fml/common/AutomaticEventSubscriber.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/AutomaticEventSubscriber.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/AutomaticEventSubscriber.java diff --git a/src/main/java/net/minecraftforge/fml/common/CertificateHelper.java b/module/forge/src/main/java/net/minecraftforge/fml/common/CertificateHelper.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/CertificateHelper.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/CertificateHelper.java diff --git a/src/main/java/net/minecraftforge/fml/common/ClassNameUtils.java b/module/forge/src/main/java/net/minecraftforge/fml/common/ClassNameUtils.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/ClassNameUtils.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/ClassNameUtils.java diff --git a/src/main/java/net/minecraftforge/fml/common/DummyModContainer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/DummyModContainer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/DummyModContainer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/DummyModContainer.java diff --git a/src/main/java/net/minecraftforge/fml/common/DuplicateModsFoundException.java b/module/forge/src/main/java/net/minecraftforge/fml/common/DuplicateModsFoundException.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/DuplicateModsFoundException.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/DuplicateModsFoundException.java diff --git a/src/main/java/net/minecraftforge/fml/common/EnhancedRuntimeException.java b/module/forge/src/main/java/net/minecraftforge/fml/common/EnhancedRuntimeException.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/EnhancedRuntimeException.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/EnhancedRuntimeException.java diff --git a/src/main/java/net/minecraftforge/fml/common/FMLCommonHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/FMLCommonHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/FMLCommonHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/FMLCommonHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/FMLContainer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/FMLContainer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/FMLContainer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/FMLContainer.java diff --git a/src/main/java/net/minecraftforge/fml/common/FMLContainerHolder.java b/module/forge/src/main/java/net/minecraftforge/fml/common/FMLContainerHolder.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/FMLContainerHolder.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/FMLContainerHolder.java diff --git a/src/main/java/net/minecraftforge/fml/common/FMLContextQuery.java b/module/forge/src/main/java/net/minecraftforge/fml/common/FMLContextQuery.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/FMLContextQuery.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/FMLContextQuery.java diff --git a/src/main/java/net/minecraftforge/fml/common/FMLLog.java b/module/forge/src/main/java/net/minecraftforge/fml/common/FMLLog.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/FMLLog.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/FMLLog.java diff --git a/src/main/java/net/minecraftforge/fml/common/FMLModContainer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/FMLModContainer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/FMLModContainer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/FMLModContainer.java diff --git a/src/main/java/net/minecraftforge/fml/common/ICrashCallable.java b/module/forge/src/main/java/net/minecraftforge/fml/common/ICrashCallable.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/ICrashCallable.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/ICrashCallable.java diff --git a/src/main/java/net/minecraftforge/fml/common/IEntitySelectorFactory.java b/module/forge/src/main/java/net/minecraftforge/fml/common/IEntitySelectorFactory.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/IEntitySelectorFactory.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/IEntitySelectorFactory.java diff --git a/src/main/java/net/minecraftforge/fml/common/IFMLHandledException.java b/module/forge/src/main/java/net/minecraftforge/fml/common/IFMLHandledException.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/IFMLHandledException.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/IFMLHandledException.java diff --git a/src/main/java/net/minecraftforge/fml/common/IFMLSidedHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/IFMLSidedHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/IFMLSidedHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/IFMLSidedHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/IFuelHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/IFuelHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/IFuelHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/IFuelHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/ILanguageAdapter.java b/module/forge/src/main/java/net/minecraftforge/fml/common/ILanguageAdapter.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/ILanguageAdapter.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/ILanguageAdapter.java diff --git a/src/main/java/net/minecraftforge/fml/common/IWorldGenerator.java b/module/forge/src/main/java/net/minecraftforge/fml/common/IWorldGenerator.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/IWorldGenerator.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/IWorldGenerator.java diff --git a/src/main/java/net/minecraftforge/fml/common/InjectedModContainer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/InjectedModContainer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/InjectedModContainer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/InjectedModContainer.java diff --git a/src/main/java/net/minecraftforge/fml/common/LoadController.java b/module/forge/src/main/java/net/minecraftforge/fml/common/LoadController.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/LoadController.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/LoadController.java diff --git a/src/main/java/net/minecraftforge/fml/common/Loader.java b/module/forge/src/main/java/net/minecraftforge/fml/common/Loader.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/Loader.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/Loader.java diff --git a/src/main/java/net/minecraftforge/fml/common/LoaderException.java b/module/forge/src/main/java/net/minecraftforge/fml/common/LoaderException.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/LoaderException.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/LoaderException.java diff --git a/src/main/java/net/minecraftforge/fml/common/LoaderExceptionModCrash.java b/module/forge/src/main/java/net/minecraftforge/fml/common/LoaderExceptionModCrash.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/LoaderExceptionModCrash.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/LoaderExceptionModCrash.java diff --git a/src/main/java/net/minecraftforge/fml/common/LoaderState.java b/module/forge/src/main/java/net/minecraftforge/fml/common/LoaderState.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/LoaderState.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/LoaderState.java diff --git a/src/main/java/net/minecraftforge/fml/common/MCPDummyContainer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/MCPDummyContainer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/MCPDummyContainer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/MCPDummyContainer.java diff --git a/src/main/java/net/minecraftforge/fml/common/MetadataCollection.java b/module/forge/src/main/java/net/minecraftforge/fml/common/MetadataCollection.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/MetadataCollection.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/MetadataCollection.java diff --git a/src/main/java/net/minecraftforge/fml/common/MinecraftDummyContainer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/MinecraftDummyContainer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/MinecraftDummyContainer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/MinecraftDummyContainer.java diff --git a/src/main/java/net/minecraftforge/fml/common/MissingModsException.java b/module/forge/src/main/java/net/minecraftforge/fml/common/MissingModsException.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/MissingModsException.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/MissingModsException.java diff --git a/src/main/java/net/minecraftforge/fml/common/Mod.java b/module/forge/src/main/java/net/minecraftforge/fml/common/Mod.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/Mod.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/Mod.java diff --git a/src/main/java/net/minecraftforge/fml/common/ModAPIManager.java b/module/forge/src/main/java/net/minecraftforge/fml/common/ModAPIManager.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/ModAPIManager.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/ModAPIManager.java diff --git a/src/main/java/net/minecraftforge/fml/common/ModClassLoader.java b/module/forge/src/main/java/net/minecraftforge/fml/common/ModClassLoader.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/ModClassLoader.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/ModClassLoader.java diff --git a/src/main/java/net/minecraftforge/fml/common/ModContainer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/ModContainer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/ModContainer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/ModContainer.java diff --git a/src/main/java/net/minecraftforge/fml/common/ModContainerFactory.java b/module/forge/src/main/java/net/minecraftforge/fml/common/ModContainerFactory.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/ModContainerFactory.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/ModContainerFactory.java diff --git a/src/main/java/net/minecraftforge/fml/common/ModMetadata.java b/module/forge/src/main/java/net/minecraftforge/fml/common/ModMetadata.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/ModMetadata.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/ModMetadata.java diff --git a/src/main/java/net/minecraftforge/fml/common/MultipleModsErrored.java b/module/forge/src/main/java/net/minecraftforge/fml/common/MultipleModsErrored.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/MultipleModsErrored.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/MultipleModsErrored.java diff --git a/src/main/java/net/minecraftforge/fml/common/ObfuscationReflectionHelper.java b/module/forge/src/main/java/net/minecraftforge/fml/common/ObfuscationReflectionHelper.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/ObfuscationReflectionHelper.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/ObfuscationReflectionHelper.java diff --git a/src/main/java/net/minecraftforge/fml/common/Optional.java b/module/forge/src/main/java/net/minecraftforge/fml/common/Optional.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/Optional.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/Optional.java diff --git a/src/main/java/net/minecraftforge/fml/common/ProgressManager.java b/module/forge/src/main/java/net/minecraftforge/fml/common/ProgressManager.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/ProgressManager.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/ProgressManager.java diff --git a/src/main/java/net/minecraftforge/fml/common/ProxyInjector.java b/module/forge/src/main/java/net/minecraftforge/fml/common/ProxyInjector.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/ProxyInjector.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/ProxyInjector.java diff --git a/src/main/java/net/minecraftforge/fml/common/SaveInspectionHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/SaveInspectionHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/SaveInspectionHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/SaveInspectionHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/SidedProxy.java b/module/forge/src/main/java/net/minecraftforge/fml/common/SidedProxy.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/SidedProxy.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/SidedProxy.java diff --git a/src/main/java/net/minecraftforge/fml/common/StartupQuery.java b/module/forge/src/main/java/net/minecraftforge/fml/common/StartupQuery.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/StartupQuery.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/StartupQuery.java diff --git a/src/main/java/net/minecraftforge/fml/common/TracingPrintStream.java b/module/forge/src/main/java/net/minecraftforge/fml/common/TracingPrintStream.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/TracingPrintStream.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/TracingPrintStream.java diff --git a/src/main/java/net/minecraftforge/fml/common/WorldAccessContainer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/WorldAccessContainer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/WorldAccessContainer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/WorldAccessContainer.java diff --git a/src/main/java/net/minecraftforge/fml/common/WrongMinecraftVersionException.java b/module/forge/src/main/java/net/minecraftforge/fml/common/WrongMinecraftVersionException.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/WrongMinecraftVersionException.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/WrongMinecraftVersionException.java diff --git a/src/main/java/net/minecraftforge/fml/common/ZipperUtil.java b/module/forge/src/main/java/net/minecraftforge/fml/common/ZipperUtil.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/ZipperUtil.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/ZipperUtil.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/ASMTransformerWrapper.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/ASMTransformerWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/ASMTransformerWrapper.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/ASMTransformerWrapper.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/FMLSanityChecker.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/FMLSanityChecker.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/FMLSanityChecker.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/FMLSanityChecker.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/ReobfuscationMarker.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/ReobfuscationMarker.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/ReobfuscationMarker.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/ReobfuscationMarker.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/AccessTransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/AccessTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/AccessTransformer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/AccessTransformer.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/DeobfuscationTransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/DeobfuscationTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/DeobfuscationTransformer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/DeobfuscationTransformer.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/EventSubscriberTransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/EventSubscriberTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/EventSubscriberTransformer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/EventSubscriberTransformer.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/EventSubscriptionTransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/EventSubscriptionTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/EventSubscriptionTransformer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/EventSubscriptionTransformer.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/FieldRedirectTransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/FieldRedirectTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/FieldRedirectTransformer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/FieldRedirectTransformer.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemBlockSpecialTransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemBlockSpecialTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemBlockSpecialTransformer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemBlockSpecialTransformer.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemBlockTransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemBlockTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemBlockTransformer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemBlockTransformer.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemStackTransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemStackTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemStackTransformer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemStackTransformer.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/LWJGLTransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/LWJGLTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/LWJGLTransformer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/LWJGLTransformer.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/MarkerTransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/MarkerTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/MarkerTransformer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/MarkerTransformer.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/ModAPITransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/ModAPITransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/ModAPITransformer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/ModAPITransformer.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/ModAccessTransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/ModAccessTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/ModAccessTransformer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/ModAccessTransformer.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/PatchingTransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/PatchingTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/PatchingTransformer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/PatchingTransformer.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/PotionEffectTransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/PotionEffectTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/PotionEffectTransformer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/PotionEffectTransformer.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/SideTransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/SideTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/SideTransformer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/SideTransformer.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/SoundEngineFixTransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/SoundEngineFixTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/SoundEngineFixTransformer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/SoundEngineFixTransformer.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/TerminalTransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/TerminalTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/TerminalTransformer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/TerminalTransformer.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/deobf/FMLRemappingAdapter.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/deobf/FMLRemappingAdapter.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/deobf/FMLRemappingAdapter.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/deobf/FMLRemappingAdapter.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/deobf/LZMAInputSupplier.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/deobf/LZMAInputSupplier.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/deobf/LZMAInputSupplier.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/deobf/LZMAInputSupplier.java diff --git a/src/main/java/net/minecraftforge/fml/common/discovery/ASMDataTable.java b/module/forge/src/main/java/net/minecraftforge/fml/common/discovery/ASMDataTable.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/discovery/ASMDataTable.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/discovery/ASMDataTable.java diff --git a/src/main/java/net/minecraftforge/fml/common/discovery/ContainerType.java b/module/forge/src/main/java/net/minecraftforge/fml/common/discovery/ContainerType.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/discovery/ContainerType.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/discovery/ContainerType.java diff --git a/src/main/java/net/minecraftforge/fml/common/discovery/DirectoryDiscoverer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/discovery/DirectoryDiscoverer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/discovery/DirectoryDiscoverer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/discovery/DirectoryDiscoverer.java diff --git a/src/main/java/net/minecraftforge/fml/common/discovery/ITypeDiscoverer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/discovery/ITypeDiscoverer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/discovery/ITypeDiscoverer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/discovery/ITypeDiscoverer.java diff --git a/src/main/java/net/minecraftforge/fml/common/discovery/JarDiscoverer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/discovery/JarDiscoverer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/discovery/JarDiscoverer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/discovery/JarDiscoverer.java diff --git a/src/main/java/net/minecraftforge/fml/common/discovery/ModCandidate.java b/module/forge/src/main/java/net/minecraftforge/fml/common/discovery/ModCandidate.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/discovery/ModCandidate.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/discovery/ModCandidate.java diff --git a/src/main/java/net/minecraftforge/fml/common/discovery/ModDiscoverer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/discovery/ModDiscoverer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/discovery/ModDiscoverer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/discovery/ModDiscoverer.java diff --git a/src/main/java/net/minecraftforge/fml/common/discovery/asm/ASMModParser.java b/module/forge/src/main/java/net/minecraftforge/fml/common/discovery/asm/ASMModParser.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/discovery/asm/ASMModParser.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/discovery/asm/ASMModParser.java diff --git a/src/main/java/net/minecraftforge/fml/common/discovery/asm/ModAnnotation.java b/module/forge/src/main/java/net/minecraftforge/fml/common/discovery/asm/ModAnnotation.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/discovery/asm/ModAnnotation.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/discovery/asm/ModAnnotation.java diff --git a/src/main/java/net/minecraftforge/fml/common/discovery/asm/ModAnnotationVisitor.java b/module/forge/src/main/java/net/minecraftforge/fml/common/discovery/asm/ModAnnotationVisitor.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/discovery/asm/ModAnnotationVisitor.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/discovery/asm/ModAnnotationVisitor.java diff --git a/src/main/java/net/minecraftforge/fml/common/discovery/asm/ModClassVisitor.java b/module/forge/src/main/java/net/minecraftforge/fml/common/discovery/asm/ModClassVisitor.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/discovery/asm/ModClassVisitor.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/discovery/asm/ModClassVisitor.java diff --git a/src/main/java/net/minecraftforge/fml/common/discovery/asm/ModFieldVisitor.java b/module/forge/src/main/java/net/minecraftforge/fml/common/discovery/asm/ModFieldVisitor.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/discovery/asm/ModFieldVisitor.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/discovery/asm/ModFieldVisitor.java diff --git a/src/main/java/net/minecraftforge/fml/common/discovery/asm/ModMethodVisitor.java b/module/forge/src/main/java/net/minecraftforge/fml/common/discovery/asm/ModMethodVisitor.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/discovery/asm/ModMethodVisitor.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/discovery/asm/ModMethodVisitor.java diff --git a/src/main/java/net/minecraftforge/fml/common/discovery/json/ASMInfo.java b/module/forge/src/main/java/net/minecraftforge/fml/common/discovery/json/ASMInfo.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/discovery/json/ASMInfo.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/discovery/json/ASMInfo.java diff --git a/src/main/java/net/minecraftforge/fml/common/discovery/json/JsonAnnotationLoader.java b/module/forge/src/main/java/net/minecraftforge/fml/common/discovery/json/JsonAnnotationLoader.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/discovery/json/JsonAnnotationLoader.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/discovery/json/JsonAnnotationLoader.java diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLConstructionEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLConstructionEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/event/FMLConstructionEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLConstructionEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/event/FMLEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLFingerprintViolationEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLFingerprintViolationEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/event/FMLFingerprintViolationEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLFingerprintViolationEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLInitializationEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLInitializationEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/event/FMLInitializationEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLInitializationEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLInterModComms.java b/module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLInterModComms.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/event/FMLInterModComms.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLInterModComms.java diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLLoadCompleteEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLLoadCompleteEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/event/FMLLoadCompleteEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLLoadCompleteEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLLoadEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLLoadEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/event/FMLLoadEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLLoadEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLModDisabledEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLModDisabledEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/event/FMLModDisabledEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLModDisabledEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLModIdMappingEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLModIdMappingEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/event/FMLModIdMappingEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLModIdMappingEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLPostInitializationEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLPostInitializationEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/event/FMLPostInitializationEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLPostInitializationEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLPreInitializationEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLPreInitializationEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/event/FMLPreInitializationEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLPreInitializationEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLServerAboutToStartEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLServerAboutToStartEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/event/FMLServerAboutToStartEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLServerAboutToStartEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLServerStartedEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLServerStartedEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/event/FMLServerStartedEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLServerStartedEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLServerStartingEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLServerStartingEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/event/FMLServerStartingEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLServerStartingEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLServerStoppedEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLServerStoppedEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/event/FMLServerStoppedEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLServerStoppedEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLServerStoppingEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLServerStoppingEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/event/FMLServerStoppingEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLServerStoppingEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLStateEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLStateEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/event/FMLStateEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLStateEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/eventhandler/ASMEventHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/ASMEventHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/eventhandler/ASMEventHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/ASMEventHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/eventhandler/Cancelable.java b/module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/Cancelable.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/eventhandler/Cancelable.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/Cancelable.java diff --git a/src/main/java/net/minecraftforge/fml/common/eventhandler/Event.java b/module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/Event.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/eventhandler/Event.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/Event.java diff --git a/src/main/java/net/minecraftforge/fml/common/eventhandler/EventBus.java b/module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/EventBus.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/eventhandler/EventBus.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/EventBus.java diff --git a/src/main/java/net/minecraftforge/fml/common/eventhandler/EventListenerFactory.java b/module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/EventListenerFactory.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/eventhandler/EventListenerFactory.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/EventListenerFactory.java diff --git a/src/main/java/net/minecraftforge/fml/common/eventhandler/EventPriority.java b/module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/EventPriority.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/eventhandler/EventPriority.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/EventPriority.java diff --git a/src/main/java/net/minecraftforge/fml/common/eventhandler/FMLThrowingEventBus.java b/module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/FMLThrowingEventBus.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/eventhandler/FMLThrowingEventBus.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/FMLThrowingEventBus.java diff --git a/src/main/java/net/minecraftforge/fml/common/eventhandler/GenericEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/GenericEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/eventhandler/GenericEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/GenericEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/eventhandler/IContextSetter.java b/module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/IContextSetter.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/eventhandler/IContextSetter.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/IContextSetter.java diff --git a/src/main/java/net/minecraftforge/fml/common/eventhandler/IEventExceptionHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/IEventExceptionHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/eventhandler/IEventExceptionHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/IEventExceptionHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/eventhandler/IEventListener.java b/module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/IEventListener.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/eventhandler/IEventListener.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/IEventListener.java diff --git a/src/main/java/net/minecraftforge/fml/common/eventhandler/IGenericEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/IGenericEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/eventhandler/IGenericEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/IGenericEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/eventhandler/ListenerList.java b/module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/ListenerList.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/eventhandler/ListenerList.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/ListenerList.java diff --git a/src/main/java/net/minecraftforge/fml/common/eventhandler/SubscribeEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/SubscribeEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/eventhandler/SubscribeEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/SubscribeEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/gameevent/InputEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/gameevent/InputEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/gameevent/InputEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/gameevent/InputEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/gameevent/PlayerEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/gameevent/PlayerEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/gameevent/PlayerEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/gameevent/PlayerEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/gameevent/TickEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/gameevent/TickEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/gameevent/TickEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/gameevent/TickEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/launcher/FMLDeobfTweaker.java b/module/forge/src/main/java/net/minecraftforge/fml/common/launcher/FMLDeobfTweaker.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/launcher/FMLDeobfTweaker.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/launcher/FMLDeobfTweaker.java diff --git a/src/main/java/net/minecraftforge/fml/common/launcher/FMLInjectionAndSortingTweaker.java b/module/forge/src/main/java/net/minecraftforge/fml/common/launcher/FMLInjectionAndSortingTweaker.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/launcher/FMLInjectionAndSortingTweaker.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/launcher/FMLInjectionAndSortingTweaker.java diff --git a/src/main/java/net/minecraftforge/fml/common/launcher/FMLServerTweaker.java b/module/forge/src/main/java/net/minecraftforge/fml/common/launcher/FMLServerTweaker.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/launcher/FMLServerTweaker.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/launcher/FMLServerTweaker.java diff --git a/src/main/java/net/minecraftforge/fml/common/launcher/FMLTweaker.java b/module/forge/src/main/java/net/minecraftforge/fml/common/launcher/FMLTweaker.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/launcher/FMLTweaker.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/launcher/FMLTweaker.java diff --git a/src/main/java/net/minecraftforge/fml/common/launcher/Yggdrasil.java b/module/forge/src/main/java/net/minecraftforge/fml/common/launcher/Yggdrasil.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/launcher/Yggdrasil.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/launcher/Yggdrasil.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/ByteBufUtils.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/ByteBufUtils.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/ByteBufUtils.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/ByteBufUtils.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/FMLEmbeddedChannel.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/FMLEmbeddedChannel.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/FMLEmbeddedChannel.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/FMLEmbeddedChannel.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/FMLEventChannel.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/FMLEventChannel.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/FMLEventChannel.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/FMLEventChannel.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/FMLIndexedMessageToMessageCodec.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/FMLIndexedMessageToMessageCodec.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/FMLIndexedMessageToMessageCodec.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/FMLIndexedMessageToMessageCodec.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/FMLNetworkEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/FMLNetworkEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/FMLNetworkEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/FMLNetworkEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/FMLNetworkException.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/FMLNetworkException.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/FMLNetworkException.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/FMLNetworkException.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/FMLOutboundHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/FMLOutboundHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/FMLOutboundHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/FMLOutboundHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/IGuiHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/IGuiHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/IGuiHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/IGuiHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/NetworkCheckHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/NetworkCheckHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/NetworkCheckHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/NetworkCheckHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/NetworkEventFiringHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/NetworkEventFiringHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/NetworkEventFiringHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/NetworkEventFiringHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/NetworkHandshakeEstablished.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/NetworkHandshakeEstablished.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/NetworkHandshakeEstablished.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/NetworkHandshakeEstablished.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/NetworkRegistry.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/NetworkRegistry.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/NetworkRegistry.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/NetworkRegistry.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/PacketLoggingHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/PacketLoggingHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/PacketLoggingHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/PacketLoggingHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/handshake/ChannelRegistrationHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/ChannelRegistrationHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/handshake/ChannelRegistrationHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/ChannelRegistrationHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeClientState.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeClientState.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeClientState.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeClientState.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeCodec.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeCodec.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeCodec.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeCodec.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeMessage.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeMessage.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeMessage.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeMessage.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeServerState.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeServerState.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeServerState.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeServerState.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/handshake/HandshakeInjector.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/HandshakeInjector.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/handshake/HandshakeInjector.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/HandshakeInjector.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/handshake/HandshakeMessageHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/HandshakeMessageHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/handshake/HandshakeMessageHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/HandshakeMessageHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/handshake/IHandshakeState.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/IHandshakeState.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/handshake/IHandshakeState.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/IHandshakeState.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/handshake/NetworkDispatcher.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/NetworkDispatcher.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/handshake/NetworkDispatcher.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/NetworkDispatcher.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/internal/EntitySpawnHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/internal/EntitySpawnHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/internal/EntitySpawnHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/internal/EntitySpawnHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/internal/FMLMessage.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/internal/FMLMessage.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/internal/FMLMessage.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/internal/FMLMessage.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/internal/FMLNetworkHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/internal/FMLNetworkHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/internal/FMLNetworkHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/internal/FMLNetworkHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/internal/FMLProxyPacket.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/internal/FMLProxyPacket.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/internal/FMLProxyPacket.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/internal/FMLProxyPacket.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/internal/FMLRuntimeCodec.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/internal/FMLRuntimeCodec.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/internal/FMLRuntimeCodec.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/internal/FMLRuntimeCodec.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/internal/HandshakeCompletionHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/internal/HandshakeCompletionHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/internal/HandshakeCompletionHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/internal/HandshakeCompletionHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/internal/NetworkModHolder.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/internal/NetworkModHolder.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/internal/NetworkModHolder.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/internal/NetworkModHolder.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/internal/OpenGuiHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/internal/OpenGuiHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/internal/OpenGuiHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/internal/OpenGuiHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/IMessage.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/IMessage.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/simpleimpl/IMessage.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/IMessage.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/IMessageHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/IMessageHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/simpleimpl/IMessageHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/IMessageHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/MessageContext.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/MessageContext.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/simpleimpl/MessageContext.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/MessageContext.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleChannelHandlerWrapper.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleChannelHandlerWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleChannelHandlerWrapper.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleChannelHandlerWrapper.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleIndexedCodec.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleIndexedCodec.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleIndexedCodec.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleIndexedCodec.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleNetworkWrapper.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleNetworkWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleNetworkWrapper.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleNetworkWrapper.java diff --git a/src/main/java/net/minecraftforge/fml/common/patcher/ClassPatch.java b/module/forge/src/main/java/net/minecraftforge/fml/common/patcher/ClassPatch.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/patcher/ClassPatch.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/patcher/ClassPatch.java diff --git a/src/main/java/net/minecraftforge/fml/common/patcher/ClassPatchManager.java b/module/forge/src/main/java/net/minecraftforge/fml/common/patcher/ClassPatchManager.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/patcher/ClassPatchManager.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/patcher/ClassPatchManager.java diff --git a/src/main/java/net/minecraftforge/fml/common/patcher/GenDiffSet.java b/module/forge/src/main/java/net/minecraftforge/fml/common/patcher/GenDiffSet.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/patcher/GenDiffSet.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/patcher/GenDiffSet.java diff --git a/src/main/java/net/minecraftforge/fml/common/registry/EntityEntry.java b/module/forge/src/main/java/net/minecraftforge/fml/common/registry/EntityEntry.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/registry/EntityEntry.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/registry/EntityEntry.java diff --git a/src/main/java/net/minecraftforge/fml/common/registry/EntityEntryBuilder.java b/module/forge/src/main/java/net/minecraftforge/fml/common/registry/EntityEntryBuilder.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/registry/EntityEntryBuilder.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/registry/EntityEntryBuilder.java diff --git a/src/main/java/net/minecraftforge/fml/common/registry/EntityRegistry.java b/module/forge/src/main/java/net/minecraftforge/fml/common/registry/EntityRegistry.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/registry/EntityRegistry.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/registry/EntityRegistry.java diff --git a/src/main/java/net/minecraftforge/fml/common/registry/ExistingSubstitutionException.java b/module/forge/src/main/java/net/minecraftforge/fml/common/registry/ExistingSubstitutionException.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/registry/ExistingSubstitutionException.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/registry/ExistingSubstitutionException.java diff --git a/src/main/java/net/minecraftforge/fml/common/registry/ForgeRegistries.java b/module/forge/src/main/java/net/minecraftforge/fml/common/registry/ForgeRegistries.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/registry/ForgeRegistries.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/registry/ForgeRegistries.java diff --git a/src/main/java/net/minecraftforge/fml/common/registry/GameRegistry.java b/module/forge/src/main/java/net/minecraftforge/fml/common/registry/GameRegistry.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/registry/GameRegistry.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/registry/GameRegistry.java diff --git a/src/main/java/net/minecraftforge/fml/common/registry/IEntityAdditionalSpawnData.java b/module/forge/src/main/java/net/minecraftforge/fml/common/registry/IEntityAdditionalSpawnData.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/registry/IEntityAdditionalSpawnData.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/registry/IEntityAdditionalSpawnData.java diff --git a/src/main/java/net/minecraftforge/fml/common/registry/IThrowableEntity.java b/module/forge/src/main/java/net/minecraftforge/fml/common/registry/IThrowableEntity.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/registry/IThrowableEntity.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/registry/IThrowableEntity.java diff --git a/src/main/java/net/minecraftforge/fml/common/registry/ItemStackHolderInjector.java b/module/forge/src/main/java/net/minecraftforge/fml/common/registry/ItemStackHolderInjector.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/registry/ItemStackHolderInjector.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/registry/ItemStackHolderInjector.java diff --git a/src/main/java/net/minecraftforge/fml/common/registry/ItemStackHolderRef.java b/module/forge/src/main/java/net/minecraftforge/fml/common/registry/ItemStackHolderRef.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/registry/ItemStackHolderRef.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/registry/ItemStackHolderRef.java diff --git a/src/main/java/net/minecraftforge/fml/common/registry/VillagerRegistry.java b/module/forge/src/main/java/net/minecraftforge/fml/common/registry/VillagerRegistry.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/registry/VillagerRegistry.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/registry/VillagerRegistry.java diff --git a/src/main/java/net/minecraftforge/fml/common/thread/SidedThreadGroup.java b/module/forge/src/main/java/net/minecraftforge/fml/common/thread/SidedThreadGroup.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/thread/SidedThreadGroup.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/thread/SidedThreadGroup.java diff --git a/src/main/java/net/minecraftforge/fml/common/thread/SidedThreadGroups.java b/module/forge/src/main/java/net/minecraftforge/fml/common/thread/SidedThreadGroups.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/thread/SidedThreadGroups.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/thread/SidedThreadGroups.java diff --git a/src/main/java/net/minecraftforge/fml/common/toposort/ModSorter.java b/module/forge/src/main/java/net/minecraftforge/fml/common/toposort/ModSorter.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/toposort/ModSorter.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/toposort/ModSorter.java diff --git a/src/main/java/net/minecraftforge/fml/common/toposort/ModSortingException.java b/module/forge/src/main/java/net/minecraftforge/fml/common/toposort/ModSortingException.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/toposort/ModSortingException.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/toposort/ModSortingException.java diff --git a/src/main/java/net/minecraftforge/fml/common/toposort/TopologicalSort.java b/module/forge/src/main/java/net/minecraftforge/fml/common/toposort/TopologicalSort.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/toposort/TopologicalSort.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/toposort/TopologicalSort.java diff --git a/src/main/java/net/minecraftforge/fml/common/versioning/ArtifactVersion.java b/module/forge/src/main/java/net/minecraftforge/fml/common/versioning/ArtifactVersion.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/versioning/ArtifactVersion.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/versioning/ArtifactVersion.java diff --git a/src/main/java/net/minecraftforge/fml/common/versioning/ComparableVersion.java b/module/forge/src/main/java/net/minecraftforge/fml/common/versioning/ComparableVersion.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/versioning/ComparableVersion.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/versioning/ComparableVersion.java diff --git a/src/main/java/net/minecraftforge/fml/common/versioning/DefaultArtifactVersion.java b/module/forge/src/main/java/net/minecraftforge/fml/common/versioning/DefaultArtifactVersion.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/versioning/DefaultArtifactVersion.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/versioning/DefaultArtifactVersion.java diff --git a/src/main/java/net/minecraftforge/fml/common/versioning/DependencyParser.java b/module/forge/src/main/java/net/minecraftforge/fml/common/versioning/DependencyParser.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/versioning/DependencyParser.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/versioning/DependencyParser.java diff --git a/src/main/java/net/minecraftforge/fml/common/versioning/InvalidVersionSpecificationException.java b/module/forge/src/main/java/net/minecraftforge/fml/common/versioning/InvalidVersionSpecificationException.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/versioning/InvalidVersionSpecificationException.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/versioning/InvalidVersionSpecificationException.java diff --git a/src/main/java/net/minecraftforge/fml/common/versioning/Restriction.java b/module/forge/src/main/java/net/minecraftforge/fml/common/versioning/Restriction.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/versioning/Restriction.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/versioning/Restriction.java diff --git a/src/main/java/net/minecraftforge/fml/common/versioning/VersionParser.java b/module/forge/src/main/java/net/minecraftforge/fml/common/versioning/VersionParser.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/versioning/VersionParser.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/versioning/VersionParser.java diff --git a/src/main/java/net/minecraftforge/fml/common/versioning/VersionRange.java b/module/forge/src/main/java/net/minecraftforge/fml/common/versioning/VersionRange.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/versioning/VersionRange.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/versioning/VersionRange.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/CoreModManager.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/CoreModManager.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/CoreModManager.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/CoreModManager.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/FMLCorePlugin.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/FMLCorePlugin.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/FMLCorePlugin.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/FMLCorePlugin.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/FMLInjectionData.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/FMLInjectionData.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/FMLInjectionData.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/FMLInjectionData.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/FMLLaunchHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/FMLLaunchHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/FMLLaunchHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/FMLLaunchHandler.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/FMLRelaunchLog.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/FMLRelaunchLog.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/FMLRelaunchLog.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/FMLRelaunchLog.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/FileListHelper.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/FileListHelper.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/FileListHelper.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/FileListHelper.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/IFMLCallHook.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/IFMLCallHook.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/IFMLCallHook.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/IFMLCallHook.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/IFMLLoadingPlugin.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/IFMLLoadingPlugin.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/IFMLLoadingPlugin.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/IFMLLoadingPlugin.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/MixinBooterPlugin.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/MixinBooterPlugin.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/MixinBooterPlugin.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/MixinBooterPlugin.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/ReflectionHelper.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/ReflectionHelper.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/ReflectionHelper.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/ReflectionHelper.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/ServerLaunchWrapper.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/ServerLaunchWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/ServerLaunchWrapper.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/ServerLaunchWrapper.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/Side.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/Side.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/Side.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/Side.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/SideOnly.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/SideOnly.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/SideOnly.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/SideOnly.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/libraries/Artifact.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/libraries/Artifact.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/libraries/Artifact.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/libraries/Artifact.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/libraries/LibraryManager.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/libraries/LibraryManager.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/libraries/LibraryManager.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/libraries/LibraryManager.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/libraries/LinkRepository.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/libraries/LinkRepository.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/libraries/LinkRepository.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/libraries/LinkRepository.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/libraries/MemoryModList.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/libraries/MemoryModList.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/libraries/MemoryModList.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/libraries/MemoryModList.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/libraries/ModList.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/libraries/ModList.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/libraries/ModList.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/libraries/ModList.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/libraries/Repository.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/libraries/Repository.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/libraries/Repository.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/libraries/Repository.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/libraries/SnapshotJson.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/libraries/SnapshotJson.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/libraries/SnapshotJson.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/libraries/SnapshotJson.java diff --git a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/ByteBufferSeekableSource.java b/module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/ByteBufferSeekableSource.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/ByteBufferSeekableSource.java rename to module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/ByteBufferSeekableSource.java diff --git a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/Checksum.java b/module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/Checksum.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/Checksum.java rename to module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/Checksum.java diff --git a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/DebugDiffWriter.java b/module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/DebugDiffWriter.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/DebugDiffWriter.java rename to module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/DebugDiffWriter.java diff --git a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/Delta.java b/module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/Delta.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/Delta.java rename to module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/Delta.java diff --git a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/DiffWriter.java b/module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/DiffWriter.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/DiffWriter.java rename to module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/DiffWriter.java diff --git a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/GDiffPatcher.java b/module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/GDiffPatcher.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/GDiffPatcher.java rename to module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/GDiffPatcher.java diff --git a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/GDiffWriter.java b/module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/GDiffWriter.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/GDiffWriter.java rename to module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/GDiffWriter.java diff --git a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/PatchException.java b/module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/PatchException.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/PatchException.java rename to module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/PatchException.java diff --git a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/RandomAccessFileSeekableSource.java b/module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/RandomAccessFileSeekableSource.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/RandomAccessFileSeekableSource.java rename to module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/RandomAccessFileSeekableSource.java diff --git a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/SeekableSource.java b/module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/SeekableSource.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/SeekableSource.java rename to module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/SeekableSource.java diff --git a/src/main/java/net/minecraftforge/fml/server/FMLServerHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/server/FMLServerHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/server/FMLServerHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/server/FMLServerHandler.java diff --git a/src/main/java/net/minecraftforge/items/CapabilityItemHandler.java b/module/forge/src/main/java/net/minecraftforge/items/CapabilityItemHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/items/CapabilityItemHandler.java rename to module/forge/src/main/java/net/minecraftforge/items/CapabilityItemHandler.java diff --git a/src/main/java/net/minecraftforge/items/IItemHandler.java b/module/forge/src/main/java/net/minecraftforge/items/IItemHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/items/IItemHandler.java rename to module/forge/src/main/java/net/minecraftforge/items/IItemHandler.java diff --git a/src/main/java/net/minecraftforge/items/IItemHandlerModifiable.java b/module/forge/src/main/java/net/minecraftforge/items/IItemHandlerModifiable.java similarity index 100% rename from src/main/java/net/minecraftforge/items/IItemHandlerModifiable.java rename to module/forge/src/main/java/net/minecraftforge/items/IItemHandlerModifiable.java diff --git a/src/main/java/net/minecraftforge/items/ItemHandlerHelper.java b/module/forge/src/main/java/net/minecraftforge/items/ItemHandlerHelper.java similarity index 100% rename from src/main/java/net/minecraftforge/items/ItemHandlerHelper.java rename to module/forge/src/main/java/net/minecraftforge/items/ItemHandlerHelper.java diff --git a/src/main/java/net/minecraftforge/items/ItemStackHandler.java b/module/forge/src/main/java/net/minecraftforge/items/ItemStackHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/items/ItemStackHandler.java rename to module/forge/src/main/java/net/minecraftforge/items/ItemStackHandler.java diff --git a/src/main/java/net/minecraftforge/items/SlotItemHandler.java b/module/forge/src/main/java/net/minecraftforge/items/SlotItemHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/items/SlotItemHandler.java rename to module/forge/src/main/java/net/minecraftforge/items/SlotItemHandler.java diff --git a/src/main/java/net/minecraftforge/items/VanillaDoubleChestItemHandler.java b/module/forge/src/main/java/net/minecraftforge/items/VanillaDoubleChestItemHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/items/VanillaDoubleChestItemHandler.java rename to module/forge/src/main/java/net/minecraftforge/items/VanillaDoubleChestItemHandler.java diff --git a/src/main/java/net/minecraftforge/items/VanillaHopperItemHandler.java b/module/forge/src/main/java/net/minecraftforge/items/VanillaHopperItemHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/items/VanillaHopperItemHandler.java rename to module/forge/src/main/java/net/minecraftforge/items/VanillaHopperItemHandler.java diff --git a/src/main/java/net/minecraftforge/items/VanillaInventoryCodeHooks.java b/module/forge/src/main/java/net/minecraftforge/items/VanillaInventoryCodeHooks.java similarity index 100% rename from src/main/java/net/minecraftforge/items/VanillaInventoryCodeHooks.java rename to module/forge/src/main/java/net/minecraftforge/items/VanillaInventoryCodeHooks.java diff --git a/src/main/java/net/minecraftforge/items/wrapper/CombinedInvWrapper.java b/module/forge/src/main/java/net/minecraftforge/items/wrapper/CombinedInvWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/items/wrapper/CombinedInvWrapper.java rename to module/forge/src/main/java/net/minecraftforge/items/wrapper/CombinedInvWrapper.java diff --git a/src/main/java/net/minecraftforge/items/wrapper/EmptyHandler.java b/module/forge/src/main/java/net/minecraftforge/items/wrapper/EmptyHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/items/wrapper/EmptyHandler.java rename to module/forge/src/main/java/net/minecraftforge/items/wrapper/EmptyHandler.java diff --git a/src/main/java/net/minecraftforge/items/wrapper/EntityArmorInvWrapper.java b/module/forge/src/main/java/net/minecraftforge/items/wrapper/EntityArmorInvWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/items/wrapper/EntityArmorInvWrapper.java rename to module/forge/src/main/java/net/minecraftforge/items/wrapper/EntityArmorInvWrapper.java diff --git a/src/main/java/net/minecraftforge/items/wrapper/EntityEquipmentInvWrapper.java b/module/forge/src/main/java/net/minecraftforge/items/wrapper/EntityEquipmentInvWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/items/wrapper/EntityEquipmentInvWrapper.java rename to module/forge/src/main/java/net/minecraftforge/items/wrapper/EntityEquipmentInvWrapper.java diff --git a/src/main/java/net/minecraftforge/items/wrapper/EntityHandsInvWrapper.java b/module/forge/src/main/java/net/minecraftforge/items/wrapper/EntityHandsInvWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/items/wrapper/EntityHandsInvWrapper.java rename to module/forge/src/main/java/net/minecraftforge/items/wrapper/EntityHandsInvWrapper.java diff --git a/src/main/java/net/minecraftforge/items/wrapper/InvWrapper.java b/module/forge/src/main/java/net/minecraftforge/items/wrapper/InvWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/items/wrapper/InvWrapper.java rename to module/forge/src/main/java/net/minecraftforge/items/wrapper/InvWrapper.java diff --git a/src/main/java/net/minecraftforge/items/wrapper/PlayerArmorInvWrapper.java b/module/forge/src/main/java/net/minecraftforge/items/wrapper/PlayerArmorInvWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/items/wrapper/PlayerArmorInvWrapper.java rename to module/forge/src/main/java/net/minecraftforge/items/wrapper/PlayerArmorInvWrapper.java diff --git a/src/main/java/net/minecraftforge/items/wrapper/PlayerInvWrapper.java b/module/forge/src/main/java/net/minecraftforge/items/wrapper/PlayerInvWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/items/wrapper/PlayerInvWrapper.java rename to module/forge/src/main/java/net/minecraftforge/items/wrapper/PlayerInvWrapper.java diff --git a/src/main/java/net/minecraftforge/items/wrapper/PlayerMainInvWrapper.java b/module/forge/src/main/java/net/minecraftforge/items/wrapper/PlayerMainInvWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/items/wrapper/PlayerMainInvWrapper.java rename to module/forge/src/main/java/net/minecraftforge/items/wrapper/PlayerMainInvWrapper.java diff --git a/src/main/java/net/minecraftforge/items/wrapper/PlayerOffhandInvWrapper.java b/module/forge/src/main/java/net/minecraftforge/items/wrapper/PlayerOffhandInvWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/items/wrapper/PlayerOffhandInvWrapper.java rename to module/forge/src/main/java/net/minecraftforge/items/wrapper/PlayerOffhandInvWrapper.java diff --git a/src/main/java/net/minecraftforge/items/wrapper/RangedWrapper.java b/module/forge/src/main/java/net/minecraftforge/items/wrapper/RangedWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/items/wrapper/RangedWrapper.java rename to module/forge/src/main/java/net/minecraftforge/items/wrapper/RangedWrapper.java diff --git a/src/main/java/net/minecraftforge/items/wrapper/SidedInvWrapper.java b/module/forge/src/main/java/net/minecraftforge/items/wrapper/SidedInvWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/items/wrapper/SidedInvWrapper.java rename to module/forge/src/main/java/net/minecraftforge/items/wrapper/SidedInvWrapper.java diff --git a/src/main/java/net/minecraftforge/oredict/DyeUtils.java b/module/forge/src/main/java/net/minecraftforge/oredict/DyeUtils.java similarity index 100% rename from src/main/java/net/minecraftforge/oredict/DyeUtils.java rename to module/forge/src/main/java/net/minecraftforge/oredict/DyeUtils.java diff --git a/src/main/java/net/minecraftforge/oredict/OreDictionary.java b/module/forge/src/main/java/net/minecraftforge/oredict/OreDictionary.java similarity index 100% rename from src/main/java/net/minecraftforge/oredict/OreDictionary.java rename to module/forge/src/main/java/net/minecraftforge/oredict/OreDictionary.java diff --git a/src/main/java/net/minecraftforge/oredict/OreIngredient.java b/module/forge/src/main/java/net/minecraftforge/oredict/OreIngredient.java similarity index 100% rename from src/main/java/net/minecraftforge/oredict/OreIngredient.java rename to module/forge/src/main/java/net/minecraftforge/oredict/OreIngredient.java diff --git a/src/main/java/net/minecraftforge/oredict/RecipeSorter.java b/module/forge/src/main/java/net/minecraftforge/oredict/RecipeSorter.java similarity index 100% rename from src/main/java/net/minecraftforge/oredict/RecipeSorter.java rename to module/forge/src/main/java/net/minecraftforge/oredict/RecipeSorter.java diff --git a/src/main/java/net/minecraftforge/oredict/ShapedOreRecipe.java b/module/forge/src/main/java/net/minecraftforge/oredict/ShapedOreRecipe.java similarity index 100% rename from src/main/java/net/minecraftforge/oredict/ShapedOreRecipe.java rename to module/forge/src/main/java/net/minecraftforge/oredict/ShapedOreRecipe.java diff --git a/src/main/java/net/minecraftforge/oredict/ShapelessOreRecipe.java b/module/forge/src/main/java/net/minecraftforge/oredict/ShapelessOreRecipe.java similarity index 100% rename from src/main/java/net/minecraftforge/oredict/ShapelessOreRecipe.java rename to module/forge/src/main/java/net/minecraftforge/oredict/ShapelessOreRecipe.java diff --git a/src/main/java/net/minecraftforge/registries/DataSerializerEntry.java b/module/forge/src/main/java/net/minecraftforge/registries/DataSerializerEntry.java similarity index 100% rename from src/main/java/net/minecraftforge/registries/DataSerializerEntry.java rename to module/forge/src/main/java/net/minecraftforge/registries/DataSerializerEntry.java diff --git a/src/main/java/net/minecraftforge/registries/ForgeRegistry.java b/module/forge/src/main/java/net/minecraftforge/registries/ForgeRegistry.java similarity index 100% rename from src/main/java/net/minecraftforge/registries/ForgeRegistry.java rename to module/forge/src/main/java/net/minecraftforge/registries/ForgeRegistry.java diff --git a/src/main/java/net/minecraftforge/registries/GameData.java b/module/forge/src/main/java/net/minecraftforge/registries/GameData.java similarity index 100% rename from src/main/java/net/minecraftforge/registries/GameData.java rename to module/forge/src/main/java/net/minecraftforge/registries/GameData.java diff --git a/src/main/java/net/minecraftforge/registries/IForgeRegistry.java b/module/forge/src/main/java/net/minecraftforge/registries/IForgeRegistry.java similarity index 100% rename from src/main/java/net/minecraftforge/registries/IForgeRegistry.java rename to module/forge/src/main/java/net/minecraftforge/registries/IForgeRegistry.java diff --git a/src/main/java/net/minecraftforge/registries/IForgeRegistryEntry.java b/module/forge/src/main/java/net/minecraftforge/registries/IForgeRegistryEntry.java similarity index 100% rename from src/main/java/net/minecraftforge/registries/IForgeRegistryEntry.java rename to module/forge/src/main/java/net/minecraftforge/registries/IForgeRegistryEntry.java diff --git a/src/main/java/net/minecraftforge/registries/IForgeRegistryInternal.java b/module/forge/src/main/java/net/minecraftforge/registries/IForgeRegistryInternal.java similarity index 100% rename from src/main/java/net/minecraftforge/registries/IForgeRegistryInternal.java rename to module/forge/src/main/java/net/minecraftforge/registries/IForgeRegistryInternal.java diff --git a/src/main/java/net/minecraftforge/registries/IForgeRegistryModifiable.java b/module/forge/src/main/java/net/minecraftforge/registries/IForgeRegistryModifiable.java similarity index 100% rename from src/main/java/net/minecraftforge/registries/IForgeRegistryModifiable.java rename to module/forge/src/main/java/net/minecraftforge/registries/IForgeRegistryModifiable.java diff --git a/src/main/java/net/minecraftforge/registries/ILockableRegistry.java b/module/forge/src/main/java/net/minecraftforge/registries/ILockableRegistry.java similarity index 100% rename from src/main/java/net/minecraftforge/registries/ILockableRegistry.java rename to module/forge/src/main/java/net/minecraftforge/registries/ILockableRegistry.java diff --git a/src/main/java/net/minecraftforge/registries/IRegistryDelegate.java b/module/forge/src/main/java/net/minecraftforge/registries/IRegistryDelegate.java similarity index 100% rename from src/main/java/net/minecraftforge/registries/IRegistryDelegate.java rename to module/forge/src/main/java/net/minecraftforge/registries/IRegistryDelegate.java diff --git a/src/main/java/net/minecraftforge/registries/NamespacedDefaultedWrapper.java b/module/forge/src/main/java/net/minecraftforge/registries/NamespacedDefaultedWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/registries/NamespacedDefaultedWrapper.java rename to module/forge/src/main/java/net/minecraftforge/registries/NamespacedDefaultedWrapper.java diff --git a/src/main/java/net/minecraftforge/registries/NamespacedWrapper.java b/module/forge/src/main/java/net/minecraftforge/registries/NamespacedWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/registries/NamespacedWrapper.java rename to module/forge/src/main/java/net/minecraftforge/registries/NamespacedWrapper.java diff --git a/src/main/java/net/minecraftforge/registries/ObjectHolderRef.java b/module/forge/src/main/java/net/minecraftforge/registries/ObjectHolderRef.java similarity index 100% rename from src/main/java/net/minecraftforge/registries/ObjectHolderRef.java rename to module/forge/src/main/java/net/minecraftforge/registries/ObjectHolderRef.java diff --git a/src/main/java/net/minecraftforge/registries/ObjectHolderRegistry.java b/module/forge/src/main/java/net/minecraftforge/registries/ObjectHolderRegistry.java similarity index 100% rename from src/main/java/net/minecraftforge/registries/ObjectHolderRegistry.java rename to module/forge/src/main/java/net/minecraftforge/registries/ObjectHolderRegistry.java diff --git a/src/main/java/net/minecraftforge/registries/RegistryBuilder.java b/module/forge/src/main/java/net/minecraftforge/registries/RegistryBuilder.java similarity index 100% rename from src/main/java/net/minecraftforge/registries/RegistryBuilder.java rename to module/forge/src/main/java/net/minecraftforge/registries/RegistryBuilder.java diff --git a/src/main/java/net/minecraftforge/registries/RegistryDelegate.java b/module/forge/src/main/java/net/minecraftforge/registries/RegistryDelegate.java similarity index 100% rename from src/main/java/net/minecraftforge/registries/RegistryDelegate.java rename to module/forge/src/main/java/net/minecraftforge/registries/RegistryDelegate.java diff --git a/src/main/java/net/minecraftforge/registries/RegistryManager.java b/module/forge/src/main/java/net/minecraftforge/registries/RegistryManager.java similarity index 100% rename from src/main/java/net/minecraftforge/registries/RegistryManager.java rename to module/forge/src/main/java/net/minecraftforge/registries/RegistryManager.java diff --git a/src/main/java/net/minecraftforge/server/ForgeTimeTracker.java b/module/forge/src/main/java/net/minecraftforge/server/ForgeTimeTracker.java similarity index 100% rename from src/main/java/net/minecraftforge/server/ForgeTimeTracker.java rename to module/forge/src/main/java/net/minecraftforge/server/ForgeTimeTracker.java diff --git a/src/main/java/net/minecraftforge/server/command/ChunkGenWorker.java b/module/forge/src/main/java/net/minecraftforge/server/command/ChunkGenWorker.java similarity index 100% rename from src/main/java/net/minecraftforge/server/command/ChunkGenWorker.java rename to module/forge/src/main/java/net/minecraftforge/server/command/ChunkGenWorker.java diff --git a/src/main/java/net/minecraftforge/server/command/CommandDimensions.java b/module/forge/src/main/java/net/minecraftforge/server/command/CommandDimensions.java similarity index 100% rename from src/main/java/net/minecraftforge/server/command/CommandDimensions.java rename to module/forge/src/main/java/net/minecraftforge/server/command/CommandDimensions.java diff --git a/src/main/java/net/minecraftforge/server/command/CommandEntity.java b/module/forge/src/main/java/net/minecraftforge/server/command/CommandEntity.java similarity index 100% rename from src/main/java/net/minecraftforge/server/command/CommandEntity.java rename to module/forge/src/main/java/net/minecraftforge/server/command/CommandEntity.java diff --git a/src/main/java/net/minecraftforge/server/command/CommandGenerate.java b/module/forge/src/main/java/net/minecraftforge/server/command/CommandGenerate.java similarity index 100% rename from src/main/java/net/minecraftforge/server/command/CommandGenerate.java rename to module/forge/src/main/java/net/minecraftforge/server/command/CommandGenerate.java diff --git a/src/main/java/net/minecraftforge/server/command/CommandSetDimension.java b/module/forge/src/main/java/net/minecraftforge/server/command/CommandSetDimension.java similarity index 100% rename from src/main/java/net/minecraftforge/server/command/CommandSetDimension.java rename to module/forge/src/main/java/net/minecraftforge/server/command/CommandSetDimension.java diff --git a/src/main/java/net/minecraftforge/server/command/CommandTps.java b/module/forge/src/main/java/net/minecraftforge/server/command/CommandTps.java similarity index 100% rename from src/main/java/net/minecraftforge/server/command/CommandTps.java rename to module/forge/src/main/java/net/minecraftforge/server/command/CommandTps.java diff --git a/src/main/java/net/minecraftforge/server/command/CommandTrack.java b/module/forge/src/main/java/net/minecraftforge/server/command/CommandTrack.java similarity index 100% rename from src/main/java/net/minecraftforge/server/command/CommandTrack.java rename to module/forge/src/main/java/net/minecraftforge/server/command/CommandTrack.java diff --git a/src/main/java/net/minecraftforge/server/command/CommandTreeBase.java b/module/forge/src/main/java/net/minecraftforge/server/command/CommandTreeBase.java similarity index 100% rename from src/main/java/net/minecraftforge/server/command/CommandTreeBase.java rename to module/forge/src/main/java/net/minecraftforge/server/command/CommandTreeBase.java diff --git a/src/main/java/net/minecraftforge/server/command/CommandTreeHelp.java b/module/forge/src/main/java/net/minecraftforge/server/command/CommandTreeHelp.java similarity index 100% rename from src/main/java/net/minecraftforge/server/command/CommandTreeHelp.java rename to module/forge/src/main/java/net/minecraftforge/server/command/CommandTreeHelp.java diff --git a/src/main/java/net/minecraftforge/server/command/ForgeCommand.java b/module/forge/src/main/java/net/minecraftforge/server/command/ForgeCommand.java similarity index 100% rename from src/main/java/net/minecraftforge/server/command/ForgeCommand.java rename to module/forge/src/main/java/net/minecraftforge/server/command/ForgeCommand.java diff --git a/src/main/java/net/minecraftforge/server/command/TextComponentHelper.java b/module/forge/src/main/java/net/minecraftforge/server/command/TextComponentHelper.java similarity index 100% rename from src/main/java/net/minecraftforge/server/command/TextComponentHelper.java rename to module/forge/src/main/java/net/minecraftforge/server/command/TextComponentHelper.java diff --git a/src/main/java/net/minecraftforge/server/command/package-info.java b/module/forge/src/main/java/net/minecraftforge/server/command/package-info.java similarity index 100% rename from src/main/java/net/minecraftforge/server/command/package-info.java rename to module/forge/src/main/java/net/minecraftforge/server/command/package-info.java diff --git a/src/main/java/net/minecraftforge/server/console/ConsoleCommandCompleter.java b/module/forge/src/main/java/net/minecraftforge/server/console/ConsoleCommandCompleter.java similarity index 100% rename from src/main/java/net/minecraftforge/server/console/ConsoleCommandCompleter.java rename to module/forge/src/main/java/net/minecraftforge/server/console/ConsoleCommandCompleter.java diff --git a/src/main/java/net/minecraftforge/server/console/TerminalHandler.java b/module/forge/src/main/java/net/minecraftforge/server/console/TerminalHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/server/console/TerminalHandler.java rename to module/forge/src/main/java/net/minecraftforge/server/console/TerminalHandler.java diff --git a/src/main/java/net/minecraftforge/server/permission/DefaultPermissionHandler.java b/module/forge/src/main/java/net/minecraftforge/server/permission/DefaultPermissionHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/server/permission/DefaultPermissionHandler.java rename to module/forge/src/main/java/net/minecraftforge/server/permission/DefaultPermissionHandler.java diff --git a/src/main/java/net/minecraftforge/server/permission/DefaultPermissionLevel.java b/module/forge/src/main/java/net/minecraftforge/server/permission/DefaultPermissionLevel.java similarity index 100% rename from src/main/java/net/minecraftforge/server/permission/DefaultPermissionLevel.java rename to module/forge/src/main/java/net/minecraftforge/server/permission/DefaultPermissionLevel.java diff --git a/src/main/java/net/minecraftforge/server/permission/IPermissionHandler.java b/module/forge/src/main/java/net/minecraftforge/server/permission/IPermissionHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/server/permission/IPermissionHandler.java rename to module/forge/src/main/java/net/minecraftforge/server/permission/IPermissionHandler.java diff --git a/src/main/java/net/minecraftforge/server/permission/PermissionAPI.java b/module/forge/src/main/java/net/minecraftforge/server/permission/PermissionAPI.java similarity index 100% rename from src/main/java/net/minecraftforge/server/permission/PermissionAPI.java rename to module/forge/src/main/java/net/minecraftforge/server/permission/PermissionAPI.java diff --git a/src/main/java/net/minecraftforge/server/permission/context/AreaContext.java b/module/forge/src/main/java/net/minecraftforge/server/permission/context/AreaContext.java similarity index 100% rename from src/main/java/net/minecraftforge/server/permission/context/AreaContext.java rename to module/forge/src/main/java/net/minecraftforge/server/permission/context/AreaContext.java diff --git a/src/main/java/net/minecraftforge/server/permission/context/BlockPosContext.java b/module/forge/src/main/java/net/minecraftforge/server/permission/context/BlockPosContext.java similarity index 100% rename from src/main/java/net/minecraftforge/server/permission/context/BlockPosContext.java rename to module/forge/src/main/java/net/minecraftforge/server/permission/context/BlockPosContext.java diff --git a/src/main/java/net/minecraftforge/server/permission/context/Context.java b/module/forge/src/main/java/net/minecraftforge/server/permission/context/Context.java similarity index 100% rename from src/main/java/net/minecraftforge/server/permission/context/Context.java rename to module/forge/src/main/java/net/minecraftforge/server/permission/context/Context.java diff --git a/src/main/java/net/minecraftforge/server/permission/context/ContextKey.java b/module/forge/src/main/java/net/minecraftforge/server/permission/context/ContextKey.java similarity index 100% rename from src/main/java/net/minecraftforge/server/permission/context/ContextKey.java rename to module/forge/src/main/java/net/minecraftforge/server/permission/context/ContextKey.java diff --git a/src/main/java/net/minecraftforge/server/permission/context/ContextKeys.java b/module/forge/src/main/java/net/minecraftforge/server/permission/context/ContextKeys.java similarity index 100% rename from src/main/java/net/minecraftforge/server/permission/context/ContextKeys.java rename to module/forge/src/main/java/net/minecraftforge/server/permission/context/ContextKeys.java diff --git a/src/main/java/net/minecraftforge/server/permission/context/IContext.java b/module/forge/src/main/java/net/minecraftforge/server/permission/context/IContext.java similarity index 100% rename from src/main/java/net/minecraftforge/server/permission/context/IContext.java rename to module/forge/src/main/java/net/minecraftforge/server/permission/context/IContext.java diff --git a/src/main/java/net/minecraftforge/server/permission/context/PlayerContext.java b/module/forge/src/main/java/net/minecraftforge/server/permission/context/PlayerContext.java similarity index 100% rename from src/main/java/net/minecraftforge/server/permission/context/PlayerContext.java rename to module/forge/src/main/java/net/minecraftforge/server/permission/context/PlayerContext.java diff --git a/src/main/java/net/minecraftforge/server/permission/context/TargetContext.java b/module/forge/src/main/java/net/minecraftforge/server/permission/context/TargetContext.java similarity index 100% rename from src/main/java/net/minecraftforge/server/permission/context/TargetContext.java rename to module/forge/src/main/java/net/minecraftforge/server/permission/context/TargetContext.java diff --git a/src/main/java/net/minecraftforge/server/permission/context/WorldContext.java b/module/forge/src/main/java/net/minecraftforge/server/permission/context/WorldContext.java similarity index 100% rename from src/main/java/net/minecraftforge/server/permission/context/WorldContext.java rename to module/forge/src/main/java/net/minecraftforge/server/permission/context/WorldContext.java diff --git a/src/main/java/net/minecraftforge/server/permission/context/package-info.java b/module/forge/src/main/java/net/minecraftforge/server/permission/context/package-info.java similarity index 100% rename from src/main/java/net/minecraftforge/server/permission/context/package-info.java rename to module/forge/src/main/java/net/minecraftforge/server/permission/context/package-info.java diff --git a/src/main/java/net/minecraftforge/server/permission/package-info.java b/module/forge/src/main/java/net/minecraftforge/server/permission/package-info.java similarity index 100% rename from src/main/java/net/minecraftforge/server/permission/package-info.java rename to module/forge/src/main/java/net/minecraftforge/server/permission/package-info.java diff --git a/src/main/java/net/minecraftforge/server/terminalconsole/HighlightErrorConverter.java b/module/forge/src/main/java/net/minecraftforge/server/terminalconsole/HighlightErrorConverter.java similarity index 100% rename from src/main/java/net/minecraftforge/server/terminalconsole/HighlightErrorConverter.java rename to module/forge/src/main/java/net/minecraftforge/server/terminalconsole/HighlightErrorConverter.java diff --git a/src/main/java/net/minecraftforge/server/terminalconsole/MinecraftFormattingConverter.java b/module/forge/src/main/java/net/minecraftforge/server/terminalconsole/MinecraftFormattingConverter.java similarity index 100% rename from src/main/java/net/minecraftforge/server/terminalconsole/MinecraftFormattingConverter.java rename to module/forge/src/main/java/net/minecraftforge/server/terminalconsole/MinecraftFormattingConverter.java diff --git a/src/main/java/net/minecraftforge/server/terminalconsole/TerminalConsoleAppender.java b/module/forge/src/main/java/net/minecraftforge/server/terminalconsole/TerminalConsoleAppender.java similarity index 100% rename from src/main/java/net/minecraftforge/server/terminalconsole/TerminalConsoleAppender.java rename to module/forge/src/main/java/net/minecraftforge/server/terminalconsole/TerminalConsoleAppender.java diff --git a/src/main/java/net/minecraftforge/server/terminalconsole/package-info.java b/module/forge/src/main/java/net/minecraftforge/server/terminalconsole/package-info.java similarity index 100% rename from src/main/java/net/minecraftforge/server/terminalconsole/package-info.java rename to module/forge/src/main/java/net/minecraftforge/server/terminalconsole/package-info.java diff --git a/src/main/java/net/minecraftforge/server/terminalconsole/util/LoggerNamePatternSelector.java b/module/forge/src/main/java/net/minecraftforge/server/terminalconsole/util/LoggerNamePatternSelector.java similarity index 100% rename from src/main/java/net/minecraftforge/server/terminalconsole/util/LoggerNamePatternSelector.java rename to module/forge/src/main/java/net/minecraftforge/server/terminalconsole/util/LoggerNamePatternSelector.java diff --git a/src/main/java/net/minecraftforge/server/terminalconsole/util/package-info.java b/module/forge/src/main/java/net/minecraftforge/server/terminalconsole/util/package-info.java similarity index 100% rename from src/main/java/net/minecraftforge/server/terminalconsole/util/package-info.java rename to module/forge/src/main/java/net/minecraftforge/server/terminalconsole/util/package-info.java diff --git a/src/main/java/net/minecraftforge/server/timings/ForgeTimings.java b/module/forge/src/main/java/net/minecraftforge/server/timings/ForgeTimings.java similarity index 100% rename from src/main/java/net/minecraftforge/server/timings/ForgeTimings.java rename to module/forge/src/main/java/net/minecraftforge/server/timings/ForgeTimings.java diff --git a/src/main/java/net/minecraftforge/server/timings/TimeTracker.java b/module/forge/src/main/java/net/minecraftforge/server/timings/TimeTracker.java similarity index 100% rename from src/main/java/net/minecraftforge/server/timings/TimeTracker.java rename to module/forge/src/main/java/net/minecraftforge/server/timings/TimeTracker.java diff --git a/src/main/java/paulscode/sound/codecs/CodecIBXM.java b/module/forge/src/main/java/paulscode/sound/codecs/CodecIBXM.java similarity index 100% rename from src/main/java/paulscode/sound/codecs/CodecIBXM.java rename to module/forge/src/main/java/paulscode/sound/codecs/CodecIBXM.java diff --git a/src/main/resources/META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat b/module/forge/src/main/resources/META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat similarity index 100% rename from src/main/resources/META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat rename to module/forge/src/main/resources/META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat diff --git a/src/main/resources/assets/fml/textures/gui/forge.png b/module/forge/src/main/resources/assets/fml/textures/gui/forge.png similarity index 100% rename from src/main/resources/assets/fml/textures/gui/forge.png rename to module/forge/src/main/resources/assets/fml/textures/gui/forge.png diff --git a/src/main/resources/assets/fml/textures/gui/icons.png b/module/forge/src/main/resources/assets/fml/textures/gui/icons.png similarity index 100% rename from src/main/resources/assets/fml/textures/gui/icons.png rename to module/forge/src/main/resources/assets/fml/textures/gui/icons.png diff --git a/src/main/resources/assets/forge/blockstates/dynbucket.json b/module/forge/src/main/resources/assets/forge/blockstates/dynbucket.json similarity index 100% rename from src/main/resources/assets/forge/blockstates/dynbucket.json rename to module/forge/src/main/resources/assets/forge/blockstates/dynbucket.json diff --git a/src/main/resources/assets/forge/lang/README.txt b/module/forge/src/main/resources/assets/forge/lang/README.txt similarity index 100% rename from src/main/resources/assets/forge/lang/README.txt rename to module/forge/src/main/resources/assets/forge/lang/README.txt diff --git a/src/main/resources/assets/forge/lang/en_pt.lang b/module/forge/src/main/resources/assets/forge/lang/en_pt.lang similarity index 100% rename from src/main/resources/assets/forge/lang/en_pt.lang rename to module/forge/src/main/resources/assets/forge/lang/en_pt.lang diff --git a/src/main/resources/assets/forge/lang/en_us.lang b/module/forge/src/main/resources/assets/forge/lang/en_us.lang similarity index 100% rename from src/main/resources/assets/forge/lang/en_us.lang rename to module/forge/src/main/resources/assets/forge/lang/en_us.lang diff --git a/src/main/resources/assets/forge/lang/es_es.lang b/module/forge/src/main/resources/assets/forge/lang/es_es.lang similarity index 100% rename from src/main/resources/assets/forge/lang/es_es.lang rename to module/forge/src/main/resources/assets/forge/lang/es_es.lang diff --git a/src/main/resources/assets/forge/lang/fr_fr.lang b/module/forge/src/main/resources/assets/forge/lang/fr_fr.lang similarity index 100% rename from src/main/resources/assets/forge/lang/fr_fr.lang rename to module/forge/src/main/resources/assets/forge/lang/fr_fr.lang diff --git a/src/main/resources/assets/forge/lang/ja_jp.lang b/module/forge/src/main/resources/assets/forge/lang/ja_jp.lang similarity index 100% rename from src/main/resources/assets/forge/lang/ja_jp.lang rename to module/forge/src/main/resources/assets/forge/lang/ja_jp.lang diff --git a/src/main/resources/assets/forge/lang/ko_kr.lang b/module/forge/src/main/resources/assets/forge/lang/ko_kr.lang similarity index 100% rename from src/main/resources/assets/forge/lang/ko_kr.lang rename to module/forge/src/main/resources/assets/forge/lang/ko_kr.lang diff --git a/src/main/resources/assets/forge/lang/ru_ru.lang b/module/forge/src/main/resources/assets/forge/lang/ru_ru.lang similarity index 100% rename from src/main/resources/assets/forge/lang/ru_ru.lang rename to module/forge/src/main/resources/assets/forge/lang/ru_ru.lang diff --git a/src/main/resources/assets/forge/lang/zh_cn.lang b/module/forge/src/main/resources/assets/forge/lang/zh_cn.lang similarity index 100% rename from src/main/resources/assets/forge/lang/zh_cn.lang rename to module/forge/src/main/resources/assets/forge/lang/zh_cn.lang diff --git a/src/main/resources/assets/forge/lang/zh_tw.lang b/module/forge/src/main/resources/assets/forge/lang/zh_tw.lang similarity index 100% rename from src/main/resources/assets/forge/lang/zh_tw.lang rename to module/forge/src/main/resources/assets/forge/lang/zh_tw.lang diff --git a/src/main/resources/assets/forge/models/item/bucket.json b/module/forge/src/main/resources/assets/forge/models/item/bucket.json similarity index 100% rename from src/main/resources/assets/forge/models/item/bucket.json rename to module/forge/src/main/resources/assets/forge/models/item/bucket.json diff --git a/src/main/resources/assets/forge/models/item/bucket_milk.json b/module/forge/src/main/resources/assets/forge/models/item/bucket_milk.json similarity index 100% rename from src/main/resources/assets/forge/models/item/bucket_milk.json rename to module/forge/src/main/resources/assets/forge/models/item/bucket_milk.json diff --git a/src/main/resources/assets/forge/textures/gui/version_check_icons.png b/module/forge/src/main/resources/assets/forge/textures/gui/version_check_icons.png similarity index 100% rename from src/main/resources/assets/forge/textures/gui/version_check_icons.png rename to module/forge/src/main/resources/assets/forge/textures/gui/version_check_icons.png diff --git a/src/main/resources/assets/forge/textures/items/bucket_fluid.png b/module/forge/src/main/resources/assets/forge/textures/items/bucket_fluid.png similarity index 100% rename from src/main/resources/assets/forge/textures/items/bucket_fluid.png rename to module/forge/src/main/resources/assets/forge/textures/items/bucket_fluid.png diff --git a/src/main/resources/assets/forge/textures/items/vanilla_bucket_cover_mask.png b/module/forge/src/main/resources/assets/forge/textures/items/vanilla_bucket_cover_mask.png similarity index 100% rename from src/main/resources/assets/forge/textures/items/vanilla_bucket_cover_mask.png rename to module/forge/src/main/resources/assets/forge/textures/items/vanilla_bucket_cover_mask.png diff --git a/src/main/resources/forge.exc b/module/forge/src/main/resources/forge.exc similarity index 100% rename from src/main/resources/forge.exc rename to module/forge/src/main/resources/forge.exc diff --git a/src/main/resources/forge.srg b/module/forge/src/main/resources/forge.srg similarity index 100% rename from src/main/resources/forge.srg rename to module/forge/src/main/resources/forge.srg diff --git a/src/main/resources/forge_at.cfg b/module/forge/src/main/resources/forge_at.cfg similarity index 100% rename from src/main/resources/forge_at.cfg rename to module/forge/src/main/resources/forge_at.cfg diff --git a/src/main/resources/forge_logo.png b/module/forge/src/main/resources/forge_logo.png similarity index 100% rename from src/main/resources/forge_logo.png rename to module/forge/src/main/resources/forge_logo.png diff --git a/src/main/resources/log4j2.xml b/module/forge/src/main/resources/log4j2.xml similarity index 100% rename from src/main/resources/log4j2.xml rename to module/forge/src/main/resources/log4j2.xml diff --git a/src/main/resources/log4j2_server.xml b/module/forge/src/main/resources/log4j2_server.xml similarity index 100% rename from src/main/resources/log4j2_server.xml rename to module/forge/src/main/resources/log4j2_server.xml diff --git a/src/main/resources/logging.properties b/module/forge/src/main/resources/logging.properties similarity index 100% rename from src/main/resources/logging.properties rename to module/forge/src/main/resources/logging.properties diff --git a/src/main/resources/mcplogo.png b/module/forge/src/main/resources/mcplogo.png similarity index 100% rename from src/main/resources/mcplogo.png rename to module/forge/src/main/resources/mcplogo.png diff --git a/src/main/resources/mcpmod.info b/module/forge/src/main/resources/mcpmod.info similarity index 100% rename from src/main/resources/mcpmod.info rename to module/forge/src/main/resources/mcpmod.info diff --git a/src/main/resources/pack.mcmeta b/module/forge/src/main/resources/pack.mcmeta similarity index 100% rename from src/main/resources/pack.mcmeta rename to module/forge/src/main/resources/pack.mcmeta diff --git a/src/main/resources/url.png b/module/forge/src/main/resources/url.png similarity index 100% rename from src/main/resources/url.png rename to module/forge/src/main/resources/url.png diff --git a/src/test/java/net/minecraftforge/debug/PotionEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/PotionEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/PotionEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/PotionEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/block/BasePlaceEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/block/BasePlaceEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/block/BasePlaceEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/block/BasePlaceEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/block/FarmlandTrampleEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/block/FarmlandTrampleEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/block/FarmlandTrampleEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/block/FarmlandTrampleEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/block/FarmlandWaterTest.java b/module/forge/src/test/java/net/minecraftforge/debug/block/FarmlandWaterTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/block/FarmlandWaterTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/block/FarmlandWaterTest.java diff --git a/src/test/java/net/minecraftforge/debug/block/MaterialFogColorTest.java b/module/forge/src/test/java/net/minecraftforge/debug/block/MaterialFogColorTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/block/MaterialFogColorTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/block/MaterialFogColorTest.java diff --git a/src/test/java/net/minecraftforge/debug/block/NeighborNotifyEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/block/NeighborNotifyEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/block/NeighborNotifyEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/block/NeighborNotifyEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/block/ParticleEffectsTest.java b/module/forge/src/test/java/net/minecraftforge/debug/block/ParticleEffectsTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/block/ParticleEffectsTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/block/ParticleEffectsTest.java diff --git a/src/test/java/net/minecraftforge/debug/block/PathNodeTypeTest.java b/module/forge/src/test/java/net/minecraftforge/debug/block/PathNodeTypeTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/block/PathNodeTypeTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/block/PathNodeTypeTest.java diff --git a/src/test/java/net/minecraftforge/debug/block/PlaceEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/block/PlaceEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/block/PlaceEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/block/PlaceEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/block/PortalSpawnEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/block/PortalSpawnEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/block/PortalSpawnEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/block/PortalSpawnEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/block/SlipperinessTest.java b/module/forge/src/test/java/net/minecraftforge/debug/block/SlipperinessTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/block/SlipperinessTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/block/SlipperinessTest.java diff --git a/src/test/java/net/minecraftforge/debug/block/StickyBlockTest.java b/module/forge/src/test/java/net/minecraftforge/debug/block/StickyBlockTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/block/StickyBlockTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/block/StickyBlockTest.java diff --git a/src/test/java/net/minecraftforge/debug/block/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/block/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/block/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/block/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/chat/ClientChatEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/chat/ClientChatEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/chat/ClientChatEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/chat/ClientChatEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/chat/ClientCommandTest.java b/module/forge/src/test/java/net/minecraftforge/debug/chat/ClientCommandTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/chat/ClientCommandTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/chat/ClientCommandTest.java diff --git a/src/test/java/net/minecraftforge/debug/chat/CommandTreeBaseTest.java b/module/forge/src/test/java/net/minecraftforge/debug/chat/CommandTreeBaseTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/chat/CommandTreeBaseTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/chat/CommandTreeBaseTest.java diff --git a/src/test/java/net/minecraftforge/debug/chat/EntitySelectorFactoryTest.java b/module/forge/src/test/java/net/minecraftforge/debug/chat/EntitySelectorFactoryTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/chat/EntitySelectorFactoryTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/chat/EntitySelectorFactoryTest.java diff --git a/src/test/java/net/minecraftforge/debug/chat/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/chat/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/chat/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/chat/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/client/CustomTextureAtlasSpriteTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/CustomTextureAtlasSpriteTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/CustomTextureAtlasSpriteTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/CustomTextureAtlasSpriteTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/FOVModifierEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/FOVModifierEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/FOVModifierEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/FOVModifierEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/SearchableCreativeTabTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/SearchableCreativeTabTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/SearchableCreativeTabTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/SearchableCreativeTabTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/gui/ContainerDrawForegroundEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/gui/ContainerDrawForegroundEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/gui/ContainerDrawForegroundEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/gui/ContainerDrawForegroundEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/gui/TooltipColorEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/gui/TooltipColorEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/gui/TooltipColorEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/gui/TooltipColorEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/model/AnimatedModelTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/model/AnimatedModelTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/model/AnimatedModelTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/model/AnimatedModelTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/model/BlockstateRetextureTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/model/BlockstateRetextureTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/model/BlockstateRetextureTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/model/BlockstateRetextureTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/model/ForgeBlockStatesLoaderTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/model/ForgeBlockStatesLoaderTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/model/ForgeBlockStatesLoaderTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/model/ForgeBlockStatesLoaderTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/model/ItemLayerModelTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/model/ItemLayerModelTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/model/ItemLayerModelTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/model/ItemLayerModelTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/model/ItemModelConflictTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/model/ItemModelConflictTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/model/ItemModelConflictTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/model/ItemModelConflictTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/model/ItemModelGenerationTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/model/ItemModelGenerationTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/model/ItemModelGenerationTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/model/ItemModelGenerationTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/model/ModelBakeEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/model/ModelBakeEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/model/ModelBakeEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/model/ModelBakeEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/model/ModelFluidTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/model/ModelFluidTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/model/ModelFluidTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/model/ModelFluidTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/model/ModelLoaderRegistryTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/model/ModelLoaderRegistryTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/model/ModelLoaderRegistryTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/model/ModelLoaderRegistryTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/model/MultiLayerModelTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/model/MultiLayerModelTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/model/MultiLayerModelTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/model/MultiLayerModelTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/model/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/client/model/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/model/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/model/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/client/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/client/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/client/rendering/FastTESRTransparentTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/rendering/FastTESRTransparentTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/rendering/FastTESRTransparentTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/rendering/FastTESRTransparentTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/rendering/ItemTESRTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/rendering/ItemTESRTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/rendering/ItemTESRTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/rendering/ItemTESRTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/rendering/VertexBufferNormalTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/rendering/VertexBufferNormalTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/rendering/VertexBufferNormalTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/rendering/VertexBufferNormalTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/rendering/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/client/rendering/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/rendering/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/rendering/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/entity/BlockEntityUpdateTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/BlockEntityUpdateTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/BlockEntityUpdateTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/BlockEntityUpdateTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/EntityTravelToDimensionEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/EntityTravelToDimensionEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/EntityTravelToDimensionEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/EntityTravelToDimensionEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/GetCollisionBoxesEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/GetCollisionBoxesEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/GetCollisionBoxesEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/GetCollisionBoxesEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/ProjectileImpactEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/ProjectileImpactEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/ProjectileImpactEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/ProjectileImpactEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/living/AnimalTameEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/living/AnimalTameEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/living/AnimalTameEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/living/AnimalTameEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/living/AttackEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/living/AttackEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/living/AttackEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/living/AttackEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/living/BabyEntitySpawnEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/living/BabyEntitySpawnEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/living/BabyEntitySpawnEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/living/BabyEntitySpawnEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/living/CheckSpawnEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/living/CheckSpawnEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/living/CheckSpawnEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/living/CheckSpawnEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/living/CustomSpawnPlacementTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/living/CustomSpawnPlacementTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/living/CustomSpawnPlacementTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/living/CustomSpawnPlacementTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/living/DamageEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/living/DamageEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/living/DamageEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/living/DamageEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/living/EquipmentChangeEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/living/EquipmentChangeEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/living/EquipmentChangeEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/living/EquipmentChangeEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/living/KnockBackEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/living/KnockBackEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/living/KnockBackEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/living/KnockBackEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/living/MobGriefingEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/living/MobGriefingEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/living/MobGriefingEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/living/MobGriefingEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/living/SpecialSpawnTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/living/SpecialSpawnTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/living/SpecialSpawnTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/living/SpecialSpawnTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/living/VillagerProfessionTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/living/VillagerProfessionTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/living/VillagerProfessionTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/living/VillagerProfessionTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/living/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/living/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/living/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/living/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/entity/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/entity/player/CriticalHitEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/player/CriticalHitEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/player/CriticalHitEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/player/CriticalHitEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/player/DamageReworkTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/player/DamageReworkTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/player/DamageReworkTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/player/DamageReworkTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/player/ItemPickupEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/player/ItemPickupEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/player/ItemPickupEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/player/ItemPickupEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/player/PlayerInteractEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/player/PlayerInteractEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/player/PlayerInteractEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/player/PlayerInteractEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/player/PlayerSetSpawnTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/player/PlayerSetSpawnTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/player/PlayerSetSpawnTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/player/PlayerSetSpawnTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/player/ReachDistanceAttributeTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/player/ReachDistanceAttributeTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/player/ReachDistanceAttributeTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/player/ReachDistanceAttributeTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/player/SwimSpeedAttributeTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/player/SwimSpeedAttributeTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/player/SwimSpeedAttributeTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/player/SwimSpeedAttributeTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/player/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/player/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/player/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/player/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/fluid/ColoredFluidTest.java b/module/forge/src/test/java/net/minecraftforge/debug/fluid/ColoredFluidTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/fluid/ColoredFluidTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/fluid/ColoredFluidTest.java diff --git a/src/test/java/net/minecraftforge/debug/fluid/CreateFluidSourceEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/fluid/CreateFluidSourceEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/fluid/CreateFluidSourceEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/fluid/CreateFluidSourceEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/fluid/DynBucketTest.java b/module/forge/src/test/java/net/minecraftforge/debug/fluid/DynBucketTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/fluid/DynBucketTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/fluid/DynBucketTest.java diff --git a/src/test/java/net/minecraftforge/debug/fluid/FluidPlaceBlockEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/fluid/FluidPlaceBlockEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/fluid/FluidPlaceBlockEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/fluid/FluidPlaceBlockEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/fluid/FluidPlacementTest.java b/module/forge/src/test/java/net/minecraftforge/debug/fluid/FluidPlacementTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/fluid/FluidPlacementTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/fluid/FluidPlacementTest.java diff --git a/src/test/java/net/minecraftforge/debug/fluid/ItemFluidHandlerTest.java b/module/forge/src/test/java/net/minecraftforge/debug/fluid/ItemFluidHandlerTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/fluid/ItemFluidHandlerTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/fluid/ItemFluidHandlerTest.java diff --git a/src/test/java/net/minecraftforge/debug/fluid/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/fluid/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/fluid/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/fluid/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/AnytimeSleepingTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/AnytimeSleepingTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/AnytimeSleepingTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/AnytimeSleepingTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/BrewingRecipeRegistryTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/BrewingRecipeRegistryTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/BrewingRecipeRegistryTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/BrewingRecipeRegistryTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/ConstantLoadingTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/ConstantLoadingTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/ConstantLoadingTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/ConstantLoadingTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/CraftingSystemTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/CraftingSystemTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/CraftingSystemTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/CraftingSystemTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/DifficultyChangeEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/DifficultyChangeEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/DifficultyChangeEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/DifficultyChangeEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/DynamicBannerTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/DynamicBannerTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/DynamicBannerTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/DynamicBannerTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/EnchantmentLevelSetEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/EnchantmentLevelSetEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/EnchantmentLevelSetEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/EnchantmentLevelSetEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/FurnaceFuelBurnTimeEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/FurnaceFuelBurnTimeEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/FurnaceFuelBurnTimeEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/FurnaceFuelBurnTimeEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/GiveItemToPlayerTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/GiveItemToPlayerTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/GiveItemToPlayerTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/GiveItemToPlayerTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/InputUpdateEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/InputUpdateEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/InputUpdateEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/InputUpdateEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/NoBedSleepingTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/NoBedSleepingTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/NoBedSleepingTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/NoBedSleepingTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/PotionRegistryTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/PotionRegistryTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/PotionRegistryTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/PotionRegistryTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/RecipeMatchingTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/RecipeMatchingTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/RecipeMatchingTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/RecipeMatchingTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/advancement/AdvancementCriterionTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/advancement/AdvancementCriterionTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/advancement/AdvancementCriterionTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/advancement/AdvancementCriterionTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/advancement/AdvancementEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/advancement/AdvancementEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/advancement/AdvancementEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/advancement/AdvancementEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/advancement/AdvancementsPaginationTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/advancement/AdvancementsPaginationTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/advancement/AdvancementsPaginationTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/advancement/AdvancementsPaginationTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/advancement/OredictTriggerTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/advancement/OredictTriggerTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/advancement/OredictTriggerTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/advancement/OredictTriggerTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/advancement/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/advancement/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/advancement/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/advancement/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/loot/LootContextTweaksTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/loot/LootContextTweaksTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/loot/LootContextTweaksTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/loot/LootContextTweaksTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/loot/LootTableLoadEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/loot/LootTableLoadEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/loot/LootTableLoadEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/loot/LootTableLoadEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/loot/LootTableTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/loot/LootTableTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/loot/LootTableTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/loot/LootTableTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/loot/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/loot/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/loot/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/loot/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/item/BonemealEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/item/BonemealEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/item/BonemealEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/item/BonemealEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/item/CanApplyAtEnchantingTableTest.java b/module/forge/src/test/java/net/minecraftforge/debug/item/CanApplyAtEnchantingTableTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/item/CanApplyAtEnchantingTableTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/item/CanApplyAtEnchantingTableTest.java diff --git a/src/test/java/net/minecraftforge/debug/item/CanDestroyBlocksInCreativeTest.java b/module/forge/src/test/java/net/minecraftforge/debug/item/CanDestroyBlocksInCreativeTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/item/CanDestroyBlocksInCreativeTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/item/CanDestroyBlocksInCreativeTest.java diff --git a/src/test/java/net/minecraftforge/debug/item/ContinuousUseItemTest.java b/module/forge/src/test/java/net/minecraftforge/debug/item/ContinuousUseItemTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/item/ContinuousUseItemTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/item/ContinuousUseItemTest.java diff --git a/src/test/java/net/minecraftforge/debug/item/CustomRarityTest.java b/module/forge/src/test/java/net/minecraftforge/debug/item/CustomRarityTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/item/CustomRarityTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/item/CustomRarityTest.java diff --git a/src/test/java/net/minecraftforge/debug/item/HorseArmorTest.java b/module/forge/src/test/java/net/minecraftforge/debug/item/HorseArmorTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/item/HorseArmorTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/item/HorseArmorTest.java diff --git a/src/test/java/net/minecraftforge/debug/item/IsBookEnchantableTest.java b/module/forge/src/test/java/net/minecraftforge/debug/item/IsBookEnchantableTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/item/IsBookEnchantableTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/item/IsBookEnchantableTest.java diff --git a/src/test/java/net/minecraftforge/debug/item/ItemFishedEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/item/ItemFishedEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/item/ItemFishedEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/item/ItemFishedEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/item/MapDataTest.java b/module/forge/src/test/java/net/minecraftforge/debug/item/MapDataTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/item/MapDataTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/item/MapDataTest.java diff --git a/src/test/java/net/minecraftforge/debug/item/MendingRepairTest.java b/module/forge/src/test/java/net/minecraftforge/debug/item/MendingRepairTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/item/MendingRepairTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/item/MendingRepairTest.java diff --git a/src/test/java/net/minecraftforge/debug/item/NBTShareTagTest.java b/module/forge/src/test/java/net/minecraftforge/debug/item/NBTShareTagTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/item/NBTShareTagTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/item/NBTShareTagTest.java diff --git a/src/test/java/net/minecraftforge/debug/item/OnItemUseFirstTest.java b/module/forge/src/test/java/net/minecraftforge/debug/item/OnItemUseFirstTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/item/OnItemUseFirstTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/item/OnItemUseFirstTest.java diff --git a/src/test/java/net/minecraftforge/debug/item/PotionCurabilityTest.java b/module/forge/src/test/java/net/minecraftforge/debug/item/PotionCurabilityTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/item/PotionCurabilityTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/item/PotionCurabilityTest.java diff --git a/src/test/java/net/minecraftforge/debug/item/PotionShouldRenderTest.java b/module/forge/src/test/java/net/minecraftforge/debug/item/PotionShouldRenderTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/item/PotionShouldRenderTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/item/PotionShouldRenderTest.java diff --git a/src/test/java/net/minecraftforge/debug/item/ShieldTest.java b/module/forge/src/test/java/net/minecraftforge/debug/item/ShieldTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/item/ShieldTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/item/ShieldTest.java diff --git a/src/test/java/net/minecraftforge/debug/item/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/item/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/item/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/item/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/misc/EnumPlantTypeTest.java b/module/forge/src/test/java/net/minecraftforge/debug/misc/EnumPlantTypeTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/misc/EnumPlantTypeTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/misc/EnumPlantTypeTest.java diff --git a/src/test/java/net/minecraftforge/debug/misc/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/misc/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/misc/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/misc/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/mod/CapabilityTest.java b/module/forge/src/test/java/net/minecraftforge/debug/mod/CapabilityTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/mod/CapabilityTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/mod/CapabilityTest.java diff --git a/src/test/java/net/minecraftforge/debug/mod/ClientLoadingExceptionTest.java b/module/forge/src/test/java/net/minecraftforge/debug/mod/ClientLoadingExceptionTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/mod/ClientLoadingExceptionTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/mod/ClientLoadingExceptionTest.java diff --git a/src/test/java/net/minecraftforge/debug/mod/ConfigAnnotationTest.java b/module/forge/src/test/java/net/minecraftforge/debug/mod/ConfigAnnotationTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/mod/ConfigAnnotationTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/mod/ConfigAnnotationTest.java diff --git a/src/test/java/net/minecraftforge/debug/mod/ObjectHolderAnnotationTest.java b/module/forge/src/test/java/net/minecraftforge/debug/mod/ObjectHolderAnnotationTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/mod/ObjectHolderAnnotationTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/mod/ObjectHolderAnnotationTest.java diff --git a/src/test/java/net/minecraftforge/debug/mod/PermissionTest.java b/module/forge/src/test/java/net/minecraftforge/debug/mod/PermissionTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/mod/PermissionTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/mod/PermissionTest.java diff --git a/src/test/java/net/minecraftforge/debug/mod/RegistryOverrideTest.java b/module/forge/src/test/java/net/minecraftforge/debug/mod/RegistryOverrideTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/mod/RegistryOverrideTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/mod/RegistryOverrideTest.java diff --git a/src/test/java/net/minecraftforge/debug/mod/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/mod/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/mod/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/mod/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/network/BigNetworkMessageTest.java b/module/forge/src/test/java/net/minecraftforge/debug/network/BigNetworkMessageTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/network/BigNetworkMessageTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/network/BigNetworkMessageTest.java diff --git a/src/test/java/net/minecraftforge/debug/network/TrackingTargetTest.java b/module/forge/src/test/java/net/minecraftforge/debug/network/TrackingTargetTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/network/TrackingTargetTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/network/TrackingTargetTest.java diff --git a/src/test/java/net/minecraftforge/debug/network/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/network/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/network/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/network/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/util/ModNameTooltip.java b/module/forge/src/test/java/net/minecraftforge/debug/util/ModNameTooltip.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/util/ModNameTooltip.java rename to module/forge/src/test/java/net/minecraftforge/debug/util/ModNameTooltip.java diff --git a/src/test/java/net/minecraftforge/debug/util/RotatingWrench.java b/module/forge/src/test/java/net/minecraftforge/debug/util/RotatingWrench.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/util/RotatingWrench.java rename to module/forge/src/test/java/net/minecraftforge/debug/util/RotatingWrench.java diff --git a/src/test/java/net/minecraftforge/debug/util/TextureDumper.java b/module/forge/src/test/java/net/minecraftforge/debug/util/TextureDumper.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/util/TextureDumper.java rename to module/forge/src/test/java/net/minecraftforge/debug/util/TextureDumper.java diff --git a/src/test/java/net/minecraftforge/debug/util/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/util/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/util/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/util/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/village/MerchantTradeOffersEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/village/MerchantTradeOffersEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/village/MerchantTradeOffersEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/village/MerchantTradeOffersEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/village/VillageSiegeEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/village/VillageSiegeEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/village/VillageSiegeEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/village/VillageSiegeEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/world/ChunkCapabilityTest.java b/module/forge/src/test/java/net/minecraftforge/debug/world/ChunkCapabilityTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/world/ChunkCapabilityTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/world/ChunkCapabilityTest.java diff --git a/src/test/java/net/minecraftforge/debug/world/ChunkWatchEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/world/ChunkWatchEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/world/ChunkWatchEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/world/ChunkWatchEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/world/DecorateEventDebug.java b/module/forge/src/test/java/net/minecraftforge/debug/world/DecorateEventDebug.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/world/DecorateEventDebug.java rename to module/forge/src/test/java/net/minecraftforge/debug/world/DecorateEventDebug.java diff --git a/src/test/java/net/minecraftforge/debug/world/SpawnDimensionTest.java b/module/forge/src/test/java/net/minecraftforge/debug/world/SpawnDimensionTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/world/SpawnDimensionTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/world/SpawnDimensionTest.java diff --git a/src/test/java/net/minecraftforge/debug/world/TileEntityLoadingTest.java b/module/forge/src/test/java/net/minecraftforge/debug/world/TileEntityLoadingTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/world/TileEntityLoadingTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/world/TileEntityLoadingTest.java diff --git a/src/test/java/net/minecraftforge/debug/world/WorldCapabilityTest.java b/module/forge/src/test/java/net/minecraftforge/debug/world/WorldCapabilityTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/world/WorldCapabilityTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/world/WorldCapabilityTest.java diff --git a/src/test/java/net/minecraftforge/debug/world/WorldProviderCanSleepAtTest.java b/module/forge/src/test/java/net/minecraftforge/debug/world/WorldProviderCanSleepAtTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/world/WorldProviderCanSleepAtTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/world/WorldProviderCanSleepAtTest.java diff --git a/src/test/java/net/minecraftforge/debug/world/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/world/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/world/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/world/package-info.java diff --git a/src/test/java/net/minecraftforge/fml/common/eventhandler/EventBusTest.java b/module/forge/src/test/java/net/minecraftforge/fml/common/eventhandler/EventBusTest.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/common/eventhandler/EventBusTest.java rename to module/forge/src/test/java/net/minecraftforge/fml/common/eventhandler/EventBusTest.java diff --git a/src/test/java/net/minecraftforge/fml/common/eventhandler/impl/AbnormalListeners.java b/module/forge/src/test/java/net/minecraftforge/fml/common/eventhandler/impl/AbnormalListeners.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/common/eventhandler/impl/AbnormalListeners.java rename to module/forge/src/test/java/net/minecraftforge/fml/common/eventhandler/impl/AbnormalListeners.java diff --git a/src/test/java/net/minecraftforge/fml/common/eventhandler/impl/ExampleEvent.java b/module/forge/src/test/java/net/minecraftforge/fml/common/eventhandler/impl/ExampleEvent.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/common/eventhandler/impl/ExampleEvent.java rename to module/forge/src/test/java/net/minecraftforge/fml/common/eventhandler/impl/ExampleEvent.java diff --git a/src/test/java/net/minecraftforge/fml/common/eventhandler/impl/InstanceListeners.java b/module/forge/src/test/java/net/minecraftforge/fml/common/eventhandler/impl/InstanceListeners.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/common/eventhandler/impl/InstanceListeners.java rename to module/forge/src/test/java/net/minecraftforge/fml/common/eventhandler/impl/InstanceListeners.java diff --git a/src/test/java/net/minecraftforge/fml/common/eventhandler/impl/StaticListeners.java b/module/forge/src/test/java/net/minecraftforge/fml/common/eventhandler/impl/StaticListeners.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/common/eventhandler/impl/StaticListeners.java rename to module/forge/src/test/java/net/minecraftforge/fml/common/eventhandler/impl/StaticListeners.java diff --git a/src/test/java/net/minecraftforge/fml/common/registry/BlockStateMappingsTest.java b/module/forge/src/test/java/net/minecraftforge/fml/common/registry/BlockStateMappingsTest.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/common/registry/BlockStateMappingsTest.java rename to module/forge/src/test/java/net/minecraftforge/fml/common/registry/BlockStateMappingsTest.java diff --git a/src/test/java/net/minecraftforge/fml/common/registry/DummyBlockReplacementTest.java b/module/forge/src/test/java/net/minecraftforge/fml/common/registry/DummyBlockReplacementTest.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/common/registry/DummyBlockReplacementTest.java rename to module/forge/src/test/java/net/minecraftforge/fml/common/registry/DummyBlockReplacementTest.java diff --git a/src/test/java/net/minecraftforge/fml/common/registry/ForgeTestRunner.java b/module/forge/src/test/java/net/minecraftforge/fml/common/registry/ForgeTestRunner.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/common/registry/ForgeTestRunner.java rename to module/forge/src/test/java/net/minecraftforge/fml/common/registry/ForgeTestRunner.java diff --git a/src/test/java/net/minecraftforge/fml/common/registry/FreezingTests.java b/module/forge/src/test/java/net/minecraftforge/fml/common/registry/FreezingTests.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/common/registry/FreezingTests.java rename to module/forge/src/test/java/net/minecraftforge/fml/common/registry/FreezingTests.java diff --git a/src/test/java/net/minecraftforge/fml/common/registry/ItemBlockSubstitutionRemoveRestoreTest.java b/module/forge/src/test/java/net/minecraftforge/fml/common/registry/ItemBlockSubstitutionRemoveRestoreTest.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/common/registry/ItemBlockSubstitutionRemoveRestoreTest.java rename to module/forge/src/test/java/net/minecraftforge/fml/common/registry/ItemBlockSubstitutionRemoveRestoreTest.java diff --git a/src/test/java/net/minecraftforge/fml/common/registry/RegistryTestSuite.java b/module/forge/src/test/java/net/minecraftforge/fml/common/registry/RegistryTestSuite.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/common/registry/RegistryTestSuite.java rename to module/forge/src/test/java/net/minecraftforge/fml/common/registry/RegistryTestSuite.java diff --git a/src/test/java/net/minecraftforge/fml/common/registry/SubstitutionInjectionTest.java b/module/forge/src/test/java/net/minecraftforge/fml/common/registry/SubstitutionInjectionTest.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/common/registry/SubstitutionInjectionTest.java rename to module/forge/src/test/java/net/minecraftforge/fml/common/registry/SubstitutionInjectionTest.java diff --git a/src/test/java/net/minecraftforge/fml/common/registry/SubstitutionRemoveRestoreTest.java b/module/forge/src/test/java/net/minecraftforge/fml/common/registry/SubstitutionRemoveRestoreTest.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/common/registry/SubstitutionRemoveRestoreTest.java rename to module/forge/src/test/java/net/minecraftforge/fml/common/registry/SubstitutionRemoveRestoreTest.java diff --git a/src/test/java/net/minecraftforge/fml/common/registry/VanillaRegistryTests.java b/module/forge/src/test/java/net/minecraftforge/fml/common/registry/VanillaRegistryTests.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/common/registry/VanillaRegistryTests.java rename to module/forge/src/test/java/net/minecraftforge/fml/common/registry/VanillaRegistryTests.java diff --git a/src/test/java/net/minecraftforge/fml/debug/FaultyCoreMod.java b/module/forge/src/test/java/net/minecraftforge/fml/debug/FaultyCoreMod.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/debug/FaultyCoreMod.java rename to module/forge/src/test/java/net/minecraftforge/fml/debug/FaultyCoreMod.java diff --git a/src/test/java/net/minecraftforge/fml/test/DependencyParserTest.java b/module/forge/src/test/java/net/minecraftforge/fml/test/DependencyParserTest.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/test/DependencyParserTest.java rename to module/forge/src/test/java/net/minecraftforge/fml/test/DependencyParserTest.java diff --git a/src/test/java/net/minecraftforge/fml/test/ForgeNetworkTestMod.java b/module/forge/src/test/java/net/minecraftforge/fml/test/ForgeNetworkTestMod.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/test/ForgeNetworkTestMod.java rename to module/forge/src/test/java/net/minecraftforge/fml/test/ForgeNetworkTestMod.java diff --git a/src/test/java/net/minecraftforge/fml/test/SpecialSpawnEventTest.java b/module/forge/src/test/java/net/minecraftforge/fml/test/SpecialSpawnEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/test/SpecialSpawnEventTest.java rename to module/forge/src/test/java/net/minecraftforge/fml/test/SpecialSpawnEventTest.java diff --git a/src/test/java/net/minecraftforge/fml/test/TestNetStuff.java b/module/forge/src/test/java/net/minecraftforge/fml/test/TestNetStuff.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/test/TestNetStuff.java rename to module/forge/src/test/java/net/minecraftforge/fml/test/TestNetStuff.java diff --git a/src/test/java/net/minecraftforge/fml/test/networkhandshake/TestNetworkHandshake.java b/module/forge/src/test/java/net/minecraftforge/fml/test/networkhandshake/TestNetworkHandshake.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/test/networkhandshake/TestNetworkHandshake.java rename to module/forge/src/test/java/net/minecraftforge/fml/test/networkhandshake/TestNetworkHandshake.java diff --git a/src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetHandler1.java b/module/forge/src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetHandler1.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetHandler1.java rename to module/forge/src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetHandler1.java diff --git a/src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetHandler2.java b/module/forge/src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetHandler2.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetHandler2.java rename to module/forge/src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetHandler2.java diff --git a/src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetTestMessage1.java b/module/forge/src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetTestMessage1.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetTestMessage1.java rename to module/forge/src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetTestMessage1.java diff --git a/src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetTestMessage2.java b/module/forge/src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetTestMessage2.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetTestMessage2.java rename to module/forge/src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetTestMessage2.java diff --git a/src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetTester.java b/module/forge/src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetTester.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetTester.java rename to module/forge/src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetTester.java diff --git a/src/test/java/net/minecraftforge/test/BiomeSpawnableListTest.java b/module/forge/src/test/java/net/minecraftforge/test/BiomeSpawnableListTest.java similarity index 100% rename from src/test/java/net/minecraftforge/test/BiomeSpawnableListTest.java rename to module/forge/src/test/java/net/minecraftforge/test/BiomeSpawnableListTest.java diff --git a/src/test/java/net/minecraftforge/test/BufferBuilderExpansionTest.java b/module/forge/src/test/java/net/minecraftforge/test/BufferBuilderExpansionTest.java similarity index 100% rename from src/test/java/net/minecraftforge/test/BufferBuilderExpansionTest.java rename to module/forge/src/test/java/net/minecraftforge/test/BufferBuilderExpansionTest.java diff --git a/src/test/java/net/minecraftforge/test/ConfigurationTest.java b/module/forge/src/test/java/net/minecraftforge/test/ConfigurationTest.java similarity index 100% rename from src/test/java/net/minecraftforge/test/ConfigurationTest.java rename to module/forge/src/test/java/net/minecraftforge/test/ConfigurationTest.java diff --git a/src/test/java/net/minecraftforge/test/EnumHelperTest.java b/module/forge/src/test/java/net/minecraftforge/test/EnumHelperTest.java similarity index 100% rename from src/test/java/net/minecraftforge/test/EnumHelperTest.java rename to module/forge/src/test/java/net/minecraftforge/test/EnumHelperTest.java diff --git a/src/test/java/net/minecraftforge/test/SelectorHandlerTest.java b/module/forge/src/test/java/net/minecraftforge/test/SelectorHandlerTest.java similarity index 100% rename from src/test/java/net/minecraftforge/test/SelectorHandlerTest.java rename to module/forge/src/test/java/net/minecraftforge/test/SelectorHandlerTest.java diff --git a/src/test/java/net/minecraftforge/test/SliderConfigElementTest.java b/module/forge/src/test/java/net/minecraftforge/test/SliderConfigElementTest.java similarity index 100% rename from src/test/java/net/minecraftforge/test/SliderConfigElementTest.java rename to module/forge/src/test/java/net/minecraftforge/test/SliderConfigElementTest.java diff --git a/src/test/java/net/minecraftforge/test/TestAnnotationParser.java b/module/forge/src/test/java/net/minecraftforge/test/TestAnnotationParser.java similarity index 100% rename from src/test/java/net/minecraftforge/test/TestAnnotationParser.java rename to module/forge/src/test/java/net/minecraftforge/test/TestAnnotationParser.java diff --git a/src/test/java/net/minecraftforge/test/TextTableTest.java b/module/forge/src/test/java/net/minecraftforge/test/TextTableTest.java similarity index 100% rename from src/test/java/net/minecraftforge/test/TextTableTest.java rename to module/forge/src/test/java/net/minecraftforge/test/TextTableTest.java diff --git a/src/test/java/net/minecraftforge/test/package-info.java b/module/forge/src/test/java/net/minecraftforge/test/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/test/package-info.java rename to module/forge/src/test/java/net/minecraftforge/test/package-info.java diff --git a/src/test/resources/assets/advancementcriteriontest/advancements/root.json b/module/forge/src/test/resources/assets/advancementcriteriontest/advancements/root.json similarity index 100% rename from src/test/resources/assets/advancementcriteriontest/advancements/root.json rename to module/forge/src/test/resources/assets/advancementcriteriontest/advancements/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a1/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a1/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a1/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a1/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a10/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a10/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a10/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a10/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a11/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a11/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a11/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a11/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a12/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a12/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a12/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a12/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a13/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a13/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a13/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a13/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a14/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a14/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a14/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a14/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a15/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a15/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a15/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a15/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a16/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a16/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a16/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a16/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a17/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a17/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a17/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a17/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a18/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a18/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a18/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a18/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a19/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a19/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a19/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a19/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a2/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a2/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a2/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a2/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a20/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a20/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a20/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a20/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a21/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a21/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a21/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a21/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a22/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a22/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a22/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a22/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a23/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a23/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a23/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a23/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a24/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a24/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a24/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a24/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a25/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a25/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a25/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a25/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a26/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a26/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a26/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a26/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a27/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a27/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a27/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a27/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a28/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a28/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a28/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a28/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a29/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a29/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a29/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a29/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a3/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a3/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a3/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a3/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a30/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a30/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a30/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a30/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a31/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a31/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a31/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a31/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a32/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a32/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a32/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a32/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a33/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a33/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a33/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a33/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a34/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a34/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a34/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a34/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a35/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a35/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a35/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a35/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a36/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a36/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a36/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a36/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a37/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a37/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a37/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a37/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a38/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a38/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a38/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a38/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a39/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a39/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a39/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a39/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a4/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a4/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a4/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a4/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a40/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a40/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a40/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a40/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a41/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a41/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a41/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a41/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a42/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a42/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a42/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a42/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a43/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a43/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a43/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a43/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a44/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a44/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a44/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a44/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a45/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a45/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a45/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a45/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a46/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a46/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a46/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a46/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a47/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a47/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a47/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a47/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a48/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a48/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a48/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a48/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a49/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a49/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a49/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a49/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a5/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a5/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a5/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a5/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a50/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a50/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a50/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a50/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a51/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a51/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a51/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a51/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a52/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a52/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a52/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a52/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a53/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a53/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a53/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a53/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a54/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a54/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a54/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a54/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a55/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a55/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a55/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a55/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a56/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a56/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a56/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a56/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a57/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a57/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a57/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a57/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a58/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a58/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a58/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a58/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a59/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a59/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a59/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a59/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a6/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a6/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a6/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a6/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a60/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a60/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a60/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a60/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a61/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a61/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a61/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a61/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a62/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a62/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a62/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a62/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a63/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a63/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a63/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a63/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a64/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a64/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a64/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a64/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a7/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a7/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a7/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a7/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a8/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a8/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a8/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a8/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a9/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a9/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a9/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a9/root.json diff --git a/src/test/resources/assets/collisionboxexeventtest/blockstates/box_block.json b/module/forge/src/test/resources/assets/collisionboxexeventtest/blockstates/box_block.json similarity index 100% rename from src/test/resources/assets/collisionboxexeventtest/blockstates/box_block.json rename to module/forge/src/test/resources/assets/collisionboxexeventtest/blockstates/box_block.json diff --git a/src/test/resources/assets/config_test/lang/en_US.lang b/module/forge/src/test/resources/assets/config_test/lang/en_US.lang similarity index 100% rename from src/test/resources/assets/config_test/lang/en_US.lang rename to module/forge/src/test/resources/assets/config_test/lang/en_US.lang diff --git a/src/test/resources/assets/constantloadingtest/test/_constants.json b/module/forge/src/test/resources/assets/constantloadingtest/test/_constants.json similarity index 100% rename from src/test/resources/assets/constantloadingtest/test/_constants.json rename to module/forge/src/test/resources/assets/constantloadingtest/test/_constants.json diff --git a/src/test/resources/assets/crafting_system_test/recipes/_factories.json b/module/forge/src/test/resources/assets/crafting_system_test/recipes/_factories.json similarity index 100% rename from src/test/resources/assets/crafting_system_test/recipes/_factories.json rename to module/forge/src/test/resources/assets/crafting_system_test/recipes/_factories.json diff --git a/src/test/resources/assets/crafting_system_test/recipes/conditions_property_not_array.json b/module/forge/src/test/resources/assets/crafting_system_test/recipes/conditions_property_not_array.json similarity index 100% rename from src/test/resources/assets/crafting_system_test/recipes/conditions_property_not_array.json rename to module/forge/src/test/resources/assets/crafting_system_test/recipes/conditions_property_not_array.json diff --git a/src/test/resources/assets/crafting_system_test/recipes/oak_planks_from_logs.json b/module/forge/src/test/resources/assets/crafting_system_test/recipes/oak_planks_from_logs.json similarity index 100% rename from src/test/resources/assets/crafting_system_test/recipes/oak_planks_from_logs.json rename to module/forge/src/test/resources/assets/crafting_system_test/recipes/oak_planks_from_logs.json diff --git a/src/test/resources/assets/custom_sprite_test/blockstates/custom_sprite_block.json b/module/forge/src/test/resources/assets/custom_sprite_test/blockstates/custom_sprite_block.json similarity index 100% rename from src/test/resources/assets/custom_sprite_test/blockstates/custom_sprite_block.json rename to module/forge/src/test/resources/assets/custom_sprite_test/blockstates/custom_sprite_block.json diff --git a/src/test/resources/assets/custom_sprite_test/models/block/custom_sprite_block.json b/module/forge/src/test/resources/assets/custom_sprite_test/models/block/custom_sprite_block.json similarity index 100% rename from src/test/resources/assets/custom_sprite_test/models/block/custom_sprite_block.json rename to module/forge/src/test/resources/assets/custom_sprite_test/models/block/custom_sprite_block.json diff --git a/src/test/resources/assets/dynbuckettest/blockstates/simpletank.json b/module/forge/src/test/resources/assets/dynbuckettest/blockstates/simpletank.json similarity index 100% rename from src/test/resources/assets/dynbuckettest/blockstates/simpletank.json rename to module/forge/src/test/resources/assets/dynbuckettest/blockstates/simpletank.json diff --git a/src/test/resources/assets/farmlandwatertest/blockstates/test_block.json b/module/forge/src/test/resources/assets/farmlandwatertest/blockstates/test_block.json similarity index 100% rename from src/test/resources/assets/farmlandwatertest/blockstates/test_block.json rename to module/forge/src/test/resources/assets/farmlandwatertest/blockstates/test_block.json diff --git a/src/test/resources/assets/fluidadditionalfields/blockstates/slime.json b/module/forge/src/test/resources/assets/fluidadditionalfields/blockstates/slime.json similarity index 100% rename from src/test/resources/assets/fluidadditionalfields/blockstates/slime.json rename to module/forge/src/test/resources/assets/fluidadditionalfields/blockstates/slime.json diff --git a/src/test/resources/assets/fluidadditionalfields/textures/slime_flow.png b/module/forge/src/test/resources/assets/fluidadditionalfields/textures/slime_flow.png similarity index 100% rename from src/test/resources/assets/fluidadditionalfields/textures/slime_flow.png rename to module/forge/src/test/resources/assets/fluidadditionalfields/textures/slime_flow.png diff --git a/src/test/resources/assets/fluidadditionalfields/textures/slime_flow.png.mcmeta b/module/forge/src/test/resources/assets/fluidadditionalfields/textures/slime_flow.png.mcmeta similarity index 100% rename from src/test/resources/assets/fluidadditionalfields/textures/slime_flow.png.mcmeta rename to module/forge/src/test/resources/assets/fluidadditionalfields/textures/slime_flow.png.mcmeta diff --git a/src/test/resources/assets/fluidadditionalfields/textures/slime_overlay.png b/module/forge/src/test/resources/assets/fluidadditionalfields/textures/slime_overlay.png similarity index 100% rename from src/test/resources/assets/fluidadditionalfields/textures/slime_overlay.png rename to module/forge/src/test/resources/assets/fluidadditionalfields/textures/slime_overlay.png diff --git a/src/test/resources/assets/fluidadditionalfields/textures/slime_still.png b/module/forge/src/test/resources/assets/fluidadditionalfields/textures/slime_still.png similarity index 100% rename from src/test/resources/assets/fluidadditionalfields/textures/slime_still.png rename to module/forge/src/test/resources/assets/fluidadditionalfields/textures/slime_still.png diff --git a/src/test/resources/assets/fluidadditionalfields/textures/slime_still.png.mcmeta b/module/forge/src/test/resources/assets/fluidadditionalfields/textures/slime_still.png.mcmeta similarity index 100% rename from src/test/resources/assets/fluidadditionalfields/textures/slime_still.png.mcmeta rename to module/forge/src/test/resources/assets/fluidadditionalfields/textures/slime_still.png.mcmeta diff --git a/src/test/resources/assets/fogcolorinsidematerialtest/blockstates/slime.json b/module/forge/src/test/resources/assets/fogcolorinsidematerialtest/blockstates/slime.json similarity index 100% rename from src/test/resources/assets/fogcolorinsidematerialtest/blockstates/slime.json rename to module/forge/src/test/resources/assets/fogcolorinsidematerialtest/blockstates/slime.json diff --git a/src/test/resources/assets/fogcolorinsidematerialtest/pack.mcmeta b/module/forge/src/test/resources/assets/fogcolorinsidematerialtest/pack.mcmeta similarity index 100% rename from src/test/resources/assets/fogcolorinsidematerialtest/pack.mcmeta rename to module/forge/src/test/resources/assets/fogcolorinsidematerialtest/pack.mcmeta diff --git a/src/test/resources/assets/fogcolorinsidematerialtest/test_fluid.json b/module/forge/src/test/resources/assets/fogcolorinsidematerialtest/test_fluid.json similarity index 100% rename from src/test/resources/assets/fogcolorinsidematerialtest/test_fluid.json rename to module/forge/src/test/resources/assets/fogcolorinsidematerialtest/test_fluid.json diff --git a/src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_flow.png b/module/forge/src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_flow.png similarity index 100% rename from src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_flow.png rename to module/forge/src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_flow.png diff --git a/src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_flow.png.mcmeta b/module/forge/src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_flow.png.mcmeta similarity index 100% rename from src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_flow.png.mcmeta rename to module/forge/src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_flow.png.mcmeta diff --git a/src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_overlay.png b/module/forge/src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_overlay.png similarity index 100% rename from src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_overlay.png rename to module/forge/src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_overlay.png diff --git a/src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_still.png b/module/forge/src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_still.png similarity index 100% rename from src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_still.png rename to module/forge/src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_still.png diff --git a/src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_still.png.mcmeta b/module/forge/src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_still.png.mcmeta similarity index 100% rename from src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_still.png.mcmeta rename to module/forge/src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_still.png.mcmeta diff --git a/src/test/resources/assets/forge/blockstates/dynbottle.json b/module/forge/src/test/resources/assets/forge/blockstates/dynbottle.json similarity index 100% rename from src/test/resources/assets/forge/blockstates/dynbottle.json rename to module/forge/src/test/resources/assets/forge/blockstates/dynbottle.json diff --git a/src/test/resources/assets/forge/recipes/_constants.json b/module/forge/src/test/resources/assets/forge/recipes/_constants.json similarity index 100% rename from src/test/resources/assets/forge/recipes/_constants.json rename to module/forge/src/test/resources/assets/forge/recipes/_constants.json diff --git a/src/test/resources/assets/forge/recipes/ore_shaped.json b/module/forge/src/test/resources/assets/forge/recipes/ore_shaped.json similarity index 100% rename from src/test/resources/assets/forge/recipes/ore_shaped.json rename to module/forge/src/test/resources/assets/forge/recipes/ore_shaped.json diff --git a/src/test/resources/assets/forge/recipes/shapeless.json b/module/forge/src/test/resources/assets/forge/recipes/shapeless.json similarity index 100% rename from src/test/resources/assets/forge/recipes/shapeless.json rename to module/forge/src/test/resources/assets/forge/recipes/shapeless.json diff --git a/src/test/resources/assets/forge/recipes/shapeless_constant.json b/module/forge/src/test/resources/assets/forge/recipes/shapeless_constant.json similarity index 100% rename from src/test/resources/assets/forge/recipes/shapeless_constant.json rename to module/forge/src/test/resources/assets/forge/recipes/shapeless_constant.json diff --git a/src/test/resources/assets/forge/recipes/shapeless_damageable.json b/module/forge/src/test/resources/assets/forge/recipes/shapeless_damageable.json similarity index 100% rename from src/test/resources/assets/forge/recipes/shapeless_damageable.json rename to module/forge/src/test/resources/assets/forge/recipes/shapeless_damageable.json diff --git a/src/test/resources/assets/forge/recipes/shapeless_ore.json b/module/forge/src/test/resources/assets/forge/recipes/shapeless_ore.json similarity index 100% rename from src/test/resources/assets/forge/recipes/shapeless_ore.json rename to module/forge/src/test/resources/assets/forge/recipes/shapeless_ore.json diff --git a/src/test/resources/assets/forge/recipes/shapeless_wildcard.json b/module/forge/src/test/resources/assets/forge/recipes/shapeless_wildcard.json similarity index 100% rename from src/test/resources/assets/forge/recipes/shapeless_wildcard.json rename to module/forge/src/test/resources/assets/forge/recipes/shapeless_wildcard.json diff --git a/src/test/resources/assets/forge/textures/blocks/milk_flow.png b/module/forge/src/test/resources/assets/forge/textures/blocks/milk_flow.png similarity index 100% rename from src/test/resources/assets/forge/textures/blocks/milk_flow.png rename to module/forge/src/test/resources/assets/forge/textures/blocks/milk_flow.png diff --git a/src/test/resources/assets/forge/textures/blocks/milk_flow.png.mcmeta b/module/forge/src/test/resources/assets/forge/textures/blocks/milk_flow.png.mcmeta similarity index 100% rename from src/test/resources/assets/forge/textures/blocks/milk_flow.png.mcmeta rename to module/forge/src/test/resources/assets/forge/textures/blocks/milk_flow.png.mcmeta diff --git a/src/test/resources/assets/forge/textures/blocks/milk_still.png b/module/forge/src/test/resources/assets/forge/textures/blocks/milk_still.png similarity index 100% rename from src/test/resources/assets/forge/textures/blocks/milk_still.png rename to module/forge/src/test/resources/assets/forge/textures/blocks/milk_still.png diff --git a/src/test/resources/assets/forge/textures/blocks/milk_still.png.mcmeta b/module/forge/src/test/resources/assets/forge/textures/blocks/milk_still.png.mcmeta similarity index 100% rename from src/test/resources/assets/forge/textures/blocks/milk_still.png.mcmeta rename to module/forge/src/test/resources/assets/forge/textures/blocks/milk_still.png.mcmeta diff --git a/src/test/resources/assets/forgeblockstatesloader/blockstates/cobblestone_wall.json b/module/forge/src/test/resources/assets/forgeblockstatesloader/blockstates/cobblestone_wall.json similarity index 100% rename from src/test/resources/assets/forgeblockstatesloader/blockstates/cobblestone_wall.json rename to module/forge/src/test/resources/assets/forgeblockstatesloader/blockstates/cobblestone_wall.json diff --git a/src/test/resources/assets/forgeblockstatesloader/blockstates/mossy_cobblestone_wall.json b/module/forge/src/test/resources/assets/forgeblockstatesloader/blockstates/mossy_cobblestone_wall.json similarity index 100% rename from src/test/resources/assets/forgeblockstatesloader/blockstates/mossy_cobblestone_wall.json rename to module/forge/src/test/resources/assets/forgeblockstatesloader/blockstates/mossy_cobblestone_wall.json diff --git a/src/test/resources/assets/forgeblockstatesloader/models/block/wall_connect.json b/module/forge/src/test/resources/assets/forgeblockstatesloader/models/block/wall_connect.json similarity index 100% rename from src/test/resources/assets/forgeblockstatesloader/models/block/wall_connect.json rename to module/forge/src/test/resources/assets/forgeblockstatesloader/models/block/wall_connect.json diff --git a/src/test/resources/assets/forgedebugcustomslimeblock/blockstates/custom_slime_block.json b/module/forge/src/test/resources/assets/forgedebugcustomslimeblock/blockstates/custom_slime_block.json similarity index 100% rename from src/test/resources/assets/forgedebugcustomslimeblock/blockstates/custom_slime_block.json rename to module/forge/src/test/resources/assets/forgedebugcustomslimeblock/blockstates/custom_slime_block.json diff --git a/src/test/resources/assets/forgedebugcustomslimeblock/lang/en_US.lang b/module/forge/src/test/resources/assets/forgedebugcustomslimeblock/lang/en_US.lang similarity index 100% rename from src/test/resources/assets/forgedebugcustomslimeblock/lang/en_US.lang rename to module/forge/src/test/resources/assets/forgedebugcustomslimeblock/lang/en_US.lang diff --git a/src/test/resources/assets/forgedebugcustomslimeblock/models/block/blue_slime_block.json b/module/forge/src/test/resources/assets/forgedebugcustomslimeblock/models/block/blue_slime_block.json similarity index 100% rename from src/test/resources/assets/forgedebugcustomslimeblock/models/block/blue_slime_block.json rename to module/forge/src/test/resources/assets/forgedebugcustomslimeblock/models/block/blue_slime_block.json diff --git a/src/test/resources/assets/forgedebugcustomslimeblock/models/block/obsidian_slime_block.json b/module/forge/src/test/resources/assets/forgedebugcustomslimeblock/models/block/obsidian_slime_block.json similarity index 100% rename from src/test/resources/assets/forgedebugcustomslimeblock/models/block/obsidian_slime_block.json rename to module/forge/src/test/resources/assets/forgedebugcustomslimeblock/models/block/obsidian_slime_block.json diff --git a/src/test/resources/assets/forgedebugcustomslimeblock/models/item/blue_slime_block.json b/module/forge/src/test/resources/assets/forgedebugcustomslimeblock/models/item/blue_slime_block.json similarity index 100% rename from src/test/resources/assets/forgedebugcustomslimeblock/models/item/blue_slime_block.json rename to module/forge/src/test/resources/assets/forgedebugcustomslimeblock/models/item/blue_slime_block.json diff --git a/src/test/resources/assets/forgedebugcustomslimeblock/models/item/obsidian_slime_block.json b/module/forge/src/test/resources/assets/forgedebugcustomslimeblock/models/item/obsidian_slime_block.json similarity index 100% rename from src/test/resources/assets/forgedebugcustomslimeblock/models/item/obsidian_slime_block.json rename to module/forge/src/test/resources/assets/forgedebugcustomslimeblock/models/item/obsidian_slime_block.json diff --git a/src/test/resources/assets/forgedebugcustomslimeblock/textures/blocks/blue_slime_block.png b/module/forge/src/test/resources/assets/forgedebugcustomslimeblock/textures/blocks/blue_slime_block.png similarity index 100% rename from src/test/resources/assets/forgedebugcustomslimeblock/textures/blocks/blue_slime_block.png rename to module/forge/src/test/resources/assets/forgedebugcustomslimeblock/textures/blocks/blue_slime_block.png diff --git a/src/test/resources/assets/forgedebugcustomslimeblock/textures/blocks/obsidian_slime_block.png b/module/forge/src/test/resources/assets/forgedebugcustomslimeblock/textures/blocks/obsidian_slime_block.png similarity index 100% rename from src/test/resources/assets/forgedebugcustomslimeblock/textures/blocks/obsidian_slime_block.png rename to module/forge/src/test/resources/assets/forgedebugcustomslimeblock/textures/blocks/obsidian_slime_block.png diff --git a/src/test/resources/assets/forgedebugfluidplacement/blockstates/finite_fluid_block.json b/module/forge/src/test/resources/assets/forgedebugfluidplacement/blockstates/finite_fluid_block.json similarity index 100% rename from src/test/resources/assets/forgedebugfluidplacement/blockstates/finite_fluid_block.json rename to module/forge/src/test/resources/assets/forgedebugfluidplacement/blockstates/finite_fluid_block.json diff --git a/src/test/resources/assets/forgedebugitemlayermodel/blockstates/test_item.json b/module/forge/src/test/resources/assets/forgedebugitemlayermodel/blockstates/test_item.json similarity index 100% rename from src/test/resources/assets/forgedebugitemlayermodel/blockstates/test_item.json rename to module/forge/src/test/resources/assets/forgedebugitemlayermodel/blockstates/test_item.json diff --git a/src/test/resources/assets/forgedebugitemtile/blockstates/custom_model_block.json b/module/forge/src/test/resources/assets/forgedebugitemtile/blockstates/custom_model_block.json similarity index 100% rename from src/test/resources/assets/forgedebugitemtile/blockstates/custom_model_block.json rename to module/forge/src/test/resources/assets/forgedebugitemtile/blockstates/custom_model_block.json diff --git a/src/test/resources/assets/forgedebugmodelanimation/armatures/block/engine_ring.json b/module/forge/src/test/resources/assets/forgedebugmodelanimation/armatures/block/engine_ring.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelanimation/armatures/block/engine_ring.json rename to module/forge/src/test/resources/assets/forgedebugmodelanimation/armatures/block/engine_ring.json diff --git a/src/test/resources/assets/forgedebugmodelanimation/armatures/block/rotatest.json b/module/forge/src/test/resources/assets/forgedebugmodelanimation/armatures/block/rotatest.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelanimation/armatures/block/rotatest.json rename to module/forge/src/test/resources/assets/forgedebugmodelanimation/armatures/block/rotatest.json diff --git a/src/test/resources/assets/forgedebugmodelanimation/asms/block/chest.json b/module/forge/src/test/resources/assets/forgedebugmodelanimation/asms/block/chest.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelanimation/asms/block/chest.json rename to module/forge/src/test/resources/assets/forgedebugmodelanimation/asms/block/chest.json diff --git a/src/test/resources/assets/forgedebugmodelanimation/asms/block/engine.json b/module/forge/src/test/resources/assets/forgedebugmodelanimation/asms/block/engine.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelanimation/asms/block/engine.json rename to module/forge/src/test/resources/assets/forgedebugmodelanimation/asms/block/engine.json diff --git a/src/test/resources/assets/forgedebugmodelanimation/asms/block/engine2.json b/module/forge/src/test/resources/assets/forgedebugmodelanimation/asms/block/engine2.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelanimation/asms/block/engine2.json rename to module/forge/src/test/resources/assets/forgedebugmodelanimation/asms/block/engine2.json diff --git a/src/test/resources/assets/forgedebugmodelanimation/asms/block/rotatest.json b/module/forge/src/test/resources/assets/forgedebugmodelanimation/asms/block/rotatest.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelanimation/asms/block/rotatest.json rename to module/forge/src/test/resources/assets/forgedebugmodelanimation/asms/block/rotatest.json diff --git a/src/test/resources/assets/forgedebugmodelanimation/blockstates/rotatest.json b/module/forge/src/test/resources/assets/forgedebugmodelanimation/blockstates/rotatest.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelanimation/blockstates/rotatest.json rename to module/forge/src/test/resources/assets/forgedebugmodelanimation/blockstates/rotatest.json diff --git a/src/test/resources/assets/forgedebugmodelanimation/blockstates/test_animation_block.json b/module/forge/src/test/resources/assets/forgedebugmodelanimation/blockstates/test_animation_block.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelanimation/blockstates/test_animation_block.json rename to module/forge/src/test/resources/assets/forgedebugmodelanimation/blockstates/test_animation_block.json diff --git a/src/test/resources/assets/forgedebugmodelanimation/models/block/engine.json b/module/forge/src/test/resources/assets/forgedebugmodelanimation/models/block/engine.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelanimation/models/block/engine.json rename to module/forge/src/test/resources/assets/forgedebugmodelanimation/models/block/engine.json diff --git a/src/test/resources/assets/forgedebugmodelanimation/models/block/engine_ring.json b/module/forge/src/test/resources/assets/forgedebugmodelanimation/models/block/engine_ring.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelanimation/models/block/engine_ring.json rename to module/forge/src/test/resources/assets/forgedebugmodelanimation/models/block/engine_ring.json diff --git a/src/test/resources/assets/forgedebugmodelanimation/models/block/rotatest.json b/module/forge/src/test/resources/assets/forgedebugmodelanimation/models/block/rotatest.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelanimation/models/block/rotatest.json rename to module/forge/src/test/resources/assets/forgedebugmodelanimation/models/block/rotatest.json diff --git a/src/test/resources/assets/forgedebugmodelfluid/blockstates/test_fluid_block.json b/module/forge/src/test/resources/assets/forgedebugmodelfluid/blockstates/test_fluid_block.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelfluid/blockstates/test_fluid_block.json rename to module/forge/src/test/resources/assets/forgedebugmodelfluid/blockstates/test_fluid_block.json diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/custom_model_block.json b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/custom_model_block.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/custom_model_block.json rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/custom_model_block.json diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_custom_data_block.json b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_custom_data_block.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_custom_data_block.json rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_custom_data_block.json diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_direction_block.json b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_direction_block.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_direction_block.json rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_direction_block.json diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_direction_eye.json b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_direction_eye.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_direction_eye.json rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_direction_eye.json diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_dynamic_eye.json b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_dynamic_eye.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_dynamic_eye.json rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_dynamic_eye.json diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_tesseract_block.json b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_tesseract_block.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_tesseract_block.json rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_tesseract_block.json diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_vertex_coloring1.json b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_vertex_coloring1.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_vertex_coloring1.json rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_vertex_coloring1.json diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_vertex_coloring2.json b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_vertex_coloring2.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_vertex_coloring2.json rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_vertex_coloring2.json diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/chest.b3d b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/chest.b3d similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/models/block/chest.b3d rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/chest.b3d diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/direction_test.mtl b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/direction_test.mtl similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/models/block/direction_test.mtl rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/direction_test.mtl diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/direction_test.obj b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/direction_test.obj similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/models/block/direction_test.obj rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/direction_test.obj diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/eye.mtl b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/eye.mtl similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/models/block/eye.mtl rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/eye.mtl diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/eye.obj b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/eye.obj similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/models/block/eye.obj rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/eye.obj diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/fancy_fence.mtl b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/fancy_fence.mtl similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/models/block/fancy_fence.mtl rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/fancy_fence.mtl diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/fancy_fence.obj b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/fancy_fence.obj similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/models/block/fancy_fence.obj rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/fancy_fence.obj diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/tesseract.mtl b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/tesseract.mtl similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/models/block/tesseract.mtl rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/tesseract.mtl diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/tesseract.obj b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/tesseract.obj similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/models/block/tesseract.obj rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/tesseract.obj diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/untitled2.b3d b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/untitled2.b3d similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/models/block/untitled2.b3d rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/untitled2.b3d diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/vertex_coloring.mtl b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/vertex_coloring.mtl similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/models/block/vertex_coloring.mtl rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/vertex_coloring.mtl diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/vertex_coloring.obj b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/vertex_coloring.obj similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/models/block/vertex_coloring.obj rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/vertex_coloring.obj diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_arrow.png b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_arrow.png similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_arrow.png rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_arrow.png diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_arrow_top.png b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_arrow_top.png similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_arrow_top.png rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_arrow_top.png diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_back.png b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_back.png similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_back.png rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_back.png diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_front.png b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_front.png similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_front.png rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_front.png diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/textures/eye.png b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/textures/eye.png similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/textures/eye.png rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/textures/eye.png diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/textures/eye128.png b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/textures/eye128.png similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/textures/eye128.png rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/textures/eye128.png diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/textures/texture.png b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/textures/texture.png similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/textures/texture.png rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/textures/texture.png diff --git a/src/test/resources/assets/forgedebugmultilayermodel/blockstates/test_layer_block.json b/module/forge/src/test/resources/assets/forgedebugmultilayermodel/blockstates/test_layer_block.json similarity index 100% rename from src/test/resources/assets/forgedebugmultilayermodel/blockstates/test_layer_block.json rename to module/forge/src/test/resources/assets/forgedebugmultilayermodel/blockstates/test_layer_block.json diff --git a/src/test/resources/assets/forgedebugnobedsleeping/models/item/sleeping_pill.json b/module/forge/src/test/resources/assets/forgedebugnobedsleeping/models/item/sleeping_pill.json similarity index 100% rename from src/test/resources/assets/forgedebugnobedsleeping/models/item/sleeping_pill.json rename to module/forge/src/test/resources/assets/forgedebugnobedsleeping/models/item/sleeping_pill.json diff --git a/src/test/resources/assets/furnacefuelburntimeeventtest/models/item/flammable_gold_shovel.json b/module/forge/src/test/resources/assets/furnacefuelburntimeeventtest/models/item/flammable_gold_shovel.json similarity index 100% rename from src/test/resources/assets/furnacefuelburntimeeventtest/models/item/flammable_gold_shovel.json rename to module/forge/src/test/resources/assets/furnacefuelburntimeeventtest/models/item/flammable_gold_shovel.json diff --git a/src/test/resources/assets/furnacefuelburntimeeventtest/models/item/unburnable_wood_shovel.json b/module/forge/src/test/resources/assets/furnacefuelburntimeeventtest/models/item/unburnable_wood_shovel.json similarity index 100% rename from src/test/resources/assets/furnacefuelburntimeeventtest/models/item/unburnable_wood_shovel.json rename to module/forge/src/test/resources/assets/furnacefuelburntimeeventtest/models/item/unburnable_wood_shovel.json diff --git a/src/test/resources/assets/horse_armor_test/lang/en_US.lang b/module/forge/src/test/resources/assets/horse_armor_test/lang/en_US.lang similarity index 100% rename from src/test/resources/assets/horse_armor_test/lang/en_US.lang rename to module/forge/src/test/resources/assets/horse_armor_test/lang/en_US.lang diff --git a/src/test/resources/assets/horse_armor_test/models/item/test_armor.json b/module/forge/src/test/resources/assets/horse_armor_test/models/item/test_armor.json similarity index 100% rename from src/test/resources/assets/horse_armor_test/models/item/test_armor.json rename to module/forge/src/test/resources/assets/horse_armor_test/models/item/test_armor.json diff --git a/src/test/resources/assets/horse_armor_test/textures/entity/horse/armor/test.png b/module/forge/src/test/resources/assets/horse_armor_test/textures/entity/horse/armor/test.png similarity index 100% rename from src/test/resources/assets/horse_armor_test/textures/entity/horse/armor/test.png rename to module/forge/src/test/resources/assets/horse_armor_test/textures/entity/horse/armor/test.png diff --git a/src/test/resources/assets/horse_armor_test/textures/items/test_armor.png b/module/forge/src/test/resources/assets/horse_armor_test/textures/items/test_armor.png similarity index 100% rename from src/test/resources/assets/horse_armor_test/textures/items/test_armor.png rename to module/forge/src/test/resources/assets/horse_armor_test/textures/items/test_armor.png diff --git a/src/test/resources/assets/item_can_destroy_blocks_in_creative_test/models/item/item_test.json b/module/forge/src/test/resources/assets/item_can_destroy_blocks_in_creative_test/models/item/item_test.json similarity index 100% rename from src/test/resources/assets/item_can_destroy_blocks_in_creative_test/models/item/item_test.json rename to module/forge/src/test/resources/assets/item_can_destroy_blocks_in_creative_test/models/item/item_test.json diff --git a/src/test/resources/assets/item_model_conflict_test/blockstates/test.json b/module/forge/src/test/resources/assets/item_model_conflict_test/blockstates/test.json similarity index 100% rename from src/test/resources/assets/item_model_conflict_test/blockstates/test.json rename to module/forge/src/test/resources/assets/item_model_conflict_test/blockstates/test.json diff --git a/src/test/resources/assets/item_model_conflict_test/models/block/test.json b/module/forge/src/test/resources/assets/item_model_conflict_test/models/block/test.json similarity index 100% rename from src/test/resources/assets/item_model_conflict_test/models/block/test.json rename to module/forge/src/test/resources/assets/item_model_conflict_test/models/block/test.json diff --git a/src/test/resources/assets/item_model_conflict_test/models/item/test.json b/module/forge/src/test/resources/assets/item_model_conflict_test/models/item/test.json similarity index 100% rename from src/test/resources/assets/item_model_conflict_test/models/item/test.json rename to module/forge/src/test/resources/assets/item_model_conflict_test/models/item/test.json diff --git a/src/test/resources/assets/item_model_generation_test/models/item/animation_test.json b/module/forge/src/test/resources/assets/item_model_generation_test/models/item/animation_test.json similarity index 100% rename from src/test/resources/assets/item_model_generation_test/models/item/animation_test.json rename to module/forge/src/test/resources/assets/item_model_generation_test/models/item/animation_test.json diff --git a/src/test/resources/assets/item_model_generation_test/models/item/intersection_test.json b/module/forge/src/test/resources/assets/item_model_generation_test/models/item/intersection_test.json similarity index 100% rename from src/test/resources/assets/item_model_generation_test/models/item/intersection_test.json rename to module/forge/src/test/resources/assets/item_model_generation_test/models/item/intersection_test.json diff --git a/src/test/resources/assets/item_model_generation_test/models/item/opacity_test.json b/module/forge/src/test/resources/assets/item_model_generation_test/models/item/opacity_test.json similarity index 100% rename from src/test/resources/assets/item_model_generation_test/models/item/opacity_test.json rename to module/forge/src/test/resources/assets/item_model_generation_test/models/item/opacity_test.json diff --git a/src/test/resources/assets/item_model_generation_test/models/item/overlap_test.json b/module/forge/src/test/resources/assets/item_model_generation_test/models/item/overlap_test.json similarity index 100% rename from src/test/resources/assets/item_model_generation_test/models/item/overlap_test.json rename to module/forge/src/test/resources/assets/item_model_generation_test/models/item/overlap_test.json diff --git a/src/test/resources/assets/item_model_generation_test/models/item/pattern_test.json b/module/forge/src/test/resources/assets/item_model_generation_test/models/item/pattern_test.json similarity index 100% rename from src/test/resources/assets/item_model_generation_test/models/item/pattern_test.json rename to module/forge/src/test/resources/assets/item_model_generation_test/models/item/pattern_test.json diff --git a/src/test/resources/assets/item_model_generation_test/textures/items/animation_test.png b/module/forge/src/test/resources/assets/item_model_generation_test/textures/items/animation_test.png similarity index 100% rename from src/test/resources/assets/item_model_generation_test/textures/items/animation_test.png rename to module/forge/src/test/resources/assets/item_model_generation_test/textures/items/animation_test.png diff --git a/src/test/resources/assets/item_model_generation_test/textures/items/animation_test.png.mcmeta b/module/forge/src/test/resources/assets/item_model_generation_test/textures/items/animation_test.png.mcmeta similarity index 100% rename from src/test/resources/assets/item_model_generation_test/textures/items/animation_test.png.mcmeta rename to module/forge/src/test/resources/assets/item_model_generation_test/textures/items/animation_test.png.mcmeta diff --git a/src/test/resources/assets/item_model_generation_test/textures/items/intersection_test.png b/module/forge/src/test/resources/assets/item_model_generation_test/textures/items/intersection_test.png similarity index 100% rename from src/test/resources/assets/item_model_generation_test/textures/items/intersection_test.png rename to module/forge/src/test/resources/assets/item_model_generation_test/textures/items/intersection_test.png diff --git a/src/test/resources/assets/item_model_generation_test/textures/items/opacity_test.png b/module/forge/src/test/resources/assets/item_model_generation_test/textures/items/opacity_test.png similarity index 100% rename from src/test/resources/assets/item_model_generation_test/textures/items/opacity_test.png rename to module/forge/src/test/resources/assets/item_model_generation_test/textures/items/opacity_test.png diff --git a/src/test/resources/assets/item_model_generation_test/textures/items/overlap_test.png b/module/forge/src/test/resources/assets/item_model_generation_test/textures/items/overlap_test.png similarity index 100% rename from src/test/resources/assets/item_model_generation_test/textures/items/overlap_test.png rename to module/forge/src/test/resources/assets/item_model_generation_test/textures/items/overlap_test.png diff --git a/src/test/resources/assets/item_model_generation_test/textures/items/pattern_test.png b/module/forge/src/test/resources/assets/item_model_generation_test/textures/items/pattern_test.png similarity index 100% rename from src/test/resources/assets/item_model_generation_test/textures/items/pattern_test.png rename to module/forge/src/test/resources/assets/item_model_generation_test/textures/items/pattern_test.png diff --git a/src/test/resources/assets/loot_context_tweaks_test/advancements/test/root.json b/module/forge/src/test/resources/assets/loot_context_tweaks_test/advancements/test/root.json similarity index 100% rename from src/test/resources/assets/loot_context_tweaks_test/advancements/test/root.json rename to module/forge/src/test/resources/assets/loot_context_tweaks_test/advancements/test/root.json diff --git a/src/test/resources/assets/loottable_load_event_test/loot_tables/chests/custom_spawn_bonus_chest.json b/module/forge/src/test/resources/assets/loottable_load_event_test/loot_tables/chests/custom_spawn_bonus_chest.json similarity index 100% rename from src/test/resources/assets/loottable_load_event_test/loot_tables/chests/custom_spawn_bonus_chest.json rename to module/forge/src/test/resources/assets/loottable_load_event_test/loot_tables/chests/custom_spawn_bonus_chest.json diff --git a/src/test/resources/assets/nbtsharetagitemtest/models/item/nbt_share_tag_item.json b/module/forge/src/test/resources/assets/nbtsharetagitemtest/models/item/nbt_share_tag_item.json similarity index 100% rename from src/test/resources/assets/nbtsharetagitemtest/models/item/nbt_share_tag_item.json rename to module/forge/src/test/resources/assets/nbtsharetagitemtest/models/item/nbt_share_tag_item.json diff --git a/src/test/resources/assets/onitemusefirsttest/models/item/test_item.json b/module/forge/src/test/resources/assets/onitemusefirsttest/models/item/test_item.json similarity index 100% rename from src/test/resources/assets/onitemusefirsttest/models/item/test_item.json rename to module/forge/src/test/resources/assets/onitemusefirsttest/models/item/test_item.json diff --git a/src/test/resources/assets/oredict_predicate/advancements/recipes/wood_unlock_tnt.json b/module/forge/src/test/resources/assets/oredict_predicate/advancements/recipes/wood_unlock_tnt.json similarity index 100% rename from src/test/resources/assets/oredict_predicate/advancements/recipes/wood_unlock_tnt.json rename to module/forge/src/test/resources/assets/oredict_predicate/advancements/recipes/wood_unlock_tnt.json diff --git a/src/test/resources/assets/professiontest/textures/entity/test_villager.png b/module/forge/src/test/resources/assets/professiontest/textures/entity/test_villager.png similarity index 100% rename from src/test/resources/assets/professiontest/textures/entity/test_villager.png rename to module/forge/src/test/resources/assets/professiontest/textures/entity/test_villager.png diff --git a/src/test/resources/assets/professiontest/textures/entity/zombie_test_villager.png b/module/forge/src/test/resources/assets/professiontest/textures/entity/zombie_test_villager.png similarity index 100% rename from src/test/resources/assets/professiontest/textures/entity/zombie_test_villager.png rename to module/forge/src/test/resources/assets/professiontest/textures/entity/zombie_test_villager.png diff --git a/src/test/resources/assets/recipetest/recipes/tool_complex.json b/module/forge/src/test/resources/assets/recipetest/recipes/tool_complex.json similarity index 100% rename from src/test/resources/assets/recipetest/recipes/tool_complex.json rename to module/forge/src/test/resources/assets/recipetest/recipes/tool_complex.json diff --git a/src/test/resources/assets/recipetest/recipes/tool_simple.json b/module/forge/src/test/resources/assets/recipetest/recipes/tool_simple.json similarity index 100% rename from src/test/resources/assets/recipetest/recipes/tool_simple.json rename to module/forge/src/test/resources/assets/recipetest/recipes/tool_simple.json diff --git a/src/test/resources/assets/shield_test/lang/en_US.lang b/module/forge/src/test/resources/assets/shield_test/lang/en_US.lang similarity index 100% rename from src/test/resources/assets/shield_test/lang/en_US.lang rename to module/forge/src/test/resources/assets/shield_test/lang/en_US.lang diff --git a/src/test/resources/assets/shield_test/models/item/diamond_shield.json b/module/forge/src/test/resources/assets/shield_test/models/item/diamond_shield.json similarity index 100% rename from src/test/resources/assets/shield_test/models/item/diamond_shield.json rename to module/forge/src/test/resources/assets/shield_test/models/item/diamond_shield.json diff --git a/src/test/resources/assets/shield_test/models/item/diamond_shield_blocking.json b/module/forge/src/test/resources/assets/shield_test/models/item/diamond_shield_blocking.json similarity index 100% rename from src/test/resources/assets/shield_test/models/item/diamond_shield_blocking.json rename to module/forge/src/test/resources/assets/shield_test/models/item/diamond_shield_blocking.json diff --git a/src/test/resources/assets/wrenchrotatedebug/models/item/test_wrench.json b/module/forge/src/test/resources/assets/wrenchrotatedebug/models/item/test_wrench.json similarity index 100% rename from src/test/resources/assets/wrenchrotatedebug/models/item/test_wrench.json rename to module/forge/src/test/resources/assets/wrenchrotatedebug/models/item/test_wrench.json diff --git a/src/test/resources/assets/wrenchrotatedebug/textures/items/test_wrench.png b/module/forge/src/test/resources/assets/wrenchrotatedebug/textures/items/test_wrench.png similarity index 100% rename from src/test/resources/assets/wrenchrotatedebug/textures/items/test_wrench.png rename to module/forge/src/test/resources/assets/wrenchrotatedebug/textures/items/test_wrench.png diff --git a/src/test/resources/mcmod.info b/module/forge/src/test/resources/mcmod.info similarity index 100% rename from src/test/resources/mcmod.info rename to module/forge/src/test/resources/mcmod.info diff --git a/projects/kirino b/module/kirino similarity index 100% rename from projects/kirino rename to module/kirino diff --git a/src/main/java/zone/rong/mixinbooter/Context.java b/module/mixinbooter/src/main/java/zone/rong/mixinbooter/Context.java similarity index 100% rename from src/main/java/zone/rong/mixinbooter/Context.java rename to module/mixinbooter/src/main/java/zone/rong/mixinbooter/Context.java diff --git a/src/main/java/zone/rong/mixinbooter/IEarlyMixinLoader.java b/module/mixinbooter/src/main/java/zone/rong/mixinbooter/IEarlyMixinLoader.java similarity index 100% rename from src/main/java/zone/rong/mixinbooter/IEarlyMixinLoader.java rename to module/mixinbooter/src/main/java/zone/rong/mixinbooter/IEarlyMixinLoader.java diff --git a/src/main/java/zone/rong/mixinbooter/ILateMixinLoader.java b/module/mixinbooter/src/main/java/zone/rong/mixinbooter/ILateMixinLoader.java similarity index 100% rename from src/main/java/zone/rong/mixinbooter/ILateMixinLoader.java rename to module/mixinbooter/src/main/java/zone/rong/mixinbooter/ILateMixinLoader.java diff --git a/src/main/java/zone/rong/mixinbooter/IMixinConfigHijacker.java b/module/mixinbooter/src/main/java/zone/rong/mixinbooter/IMixinConfigHijacker.java similarity index 100% rename from src/main/java/zone/rong/mixinbooter/IMixinConfigHijacker.java rename to module/mixinbooter/src/main/java/zone/rong/mixinbooter/IMixinConfigHijacker.java diff --git a/projects/cleanroom/build.gradle b/projects/cleanroom/build.gradle deleted file mode 100644 index ba5b7cbc9..000000000 --- a/projects/cleanroom/build.gradle +++ /dev/null @@ -1,1083 +0,0 @@ -import com.cleanroommc.gradle.helpers.ProjectConstants -import com.cleanroommc.gradle.helpers.tasks.GenVersionTask -import com.cleanroommc.gradle.helpers.tasks.CreateMMCPackTask -import com.cleanroommc.gradle.helpers.tasks.Util -import com.palantir.gradle.gitversion.VersionDetails -import groovy.json.JsonBuilder -import groovy.json.JsonSlurper -import net.minecraftforge.gradle.common.tasks.ApplyBinPatches -import net.minecraftforge.gradle.common.tasks.DownloadMavenArtifact -import net.minecraftforge.gradle.common.tasks.ExtractInheritance -import net.minecraftforge.gradle.common.tasks.ExtractMCPData -import net.minecraftforge.gradle.patcher.tasks.GenerateBinPatches -import net.minecraftforge.gradle.patcher.tasks.GeneratePatches -import net.minecraftforge.gradle.patcher.tasks.ReobfuscateJar -import net.minecraftforge.srgutils.IMappingFile -import org.apache.commons.compress.compressors.lzma.LZMACompressorOutputStream -import org.objectweb.asm.ClassReader -import org.objectweb.asm.ClassVisitor -import org.objectweb.asm.FieldVisitor -import org.objectweb.asm.MethodVisitor -import org.objectweb.asm.Opcodes - -import java.nio.file.Files -import java.util.zip.ZipFile - -def props = project.properties -def spec_version = versionDetails().lastTag - -evaluationDependsOn(':minecraft') -apply plugin: 'java-library' -apply plugin: 'maven-publish' -apply plugin: 'top.outlands.gradle.patcher' - -// = 'net.minecraftforge' -group = 'com.cleanroommc' -version = rootProject.version - -tasks.register("genVersion", GenVersionTask.class) - -compileJava { - dependsOn tasks.genVersion -} - -java { - toolchain.languageVersion = JavaLanguageVersion.of(25) -} - -sourceSets { - main { - java { - srcDirs = ["$rootDir/src/main/java", "$rootDir/projects/kirino/src/main/java"] - } - resources { - srcDirs = ["$rootDir/src/main/resources", "$rootDir/projects/kirino/src/main/resources"] - } - } - test { - compileClasspath += sourceSets.main.runtimeClasspath - runtimeClasspath += sourceSets.main.runtimeClasspath - java { - srcDirs = ["$rootDir/src/test/java", "$rootDir/projects/kirino/src/test/java"] - } - resources { - srcDirs = ["$rootDir/src/test/resources"] - } - } - userdev { - compileClasspath += sourceSets.main.runtimeClasspath - runtimeClasspath += sourceSets.main.runtimeClasspath - } - userdevTest { - compileClasspath += sourceSets.userdev.runtimeClasspath - runtimeClasspath += sourceSets.userdev.runtimeClasspath - compileClasspath += sourceSets.test.runtimeClasspath - runtimeClasspath += sourceSets.test.runtimeClasspath - } -} - -repositories { - mavenLocal() - mavenCentral() - maven { - name = 'Cleanroom Maven' - url = 'https://repo.cleanroommc.com/releases/' - } - maven { - url = "https://maven.arcseekers.com/releases/" - } -} - -ext { - version_json = project(':mcp').file('build/mcp/downloadJson/version.json') - lwjglArch = Util.getCurrentArch() - // Do not change the order unless it is required so - lwjglLibraries = [ - [ - 'lwjgl-glfw', 'lwjgl-jemalloc', 'lwjgl-openal', - 'lwjgl-opengl', 'lwjgl-stb', 'lwjgl-tinyfd', 'lwjgl' - ], - - [ - 'natives-linux-arm64', 'natives-linux-arm32', 'natives-linux', - 'natives-macos-arm64', 'natives-macos', - 'natives-windows-arm64', 'natives-windows-x86', 'natives-windows' - ] - ] -} - -patcher { - excs.from file("$rootDir/src/main/resources/forge.exc") - parent = project(':minecraft') - patches = file("$rootDir/patches/minecraft") - patchedSrc = file('src/main/java') - srgPatches = false - notchObf = true - accessTransformer = file("$rootDir/src/main/resources/forge_at.cfg") - // sideAnnotationStripper = file("$rootDir/src/main/resources/forge.sas") - processor = ProjectConstants.PATCHER_POST_PROCESSOR - - runs { - - cleanroomClient { - client = true - taskName 'cleanroomClient' - ideaModule "${rootProject.name}.${project.name}.main" - main 'com.cleanroommc.boot.MainClient' - workingDirectory project.file('run') - - environment 'target', 'fmldevclient' - environment 'tweakClass', 'net.minecraftforge.fml.common.launcher.FMLTweaker' - environment 'mainClass', 'top.outlands.foundation.boot.Foundation' - environment 'assetIndex', '{asset_index}' - environment 'assetDirectory', downloadAssets.output - environment 'nativesDirectory', extractNatives.output.get().asFile - environment 'MC_VERSION', props.minecraft_version - environment 'MCP_VERSION', props.mcp_version - environment 'MCP_MAPPINGS', '{mcp_mappings}' - environment 'MCP_TO_SRG', createSrg2Mcp.getOutput().get().getAsFile().getAbsolutePath() - environment 'FORGE_GROUP', project.group - environment 'FORGE_VERSION', props.last_forge_version - - jvmArgs ProjectConstants.JVM_ARGUMENTS + '-Dmixin.debug.export=true' + '-Dmixin.checks.interfaces=true' - //jvmArgs jvm_arguments - - // Lazily supply the Mappings target, createSrg2Mcp.getMappings() doesn't get populated until later - lazyToken 'mcp_mappings', { -> - createSrg2Mcp.getMappings().get() - } - - mods { - cleanroom { - source sourceSets.main - } - } - } - - cleanroomTestClient { - parent runs.cleanroomClient - taskName 'cleanroomTestClient' - - environment 'MOD_CLASSES', 'dummy' // Needed to work around FG limitation, FG will replace this! - - ideaModule "${rootProject.name}.${project.name}.userdevTest" - - mods { - cleanroom { - source sourceSets.main - } - tests { - sources sourceSets.test - } - } - } - - cleanroomServer { - client false - taskName 'cleanroomServer' - ideaModule "${rootProject.name}.${project.name}.main" - main 'com.cleanroommc.boot.MainServer' - workingDirectory project.file('run') - - environment 'target', 'fmldevserver' - environment 'tweakClass', 'net.minecraftforge.fml.common.launcher.FMLServerTweaker' - environment 'mainClass', 'top.outlands.foundation.boot.Foundation' - environment 'MC_VERSION', props.minecraft_version - environment 'MCP_VERSION', props.mcp_version - environment 'MCP_MAPPINGS', '{mcp_mappings}' - environment 'MCP_TO_SRG', createSrg2Mcp.getOutput().get().getAsFile().getAbsolutePath() - environment 'FORGE_GROUP', project.group - environment 'FORGE_VERSION', props.last_forge_version - - // Lazily supply the Mappings target, createSrg2Mcp.getMappings() doesn't get populated until later - lazyToken 'mcp_mappings', { -> - createSrg2Mcp.getMappings().get() - } - - mods { - cleanroom { - source sourceSets.main - } - } - } - - cleanroomTestServer { - parent runs.cleanroomServer - taskName 'cleanroomTestServer' - - environment 'MOD_CLASSES', 'dummy' // Needed to work around FG limitation, FG will replace this! - - ideaModule "${rootProject.name}.${project.name}.userdevTest" - - mods { - cleanroom { - source sourceSets.main - } - tests { - sources sourceSets.test - } - } - } - } - -} - -// Patches -applyPatches { - originalPrefix = 'before/' - modifiedPrefix = 'after/' - printSummary = true -} - -genPatches { - originalPrefix = 'before/' - modifiedPrefix = 'after/' -} - -// Dependencies -configurations { - configureEach { // LWJGL2 isn't friendly with us, so pye pye - exclude group: 'org.lwjgl.lwjgl' - exclude group: 'com.ibm.icu', module: 'icu4j-core-mojang' - } - - // Don't pull all libraries, if we're missing something, add it to the installer list so the installer knows to download it. - installer { - transitive = false - } - api.extendsFrom(installer) - - lwjglNatives { - transitive = false - } - - testCompile.extendsFrom(lwjglNatives) -} - -dependencies { - // LWJGL - compileOnly "com.cleanroommc:lwjglx:1.0.0" - installer "com.cleanroommc:lwjglxx:1.1.21" - lwjglLibraries[0].each { - if (it == 'lwjgl') { - installer "org.lwjgl:$it:$props.lwjgl_version:unsafe" - } - else { - installer "org.lwjgl:$it:$props.lwjgl_version" - } - runtimeOnly "org.lwjgl:$it::$lwjglArch" - - lwjglLibraries[1].each { arch -> - lwjglNatives "org.lwjgl:$it:$props.lwjgl_version:$arch" - } - } - - // ASM - installer "org.ow2.asm:asm:$props.asm_version" - installer "org.ow2.asm:asm-commons:$props.asm_version" - installer "org.ow2.asm:asm-tree:$props.asm_version" - installer "org.ow2.asm:asm-util:$props.asm_version" - installer "org.ow2.asm:asm-analysis:$props.asm_version" - // Added back deprecated features for mods to load up properly, hosted on outlands - installer "org.ow2.asm:asm-deprecated:$props.asm_deprecated" - - // Hacks - installer "top.outlands:foundation:0.19.8" - installer 'net.lenni0451:Reflect:1.6.4' - installer 'net.lenni0451.commons:unchecked:1.9.2' - installer 'org.javassist:javassist:3.30.2-GA' - //installer "zone.rong:imaginebreaker:2.1" - - // Regular deps - installer 'com.ibm.icu:icu4j:78.3' - installer 'org.jline:jline:4.1.3' - installer 'org.jline:jline-native:4.1.3' - installer 'net.java.jinput:jinput:2.0.10' - - installer 'lzma:lzma:0.0.1' - installer 'java3d:vecmath:1.5.2' - installer 'net.sf.trove4j:core:3.1.0' - installer 'net.sf.trove4j:experimental:3.1.0' - - installer 'net.sf.jopt-simple:jopt-simple:5.0.4' - - installer 'com.github.oshi:oshi-core-ffm:7.3.2' - installer 'com.github.oshi:oshi-common:7.3.2' - installer 'net.java.dev.jna:jna:5.19.1' - installer 'net.java.dev.jna:jna-platform:5.19.1' - - installer 'it.unimi.dsi:fastutil:8.5.18' - - installer 'com.google.guava:guava:33.6.0-jre' - installer 'com.google.guava:failureaccess:1.0.2' - installer 'com.google.code.gson:gson:2.14.0' - - installer 'org.apache.commons:commons-lang3:3.20.0' - installer 'org.apache.commons:commons-compress:1.28.0' - installer 'commons-codec:commons-codec:1.22.0' - installer 'commons-io:commons-io:2.22.0' - installer 'commons-logging:commons-logging:1.4.0' - installer 'org.apache.maven:maven-artifact:3.9.16' - installer 'org.apache.commons:commons-text:1.15.0' // Some old classes in lang3 moved to here, wtf - - // xz in common-compress need this to work - installer 'org.tukaani:xz:1.12' - - installer 'com.google.code.findbugs:jsr305:3.0.2' - installer 'org.jspecify:jspecify:1.0.0' - - // Apache HTTP, 4 and 5 - installer 'org.apache.httpcomponents.core5:httpcore5:5.4.3' - installer 'org.apache.httpcomponents.core5:httpcore5-h2:5.4.3' - installer 'org.apache.httpcomponents.client5:httpclient5:5.6.1' - - installer 'org.apache.httpcomponents:httpclient:4.5.14' - installer 'org.apache.httpcomponents:httpcore:4.4.16' - - // Netty - installer "io.netty:netty-codec-base:$props.netty_version" - installer "io.netty:netty-buffer:$props.netty_version" - installer "io.netty:netty-common:$props.netty_version" - installer "io.netty:netty-handler:$props.netty_version" - installer "io.netty:netty-resolver:$props.netty_version" - installer "io.netty:netty-transport:$props.netty_version" - installer "io.netty:netty-transport-native-unix-common:$props.netty_version:linux-x86_64" - installer "io.netty:netty-transport-classes-epoll:$props.netty_version" - installer "io.netty:netty-transport-native-epoll:$props.netty_version:linux-x86_64" - installer "io.netty:netty-codec-http:$props.netty_version" - installer "io.netty:netty-codec-http2:$props.netty_version" - installer "io.netty:netty-codec-dns:$props.netty_version" - installer "io.netty:netty-codec-compression:$props.netty_version" - installer "io.netty:netty-resolver-dns:$props.netty_version" - - // Jakarta (javax in Java 8) - installer 'jakarta.xml.ws:jakarta.xml.ws-api:4.0.3' - installer 'jakarta.activation:jakarta.activation-api:2.1.4' - installer 'jakarta.annotation:jakarta.annotation-api:3.0.0' - installer 'jakarta.xml.bind:jakarta.xml.bind-api:4.0.5' - installer 'jakarta.inject:jakarta.inject-api:2.0.1' - - // Logging - installer 'org.apache.logging.log4j:log4j-api:2.26.0' - installer 'org.apache.logging.log4j:log4j-core:2.26.0' - installer 'org.apache.logging.log4j:log4j-slf4j2-impl:2.26.0' - installer 'org.slf4j:slf4j-api:2.0.18' - - // Scripts - installer 'org.glassfish.jaxb:jaxb-runtime:4.0.9' - installer 'org.glassfish.jaxb:jaxb-core:4.0.9' - installer 'com.sun.istack:istack-commons-runtime:4.2.0' - installer 'org.glassfish.corba:glassfish-corba-omgapi:5.0.2' - installer 'org.openjdk.nashorn:nashorn-core:15.7' - - // Mac - installer 'ca.weblite:java-objc-bridge:1.2' - - // Kirino Engine - installer 'org.joml:joml:1.10.9' - installer 'io.github.classgraph:classgraph:4.8.184' - - // Mixin - installer 'com.cleanroommc:sponge-mixin:0.20.12+mixin.0.8.7' - installer annotationProcessor('io.github.llamalad7:mixinextras-common:0.5.4') - - testImplementation platform('org.junit:junit-bom:6.1.0') - testImplementation 'org.junit.jupiter:junit-jupiter' - testImplementation 'org.junit.vintage:junit-vintage-engine' - testRuntimeOnly 'org.junit.platform:junit-platform-launcher' -} - -test { - maxParallelForks = 1 - useJUnitPlatform() - testLogging { - events 'passed', 'skipped', 'failed' - } - jvmArgs ProjectConstants.JVM_ARGUMENTS + ProjectConstants.COMPILER_JVM_ARGUMENTS -} - -// TODO: Include? -def extra_files = [ - rootProject.file('CREDITS.txt'), - rootProject.file('LICENSE.txt'), - rootProject.file('LICENSE-Paulscode IBXM Library.txt'), - rootProject.file('LICENSE-Paulscode SoundSystem CodecIBXM.txt') -] - -def changelog = rootProject.file('build/changelog.txt') -if (changelog.exists()) { - extra_files += changelog -} - -// Binary Patching - -// We apply the bin patches we just created to make a jar that is JUST our changes -['Client', 'Server', 'Joined'].each { side -> - def gen = tasks.getByName("gen${side}BinPatches") - gen.tool = props.binary_patcher - tasks.register("apply${side}BinPatches", ApplyBinPatches) { - dependsOn gen - clean = gen.cleanJar - patch = gen.output - tool = props.binary_patcher - } -} - -tasks.register('genRuntimeBinPatches', GenerateBinPatches) { - dependsOn genClientBinPatches, genServerBinPatches - tool = props.binary_patcher -} - -afterEvaluate { p -> - genRuntimeBinPatches { - cleanJar = genClientBinPatches.cleanJar - dirtyJar = genClientBinPatches.dirtyJar - srg = genClientBinPatches.srg - patchSets.setFrom(genClientBinPatches.patchSets) - getArgs().set([ - '--output', '{output}', - '--patches', '{patches}', - '--srg', '{srg}', - // '--legacy', - '--clean', '{clean}', - '--dirty', '{dirty}', - '--prefix', 'binpatch/client', - '--clean', genServerBinPatches.cleanJar.get().asFile.path, - '--dirty', genServerBinPatches.dirtyJar.get().asFile.path, - '--prefix', 'binpatch/server', - ]) - } - - if (!patcher.srgPatches) { - srg2mcpClean { - dependsOn = [] - input = project(':minecraft').postProcess.output - } - userdevJar { - onlyIf = { t -> true } - } - def patches = project.file('build/genPatchesForUserdev/output/') - patches.mkdirs() - def genPatchesForUserdev = tasks.register('genPatchesForUserdev', GeneratePatches){ - base = project(':minecraft').postProcess.output - modified = applyRangeMapBase.output - originalPrefix = genPatches.originalPrefix - modifiedPrefix = genPatches.modifiedPrefix - output = patches - autoHeader = true - lineEnding = '\n' - } - bakePatches { - dependsOn = [] - input = genPatchesForUserdev.get().output - } - } -} - -tasks.register('downloadLibraries') { - dependsOn ':mcp:setupMCP' - inputs.file version_json - doLast { - def json = version_json.json() - json.libraries.each { lib -> - def artifacts = [lib.downloads.artifact] + lib.downloads.get('archiveClassifier', [:]).values() - artifacts.each { art -> - def target = file('build/libraries/' + art.path) - if (!target.exists()) { - download { - src art.url - dest target - } - } - } - } - } -} - -tasks.register('extractInheritance', ExtractInheritance) { - dependsOn genJoinedBinPatches, downloadLibraries - input = genJoinedBinPatches.cleanJar - doFirst { - def json = version_json.json() - json.libraries.each { lib -> - def artifacts = [lib.downloads.artifact] + lib.downloads.get('archiveClassifier', [:]).values() - artifacts.each { art -> - def target = file('build/libraries/' + art.path) - if (target.exists()) { - addLibrary(target) - } - } - } - } -} - -tasks.register('checkAccessTransformers') { - dependsOn genJoinedBinPatches - inputs.file { - genJoinedBinPatches.cleanJar - } - inputs.files patcher.accessTransformers - doLast { - def vanilla = [:] - def zip = new ZipFile(genJoinedBinPatches.cleanJar.get().asFile) - zip.entries().findAll { - !it.directory && it.name.endsWith('.class') - }.each { entry -> - new ClassReader(zip.getInputStream(entry)).accept(new ClassVisitor(Opcodes.ASM9) { - - String name - - void visit(int version, int access, String name, String sig, String superName, String[] interfaces) { - this.name = name - vanilla[name] = access - } - - FieldVisitor visitField(int access, String name, String desc, String sig, Object value) { - vanilla[this.name + ' ' + name] = access - return null - } - - MethodVisitor visitMethod(int access, String name, String desc, String sig, String[] excs) { - vanilla[this.name + ' ' + name + desc] = access - return null - } - - }, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES) - } - patcher.accessTransformers.each { f -> - TreeMap lines = [:] - f.eachLine { line -> - def idx = line.indexOf('#') - if (idx == 0 || line.isEmpty()) { - return - } - def comment = idx == -1 ? null : line.substring(idx) - if (idx != -1) { - line = line.substring(0, idx - 1) - } - def (modifier, cls, desc) = (line.trim() + ' ').split(' ', -1) - def key = cls + (desc.isEmpty() ? '' : ' ' + desc) - def access = vanilla[key.replace('.', '/')] - if (access == null) { - if ((desc == '*' || desc == '*()') && vanilla[cls.replace('.', '/')] != null) { - println('Warning: ' + line) - } else { - println('Invalid: ' + line) - return - } - } - // TODO: Check access actually changes, and expand inheritance? - lines[key] = [modifier: modifier, comment: comment] - } - f.text = lines.collect { it.value.modifier + ' ' + it.key + (it.value.comment == null ? '' : ' ' + it.value.comment) }.join('\n') - } - } -} - -tasks.register('checkSAS') { - dependsOn extractInheritance - inputs.file { - extractInheritance.output - } - inputs.files patcher.sideAnnotationStrippers - doLast { - def json = extractInheritance.output.json() - patcher.sideAnnotationStrippers.each { f -> - def lines = [] - f.eachLine { line -> - if (line[0] == '\t') { - return // Skip any tabbed lines, those are ones we add - } - def idx = line.indexOf('#') - if (idx == 0 || line.isEmpty()) { - lines.add(line) - return - } - def comment = idx == -1 ? null : line.substring(idx) - if (idx != -1) line = line.substring(0, idx - 1) - - def (cls, desc) = (line.trim() + ' ').split(' ', -1) - cls = cls.replaceAll('\\.', '/') - desc = desc.replace('(', ' (') - if (desc.isEmpty() || json[cls] == null || json[cls]['methods'] == null || json[cls]['methods'][desc] == null) { - println('Invalid: ' + line) - return - } -// def mtd = json[cls]['methods'][desc] - lines.add(cls + ' ' + desc.replace(' ', '') + (comment == null ? '' : ' ' + comment)) - def children = json.values() - .findAll { it.methods?[desc]?.override == cls } - .collect { it.name + ' ' + desc.replace(' ', '') } - as TreeSet - children.each { lines.add('\t' + it) } - } - f.text = lines.join('\n') - } - } -} - -tasks.register('resolveInstallerArtifacts') { - inputs.files(project.configurations.installer) - inputs.files(project.configurations.lwjglNatives) - inputs.files(project.configurations.testCompile) - - ext.outputFile = file('build/installerArtifacts.json') - outputs.file(outputFile) - - doLast { - def result = [ - artifacts : Util.getArtifacts(project.configurations.installer, true), - lwjglNatives : Util.getLWJGLNatives( - project.configurations.lwjglNatives, - project.configurations.testCompile, - lwjglLibraries[0], - lwjglLibraries[1] - ) - ] - outputFile.text = new JsonBuilder(result).toPrettyString() - } -} - -tasks.register('launcherJson') { - dependsOn universalJar, resolveInstallerArtifacts - inputs.file { - universalJar.archiveFile - } - ext { - output = file('build/version.json') - mmcVanilla = rootProject.file('mmcpack-template/patches/net.minecraft.json') - timestamp = Util.iso8601Now() - comment = [ - 'Please do not automate the download and installation of Cleanroom.', - 'Our efforts are supported by ads from the download page.' - // TODO: Donation Page? (Was LexManos') - ] - id = "1.12.2-Cleanroom-${project.version}" - } - inputs.file mmcVanilla - inputs.file resolveInstallerArtifacts.outputFile - outputs.file output - doLast { - def json_vanilla = mmcVanilla.json() - def json = [ - _comment_ : comment, - id : id, - time : timestamp, - releaseTime : timestamp, - type : 'release', - mainClass : 'top.outlands.foundation.boot.Foundation', - assetIndex : json_vanilla.assetIndex, - assets : json_vanilla.assetIndex.id, - downloads : [ - client: [ - url : 'https://piston-data.mojang.com/v1/objects/0f275bc1547d01fa5f56ba34bdc87d981ee12daf/client.jar', - sha1: '0f275bc1547d01fa5f56ba34bdc87d981ee12daf', - size: 10180113 - ], - server: [ - url : 'https://piston-data.mojang.com/v1/objects/886945bfb2b978778c3a0288fd7fab09d315b25f/server.jar', - sha1: '886945bfb2b978778c3a0288fd7fab09d315b25f', - size: 30222121 - ] - ], - javaVersion : [ - component : 'java-runtime-epsilon', - majorVersion: 25 - ], - complianceLevel : 1, - minimumLauncherVersion : 18, - minecraftArguments : [ - '--username', '${auth_player_name}', - '--version', '${version_name}', - '--gameDir', '${game_directory}', - '--assetsDir', '${assets_root}', - '--assetIndex', '${assets_index_name}', - '--uuid', '${auth_uuid}', - '--accessToken', '${auth_access_token}', - '--userType', '${user_type}', - '--tweakClass', 'net.minecraftforge.fml.common.launcher.FMLTweaker', - '--versionType', 'Forge' - ].join(' '), - libraries : new ArrayList(json_vanilla.libraries) - ] - - json.libraries.add([ - name : "${project.group}:${project.name}:${project.version}", - downloads: [ - artifact: [ - path: "${project.group.replace('.', '/')}/${project.name}/${project.version}/${project.name}-${project.version}.jar", - url : '', - sha1: Util.sha1(universalJar.archiveFile.get().asFile), - size: universalJar.archiveFile.get().asFile.length() - ] - ] - ]) - - def cache = new JsonSlurper().parse(resolveInstallerArtifacts.outputFile) - cache.artifacts.each { key, lib -> - def nameParts = (lib.name as String).split(':') - if (nameParts.length >= 4) { - def rawClassifier = nameParts[3].contains('@') ? nameParts[3].split('@')[0] : nameParts[3] - def mergedVersion = "${nameParts[2]}-${rawClassifier}" - def mergedName = "${nameParts[0]}:${nameParts[1]}:${mergedVersion}" - json.libraries.add([ - name : mergedName, - downloads: [ - artifact: [ - path: lib.downloads.artifact.path, - url : lib.downloads.artifact.url, - sha1: lib.downloads.artifact.sha1, - size: lib.downloads.artifact.size - ] - ] - ]) - } else { - json.libraries.add(lib) - } - } - cache.lwjglNatives.each { key, lib -> - json.libraries.add(lib) - } - - output.text = new JsonBuilder(json).toPrettyString() - } -} - -tasks.register('installerJson') { - dependsOn launcherJson, genClientBinPatches/*, createClientSRG, createServerSRG*/ - ext { - output = file('build/install_profile.json') - installer_tools = "net.minecraftforge:installertools:$props.installer_tools_version" - } - inputs.file universalJar.archiveFile - inputs.file genClientBinPatches.toolJar - inputs.file launcherJson.output - outputs.file output - doLast { - def libs = [ - "${project.group}:${project.name}:${project.version}": [ - name : "${project.group}:${project.name}:${project.version}", - downloads: [ - artifact: [ - path: "${project.group.replace('.', '/')}/${project.name}/${project.version}/${project.name}-${project.version}.jar", - // Do not include the URL so that the installer/launcher won't grab it. This is also why we don't have the universal classifier - url : '', - sha1: Util.sha1(universalJar.archiveFile.get().asFile), - size: universalJar.archiveFile.get().asFile.length() - ] - ] - ] - ] - def json = [ - _comment_ : launcherJson.comment, - spec : 0, - profile : rootProject.name, - version : launcherJson.id, - icon : 'data:image/png;base64,' + new String(Base64.getEncoder().encode(Files.readAllBytes(rootProject.file('icon.ico').toPath()))), - json : '/version.json', - path : "${project.group}:${project.name}:${project.version}", - logo : '/big_logo.png', - minecraft : props.minecraft_version, - welcome : 'installer.welcome.message', - data : [] as Map, - processors: [] - ] - Util.getClasspath(project, libs, project(':mcp').mcp.config.get().descriptor) // Tell it to download mcp_config - json.libraries = libs.values().sort { a, b -> a.name.compareTo(b.name) } - - output.text = new JsonBuilder(json).toPrettyString() - } -} - -tasks.register('extractObf2Srg', ExtractMCPData) { - dependsOn ':mcp:downloadConfig' - config = project(':mcp').downloadConfig.output -} - -tasks.register('deobfDataLzma') { - dependsOn extractObf2Srg - ext { - output_srg = file('build/deobfDataLzma/data.srg') - output = file('build/deobfDataLzma/data.lzma') - } - - doLast { - IMappingFile.load(extractObf2Srg.output.get().getAsFile()).write(output_srg.toPath(), IMappingFile.Format.SRG, false) - output_srg.withInputStream { ins -> - output.withOutputStream { outs -> - def lz = new LZMACompressorOutputStream(outs) - - def buf = new byte[0x100] - while ((i = ins.read(buf)) != -1) - lz.write(buf, 0, i) - - lz.close() - } - } - } -} - -universalJar { - from(extra_files) - dependsOn(extractObf2Srg) - from(extractObf2Srg.output) { - rename { - "deobf_data-${props.minecraft_version}.tsrg" // TODO: Spacing? - } - } - dependsOn(genRuntimeBinPatches) - from(genRuntimeBinPatches.output) { - rename { - 'binpatches.pack.lzma' - } - } - doFirst { - def classpath = new StringBuilder() - def artifacts = Util.getArtifacts(project.configurations.installer, false) - artifacts.each { key, lib -> - classpath.append("libraries/${lib.downloads.artifact.path} ") - } - classpath += "minecraft_server.${props.minecraft_version}.jar" - manifest.attributes([ - 'Timestamp' : new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"), - 'Main-Class' : 'net.minecraftforge.fml.relauncher.ServerLaunchWrapper', - 'Class-Path' : classpath.toString(), - 'Tweak-Class': 'net.minecraftforge.fml.common.launcher.FMLTweaker' - ]) - manifest.attributes([ - 'Specification-Title' : props.title, - 'Specification-Vendor' : props.vendor, - 'Specification-Version' : spec_version, - 'Implementation-Title' : project.group, - 'Implementation-Version': props.last_forge_version, - 'Implementation-Vendor' : props.vendor - ], 'net/minecraftforge/common/') - } - - archiveClassifier = 'universal' -} - -tasks.register('downloadInstaller', DownloadMavenArtifact) { - artifact = 'com.cleanroommc:installer:2.0.+:shrunk' - changing = true -} - -tasks.register('installerJar', Zip) { - dependsOn downloadInstaller, installerJson, launcherJson, genClientBinPatches, genServerBinPatches -/*, 'signUniversalJar'*/ - archiveClassifier = 'installer' - archiveExtension = 'jar' //Needs to be Zip task to not override Manifest, so set extension - destinationDirectory = file('build/libs') - from(extra_files) - from(rootProject.file('/src/main/resources/forge_logo.png')) { - rename { 'big_logo.png' } - } - from(rootProject.file('/src/main/resources/url.png')) - from(universalJar) { - into("/maven/${project.group.replace('.', '/')}/${project.name}/${project.version}/") - rename { "${project.name}-${project.version}.jar" } - } - from(installerJson.output) - from(launcherJson.output) - from(zipTree(downloadInstaller.output)) { - duplicatesStrategy = DuplicatesStrategy.EXCLUDE - } -} - -def versionDetailsClosure = rootProject.extensions.extraProperties.get('versionDetails') -def details = ((Closure) versionDetailsClosure).call() - -tasks.register('createMMCPack', CreateMMCPackTask) { - dependsOn launcherJson, universalJar - group = 'build' - description = 'Creates a MultiMC/Prism instance package for Cleanroom' - - versionJson = launcherJson.output - templateDir = rootProject.layout.projectDirectory.dir('mmcpack-template') - universalJarFile = universalJar.archiveFile - cleanroomVersion = rootProject.version.toString() - isRelease = !rootProject.version.toString().contains('+') - - def verStr = rootProject.version.toString() - def isRel = !verStr.contains('+') - def isCI = verStr.contains('.run.') - def suffix = '' - if (!isRel && !isCI) { - suffix = details.isCleanTag ? '-local' : '-dirty-local' - } - outputZip = layout.buildDirectory.file("libs/cleanroom-${verStr}${suffix}.zip") -} - -publish.dependsOn createMMCPack - -// TODO: Signing -/* -[universalJar, installerJar].each { t -> - task "sign${t.name.capitalize()}"(type: SignJar, dependsOn: t) { - onlyIf { - JAR_SIGNER != null && t.state.failure == null - } - def jarsigner = JAR_SIGNER == null ? [: ] : JAR_SIGNER - alias = 'forge' - storePass = jarsigner.storepass - keyPass = jarsigner.keypass - keyStore = jarsigner.keystore - inputFile = t.archivePath - outputFile = t.archivePath - doFirst { - project.logger.lifecycle('Signing: ' + inputFile) - } - } - t.finalizedBy(tasks.getByName("sign${t.name.capitalize()}")) -} - */ - -// TODO: MDK Task - -userdevConfig { - dependsOn resolveInstallerArtifacts - //noinspection GroovyAssignabilityCheck - libraries.addAll(project.provider { - def cache = new JsonSlurper().parse(resolveInstallerArtifacts.outputFile) - cache.artifacts.values().collect { it.name } - }) - libraries.add('net.minecraftforge:legacydev:0.2.3.+:fatjar') - universalFilters.add('^(?!binpatches\\.pack\\.lzma$).*$') - runs { - client { - main 'com.cleanroommc.boot.MainClient' - - environment 'tweakClass', 'net.minecraftforge.fml.common.launcher.FMLTweaker' - environment 'mainClass', 'top.outlands.foundation.boot.Foundation' - environment 'assetIndex', '{asset_index}' - environment 'assetDirectory', '{assets_root}' - environment 'nativesDirectory', '{natives}' - environment 'MC_VERSION', props.minecraft_version - environment 'MCP_MAPPINGS', '{mcp_mappings}' - environment 'MCP_TO_SRG', '{mcp_to_srg}' - environment 'FORGE_GROUP', project.group - environment 'FORGE_VERSION', props.last_forge_version - } - - server { - main 'com.cleanroommc.boot.MainServer' - - environment 'tweakClass', 'net.minecraftforge.fml.common.launcher.FMLServerTweaker' - environment 'mainClass', 'top.outlands.foundation.boot.Foundation' - environment 'MC_VERSION', props.minecraft_version - environment 'MCP_MAPPINGS', '{mcp_mappings}' - environment 'MCP_TO_SRG', '{mcp_to_srg}' - environment 'FORGE_GROUP', project.group - environment 'FORGE_VERSION', props.last_forge_version - } - } -} - -tasks.register('userdevExtras', Jar) { - dependsOn classes - from sourceSets.userdev.output - archiveClassifier = 'userdev-temp' -} - -tasks.register('userdevExtrasReobf', ReobfuscateJar) { - dependsOn userdevExtras, createMcp2Srg - input = tasks.userdevExtras.archiveFile - srg = tasks.createMcp2Srg.output -} - -tasks.register("cleanroomClientNsight", Exec) { - group 'forgegradle runs' - dependsOn { - tasks.cleanroomClient.dependsOn - } - doFirst { - def os = org.gradle.internal.os.OperatingSystem.current() - if (!os.isWindows() && !os.isLinux()) { - throw new GradleException("$it.name is only supported on Windows and Linux") - } - os = os.isWindows() ? "Windows" : "Linux" - - def activity = props.nsight_activity - if (!activity) { - throw new InvalidUserDataException("\"nsight_activity\" from \"gradle.properties\" must not be empty!") - } - - def ngfxPath = props.nsight_ngfx_path - if (!ngfxPath) { - throw new InvalidUserDataException("\"nsight_ngfx_path\" from \"gradle.properties\" must not be empty!") - } - - def javaExec = tasks.cleanroomClient.javaLauncher.get().executablePath.asFile.absolutePath - def args = [ - "-classpath", rootProject.layout.projectDirectory.file('gradle/wrapper/gradle-wrapper.jar'), - "org.gradle.wrapper.GradleWrapperMain", - tasks.cleanroomClient.name - ] - - logger.lifecycle "\nJava Executable: $javaExec" - logger.lifecycle "Nsight Graphics NGFX Path: $ngfxPath\n" - - commandLine = [ - ngfxPath, - "--activity", activity, - "--platform", os, - "--wait-hotkey", - "--dir", workingDir, - "--output-dir", workingDir, - "--exe", javaExec, - "--args", args.join(" ") - ] - } -} - -userdevJar { - dependsOn userdevExtrasReobf - from(zipTree(tasks.userdevExtrasReobf.output)) { - into '/inject/' - } - from(sourceSets.userdev.output.resourcesDir) { - into '/inject/' - } - archiveClassifier = 'userdev' // Should be 'userdev' but FG5 hardcoded pre1.13 versions to userdev3 -} - -if (project.hasProperty('UPDATE_MAPPINGS')) { - extractRangeMap { - sources sourceSets.test.java.srcDirs - } - applyRangeMap { - sources sourceSets.test.java.srcDirs - } - sourceSets.test.java.srcDirs.each { extractMappedNew.addTarget it } -} - -tasks.named("assemble") { - dependsOn(universalJar, installerJar, createMMCPack) -} - - -publishing { - repositories { - maven { - name = "cleanroom" - url = 'https://repo.cleanroommc.com/releases' - credentials(PasswordCredentials) - authentication { - basic(BasicAuthentication) - } - } - } - publications { - maven(MavenPublication) { - groupId = "com.cleanroommc" - artifactId = "cleanroom" - version = rootProject.version - from components.java - artifact userdevJar - artifact universalJar - artifact sourcesJar - artifact installerJar - artifact createMMCPack.outputZip - } - } -} diff --git a/projects/mcp/build.gradle b/projects/mcp/build.gradle deleted file mode 100644 index 80825a06b..000000000 --- a/projects/mcp/build.gradle +++ /dev/null @@ -1,16 +0,0 @@ - -def props = project.properties - -apply plugin: 'top.outlands.gradle.mcp' - -repositories { - maven { - name = "outlandsReleases" - url = "https://maven.outlands.top/releases" - } -} - -mcp { - config = props.minecraft_version + '-' + props.mcp_version - pipeline = 'joined' -} \ No newline at end of file diff --git a/projects/minecraft/build.gradle b/projects/minecraft/build.gradle deleted file mode 100644 index d65ecc579..000000000 --- a/projects/minecraft/build.gradle +++ /dev/null @@ -1,58 +0,0 @@ -import com.cleanroommc.gradle.helpers.ProjectConstants - -def props = project.properties - -evaluationDependsOn(':mcp') -apply plugin: 'top.outlands.gradle.patcher' - -repositories { - mavenLocal() - maven { - name = "outlandsReleases" - url = "https://maven.outlands.top/releases" - } - mavenCentral() -} - -dependencies { - implementation ('net.minecraftforge:mergetool:0.2.3.3:forge') { - exclude group: 'org.ow2.asm', module: 'asm-tree' - exclude group: 'org.ow2.asm', module: 'asm-util' - exclude group: 'org.ow2.asm', module: 'asm' - } -} - -patcher { - parent = project(':mcp') - mcVersion = props.minecraft_version - patchedSrc = file('src/main/java') - - mappings channel: props.mapping_channel, version: props.mapping_version - processor = ProjectConstants.PATCHER_POST_PROCESSOR - - runs { - minecraftClient { - client true - taskName 'minecraftClient' - ideaModule "${rootProject.name}.${project.name}.main" - - main 'net.minecraft.client.main.Main' - workingDirectory project.file('run') - - args '--gameDir', '.' - args '--version', props.minecraft_version - args '--assetsDir', downloadAssets.output - args '--assetIndex', '{asset_index}' - args '--accessToken', '0' - } - - minecraftServer { - client false - taskName 'minecraftServer' - ideaModule "${rootProject.name}.${project.name}.main" - - main 'net.minecraft.server.MinecraftServer' - workingDirectory project.file('run') - } - } -} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 929ed81dd..ab7e11204 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,10 +1,18 @@ -rootProject.name = 'Cleanroom' - -include ':mcp' -include ':minecraft' -include ':cleanroom' - -project(":mcp").projectDir = file("projects/mcp") -project(":minecraft").projectDir = file("projects/minecraft") -project(":cleanroom").projectDir = file("projects/cleanroom") +pluginManagement { + repositories { + maven { + name = 'CleanroomMC' + url = 'https://repo.cleanroommc.com/releases' + } + // MinecraftForge hosts CleanroomGradle's transitive plugin deps (srgutils + renamer-gradle). + maven { + name = 'MinecraftForge' + url = 'https://maven.minecraftforge.net/' + } + gradlePluginPortal() + } +} +plugins { + id 'org.gradle.toolchains.foojay-resolver-convention' version '1.0.0' +} From 94ab44f195e94ca08df8d7af62ed881e9bdf16e8 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Sat, 18 Jul 2026 03:03:39 +0100 Subject: [PATCH 02/99] Step 1 of Rewrite - CG 0.2.0 - Beginning rewriting `build.gradle` - Redirected Cleanroom Feature Proposal Guidelines to index rather than local MD file - Removed said `CFP_GUIDELINES.md` - Changed paths of some actions' routines - Modified gitignore a little - Removed `buildSrc/` - Rewritten versioning, though still similar to before - Removed icon, fetch from `Resources` repository in the future - Moved Forge's `LICENSE` back to Forge's directory - "Mock" modules to simulate "subprojects" --- .github/DISCUSSION_TEMPLATE/draft.yml | 2 +- .github/workflows/BuildTest.yml | 11 +- .github/workflows/Release.yml | 7 +- .gitignore | 5 +- CFP_GUIDELINES.md | 8 - build.gradle | 413 +++++------------- buildSrc/build.gradle | 8 - .../gradle/helpers/ProjectConstants.groovy | 15 - .../helpers/tasks/GenVersionTask.groovy | 28 -- .../gradle/helpers/tasks/Util.groovy | 24 - gradle.properties | 28 +- icon.ico | Bin 47492 -> 0 bytes .../java/zone/rong/mixinbooter/Context.java | 160 +++---- .../rong/mixinbooter/IEarlyMixinLoader.java | 0 .../rong/mixinbooter/ILateMixinLoader.java | 0 .../mixinbooter/IMixinConfigHijacker.java | 88 ++-- LICENSE => module/forge/LICENSE | 0 settings.gradle | 2 +- 18 files changed, 258 insertions(+), 541 deletions(-) delete mode 100644 CFP_GUIDELINES.md delete mode 100644 buildSrc/build.gradle delete mode 100644 buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/ProjectConstants.groovy delete mode 100644 buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/GenVersionTask.groovy delete mode 100644 buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/Util.groovy delete mode 100644 icon.ico rename module/{ => builtin}/mixinbooter/src/main/java/zone/rong/mixinbooter/Context.java (97%) rename module/{ => builtin}/mixinbooter/src/main/java/zone/rong/mixinbooter/IEarlyMixinLoader.java (100%) rename module/{ => builtin}/mixinbooter/src/main/java/zone/rong/mixinbooter/ILateMixinLoader.java (100%) rename module/{ => builtin}/mixinbooter/src/main/java/zone/rong/mixinbooter/IMixinConfigHijacker.java (97%) rename LICENSE => module/forge/LICENSE (100%) diff --git a/.github/DISCUSSION_TEMPLATE/draft.yml b/.github/DISCUSSION_TEMPLATE/draft.yml index b83a1aa88..d648fcf31 100644 --- a/.github/DISCUSSION_TEMPLATE/draft.yml +++ b/.github/DISCUSSION_TEMPLATE/draft.yml @@ -50,7 +50,7 @@ body: attributes: label: Guidelines description: | - View the guidelines here: [Cleanroom Feature Proposal Guidelines](../blob/main/CFP_GUIDELINES.md) + View the guidelines here: [Cleanroom Feature Proposal Guidelines](https://github.com/CleanroomMC/Cleanroom/discussions/63#discussion-6236162) options: - label: I have and will continue to adhere to the guidelines required: true diff --git a/.github/workflows/BuildTest.yml b/.github/workflows/BuildTest.yml index fa85fd802..97c19c6b3 100644 --- a/.github/workflows/BuildTest.yml +++ b/.github/workflows/BuildTest.yml @@ -10,12 +10,11 @@ name: Build and Upload Test Artifact on: push: paths: - - 'src/**' + - 'module/**' - 'buildSrc/**' - 'patches/**' - - 'projects/**/build.gradle' - - 'projects/kirino' - 'build.gradle' + - 'settings.gradle' - 'gradle.properties' - 'script/**' - '.github/**' @@ -70,17 +69,17 @@ jobs: - name: Upload Universal Jar uses: actions/upload-artifact@v7 with: - path: projects/cleanroom/build/libs/*-universal.jar + path: build/libs/*-universal.jar archive: false - name: Upload Installer Jar uses: actions/upload-artifact@v7 with: - path: projects/cleanroom/build/libs/*-installer.jar + path: build/libs/*-installer.jar archive: false - name: Upload MMC pack zip uses: actions/upload-artifact@v7 with: - path: projects/cleanroom/build/libs/*.zip + path: build/libs/*.zip archive: false diff --git a/.github/workflows/Release.yml b/.github/workflows/Release.yml index 9718b0ab9..7ee273114 100644 --- a/.github/workflows/Release.yml +++ b/.github/workflows/Release.yml @@ -59,14 +59,9 @@ jobs: - name: Publish to maven for mod development run: ./gradlew publish -PcleanroomUsername=${{ secrets.CLEANROOM_MAVEN_USERNAME }} -PcleanroomPassword="${{ secrets.CLEANROOM_MAVEN_PASSWORD }}" -Prun_number=${{ github.run_number }} -Prelease=true - - name: Remove userdev jars - run: | - rm projects/cleanroom/build/libs/cleanroom-${{ env.CLEANROOM_VERSION }}-userdev.jar - rm projects/cleanroom/build/libs/cleanroom-${{ env.CLEANROOM_VERSION }}-userdev-temp.jar - - uses: ncipollo/release-action@v1.21.0 with: - artifacts: "projects/cleanroom/build/libs/*" + artifacts: "build/libs/*" makeLatest: true allowUpdates: true body: ${{ steps.changelog.outputs.changes }} diff --git a/.gitignore b/.gitignore index 3b84fb0a4..6fb5d12ea 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,14 @@ /.idea/* /.run/ /.gradle/ +/build/ /run/ # Patched Minecraft source /module/minecraft/ /buildSrc/.gradle/ /buildSrc/build/ /buildSrc/out/ -/logs/ -build/ -version.txt + module/cleanroom/src/main/java/com/cleanroommc/common/CleanroomVersion.java !/.idea/icon.svg diff --git a/CFP_GUIDELINES.md b/CFP_GUIDELINES.md deleted file mode 100644 index d109bfed2..000000000 --- a/CFP_GUIDELINES.md +++ /dev/null @@ -1,8 +0,0 @@ -# Cleanroom Feature Proposal Guidelines - -1. Be as descriptive as possible! -2. Keep the content sensible. -3. Keep the profanities to a minimal level. -4. Don't spam proposals that are still in draft stage, the triage will take a look at it in due time! -5. Or, just don't spam at all! -6. Feel free to ping a triage member whenever the proposal has moved to a new stage, but only once! \ No newline at end of file diff --git a/build.gradle b/build.gradle index 043f81331..2a244400b 100644 --- a/build.gradle +++ b/build.gradle @@ -1,334 +1,155 @@ -import com.cleanroommc.gradle.helpers.ProjectConstants -import com.cleanroommc.gradle.helpers.tasks.Util -import com.palantir.gradle.gitversion.VersionDetails - plugins { id 'java-library' + id 'com.cleanroommc.gradle' id 'idea' id 'maven-publish' - id 'com.cleanroommc.gradle' version '0.0.1' } -// buildSrc path -apply plugin: 'com.palantir.git-version' - -def props = project.properties -def sysProps = System.getProperties() -VersionDetails details = versionDetails() - group = 'com.cleanroommc' - -if (project.hasProperty("release")) { - version = details.lastTag -} else if (!project.hasProperty("run_number")) { - version = "${details.lastTag}+build.${details.commitDistance}" -} else { - version = "${details.lastTag}+build.${details.commitDistance}.run.${props.run_number}" -} - -def version_txt = new File(project.projectDir, "version.txt") -version_txt.write(version.toString()) - -println "Setting up Cleanroom $version" -if (project.hasProperty('run_number')) println("On GitHub runs #${props.run_number}") -println "Java: ${ -> sysProps['java.version']} | JVM: ${ -> sysProps['java.vm.version']} | Vendor: ${ -> sysProps['java.vendor']} | Architecture: ${ -> sysProps['os.arch']}" +com.cleanroommc.gradle.api.Versioning.apply(project) java { - toolchain.languageVersion = JavaLanguageVersion.of(25) + toolchain.languageVersion = JavaLanguageVersion.of(providers.gradleProperty('java_major').get()) + withSourcesJar() } -tasks.withType(JavaCompile).configureEach { - options.compilerArgs += ProjectConstants.COMPILER_JVM_ARGUMENTS - options.encoding = 'UTF-8' -} +def modules = ['minecraft', 'forge', 'cleanroom', 'kirino', 'builtin/mixinbooter'] sourceSets { main { - java { - srcDirs = [ - "$rootDir/module/cleanroom/src/main/java", - "$rootDir/module/forge/src/main/java", - "$rootDir/module/mixinbooter/src/main/java", - "$rootDir/module/minecraft/src/main/java", - "$rootDir/module/kirino/src/main/java" - ] - } - resources { - srcDirs = [ - // module/cleanroom has no resources yet; Gradle ignores missing dirs. - "$rootDir/module/cleanroom/src/main/resources", - "$rootDir/module/forge/src/main/resources", - "$rootDir/module/kirino/src/main/resources" - ] - } + java.srcDirs = modules.collect { "module/${it}/src/main/java" } + resources.srcDirs = modules.collect { "module/${it}/src/main/resources" } } test { - compileClasspath += sourceSets.main.runtimeClasspath - runtimeClasspath += sourceSets.main.runtimeClasspath - java { - srcDirs = [ - "$rootDir/module/cleanroom/src/test/java", - "$rootDir/module/forge/src/test/java", - "$rootDir/module/kirino/src/test/java" - ] - } - resources { - srcDirs = [ - "$rootDir/module/cleanroom/src/test/resources", - "$rootDir/module/forge/src/test/resources" - ] - } + java.srcDirs = modules.collect { "module/${it}/src/test/java" } + resources.srcDirs = modules.collect { "module/${it}/src/test/resources" } } } -cleanroom { - patchDev { - minecraft { - source.set(cleanroom.localCacheDirectory.map { it.dir('sourceSets/mcp/sources').asFile }) - dependsOn 'remapSrg2Mcp' +var open_arguments = [ + '--add-opens=java.base/jdk.internal.loader=ALL-UNNAMED', + '--add-opens=java.base/jdk.internal.reflect=ALL-UNNAMED', + '--add-opens=java.base/java.lang=ALL-UNNAMED', + '--add-opens=java.base/java.lang.reflect=ALL-UNNAMED' +] + +var export_arguments = [ + '--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED', + '--add-exports=java.base/jdk.internal.reflect=ALL-UNNAMED' +] + +def asm_version = providers.gradleProperty('asm_version').get() + +configurations.configureEach { + resolutionStrategy.eachDependency { details -> + switch ("${details.requested.group}:${details.requested.name}") { + case 'com.google.guava:guava': details.useVersion '33.6.0-jre'; break + case 'com.google.code.gson:gson': details.useVersion '2.14.0'; break + case 'it.unimi.dsi:fastutil': details.useVersion '8.5.18'; break + case 'org.apache.commons:commons-lang3': details.useVersion '3.20.0'; break + case 'commons-io:commons-io': details.useVersion '2.22.0'; break + case 'commons-codec:commons-codec': details.useVersion '1.22.0'; break + case 'org.apache.commons:commons-compress': details.useVersion '1.28.0'; break + case 'commons-logging:commons-logging': details.useVersion '1.4.0'; break + case 'org.apache.httpcomponents:httpclient': details.useVersion '4.5.14'; break + case 'org.apache.httpcomponents:httpcore': details.useVersion '4.4.16'; break + case 'org.apache.logging.log4j:log4j-api': details.useVersion '2.26.0'; break + case 'org.apache.logging.log4j:log4j-core': details.useVersion '2.26.0'; break + case 'net.sf.jopt-simple:jopt-simple': details.useVersion '5.0.4'; break + case 'net.java.dev.jna:jna': details.useVersion '5.19.1'; break + case 'net.java.jinput:jinput': details.useVersion '2.0.10'; break + case 'ca.weblite:java-objc-bridge': details.useVersion '1.2'; break + case 'io.netty:netty-all': details.useVersion '4.2.16.Final'; break } - } -} - -afterEvaluate { - def patchedSrc = file('module/minecraft/src/main/java') - - sourceSets.named('minecraftPatchDev') { - java.srcDirs = [patchedSrc] - } - - // TODO - // The patch-dev source set only feeds diff/copy tasks and can't compile standalone - tasks.named('compileMinecraftPatchDevJava') { enabled = false } - tasks.named('minecraftPatchDevClasses') { enabled = false } - tasks.named('processMinecraftPatchDevResources') { enabled = false } - - tasks.named('copyMinecraftToSourceSet') { - onlyIf { - !patchedSrc.exists() || (patchedSrc.listFiles()?.length ?: 0) == 0 + if (details.requested.version != details.target.version) { + details.because 'Cleanroom Libraries Update' } } } -repositories { - mavenCentral() - maven { - name = 'Cleanroom Maven' - url = 'https://repo.cleanroommc.com/releases/' - } - maven { - url = 'https://maven.arcseekers.com/releases/' - } - maven { - name = 'Outlands' - url = 'https://maven.outlands.top/releases' - } -} - -// TODO: fix on CG side -def mojangRepo = repositories.findByName('Mojang') -if (mojangRepo != null) { - repositories.remove(mojangRepo) - repositories.add(mojangRepo) -} - -ext { - lwjglArch = Util.getCurrentArch() - // Do not change the order unless it is required so - lwjglLibraries = [ - [ - 'lwjgl-glfw', 'lwjgl-jemalloc', 'lwjgl-openal', - 'lwjgl-opengl', 'lwjgl-stb', 'lwjgl-tinyfd', 'lwjgl' - ], - - [ - 'natives-linux-arm64', 'natives-linux-arm32', 'natives-linux', - 'natives-macos-arm64', 'natives-macos', - 'natives-windows-arm64', 'natives-windows-x86', 'natives-windows' - ] - ] -} - -configurations { - configureEach { // LWJGL2 isn't friendly with us, so pye pye - exclude group: 'org.lwjgl.lwjgl' - exclude group: 'com.ibm.icu', module: 'icu4j-core-mojang' - } - - // Don't pull all libraries, if we're missing something, add it to the installer list so the installer knows to download it - installer { - transitive = false - } - api.extendsFrom(installer) - - lwjglNatives { - transitive = false - } - - // Make the joint `main` compile see the Minecraft libraries resolved by CleanroomGradle - implementation.extendsFrom(vanilla) -} - -// TODO: entire dep tree needs to be re-evaluated dependencies { - mcpConfig 'de.oceanlabs.mcp:mcp_config:1.12.2-20260220.202731' - - // TODO - // LWJGL - compileOnly "com.cleanroommc:lwjglx:1.0.0" - installer "com.cleanroommc:lwjglxx:1.1.21" - lwjglLibraries[0].each { - if (it == 'lwjgl') { - installer "org.lwjgl:$it:$props.lwjgl_version:unsafe" - } - else { - installer "org.lwjgl:$it:$props.lwjgl_version" - } - runtimeOnly "org.lwjgl:$it::$lwjglArch" - - lwjglLibraries[1].each { arch -> - lwjglNatives "org.lwjgl:$it:$props.lwjgl_version:$arch" - } - } - // ASM - installer "org.ow2.asm:asm:$props.asm_version" - installer "org.ow2.asm:asm-commons:$props.asm_version" - installer "org.ow2.asm:asm-tree:$props.asm_version" - installer "org.ow2.asm:asm-util:$props.asm_version" - installer "org.ow2.asm:asm-analysis:$props.asm_version" - // Added back deprecated features for mods to load up properly, hosted on outlands - installer "org.ow2.asm:asm-deprecated:$props.asm_deprecated" - - // Hacks - installer "top.outlands:foundation:0.19.8" - installer 'net.lenni0451:Reflect:1.6.4' - installer 'net.lenni0451.commons:unchecked:1.9.2' - installer 'org.javassist:javassist:3.30.2-GA' - - // Regular deps - installer 'com.ibm.icu:icu4j:78.3' - installer 'org.jline:jline:4.1.3' - installer 'org.jline:jline-native:4.1.3' - installer 'net.java.jinput:jinput:2.0.10' - - installer 'lzma:lzma:0.0.1' - installer 'java3d:vecmath:1.5.2' - installer 'net.sf.trove4j:core:3.1.0' - installer 'net.sf.trove4j:experimental:3.1.0' - - installer 'net.sf.jopt-simple:jopt-simple:5.0.4' - - installer 'com.github.oshi:oshi-core-ffm:7.3.2' - installer 'com.github.oshi:oshi-common:7.3.2' - installer 'net.java.dev.jna:jna:5.19.1' - installer 'net.java.dev.jna:jna-platform:5.19.1' - - installer 'it.unimi.dsi:fastutil:8.5.18' - - installer 'com.google.guava:guava:33.6.0-jre' - installer 'com.google.guava:failureaccess:1.0.2' - installer 'com.google.code.gson:gson:2.14.0' - - installer 'org.apache.commons:commons-lang3:3.20.0' - installer 'org.apache.commons:commons-compress:1.28.0' - installer 'commons-codec:commons-codec:1.22.0' - installer 'commons-io:commons-io:2.22.0' - installer 'commons-logging:commons-logging:1.4.0' - installer 'org.apache.maven:maven-artifact:3.9.16' - installer 'org.apache.commons:commons-text:1.15.0' // Some old classes in lang3 moved to here, wtf - - // xz in common-compress need this to work - installer 'org.tukaani:xz:1.12' - - installer 'com.google.code.findbugs:jsr305:3.0.2' - installer 'org.jspecify:jspecify:1.0.0' - - // Apache HTTP, 4 and 5 - installer 'org.apache.httpcomponents.core5:httpcore5:5.4.3' - installer 'org.apache.httpcomponents.core5:httpcore5-h2:5.4.3' - installer 'org.apache.httpcomponents.client5:httpclient5:5.6.1' - - installer 'org.apache.httpcomponents:httpclient:4.5.14' - installer 'org.apache.httpcomponents:httpcore:4.4.16' - - // Netty - installer "io.netty:netty-codec-base:$props.netty_version" - installer "io.netty:netty-buffer:$props.netty_version" - installer "io.netty:netty-common:$props.netty_version" - installer "io.netty:netty-handler:$props.netty_version" - installer "io.netty:netty-resolver:$props.netty_version" - installer "io.netty:netty-transport:$props.netty_version" - installer "io.netty:netty-transport-native-unix-common:$props.netty_version:linux-x86_64" - installer "io.netty:netty-transport-classes-epoll:$props.netty_version" - installer "io.netty:netty-transport-native-epoll:$props.netty_version:linux-x86_64" - installer "io.netty:netty-codec-http:$props.netty_version" - installer "io.netty:netty-codec-http2:$props.netty_version" - installer "io.netty:netty-codec-dns:$props.netty_version" - installer "io.netty:netty-codec-compression:$props.netty_version" - installer "io.netty:netty-resolver-dns:$props.netty_version" - - // Jakarta (javax in Java 8) - installer 'jakarta.xml.ws:jakarta.xml.ws-api:4.0.3' - installer 'jakarta.activation:jakarta.activation-api:2.1.4' - installer 'jakarta.annotation:jakarta.annotation-api:3.0.0' - installer 'jakarta.xml.bind:jakarta.xml.bind-api:4.0.5' - installer 'jakarta.inject:jakarta.inject-api:2.0.1' - - // Logging - installer 'org.apache.logging.log4j:log4j-api:2.26.0' - installer 'org.apache.logging.log4j:log4j-core:2.26.0' - installer 'org.apache.logging.log4j:log4j-slf4j2-impl:2.26.0' - installer 'org.slf4j:slf4j-api:2.0.18' - - // Scripts - installer 'org.glassfish.jaxb:jaxb-runtime:4.0.9' - installer 'org.glassfish.jaxb:jaxb-core:4.0.9' - installer 'com.sun.istack:istack-commons-runtime:4.2.0' - installer 'org.glassfish.corba:glassfish-corba-omgapi:5.0.2' - installer 'org.openjdk.nashorn:nashorn-core:15.7' - - // Mac - installer 'ca.weblite:java-objc-bridge:1.2' - - // Kirino Engine - installer 'org.joml:joml:1.10.9' - installer 'io.github.classgraph:classgraph:4.8.184' + implementation "org.ow2.asm:asm:${asm_version}" + implementation "org.ow2.asm:asm-commons:${asm_version}" + implementation "org.ow2.asm:asm-tree:${asm_version}" + implementation "org.ow2.asm:asm-util:${asm_version}" + implementation "org.ow2.asm:asm-analysis:${asm_version}" + implementation "org.ow2.asm:asm-deprecated:7.1" // Mixin - installer 'com.cleanroommc:sponge-mixin:0.20.12+mixin.0.8.7' - installer annotationProcessor('io.github.llamalad7:mixinextras-common:0.5.4') + implementation 'com.cleanroommc:cleanmix:0.4.6' + implementation 'io.github.llamalad7:mixinextras-common:0.5.4' + + + api 'top.outlands:foundation:0.19.8' + api 'net.lenni0451:Reflect:1.6.4' + api 'net.lenni0451.commons:unchecked:1.9.2' + api 'org.javassist:javassist:3.30.2-GA' + api 'com.google.guava:failureaccess:1.0.2' + api 'com.google.code.findbugs:jsr305:3.0.2' + api 'org.jspecify:jspecify:1.0.0' + api 'lzma:lzma:0.0.1' + api 'java3d:vecmath:1.5.2' + api 'net.sf.trove4j:core:3.1.0' + api 'net.sf.trove4j:experimental:3.1.0' + api 'org.apache.maven:maven-artifact:3.9.16' + api 'org.apache.commons:commons-text:1.15.0' + api 'org.tukaani:xz:1.12' + api 'com.ibm.icu:icu4j:78.3' + api 'org.apache.logging.log4j:log4j-slf4j2-impl:2.26.0' + api 'org.slf4j:slf4j-api:2.0.18' + + // Apache HTTP 5 + api 'org.apache.httpcomponents.core5:httpcore5:5.4.3' + api 'org.apache.httpcomponents.core5:httpcore5-h2:5.4.3' + api 'org.apache.httpcomponents.client5:httpclient5:5.6.1' + + // Jakarta (replaces javax) + api 'jakarta.xml.ws:jakarta.xml.ws-api:4.0.3' + api 'jakarta.activation:jakarta.activation-api:2.1.4' + api 'jakarta.annotation:jakarta.annotation-api:3.0.0' + api 'jakarta.xml.bind:jakarta.xml.bind-api:4.0.5' + api 'jakarta.inject:jakarta.inject-api:2.0.1' + + // Script engines / XML binding + api 'org.glassfish.jaxb:jaxb-runtime:4.0.9' + api 'org.glassfish.jaxb:jaxb-core:4.0.9' + api 'com.sun.istack:istack-commons-runtime:4.2.0' + api 'org.glassfish.corba:glassfish-corba-omgapi:5.0.2' + api 'org.openjdk.nashorn:nashorn-core:15.7' + + // cleanroom + api 'org.jline:jline:4.1.3' + api 'org.jline:jline-native:4.1.3' + api 'com.github.oshi:oshi-core-ffm:7.3.2' + api 'com.github.oshi:oshi-common:7.3.2' + api 'net.java.dev.jna:jna-platform:5.19.1' + + // kirino + // TODO + // compileOnly 'com.cleanroommc:lwjglx:1.0.0' + // api 'com.cleanroommc:lwjglxx:1.1.21' + api 'org.joml:joml:1.10.9' + api 'io.github.classgraph:classgraph:4.8.184' + // test testImplementation platform('org.junit:junit-bom:6.1.0') testImplementation 'org.junit.jupiter:junit-jupiter' testImplementation 'org.junit.vintage:junit-vintage-engine' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' } -tasks.register("genVersion", com.cleanroommc.gradle.helpers.tasks.GenVersionTask) - -tasks.named('compileJava') { - dependsOn tasks.named('genVersion') -} - -tasks.register('setup') { - group = 'setup' - description = 'Materializes the patched Minecraft source base (fresh clones) and generates the version class.' - dependsOn 'copyMinecraftToSourceSet' - dependsOn 'genVersion' - // TODO: move to CG + more robust way to see if setup is needed as switching between branches will be a pain - // Keeps `setup` a no-op once the source base exists; copy task self-guards too. - onlyIf { - def patchedSrc = file('module/minecraft/src/main/java') - !patchedSrc.exists() || (patchedSrc.listFiles()?.length ?: 0) == 0 +tasks.register('printBuildInfo') { + def v = version.toString() + outputs.upToDateWhen { false } + doLast { + logger.lifecycle("Cleanroom ${v}") + logger.lifecycle("Java: ${System.getProperty('java.version')} | JVM: ${System.getProperty('java.vm.version')} | Vendor: ${System.getProperty('java.vendor')} | Arch: ${System.getProperty('os.arch')}") } } -test { - maxParallelForks = 1 - useJUnitPlatform() - testLogging { - events 'passed', 'skipped', 'failed' - } - jvmArgs ProjectConstants.JVM_ARGUMENTS + ProjectConstants.COMPILER_JVM_ARGUMENTS -} +tasks.withType(JavaCompile).configureEach { + dependsOn 'printBuildInfo' + options.encoding = 'UTF-8' + options.compilerArgs += export_arguments +} \ No newline at end of file diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle deleted file mode 100644 index cb9d07752..000000000 --- a/buildSrc/build.gradle +++ /dev/null @@ -1,8 +0,0 @@ -repositories { - gradlePluginPortal() - mavenCentral() -} - -dependencies { - implementation 'com.palantir.gradle.gitversion:gradle-git-version:4.3.0' -} diff --git a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/ProjectConstants.groovy b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/ProjectConstants.groovy deleted file mode 100644 index 83dac7fe1..000000000 --- a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/ProjectConstants.groovy +++ /dev/null @@ -1,15 +0,0 @@ -package com.cleanroommc.gradle.helpers - -interface ProjectConstants { - List JVM_ARGUMENTS = [ - '--add-opens=java.base/jdk.internal.loader=ALL-UNNAMED', - '--add-opens=java.base/jdk.internal.reflect=ALL-UNNAMED', - '--add-opens=java.base/java.lang=ALL-UNNAMED', - '--add-opens=java.base/java.lang.reflect=ALL-UNNAMED' - ] - - List COMPILER_JVM_ARGUMENTS = [ - '--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED', - '--add-exports=java.base/jdk.internal.reflect=ALL-UNNAMED' - ] -} \ No newline at end of file diff --git a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/GenVersionTask.groovy b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/GenVersionTask.groovy deleted file mode 100644 index fbbad3059..000000000 --- a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/GenVersionTask.groovy +++ /dev/null @@ -1,28 +0,0 @@ -package com.cleanroommc.gradle.helpers.tasks - -import com.palantir.gradle.gitversion.VersionDetails; -import org.gradle.api.DefaultTask; -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.InputFile; -import org.gradle.api.tasks.OutputFile; -import org.gradle.api.tasks.TaskAction; - - -abstract class GenVersionTask extends DefaultTask { - @Input - final String lastTag = ((Closure)getProject().rootProject.getExtensions().getExtraProperties().get('versionDetails')).call().lastTag - @InputFile - final File template = new File("${getProject().rootProject.projectDir}/templates/CleanroomVersion.java") - @OutputFile - final File versionClass = new File("${getProject().rootProject.projectDir}/module/cleanroom/src/main/java/com/cleanroommc/common/CleanroomVersion.java") - @TaskAction - void action() { - versionClass.withWriter { def writer -> - template.eachLine { def line -> - def newLine = line.replace("%VERSION%", lastTag) - .replace("%BUILD_VERSION%", getProject().rootProject.version.toString()) - writer.write(newLine + "\n") - } - } - } -} diff --git a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/Util.groovy b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/Util.groovy deleted file mode 100644 index 575f7b81e..000000000 --- a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/Util.groovy +++ /dev/null @@ -1,24 +0,0 @@ -package com.cleanroommc.gradle.helpers.tasks - -class Util { - - static def getCurrentArch() { - def osName = System.getProperty("os.name").toLowerCase(); - if (osName.contains("linux")) { - def osArch = System.getProperty("os.arch") - return osArch.startsWith("arm") || osArch.startsWith("aarch64") - ? "natives-linux-${osArch.contains("64") || osArch.startsWith("armv8") ? "arm64" : "arm32"}" - : "natives-linux" - } - if (osName.contains("mac os x") || osName.contains("darwin") || osName.contains("osx")) { - return System.getProperty("os.arch").startsWith("aarch64") ? "natives-macos-arm64" : "natives-macos" - } - if (osName.contains("windows")) { - def osArch = System.getProperty("os.arch") - return osArch.contains("64") - ? "natives-windows${osArch.startsWith("aarch64") ? "-arm64" : ""}" - : "natives-windows-x86" - } - } - -} diff --git a/gradle.properties b/gradle.properties index ca37b3415..b138773a6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,29 +1,15 @@ -title = Cleanroom -vendor = CleanroomMC +# Project +version = 0.6.0 +# Stage only accepts 'alpha', 'beta', 'rc' or 'release' +version_stage = alpha +java_major = 25 # Libraries asm_version = 9.10.1 -asm_deprecated = 7.1 -netty_version = 4.2.15.Final -lwjgl_version = 3.4.1 -# Nsight Graphics -# Check https://docs.nvidia.com/nsight-graphics/UserGuide/launch-application-overview.html#cli-arguments-details for details -# Available Activities: -# Frame Debugger | Graphics Capture | GPU Trace Profiler -nsight_activity = Frame Debugger -# NGFX path should be something like this on Windows: C:\\Program Files\\NVIDIA Corporation\\Nsight Graphics 2025.5.0\\host\\windows-desktop-nomad-x64\\ngfx.exe -nsight_ngfx_path = - -# Sets default memory used for Gradle commands. Can be overridden by user or command line properties. -# This is required to provide enough memory for the Minecraft decompilation process. -org.gradle.jvmargs = -Xmx4G -# Allow Gradle to use multi threading. +# Gradle +org.gradle.jvmargs = -Xmx3G org.gradle.parallel=true -# Allow Gradle to cache build to avoid recompiling classes that did not change. org.gradle.caching=true -# Configuration cache: speeds up configuration by reusing the task graph. org.gradle.configuration-cache=true org.gradle.configuration-cache.problems=warn -# Set java home when gradle refuse to respect IDE setting -# org.gradle.java.home=/usr/lib/jvm/java-1.17.0-openjdk-amd64 \ No newline at end of file diff --git a/icon.ico b/icon.ico deleted file mode 100644 index 7e9e449f129cbe443d7ed768c7f41d38d3c03c9b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47492 zcmXV11yodB7kx9-00KjIqbQ9cBF)etB@#-fbhp6JCEZGiARvu&qrec#5CQ@sE#2M! z!|!J;7Ocg3cg{WcoPGA*?-Hr5Do=n%g9iWrfue$pCICReU!edD8~kzT_46G3foUc6 zObP(1;_xp`umAv0(OOzs-BnW_!K5fFEy({=P>}l}4?h4XL}oqr)J-~}5T8A4+Bg|&V@J6l^96BjKjnJbrr-e@8uG0DAzzj-#mQ_WCO;a`k#Y6@L_tw<=j!W}M{=i^T!N}zs zX`d@LatduwfB+o>DL>MbM;?(iqzut`?(fbmFfV+yt3sGiK7d=|F0o{$y=Ns=Siw*k zyaNCLK5*Sf0yR}TCUjb9Cqhj+wMBDh%@iaUbno3Vghhg^v;yg^71%_6ADu4 z-fmm`3YgLcUeBHxJetPMeTg^Za~AC_bScS@{XxA~l%5U`AAjqv>4#Rn#c1)HNAr$z z(f-HaU$3Wqb^+&ik{M+kAA_%)O&mPRHDgx>FcJI?Co8PisL+6`*ayQ40#*84q>s2mmdsRQg59lqx+i0FcQIEst8SeYZy58QB~ z#5ShN{z}ynhKniH3nMjQ7LFh`js3+k2&2r1#bhy25J*JkGp$9CX|Qzny5vKP5jF`1 z3atCwE@V$*^d-;Zr+b+mMqNg=$nz%$R%>AVgt|*M7BSL9_2jw^y9p2(AXD>fhiPgU z#E^A)g~Q6L?rwlzRIC|tn4i${?WBqR+i+RqNL`wHC-N)K-kIm?HpLmedc4V9E zz}TSCNYYK1VF>)IT~K_yysnC_bkW^S)*6x~m=11m2>(}hmZT!Jn!7$EXI);V!d3CQ za;5jSnHiX~?;5fbk{Tr`uo3npE~(-%-;IB$h_7g?Fs;Cy|2$uO1a6(Fa&IHvzVFWx ztQuL$l$KB*PZY0~c+vN5sh&)@J7PfvH;+v-Kbb`7v4zAkW-XRDh2u3NG-lw*u_N6YQs;B17Q2B&4nwHV4#W(SgHp42NDBbaeF2^y)8}fvH zk`&<-?G*o%mCsr)Twh3xd4I;&DtSRvVyNx+N$$lL^~GY`pA;oy#q=+liv`OEH9a-s z)X^G7AKQ$sg3iqds>4F%a>EopYMIsdP{%M+^gOiK(?yKCXk%<}*`_};eN}z7sp5fk zLF>WmtMXjh^|NKEWrAhaU*{hX!k((R-KUe8N`uUU1cScZ7~B%vRpT~gmSz5BPo{jP z+NMmmT(&5-Hl}vmow6jexU!Cf?S)U=ahn92G@3%2rrpu&;-h98-fOr={YQjrGsE&n z_J<#jDA#w!cZM0C@Cm>KO6Yq1aai#qd&9l$ zaI3|~UXB}e%p$gm|8!a&hN_aUTS;rBiZ(yWz%rYsN47Ny)PjnZYzb|GL zzAyZG5Wm7}=wYa5c+twB_9gRP_Bfw??{wFzxz+(+V_|VIi}S%X4DlXuXpT=#c-yBo zmRYejR{wGT41b)<>?;d3?z0*o{Gb>;I zo!3bDcWrPW+f!8Uv0nTeq0n@av}%dvU?zk*FO}MIp~EwJ(*2P4p=z>ic`m?&tHeB$+`DD!d27c^iH5oY-BxnrY$r6rxZQuJjwkuIWsx)qb7lM zY7OTEU;X`hHA_y;B!VUHzxMsKN#Xq`ORQ(E2h-$sp(?{4Yc$K%2`N-~i#WYrQN8kN zP-sFXu!Em$C&HH=>(5Kj(6)$&n9iX!@U{0 zhPzEiryj>!l%9CoD!&bU;=C#@+orD8an6a>18T0TEIRDxPK`T^(ckolb_j99v#*nH zM#JYv%b>T|-lxm5!D+vphMlHaR4Ze~{Y%Mf^@HJaGgRS_+KKqe zo9j#7laPZ8Zh0XzNHUqs6f~a!fX_VuK!yOoE$>9G0)RUo0IVAWfN(khP&#EcX^4V< zz;#m4a|Hl=(%Wwc@Gg@I0Llv#Wu&ycGPhd2Guh<5?_J7`8~CZB%bp5^%dsa85g7Kt5_r0pB+%TZk?V#FynJzuy78l}R zE%46Q$I_>%u=#WI=Z9Z7+9jI4uyb<8HLz9-XU{tNKYD)FL+fa`C%V^@(0d@t_urSU zUT+Cuu3<$9VJAQe`=D~6W01q+jscM2g=S^1_+bNvf$(!W;PB}AXCJDQ*qR-N zk1`0Yo?zqPq>RUD&B9rMY6x}6-6XOX#Ff}x?Zm*gJKYMUNR}#d+JF>K8U`Q~3qQ|a z@y>BJn5Y>cRv**uFV&GV`219!oeE-%i9F_8%GvUP0C=Hases>GP1_ZX<*#ttPEswT z#B*>4ssVtIIb_?7ZYBD&=@_*frg>p3R|gDW1#09a3a($oSDG#`Vj|<3%P%}8+;I~B zoaDkKVXZKL5qu;7+g^82*8SBtQjWob92rRoF?=pQDEM@lNw0*jJM?y=EWq#irftXO za*?QuY}SwtMhZz71hJ|JoJvo)-zdKBh!@l3W07>c(L)jga=>eR>Fdd2v^+>rAsvjh z(_1Ia<;|Z)*Se-Yb*B$3Gv%N!>f)ds0Uib?vqE9-@y51D3D52GvcES~I|ayo{TH}w zI}Dj3d42YVfjPv#aK<5E$bBY8qf3oeM-t`*`@jh8xX_=N`9{WfSF2vfc~yrPOq1@v zWTo;gRd^amfnf*CI@C-2ZQ7nRSy-WdE(xn4M$CrGGVgNLzVGo8jNp?->u$oHjpe@n%`>SK%HlaEX@pI%4~`vqa3Qvu5wao&R1mmd z#@VKC|ALj4IJ~~dxWo_rYAc*II8(mS_M6?G{2N`M80JgZha22zS4>p}0ygO9X@N=p z!*A7M^xGMD|AN(C#o6CM`G7(!^ed+*x_QEV##VnK#V~*jfiQ+JA9_|c*chu?8|P+g zoqzD;`NA-EqKx$x;DbtXrvGdgcR#&PhL`4*eL{_LcCf3TPTf3rhQAco#X#}`9rF4U z_C>MJ+-WC>#N4QlirUmTz$6g^QyuZ(lK|JwL_ozxlf+7sgX)u!I4I(NL&ne@;5QE7 z+34So;6L|fmtcifq;(sm&Qz9%vg+$ zLQ(XETl0+epRcsUxsLRo&lCjz#fne0uVaK7@xMB0D8DGV_P=T(4bXg(y%HMQ!3;Ev zx*Kq}JsPSIIkPAu9HYx8kprk8xmYs9&m`bqR)xXL@NtnW?)zT}!zIvEZhT`6zuIh%{ln)dCdywwaNkvb9ar^bnQqy*X(n8t`M+KND7H}im#^%?zpEBcDXPGNU?hBs z00>~Z5W&y@k6eWwe3C)|J$ifY$t(jHk6xcYTgAk(>toS52;=w;Dg znm=>S;{Rg06Lz_L#!H6RKIu?@!`5OHFg_?v21Vq4Im`;2eSVe&0a&44DJxs@f-*h! zw`bIEeD6B)q_xKAhFyO`OlRExN{{*KK4wTq)cGKCTX{n}2&PW_{v%RRkk|2&}$jKP#pI7O<(WOm|Ig*H?;vK{Aqc`SEyT z#UT7nPE*J13;5t0t2vDFjcjdVWo;QG4+8PHew9R;<%9E zf%w+W1bVvtPJmvZh2B6wYTKh-J>axqqp5CF*NqawvM_2g({9tYKyX`j@r3k|0=8|p zQ7(%R3KL5xaLIwk*vePfCDqiX6gdrirliSBRJGyKaufnU$o1bSUZ&Rb7haec^Qk#2aFdWhS-!t}S{iZ{H8Y5g)RJe*v{1zQd% zg`3A1oA+6X)#S#5IJ`+UTtND@0z2CTgHhH{ZUEq==x zmj3-?YfON_tIPJbQoow`+{}oB#ZwDT+o`%O+o>%#`ZZI? zH7(y8E6H%OhW^PL;mmf0h^Qa8JsQHQ43#u54Mogrq7QDzF7||b*{(B9PAPvCLUyy7 zSrc~q=@ll)io_m7mv04@DB6ck zO3F7<7qguwTVGFR1ecNokeP2Otfb-M-p0K8&_4$Y(($o{D<|(?VScR~@%e{kzujl* zL8kD`rw*J>7m=sm;;SA!t8C$griOHY2x>Cn-px5HchLTm~)*Nz7@QsARG951o!!fBguP z_-`&DhR{%u8?X*kgS{{_Z7?w-Sskg?o^YeYbj>G&5BdEg1dMy%6PpfYay^KQ;zFvJ zSoB;se|QP#uHD1NKF`(VYAYLE+jJCse==G3Oy*huqymg^gzgH@{&~%`{p;G7b4@(^ zqC3Lq1BM?f2RHin$#|HKmc9S%GiETAB^~=jiMDekwG;ADBgJJTj<2J;7us#>r*pvO zO8ai_>z>J5sTnCj$kJ1;xOH%L35Ej9y@Gw1b){QDMl^YyC-7g)=AWaP-Vm~~vPQA! zg%AUN5&k4Vx9Q%vNAuN6?4tgNLw&JXA7VWx`SQwh0v7Zq?8S>FVLpK&1ni0zI7P=U z=KEVol2`S=JIhJ&!|;N#JKQ4STx=-}$(GY?>g;`s6d8;0wPA*qPszLD;3IibsgE6= zB^gM8!$Pc^E7d`Zq>=C+0JvF_i6Yp}2#-B~r?Ar(KuJaNYY)Yn^@j zl=}<=Mwai5Xz%QSsC^j3jroEtLcghJO60hn(y$-)lNezHMG`%YB?V{HBvf*|TEgJX zDpl}pr8voI``nncgEMp1cKR3{cCuj=BQ3X+Gx2yN^imN{9v6jc&xO+4O6m`J2z>b9R#Ca40)5B1hlnID;o*{lK)Aa!cNwUh!WAmiH>1w`*~f9gFUa#xAz> zIcHWE37H>XJCB~!9QCsWFt``LewDYL{1`&;q`*N>TOCFx2b-~&K3- zt{EKi$3Cu~8K8J&gvsUSv}zqP#5h@Z^(@;xG5HZxlHqprB5B=JZqk$rGFQCoK>{z1 za@O_~rr%0i8ct3j{uq0bMrj^H8?EB^<$Q42Mg2Y*007Japd|5|t}|bbs zd@AWQz7aRcrgs$*1&6Ts3`jL2;Z7iJ2fM?tWbEttAmDHXjxtW}8KNQDgVoidcao{b zn36e?7Uy7DU+aVO>C2q|RjK&L{-OMmFQUXwcM}5Od67~wyy@~3Oh4p76#z%v;4>fQ zyegxp-?`KKlBf8y_+&@q@a?o{kPHRxrzll`^#3FTEa<(y>2MWDhp$)g$!5Szu0EDyWYIs4 zna*r`36}L1h+1vhB}Y>YSLfb8zYQ2#3LBXlaD?5}k|t{`%EVwYO$WH`d0W^pRarx> zq0DYpC1cgrehY|C#_%=e&;Z7N{eNe;^+vO}1}sQlyJ^*#ikt$5KgSO@NXg$9ErWy% z=AwBQDnqDzI*rfk=e^5@SbYxrpjQ8~%tP~OMyr<|LYi_`=wGv0Mv&YN2@pZRK67y* zG1O8EsbkPM=2}*?*Bc+D-B%0aAZGIMXpcxoAm(~C1)26lFq%lbQy*g2{I|fa!*At+ z5kBBD!+yGbO^6U=xYd}Fd=&IL7`vaX3XAW~6yFq8KHt3jNMJ9-cI;h33g4Oj=&)P-;R}?Y9wEJiCM;r#*GE&gyFMCZdq*@&HJ>->o(n|qh8CiH3#yWy2^Fe(#^meYj z`(e4{iLJZ9R9jG`vz)~Kuas~#NcR)%{F0RlJcVKph*8dUr_CpO>vspJ3e$!krSjXw zYoV21-7w-1FLqR?oXf>dhIhkYrjmAt8#uZ?d zJ88$jbc80MRW|s1#)&IbMSW{dkb$A)Y`6&rI7}aRYfK-1BDfooy~J*dV2YvdJ3C!V+>U1s^15<+)-V6g9p?b`Qp_)YiAj$pL_Z| zINhei`)8s|A+by$+cp9;C+rk#Z-c|R(bfO)ORf891K+Y&u5Me`dfH3vRw1oN;YGZ`glE7>rQnM1^Y_Ie4<#Sv0R4<-MgV>h*Uo;jw4$MkMOD!xNXa^m4$KGxkG zPhMZ`@t{gt6#nIoqJPjqn z7~djzN&Y zhu7IxuurxU6+(8NKqQ~5)&dIaSJBzF%mZngk;o=BfUMRB*~Pol2nBQ3zx)tDf>?!% zSUmyDk+tC{p{vJ+m)3bNCMHHPHlG%>$lhue9}-TuOPEd{r{>RGjBI~UfJin^A;&4w z;4j`zeED@Z^08hLyX^Tsvn!X*i*tz|a^su+Qx8iQ*qAU=+aFa{Rt_Cx1+tmH0OEW8 z4Q4TLa5=u5stB+e+4gIIGXuJQYYzuz>+h~vN58}GFr$*3sJh|vQe9=OrF;sBtF;?( z&i0ozXaAZNXj%m;(8L9DLF}$4M(h~q>i){1Vv`dS-PG$W5x?c1x^l%@=Z&`Vf0@@A0t|(Fe^8OJh97gQ~D_rQpOKuu^^t&zry#uIL zqAvxeBtLtJwJM{b>I_D~23kE(uf`vVxAnblogC z?UY2s3vFw;ez3_%B-6NSKWU1Xu> z$-~8U2+HZ6-^3Z9*T@R#xOfTTlL>H|5BB`9O)bgE27B2nH;f;zfOt!|IZy3qAA1FJ zhQB^muJ9FlL3$jsy}_(HOj_6PFE}bwl&;w$PC$!VS6BD6xeGz1{=?N7TsIJa`+=;r z5ehKc*1p{FptHK)U?fq|^o0d@Jz!=1shulF0E)D1C}PAyevfnzXmh8#NPDbLeB}E< z9pqO(kFo+oLqmV<+?gA%z;kvkGi-ec+Ig$K5T=7m5E2*war5cpoyodZjs|;PN14YX z8Y}%GSm=kNIbDLvkFG4vlKDT)#x34(9boIm6--9ZT}+gPtGRwR5(aH*fcY@pLN9<% zLgFSs@oE5SeFxM$Bmf8cqb?TPGw#n1>G^M*m+9d!0vTG@D0SRzrh2%1>-6Av$KtOVZ|L}pG z0BWSOMUdsa2)1G!R0gw4o?IXuT%7J7{o_oFQ_5tgQ-US?P(AS$2X3y zA_<@82D!ckiY98=FPOlP(V)ezR{OFn+RJg8lUB6vzEasiRG{14z|TKhOWy{nKqNUS zl9-f$(vYfvapwTdo4mniqnb5; zf{+<>QjcfwfR~V9vYilCF5#$7a>g>Ir z=bLqWk?$$dNE0*53Mut2*m2hvt0ch$BE^b_J6SY0W;* zg3wet6%hmPaFHMu?bz48l$f=tEjrmiVQn2zHX6PUHD2`j{n>K=poVxp&Rvh`fw{`m z+u))<5{}gx3Dm|%DBQ)Vh1@}$F~E=v z0QR~2EgIX@`iHu;`|Izvj4KlGJ50Urd1CK9gN5V>5G{|6n8zL87tMAjUqqKKTYQ?* z!vuED@L6P}NB9#Th9V%~2qcS^m4wmPa&0Ug`CPdQ?CpYFI|>WgZWQok@{(Y>juZ?& z^sOz;V`knrncYwD&5yNT#5dzX;>~$QNZ~x33*J_1-CsUkgTTs=H19ibbio;G8XmXuZ>LZ zh%XxaWK1Mn2bf+e>Wfmn4JbX|g%;CgKL^om3_x;Mgrh;Bc@P|fVCW#d2l>D)c59W4 zwaMudhi&b%{Pz zt-q2>l|Y5CcMffZZ?Ekig`YduQGp<}O0^KP)Ej36ak+QrP6TKICt`MhFGkvL^+(ff z+Zz!XD$uaN`3F^BGNf&KSrND?&mJ5X`lL#5$`s5x+i96&>wbZ@MCfTBBmU}R=})^f z-oe1Y0Dx=@JtA<*UcW3m=BsnX1|yaNWVR+M&Rbptg}u%zPm6u@>jkkWuk(WUDXGxK zGa!P^X(kNYD>HmGyJgcGQ$vu;H11~`$V=W>f$uvd6t##=L~SR^$>$kp{kQ?J&ntvu zUDNERMJ_B(#BcnI^#^6wgC`zJO^P|(2oXNms1}I-iDOHxz5BXXHnBOPx|EIEML{Z= z_xEDyHzA>;{7y*G-xSsXDyhlLE_Nl{uB1YHTyfs3QU8A=8y zvOot-f>8o=Y~9@uqGNL14&I&w-qnSByw$x2Vjl`|?Tqs7{^}cxS(dI`y|||W;cCNx zFoQ0dpS|_#IVx)v&=o==fUa)+Vl9VNP|kyLg46z0?T<8@EiF#m#ZVhfr;=pR311JDela==fU zpHB)ki!*n;|M>l|Jou|!V&O~}L-Vj_Wj>Lau=(9OlE~#>S_4J9nrcl1uCaUhTbgvp0hsiEyv+>eA`OwnuZ`45hE?Rdu<9 zhBN^%<9RFIj5YQbt!3KyzPH*`Ttd668_mkixcurkL_+_)af_%z8s(&=i4ZWM9ZF?P zKikdCszev@9j}PVduk)%pm}xA|BoJo;&hf8^!Jc(pYNb(6@BvLgx5rb6@Wr>wK$kT zPrZH2=I-{t@W0|Ep2|KR&(B9Z;_6Ux;|!dWC9YGIhPL!dl+ob_?rzU7rp`aj%vF{{ zo*XT&1>@wcgS+Pw5`qC%ZIAe#JgL9Tg0KRqw>kH&x1SEMn?AM-XulRJip?MwU5K+S zvPP}x^~a|YsHw8uy_@mCDJ8#56Eh@7BXuQc1aiT_Q zbsOkM`b(FLy#yI>`@PzIAQ>Ndc6L?)j@ZtME%DQC0#@=OZh`rsK0PP>>b)BaSX)9i zQ=XBFYFP3y9XGX1_uB*7?e~czs28GiP-U*j191Sd<^iD5+Y+_dgrOa++`1_aE>2!%pXe*r@ z;EY^-aOHD<-XeyD|INf^$lR<%NYk6=XGbmN$zkD&p!PvlCfuMyHmE%)y#0dLG)VY| zHrh}*YMY%f(g8MDV9^)0R(X{;uLi3K6H*J`y~&d1UL!WCs>3{Y7ViXWSMm((v2T?o z3!ZfB?&aYsubF{2H6r#xPhW+v`C#;faX1Yh$2c{$0pV(y*iTepd@M;aM9P?p1p?i= zcPNjkotc8ToDAff@Wn61y-81F*gj$+I*!6~n>&r4Wn7@O-wj3GU01(~Y~6!h=+3tJ z!7*1jHmhQl)Xb(rorhETy}HW@Hu<@A`gTh7dMah3u@WDOYMu(mj*hYj<=o@DU<3x? z?L-D)i!~$w5FKMt*qTgS^u)xj63RQ>Mr>(=?__S1stALz`gY3jc02&0j-S1whBaZr z5<~#vs-aW1pF*vz%KfL88$aD!O{s(hY2m^|jAD8B5U_Zem@!{e?;R%$9*AjjO!d=% zQI3Y=mKcLVmWN}5h@Tui$1lF;O;~S3h-A8nWiQJ&pabH9c^^UnNtmoaJYavKB4>Q0 zDQE2Cz!0nYLrP>m&$3E~m&LM_3zA}1!S0UkF1%4=V3XnRg5Mj@j&x;~zZTnI_S!sD zaI2t4@wh7hNFLX38Xd!gqw~k-A2$cZY{|;ok-TRI`nXJ{dG8!ZF<+#mY_Y0b!kC@t zpI=(@PA`9KeB?xKSZBtX`R;u<>+`}7qkY;H+3dqOk@Cq%-Aj2N zBEdh3Z#bsq)ri{JW0$gR(O$xR(K(26fq|vGOspNXdR->AlbTYg29+QfQ~#Zi_1Iby zO#HJQeF^9jeJ^daIH}4WOri0B47}g`(Ed8;dm|awvTi@>==7VtT%zNcG~^r)86og_ z+TmMdhH&P)fzEgHc>2|gTP(We z>!;iNsT`WT zNOeP&(7u1$zApz?v!7I*6DLH@(_`>}RN)Q*0ryS&j05WU)Hwvnv3eJ95>B2Aoc5SM zRiXd%*QL@UA4=&si^;AwVeH~VD6B~N6r=SV`J8!`g@fT62Cmt9L&mO5PKfD;!og(z z06Lc~LEIwWQXV%g^@P~8%OQ&wmo_BdI*UHCizG2TV<}=Z3&IV2H9^>k)^EXje<=$m zaPZT6|4ZJc#I!p9HKSBK9DIj6Yovj@34Wpa7hHDR+`xq?~2OWULiSsZnBdh<#3L_KQ5-)h|Ir#i-V zRA9E@-3>2;p^5#ty*1NB3uMD&_%G(bf_5|1rLEXJp3fo>w#3oYS z>Bq;cuo-?{tWAS1QA0h4lER@1{4g(OG(g3uI=N9b}@|xctypo$!>q3L9&t7kH6jY$K6O z^)-h=kNeCBxev`ToH(PM!kVolm$jE#)MbxV9e(|rtt2azl zy=IA&39oWtFb(XEJyDM)R3_w1!6V%ZPhi8;ssMl?1;987#{toC(BW(#By14;<~Eox z<8SN4LV}O+*{wE~AWGX~2Zw!!4|D=bg>AkvnW%X_=vd+pSO8d4AtcGqX6$(tLh_}d z5cvjaXq)|r;8&oPp^66I+c-SLl z!x-s(mh$|-lLJka+ZUhAm|3bgQ}+JThZ`e{MAD5w2MfDW*lwCxqXR9NE9M+@=XnD2 zuLeuZ*i2D^!oPog@hw7En>pv!<1Jbw^s$kq)y67#)AA#9LB9;&gjD47-_*EykHmN6 zagy0axN<*##L2&aC3{KhX&7v@tX;dkp(BxzO(iFP>=@b!V~>%g4ez0gm~zl*0N#B$s3Qp z(-3;&g8gZQf(p7-9{eQ4e5YBno0!Ol=Hf``&LwI17U{_8z|B4C6E$3WJw85%;`ahI z@vH1|n3)fvS&|j&?Mq>>u0@>`b$e57CJs9~b%~D;5Ihl8og^*WQTFQnE1LS%1qHGN zmy7=FF*@v39qZ5k!sVzy&HH(b1C;BZ7$nv{J#UHxt}ub&U5TgsT=;>-G)o6he^uJJ z>A}ALq>=IW3hI7Em%x3olp^;wqT1>;GUNq@d9sqeBFcFMo}a(xjJkAwb0!TPkj4JB8qj)WhZLN zzc}u}dL}{s4ax|0j+E3buYz-H!AlJ>B1uLF@-a!rj_H{zCSlHJDdwDTf)brhJzJg5 zdD2n7SB@T&d)S_F#Ea|m=Mfe9TJZ^^KyR<@Fv0pg41H6=OWNj>te{rvHbQ}_9!Cr?aR^OO(E-H`VX}t$r|Z;OnnthW4V?^DosE&kl6^jx6>9;I% zrR8Hg!|6b2RH2DS8?_M}gC)Wc)9V@C+bli>XMA5+v^HOeUnn}o<&|mb8HQM3!80-y zDulv&E`=6F^|-2BE5dJ2TURzB(S6{$KqI@-L#gE(;}gd@V<7kJ=I z&IbRn;JbYK+tDd8L$m9q2*4f-c)a(V;vlqRzL-UGgdLH|i*8^nLtCz+?D=$gLR2Q7Us>0&gp(?CntjiC(z#E!LAlHd-a2Aa z8<}Lj>tGNePWTcRn9OGkjhzTg9SxK&v{C=QGGBURYZATkHE?lM-RSk&bO}+ck$j-V zm)zwWzF0l1rtI&ue0Sp?;quELEwK6(oZ+5FF-;VaV<>WBQ3S-UEu)eZ>0)suDEXle zRt>2%v(IcE5LL9hh}_YM4rFkWdkk{)i+5?fPEDAB_Sl0HG>?9s_2{D4v>61XM9A6S;)nVYU7n+DG!4#N$1g$>E!H^F`;^hpZ z-PKjd%!RB;OhO*9!8h2g(^=#&xhS_D#{5#`TN-K)OVESx9zN-L6WFUp623^pVr_wi z<25JM7$1IHWFIkPtrst?1xu+R*-3i}X8Ct*6ISB?#?`2Rrn^mTlgcF^S!>})qU&?k zfO;X-2q<7_m`Y}jfMph#Ki zr{0o@v@~H2zQkP9x^G(<@i=g`LH^cDi)}XMGZ>@4iddWGLul0m|LH7}LrL{S`Xm_6 zZ^U#OPuohR+1!dn#AW4aPOh6aJcHODZAQDsvnI-R`{CmOSPoO0SM zIGc#PuQ`#hx|n+_EDGvAeb47z^n(Px;Jxx3(sHImv2N0LMWSo_NQgE8M6izHcrk2bzx z3%rm0wxS3qR*=wQ%lYze&J%pZhz`d}5Rc`yMknjM%Q`U^qM2<{QGL5Fi@4Od0eJ(l zWYZ4v^?gb}ky0|;BCz2$v>H1hp=Cs)F4ACHP^x4y1nk+4SW;-_i-m`bY-cgl80`D9 zr$anwkGLj&%$dF3pEZn(f4#8`JVW7&?5Rtvmq184C0It593(6H@WWNo6(Y94QP%fg z;J;ngD1J43{+xXJF?N)MgEz3#SCdhZKHma-m5L8dJB9Qr3S@p&qZmRQHuueffZ}zzAWRpp}6NiW$3EaC}6}!dQmNTYV!In z5JAfj<`JdCO1XmC@TwfDna|xqG^U5+*Et4-_L#~6ITf`y3z$c z%{;&7{qU7nB9p3iZnGp3^S*-r*(|R08@l;~bQ9fu>N-^49k(rkbX}8&Uho^!7cl?7 z3qLCDxf#x)RSu%LP_8aaWkd|$u=4(LVP4((m)a!;V*cn?zq@dlyIRcS*xgth42R?Z zwxGG}&ukZLZo>5Gj#Ey#?sBm2XkIQ$%-8Ko-L4A+UGYR!AAw@1aY4;T482QFv=VYo zrc)qXeDeGo-TYlCjk?Gx?rucm?+O&!g^B6_lSJlQ_4{noKZzGzRY9_k(T-vqOUu>E@Ks=N8IL z?d%m@iDz^*P=p*!jyyGZOGdM}qoZS?pGabCM;dc)w0v6a0QFExopSX7z_(pi$B8-8 zQ<-+X?L}Yo#zy7Fu(Oi#Ao5%+_Eb?JnM@$*8aRy%5tuIvzCWZ4w!)^~cqtL+3hcvuj{YFYrF%a1=T4V6#$|rSF7c zhlA#lcg>~83D)V#n*N*eaRm$a7UTAe=M|%LX2Ch~Ff8sq-rdw`oWBW0u#x!2@7U?)j4pj_e zeoflX6tWRP&jag8TKI;e3g!GUh~gZa26(5NXui4hNuUlNaR&Ciqw94U%)gd-w!S#C zcoM0!3ax}=Pg9)I}Ys#VpX$Z z{o@xHc%lTJ9Bc9UL?gbQm9{cNgM9DTLxlX7cXiEA&)eVTj(H7iiIbC^I*4-W zc2h<~>hm@G=IABeMRV}Z&b?}B3Soq^7wdfg5-IHamH&Dg7xa8aEEdUC@xmAP(X!W|kdRw-QDq;&f zJ95JtqXR#eDf2DFvm_m?wQ6XI0|JK~{7V$i&SV7n5%;`PtugR0>g@Y>OsvNRk7lK? z5Y&ryZ6>n0SgcNCfkVWg$J_;tTf;6c!cVvvFPAnUI9@@`k7u}6xe_wLq7_Z^E`X5j z`)Em-t&{;tH;1aNLiTBnsDrkTplCV$seZz@51p&P2$KczdIU63cu`%Br>1U>eBUa5 zONpw}@n1{}|9HKSbRgF-3%y7j)kMTu>Lb$H4l29a@-i=&Ev(g+qnQcvucjR#qBnt@ z;!pa4zLo|JBxoFKzlt8PWAt1n-2IHJ-R*CACEAq!ocSKvXwq`#xrisei!6V5>+t9- z>m;lw#H?pOO#O@PLFi>|WeN}~hMi`{DnZ_@wg&llv|*O~2M#90Z_Y-T**ACL#Vur| zsfF~iqKbyRUpu#6+S_AUIH1tt|Mt<;Lz?-{4y(UjNEJ^37XBR5B}NBrLyED?N3K*f zH8jR}CEQ@{O;^{Y)MetiRwlrya9C_mO$@65np*GRV_u)3p9lxq^7bq$q^Lo(mBB|R zaER>`P)>cJOt;7WyHf>B%l(lz8--A^g7J}NV?3qRq6Ix=83g`Z; zJZLg_<}RUEsQzJtF-A$SS~SOWVI@yC3?AwyRI?iKHyn7#NIFywC3>E72?YC#8~>q; z3ZjMSrNj6(jk<5OxQ+~N?j+Lid$el20Wt_q&BE=H{=K z64$mh&)!rPUvG;A7(A1u-BGvpzyfWT;))Qj)4{zYr>7=OAlCjqDZW94z4zIAV+{Tl zRBn85TvIyGiL?#eFS~ZGCG*4nQf8GNBf`L8eqAD(zOPza?^JV?o>0h)j7OziGNryQ z#}O~0?c&4pDd>60)kcG{1~--qT+w1FW1t3oR}RgG>6MpbpS|TGuT~1_DX%?PMMIy^ z<@i1bE!dkk%l!rnfNu7qtY0wSEn|byFs7lS;-+%M$6Gv(W~I(9)FTNAEoDWlufF^` zl;>X_4%9j5&6q+DGkzt5r`o%Scvh^xXM4pGW);uxEW*L3(KJsRK@TY`*jC#mH7wC= zF%1H@Mr$w+Rl~SGRDhS%*i(HUO)N!LJbEKPp;CH z6ofQ;(VQ|#lqG5UpvWH!1L|88n0w^W<$qKmM%1vOK_%}%u4*0Crg9O}x<|K)t!`4L z8Qm1WZ?5%qR!9IKyg+ua1l!lXwi!{><9JvW5j5Aw81pQucFTQFT=nTA%xXYH4=lyx z{_fiOPE}m-FT<4(D)_53>9r8X`uIU$o?Gx>boAxW=dUeTayroQ zO0QVqFT+1Roh#3qeHRq5W%2?&`>(hRQvG*OV<%%8zx|pZWGABZen?B9gXk9wj3L6s&Ic(p6@2WQtVGmt~`p>Z+YXemn@(l>wH zG0MLAQZWCs5ry(9Q_DO_G>*hmy*+HLpBXvru%NBHvlgEBT)P5lnwg3_=YMp}uT}HG zh8u!xwtJ`y?Uac(nY*Aw74MGbAS!7psBInYHt*h=_(tvRxwH)Ep zANA1&#tCL}xEfZ3?;!eV=UjHG3ykUN3)9fSQUI(=d-TJx3G5@yw@0z>!Pm)+fIft& zO(atj5kKGu#RDlYj*mrSaO1gx z!6Qpa)t}$|OVp{$+Y|t>=Bj4sQkO%!?Sx)?wK=B7~XI$OFq{+jlOG}B!KLA5+#hU?fI@E z;eN&RO1S1i_v_6^+np0>Nhb-+%|e{Jp-KE9p=#U~r61NsE&{3GH1Qz!KjTz_M|bSYKFb^M81r>8v7@V|ET>e-9PZ$ zk!^bfC&<1>y*lCk$~0F6?yBHb>!w^b1va!*(94XYC`W3i@aOdbdpfOHtLXlHva=QS z7-5^8X|br{R5eMhk>r5U<^?;`*zum!D;k zG%4_7bSC)9Df2UdoFl48)m8bB*MF4zH~iE7!313K;k$wOSG2aO-z`HJDlY-`2c!c| zVt}m*<{HdU0~L{^4x#6TD&o_l$m$($wKfd+GV{egKHgQPj58!9FcMYa9D14Zn zs5!zW!z+G87(ht8K;W5~)!g^5S|e!R)kV*q$<4fa@tC|cY5mbKX2YyN#s0mp zq%cagSJCl6h%>1|>~dU>5|L-SqOXd1o1UB1i)643t0E89`eXAGZn5PeS2Q7kVZ2cY zoU#DIj+qHs=>( zqHWpOaO;OFAtSt4k1TmKOkkSmTM$cr0|uyGZQxDQASmY8L@klm$#5IdZKgJUe45YK zR01+P1FO$2gWiFB^1EBuBRdF~fIz-)+>UoO0?D`T{TK``l%gDJ;E8Y)d}j+R|5Oxs zLY8n+ZCm~AjGxvft5F~ z3Ch~cB!gz{wxZMD3atZ`u5McUhvFbLCo%~LPePJAkaIU%Qb!JZZpHx&WjM&Qi7e1L zROKa$H646$RH^ulc`x*#u8Je!?3pOQ)eL>MUlpjO;L<59j5uIU%Z#~1N+0s0^zLXV zKig?(*zz60XNAOtHVA-{aQ}}5{v6${oBu8_3R9WU2Rf^bGBEl@9%;nE!Zqy8VBkJd z5GsUEIe$IaF4wW#PEzg=DuOpzf-{>ovv!U_c5I2GAi%OfKI(WRNau}S7DzK zdAB6RmKia%)Jyo*t+LK6F$AL*`kxYS;+QEdi($T3y-`@Q0kn};8{8tJC8PPL3qqZaQ=?=b?g6p)tad!vql*S^*}s3hV^ zgkxE;uhaw__*}IKQGxlE8cmj-%umtFF-J6fZg#yE7+Glh z&dOw4Tj>#F$b?iM*OG-{kNy!pMGfv&^NgyPy(oX8cB3!zR2_JfS^A7d`>a%SOQ)i} zUl68oulVmy9k4y=3cXi9YF@o3zvPn{757nfeV zhQJ;JP~Vj^H~uISjjC0{4cCpd{#6)B9aa0y$XND_vQzq1ZKVhmLUmx}nRQ4A*Xn+N zi$A?W>d&#iBB^_qdiy%A<*37qyl9U8ZDut2D5P{U3j@woTTVPHQ*T+LV&yIeUTqe< zz7TH2RWg-1OL+`^kr8vgS5H%CB~N;)*Vf2L79498vMCm-X7=|4jv14~yh`91{s>rI z;`p1iR@EG$l=rQwz9%_9(6jN~Uw^L3$qffyaVaSnD2OdnZ4wfiDnq}uq*-D3?m=DY zng8Xt-p=32!Fb3}-*cprd+T>0+Gi=DQ{pfmk)sb1v~U=SaFOO%!Amr9^9K80D$lO!cw)@jdyLBe}k zKQV2ur7~#;LaY%)P0z3VU#K z{z(!ABfmtrma?t^*QvJ9D}IC{b0CdT3^Jof?8AxhC6HV?YQEVyS7YZDbwpE%HGyKt zkE!@Wx*dW{zg`R2_6#vj;4dH9@aL-jN(JWye^bc|HrRc;JmBL9`%JZ})>gHdhhXHv7TUz{Z+~ z0c4y<+yQY$r1rLydH3PlXaqvSM~q*G{;kMzt*B}G@J&t7sIy~YJUh-?CGwB+Z!m7o zrRhO+FVB2~5Ib;!)1y`DMYX^GR&8MC}O+I z;TM+lnr>=3(rmLorgDX$`203$Fmq|F@izoNBlNF8{T}fU&4BJ^>t$>-*l7HB%% zNH3uM0VDVxV4)zRq-|R4RW#wGf9Z3c(Wg_~sBRR$Q@ub` zsw!*Y$vy(rAW|;OAv-M;ekXX2>a2(#jMUUpVGU4J_+4xS#<)WN5s4p~a`DRT$H8qB zSWpW5ScK3^^t16h${51Oc8YVz!h*5VSdWvd!u5#p%9FDo*n` z;&FoWG`llxo7Zp{cRPGE{yb3m(C_h(o$@3k4U9DBNlH)~A$%-6Mz8;m7V}O6 zWrDc!-`#U_6MdQp(9Z3c+AfDn2cy-NWle)<0piBWd;I*O%K*e6STR|eBFXW1?-=r% z@g%HN#m~ZG4?lqemv=fx$ejgYF$fYf%U!W|n;+vbjY+5%2)L^8NzN4ol>9D| zh7O6OKyxWxqK1~Zu{AgIpP`qN{0>4?3*fxq8_@q^((E%SP8_^;w4wsOfin<`pe*c0 zlIox*Wic##TE+Jzoq8-JS=2!tsZSkEjRh?z+O9(2H1PRpr|NDTi>I&0e4$*k$V)x| zmvz1J+fDi^=D~u{qH&DhJRP?hT;-cQFzkHktq=LZdQMa)T_38)$*$erI{6mp{{AeA zr5-swr>{!8qpX|1@;cNI_h;JedqyOx%rrtZue3f-|NU=7Rb`TQaOlKD$e=4GN7jRq zYdVl`M)036FT2%FH+6DqNPlQr?0MOhd3VsuEqh(K)#L_Y9y-wvQ-o-TA?_?8((>o< z3E5VM7FFxvPxpFQv5#(s9M)CJ+oNfz&l4AxGFyl6xZTd$oc7A6J!uPk7)FKG3XPjH zji!A%9*A-ZP>wWw=h7z<5?qx6eklBAspEMiZ%Fthk_{L}YKM6mBDAjhn<4uueQw}o z9$HU{;|pE|#8dhrmz%-a4DqNjO*ZxXP3^!#?XkdhDZ+B5-H(1tShL+|_qJt42`raC z7*ilYyhBPxMwU0d(!?132v>GCRBFvWFJo#3^3tWrjnZv7#*TN`g`Ny?n}ukA=XnZB z{=g|wI~*YOWpX1lcz_uy_2zIuuWw<41i%$Adf}UlGyz|s2YC#M+cj-wAEI58fKS7# z4BLVD#XMHO^(N}x?-n0eXsF96zkrU6X`QZ#6Q+t{rsrXk^x=-*S*eXn2=Obo{$dht z^7)d2vY7mS|LVekF(>hFVRSCzqtM|o>1SXIJ3v9;b%LvBx5>6>)3 z!RsioW3kJ6`~3yFsS05QeilJI80P{?lJK~;^WGG*SAHu@e?a%k0$^@Kc`jEj_QxKj zty(|q&KOyaV}gL)G%r!OTiOHBYqcPIX?$I!%oH|RW#i^X%hB1q!+OgL>59Y(a0{@X zzkTJ}b+fPD_+^dXJP@jg0HyFC0h#A8KU)#X=KO2%^s#m6;05h1?UDL3 z=h;3c{szWdYh$fpG09QM1{4MTVzcE%5EHJPB~_f_{#cMSC^c|%$T%>V>#`J$%G?M_ zQBN|^)K|Rs=@JVEOGF|$e(JZ`t1%>v7Y%sl$PBR+FdBn{ z`9O{W)IM?XV%{_e-90~zVT4yuNe4X%LQ1{elyG(Td{cMCg(OQ^P_7v3m;Nb>9GN(8 zANmY75`X}W3#b=23y(b;@(9TD-HgIwRmAp~fc#lf9^BI_3V2Tjs5~`!SJdk6eu@7J z#AE3<`k#l>qsit659_7RDNa6tvHajDV-|N7WMd{+>_?HW7)QN>l%s-J& z$(>ug=t-~lOPtb!fc!#wN(WfJ{?vNZ;3Rv`eSdxRd#;QCkuQq&eIR_jVr<@~2y84eZA~KgX@2ttlOq`TAg+B#VLSrAa;mqnmlY&s>8A0yOUmEPX6(Cp~MGlu?EE;I|Sm6 zpge#a{i}5|L$CR#+=Zbk<|P3!82z1$-w@{NefP$cYdxt-TsVnn-s}9}FId~yK)|#i z1EKZim|JlK1Rc|zv@KM+B`&TNH3H>fC|)c9>yqj>c8&g`ZyD3kfGt2^=m-BD97YWurbm@W)=b=~;G%4@ zt$0L4(>2c-?c=bUn%BNAai1VnY(MoV{}Q9O-PHCk>a@Cgd9G^@8s8{IkyZgleQI@8 zbFj7d_SY-N(Q8Xrp)sG*#i?_5{eIA8Pm&k%UWF0zu+HBo!8UAgBnAc-fx?6a&x_YT z3lcs4ouIQFopB{9sSwpA!=ZXE2KKyuG08I(0S`&0c(Q2oN^v?yskF2;jSXfN^;D4NNfwha2zoGa&gE0lUx+8O(-)g>c zKR+XNa<#ku^~amKH5O6M1<-aw3PH3O!@0!8OEAnU0B|#>%tx-kr@uiIe5gfzAc?DX zla+FYCqek9^wHnuAmv687$F{|5C0ESOwFy#%mm1uHL}>da~Lc!>;@XLe#I+Zy|I6! zqtk{Y?$OIiRwP@FG&NxqDw%+kfxSuKPvE&wWHFAhRx-CX1n@p(g@qeuaSZ7_=4C6muXpWdb++55AJ zzTOt!+)B@){nsclL#M!D9%=TZ`KUs34p(&i!Vrv>lDSzx4D9Zf)!ZS()c1r0QPF4R z{raK$nPTv#TIsKAVQaPcKXXI)0V<(f3r>th8THrch=4C-oXD@JAScF?$9)k?;~D8O zjTYCNjlYo6DTY$h>ivr2egrlcHQknmVR&Mu5|WlO00-4?S}|dX5)k|)YBYCt)P+%C z$m3YCs$AVKuP;8o^!PiQ{^!wmYgC2j+IG)h*Lm!c2e5YQm(RdK|b^cgBjtE_K}P=T@MhQ}nm5q1vn!mHkQr`erbf z2FbHz;g`*>H&8!JtPU<^5D!!KBE-xEX_f?zXfv)~iqq$0!GQVR(5^HAU!*-2+5$R$ zY#)dmx}X_JB=o-y?YJ2RD70-`W0EZe9;RjJ^)?@JBP(D1vwHnu3n@$-0O{ap)jZ(1 zo5wV=Js!+_71X+&S^<_xQlWG-W_F8Q@782OshAHQ(z?Ti{I94Ch^F^Ai9`y#l_(@hL+DxB#gO ze8g!=_}9E1Mnb0?%wef$(7$&kE^g`s!iMAz=QSg(55zkDDVudeU(La`K~Z|NdlEOs z2QObJGU&@eZqXSTWTOo?Cg-_djA8GFM@*}SNXpLnF%S~suMbo9-m>sJ%494(tOosK zxQHq{q>1!;BO|6_w$YkCnRI?c?zVxKXiHTmTC7Q?^DunU^1;7oe>uWZXBnpl2RSG` z%#?$+OIB{Q_anqczwKRWlsYWyB#~f#t^wZOsqX3#k2!LkwwzZ#KvNlD%VYvn1@YS) z^0+C%Ro&O0niqsa6jMxQiykmGY%l9rD`ctH9Z~iXHpXaW58ffJUZ%wTC2ziNlItqg z6y)jzwKP_&zIhI*trGou>miui3e6q=yzuPd$|ylnfX4pU30f^Z3QB!6zZXQ+aL}dv zST4?-n5s<9<);K4BB68XB0|WV5XH8asO%i+ab`jRy*;en8HxQSVL9$@3U%hh;)#HZU7}FPF$}{d#n`Dc~ z8w4uNcg3wryhBgiuW_BffrW>Mms;21(|#D?*MG}B24SW6vN<^EqA8U~mr+1GLU%>8 zk_}M3>uR*A!++B}0Ilh+WM8Cp%%Sd>KSzt`cECpnxl2Z;gjQOiDbr=Yz$r!OP` zd+zU14C#7#9W!x*g@pz4VH&Gx`8KLBsV~bc)7sj4;IQj0fTR5VpoN;G*mTT|{Nmkv zIDgd^V9=nrQ?j5^F%0Xe$~CpGs+t!8zXqWg$#ioaOPa0iR0l>sRF&NFoUo;5aT9rm%pA5 z=MR8>iX~e?KHMs5ZcgjQlWYZW32J*ipi9^3!|*r5q0jP%JNIy!{Tz{nw0G?$*GjKj z|E$4+`|o&eN{Yj3Dw&Cm0lNqvf?=1Xdyi%xIyJTPH6JD^^P0k zUG_KE2H;UST(YEe$}+4A$+!M@1Tx67Fd(azkxjS#NQ|wp@f0E@Op-09NP-MH(W?Ej z?AQk<1&={yZwSDhO#N$&{|p>_)*slYx0Ll^BkuofE&6V@_%)<$V2uI9b&tbzDKVz` zUlUtQl{F?!ZC?yup|U|mXC(Hw9C9IHoc#+!rw4?_Hr<1p{ck{E%utyLW05n;u@2)h zQu=Y*e&4pTLMox``Ao@2Q22k(({%)Fkoh9>_Pc4QJ8HU-e4fATE`f7Yw20WW_4f|x z%u^%UupB4~?tR9oepFa`*ElmCFI}MiahnO_(RKI`bqJ%nhaJ0@3vS$~r zlrO!@KQ;>I#qn1xJWKd@zV@0GS?2CXyN`zP`$KAdupTzE;M-@3cIHLkHN38os!UrW zG~RiZz8A>wxO*9z(l3LaRSZfw0x#{q6Y8-6D>dL1kI7%lHtv*t$aq}aXL_yO_dO4S ze|!367cQPSQaDApbe&VHcjW9pvCF;ufC8iSPWQ37UF<#mJK1E9II0?XcTS;_7&V^j z+8?aoqEt)G{2d~13!7Q(ec%}Kpr@B5s$$d#0@ogzlvY}I z{@I)yi^ZBgehG=uP@TxSLY2H4&R|Nc{x$vkvu39EvWJoeJo2MW0`A;D^~;L(ZM8pg z`wQPBlfh&ixGyQl1S$5mJJn(v8NguPHA!xM-Caao?&`%Yn<6o8)=elrB3`dCBBi0p*VoE6~G-=8V? z^Lf{0r`UxypTsm$!{jEZw&}GtH;^9zMH`O?Pt=|K%r>swet2Dml3uRj;l62gFN+rM zbrKc6>w`Qu*-Ho2!(w(HI*krsI6=&53>NZdqpyZE?cE)cUAyC4pSzYASsQM0by+IJ zC70`;@>h<>H-N{TxFX+^1xWKaX}W`zRKv+jk@vX^HJ`>9Ri#a?&+YB{AMV!dGwx-= zv=nN@4iFuhq3;N!SfjV^ZWLUWe*5TbH*CECd;OpGvb6k2 z{W!*V%W8D5aWf%<(x$nhcylyE2%)OZeks!>viVMU2o&S@Ln};jLID6ad`*YEYH<7~&0zuYtbpfd z4cB?77|+Vp;g4igNk|m0=8&M?8s23eJ)AD6Z}nX4-Elw}wk*jR=sikDWh7wZLD&+$ zlzQ82bT)pH{bLv?DvNtTfi0>aI0-U^wH-s9eo{x84?ky%>kBxs+OL^YEi|5~-6Tl*T7FR{kc^o)}zAuhhm{g@vB#s*JJ z9o`df7*gj~eg~Z#1^8EEe@D4lqMZ6CtXnE4qO&ZCG_muHOZ0p2wD?rO_;_-~;86MO z`3kS!K^L_Nr-4Lg7J1x_m+1I4c89np_lt~iv5$HVO7{^O? zRo+Y$8N}q+lR~KZ^(Kb5{>JBMP~%^v+IOcxC3~rv1kJg^cU~#q(%6}$Gx3f0YZ9rA zN{X{v01@=dKL+#wpcEXk*ga10+^~NkOzV1mqr7A6X|);jxoHft{DrY}q)Yf%wKHJp z+kUal!q0>wkPlsKHu~wUiCwg`h38ar1=&7?jS5gitorJFRueGPGU#>SAAVsKv>73Ugv>c7`6qaI>8ig{VUrS2WB( zWp3y{Z~x^!1V3@4$!zUPy9i<4>HO9n8*9FW)Rv7PDo7iL<$xVXFDPsNTtBRT#=sR~ zlX|u4qu0CD-$G}J3mMV+@bg5c!l61FYil0v?wdf*($4xqmq(^)_8R{ezCU0W*Sr z;%=J#726HT^h-Cz#r4U5zyP2Qj#=I@AXWl*!7-s6keKv+<Phx6v||6(nTck;aqE zLXLA*Ap!7ESB1~w`br=AekyHSfazX%Lu3dPz}$r${pFpAzKr-?r+dBg^+_i$RWDb_ zRM{N~I%Mdu4@=SI_tWGt#HOEYgk3vw-q_PJNoIq_G-}V}y(**C=O>)L!tf;6fB)7w@Cf7?o#ugO^7Nz6 zUk*s5$oiuneSnOb6#9Z9brkz@CIp`%{*{{vGNwj?z(>nDVp!`t?C&KbwI6zR8U>sm zza_oco9Rs^G%;i=bY~BGL1$HO=-E;mcniHLKonRTS{27uUu3f=!I+gv7z*0aI_pe%OKxojcl)vK zGFBfTzHg^=bN_PC*&J9@m4`6DjeX;-h{P)-nGs{Fm{=)p65Xw>5m6@K$N%^Xw!Yhy z`#=_9T&EE0V3(hYXkYzEYzqpQw_%%CPnh0JamXCZy^}rTt$Xb4*$ML8|IceXxc)6d* zhr=y@u0L;RgU(WdK?St>_J`qqdvy1kVu5wfD$usXO)ngx4uI_tNiUTshx}<^ZB9Ef zI@=Zq4Xad6Oxk=x2bh*QFD9&V4$=-IKPW-{0K*ooKrnyLRSfUV?rSr!b-?+mE?!(!FL2W*oB@ z?C~hZjzOjjfyeSC{*Hll9K3Kq1OH;N^)9xFS-vCJ{q{8+A$MxNg7p0CxEBB>=(cNr zZ}o@S(?Y(vI%|auokXaDo3nOMtpTkT0Rc?MF&Z~@c@cYYyKexzDR1tjW6eEVUpE%) z8?o_0HR4?0G|0TofXrLNLPg5HZPM26>ffDLj0hs26O=EBAvkyGa)Y|49( z)V%{%SKj0I@|^0k>lbGl;ZUopcDBvV3Y`RU8FtV|m(GJ>4Uc_EliNkv2D#7k@c~pg(vcp-T^>i6}F2H50&?@$N%=LGJ65C*Wc)gE$J!suU1;JJaf4WaLK!%{gL=rF7` zRCPe@N^&<{)ssK7fZ-omN*-d@Q^gJ281G;Dq%$7FK35m}lS8Mb5~smTWjYY8eox)l z(bfdRRNR6QKTCAb*=Bc}zKsBLG!W_qMX+BtV~0>cO0wBR^U}srkEl7#Z|O%_RR<`% z*r~bMY1?%UCPw%Hue2Wxo!OAX!^OJrmc>3|I z3sXwALu@8LD;;YhmbJdY-0K4rjGsGl70B*{p5Ubj_{{e|8YsS|Ro*&%v9KlJW84Gr zjD-5=-sS=MDPwS*AU__TFstexal+Zsl}%;S#W&mJc5lR=j(TXA#sM3aPzvdK|*I$)RsLqJ~ zu!=_q(xM6%yiYs(`h?PM`l=@F+|~Y5*~+0L@oJ_HY;yp>x*-tPhJ88GiGWW3n@%X8 zR6+f*E_@o-W*OS$lS$Z>J39Vc)jDQfGbt5DNb2it{oZkCmx828F)Adc!CyvLwT5V^ z(?sdxqN5+fs5-A_4@_tUsP-te~xksDNhY@u9he zxL!gBHNXsAed;btF`a^tyUS{^)6WYlsS9F%`^`D`zx6)dnqvpOTNR@UQTxY{K-<@w7p{nwh*M(TKo?hA0ctDmxxDf#Yy#A;gPsr+$ zG?UNQ|DSl8*qD(Y{7QOvm77Gs7Ms76sI#iuO3kFqs1eJ&>wXdC$%A32I}dW4t3s=> zYI(C}q|n1f!2eUu2aZI2cVfFxm2KTKJNkf63IrF} zcZv{R?xGOSwRbwj;Gv6oF6_~o63g=u35g#%iPRu*97t7mHDlNT>mCa|(ycY@n*Xi$ zW2I@7YnpujgW7GP(>4F@KS&e0%#Q42jQUZjCrlk!QXE&Qb^KM=2h5AQ9Dt!BcEwV?HhdH?nI>!Z1Knx*{fPDc!L*}udxwnrD zn}g2rxU`ySBS*-|wn+esQm0E6q0MHFF1AsQ6P$Dn6-xkz^1UTAkws~@dNwm)*VB8K zMLFiP*hEZ2$j~Vmu6e+Y9n9_x;GK4eK`W^vG<^)2coBfkl|5MwxD@VMT1_|!r68|m zcD5(8g<;6C$;Cz*q#fchX1Bns2t#rM)+AX!FdJcYZZ4uqzyjCwwFzYhTum1}5Ni(R zypDNoF7Znc0L+)H5fubpJz-fgP?ZnGE!K^BEr zzM(2^!GkdVA=+0&lsZlLOa{ugt5o{R4Wn&CcBUl!=5b6WKPnf|6->$3UUJi0@tOX- z8A$f5DG9rn)U#!jl}QE?+&RjvZ^Yk?|-VEP$&;ZwA7|hUI>i!y9(0I z`NcS*V}pgd*8Zv!dmZKxGV4vL0q8i1zrHg*k0f(JmWtyd);h8Y6`uiN)&yv7B^SNQ zt;#eK#-1CT55Vy#G8W%BpC3QlnXT9oP$ab2J5M{=_iC_MBZPfe#~0By?4$3|0^T5t zMxqOrIY7^{M^zR2DT4^nKP--6+mT{ODC1_m+R|_Jjk7z_!ub-KLy;62a&XmuT4XWF zOjJ~mVP}byo{^?VTS?_HOCI>t5fM)z$+Fub0x*VXiaw^*+kWYdkFlt+j`Cz>ljEkj zygQH?zx|7J$o;e;+7U;N=Gr_+G(rj=7b5%(vrGk&=9JH;9-UIT@cWC9JK@Th_h&AB1PTJ|{ z3}w`ypm)gyF&O>J4zv{7t;=47+}=%>@%a$gfRDPC6Q0xPtPoF=z7Qvxa+b0p53;(D z$ALfcS=r;XcF?@Tm3GxV^L%Sd>dU50wLkn=xu;HOj=^n$!A{m3;`{BMF*|TDLeE6% z)ae<_Ko;qAJAIXIg8Av?`ngXV;D`YRtDuz=ZsZSOcIpTBTOT3m2Hn)qq{$f;Clg+Q zFoE0gwH_5Lrc3cDP9QB|$_ir9pd&_tq0ouMbF6i+NawZd0^(Qr&pt}}_k@jF)o@D3 zo4kJrix>qvd}jUj3N&^Kc|thY9Ts!cUkljBtmUK<7CyH#cI7kjTww42*`dUGY=|e# zYg!#hFn)DK=!i1o7cUIdzDt9+FQ$qv`CRu0sa5FWmB%%%U)vJxS`)yTIB4E;7V>Ea zmYcLi5`srpF3HAvYaCysKEJ`5ScHnwZ?R7aRLqCA;J8X1$h+Gt-?3ItF>W^w~vZvV5y(NYwGM_?Z(SzOeqjJNfx{rZNmW_uNmQSP*9c0 z%^gDj@ACSySq>wj?BC3vjh)_NHmMVx?HYqdop+bgXh{wFCBz?qIJF(r9^m-LWF^*j zxwBWq9`JN+Zj*=B9uN{dF6Q;oX%?40o)8V%mtQP7mbhc$K zQ>hJDw?BWA)g-Xmc8^40d;ZT8YaWWx^#^q3Bh(+*=ZjeuFl`T1CDbPbH{B)^ifaB@ z_LfF~>;+!ic|(g}cnkbiR9{dD7q3#lNq*CV9j!UXr6~I9pw5Xuwes2IbU!>eM5wM< zy1$k6?7z|{>PfZCG%KL29lTxMd6u;&kKa=e*T*^+aXlGzH$@so-fG=GwZS*d8F{}- z=qhGyvpfIE7PNT(Ys41{KFs~e*oC;oEZsm&iFIym>f7Qkr~q#F+Jm>f3<_d+zpk_( zQ+RU%vn$`Hw0qPs*ZV7|*Qn5TV&J&Gky~H|I@e^W7 zJ2LklTXkT_rub5r<3ZSi)-Mo4BOCqu`EW8iOs6$M7ijn-eP-5QeH14vod=d!tYRzTud~_Md8M+T}Ab$*a z=|0-BGB$gd_Y#2f=_a0eZ2RZXC2+r$tZvIv|8%BBRBTiI^UdZ9)o2y>Or8j?zT);= zT%$MRi?|5^)0^N3o>e^eRw$s?cgr}s+!ll+1A7n5Vl}1xIy8iNJYua(N~|1rmJDRB z6%CECF2{kL$k@}_W9O^?UdohZwqVn4`7NE%HT4c6o{RoC4~e{t7W$Q--HnLpr6E9$oiK^D1q)0V2>s}a}JF(v%LN9Xr_K7U!kPW(IVgsi3%75Ww zzt<1O0IG_ids6kMR7gxfh3|Vwwyy35hm9ZR5>S*Qo`JOP5*soSPruVAqL|r}@r)u`ey_3J zL8khpl2F*)x-arfUkB!<|L6fQdW~n-I~F|=8k>rC1>3EY*-HquRI%(uv|WEV!9Q7X zbF03u6{R?HTC0P*A@laLe0=ZRZ)SAU)>$L+0l`HMqPvA;1t)wy5tEL!cXGQAv+Az0Fn) zyJUXjBN8gV_r)6ILV(Sq(`iJ*;=l2ZXcH(8rL0&6t*uIwU*7hOmh^9L7Pv>`W0>tB@UekY<%10F&%LU=Y3X_y#F^5hQ?>YZC!-$>ZNvoI66-C=*N|sQa zzG6dAo*u;Su^7IPlpn;(a_!E0X-I8%%LttH7j!3?Q-R&?s>;#YYy(9Hna(G*pB%&k z>=Mpv*5B~X!?T@D5K>%!QRR$Rv@(S7h8>y3yplN{YHKyO#$o=|Q=5?a6mv(35l8Nd z8;gFVz2bE=f0%<63)*rTwy`JcCdJU*bCRJ)WSZn}YuNUu9hn85)oU9H99Mvpet*WB zuGoFsTn1(rOVXUs!vuZNf5y?Na)eV7i{MfNsMY~nJQdE+EQ!#`z;5` zOB1zz2@lgI$`9T;b+2g=%MFjE4$gQgPdUYA8_0RO9^tFO~RxcOfV3 zLbdn4!f{-X&qrAFZ^#2surA#+-ROU#{@gvJ_^i*jc1~wD^tLx#wpyM;V0F*p$Wnbuu^Y{|42`^uR5gBhW^65*53$#0agn($MXocwrd zc20GbDG3w44@GGmeTWbr)YFog?blS+4J%C<4esf+tfgvea)7qou++kieB$iF$z@jZ zpHmdSrO$2?6$4g^p{+5HGt`6+>2~1vhfwzhw+zfjY7;i_0DdWGLo!}J5vqhd(S=ii zs&~;e_K2WC3Cl&XfK4FQs(-ha4~WH$9|YkuzG4D~u;&$lNSPcmVel$rw3hV_>gO46 zUGBYE(UN*#a+fHjuR*MDdkx`^sU3ksruP3mvCjMZe>GisJk;Iy9}>zoQYy<>vQ%W^ z5weZ!Qk2S886{hhCCk`mY+1AAL9&;UeGS=$?8(0G%h1T!83r@scjx)Oe)Ip_&;5Mv zx#ynqKKH!eKe5U#rn>x$6pq4B$liC=7-Rf=jDyBRc%H*wIf|~_g z;zXwoq%x`jr&l7$;CcM#yYreCZ}5m!9~OkNTAjLHpm;Wj z^%l6@82BwIe#tuVV7vU#TFB3=Wn;1rW-?7MJW2~$b|F}v6IP5*bU+F2PbWq_3KAv# zthHbR^iz54t%8@pDY@IlqI-J8qT%uY$3$f1v+mQeFx*|L2sG{1^+l}fJXVLGlfU`a z6U#FaWBe%eMJyelbv`_&JP=->0=Ar~-^zz`v0BuEmb+F!n`(N$EiAa;l5cTU(Z%3i zED&e8VQO?X?v^nqkaV~z8ay$j$S`L3v=f2z5Ye=b)uN?9y28~WMs438rTJw>1&P@_ zN~Rn6P1g(a9dI#gU_IcC4gBMW^=&sN{l=iqopnvNTVWH?ICzky!C}sbie#T)r3+W# zP%`G7u&C-;j3KngV(B3KTTCv~2fXvW7+iv-+4xaSUVtfh6ovJE@=4B%^fMatA`Nyi z{n=!kLzw}!z=P2{z;n{2OEhKP3hRC2#U=}Zkv@yq?oW#*KOsjN39aYSgao@qI!Zo^ zBGQ*or%zd^9AsN%6M3Fxifhg!A*)~V0@@r>3&Maozgh4xSis-}DRsMpSgYMUm=e1tIp(7wc!#-u8N_O8AFeevDg9b@asX^SN0QL_q;e}+;`qypLLr%KEU=~ zjciimu)6}$&6Ih2mjy;O^Ig`YUj4PA2;^zWUJ)lxp!@zFVmB)Fvq1M6hPtRVoOR(c zNb55P^@UF7oyz#C4BtNAPq4j`BD#&gaULQscA}y0;NvBR%`A-P$=~u%Nh2+E!}Av| z14kTdy{xJ%7_sZ(U?!f~`TIhL2qrCrgOwz#KRUjntOju&O(_mJNIb!z?EcVQm+^F_ z@5M|6-F0Qod!Ea>)QZvfEvnsee-#W=?3Y{?nkoG9urrwK1{7z#5XOrcYisth_GhU% zcc2e?$GqBR)cfuIi~rUBwWnCL4u6)8Es*Eg%&`^HafuJ~$W)h)+j`iXTj#)0W$3Gv zDA|2GIL{Nwz3?2qC`pQ}LNWp9@7hh_6T_hB#t^qR5LcI7Q`c7@UD9Hpe^}A7A<&+y z)8dk7;gZ;axGk9@)TOB%r7F57JC}<5@geAF*6T#7=g7CzOx6m2a5*|3+TYRf8@jnt z8o3uI#;%7p+|i5I6TD{CG3zg`JA2gRO4mSIH)*bP*P#C_({~E!9EF6nJ#sUo`Spc; zN4x0wGYUn90~a2VWEPzuYO`h#2-uQ=aLP!O^GM!R{5Mv&;6!@0B<-uY;&7QLU0l4o zssFG%d|`jh&bQ_p4EqJ`5O#lp%&teLdV8^)wrDWz2_K#jd<+#@ul&y`5QYIzzpyf@1_vAE z*4!CC&>gbdqqVyjzcTkX-ga8Kl`fY*ii3x~wJ_eq@6$=fZm$b31U{83*2+aU;%8j= zSrb`)u3W#z0-Bew@v zssA3bE&`OboH#EbpCcxTE< z-gz7r&1TAd+*`=|El7@D@b5EmQF-&narFn;hxT2iEnkF{8s8^!4-*V`?yf{u@I}Ej zs1%koUBtUli<*n7hg~KR8JhHS~t1pW;~RhZ=v@YEUqUeYE_qkma@Ff3|RZIYhXy#;t|W3cd}= z=m5SKOK8p3gG7SoEdZS(DLW5N3(L#_@KkNo?fextAxxqIDpoZ*Y8huQrL4TcQM)@ZhfG63T#TRj5<- zFCy0ve2Z{&O?oyy5ZV}u{_9G+V+u++rz3uWKXXE=*|^oe5vsC7{4qC@6uNh*4M!mSfnZI3F z?4RFj)(&oCB?HR`DvNgv3{?Ggm-{1u*!1ITT@%HMV&ohE_0LphtFNF@bWj5D6Mxvw9UKNbv0=evACr+|XaN%P3YDjcFq!boSe0PQj#&uPr+;{djbQ5- zJX^^tTv&-BD~VQ3xG%~5%)x>6WA|52Fhw6Q#YFWiXK~2yZLu4(#@33lIfh0H_+gy* zcPpZ3-YC30r)N;0hbVk7orw^7qYJJJ`orr8jALas_ip`h$1>$LQ}0m)n%YYNF>hBV#rhs4{X$1Tgq-w~*~7TgzJI6X8^^L z*Ts(BbCInki>^O1Hj7wt9$ua1sS1U# zUHL`NvHi6$CP#(CsJ--ACo@T|qTRkTWA}o@!Oot2ruakRUNaH5uuy2VnSAVg4H#O$ z{fm8Imxk%*YO5?#v2T9xy?ghract}YpOVLF28V#^RC%acb!xpd)Rcr&Y5_VFc{&%LLs+o%KU2de= zEwHs{n9AXjM{PY&*=rCG%68+Rn}O$ctU}oS64c4cD}p!MKH3X%auwi1k7{ib>Fike zbrBbsBrN>qwMm1>`ZJOel%s2muCb@+VncwE5A6%vl>g;d^(D;!+UGB(k~87Zk4y6c z;s6jRD?9wmc}iIiVb}G%`F5Ftoa|4v;4x@FL3}I!qbaL*77NgdxEPA}+AN39(hD56 zc0q8wuNlvPw#i1FA5Zp@*e60c1gOrr4=0Q+pIz5sz7gn=t@2`KPLwB*ikdj6lmSXz zGAs@JYtrW1;wnWS$!xojUJrk9R2$bGQGe7Sbbr?4)cILPhh+&mK=c0`khUJ`Gra@bJpe9(Afnpn7(77UvDd=a~}oM|1opsl~I^ z&(7Bo{;*UJTd6UDaCar(k`PX0vZ?77&3aRnyJ^dE*zBClVA>A~{ z6wMFE2(P>-9v&+{;>>QW7xt9$jjSC+lf|9~V5Eu2%I7jSVfTGbMgW`|U};?1iUSBEuKA63PC%KS(&bI_^> zihf>+)_wv)y8#kT#}f<||2m*(tP|QdO2LNu7S`m#_igxP-^=foM|*2P?H6wdp1pT@ zGPC*~abZ&`qZOtS9reuu^O4_PIj>W|@;(G?5P$1y(G1$*%bQLLa`zicrJ)=NYe^CB zVC&LAjOiV;hVp9?yQfhgc=K5+i$B<+mkWVHQ`6KGU%}H_?u6T4_JP`(PtKqjJWsVh zxO*^EDm&Wh^W$Q~y65<)Q0M6K@?};I4h^ZQY7JhgAGk1jJ_Ms{rlQpqBTF2~@Mc4M zSpmo0J9o(OPUlmxvAd7^F#r0c79Q{O&TNLXR9mYZh^P$%B9Ib~HFMCFKa-^qx-OA$ z`!NvZPD`{-`?`fku)1J?%5Kns|icv~t(Qu#@_eP0iwZ zO7C~?4DvNAP~TabIeD*^wo3^J2y6%)S63=6!`Cmc9}of?&Oov`Y&H%5w`Z8x`AE*C zrc>sU+=x)9x!_hOi!9Z&h0*?I>Ul$vt(?|ax75%^AyF^>&J5%1*cNNS^O9+7e6u3b zC1dlkO4bxO(76*(>Gc^Wkw~*lYoKw#gGs7eDvIpxg{&|;2|al%JfF?s^>hq0<$i~`=r^3Z%(VeG#e40SldH_&+0bdy8pt;SIhgrn>0JY}6eyvZK84`_zVl^(n@g7eAjj^8lIfN5sR=(OY#$WzK?8 z=F_TBKlo8FDF>>a!RT*jc;`;VC*~i6f88h<*-ROlEBD*ogfS2{1_+BL@($otM4>K# z0^i(Nsg(~Nk4IL4XGs8i^ozz>ZU|*YknIUeT2Ja$HCdRr1@bx&xlPYuvQ~kxA@wvwRa#p5eheX8hq(8-0}=jP&xfKI?tcd$x?#1_iPlXW9n7Gd));q5 z$3vbc$|UVg&&^_YK5m%1i>Ng((bL@5 zOc*UdlgNUVmaCf9&3nOsY6i`_N=izi;^X7@*Tzb5RG^altleb>ETDG$ud*SD8c9Rp zw$ewO=M4ilJh$=Fl?EL^2)!Trx zFDy{%Jd1er?Jx98t``kb6`u9>^ngIRCoKc;if1_U;T_Wqa<1lC%urGCtct|tK?ju0 z30+5BLXwcSvu{Z(>Uv1RRYumW2MPO-IiE!9Y1*0xX#AN^$D}$wImjL>8w0A~kLfZ` z=)UGtXQq{n%?p2qbBVtM>T4TdS>AlxgU$`BMV5@l4Y{nMxauM-umvBSpLuV)^(Bz> z9L_;$67Ip!!?~8077iDmEs(IKw`6#zDrUkNAg?t5H^b_U`~tjGG^=L#L~D!#kE{PvE_y?#08nG?jhh3Tt}T5Cm4`bLEEWpaM9$+{Umnq`w8rH52(|Qrg_eInJ7kURD`NssOx!P zqj*oVUYI$tk~J!AebLE#pKKYHp=h&Gd$VmY zMC9$|ZSxBy8Y9GW$u}Mj;V`F!c5{Hkar#`jcK0ZyMO7-X8dt3@$X-+b24ItyTd$t3 zAmVqtOv`Q9fC?MUFTMtPw2O5+JwB0+lcqk*%W89y)~4Z4&u#5|OOaz7ucyi)KgrNH zDI5tA1Z$$+_j5uMPU&B%twSE;Vi2#xkU(1oG92q?711gTR0i2Uc8je}R&8|g%D-Nn z(D0XonW;y3s+ftRpVUgmW6V|Rl9=0W>9}ORfoFWJ6JE#wO1wZ2_RbWVQh;fvaG#sK zEr=G7Fo$&1-JGuhg1Qc4C3JuA_ibJZ$WN(tIzdyg7rr(`Ik z`igqO`Gm@K;I#n-VzdC_b%v_nVKYA6XI&gTN8Di&or3qu^*5te# z#b)0u{Gg(Qem^aN?kUft$Y%8YHw#ELX21Tj0z~qM4+{J@p7lbpe85dpPc}^tm;map zMi>{ccP1uEG5d&(t?ld^>H&WCZ_Vpb82zWPva+(r?)S(nFhBgC~u?w9!HS z$IAp|7f@Bc2_zW_=bt#!?ZN0}iFqq)@k50VdQo2hB5%4`BcMEs1Vfi2F?=q(3rT<{ z$Y1K79#xh6C8)W%ndU6(fsU>__nu<~H@I)9FoW7qci77gH^E~;pfy}zQO`r0 zHPvK|p<72s#MuVh-gJTay)hRb zie!rb75j2wRO>Rpj-7p$T`EP|?XxsI8j*@)cCwZmGxbPSLP0sz2Z&NS@_PM1R3HTK%5&SIYcTxc>ND1~BmyImbY&_UQ3m#4$Nk zBH`DF>ksnHt}<>r--U^VvH6i}T_H)u71}~Y@)|}VvSMda(Dv1C3^99wLpl>jkw?C* zoUhc!{eYJ4^iEx*-?lh~t0)IFe&!5@SLpjxIa9m6Rh+xZ$GSqcSs`##x@rc4O>Vrb z>hVsqK9av64eTtH^H1IS(~1b_iORJl6$U#B@bmWtOWr%1_i8?TqU`8Acl3AP!k16; zJ21{u#HdsT8+XeRUU{SU!y}hVvt_adDi- z`9bmJ<>gpvSyKJ#CGeDy%C!ulGKa)u^BE0ppIv|raUqSmpg zGQoH)X($xy=IrKnb`PW$wHC$Lm4!$+x)7(}Ia%pf`p#4{_AH0%!&_v<2?ocbx7B7@ z8obRrewKEIcp%p+tiEgo4)C1M%#%<=TD<|lINYjHbyoKh_`}pegS@GP&c2Fa92(@V&3(dgN4knn zbU9EH7DK1X%+ES^&Oj0Tz`@@StGzkj_BEpe(b@3uYExSjZ&tru;|{Q-gzgl1%y*+) za*^X?Rn_Dgo1}YWS?hQFtwu^8LA>g0lgM({aP8GPxmz{9kEr@uVc2O zW5l$lWb(o?lAOln7^knda6kemhvH&l>7Qwg@(YQlj%~t_QsCnCoYt3d3Wp~F$rHA6 zH+Pe(QUEkV18haXbur9uWhghs0<5BEZPC%G$;#Q0zixR2?h(R%e6^BLgdy@Oj~Lc~ zU*<#}ug%kN#8P!A^iWEDc`rOXTt)T;>`|yws0P`kJ)WGC%9R);MEwV>LLgL+Cy%o7 zksq+Dga9~1!EO1Tqm9iU71|P{MdPNdCijX_0V)idXX0L~So3>R>ijwb@twR<_x#o` zic**Udku832KhclXT1CjhIAZ4YSoaS%Vc>Nd&3Zu?JgXgh(Od~j;Wo=$;nl9ns=+Cz$I6K2;bL4cB{ShjOP>-%TsWH zE>q_2)j_7ndTX;1Z{kbL-?^Fb@$pHi+SM`%$H|7#$~BYDcZTPGcAM8_$BtXszFi5q zncu>pe?$aBku~^!yg!2-FUBHb&FK8!ltb0cbGE&XaKm#z&BV0oH9ufK`^f^YE2#y_ zCZ6NgNz>0K_f(>Bk{iIu=j8E@uYBl9>etPMo^0AVQ*RV{_NvzFk540FfN$|Dn0|dc z-O{2d9^t^Ym5*t7s4hVlJH*^FJ`Z|9$6s_$p4UrD$KL|VP;9(%Gze$z2R{91hD;`l zCO!2SPXV*<0tb@{L)mR|nIr1x{gTdEw{XLUN|ypiF+k?m7DPwIhf$=#Ro%(z1a?OT z$Xat_t%ZQFk5EN}>2ph=4@S8RG*9{V?Mc+1WZQ-^u%C+ASy{;-P=8i&=Z5p z#7~A{$Fl0n<;+=zAP)qjQiBKP;lSJ;`tNIGKDcx(?-t7hD~Lzu<^=f^-8#}gemq?6 zLQ=PDpN>*A^M@m*HT=J*a`TQ8|9;rUuSu-RMxL8C1o5O%>gHvUOss6VB^O^gv7cVA3ohUfB1VSr1(&C ztfMH#_KpmtWGFvgZJBGq38c#MU?JU}KVMKVTxh?-Wh-Ev;wH%+LRtc4-?>?Z)V526 zMR>|tXTSL|k`FTt+KYrYDBS$#pPfXBqUuk!906!?tN860rp{VPMaDR5(+#-xK@sH; z*CD3|Y2lA4yU{Xx479BKl$GlU!-X*ZPK2GU88;2aFfKGd39sAy`JXu#)ouThcwA__ z3Sum)mC-|I!CKX)Stqv2VNCvew0$wSKAIuMyb!I`Y8QsZfNttOA?w_DxH0AvPoqK# z5UApnbMOZoV5q%uTThS*S$GnMO=bsxCfOcTFbdukd@cT+Jq4AX+6&qFc0&BK;CqtS z_%qV8iDE=l#s4ygEvt0k;@ALSyzGo~6UCfC%A8_o|9bCoqnT~mNh>Rm7z`R>iYVFKsoL;I~_n5(dy>tMAEb*-`gJUWX{?1qu&bl{%L?^WC1O(H$_!gMLV7-QA zIYQLUW40|@URrd&JW;Y;5Tx@&*rGb~E@0)k_PDYUa62k*wQwQF8~l7g{FYrxELUrM z`zs_?Q?ielW%%NaWZ*z?V7;K8SgLa|qFdELCuLo}Wmcf$9i;JL_b*V}xIeH1VrjnNRp>BK^Zeq|;fj3P`da z>Q103_k*3nX8pNykzQPE<7{xLKsXN^Bjb0Hmu2FO(3Qwn@_?TU0K5JtnApc+RQASn z@`qPOZhzUn8Qe$T={FKb)+;*4v5D3;Q{&O+x$@07NiU;V;qe^=+#H}X%DuHBcc>sO z#TyRz@ViUimeq_y4Q*w+D&X7ZC+h>Y)0HkEuO>rMYh&jZm z@&TM-InF(eZ4BJA3)2|kz4IuUg|kv}3AZZQ6?o&-2uYtw+%Qd%nE0yb$Dhx@^N%{n zIh};)i*Dg23PrZ}l__FOA-7W2o_}xNb)gq>P^J;~)S%wy~-%DTLI+!wuL%L`DVaewpdd-Xq9?FE@5%6TV@ZCEg zYL>))KL(N zoKaskY-?|~ZC-L=Po`~WIM7U(5=2NH_R2~{#+dZz+L-z(rwYPGHVuEu>^fM zn1QC*`}QxBhV5?f02Bw^K(+DJ1KX2&*>4|5w?@y+Q~}H34erwcV;cr{0UX}GeZeve zi=aUi-jGksW-kt(?rP`)j)*H=(QH*ufU!GHRyL8z%F26VR><)mZ}28eOiY-nafg}p zn%4`!@V7c)+>LLeo0$~cw|eNq&?5?Gu&>NUFgnbBC|_T)WwmlNBus(}FMh=syo4Tb zu%<>1b%dd&3s`ZW*b929M!rdEQSEEk2*YRr@rYqP4Dn3!V`U)Fu60ausO*xhYF zXGrR(gWTJ4-dcUuwX3n9Z@iII2@CGqhSB$`>`yHY4Gldms^6Q4nW(I<3x(LLTn)b9 zgsAh|Qu_$Kw?*zFol0$g9o)wRg0+V8s%>KwRQuYCgD$R_Pa>IYA42yqO(y)Z|$4si{JUq+}<^JloUXkDXYwK^mi?~_*UUEI2*{Rd_-H!2T zADB_$tNk{%5G|f?>88%atCr_ZnXri$kcY|&b%e$F7?WOY&3YLh`iiZ8f#uh@OVG|H zn9pkI#_-GU`bD+tHS+Q)-L-t}<5HKT#v4%WBHM!v759d4$eCgc*s5I0i9{IYV_Kd^ zhZ-%EMK6EfM9pgscXq`v2MEd}f-I5dFwF}YaX1|E=Kj^>@VcTC`-6@l&J`<(--<>WifC~q!+UyZ>_N`-8042zK ziwphkd3#!uxTTXb^=LDz2t8{~by@%ma?J0z_89Db4Wa0$8st#`Kt}E<7q>{TbE01y zLU&9pLb7OJ@66gcI z)ET}2XwzHT;SZufF~fA_gAv}>)$`HD`R*G7F!~<}x2bi0J5P>!<4E0T%7^PMv$Q5> z-!Sh!yFnX;2Gh()`2A$Yi}YdNrMs3~OI&c;G|)}?U@_i@b~GH)2K!~4PfWHcKe!69 z`~_|_$9NrN>Fw-)RICEdz_0+ zchavf7?EC(eKP4Imwhh#vg$xI4;F8c=a0b-z8CPD8FG%}TLhzNRr==@3v7f?3V*GJC# z85=sSZ(>J$qLkV$jmRPth$K1YtQ^-LQ}DI%a{Sc{vfj+#^_w~4TCLok%DH@( zar*>OgZJpw+ASU-4n7Hyoo~XVw*>v(AL^26S2D8K0MvuM9k%%;bpad3h z$3+%}AYJXatyOHAc)dT0JV-W8JV_WS45HcQ;olr_!&HT>5niV{7vLFtcUrDgzhE4DSsnms@B^5Hy>#cB;cg|C?x@Dv3}B^{-2e7pz%6L< z8Ay%XN3%WAly^tr9sSXpqP2W?&G?JrFC%UtK{XDPd-won>1M~J7+)ed zxsfv(jV`HUAjl(do#f0#zprUp9gU%}+*b5?T+BRv&V+QfK!Y^RCwl&sx{ssXuhOAh z!VUb}%Sb@<<~-wtZ~FcF-Tr1X$MMqK9MG1?%0hH5x&9-(!ZjbcUz^0;K9EsqZFa1b z)b;ebwDeYr>Vb~Rewu;!mLK4L!1G6x#niy`+6Q{#cQ0`GoCvy3yK*e}S9H@y+DuI7 z8~~^*%<3_pKYymtrPGYhZ*{CxsR&Cw^x77u2arbAuy65gIjiBATeDOIa2D+9 z%O1dH>fwNX_Juj5qyZ&aDMS9Y`Ne9r=0Ip`X|fQYu5E2?v~)TDu7N?rK5!J|YR5@W zxTK`zno#Cp1IZf29N`_NcUrPpvoU|l%j^uK;Xpd=g}6N5oK3Hi6fW%WJ7iFK?? zk3@GHAbykrVPapLCF*ctUPtRsP!62m>L)S5CcbMaaUY5zZ?*6LXNBQ z3C5;aw94vux$XY$?k*tr?SA#2RRaG=vj8<7Y?w4AxX&WEj~{?)NcQ#@VHqJU^!$44QfF%d`VK>#6`ta1uvk*bEk{C4{{D5Q2ogWHQ2i`_t4 zMj%0h-Ni*LO9RAb(ReR>6nOueWCI-eREFXEr$aZ}`32kVOqb|Zpe2s)apG;0L_ax=|ZL0C^&B90=Dwc1@&t4m5Y zXTX)02$Ltb7DSSNhYB&-!l~+_e z4eW9gY@$h>7+5_n1e{{+E~&NL+}tzkUKWcm`U>eU;gD2CsJeS_AD&a)bA6`XM=r{e zMuq)N>+4DX=*6bNq;S0=fhWi^!eek@sKEUD>2$xn@d;2XpYa*IEAKbuk_u{FXTOp` zyaksL zhq#FdJ@rfeKsxN7=K*lmScN?ot*!;bkhki^4by!o-SV@(*5%{mJD>ZPL50gURY>ChAL?58Yq**ARgEvyE!1GNNEKj`W5*cU&oRhXY$YXHTC5X;9?x!Tj{#;Na-2 zYu7dPJt)L9{n8vLaRfmR8=FBe`oJ7fef+hPdk$=Dx%XDefJo}0;6LDq(l%}XfI5_s z{_DjS*Z^u{z%87Ra~OlfC~tS{gQ60={@_mv#u3yFrP^IQHuHMR3YfsMHfnIF>|Vc{ zs&Fjd;$$g!eu4!u&1;$F``=4S?bXD` zOKpcx)AvUk)#NI=AWEZe$w%qDs zRWtTMiZq}O`mc$lgRAuA2kOjCA8)*x1896mP6oPWuUUY)S%2x$B|Ny8;5%McVBE0> z1X_+9dv|({It|g=OPl2hLy_&JY{xLqbYX9D!&CD#h3hKlAatPdMF>AncL7O8dW-lO zcVlj;w@h-ZAEp1_uNbifsudWf@^R8sAEA-9bf^zNm0IBuV0wvr=cldeLQ gRRX))^e^d{ZV0L!7k96)8UlWLS_Ya$>Xw232QU?b1poj5 diff --git a/module/mixinbooter/src/main/java/zone/rong/mixinbooter/Context.java b/module/builtin/mixinbooter/src/main/java/zone/rong/mixinbooter/Context.java similarity index 97% rename from module/mixinbooter/src/main/java/zone/rong/mixinbooter/Context.java rename to module/builtin/mixinbooter/src/main/java/zone/rong/mixinbooter/Context.java index d1a9fa716..c1bdea26f 100644 --- a/module/mixinbooter/src/main/java/zone/rong/mixinbooter/Context.java +++ b/module/builtin/mixinbooter/src/main/java/zone/rong/mixinbooter/Context.java @@ -1,81 +1,81 @@ -package zone.rong.mixinbooter; - -import net.minecraft.launchwrapper.Launch; -import net.minecraftforge.fml.common.Loader; -import net.minecraftforge.fml.relauncher.FMLLaunchHandler; - -import java.util.Collection; - -/** - * This class contains loading context for callers - * - * - * @since 10.0 - * @deprecated We forked Mixin. - *
New approach: - * Check Fugue.
- * Summary:
- * If you are coremod, just call {@link org.spongepowered.asm.mixin.Mixins#addConfigurations(String...)} in loadingPluging or Tweaker, and handle shouldApply in IMixinConfigPlugin
- * If you aren't coremod:
- * Group mixins by phase, add target env in config, use @env(MOD) for mod mixins.
- * Add {"MixinConfigs": "modid.mod.mixin.json,modid.default.mixin.json"} to your jar manifest.
- * Handle shouldApply in IMixinConfigPlugin. You can call {@link net.minecraftforge.fml.common.Loader#isModLoaded(String)} for {@link org.spongepowered.asm.mixin.MixinEnvironment.Phase#MOD} mixin.
- * Recommend to group target mod name by package name. You can also get config instance from {@link org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin#injectConfig(org.spongepowered.asm.mixin.transformer.Config)}. - */ -@Deprecated -public final class Context { - - public enum ModLoader { - FORGE, - CLEANROOM; - } - - private final String mixinConfig; - private final Collection presentMods; - - public Context(String mixinConfigIn, Collection presentModsIn) { - this.mixinConfig = mixinConfigIn; - this.presentMods = presentModsIn; - } - - public Context(String mixinConfigIn) { - this(mixinConfigIn, null); - } - - /** - * @return the current mod loader - */ - public ModLoader modLoader() { - return ModLoader.CLEANROOM; - } - - /** - * @return if the current environment is in-dev - */ - public boolean inDev() { - return FMLLaunchHandler.isDeobfuscatedEnvironment(); - } - - /** - * @return name of the mixin config that is currently being processed - */ - public String mixinConfig() { - return mixinConfig; - } - - /** - *

For early contexts, the list of mods are gathered from culling the classloader - * for any jars that has the mcmod.info file. The mod IDs are obtained from the mcmod.info file. - * This means mostly, if not only coremods are queryable here, - * make sure to test a normal mod's existence in your mixin plugin or in the mixin itself.

- * - *

For late contexts, it comes from {@link net.minecraftforge.fml.common.Loader#getActiveModList} - * akin to {@link net.minecraftforge.fml.common.Loader#isModLoaded(String)}

- * @param modId to check against the list of present mods in the context - * @return whether the mod is present - */ - public boolean isModPresent(String modId) { - return presentMods == null ? Loader.isModLoaded(modId) : presentMods.contains(modId); - } - +package zone.rong.mixinbooter; + +import net.minecraft.launchwrapper.Launch; +import net.minecraftforge.fml.common.Loader; +import net.minecraftforge.fml.relauncher.FMLLaunchHandler; + +import java.util.Collection; + +/** + * This class contains loading context for callers + * + * + * @since 10.0 + * @deprecated We forked Mixin. + *
New approach: + * Check Fugue.
+ * Summary:
+ * If you are coremod, just call {@link org.spongepowered.asm.mixin.Mixins#addConfigurations(String...)} in loadingPluging or Tweaker, and handle shouldApply in IMixinConfigPlugin
+ * If you aren't coremod:
+ * Group mixins by phase, add target env in config, use @env(MOD) for mod mixins.
+ * Add {"MixinConfigs": "modid.mod.mixin.json,modid.default.mixin.json"} to your jar manifest.
+ * Handle shouldApply in IMixinConfigPlugin. You can call {@link net.minecraftforge.fml.common.Loader#isModLoaded(String)} for {@link org.spongepowered.asm.mixin.MixinEnvironment.Phase#MOD} mixin.
+ * Recommend to group target mod name by package name. You can also get config instance from {@link org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin#injectConfig(org.spongepowered.asm.mixin.transformer.Config)}. + */ +@Deprecated +public final class Context { + + public enum ModLoader { + FORGE, + CLEANROOM; + } + + private final String mixinConfig; + private final Collection presentMods; + + public Context(String mixinConfigIn, Collection presentModsIn) { + this.mixinConfig = mixinConfigIn; + this.presentMods = presentModsIn; + } + + public Context(String mixinConfigIn) { + this(mixinConfigIn, null); + } + + /** + * @return the current mod loader + */ + public ModLoader modLoader() { + return ModLoader.CLEANROOM; + } + + /** + * @return if the current environment is in-dev + */ + public boolean inDev() { + return FMLLaunchHandler.isDeobfuscatedEnvironment(); + } + + /** + * @return name of the mixin config that is currently being processed + */ + public String mixinConfig() { + return mixinConfig; + } + + /** + *

For early contexts, the list of mods are gathered from culling the classloader + * for any jars that has the mcmod.info file. The mod IDs are obtained from the mcmod.info file. + * This means mostly, if not only coremods are queryable here, + * make sure to test a normal mod's existence in your mixin plugin or in the mixin itself.

+ * + *

For late contexts, it comes from {@link net.minecraftforge.fml.common.Loader#getActiveModList} + * akin to {@link net.minecraftforge.fml.common.Loader#isModLoaded(String)}

+ * @param modId to check against the list of present mods in the context + * @return whether the mod is present + */ + public boolean isModPresent(String modId) { + return presentMods == null ? Loader.isModLoaded(modId) : presentMods.contains(modId); + } + } \ No newline at end of file diff --git a/module/mixinbooter/src/main/java/zone/rong/mixinbooter/IEarlyMixinLoader.java b/module/builtin/mixinbooter/src/main/java/zone/rong/mixinbooter/IEarlyMixinLoader.java similarity index 100% rename from module/mixinbooter/src/main/java/zone/rong/mixinbooter/IEarlyMixinLoader.java rename to module/builtin/mixinbooter/src/main/java/zone/rong/mixinbooter/IEarlyMixinLoader.java diff --git a/module/mixinbooter/src/main/java/zone/rong/mixinbooter/ILateMixinLoader.java b/module/builtin/mixinbooter/src/main/java/zone/rong/mixinbooter/ILateMixinLoader.java similarity index 100% rename from module/mixinbooter/src/main/java/zone/rong/mixinbooter/ILateMixinLoader.java rename to module/builtin/mixinbooter/src/main/java/zone/rong/mixinbooter/ILateMixinLoader.java diff --git a/module/mixinbooter/src/main/java/zone/rong/mixinbooter/IMixinConfigHijacker.java b/module/builtin/mixinbooter/src/main/java/zone/rong/mixinbooter/IMixinConfigHijacker.java similarity index 97% rename from module/mixinbooter/src/main/java/zone/rong/mixinbooter/IMixinConfigHijacker.java rename to module/builtin/mixinbooter/src/main/java/zone/rong/mixinbooter/IMixinConfigHijacker.java index 2b9293323..61376882a 100644 --- a/module/mixinbooter/src/main/java/zone/rong/mixinbooter/IMixinConfigHijacker.java +++ b/module/builtin/mixinbooter/src/main/java/zone/rong/mixinbooter/IMixinConfigHijacker.java @@ -1,45 +1,45 @@ -package zone.rong.mixinbooter; - -import java.util.Set; - -/** - * Hijackers are used to stop certain mixin configurations from ever being applied. - * Usage is similar to {@link IEarlyMixinLoader}, implement it in your coremod class. - * Requested by: @Desoroxxx - * - * @since 9.0 - * @deprecated We forked Mixin. - *
New approach: - * Check Fugue.
- * Summary:
- * If you are coremod, just call {@link org.spongepowered.asm.mixin.Mixins#addConfigurations(String...)} in loadingPlugin or Tweaker, and handle shouldApply in IMixinConfigPlugin
- * If you aren't coremod:
- * Group mixins by phase, add target env in config, use @env(MOD) for mod mixins.
- * Add {"MixinConfigs": "modid.mod.mixin.json,modid.default.mixin.json"} to your jar manifest.
- * Handle shouldApply in IMixinConfigPlugin. You can call {@link net.minecraftforge.fml.common.Loader#isModLoaded(String)} for {@link org.spongepowered.asm.mixin.MixinEnvironment.Phase#MOD} mixin.
- * Recommend to group target mod name by package name. You can also get config instance from {@link org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin#injectConfig(org.spongepowered.asm.mixin.transformer.Config)}. - * - * If you what to block a mixin config, {@code GlobalProperties.get(GlobalProperties.Keys.CLEANROOM_DISABLE_MIXIN_CONFIGS)#add(String)} - */ - -@Deprecated -public interface IMixinConfigHijacker { - - /** - * Return a set of mixin config names to not be loaded by the mixin environment. - * - * @since 9.0 - */ - Set getHijackedMixinConfigs(); - - /** - * Return a set of mixin config names to not be loaded by the mixin environment. - * - * @since 10.3 - * @param context current context of the loading process. Mixin config will be null as it is not applicable. - */ - default Set getHijackedMixinConfigs(Context context) { - return getHijackedMixinConfigs(); - } - +package zone.rong.mixinbooter; + +import java.util.Set; + +/** + * Hijackers are used to stop certain mixin configurations from ever being applied. + * Usage is similar to {@link IEarlyMixinLoader}, implement it in your coremod class. + * Requested by: @Desoroxxx + * + * @since 9.0 + * @deprecated We forked Mixin. + *
New approach: + * Check Fugue.
+ * Summary:
+ * If you are coremod, just call {@link org.spongepowered.asm.mixin.Mixins#addConfigurations(String...)} in loadingPlugin or Tweaker, and handle shouldApply in IMixinConfigPlugin
+ * If you aren't coremod:
+ * Group mixins by phase, add target env in config, use @env(MOD) for mod mixins.
+ * Add {"MixinConfigs": "modid.mod.mixin.json,modid.default.mixin.json"} to your jar manifest.
+ * Handle shouldApply in IMixinConfigPlugin. You can call {@link net.minecraftforge.fml.common.Loader#isModLoaded(String)} for {@link org.spongepowered.asm.mixin.MixinEnvironment.Phase#MOD} mixin.
+ * Recommend to group target mod name by package name. You can also get config instance from {@link org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin#injectConfig(org.spongepowered.asm.mixin.transformer.Config)}. + * + * If you what to block a mixin config, {@code GlobalProperties.get(GlobalProperties.Keys.CLEANROOM_DISABLE_MIXIN_CONFIGS)#add(String)} + */ + +@Deprecated +public interface IMixinConfigHijacker { + + /** + * Return a set of mixin config names to not be loaded by the mixin environment. + * + * @since 9.0 + */ + Set getHijackedMixinConfigs(); + + /** + * Return a set of mixin config names to not be loaded by the mixin environment. + * + * @since 10.3 + * @param context current context of the loading process. Mixin config will be null as it is not applicable. + */ + default Set getHijackedMixinConfigs(Context context) { + return getHijackedMixinConfigs(); + } + } \ No newline at end of file diff --git a/LICENSE b/module/forge/LICENSE similarity index 100% rename from LICENSE rename to module/forge/LICENSE diff --git a/settings.gradle b/settings.gradle index ab7e11204..87c43f334 100644 --- a/settings.gradle +++ b/settings.gradle @@ -14,5 +14,5 @@ pluginManagement { } plugins { - id 'org.gradle.toolchains.foojay-resolver-convention' version '1.0.0' + id 'com.cleanroommc.gradle.settings' version '0.2.0' } From b4d561bc49669b9f35bfd7fabe6a35b26d9986a3 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Mon, 20 Jul 2026 01:45:57 +0100 Subject: [PATCH 03/99] CG 0.3.0, notes in dependencies block --- build.gradle | 62 +++++++++++++++++++++++++++++++++++-------------- settings.gradle | 2 +- 2 files changed, 46 insertions(+), 18 deletions(-) diff --git a/build.gradle b/build.gradle index 2a244400b..6c1d01348 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ plugins { id 'java-library' - id 'com.cleanroommc.gradle' + id 'com.cleanroommc.cleanroomgradle' id 'idea' id 'maven-publish' } @@ -13,6 +13,22 @@ java { withSourcesJar() } +cleanroom { + loaderProject = true + accessTransformers.from file('module/forge/src/main/resources/forge_at.cfg') + patchDev { + minecraft { + source = layout.buildDirectory.dir('cleanroom_gradle/sourceSets/mcp/sources').get().asFile + patchesDirectory = file('module/minecraft/patches') + dependsOn 'remapSrg2Mcp' + } + } +} + +afterEvaluate { + sourceSets.minecraftPatchDev.java.srcDir 'module/minecraft/src/main/java' +} + def modules = ['minecraft', 'forge', 'cleanroom', 'kirino', 'builtin/mixinbooter'] sourceSets { @@ -38,8 +54,6 @@ var export_arguments = [ '--add-exports=java.base/jdk.internal.reflect=ALL-UNNAMED' ] -def asm_version = providers.gradleProperty('asm_version').get() - configurations.configureEach { resolutionStrategy.eachDependency { details -> switch ("${details.requested.group}:${details.requested.name}") { @@ -69,6 +83,7 @@ configurations.configureEach { dependencies { // ASM + def asm_version = providers.gradleProperty('asm_version').get() implementation "org.ow2.asm:asm:${asm_version}" implementation "org.ow2.asm:asm-commons:${asm_version}" implementation "org.ow2.asm:asm-tree:${asm_version}" @@ -80,16 +95,14 @@ dependencies { implementation 'com.cleanroommc:cleanmix:0.4.6' implementation 'io.github.llamalad7:mixinextras-common:0.5.4' - - api 'top.outlands:foundation:0.19.8' - api 'net.lenni0451:Reflect:1.6.4' - api 'net.lenni0451.commons:unchecked:1.9.2' - api 'org.javassist:javassist:3.30.2-GA' - api 'com.google.guava:failureaccess:1.0.2' - api 'com.google.code.findbugs:jsr305:3.0.2' api 'org.jspecify:jspecify:1.0.0' + api 'top.outlands:foundation:0.19.8' + api 'net.lenni0451:Reflect:1.6.4' // FIXME + api 'net.lenni0451.commons:unchecked:1.9.2' // FIXME + api 'org.javassist:javassist:3.30.2-GA' // FIXME + api 'com.google.code.findbugs:jsr305:3.0.2' // FIXME api 'lzma:lzma:0.0.1' - api 'java3d:vecmath:1.5.2' + api 'java3d:vecmath:1.5.2' // TODO: joml api 'net.sf.trove4j:core:3.1.0' api 'net.sf.trove4j:experimental:3.1.0' api 'org.apache.maven:maven-artifact:3.9.16' @@ -99,6 +112,7 @@ dependencies { api 'org.apache.logging.log4j:log4j-slf4j2-impl:2.26.0' api 'org.slf4j:slf4j-api:2.0.18' + // TODO reconsider // Apache HTTP 5 api 'org.apache.httpcomponents.core5:httpcore5:5.4.3' api 'org.apache.httpcomponents.core5:httpcore5-h2:5.4.3' @@ -111,6 +125,7 @@ dependencies { api 'jakarta.xml.bind:jakarta.xml.bind-api:4.0.5' api 'jakarta.inject:jakarta.inject-api:2.0.1' + // TODO reconsider // Script engines / XML binding api 'org.glassfish.jaxb:jaxb-runtime:4.0.9' api 'org.glassfish.jaxb:jaxb-core:4.0.9' @@ -118,21 +133,30 @@ dependencies { api 'org.glassfish.corba:glassfish-corba-omgapi:5.0.2' api 'org.openjdk.nashorn:nashorn-core:15.7' - // cleanroom + // Others api 'org.jline:jline:4.1.3' api 'org.jline:jline-native:4.1.3' api 'com.github.oshi:oshi-core-ffm:7.3.2' api 'com.github.oshi:oshi-common:7.3.2' api 'net.java.dev.jna:jna-platform:5.19.1' - // kirino - // TODO - // compileOnly 'com.cleanroommc:lwjglx:1.0.0' - // api 'com.cleanroommc:lwjglxx:1.1.21' + // LWJGL + api platform('org.lwjgl:lwjgl-bom:3.4.1') + api 'org.lwjgl:lwjgl' + api 'org.lwjgl:lwjgl-opengl' + api 'org.lwjgl:lwjgl-openal' + api 'org.lwjgl:lwjgl-sdl' + runtimeOnly 'org.lwjgl:lwjgl::natives-windows' + runtimeOnly 'org.lwjgl:lwjgl-opengl::natives-windows' + runtimeOnly 'org.lwjgl:lwjgl-openal::natives-windows' + runtimeOnly 'org.lwjgl:lwjgl-sdl::natives-windows' + // runtimeOnly 'com.cleanroommc:lwjgly:1.0.0' + + // Kirino api 'org.joml:joml:1.10.9' api 'io.github.classgraph:classgraph:4.8.184' - // test + // Test testImplementation platform('org.junit:junit-bom:6.1.0') testImplementation 'org.junit.jupiter:junit-jupiter' testImplementation 'org.junit.vintage:junit-vintage-engine' @@ -152,4 +176,8 @@ tasks.withType(JavaCompile).configureEach { dependsOn 'printBuildInfo' options.encoding = 'UTF-8' options.compilerArgs += export_arguments +} + +tasks.withType(com.cleanroommc.gradle.api.task.mc.RunMinecraft).configureEach { + jvmArgs '-Dmixin.debug.export=true', '-Dmixin.checks.interfaces=true' } \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 87c43f334..28f540333 100644 --- a/settings.gradle +++ b/settings.gradle @@ -14,5 +14,5 @@ pluginManagement { } plugins { - id 'com.cleanroommc.gradle.settings' version '0.2.0' + id 'com.cleanroommc.cleanroomgradle.settings' version '0.3.0' } From 42749a773fe120304df0b580fb06790aa141988d Mon Sep 17 00:00:00 2001 From: Rongmario Date: Thu, 16 Jul 2026 10:41:39 +0100 Subject: [PATCH 04/99] Move... --- .gitignore | 11 +- .gitmodules | 2 +- README.md | 4 +- build.gradle | 333 ++++- buildSrc/build.gradle | 2 - .../gradle/helpers/ProjectConstants.groovy | 6 - .../helpers/tasks/BytecodeFinder.groovy | 61 - .../tasks/CheckAccessTransformers.groovy | 231 ---- .../gradle/helpers/tasks/CheckExcs.groovy | 95 -- .../gradle/helpers/tasks/CheckPatches.groovy | 218 ---- .../gradle/helpers/tasks/CheckSAS.groovy | 64 - .../gradle/helpers/tasks/ClosureHelper.groovy | 31 - .../helpers/tasks/CreateMMCPackTask.groovy | 138 -- .../gradle/helpers/tasks/CrowdinTask.groovy | 65 - .../tasks/DownloadLibrariesTask.groovy | 43 - .../helpers/tasks/FieldCompareFinder.groovy | 108 -- .../helpers/tasks/GenVersionTask.groovy | 2 +- .../gradle/helpers/tasks/ObjectTarget.groovy | 31 - .../gradle/helpers/tasks/Util.groovy | 212 +--- gradle.properties | 21 +- mmcpack-template/.packignore | 1 - mmcpack-template/cleanroom.png | Bin 47513 -> 0 bytes mmcpack-template/instance.cfg | 17 - mmcpack-template/mmc-pack.json | 38 - .../patches/net.minecraftforge.json | 17 - mmcpack-template/patches/org.lwjgl3.json | 10 - .../main/java/com/cleanroommc/boot/Main.java | 0 .../java/com/cleanroommc/boot/MainClient.java | 0 .../java/com/cleanroommc/boot/MainServer.java | 0 .../cleanroommc/client/ICU4JInstances.java | 0 .../com/cleanroommc/client/IMEHandler.java | 0 .../cleanroommc/client/LoadingTracker.java | 0 .../client/ime/DummyIMEHandler.java | 0 .../client/ime/WaylandIMEhandler.java | 0 .../client/ime/WindowsIMEHandler.java | 0 .../cleanroommc/client/ime/X11IMEHandler.java | 0 .../cleanroommc/client/windows/DwmApi.java | 0 .../com/cleanroommc/client/windows/NtDll.java | 0 .../client/windows/TaskbarApi.java | 0 .../client/windows/WindowsProperties.java | 0 .../client/windows/WindowsTheme.java | 0 .../common/CleanroomContainer.java | 0 .../common/CleanroomEnvironment.java | 0 .../common/ConfigAnytimeContainer.java | 0 .../common/PatchModPresentChecker.java | 0 .../configanytime/ConfigAnytime.java | 0 .../com/cleanroommc/hackery/Reflection.java | 0 .../hackery/ReflectionHackery.java | 0 .../hackery/enums/EnumHackery.java | 0 .../loader/LanguageAdapterRegistry.java | 0 .../cleanroommc/loader/javafix/UUIDFix.java | 0 .../CleanroomScriptEngineManager.java | 0 .../cleanroommc/hackery/EnumHackeryTest.java | 0 .../forge/src}/main/java/ibxm/Channel.java | 0 .../forge/src}/main/java/ibxm/Envelope.java | 0 .../src}/main/java/ibxm/FastTracker2.java | 0 .../forge/src}/main/java/ibxm/IBXM.java | 0 .../forge/src}/main/java/ibxm/Instrument.java | 0 .../forge/src}/main/java/ibxm/LogTable.java | 0 .../forge/src}/main/java/ibxm/Module.java | 0 .../forge/src}/main/java/ibxm/Pattern.java | 0 .../forge/src}/main/java/ibxm/Player.java | 0 .../forge/src}/main/java/ibxm/ProTracker.java | 0 .../forge/src}/main/java/ibxm/Sample.java | 0 .../src}/main/java/ibxm/ScreamTracker3.java | 0 .../critereon/ItemPredicates.java | 0 .../critereon/OredictItemPredicate.java | 0 .../classloading/FMLForgePlugin.java | 0 .../client/ClientCommandHandler.java | 0 .../minecraftforge/client/CloudRenderer.java | 0 .../client/EnumHelperClient.java | 0 .../client/FluidContainerColorer.java | 0 .../client/ForgeClientHandler.java | 0 .../client/ForgeHooksClient.java | 0 .../minecraftforge/client/GuiIngameForge.java | 0 .../minecraftforge/client/IClientCommand.java | 0 .../client/IRenderContextHandler.java | 0 .../minecraftforge/client/IRenderHandler.java | 0 .../client/ItemModelMesherForge.java | 0 .../client/MinecraftForgeClient.java | 0 .../client/event/ClientChatEvent.java | 0 .../client/event/ClientChatReceivedEvent.java | 0 .../client/event/ColorHandlerEvent.java | 0 .../client/event/DrawBlockHighlightEvent.java | 0 .../client/event/EntityViewRenderEvent.java | 0 .../client/event/FOVUpdateEvent.java | 0 .../client/event/GuiContainerEvent.java | 0 .../client/event/GuiOpenEvent.java | 0 .../client/event/GuiScreenEvent.java | 0 .../client/event/InputUpdateEvent.java | 0 .../client/event/ModelBakeEvent.java | 0 .../client/event/ModelRegistryEvent.java | 0 .../client/event/MouseEvent.java | 0 .../event/PlayerSPPushOutOfBlocksEvent.java | 0 .../client/event/RenderArmEvent.java | 0 .../client/event/RenderBlockOverlayEvent.java | 0 .../client/event/RenderGameOverlayEvent.java | 0 .../client/event/RenderHandEvent.java | 0 .../client/event/RenderItemInFrameEvent.java | 0 .../client/event/RenderLivingEvent.java | 0 .../client/event/RenderPlayerEvent.java | 0 .../client/event/RenderSpecificHandEvent.java | 0 .../client/event/RenderTooltipEvent.java | 0 .../client/event/RenderWorldLastEvent.java | 0 .../client/event/ScreenshotEvent.java | 0 .../client/event/TextureStitchEvent.java | 0 .../client/event/sound/PlaySoundEvent.java | 0 .../event/sound/PlaySoundSourceEvent.java | 0 .../event/sound/PlayStreamingSourceEvent.java | 0 .../client/event/sound/SoundEvent.java | 0 .../client/event/sound/SoundLoadEvent.java | 0 .../client/event/sound/SoundSetupEvent.java | 0 .../client/gui/ForgeGuiFactory.java | 0 .../gui/NotificationModUpdateScreen.java | 0 .../client/model/Attributes.java | 0 .../client/model/BakedItemModel.java | 0 .../client/model/BakedModelWrapper.java | 0 .../client/model/BlockStateLoader.java | 0 .../client/model/FancyMissingModel.java | 0 .../client/model/ForgeBlockStateV1.java | 0 .../client/model/ICustomModelLoader.java | 0 .../minecraftforge/client/model/IModel.java | 0 .../client/model/ISmartVariant.java | 0 .../client/model/ItemLayerModel.java | 0 .../model/ItemTextureQuadConverter.java | 0 .../client/model/MapModelState.java | 0 .../client/model/ModelDynBucket.java | 0 .../client/model/ModelFluid.java | 0 .../client/model/ModelLoader.java | 0 .../client/model/ModelLoaderRegistry.java | 0 .../client/model/ModelStateComposition.java | 0 .../client/model/MultiLayerModel.java | 0 .../client/model/MultiModel.java | 0 .../client/model/MultiModelState.java | 0 .../client/model/PerspectiveMapWrapper.java | 0 .../client/model/SimpleModelFontRenderer.java | 0 .../client/model/SimpleModelState.java | 0 .../client/model/animation/Animation.java | 0 .../animation/AnimationItemOverrideList.java | 0 .../model/animation/AnimationModelBase.java | 0 .../client/model/animation/AnimationTESR.java | 0 .../client/model/animation/FastTESR.java | 0 .../model/animation/ModelBlockAnimation.java | 0 .../client/model/animation/package-info.java | 0 .../client/model/b3d/B3DClip.java | 0 .../client/model/b3d/B3DLoader.java | 0 .../client/model/b3d/B3DModel.java | 0 .../client/model/b3d/package-info.java | 0 .../client/model/obj/OBJLoader.java | 0 .../client/model/obj/OBJModel.java | 0 .../client/model/obj/package-info.java | 0 .../client/model/package-info.java | 0 .../client/model/pipeline/BlockInfo.java | 0 .../pipeline/ForgeBlockModelRenderer.java | 0 .../model/pipeline/IVertexConsumer.java | 0 .../model/pipeline/IVertexProducer.java | 0 .../client/model/pipeline/LightUtil.java | 0 .../pipeline/QuadGatheringTransformer.java | 0 .../model/pipeline/TRSRTransformer.java | 0 .../model/pipeline/TransformerConsumer.java | 0 .../model/pipeline/UnpackedBakedQuad.java | 0 .../model/pipeline/VertexBufferConsumer.java | 0 .../model/pipeline/VertexLighterFlat.java | 0 .../model/pipeline/VertexLighterSmoothAo.java | 0 .../model/pipeline/VertexTransformer.java | 0 .../client/model/pipeline/package-info.java | 0 .../client/resource/IResourceType.java | 0 .../ISelectiveResourceReloadListener.java | 0 .../client/resource/ReloadRequirements.java | 0 .../resource/SelectiveReloadStateHandler.java | 0 .../client/resource/VanillaResourceType.java | 0 .../client/resource/package-info.java | 0 .../client/settings/IKeyConflictContext.java | 0 .../client/settings/KeyBindingMap.java | 0 .../client/settings/KeyConflictContext.java | 0 .../client/settings/KeyModifier.java | 0 .../common/BiomeDictionary.java | 0 .../minecraftforge/common/BiomeManager.java | 0 .../common/DimensionManager.java | 0 .../minecraftforge/common/DungeonHooks.java | 0 .../minecraftforge/common/EnumPlantType.java | 0 .../common/FarmlandWaterManager.java | 0 .../common/ForgeChunkManager.java | 0 .../common/ForgeEarlyConfig.java | 0 .../net/minecraftforge/common/ForgeHooks.java | 0 .../common/ForgeInternalHandler.java | 0 .../common/ForgeModContainer.java | 0 .../minecraftforge/common/ForgeVersion.java | 0 .../common/IMinecartCollisionHandler.java | 0 .../net/minecraftforge/common/IPlantable.java | 0 .../net/minecraftforge/common/IRarity.java | 0 .../net/minecraftforge/common/IShearable.java | 0 .../minecraftforge/common/ISpecialArmor.java | 0 .../minecraftforge/common/MinecraftForge.java | 0 .../minecraftforge/common/UsernameCache.java | 0 .../common/WorldSpecificSaveHandler.java | 0 .../common/WorldWorkerManager.java | 0 .../common/animation/Event.java | 0 .../common/animation/IEventHandler.java | 0 .../common/animation/ITimeValue.java | 0 .../common/animation/TimeValues.java | 0 .../common/brewing/AbstractBrewingRecipe.java | 0 .../common/brewing/BrewingOreRecipe.java | 0 .../common/brewing/BrewingRecipe.java | 0 .../common/brewing/BrewingRecipeRegistry.java | 0 .../common/brewing/IBrewingRecipe.java | 0 .../common/brewing/VanillaBrewingRecipe.java | 0 .../common/capabilities/Capability.java | 0 .../capabilities/CapabilityDispatcher.java | 0 .../common/capabilities/CapabilityInject.java | 0 .../capabilities/CapabilityManager.java | 0 .../capabilities/ICapabilityProvider.java | 0 .../capabilities/ICapabilitySerializable.java | 0 .../common/chunkio/ChunkIOExecutor.java | 0 .../common/chunkio/ChunkIOProvider.java | 0 .../chunkio/ChunkIOThreadPoolExecutor.java | 0 .../common/chunkio/QueuedChunk.java | 0 .../common/command/SelectorHandler.java | 0 .../command/SelectorHandlerManager.java | 0 .../minecraftforge/common/config/Config.java | 0 .../common/config/ConfigCategory.java | 0 .../common/config/ConfigElement.java | 0 .../common/config/ConfigManager.java | 0 .../common/config/Configuration.java | 0 .../common/config/FieldWrapper.java | 0 .../common/config/IFieldWrapper.java | 0 .../common/config/ITypeAdapter.java | 0 .../common/config/Property.java | 0 .../common/config/TypeAdapters.java | 0 .../common/crafting/CompoundIngredient.java | 0 .../common/crafting/CraftingHelper.java | 0 .../common/crafting/IConditionFactory.java | 0 .../common/crafting/IIngredientFactory.java | 0 .../common/crafting/IRecipeContainer.java | 0 .../common/crafting/IRecipeFactory.java | 0 .../common/crafting/IShapedRecipe.java | 0 .../common/crafting/IngredientNBT.java | 0 .../common/crafting/JsonContext.java | 0 .../common/model/HiddenModelPart.java | 0 .../common/model/IModelPart.java | 0 .../common/model/IModelState.java | 0 .../common/model/ITransformation.java | 0 .../minecraftforge/common/model/Models.java | 0 .../common/model/TRSRTransformation.java | 0 .../animation/AnimationStateMachine.java | 0 .../model/animation/CapabilityAnimation.java | 0 .../common/model/animation/Clips.java | 0 .../animation/IAnimationStateMachine.java | 0 .../common/model/animation/IClip.java | 0 .../common/model/animation/IJoint.java | 0 .../common/model/animation/IJointClip.java | 0 .../common/model/animation/JointClips.java | 0 .../network/DimensionMessageHandler.java | 0 .../FluidIdRegistryMessageHandler.java | 0 .../common/network/ForgeMessage.java | 0 .../common/network/ForgeNetworkHandler.java | 0 .../common/network/ForgeRuntimeCodec.java | 0 ...rToClientConnectionEstablishedHandler.java | 0 .../common/property/ExtendedBlockState.java | 0 .../common/property/IExtendedBlockState.java | 0 .../common/property/IUnlistedProperty.java | 0 .../common/property/Properties.java | 0 .../common/property/PropertyFloat.java | 0 .../common/ticket/AABBTicket.java | 0 .../common/ticket/ChunkTicketManager.java | 0 .../common/ticket/ITicketGetter.java | 0 .../common/ticket/ITicketManager.java | 0 .../common/ticket/MultiTicketManager.java | 0 .../common/ticket/SimpleTicket.java | 0 .../common/util/BlockSnapshot.java | 0 .../common/util/ChunkCoordComparator.java | 0 .../common/util/CompoundDataFixer.java | 0 .../minecraftforge/common/util/Constants.java | 0 .../common/util/EnumHelper.java | 0 .../common/util/FakePlayer.java | 0 .../common/util/FakePlayerFactory.java | 0 .../common/util/IDataFixerData.java | 0 .../common/util/INBTSerializable.java | 0 .../common/util/ITeleporter.java | 0 .../minecraftforge/common/util/JsonUtils.java | 0 .../minecraftforge/common/util/ModFixs.java | 0 .../common/util/PacketUtil.java | 0 .../common/util/RecipeMatcher.java | 0 .../minecraftforge/common/util/TextTable.java | 0 .../common/util/WorldCapabilityData.java | 0 .../energy/CapabilityEnergy.java | 0 .../minecraftforge/energy/EnergyStorage.java | 0 .../minecraftforge/energy/IEnergyStorage.java | 0 .../event/AnvilUpdateEvent.java | 0 .../event/AttachCapabilitiesEvent.java | 0 .../minecraftforge/event/CommandEvent.java | 0 .../event/DifficultyChangeEvent.java | 0 .../event/ForgeEventFactory.java | 0 .../event/GameRuleChangeEvent.java | 0 .../event/LootTableLoadEvent.java | 0 .../minecraftforge/event/RegistryEvent.java | 0 .../minecraftforge/event/ServerChatEvent.java | 0 .../brewing/PlayerBrewedPotionEvent.java | 0 .../event/brewing/PotionBrewEvent.java | 0 .../enchanting/EnchantmentLevelSetEvent.java | 0 .../event/entity/EntityEvent.java | 0 .../event/entity/EntityJoinWorldEvent.java | 0 .../event/entity/EntityMobGriefingEvent.java | 0 .../event/entity/EntityMountEvent.java | 0 .../entity/EntityStruckByLightningEvent.java | 0 .../entity/EntityTravelToDimensionEvent.java | 0 .../event/entity/PlaySoundAtEntityEvent.java | 0 .../event/entity/ProjectileImpactEvent.java | 0 .../event/entity/ThrowableImpactEvent.java | 0 .../event/entity/item/ItemEvent.java | 0 .../event/entity/item/ItemExpireEvent.java | 0 .../event/entity/item/ItemTossEvent.java | 0 .../event/entity/living/AnimalTameEvent.java | 0 .../entity/living/BabyEntitySpawnEvent.java | 0 .../entity/living/EnderTeleportEvent.java | 0 .../entity/living/LivingAttackEvent.java | 0 .../entity/living/LivingDamageEvent.java | 0 .../event/entity/living/LivingDeathEvent.java | 0 .../living/LivingDestroyBlockEvent.java | 0 .../event/entity/living/LivingDropsEvent.java | 0 .../living/LivingEntityUseItemEvent.java | 0 .../living/LivingEquipmentChangeEvent.java | 0 .../event/entity/living/LivingEvent.java | 0 .../living/LivingExperienceDropEvent.java | 0 .../event/entity/living/LivingFallEvent.java | 0 .../event/entity/living/LivingHealEvent.java | 0 .../event/entity/living/LivingHurtEvent.java | 0 .../entity/living/LivingKnockBackEvent.java | 0 .../entity/living/LivingPackSizeEvent.java | 0 .../living/LivingSetAttackTargetEvent.java | 0 .../event/entity/living/LivingSpawnEvent.java | 0 .../entity/living/LootingLevelEvent.java | 0 .../living/PotionColorCalculationEvent.java | 0 .../event/entity/living/PotionEvent.java | 0 .../event/entity/living/ZombieEvent.java | 0 .../minecart/MinecartCollisionEvent.java | 0 .../event/entity/minecart/MinecartEvent.java | 0 .../minecart/MinecartInteractEvent.java | 0 .../entity/minecart/MinecartUpdateEvent.java | 0 .../event/entity/player/AdvancementEvent.java | 0 .../event/entity/player/AnvilRepairEvent.java | 0 .../event/entity/player/ArrowLooseEvent.java | 0 .../event/entity/player/ArrowNockEvent.java | 0 .../entity/player/AttackEntityEvent.java | 0 .../event/entity/player/BonemealEvent.java | 0 .../event/entity/player/CriticalHitEvent.java | 0 .../entity/player/EntityItemPickupEvent.java | 0 .../event/entity/player/FillBucketEvent.java | 0 .../event/entity/player/ItemFishedEvent.java | 0 .../event/entity/player/ItemTooltipEvent.java | 0 .../entity/player/PlayerContainerEvent.java | 0 .../entity/player/PlayerDestroyItemEvent.java | 0 .../event/entity/player/PlayerDropsEvent.java | 0 .../event/entity/player/PlayerEvent.java | 0 .../entity/player/PlayerFlyableFallEvent.java | 0 .../entity/player/PlayerInteractEvent.java | 0 .../entity/player/PlayerPickupXpEvent.java | 0 .../entity/player/PlayerSetSpawnEvent.java | 0 .../entity/player/PlayerSleepInBedEvent.java | 0 .../entity/player/PlayerWakeUpEvent.java | 0 .../player/SleepingLocationCheckEvent.java | 0 .../entity/player/SleepingTimeCheckEvent.java | 0 .../event/entity/player/UseHoeEvent.java | 0 .../furnace/FurnaceFuelBurnTimeEvent.java | 0 .../event/terraingen/BiomeEvent.java | 0 .../event/terraingen/ChunkGeneratorEvent.java | 0 .../event/terraingen/DecorateBiomeEvent.java | 0 .../terraingen/DeferredBiomeDecorator.java | 0 .../event/terraingen/InitMapGenEvent.java | 0 .../event/terraingen/InitNoiseGensEvent.java | 0 .../event/terraingen/OreGenEvent.java | 0 .../event/terraingen/PopulateChunkEvent.java | 0 .../terraingen/SaplingGrowTreeEvent.java | 0 .../event/terraingen/TerrainGen.java | 0 .../event/terraingen/WorldTypeEvent.java | 0 .../village/MerchantTradeOffersEvent.java | 0 .../event/village/VillageSiegeEvent.java | 0 .../event/world/BlockEvent.java | 0 .../event/world/ChunkDataEvent.java | 0 .../event/world/ChunkEvent.java | 0 .../event/world/ChunkWatchEvent.java | 0 .../event/world/ExplosionEvent.java | 0 .../event/world/GetCollisionBoxesEvent.java | 0 .../event/world/NoteBlockEvent.java | 0 .../event/world/WorldEvent.java | 0 .../minecraftforge/fluids/BlockFluidBase.java | 0 .../fluids/BlockFluidClassic.java | 0 .../fluids/BlockFluidFinite.java | 0 .../fluids/DispenseFluidContainer.java | 0 .../java/net/minecraftforge/fluids/Fluid.java | 0 .../fluids/FluidActionResult.java | 0 .../net/minecraftforge/fluids/FluidEvent.java | 0 .../minecraftforge/fluids/FluidRegistry.java | 0 .../net/minecraftforge/fluids/FluidStack.java | 0 .../net/minecraftforge/fluids/FluidTank.java | 0 .../minecraftforge/fluids/FluidTankInfo.java | 0 .../net/minecraftforge/fluids/FluidUtil.java | 0 .../minecraftforge/fluids/IFluidBlock.java | 0 .../net/minecraftforge/fluids/IFluidTank.java | 0 .../fluids/UniversalBucket.java | 0 .../capability/CapabilityFluidHandler.java | 0 .../capability/FluidTankProperties.java | 0 .../FluidTankPropertiesWrapper.java | 0 .../fluids/capability/IFluidHandler.java | 0 .../fluids/capability/IFluidHandlerItem.java | 0 .../capability/IFluidTankProperties.java | 0 .../fluids/capability/ItemFluidContainer.java | 0 .../fluids/capability/TileFluidHandler.java | 0 .../templates/EmptyFluidHandler.java | 0 .../templates/FluidHandlerConcatenate.java | 0 .../templates/FluidHandlerFluidMap.java | 0 .../templates/FluidHandlerItemStack.java | 0 .../FluidHandlerItemStackSimple.java | 0 .../templates/VoidFluidHandler.java | 0 .../wrappers/BlockLiquidWrapper.java | 0 .../capability/wrappers/BlockWrapper.java | 0 .../wrappers/FluidBlockWrapper.java | 0 .../wrappers/FluidBucketWrapper.java | 0 ...CustomModLoadingErrorDisplayException.java | 0 .../fml/client/DefaultGuiFactory.java | 0 .../fml/client/ExtendedServerListData.java | 0 .../fml/client/FMLClientHandler.java | 0 .../fml/client/FMLConfigGuiFactory.java | 0 .../fml/client/FMLFileResourcePack.java | 0 .../fml/client/FMLFolderResourcePack.java | 0 .../fml/client/GuiAccessDenied.java | 0 .../fml/client/GuiBackupFailed.java | 0 .../fml/client/GuiConfirmation.java | 0 .../GuiCustomModLoadingErrorScreen.java | 0 .../fml/client/GuiDupesFound.java | 0 .../fml/client/GuiErrorBase.java | 0 .../minecraftforge/fml/client/GuiModList.java | 0 .../fml/client/GuiModsMissing.java | 0 .../fml/client/GuiModsMissingForServer.java | 0 .../fml/client/GuiMultipleModsErrored.java | 0 .../fml/client/GuiNotification.java | 0 .../fml/client/GuiOldSaveLoadConfirm.java | 0 .../fml/client/GuiScrollingList.java | 0 .../fml/client/GuiSlotModList.java | 0 .../fml/client/GuiSortingProblem.java | 0 .../fml/client/GuiWrongMinecraft.java | 0 .../fml/client/IDisplayableError.java | 0 .../fml/client/IModGuiFactory.java | 0 .../fml/client/SplashProgress.java | 0 .../fml/client/config/ConfigGuiType.java | 0 .../fml/client/config/DummyConfigElement.java | 0 .../fml/client/config/GuiButtonExt.java | 0 .../fml/client/config/GuiCheckBox.java | 0 .../fml/client/config/GuiConfig.java | 0 .../fml/client/config/GuiConfigEntries.java | 0 .../fml/client/config/GuiEditArray.java | 0 .../client/config/GuiEditArrayEntries.java | 0 .../fml/client/config/GuiMessageDialog.java | 0 .../fml/client/config/GuiSelectString.java | 0 .../client/config/GuiSelectStringEntries.java | 0 .../fml/client/config/GuiSlider.java | 0 .../client/config/GuiUnicodeGlyphButton.java | 0 .../fml/client/config/GuiUtils.java | 0 .../fml/client/config/HoverChecker.java | 0 .../fml/client/config/IConfigElement.java | 0 .../fml/client/event/ConfigChangedEvent.java | 0 .../fml/client/registry/ClientRegistry.java | 0 .../fml/client/registry/IRenderFactory.java | 0 .../client/registry/RenderingRegistry.java | 0 .../net/minecraftforge/fml/common/API.java | 0 .../fml/common/AutomaticEventSubscriber.java | 0 .../fml/common/CertificateHelper.java | 0 .../fml/common/ClassNameUtils.java | 0 .../fml/common/DummyModContainer.java | 0 .../common/DuplicateModsFoundException.java | 0 .../fml/common/EnhancedRuntimeException.java | 0 .../fml/common/FMLCommonHandler.java | 0 .../fml/common/FMLContainer.java | 0 .../fml/common/FMLContainerHolder.java | 0 .../net/minecraftforge/fml/common/FMLLog.java | 0 .../fml/common/FMLModContainer.java | 0 .../fml/common/ICrashCallable.java | 0 .../fml/common/IEntitySelectorFactory.java | 0 .../fml/common/IFMLHandledException.java | 0 .../fml/common/IFMLSidedHandler.java | 0 .../fml/common/IFuelHandler.java | 0 .../fml/common/ILanguageAdapter.java | 0 .../fml/common/IWorldGenerator.java | 0 .../fml/common/InjectedModContainer.java | 0 .../fml/common/LoadController.java | 0 .../net/minecraftforge/fml/common/Loader.java | 0 .../fml/common/LoaderException.java | 0 .../fml/common/LoaderExceptionModCrash.java | 0 .../fml/common/LoaderState.java | 0 .../fml/common/MCPDummyContainer.java | 0 .../fml/common/MetadataCollection.java | 0 .../fml/common/MinecraftDummyContainer.java | 0 .../fml/common/MissingModsException.java | 0 .../net/minecraftforge/fml/common/Mod.java | 0 .../fml/common/ModAPIManager.java | 0 .../fml/common/ModClassLoader.java | 0 .../fml/common/ModContainer.java | 0 .../fml/common/ModContainerFactory.java | 0 .../fml/common/ModMetadata.java | 0 .../fml/common/MultipleModsErrored.java | 0 .../common/ObfuscationReflectionHelper.java | 0 .../minecraftforge/fml/common/Optional.java | 0 .../fml/common/ProgressManager.java | 0 .../fml/common/ProxyInjector.java | 0 .../fml/common/SaveInspectionHandler.java | 0 .../minecraftforge/fml/common/SidedProxy.java | 0 .../fml/common/StartupQuery.java | 0 .../fml/common/TracingPrintStream.java | 0 .../fml/common/WorldAccessContainer.java | 0 .../WrongMinecraftVersionException.java | 0 .../minecraftforge/fml/common/ZipperUtil.java | 0 .../fml/common/asm/ASMTransformerWrapper.java | 0 .../fml/common/asm/FMLSanityChecker.java | 0 .../fml/common/asm/ReobfuscationMarker.java | 0 .../asm/transformers/AccessTransformer.java | 0 .../DeobfuscationTransformer.java | 0 .../EventSubscriberTransformer.java | 0 .../EventSubscriptionTransformer.java | 0 .../FieldRedirectTransformer.java | 0 .../ItemBlockSpecialTransformer.java | 0 .../transformers/ItemBlockTransformer.java | 0 .../transformers/ItemStackTransformer.java | 0 .../asm/transformers/LWJGLTransformer.java | 0 .../asm/transformers/MarkerTransformer.java | 0 .../asm/transformers/ModAPITransformer.java | 0 .../transformers/ModAccessTransformer.java | 0 .../asm/transformers/PatchingTransformer.java | 0 .../transformers/PotionEffectTransformer.java | 0 .../asm/transformers/SideTransformer.java | 0 .../SoundEngineFixTransformer.java | 0 .../asm/transformers/TerminalTransformer.java | 0 .../deobf/FMLDeobfuscatingRemapper.java | 0 .../deobf/FMLRemappingAdapter.java | 0 .../transformers/deobf/LZMAInputSupplier.java | 0 .../fml/common/discovery/ASMDataTable.java | 0 .../fml/common/discovery/ContainerType.java | 0 .../common/discovery/DirectoryDiscoverer.java | 0 .../fml/common/discovery/ITypeDiscoverer.java | 0 .../fml/common/discovery/JarDiscoverer.java | 0 .../fml/common/discovery/ModCandidate.java | 0 .../fml/common/discovery/ModDiscoverer.java | 0 .../common/discovery/asm/ASMModParser.java | 0 .../common/discovery/asm/ModAnnotation.java | 0 .../discovery/asm/ModAnnotationVisitor.java | 0 .../common/discovery/asm/ModClassVisitor.java | 0 .../common/discovery/asm/ModFieldVisitor.java | 0 .../discovery/asm/ModMethodVisitor.java | 0 .../fml/common/discovery/json/ASMInfo.java | 0 .../discovery/json/JsonAnnotationLoader.java | 0 .../common/event/FMLConstructionEvent.java | 0 .../fml/common/event/FMLEvent.java | 0 .../event/FMLFingerprintViolationEvent.java | 0 .../common/event/FMLInitializationEvent.java | 0 .../fml/common/event/FMLInterModComms.java | 0 .../common/event/FMLLoadCompleteEvent.java | 0 .../fml/common/event/FMLLoadEvent.java | 0 .../fml/common/event/FMLModDisabledEvent.java | 0 .../common/event/FMLModIdMappingEvent.java | 0 .../event/FMLPostInitializationEvent.java | 0 .../event/FMLPreInitializationEvent.java | 0 .../event/FMLServerAboutToStartEvent.java | 0 .../common/event/FMLServerStartedEvent.java | 0 .../common/event/FMLServerStartingEvent.java | 0 .../common/event/FMLServerStoppedEvent.java | 0 .../common/event/FMLServerStoppingEvent.java | 0 .../fml/common/event/FMLStateEvent.java | 0 .../common/eventhandler/ASMEventHandler.java | 0 .../fml/common/eventhandler/Cancelable.java | 0 .../fml/common/eventhandler/Event.java | 0 .../fml/common/eventhandler/EventBus.java | 0 .../eventhandler/EventListenerFactory.java | 0 .../common/eventhandler/EventPriority.java | 0 .../eventhandler/FMLThrowingEventBus.java | 0 .../fml/common/eventhandler/GenericEvent.java | 0 .../common/eventhandler/IContextSetter.java | 0 .../eventhandler/IEventExceptionHandler.java | 0 .../common/eventhandler/IEventListener.java | 0 .../common/eventhandler/IGenericEvent.java | 0 .../fml/common/eventhandler/ListenerList.java | 0 .../common/eventhandler/SubscribeEvent.java | 0 .../fml/common/gameevent/InputEvent.java | 0 .../fml/common/gameevent/PlayerEvent.java | 0 .../fml/common/gameevent/TickEvent.java | 0 .../fml/common/launcher/FMLDeobfTweaker.java | 0 .../FMLInjectionAndSortingTweaker.java | 0 .../fml/common/launcher/FMLServerTweaker.java | 0 .../fml/common/launcher/FMLTweaker.java | 0 .../fml/common/launcher/Yggdrasil.java | 0 .../fml/common/network/ByteBufUtils.java | 0 .../common/network/FMLEmbeddedChannel.java | 0 .../fml/common/network/FMLEventChannel.java | 0 .../FMLIndexedMessageToMessageCodec.java | 0 .../fml/common/network/FMLNetworkEvent.java | 0 .../common/network/FMLNetworkException.java | 0 .../common/network/FMLOutboundHandler.java | 0 .../fml/common/network/IGuiHandler.java | 0 .../common/network/NetworkCheckHandler.java | 0 .../network/NetworkEventFiringHandler.java | 0 .../network/NetworkHandshakeEstablished.java | 0 .../fml/common/network/NetworkRegistry.java | 0 .../common/network/PacketLoggingHandler.java | 0 .../handshake/ChannelRegistrationHandler.java | 0 .../handshake/FMLHandshakeClientState.java | 0 .../network/handshake/FMLHandshakeCodec.java | 0 .../handshake/FMLHandshakeMessage.java | 0 .../handshake/FMLHandshakeServerState.java | 0 .../network/handshake/HandshakeInjector.java | 0 .../handshake/HandshakeMessageHandler.java | 0 .../network/handshake/IHandshakeState.java | 0 .../network/handshake/NetworkDispatcher.java | 0 .../network/internal/EntitySpawnHandler.java | 0 .../common/network/internal/FMLMessage.java | 0 .../network/internal/FMLNetworkHandler.java | 0 .../network/internal/FMLProxyPacket.java | 0 .../network/internal/FMLRuntimeCodec.java | 0 .../internal/HandshakeCompletionHandler.java | 0 .../network/internal/NetworkModHolder.java | 0 .../network/internal/OpenGuiHandler.java | 0 .../common/network/simpleimpl/IMessage.java | 0 .../network/simpleimpl/IMessageHandler.java | 0 .../network/simpleimpl/MessageContext.java | 0 .../SimpleChannelHandlerWrapper.java | 0 .../simpleimpl/SimpleIndexedCodec.java | 0 .../simpleimpl/SimpleNetworkWrapper.java | 0 .../fml/common/patcher/ClassPatch.java | 0 .../fml/common/patcher/ClassPatchManager.java | 0 .../fml/common/patcher/GenDiffSet.java | 0 .../fml/common/registry/EntityEntry.java | 0 .../common/registry/EntityEntryBuilder.java | 0 .../fml/common/registry/EntityRegistry.java | 0 .../ExistingSubstitutionException.java | 0 .../fml/common/registry/ForgeRegistries.java | 0 .../fml/common/registry/GameRegistry.java | 0 .../registry/IEntityAdditionalSpawnData.java | 0 .../fml/common/registry/IThrowableEntity.java | 0 .../registry/ItemStackHolderInjector.java | 0 .../common/registry/ItemStackHolderRef.java | 0 .../fml/common/registry/VillagerRegistry.java | 0 .../fml/common/thread/SidedThreadGroup.java | 0 .../fml/common/thread/SidedThreadGroups.java | 0 .../fml/common/toposort/ModSorter.java | 0 .../common/toposort/ModSortingException.java | 0 .../fml/common/toposort/TopologicalSort.java | 0 .../common/versioning/ArtifactVersion.java | 0 .../common/versioning/ComparableVersion.java | 0 .../versioning/DefaultArtifactVersion.java | 0 .../common/versioning/DependencyParser.java | 0 .../InvalidVersionSpecificationException.java | 0 .../fml/common/versioning/Restriction.java | 0 .../fml/common/versioning/VersionParser.java | 0 .../fml/common/versioning/VersionRange.java | 0 .../fml/relauncher/CoreModManager.java | 0 .../fml/relauncher/FMLCorePlugin.java | 0 .../fml/relauncher/FMLInjectionData.java | 0 .../fml/relauncher/FMLLaunchHandler.java | 0 .../fml/relauncher/FMLRelaunchLog.java | 0 .../fml/relauncher/FileListHelper.java | 0 .../fml/relauncher/IFMLCallHook.java | 0 .../fml/relauncher/IFMLLoadingPlugin.java | 0 .../fml/relauncher/ReflectionHelper.java | 0 .../fml/relauncher/ServerLaunchWrapper.java | 0 .../minecraftforge/fml/relauncher/Side.java | 0 .../fml/relauncher/SideOnly.java | 0 .../fml/relauncher/libraries/Artifact.java | 0 .../relauncher/libraries/LibraryManager.java | 0 .../relauncher/libraries/LinkRepository.java | 0 .../relauncher/libraries/MemoryModList.java | 0 .../fml/relauncher/libraries/ModList.java | 0 .../fml/relauncher/libraries/Repository.java | 0 .../relauncher/libraries/SnapshotJson.java | 0 .../delta/ByteBufferSeekableSource.java | 0 .../repackage/com/nothome/delta/Checksum.java | 0 .../com/nothome/delta/DebugDiffWriter.java | 0 .../repackage/com/nothome/delta/Delta.java | 0 .../com/nothome/delta/DiffWriter.java | 0 .../com/nothome/delta/GDiffPatcher.java | 0 .../com/nothome/delta/GDiffWriter.java | 0 .../com/nothome/delta/PatchException.java | 0 .../delta/RandomAccessFileSeekableSource.java | 0 .../com/nothome/delta/SeekableSource.java | 0 .../fml/server/FMLServerHandler.java | 0 .../items/CapabilityItemHandler.java | 0 .../minecraftforge/items/IItemHandler.java | 0 .../items/IItemHandlerModifiable.java | 0 .../items/ItemHandlerHelper.java | 0 .../items/ItemStackHandler.java | 0 .../minecraftforge/items/SlotItemHandler.java | 0 .../items/VanillaDoubleChestItemHandler.java | 0 .../items/VanillaHopperItemHandler.java | 0 .../items/VanillaInventoryCodeHooks.java | 0 .../items/wrapper/CombinedInvWrapper.java | 0 .../items/wrapper/EmptyHandler.java | 0 .../items/wrapper/EntityArmorInvWrapper.java | 0 .../wrapper/EntityEquipmentInvWrapper.java | 0 .../items/wrapper/EntityHandsInvWrapper.java | 0 .../items/wrapper/InvWrapper.java | 0 .../items/wrapper/PlayerArmorInvWrapper.java | 0 .../items/wrapper/PlayerInvWrapper.java | 0 .../items/wrapper/PlayerMainInvWrapper.java | 0 .../wrapper/PlayerOffhandInvWrapper.java | 0 .../items/wrapper/RangedWrapper.java | 0 .../items/wrapper/SidedInvWrapper.java | 0 .../net/minecraftforge/oredict/DyeUtils.java | 0 .../minecraftforge/oredict/OreDictionary.java | 0 .../minecraftforge/oredict/OreIngredient.java | 0 .../minecraftforge/oredict/RecipeSorter.java | 0 .../oredict/ShapedOreRecipe.java | 0 .../oredict/ShapelessOreRecipe.java | 0 .../registries/DataSerializerEntry.java | 0 .../registries/ForgeRegistry.java | 0 .../minecraftforge/registries/GameData.java | 0 .../registries/IForgeRegistry.java | 0 .../registries/IForgeRegistryEntry.java | 0 .../registries/IForgeRegistryInternal.java | 0 .../registries/IForgeRegistryModifiable.java | 0 .../registries/ILockableRegistry.java | 0 .../registries/IRegistryDelegate.java | 0 .../NamespacedDefaultedWrapper.java | 0 .../registries/NamespacedWrapper.java | 0 .../registries/ObjectHolderRef.java | 0 .../registries/ObjectHolderRegistry.java | 0 .../registries/RegistryBuilder.java | 0 .../registries/RegistryDelegate.java | 0 .../registries/RegistryManager.java | 0 .../server/ForgeTimeTracker.java | 0 .../server/command/ChunkGenWorker.java | 0 .../server/command/CommandDimensions.java | 0 .../server/command/CommandEntity.java | 0 .../server/command/CommandGenerate.java | 0 .../server/command/CommandSetDimension.java | 0 .../server/command/CommandTps.java | 0 .../server/command/CommandTrack.java | 0 .../server/command/CommandTreeBase.java | 0 .../server/command/CommandTreeHelp.java | 0 .../server/command/ForgeCommand.java | 0 .../server/command/TextComponentHelper.java | 0 .../server/command/package-info.java | 0 .../console/ConsoleCommandCompleter.java | 0 .../server/console/TerminalHandler.java | 0 .../permission/DefaultPermissionHandler.java | 0 .../permission/DefaultPermissionLevel.java | 0 .../server/permission/IPermissionHandler.java | 0 .../server/permission/PermissionAPI.java | 0 .../permission/context/AreaContext.java | 0 .../permission/context/BlockPosContext.java | 0 .../server/permission/context/Context.java | 0 .../server/permission/context/ContextKey.java | 0 .../permission/context/ContextKeys.java | 0 .../server/permission/context/IContext.java | 0 .../permission/context/PlayerContext.java | 0 .../permission/context/TargetContext.java | 0 .../permission/context/WorldContext.java | 0 .../permission/context/package-info.java | 0 .../server/permission/package-info.java | 0 .../HighlightErrorConverter.java | 0 .../MinecraftFormattingConverter.java | 0 .../TerminalConsoleAppender.java | 0 .../server/terminalconsole/package-info.java | 0 .../util/LoggerNamePatternSelector.java | 0 .../terminalconsole/util/package-info.java | 0 .../server/timings/ForgeTimings.java | 0 .../server/timings/TimeTracker.java | 0 .../paulscode/sound/codecs/CodecIBXM.java | 0 .../core/config/plugins/Log4j2Plugins.dat | Bin ...rg.spongepowered.asm.service.IMixinService | 0 ...powered.asm.service.IMixinServiceBootstrap | 0 .../resources/assets/cleanroom/background.png | Bin .../resources/assets/cleanroom/banner.png | Bin .../main/resources/assets/cleanroom/icon.png | Bin .../assets/cleanroom/lang/de_de.lang | 0 .../assets/cleanroom/lang/en_au.lang | 0 .../assets/cleanroom/lang/en_us.lang | 0 .../assets/cleanroom/lang/pl_pl.lang | 0 .../assets/cleanroom/lang/ru_ru.lang | 0 .../assets/cleanroom/lang/zh_cn.lang | 0 .../cleanroom/textures/gui/checkbox.png | Bin .../assets/cleanroom/textures/gui/icons.png | Bin .../cleanroom/textures/gui/minecraft.png | Bin .../textures/gui/missing_background.png | Bin .../cleanroom/textures/gui/missing_banner.png | Bin .../textures/gui/sprites/dropdown/item.png | Bin .../gui/sprites/dropdown/item_highlighted.png | Bin .../textures/gui/sprites/widget/button.png | Bin .../gui/sprites/widget/button_disabled.png | Bin .../gui/sprites/widget/button_highlighted.png | Bin .../resources/assets/configanytime/icon.png | Bin .../assets/fml/textures/gui/forge.png | Bin .../assets/fml/textures/gui/icons.png | Bin .../assets/forge/blockstates/dynbucket.json | 0 .../resources/assets/forge/lang/README.txt | 0 .../resources/assets/forge/lang/en_pt.lang | 0 .../resources/assets/forge/lang/en_us.lang | 0 .../resources/assets/forge/lang/es_es.lang | 0 .../resources/assets/forge/lang/fr_fr.lang | 0 .../resources/assets/forge/lang/ja_jp.lang | 0 .../resources/assets/forge/lang/ko_kr.lang | 0 .../resources/assets/forge/lang/ru_ru.lang | 0 .../resources/assets/forge/lang/zh_cn.lang | 0 .../resources/assets/forge/lang/zh_tw.lang | 0 .../assets/forge/models/item/bucket.json | 0 .../assets/forge/models/item/bucket_milk.json | 0 .../textures/gui/version_check_icons.png | Bin .../forge/textures/items/bucket_fluid.png | Bin .../items/vanilla_bucket_cover_mask.png | Bin .../resources/assets/mixinbooter/icon.png | Bin .../forge/src}/main/resources/cleanmix.info | 0 .../forge/src}/main/resources/forge.exc | 0 .../forge/src}/main/resources/forge.srg | 0 .../forge/src}/main/resources/forge_at.cfg | 0 .../forge/src}/main/resources/forge_logo.png | Bin .../forge/src}/main/resources/log4j2.xml | 0 .../src}/main/resources/log4j2_server.xml | 0 .../src}/main/resources/logging.properties | 0 .../forge/src}/main/resources/mcplogo.png | Bin .../forge/src}/main/resources/mcpmod.info | 0 .../src}/main/resources/mixinbooter.info | 0 .../forge/src}/main/resources/pack.mcmeta | 0 .../forge/src}/main/resources/url.png | Bin .../minecraftforge/debug/PotionEventTest.java | 0 .../debug/block/BasePlaceEventTest.java | 0 .../debug/block/FarmlandTrampleEventTest.java | 0 .../debug/block/FarmlandWaterTest.java | 0 .../debug/block/MaterialFogColorTest.java | 0 .../debug/block/NeighborNotifyEventTest.java | 0 .../debug/block/ParticleEffectsTest.java | 0 .../debug/block/PathNodeTypeTest.java | 0 .../debug/block/PlaceEventTest.java | 0 .../debug/block/PortalSpawnEventTest.java | 0 .../debug/block/SlipperinessTest.java | 0 .../debug/block/StickyBlockTest.java | 0 .../debug/block/package-info.java | 0 .../debug/chat/ClientChatEventTest.java | 0 .../debug/chat/ClientCommandTest.java | 0 .../debug/chat/CommandTreeBaseTest.java | 0 .../debug/chat/EntitySelectorFactoryTest.java | 0 .../debug/chat/package-info.java | 0 .../client/CustomTextureAtlasSpriteTest.java | 0 .../debug/client/FOVModifierEventTest.java | 0 .../client/SearchableCreativeTabTest.java | 0 .../gui/ContainerDrawForegroundEventTest.java | 0 .../client/gui/TooltipColorEventTest.java | 0 .../debug/client/model/AnimatedModelTest.java | 0 .../client/model/BlockstateRetextureTest.java | 0 .../model/ForgeBlockStatesLoaderTest.java | 0 .../client/model/ItemLayerModelTest.java | 0 .../client/model/ItemModelConflictTest.java | 0 .../client/model/ItemModelGenerationTest.java | 0 .../client/model/ModelBakeEventTest.java | 0 .../debug/client/model/ModelFluidTest.java | 0 .../client/model/ModelLoaderRegistryTest.java | 0 .../client/model/MultiLayerModelTest.java | 0 .../debug/client/model/package-info.java | 0 .../debug/client/package-info.java | 0 .../rendering/FastTESRTransparentTest.java | 0 .../debug/client/rendering/ItemTESRTest.java | 0 .../rendering/VertexBufferNormalTest.java | 0 .../debug/client/rendering/package-info.java | 0 .../debug/entity/BlockEntityUpdateTest.java | 0 .../EntityTravelToDimensionEventTest.java | 0 .../entity/GetCollisionBoxesEventTest.java | 0 .../entity/ProjectileImpactEventTest.java | 0 .../entity/living/AnimalTameEventTest.java | 0 .../debug/entity/living/AttackEventTest.java | 0 .../living/BabyEntitySpawnEventTest.java | 0 .../entity/living/CheckSpawnEventTest.java | 0 .../living/CustomSpawnPlacementTest.java | 0 .../debug/entity/living/DamageEventTest.java | 0 .../living/EquipmentChangeEventTest.java | 0 .../entity/living/KnockBackEventTest.java | 0 .../entity/living/MobGriefingEventTest.java | 0 .../debug/entity/living/SpecialSpawnTest.java | 0 .../entity/living/VillagerProfessionTest.java | 0 .../debug/entity/living/package-info.java | 0 .../debug/entity/package-info.java | 0 .../entity/player/CriticalHitEventTest.java | 0 .../debug/entity/player/DamageReworkTest.java | 0 .../entity/player/ItemPickupEventTest.java | 0 .../player/PlayerInteractEventTest.java | 0 .../entity/player/PlayerSetSpawnTest.java | 0 .../player/ReachDistanceAttributeTest.java | 0 .../entity/player/SwimSpeedAttributeTest.java | 0 .../debug/entity/player/package-info.java | 0 .../debug/fluid/ColoredFluidTest.java | 0 .../fluid/CreateFluidSourceEventTest.java | 0 .../debug/fluid/DynBucketTest.java | 0 .../debug/fluid/FluidPlaceBlockEventTest.java | 0 .../debug/fluid/FluidPlacementTest.java | 0 .../debug/fluid/ItemFluidHandlerTest.java | 0 .../debug/fluid/package-info.java | 0 .../debug/gameplay/AnytimeSleepingTest.java | 0 .../gameplay/BrewingRecipeRegistryTest.java | 0 .../debug/gameplay/ConstantLoadingTest.java | 0 .../debug/gameplay/CraftingSystemTest.java | 0 .../gameplay/DifficultyChangeEventTest.java | 0 .../debug/gameplay/DynamicBannerTest.java | 0 .../EnchantmentLevelSetEventTest.java | 0 .../FurnaceFuelBurnTimeEventTest.java | 0 .../debug/gameplay/GiveItemToPlayerTest.java | 0 .../debug/gameplay/InputUpdateEventTest.java | 0 .../debug/gameplay/NoBedSleepingTest.java | 0 .../debug/gameplay/PotionRegistryTest.java | 0 .../debug/gameplay/RecipeMatchingTest.java | 0 .../advancement/AdvancementCriterionTest.java | 0 .../advancement/AdvancementEventTest.java | 0 .../AdvancementsPaginationTest.java | 0 .../advancement/OredictTriggerTest.java | 0 .../gameplay/advancement/package-info.java | 0 .../gameplay/loot/LootContextTweaksTest.java | 0 .../gameplay/loot/LootTableLoadEventTest.java | 0 .../debug/gameplay/loot/LootTableTest.java | 0 .../debug/gameplay/loot/package-info.java | 0 .../debug/gameplay/package-info.java | 0 .../debug/item/BonemealEventTest.java | 0 .../item/CanApplyAtEnchantingTableTest.java | 0 .../item/CanDestroyBlocksInCreativeTest.java | 0 .../debug/item/ContinuousUseItemTest.java | 0 .../debug/item/CustomRarityTest.java | 0 .../debug/item/HorseArmorTest.java | 0 .../debug/item/IsBookEnchantableTest.java | 0 .../debug/item/ItemFishedEventTest.java | 0 .../debug/item/MapDataTest.java | 0 .../debug/item/MendingRepairTest.java | 0 .../debug/item/NBTShareTagTest.java | 0 .../debug/item/OnItemUseFirstTest.java | 0 .../debug/item/PotionCurabilityTest.java | 0 .../debug/item/PotionShouldRenderTest.java | 0 .../minecraftforge/debug/item/ShieldTest.java | 0 .../debug/item/package-info.java | 0 .../debug/misc/EnumPlantTypeTest.java | 0 .../debug/misc/package-info.java | 0 .../debug/mod/CapabilityTest.java | 0 .../debug/mod/ClientLoadingExceptionTest.java | 0 .../debug/mod/ConfigAnnotationTest.java | 0 .../debug/mod/ObjectHolderAnnotationTest.java | 0 .../debug/mod/PermissionTest.java | 0 .../debug/mod/RegistryOverrideTest.java | 0 .../debug/mod/package-info.java | 0 .../debug/network/BigNetworkMessageTest.java | 0 .../debug/network/TrackingTargetTest.java | 0 .../debug/network/package-info.java | 0 .../minecraftforge/debug/package-info.java | 0 .../debug/util/ModNameTooltip.java | 0 .../debug/util/RotatingWrench.java | 0 .../debug/util/TextureDumper.java | 0 .../debug/util/package-info.java | 0 .../village/MerchantTradeOffersEventTest.java | 0 .../debug/village/VillageSiegeEventTest.java | 0 .../debug/world/ChunkCapabilityTest.java | 0 .../debug/world/ChunkWatchEventTest.java | 0 .../debug/world/DecorateEventDebug.java | 0 .../debug/world/SpawnDimensionTest.java | 0 .../debug/world/TileEntityLoadingTest.java | 0 .../debug/world/WorldCapabilityTest.java | 0 .../world/WorldProviderCanSleepAtTest.java | 0 .../debug/world/package-info.java | 0 .../fml/common/eventhandler/EventBusTest.java | 0 .../eventhandler/impl/AbnormalListeners.java | 0 .../eventhandler/impl/ExampleEvent.java | 0 .../eventhandler/impl/InstanceListeners.java | 0 .../eventhandler/impl/StaticListeners.java | 0 .../registry/BlockStateMappingsTest.java | 0 .../registry/DummyBlockReplacementTest.java | 0 .../fml/common/registry/ForgeTestRunner.java | 0 .../fml/common/registry/FreezingTests.java | 0 ...temBlockSubstitutionRemoveRestoreTest.java | 0 .../common/registry/RegistryTestSuite.java | 0 .../registry/SubstitutionInjectionTest.java | 0 .../SubstitutionRemoveRestoreTest.java | 0 .../common/registry/VanillaRegistryTests.java | 0 .../fml/debug/FaultyCoreMod.java | 0 .../fml/test/DependencyParserTest.java | 0 .../fml/test/ForgeNetworkTestMod.java | 0 .../fml/test/SpecialSpawnEventTest.java | 0 .../minecraftforge/fml/test/TestNetStuff.java | 0 .../TestNetworkHandshake.java | 0 .../fml/test/simplenet/SimpleNetHandler1.java | 0 .../fml/test/simplenet/SimpleNetHandler2.java | 0 .../test/simplenet/SimpleNetTestMessage1.java | 0 .../test/simplenet/SimpleNetTestMessage2.java | 0 .../fml/test/simplenet/SimpleNetTester.java | 0 .../test/BiomeSpawnableListTest.java | 0 .../test/BufferBuilderExpansionTest.java | 0 .../test/ConfigurationTest.java | 0 .../minecraftforge/test/EnumHelperTest.java | 0 .../test/SelectorHandlerTest.java | 0 .../test/SliderConfigElementTest.java | 0 .../test/TestAnnotationParser.java | 0 .../minecraftforge/test/TextTableTest.java | 0 .../net/minecraftforge/test/package-info.java | 0 .../advancements/root.json | 0 .../advancements/a1/root.json | 0 .../advancements/a10/root.json | 0 .../advancements/a11/root.json | 0 .../advancements/a12/root.json | 0 .../advancements/a13/root.json | 0 .../advancements/a14/root.json | 0 .../advancements/a15/root.json | 0 .../advancements/a16/root.json | 0 .../advancements/a17/root.json | 0 .../advancements/a18/root.json | 0 .../advancements/a19/root.json | 0 .../advancements/a2/root.json | 0 .../advancements/a20/root.json | 0 .../advancements/a21/root.json | 0 .../advancements/a22/root.json | 0 .../advancements/a23/root.json | 0 .../advancements/a24/root.json | 0 .../advancements/a25/root.json | 0 .../advancements/a26/root.json | 0 .../advancements/a27/root.json | 0 .../advancements/a28/root.json | 0 .../advancements/a29/root.json | 0 .../advancements/a3/root.json | 0 .../advancements/a30/root.json | 0 .../advancements/a31/root.json | 0 .../advancements/a32/root.json | 0 .../advancements/a33/root.json | 0 .../advancements/a34/root.json | 0 .../advancements/a35/root.json | 0 .../advancements/a36/root.json | 0 .../advancements/a37/root.json | 0 .../advancements/a38/root.json | 0 .../advancements/a39/root.json | 0 .../advancements/a4/root.json | 0 .../advancements/a40/root.json | 0 .../advancements/a41/root.json | 0 .../advancements/a42/root.json | 0 .../advancements/a43/root.json | 0 .../advancements/a44/root.json | 0 .../advancements/a45/root.json | 0 .../advancements/a46/root.json | 0 .../advancements/a47/root.json | 0 .../advancements/a48/root.json | 0 .../advancements/a49/root.json | 0 .../advancements/a5/root.json | 0 .../advancements/a50/root.json | 0 .../advancements/a51/root.json | 0 .../advancements/a52/root.json | 0 .../advancements/a53/root.json | 0 .../advancements/a54/root.json | 0 .../advancements/a55/root.json | 0 .../advancements/a56/root.json | 0 .../advancements/a57/root.json | 0 .../advancements/a58/root.json | 0 .../advancements/a59/root.json | 0 .../advancements/a6/root.json | 0 .../advancements/a60/root.json | 0 .../advancements/a61/root.json | 0 .../advancements/a62/root.json | 0 .../advancements/a63/root.json | 0 .../advancements/a64/root.json | 0 .../advancements/a7/root.json | 0 .../advancements/a8/root.json | 0 .../advancements/a9/root.json | 0 .../blockstates/box_block.json | 0 .../assets/config_test/lang/en_US.lang | 0 .../constantloadingtest/test/_constants.json | 0 .../recipes/_factories.json | 0 .../conditions_property_not_array.json | 0 .../recipes/oak_planks_from_logs.json | 0 .../blockstates/custom_sprite_block.json | 0 .../models/block/custom_sprite_block.json | 0 .../dynbuckettest/blockstates/simpletank.json | 0 .../blockstates/test_block.json | 0 .../blockstates/slime.json | 0 .../textures/slime_flow.png | Bin .../textures/slime_flow.png.mcmeta | 0 .../textures/slime_overlay.png | Bin .../textures/slime_still.png | Bin .../textures/slime_still.png.mcmeta | 0 .../blockstates/slime.json | 0 .../fogcolorinsidematerialtest/pack.mcmeta | 0 .../test_fluid.json | 0 .../textures/slime_flow.png | Bin .../textures/slime_flow.png.mcmeta | 0 .../textures/slime_overlay.png | Bin .../textures/slime_still.png | Bin .../textures/slime_still.png.mcmeta | 0 .../assets/forge/blockstates/dynbottle.json | 0 .../assets/forge/recipes/_constants.json | 0 .../assets/forge/recipes/ore_shaped.json | 0 .../assets/forge/recipes/shapeless.json | 0 .../forge/recipes/shapeless_constant.json | 0 .../forge/recipes/shapeless_damageable.json | 0 .../assets/forge/recipes/shapeless_ore.json | 0 .../forge/recipes/shapeless_wildcard.json | 0 .../forge/textures/blocks/milk_flow.png | Bin .../textures/blocks/milk_flow.png.mcmeta | 0 .../forge/textures/blocks/milk_still.png | Bin .../textures/blocks/milk_still.png.mcmeta | 0 .../blockstates/cobblestone_wall.json | 0 .../blockstates/mossy_cobblestone_wall.json | 0 .../models/block/wall_connect.json | 0 .../blockstates/custom_slime_block.json | 0 .../lang/en_US.lang | 0 .../models/block/blue_slime_block.json | 0 .../models/block/obsidian_slime_block.json | 0 .../models/item/blue_slime_block.json | 0 .../models/item/obsidian_slime_block.json | 0 .../textures/blocks/blue_slime_block.png | Bin .../textures/blocks/obsidian_slime_block.png | Bin .../blockstates/finite_fluid_block.json | 0 .../blockstates/test_item.json | 0 .../blockstates/custom_model_block.json | 0 .../armatures/block/engine_ring.json | 0 .../armatures/block/rotatest.json | 0 .../asms/block/chest.json | 0 .../asms/block/engine.json | 0 .../asms/block/engine2.json | 0 .../asms/block/rotatest.json | 0 .../blockstates/rotatest.json | 0 .../blockstates/test_animation_block.json | 0 .../models/block/engine.json | 0 .../models/block/engine_ring.json | 0 .../models/block/rotatest.json | 0 .../blockstates/test_fluid_block.json | 0 .../blockstates/custom_model_block.json | 0 .../blockstates/obj_custom_data_block.json | 0 .../blockstates/obj_direction_block.json | 0 .../blockstates/obj_direction_eye.json | 0 .../blockstates/obj_dynamic_eye.json | 0 .../blockstates/obj_tesseract_block.json | 0 .../blockstates/obj_vertex_coloring1.json | 0 .../blockstates/obj_vertex_coloring2.json | 0 .../models/block/chest.b3d | Bin .../models/block/direction_test.mtl | 0 .../models/block/direction_test.obj | 0 .../models/block/eye.mtl | 0 .../models/block/eye.obj | 0 .../models/block/fancy_fence.mtl | 0 .../models/block/fancy_fence.obj | 0 .../models/block/tesseract.mtl | 0 .../models/block/tesseract.obj | 0 .../models/block/untitled2.b3d | Bin .../models/block/vertex_coloring.mtl | 0 .../models/block/vertex_coloring.obj | 0 .../textures/direction_test_arrow.png | Bin .../textures/direction_test_arrow_top.png | Bin .../textures/direction_test_back.png | Bin .../textures/direction_test_front.png | Bin .../textures/eye.png | Bin .../textures/eye128.png | Bin .../textures/texture.png | Bin .../blockstates/test_layer_block.json | 0 .../models/item/sleeping_pill.json | 0 .../models/item/flammable_gold_shovel.json | 0 .../models/item/unburnable_wood_shovel.json | 0 .../assets/horse_armor_test/lang/en_US.lang | 0 .../models/item/test_armor.json | 0 .../textures/entity/horse/armor/test.png | Bin .../textures/items/test_armor.png | Bin .../models/item/item_test.json | 0 .../blockstates/test.json | 0 .../models/block/test.json | 0 .../models/item/test.json | 0 .../models/item/animation_test.json | 0 .../models/item/intersection_test.json | 0 .../models/item/opacity_test.json | 0 .../models/item/overlap_test.json | 0 .../models/item/pattern_test.json | 0 .../textures/items/animation_test.png | Bin .../textures/items/animation_test.png.mcmeta | 0 .../textures/items/intersection_test.png | Bin .../textures/items/opacity_test.png | Bin .../textures/items/overlap_test.png | Bin .../textures/items/pattern_test.png | Bin .../advancements/test/root.json | 0 .../chests/custom_spawn_bonus_chest.json | 0 .../models/item/nbt_share_tag_item.json | 0 .../models/item/test_item.json | 0 .../advancements/recipes/wood_unlock_tnt.json | 0 .../textures/entity/test_villager.png | Bin .../textures/entity/zombie_test_villager.png | Bin .../recipetest/recipes/tool_complex.json | 0 .../recipetest/recipes/tool_simple.json | 0 .../assets/shield_test/lang/en_US.lang | 0 .../models/item/diamond_shield.json | 0 .../models/item/diamond_shield_blocking.json | 0 .../models/item/test_wrench.json | 0 .../textures/items/test_wrench.png | Bin .../forge/src}/test/resources/mcmod.info | 0 {projects => module}/kirino | 0 .../java/zone/rong/mixinbooter/Context.java | 0 .../rong/mixinbooter/IEarlyMixinLoader.java | 0 .../rong/mixinbooter/ILateMixinLoader.java | 0 .../mixinbooter/IMixinConfigHijacker.java | 0 .../mixinbooter/MixinBooterModContainer.java | 0 .../rong/mixinbooter/MixinBooterPlugin.java | 0 .../zone/rong/mixinbooter/MixinLoader.java | 0 .../main/java/zone/rong/mixinbooter/Tags.java | 0 .../mixinbooter/service/ModDiscoverer.java | 0 .../rong/mixinbooter/util/Environment.java | 0 projects/cleanroom/build.gradle | 1105 ----------------- projects/mcp/build.gradle | 16 - projects/minecraft/build.gradle | 59 - settings.gradle | 26 +- 1196 files changed, 326 insertions(+), 2641 deletions(-) delete mode 100644 buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/BytecodeFinder.groovy delete mode 100644 buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CheckAccessTransformers.groovy delete mode 100644 buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CheckExcs.groovy delete mode 100644 buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CheckPatches.groovy delete mode 100644 buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CheckSAS.groovy delete mode 100644 buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/ClosureHelper.groovy delete mode 100644 buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CreateMMCPackTask.groovy delete mode 100644 buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CrowdinTask.groovy delete mode 100644 buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/DownloadLibrariesTask.groovy delete mode 100644 buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/FieldCompareFinder.groovy delete mode 100644 buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/ObjectTarget.groovy delete mode 100644 mmcpack-template/.packignore delete mode 100644 mmcpack-template/cleanroom.png delete mode 100644 mmcpack-template/instance.cfg delete mode 100644 mmcpack-template/mmc-pack.json delete mode 100644 mmcpack-template/patches/net.minecraftforge.json delete mode 100644 mmcpack-template/patches/org.lwjgl3.json rename {src => module/cleanroom/src}/main/java/com/cleanroommc/boot/Main.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/boot/MainClient.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/boot/MainServer.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/ICU4JInstances.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/IMEHandler.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/LoadingTracker.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/ime/DummyIMEHandler.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/ime/WaylandIMEhandler.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/ime/WindowsIMEHandler.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/ime/X11IMEHandler.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/windows/DwmApi.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/windows/NtDll.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/windows/TaskbarApi.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/windows/WindowsProperties.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/windows/WindowsTheme.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/common/CleanroomContainer.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/common/CleanroomEnvironment.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/common/ConfigAnytimeContainer.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/common/PatchModPresentChecker.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/configanytime/ConfigAnytime.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/hackery/Reflection.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/hackery/ReflectionHackery.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/hackery/enums/EnumHackery.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/loader/LanguageAdapterRegistry.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/loader/javafix/UUIDFix.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/loader/scripting/CleanroomScriptEngineManager.java (100%) rename {src => module/cleanroom/src}/test/java/com/cleanroommc/hackery/EnumHackeryTest.java (100%) rename {src => module/forge/src}/main/java/ibxm/Channel.java (100%) rename {src => module/forge/src}/main/java/ibxm/Envelope.java (100%) rename {src => module/forge/src}/main/java/ibxm/FastTracker2.java (100%) rename {src => module/forge/src}/main/java/ibxm/IBXM.java (100%) rename {src => module/forge/src}/main/java/ibxm/Instrument.java (100%) rename {src => module/forge/src}/main/java/ibxm/LogTable.java (100%) rename {src => module/forge/src}/main/java/ibxm/Module.java (100%) rename {src => module/forge/src}/main/java/ibxm/Pattern.java (100%) rename {src => module/forge/src}/main/java/ibxm/Player.java (100%) rename {src => module/forge/src}/main/java/ibxm/ProTracker.java (100%) rename {src => module/forge/src}/main/java/ibxm/Sample.java (100%) rename {src => module/forge/src}/main/java/ibxm/ScreamTracker3.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/advancements/critereon/ItemPredicates.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/advancements/critereon/OredictItemPredicate.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/classloading/FMLForgePlugin.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/ClientCommandHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/CloudRenderer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/EnumHelperClient.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/FluidContainerColorer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/ForgeClientHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/ForgeHooksClient.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/GuiIngameForge.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/IClientCommand.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/IRenderContextHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/IRenderHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/ItemModelMesherForge.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/MinecraftForgeClient.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/ClientChatEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/ClientChatReceivedEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/ColorHandlerEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/DrawBlockHighlightEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/EntityViewRenderEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/FOVUpdateEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/GuiContainerEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/GuiOpenEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/GuiScreenEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/InputUpdateEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/ModelBakeEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/ModelRegistryEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/MouseEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/PlayerSPPushOutOfBlocksEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/RenderArmEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/RenderBlockOverlayEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/RenderGameOverlayEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/RenderHandEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/RenderItemInFrameEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/RenderLivingEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/RenderPlayerEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/RenderSpecificHandEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/RenderTooltipEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/RenderWorldLastEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/ScreenshotEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/TextureStitchEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/sound/PlaySoundEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/sound/PlaySoundSourceEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/sound/PlayStreamingSourceEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/sound/SoundEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/sound/SoundLoadEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/event/sound/SoundSetupEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/gui/ForgeGuiFactory.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/gui/NotificationModUpdateScreen.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/Attributes.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/BakedItemModel.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/BakedModelWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/BlockStateLoader.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/FancyMissingModel.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/ForgeBlockStateV1.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/ICustomModelLoader.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/IModel.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/ISmartVariant.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/ItemLayerModel.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/ItemTextureQuadConverter.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/MapModelState.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/ModelDynBucket.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/ModelFluid.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/ModelLoader.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/ModelLoaderRegistry.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/ModelStateComposition.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/MultiLayerModel.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/MultiModel.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/MultiModelState.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/PerspectiveMapWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/SimpleModelFontRenderer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/SimpleModelState.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/animation/Animation.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/animation/AnimationItemOverrideList.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/animation/AnimationModelBase.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/animation/AnimationTESR.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/animation/FastTESR.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/animation/ModelBlockAnimation.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/animation/package-info.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/b3d/B3DClip.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/b3d/B3DLoader.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/b3d/B3DModel.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/b3d/package-info.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/obj/OBJLoader.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/obj/OBJModel.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/obj/package-info.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/package-info.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/pipeline/BlockInfo.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/pipeline/ForgeBlockModelRenderer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/pipeline/IVertexConsumer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/pipeline/IVertexProducer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/pipeline/LightUtil.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/pipeline/QuadGatheringTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/pipeline/TRSRTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/pipeline/TransformerConsumer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/pipeline/UnpackedBakedQuad.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/pipeline/VertexBufferConsumer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/pipeline/VertexLighterFlat.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/pipeline/VertexLighterSmoothAo.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/pipeline/VertexTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/model/pipeline/package-info.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/resource/IResourceType.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/resource/ISelectiveResourceReloadListener.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/resource/ReloadRequirements.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/resource/SelectiveReloadStateHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/resource/VanillaResourceType.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/resource/package-info.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/settings/IKeyConflictContext.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/settings/KeyBindingMap.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/settings/KeyConflictContext.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/client/settings/KeyModifier.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/BiomeDictionary.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/BiomeManager.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/DimensionManager.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/DungeonHooks.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/EnumPlantType.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/FarmlandWaterManager.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/ForgeChunkManager.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/ForgeEarlyConfig.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/ForgeHooks.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/ForgeInternalHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/ForgeModContainer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/ForgeVersion.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/IMinecartCollisionHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/IPlantable.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/IRarity.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/IShearable.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/ISpecialArmor.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/MinecraftForge.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/UsernameCache.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/WorldSpecificSaveHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/WorldWorkerManager.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/animation/Event.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/animation/IEventHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/animation/ITimeValue.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/animation/TimeValues.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/brewing/AbstractBrewingRecipe.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/brewing/BrewingOreRecipe.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/brewing/BrewingRecipe.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/brewing/BrewingRecipeRegistry.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/brewing/IBrewingRecipe.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/brewing/VanillaBrewingRecipe.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/capabilities/Capability.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/capabilities/CapabilityDispatcher.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/capabilities/CapabilityInject.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/capabilities/CapabilityManager.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/capabilities/ICapabilityProvider.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/capabilities/ICapabilitySerializable.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/chunkio/ChunkIOExecutor.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/chunkio/ChunkIOProvider.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/chunkio/ChunkIOThreadPoolExecutor.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/chunkio/QueuedChunk.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/command/SelectorHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/command/SelectorHandlerManager.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/config/Config.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/config/ConfigCategory.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/config/ConfigElement.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/config/ConfigManager.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/config/Configuration.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/config/FieldWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/config/IFieldWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/config/ITypeAdapter.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/config/Property.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/config/TypeAdapters.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/crafting/CompoundIngredient.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/crafting/CraftingHelper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/crafting/IConditionFactory.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/crafting/IIngredientFactory.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/crafting/IRecipeContainer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/crafting/IRecipeFactory.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/crafting/IShapedRecipe.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/crafting/IngredientNBT.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/crafting/JsonContext.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/model/HiddenModelPart.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/model/IModelPart.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/model/IModelState.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/model/ITransformation.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/model/Models.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/model/TRSRTransformation.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/model/animation/AnimationStateMachine.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/model/animation/CapabilityAnimation.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/model/animation/Clips.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/model/animation/IAnimationStateMachine.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/model/animation/IClip.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/model/animation/IJoint.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/model/animation/IJointClip.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/model/animation/JointClips.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/network/DimensionMessageHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/network/FluidIdRegistryMessageHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/network/ForgeMessage.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/network/ForgeNetworkHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/network/ForgeRuntimeCodec.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/network/ServerToClientConnectionEstablishedHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/property/ExtendedBlockState.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/property/IExtendedBlockState.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/property/IUnlistedProperty.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/property/Properties.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/property/PropertyFloat.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/ticket/AABBTicket.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/ticket/ChunkTicketManager.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/ticket/ITicketGetter.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/ticket/ITicketManager.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/ticket/MultiTicketManager.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/ticket/SimpleTicket.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/util/BlockSnapshot.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/util/ChunkCoordComparator.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/util/CompoundDataFixer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/util/Constants.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/util/EnumHelper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/util/FakePlayer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/util/FakePlayerFactory.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/util/IDataFixerData.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/util/INBTSerializable.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/util/ITeleporter.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/util/JsonUtils.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/util/ModFixs.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/util/PacketUtil.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/util/RecipeMatcher.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/util/TextTable.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/common/util/WorldCapabilityData.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/energy/CapabilityEnergy.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/energy/EnergyStorage.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/energy/IEnergyStorage.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/AnvilUpdateEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/AttachCapabilitiesEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/CommandEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/DifficultyChangeEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/ForgeEventFactory.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/GameRuleChangeEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/LootTableLoadEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/RegistryEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/ServerChatEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/brewing/PlayerBrewedPotionEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/brewing/PotionBrewEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/enchanting/EnchantmentLevelSetEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/EntityEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/EntityJoinWorldEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/EntityMobGriefingEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/EntityMountEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/EntityStruckByLightningEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/EntityTravelToDimensionEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/PlaySoundAtEntityEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/ProjectileImpactEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/ThrowableImpactEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/item/ItemEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/item/ItemExpireEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/item/ItemTossEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/AnimalTameEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/BabyEntitySpawnEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/EnderTeleportEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/LivingAttackEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/LivingDamageEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/LivingDeathEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/LivingDestroyBlockEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/LivingDropsEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/LivingEntityUseItemEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/LivingEquipmentChangeEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/LivingEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/LivingExperienceDropEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/LivingFallEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/LivingHealEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/LivingHurtEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/LivingKnockBackEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/LivingPackSizeEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/LivingSetAttackTargetEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/LivingSpawnEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/LootingLevelEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/PotionColorCalculationEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/PotionEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/living/ZombieEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/minecart/MinecartCollisionEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/minecart/MinecartEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/minecart/MinecartInteractEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/minecart/MinecartUpdateEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/AdvancementEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/AnvilRepairEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/ArrowLooseEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/ArrowNockEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/AttackEntityEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/BonemealEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/CriticalHitEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/EntityItemPickupEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/FillBucketEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/ItemFishedEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/ItemTooltipEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/PlayerContainerEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/PlayerDestroyItemEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/PlayerDropsEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/PlayerEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/PlayerFlyableFallEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/PlayerInteractEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/PlayerPickupXpEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/PlayerSetSpawnEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/PlayerSleepInBedEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/PlayerWakeUpEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/SleepingLocationCheckEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/SleepingTimeCheckEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/entity/player/UseHoeEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/furnace/FurnaceFuelBurnTimeEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/terraingen/BiomeEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/terraingen/ChunkGeneratorEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/terraingen/DecorateBiomeEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/terraingen/DeferredBiomeDecorator.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/terraingen/InitMapGenEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/terraingen/InitNoiseGensEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/terraingen/OreGenEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/terraingen/PopulateChunkEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/terraingen/SaplingGrowTreeEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/terraingen/TerrainGen.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/terraingen/WorldTypeEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/village/MerchantTradeOffersEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/village/VillageSiegeEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/world/BlockEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/world/ChunkDataEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/world/ChunkEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/world/ChunkWatchEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/world/ExplosionEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/world/GetCollisionBoxesEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/world/NoteBlockEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/event/world/WorldEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/BlockFluidBase.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/BlockFluidClassic.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/BlockFluidFinite.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/DispenseFluidContainer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/Fluid.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/FluidActionResult.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/FluidEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/FluidRegistry.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/FluidStack.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/FluidTank.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/FluidTankInfo.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/FluidUtil.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/IFluidBlock.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/IFluidTank.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/UniversalBucket.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/CapabilityFluidHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/FluidTankProperties.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/FluidTankPropertiesWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/IFluidHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/IFluidHandlerItem.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/IFluidTankProperties.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/ItemFluidContainer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/TileFluidHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/templates/EmptyFluidHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerConcatenate.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerFluidMap.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerItemStack.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerItemStackSimple.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/templates/VoidFluidHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/wrappers/BlockLiquidWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/wrappers/BlockWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/wrappers/FluidBlockWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fluids/capability/wrappers/FluidBucketWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/CustomModLoadingErrorDisplayException.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/DefaultGuiFactory.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/ExtendedServerListData.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/FMLClientHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/FMLConfigGuiFactory.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/FMLFileResourcePack.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/FMLFolderResourcePack.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/GuiAccessDenied.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/GuiBackupFailed.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/GuiConfirmation.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/GuiCustomModLoadingErrorScreen.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/GuiDupesFound.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/GuiErrorBase.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/GuiModList.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/GuiModsMissing.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/GuiModsMissingForServer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/GuiMultipleModsErrored.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/GuiNotification.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/GuiOldSaveLoadConfirm.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/GuiScrollingList.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/GuiSlotModList.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/GuiSortingProblem.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/GuiWrongMinecraft.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/IDisplayableError.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/IModGuiFactory.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/SplashProgress.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/config/ConfigGuiType.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/config/DummyConfigElement.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/config/GuiButtonExt.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/config/GuiCheckBox.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/config/GuiConfig.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/config/GuiConfigEntries.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/config/GuiEditArray.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/config/GuiEditArrayEntries.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/config/GuiMessageDialog.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/config/GuiSelectString.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/config/GuiSelectStringEntries.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/config/GuiSlider.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/config/GuiUnicodeGlyphButton.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/config/GuiUtils.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/config/HoverChecker.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/config/IConfigElement.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/event/ConfigChangedEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/registry/ClientRegistry.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/registry/IRenderFactory.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/client/registry/RenderingRegistry.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/API.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/AutomaticEventSubscriber.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/CertificateHelper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/ClassNameUtils.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/DummyModContainer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/DuplicateModsFoundException.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/EnhancedRuntimeException.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/FMLCommonHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/FMLContainer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/FMLContainerHolder.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/FMLLog.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/FMLModContainer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/ICrashCallable.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/IEntitySelectorFactory.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/IFMLHandledException.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/IFMLSidedHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/IFuelHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/ILanguageAdapter.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/IWorldGenerator.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/InjectedModContainer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/LoadController.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/Loader.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/LoaderException.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/LoaderExceptionModCrash.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/LoaderState.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/MCPDummyContainer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/MetadataCollection.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/MinecraftDummyContainer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/MissingModsException.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/Mod.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/ModAPIManager.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/ModClassLoader.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/ModContainer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/ModContainerFactory.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/ModMetadata.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/MultipleModsErrored.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/ObfuscationReflectionHelper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/Optional.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/ProgressManager.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/ProxyInjector.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/SaveInspectionHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/SidedProxy.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/StartupQuery.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/TracingPrintStream.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/WorldAccessContainer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/WrongMinecraftVersionException.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/ZipperUtil.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/ASMTransformerWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/FMLSanityChecker.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/ReobfuscationMarker.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/AccessTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/DeobfuscationTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/EventSubscriberTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/EventSubscriptionTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/FieldRedirectTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/ItemBlockSpecialTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/ItemBlockTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/ItemStackTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/LWJGLTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/MarkerTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/ModAPITransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/ModAccessTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/PatchingTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/PotionEffectTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/SideTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/SoundEngineFixTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/TerminalTransformer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/deobf/FMLRemappingAdapter.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/asm/transformers/deobf/LZMAInputSupplier.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/discovery/ASMDataTable.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/discovery/ContainerType.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/discovery/DirectoryDiscoverer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/discovery/ITypeDiscoverer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/discovery/JarDiscoverer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/discovery/ModCandidate.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/discovery/ModDiscoverer.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/discovery/asm/ASMModParser.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/discovery/asm/ModAnnotation.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/discovery/asm/ModAnnotationVisitor.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/discovery/asm/ModClassVisitor.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/discovery/asm/ModFieldVisitor.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/discovery/asm/ModMethodVisitor.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/discovery/json/ASMInfo.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/discovery/json/JsonAnnotationLoader.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/event/FMLConstructionEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/event/FMLEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/event/FMLFingerprintViolationEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/event/FMLInitializationEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/event/FMLInterModComms.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/event/FMLLoadCompleteEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/event/FMLLoadEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/event/FMLModDisabledEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/event/FMLModIdMappingEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/event/FMLPostInitializationEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/event/FMLPreInitializationEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/event/FMLServerAboutToStartEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/event/FMLServerStartedEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/event/FMLServerStartingEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/event/FMLServerStoppedEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/event/FMLServerStoppingEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/event/FMLStateEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/eventhandler/ASMEventHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/eventhandler/Cancelable.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/eventhandler/Event.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/eventhandler/EventBus.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/eventhandler/EventListenerFactory.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/eventhandler/EventPriority.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/eventhandler/FMLThrowingEventBus.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/eventhandler/GenericEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/eventhandler/IContextSetter.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/eventhandler/IEventExceptionHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/eventhandler/IEventListener.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/eventhandler/IGenericEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/eventhandler/ListenerList.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/eventhandler/SubscribeEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/gameevent/InputEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/gameevent/PlayerEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/gameevent/TickEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/launcher/FMLDeobfTweaker.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/launcher/FMLInjectionAndSortingTweaker.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/launcher/FMLServerTweaker.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/launcher/FMLTweaker.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/launcher/Yggdrasil.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/ByteBufUtils.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/FMLEmbeddedChannel.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/FMLEventChannel.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/FMLIndexedMessageToMessageCodec.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/FMLNetworkEvent.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/FMLNetworkException.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/FMLOutboundHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/IGuiHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/NetworkCheckHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/NetworkEventFiringHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/NetworkHandshakeEstablished.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/NetworkRegistry.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/PacketLoggingHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/handshake/ChannelRegistrationHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeClientState.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeCodec.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeMessage.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeServerState.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/handshake/HandshakeInjector.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/handshake/HandshakeMessageHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/handshake/IHandshakeState.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/handshake/NetworkDispatcher.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/internal/EntitySpawnHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/internal/FMLMessage.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/internal/FMLNetworkHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/internal/FMLProxyPacket.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/internal/FMLRuntimeCodec.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/internal/HandshakeCompletionHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/internal/NetworkModHolder.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/internal/OpenGuiHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/simpleimpl/IMessage.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/simpleimpl/IMessageHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/simpleimpl/MessageContext.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleChannelHandlerWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleIndexedCodec.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleNetworkWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/patcher/ClassPatch.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/patcher/ClassPatchManager.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/patcher/GenDiffSet.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/registry/EntityEntry.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/registry/EntityEntryBuilder.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/registry/EntityRegistry.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/registry/ExistingSubstitutionException.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/registry/ForgeRegistries.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/registry/GameRegistry.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/registry/IEntityAdditionalSpawnData.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/registry/IThrowableEntity.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/registry/ItemStackHolderInjector.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/registry/ItemStackHolderRef.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/registry/VillagerRegistry.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/thread/SidedThreadGroup.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/thread/SidedThreadGroups.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/toposort/ModSorter.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/toposort/ModSortingException.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/toposort/TopologicalSort.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/versioning/ArtifactVersion.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/versioning/ComparableVersion.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/versioning/DefaultArtifactVersion.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/versioning/DependencyParser.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/versioning/InvalidVersionSpecificationException.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/versioning/Restriction.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/versioning/VersionParser.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/common/versioning/VersionRange.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/CoreModManager.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/FMLCorePlugin.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/FMLInjectionData.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/FMLLaunchHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/FMLRelaunchLog.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/FileListHelper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/IFMLCallHook.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/IFMLLoadingPlugin.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/ReflectionHelper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/ServerLaunchWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/Side.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/SideOnly.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/libraries/Artifact.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/libraries/LibraryManager.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/libraries/LinkRepository.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/libraries/MemoryModList.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/libraries/ModList.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/libraries/Repository.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/relauncher/libraries/SnapshotJson.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/ByteBufferSeekableSource.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/Checksum.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/DebugDiffWriter.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/Delta.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/DiffWriter.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/GDiffPatcher.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/GDiffWriter.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/PatchException.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/RandomAccessFileSeekableSource.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/SeekableSource.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/fml/server/FMLServerHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/CapabilityItemHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/IItemHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/IItemHandlerModifiable.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/ItemHandlerHelper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/ItemStackHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/SlotItemHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/VanillaDoubleChestItemHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/VanillaHopperItemHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/VanillaInventoryCodeHooks.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/wrapper/CombinedInvWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/wrapper/EmptyHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/wrapper/EntityArmorInvWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/wrapper/EntityEquipmentInvWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/wrapper/EntityHandsInvWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/wrapper/InvWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/wrapper/PlayerArmorInvWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/wrapper/PlayerInvWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/wrapper/PlayerMainInvWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/wrapper/PlayerOffhandInvWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/wrapper/RangedWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/items/wrapper/SidedInvWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/oredict/DyeUtils.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/oredict/OreDictionary.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/oredict/OreIngredient.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/oredict/RecipeSorter.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/oredict/ShapedOreRecipe.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/oredict/ShapelessOreRecipe.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/registries/DataSerializerEntry.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/registries/ForgeRegistry.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/registries/GameData.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/registries/IForgeRegistry.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/registries/IForgeRegistryEntry.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/registries/IForgeRegistryInternal.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/registries/IForgeRegistryModifiable.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/registries/ILockableRegistry.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/registries/IRegistryDelegate.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/registries/NamespacedDefaultedWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/registries/NamespacedWrapper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/registries/ObjectHolderRef.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/registries/ObjectHolderRegistry.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/registries/RegistryBuilder.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/registries/RegistryDelegate.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/registries/RegistryManager.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/ForgeTimeTracker.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/command/ChunkGenWorker.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/command/CommandDimensions.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/command/CommandEntity.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/command/CommandGenerate.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/command/CommandSetDimension.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/command/CommandTps.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/command/CommandTrack.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/command/CommandTreeBase.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/command/CommandTreeHelp.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/command/ForgeCommand.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/command/TextComponentHelper.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/command/package-info.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/console/ConsoleCommandCompleter.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/console/TerminalHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/permission/DefaultPermissionHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/permission/DefaultPermissionLevel.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/permission/IPermissionHandler.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/permission/PermissionAPI.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/permission/context/AreaContext.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/permission/context/BlockPosContext.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/permission/context/Context.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/permission/context/ContextKey.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/permission/context/ContextKeys.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/permission/context/IContext.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/permission/context/PlayerContext.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/permission/context/TargetContext.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/permission/context/WorldContext.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/permission/context/package-info.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/permission/package-info.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/terminalconsole/HighlightErrorConverter.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/terminalconsole/MinecraftFormattingConverter.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/terminalconsole/TerminalConsoleAppender.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/terminalconsole/package-info.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/terminalconsole/util/LoggerNamePatternSelector.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/terminalconsole/util/package-info.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/timings/ForgeTimings.java (100%) rename {src => module/forge/src}/main/java/net/minecraftforge/server/timings/TimeTracker.java (100%) rename {src => module/forge/src}/main/java/paulscode/sound/codecs/CodecIBXM.java (100%) rename {src => module/forge/src}/main/resources/META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat (100%) rename {src => module/forge/src}/main/resources/META-INF/services/org.spongepowered.asm.service.IMixinService (100%) rename {src => module/forge/src}/main/resources/META-INF/services/org.spongepowered.asm.service.IMixinServiceBootstrap (100%) rename {src => module/forge/src}/main/resources/assets/cleanroom/background.png (100%) rename {src => module/forge/src}/main/resources/assets/cleanroom/banner.png (100%) rename {src => module/forge/src}/main/resources/assets/cleanroom/icon.png (100%) rename {src => module/forge/src}/main/resources/assets/cleanroom/lang/de_de.lang (100%) rename {src => module/forge/src}/main/resources/assets/cleanroom/lang/en_au.lang (100%) rename {src => module/forge/src}/main/resources/assets/cleanroom/lang/en_us.lang (100%) rename {src => module/forge/src}/main/resources/assets/cleanroom/lang/pl_pl.lang (100%) rename {src => module/forge/src}/main/resources/assets/cleanroom/lang/ru_ru.lang (100%) rename {src => module/forge/src}/main/resources/assets/cleanroom/lang/zh_cn.lang (100%) rename {src => module/forge/src}/main/resources/assets/cleanroom/textures/gui/checkbox.png (100%) rename {src => module/forge/src}/main/resources/assets/cleanroom/textures/gui/icons.png (100%) rename {src => module/forge/src}/main/resources/assets/cleanroom/textures/gui/minecraft.png (100%) rename {src => module/forge/src}/main/resources/assets/cleanroom/textures/gui/missing_background.png (100%) rename {src => module/forge/src}/main/resources/assets/cleanroom/textures/gui/missing_banner.png (100%) rename {src => module/forge/src}/main/resources/assets/cleanroom/textures/gui/sprites/dropdown/item.png (100%) rename {src => module/forge/src}/main/resources/assets/cleanroom/textures/gui/sprites/dropdown/item_highlighted.png (100%) rename {src => module/forge/src}/main/resources/assets/cleanroom/textures/gui/sprites/widget/button.png (100%) rename {src => module/forge/src}/main/resources/assets/cleanroom/textures/gui/sprites/widget/button_disabled.png (100%) rename {src => module/forge/src}/main/resources/assets/cleanroom/textures/gui/sprites/widget/button_highlighted.png (100%) rename {src => module/forge/src}/main/resources/assets/configanytime/icon.png (100%) rename {src => module/forge/src}/main/resources/assets/fml/textures/gui/forge.png (100%) rename {src => module/forge/src}/main/resources/assets/fml/textures/gui/icons.png (100%) rename {src => module/forge/src}/main/resources/assets/forge/blockstates/dynbucket.json (100%) rename {src => module/forge/src}/main/resources/assets/forge/lang/README.txt (100%) rename {src => module/forge/src}/main/resources/assets/forge/lang/en_pt.lang (100%) rename {src => module/forge/src}/main/resources/assets/forge/lang/en_us.lang (100%) rename {src => module/forge/src}/main/resources/assets/forge/lang/es_es.lang (100%) rename {src => module/forge/src}/main/resources/assets/forge/lang/fr_fr.lang (100%) rename {src => module/forge/src}/main/resources/assets/forge/lang/ja_jp.lang (100%) rename {src => module/forge/src}/main/resources/assets/forge/lang/ko_kr.lang (100%) rename {src => module/forge/src}/main/resources/assets/forge/lang/ru_ru.lang (100%) rename {src => module/forge/src}/main/resources/assets/forge/lang/zh_cn.lang (100%) rename {src => module/forge/src}/main/resources/assets/forge/lang/zh_tw.lang (100%) rename {src => module/forge/src}/main/resources/assets/forge/models/item/bucket.json (100%) rename {src => module/forge/src}/main/resources/assets/forge/models/item/bucket_milk.json (100%) rename {src => module/forge/src}/main/resources/assets/forge/textures/gui/version_check_icons.png (100%) rename {src => module/forge/src}/main/resources/assets/forge/textures/items/bucket_fluid.png (100%) rename {src => module/forge/src}/main/resources/assets/forge/textures/items/vanilla_bucket_cover_mask.png (100%) rename {src => module/forge/src}/main/resources/assets/mixinbooter/icon.png (100%) rename {src => module/forge/src}/main/resources/cleanmix.info (100%) rename {src => module/forge/src}/main/resources/forge.exc (100%) rename {src => module/forge/src}/main/resources/forge.srg (100%) rename {src => module/forge/src}/main/resources/forge_at.cfg (100%) rename {src => module/forge/src}/main/resources/forge_logo.png (100%) rename {src => module/forge/src}/main/resources/log4j2.xml (100%) rename {src => module/forge/src}/main/resources/log4j2_server.xml (100%) rename {src => module/forge/src}/main/resources/logging.properties (100%) rename {src => module/forge/src}/main/resources/mcplogo.png (100%) rename {src => module/forge/src}/main/resources/mcpmod.info (100%) rename {src => module/forge/src}/main/resources/mixinbooter.info (100%) rename {src => module/forge/src}/main/resources/pack.mcmeta (100%) rename {src => module/forge/src}/main/resources/url.png (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/PotionEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/block/BasePlaceEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/block/FarmlandTrampleEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/block/FarmlandWaterTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/block/MaterialFogColorTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/block/NeighborNotifyEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/block/ParticleEffectsTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/block/PathNodeTypeTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/block/PlaceEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/block/PortalSpawnEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/block/SlipperinessTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/block/StickyBlockTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/block/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/chat/ClientChatEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/chat/ClientCommandTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/chat/CommandTreeBaseTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/chat/EntitySelectorFactoryTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/chat/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/CustomTextureAtlasSpriteTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/FOVModifierEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/SearchableCreativeTabTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/gui/ContainerDrawForegroundEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/gui/TooltipColorEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/model/AnimatedModelTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/model/BlockstateRetextureTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/model/ForgeBlockStatesLoaderTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/model/ItemLayerModelTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/model/ItemModelConflictTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/model/ItemModelGenerationTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/model/ModelBakeEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/model/ModelFluidTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/model/ModelLoaderRegistryTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/model/MultiLayerModelTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/model/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/rendering/FastTESRTransparentTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/rendering/ItemTESRTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/rendering/VertexBufferNormalTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/client/rendering/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/BlockEntityUpdateTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/EntityTravelToDimensionEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/GetCollisionBoxesEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/ProjectileImpactEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/living/AnimalTameEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/living/AttackEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/living/BabyEntitySpawnEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/living/CheckSpawnEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/living/CustomSpawnPlacementTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/living/DamageEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/living/EquipmentChangeEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/living/KnockBackEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/living/MobGriefingEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/living/SpecialSpawnTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/living/VillagerProfessionTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/living/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/player/CriticalHitEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/player/DamageReworkTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/player/ItemPickupEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/player/PlayerInteractEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/player/PlayerSetSpawnTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/player/ReachDistanceAttributeTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/player/SwimSpeedAttributeTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/entity/player/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/fluid/ColoredFluidTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/fluid/CreateFluidSourceEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/fluid/DynBucketTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/fluid/FluidPlaceBlockEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/fluid/FluidPlacementTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/fluid/ItemFluidHandlerTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/fluid/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/AnytimeSleepingTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/BrewingRecipeRegistryTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/ConstantLoadingTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/CraftingSystemTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/DifficultyChangeEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/DynamicBannerTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/EnchantmentLevelSetEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/FurnaceFuelBurnTimeEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/GiveItemToPlayerTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/InputUpdateEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/NoBedSleepingTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/PotionRegistryTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/RecipeMatchingTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/advancement/AdvancementCriterionTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/advancement/AdvancementEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/advancement/AdvancementsPaginationTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/advancement/OredictTriggerTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/advancement/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/loot/LootContextTweaksTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/loot/LootTableLoadEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/loot/LootTableTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/loot/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/gameplay/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/item/BonemealEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/item/CanApplyAtEnchantingTableTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/item/CanDestroyBlocksInCreativeTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/item/ContinuousUseItemTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/item/CustomRarityTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/item/HorseArmorTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/item/IsBookEnchantableTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/item/ItemFishedEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/item/MapDataTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/item/MendingRepairTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/item/NBTShareTagTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/item/OnItemUseFirstTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/item/PotionCurabilityTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/item/PotionShouldRenderTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/item/ShieldTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/item/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/misc/EnumPlantTypeTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/misc/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/mod/CapabilityTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/mod/ClientLoadingExceptionTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/mod/ConfigAnnotationTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/mod/ObjectHolderAnnotationTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/mod/PermissionTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/mod/RegistryOverrideTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/mod/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/network/BigNetworkMessageTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/network/TrackingTargetTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/network/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/util/ModNameTooltip.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/util/RotatingWrench.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/util/TextureDumper.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/util/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/village/MerchantTradeOffersEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/village/VillageSiegeEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/world/ChunkCapabilityTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/world/ChunkWatchEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/world/DecorateEventDebug.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/world/SpawnDimensionTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/world/TileEntityLoadingTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/world/WorldCapabilityTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/world/WorldProviderCanSleepAtTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/debug/world/package-info.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/common/eventhandler/EventBusTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/common/eventhandler/impl/AbnormalListeners.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/common/eventhandler/impl/ExampleEvent.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/common/eventhandler/impl/InstanceListeners.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/common/eventhandler/impl/StaticListeners.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/common/registry/BlockStateMappingsTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/common/registry/DummyBlockReplacementTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/common/registry/ForgeTestRunner.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/common/registry/FreezingTests.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/common/registry/ItemBlockSubstitutionRemoveRestoreTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/common/registry/RegistryTestSuite.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/common/registry/SubstitutionInjectionTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/common/registry/SubstitutionRemoveRestoreTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/common/registry/VanillaRegistryTests.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/debug/FaultyCoreMod.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/test/DependencyParserTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/test/ForgeNetworkTestMod.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/test/SpecialSpawnEventTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/test/TestNetStuff.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/test/networkhandshake/TestNetworkHandshake.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetHandler1.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetHandler2.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetTestMessage1.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetTestMessage2.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetTester.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/test/BiomeSpawnableListTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/test/BufferBuilderExpansionTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/test/ConfigurationTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/test/EnumHelperTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/test/SelectorHandlerTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/test/SliderConfigElementTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/test/TestAnnotationParser.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/test/TextTableTest.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/test/package-info.java (100%) rename {src => module/forge/src}/test/resources/assets/advancementcriteriontest/advancements/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a1/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a10/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a11/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a12/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a13/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a14/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a15/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a16/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a17/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a18/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a19/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a2/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a20/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a21/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a22/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a23/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a24/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a25/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a26/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a27/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a28/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a29/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a3/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a30/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a31/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a32/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a33/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a34/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a35/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a36/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a37/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a38/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a39/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a4/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a40/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a41/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a42/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a43/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a44/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a45/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a46/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a47/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a48/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a49/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a5/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a50/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a51/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a52/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a53/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a54/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a55/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a56/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a57/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a58/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a59/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a6/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a60/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a61/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a62/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a63/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a64/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a7/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a8/root.json (100%) rename {src => module/forge/src}/test/resources/assets/advancements_pagination/advancements/a9/root.json (100%) rename {src => module/forge/src}/test/resources/assets/collisionboxexeventtest/blockstates/box_block.json (100%) rename {src => module/forge/src}/test/resources/assets/config_test/lang/en_US.lang (100%) rename {src => module/forge/src}/test/resources/assets/constantloadingtest/test/_constants.json (100%) rename {src => module/forge/src}/test/resources/assets/crafting_system_test/recipes/_factories.json (100%) rename {src => module/forge/src}/test/resources/assets/crafting_system_test/recipes/conditions_property_not_array.json (100%) rename {src => module/forge/src}/test/resources/assets/crafting_system_test/recipes/oak_planks_from_logs.json (100%) rename {src => module/forge/src}/test/resources/assets/custom_sprite_test/blockstates/custom_sprite_block.json (100%) rename {src => module/forge/src}/test/resources/assets/custom_sprite_test/models/block/custom_sprite_block.json (100%) rename {src => module/forge/src}/test/resources/assets/dynbuckettest/blockstates/simpletank.json (100%) rename {src => module/forge/src}/test/resources/assets/farmlandwatertest/blockstates/test_block.json (100%) rename {src => module/forge/src}/test/resources/assets/fluidadditionalfields/blockstates/slime.json (100%) rename {src => module/forge/src}/test/resources/assets/fluidadditionalfields/textures/slime_flow.png (100%) rename {src => module/forge/src}/test/resources/assets/fluidadditionalfields/textures/slime_flow.png.mcmeta (100%) rename {src => module/forge/src}/test/resources/assets/fluidadditionalfields/textures/slime_overlay.png (100%) rename {src => module/forge/src}/test/resources/assets/fluidadditionalfields/textures/slime_still.png (100%) rename {src => module/forge/src}/test/resources/assets/fluidadditionalfields/textures/slime_still.png.mcmeta (100%) rename {src => module/forge/src}/test/resources/assets/fogcolorinsidematerialtest/blockstates/slime.json (100%) rename {src => module/forge/src}/test/resources/assets/fogcolorinsidematerialtest/pack.mcmeta (100%) rename {src => module/forge/src}/test/resources/assets/fogcolorinsidematerialtest/test_fluid.json (100%) rename {src => module/forge/src}/test/resources/assets/fogcolorinsidematerialtest/textures/slime_flow.png (100%) rename {src => module/forge/src}/test/resources/assets/fogcolorinsidematerialtest/textures/slime_flow.png.mcmeta (100%) rename {src => module/forge/src}/test/resources/assets/fogcolorinsidematerialtest/textures/slime_overlay.png (100%) rename {src => module/forge/src}/test/resources/assets/fogcolorinsidematerialtest/textures/slime_still.png (100%) rename {src => module/forge/src}/test/resources/assets/fogcolorinsidematerialtest/textures/slime_still.png.mcmeta (100%) rename {src => module/forge/src}/test/resources/assets/forge/blockstates/dynbottle.json (100%) rename {src => module/forge/src}/test/resources/assets/forge/recipes/_constants.json (100%) rename {src => module/forge/src}/test/resources/assets/forge/recipes/ore_shaped.json (100%) rename {src => module/forge/src}/test/resources/assets/forge/recipes/shapeless.json (100%) rename {src => module/forge/src}/test/resources/assets/forge/recipes/shapeless_constant.json (100%) rename {src => module/forge/src}/test/resources/assets/forge/recipes/shapeless_damageable.json (100%) rename {src => module/forge/src}/test/resources/assets/forge/recipes/shapeless_ore.json (100%) rename {src => module/forge/src}/test/resources/assets/forge/recipes/shapeless_wildcard.json (100%) rename {src => module/forge/src}/test/resources/assets/forge/textures/blocks/milk_flow.png (100%) rename {src => module/forge/src}/test/resources/assets/forge/textures/blocks/milk_flow.png.mcmeta (100%) rename {src => module/forge/src}/test/resources/assets/forge/textures/blocks/milk_still.png (100%) rename {src => module/forge/src}/test/resources/assets/forge/textures/blocks/milk_still.png.mcmeta (100%) rename {src => module/forge/src}/test/resources/assets/forgeblockstatesloader/blockstates/cobblestone_wall.json (100%) rename {src => module/forge/src}/test/resources/assets/forgeblockstatesloader/blockstates/mossy_cobblestone_wall.json (100%) rename {src => module/forge/src}/test/resources/assets/forgeblockstatesloader/models/block/wall_connect.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugcustomslimeblock/blockstates/custom_slime_block.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugcustomslimeblock/lang/en_US.lang (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugcustomslimeblock/models/block/blue_slime_block.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugcustomslimeblock/models/block/obsidian_slime_block.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugcustomslimeblock/models/item/blue_slime_block.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugcustomslimeblock/models/item/obsidian_slime_block.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugcustomslimeblock/textures/blocks/blue_slime_block.png (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugcustomslimeblock/textures/blocks/obsidian_slime_block.png (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugfluidplacement/blockstates/finite_fluid_block.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugitemlayermodel/blockstates/test_item.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugitemtile/blockstates/custom_model_block.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelanimation/armatures/block/engine_ring.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelanimation/armatures/block/rotatest.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelanimation/asms/block/chest.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelanimation/asms/block/engine.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelanimation/asms/block/engine2.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelanimation/asms/block/rotatest.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelanimation/blockstates/rotatest.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelanimation/blockstates/test_animation_block.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelanimation/models/block/engine.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelanimation/models/block/engine_ring.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelanimation/models/block/rotatest.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelfluid/blockstates/test_fluid_block.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/blockstates/custom_model_block.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_custom_data_block.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_direction_block.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_direction_eye.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_dynamic_eye.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_tesseract_block.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_vertex_coloring1.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_vertex_coloring2.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/models/block/chest.b3d (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/models/block/direction_test.mtl (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/models/block/direction_test.obj (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/models/block/eye.mtl (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/models/block/eye.obj (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/models/block/fancy_fence.mtl (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/models/block/fancy_fence.obj (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/models/block/tesseract.mtl (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/models/block/tesseract.obj (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/models/block/untitled2.b3d (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/models/block/vertex_coloring.mtl (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/models/block/vertex_coloring.obj (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_arrow.png (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_arrow_top.png (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_back.png (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_front.png (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/textures/eye.png (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/textures/eye128.png (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmodelloaderregistry/textures/texture.png (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugmultilayermodel/blockstates/test_layer_block.json (100%) rename {src => module/forge/src}/test/resources/assets/forgedebugnobedsleeping/models/item/sleeping_pill.json (100%) rename {src => module/forge/src}/test/resources/assets/furnacefuelburntimeeventtest/models/item/flammable_gold_shovel.json (100%) rename {src => module/forge/src}/test/resources/assets/furnacefuelburntimeeventtest/models/item/unburnable_wood_shovel.json (100%) rename {src => module/forge/src}/test/resources/assets/horse_armor_test/lang/en_US.lang (100%) rename {src => module/forge/src}/test/resources/assets/horse_armor_test/models/item/test_armor.json (100%) rename {src => module/forge/src}/test/resources/assets/horse_armor_test/textures/entity/horse/armor/test.png (100%) rename {src => module/forge/src}/test/resources/assets/horse_armor_test/textures/items/test_armor.png (100%) rename {src => module/forge/src}/test/resources/assets/item_can_destroy_blocks_in_creative_test/models/item/item_test.json (100%) rename {src => module/forge/src}/test/resources/assets/item_model_conflict_test/blockstates/test.json (100%) rename {src => module/forge/src}/test/resources/assets/item_model_conflict_test/models/block/test.json (100%) rename {src => module/forge/src}/test/resources/assets/item_model_conflict_test/models/item/test.json (100%) rename {src => module/forge/src}/test/resources/assets/item_model_generation_test/models/item/animation_test.json (100%) rename {src => module/forge/src}/test/resources/assets/item_model_generation_test/models/item/intersection_test.json (100%) rename {src => module/forge/src}/test/resources/assets/item_model_generation_test/models/item/opacity_test.json (100%) rename {src => module/forge/src}/test/resources/assets/item_model_generation_test/models/item/overlap_test.json (100%) rename {src => module/forge/src}/test/resources/assets/item_model_generation_test/models/item/pattern_test.json (100%) rename {src => module/forge/src}/test/resources/assets/item_model_generation_test/textures/items/animation_test.png (100%) rename {src => module/forge/src}/test/resources/assets/item_model_generation_test/textures/items/animation_test.png.mcmeta (100%) rename {src => module/forge/src}/test/resources/assets/item_model_generation_test/textures/items/intersection_test.png (100%) rename {src => module/forge/src}/test/resources/assets/item_model_generation_test/textures/items/opacity_test.png (100%) rename {src => module/forge/src}/test/resources/assets/item_model_generation_test/textures/items/overlap_test.png (100%) rename {src => module/forge/src}/test/resources/assets/item_model_generation_test/textures/items/pattern_test.png (100%) rename {src => module/forge/src}/test/resources/assets/loot_context_tweaks_test/advancements/test/root.json (100%) rename {src => module/forge/src}/test/resources/assets/loottable_load_event_test/loot_tables/chests/custom_spawn_bonus_chest.json (100%) rename {src => module/forge/src}/test/resources/assets/nbtsharetagitemtest/models/item/nbt_share_tag_item.json (100%) rename {src => module/forge/src}/test/resources/assets/onitemusefirsttest/models/item/test_item.json (100%) rename {src => module/forge/src}/test/resources/assets/oredict_predicate/advancements/recipes/wood_unlock_tnt.json (100%) rename {src => module/forge/src}/test/resources/assets/professiontest/textures/entity/test_villager.png (100%) rename {src => module/forge/src}/test/resources/assets/professiontest/textures/entity/zombie_test_villager.png (100%) rename {src => module/forge/src}/test/resources/assets/recipetest/recipes/tool_complex.json (100%) rename {src => module/forge/src}/test/resources/assets/recipetest/recipes/tool_simple.json (100%) rename {src => module/forge/src}/test/resources/assets/shield_test/lang/en_US.lang (100%) rename {src => module/forge/src}/test/resources/assets/shield_test/models/item/diamond_shield.json (100%) rename {src => module/forge/src}/test/resources/assets/shield_test/models/item/diamond_shield_blocking.json (100%) rename {src => module/forge/src}/test/resources/assets/wrenchrotatedebug/models/item/test_wrench.json (100%) rename {src => module/forge/src}/test/resources/assets/wrenchrotatedebug/textures/items/test_wrench.png (100%) rename {src => module/forge/src}/test/resources/mcmod.info (100%) rename {projects => module}/kirino (100%) rename {src => module/mixinbooter/src}/main/java/zone/rong/mixinbooter/Context.java (100%) rename {src => module/mixinbooter/src}/main/java/zone/rong/mixinbooter/IEarlyMixinLoader.java (100%) rename {src => module/mixinbooter/src}/main/java/zone/rong/mixinbooter/ILateMixinLoader.java (100%) rename {src => module/mixinbooter/src}/main/java/zone/rong/mixinbooter/IMixinConfigHijacker.java (100%) rename {src => module/mixinbooter/src}/main/java/zone/rong/mixinbooter/MixinBooterModContainer.java (100%) rename {src => module/mixinbooter/src}/main/java/zone/rong/mixinbooter/MixinBooterPlugin.java (100%) rename {src => module/mixinbooter/src}/main/java/zone/rong/mixinbooter/MixinLoader.java (100%) rename {src => module/mixinbooter/src}/main/java/zone/rong/mixinbooter/Tags.java (100%) rename {src => module/mixinbooter/src}/main/java/zone/rong/mixinbooter/service/ModDiscoverer.java (100%) rename {src => module/mixinbooter/src}/main/java/zone/rong/mixinbooter/util/Environment.java (100%) delete mode 100644 projects/cleanroom/build.gradle delete mode 100644 projects/mcp/build.gradle delete mode 100644 projects/minecraft/build.gradle diff --git a/.gitignore b/.gitignore index 7032bab06..3b84fb0a4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,18 +1,15 @@ /.idea/* /.run/ /.gradle/ -/projects/cleanroom/** -/projects/minecraft/** -/projects/mcp/** -/projects/cleanroom/!build.gradle -/projects/minecraft/!build.gradle -/projects/mcp/!build.gradle +/run/ +# Patched Minecraft source +/module/minecraft/ /buildSrc/.gradle/ /buildSrc/build/ /buildSrc/out/ /logs/ build/ version.txt -src/main/java/com/cleanroommc/common/CleanroomVersion.java +module/cleanroom/src/main/java/com/cleanroommc/common/CleanroomVersion.java !/.idea/icon.svg diff --git a/.gitmodules b/.gitmodules index 9d48f6ed7..65e31ed30 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "projects/kirino"] - path = projects/kirino + path = module/kirino url = https://github.com/CleanroomMC/Kirino-Engine.git diff --git a/README.md b/README.md index ed409d1a2..a0d7351d3 100644 --- a/README.md +++ b/README.md @@ -81,9 +81,9 @@ Some mods are obsoleted or need extra handle. See [wiki](https://cleanroommc.com ## Development Tips: -- Only modify `projects/cleanroom/src/` directory if you want to change vanilla +- Only modify `module/minecraft/src/main/java/` directory if you want to change vanilla - Run `gradlew genPatches` before commit, or the changes won't exist -- Modifications on `src/` doesn't need generating patches +- Modifications on the other `module/` directories don't need generating patches - [Tips from Forge](https://github.com/MinecraftForge/MinecraftForge/wiki/If-you-want-to-contribute-to-Forge) are still apply, keep the patches clean! - The current patches is full of useless hunks after we switched to VineFlower, we encourage contributors to clean up these patches manually. diff --git a/build.gradle b/build.gradle index 3c3da2721..043f81331 100644 --- a/build.gradle +++ b/build.gradle @@ -1,31 +1,16 @@ -buildscript { - repositories { - mavenLocal() - maven { - name = "Outlands" - url = 'https://maven.outlands.top/releases/' - } - mavenCentral() - gradlePluginPortal() - } - dependencies { - classpath 'top.outlands.gradle:ForgeGradle:6.0.59' - classpath('top.outlands:artifactural:3.0.4') { - transitive = false - } - } -} - -plugins { - id "org.jetbrains.gradle.plugin.idea-ext" version "1.3" - //id "com.palantir.git-version" version "4.2.0" -} -apply plugin: 'com.palantir.git-version' // Declared in buildSrc/build.gradle - import com.cleanroommc.gradle.helpers.ProjectConstants import com.cleanroommc.gradle.helpers.tasks.Util import com.palantir.gradle.gitversion.VersionDetails +plugins { + id 'java-library' + id 'idea' + id 'maven-publish' + id 'com.cleanroommc.gradle' version '0.0.1' +} + +// buildSrc path +apply plugin: 'com.palantir.git-version' def props = project.properties def sysProps = System.getProperties() @@ -48,28 +33,302 @@ println "Setting up Cleanroom $version" if (project.hasProperty('run_number')) println("On GitHub runs #${props.run_number}") println "Java: ${ -> sysProps['java.version']} | JVM: ${ -> sysProps['java.vm.version']} | Vendor: ${ -> sysProps['java.vendor']} | Architecture: ${ -> sysProps['os.arch']}" -// Initialize buildSrc -Util.init() +java { + toolchain.languageVersion = JavaLanguageVersion.of(25) +} tasks.withType(JavaCompile).configureEach { - options.compilerArgs = options.compilerArgs + ProjectConstants.COMPILER_JVM_ARGUMENTS + options.compilerArgs += ProjectConstants.COMPILER_JVM_ARGUMENTS options.encoding = 'UTF-8' } -idea.project.settings.compiler.javac.javacAdditionalOptions = ProjectConstants.COMPILER_JVM_ARGUMENTS.join(' ') +sourceSets { + main { + java { + srcDirs = [ + "$rootDir/module/cleanroom/src/main/java", + "$rootDir/module/forge/src/main/java", + "$rootDir/module/mixinbooter/src/main/java", + "$rootDir/module/minecraft/src/main/java", + "$rootDir/module/kirino/src/main/java" + ] + } + resources { + srcDirs = [ + // module/cleanroom has no resources yet; Gradle ignores missing dirs. + "$rootDir/module/cleanroom/src/main/resources", + "$rootDir/module/forge/src/main/resources", + "$rootDir/module/kirino/src/main/resources" + ] + } + } + test { + compileClasspath += sourceSets.main.runtimeClasspath + runtimeClasspath += sourceSets.main.runtimeClasspath + java { + srcDirs = [ + "$rootDir/module/cleanroom/src/test/java", + "$rootDir/module/forge/src/test/java", + "$rootDir/module/kirino/src/test/java" + ] + } + resources { + srcDirs = [ + "$rootDir/module/cleanroom/src/test/resources", + "$rootDir/module/forge/src/test/resources" + ] + } + } +} + +cleanroom { + patchDev { + minecraft { + source.set(cleanroom.localCacheDirectory.map { it.dir('sourceSets/mcp/sources').asFile }) + dependsOn 'remapSrg2Mcp' + } + } +} + +afterEvaluate { + def patchedSrc = file('module/minecraft/src/main/java') + + sourceSets.named('minecraftPatchDev') { + java.srcDirs = [patchedSrc] + } + + // TODO + // The patch-dev source set only feeds diff/copy tasks and can't compile standalone + tasks.named('compileMinecraftPatchDevJava') { enabled = false } + tasks.named('minecraftPatchDevClasses') { enabled = false } + tasks.named('processMinecraftPatchDevResources') { enabled = false } + + tasks.named('copyMinecraftToSourceSet') { + onlyIf { + !patchedSrc.exists() || (patchedSrc.listFiles()?.length ?: 0) == 0 + } + } +} + +repositories { + mavenCentral() + maven { + name = 'Cleanroom Maven' + url = 'https://repo.cleanroommc.com/releases/' + } + maven { + url = 'https://maven.arcseekers.com/releases/' + } + maven { + name = 'Outlands' + url = 'https://maven.outlands.top/releases' + } +} + +// TODO: fix on CG side +def mojangRepo = repositories.findByName('Mojang') +if (mojangRepo != null) { + repositories.remove(mojangRepo) + repositories.add(mojangRepo) +} + +ext { + lwjglArch = Util.getCurrentArch() + // Do not change the order unless it is required so + lwjglLibraries = [ + [ + 'lwjgl-glfw', 'lwjgl-jemalloc', 'lwjgl-openal', + 'lwjgl-opengl', 'lwjgl-stb', 'lwjgl-tinyfd', 'lwjgl' + ], + + [ + 'natives-linux-arm64', 'natives-linux-arm32', 'natives-linux', + 'natives-macos-arm64', 'natives-macos', + 'natives-windows-arm64', 'natives-windows-x86', 'natives-windows' + ] + ] +} + +configurations { + configureEach { // LWJGL2 isn't friendly with us, so pye pye + exclude group: 'org.lwjgl.lwjgl' + exclude group: 'com.ibm.icu', module: 'icu4j-core-mojang' + } + + // Don't pull all libraries, if we're missing something, add it to the installer list so the installer knows to download it + installer { + transitive = false + } + api.extendsFrom(installer) + + lwjglNatives { + transitive = false + } + + // Make the joint `main` compile see the Minecraft libraries resolved by CleanroomGradle + implementation.extendsFrom(vanilla) +} + +// TODO: entire dep tree needs to be re-evaluated +dependencies { + mcpConfig 'de.oceanlabs.mcp:mcp_config:1.12.2-20260220.202731' + + // TODO + // LWJGL + compileOnly "com.cleanroommc:lwjglx:1.0.0" + installer "com.cleanroommc:lwjglxx:1.1.21" + lwjglLibraries[0].each { + if (it == 'lwjgl') { + installer "org.lwjgl:$it:$props.lwjgl_version:unsafe" + } + else { + installer "org.lwjgl:$it:$props.lwjgl_version" + } + runtimeOnly "org.lwjgl:$it::$lwjglArch" + + lwjglLibraries[1].each { arch -> + lwjglNatives "org.lwjgl:$it:$props.lwjgl_version:$arch" + } + } + + // ASM + installer "org.ow2.asm:asm:$props.asm_version" + installer "org.ow2.asm:asm-commons:$props.asm_version" + installer "org.ow2.asm:asm-tree:$props.asm_version" + installer "org.ow2.asm:asm-util:$props.asm_version" + installer "org.ow2.asm:asm-analysis:$props.asm_version" + // Added back deprecated features for mods to load up properly, hosted on outlands + installer "org.ow2.asm:asm-deprecated:$props.asm_deprecated" + + // Hacks + installer "top.outlands:foundation:0.19.8" + installer 'net.lenni0451:Reflect:1.6.4' + installer 'net.lenni0451.commons:unchecked:1.9.2' + installer 'org.javassist:javassist:3.30.2-GA' + + // Regular deps + installer 'com.ibm.icu:icu4j:78.3' + installer 'org.jline:jline:4.1.3' + installer 'org.jline:jline-native:4.1.3' + installer 'net.java.jinput:jinput:2.0.10' + + installer 'lzma:lzma:0.0.1' + installer 'java3d:vecmath:1.5.2' + installer 'net.sf.trove4j:core:3.1.0' + installer 'net.sf.trove4j:experimental:3.1.0' + + installer 'net.sf.jopt-simple:jopt-simple:5.0.4' + + installer 'com.github.oshi:oshi-core-ffm:7.3.2' + installer 'com.github.oshi:oshi-common:7.3.2' + installer 'net.java.dev.jna:jna:5.19.1' + installer 'net.java.dev.jna:jna-platform:5.19.1' + + installer 'it.unimi.dsi:fastutil:8.5.18' + + installer 'com.google.guava:guava:33.6.0-jre' + installer 'com.google.guava:failureaccess:1.0.2' + installer 'com.google.code.gson:gson:2.14.0' + + installer 'org.apache.commons:commons-lang3:3.20.0' + installer 'org.apache.commons:commons-compress:1.28.0' + installer 'commons-codec:commons-codec:1.22.0' + installer 'commons-io:commons-io:2.22.0' + installer 'commons-logging:commons-logging:1.4.0' + installer 'org.apache.maven:maven-artifact:3.9.16' + installer 'org.apache.commons:commons-text:1.15.0' // Some old classes in lang3 moved to here, wtf + + // xz in common-compress need this to work + installer 'org.tukaani:xz:1.12' + + installer 'com.google.code.findbugs:jsr305:3.0.2' + installer 'org.jspecify:jspecify:1.0.0' + + // Apache HTTP, 4 and 5 + installer 'org.apache.httpcomponents.core5:httpcore5:5.4.3' + installer 'org.apache.httpcomponents.core5:httpcore5-h2:5.4.3' + installer 'org.apache.httpcomponents.client5:httpclient5:5.6.1' + + installer 'org.apache.httpcomponents:httpclient:4.5.14' + installer 'org.apache.httpcomponents:httpcore:4.4.16' + + // Netty + installer "io.netty:netty-codec-base:$props.netty_version" + installer "io.netty:netty-buffer:$props.netty_version" + installer "io.netty:netty-common:$props.netty_version" + installer "io.netty:netty-handler:$props.netty_version" + installer "io.netty:netty-resolver:$props.netty_version" + installer "io.netty:netty-transport:$props.netty_version" + installer "io.netty:netty-transport-native-unix-common:$props.netty_version:linux-x86_64" + installer "io.netty:netty-transport-classes-epoll:$props.netty_version" + installer "io.netty:netty-transport-native-epoll:$props.netty_version:linux-x86_64" + installer "io.netty:netty-codec-http:$props.netty_version" + installer "io.netty:netty-codec-http2:$props.netty_version" + installer "io.netty:netty-codec-dns:$props.netty_version" + installer "io.netty:netty-codec-compression:$props.netty_version" + installer "io.netty:netty-resolver-dns:$props.netty_version" + + // Jakarta (javax in Java 8) + installer 'jakarta.xml.ws:jakarta.xml.ws-api:4.0.3' + installer 'jakarta.activation:jakarta.activation-api:2.1.4' + installer 'jakarta.annotation:jakarta.annotation-api:3.0.0' + installer 'jakarta.xml.bind:jakarta.xml.bind-api:4.0.5' + installer 'jakarta.inject:jakarta.inject-api:2.0.1' + + // Logging + installer 'org.apache.logging.log4j:log4j-api:2.26.0' + installer 'org.apache.logging.log4j:log4j-core:2.26.0' + installer 'org.apache.logging.log4j:log4j-slf4j2-impl:2.26.0' + installer 'org.slf4j:slf4j-api:2.0.18' + + // Scripts + installer 'org.glassfish.jaxb:jaxb-runtime:4.0.9' + installer 'org.glassfish.jaxb:jaxb-core:4.0.9' + installer 'com.sun.istack:istack-commons-runtime:4.2.0' + installer 'org.glassfish.corba:glassfish-corba-omgapi:5.0.2' + installer 'org.openjdk.nashorn:nashorn-core:15.7' + + // Mac + installer 'ca.weblite:java-objc-bridge:1.2' + + // Kirino Engine + installer 'org.joml:joml:1.10.9' + installer 'io.github.classgraph:classgraph:4.8.184' + + // Mixin + installer 'com.cleanroommc:sponge-mixin:0.20.12+mixin.0.8.7' + installer annotationProcessor('io.github.llamalad7:mixinextras-common:0.5.4') + + testImplementation platform('org.junit:junit-bom:6.1.0') + testImplementation 'org.junit.jupiter:junit-jupiter' + testImplementation 'org.junit.vintage:junit-vintage-engine' + testRuntimeOnly 'org.junit.platform:junit-platform-launcher' +} + +tasks.register("genVersion", com.cleanroommc.gradle.helpers.tasks.GenVersionTask) + +tasks.named('compileJava') { + dependsOn tasks.named('genVersion') +} tasks.register('setup') { group = 'setup' - // These must be strings so that we can do lazy resolution. Else we need evaluationDependsOnChildren above - dependsOn ':minecraft:extractMapped' - dependsOn ':cleanroom:extractMapped' + description = 'Materializes the patched Minecraft source base (fresh clones) and generates the version class.' + dependsOn 'copyMinecraftToSourceSet' + dependsOn 'genVersion' + // TODO: move to CG + more robust way to see if setup is needed as switching between branches will be a pain + // Keeps `setup` a no-op once the source base exists; copy task self-guards too. + onlyIf { + def patchedSrc = file('module/minecraft/src/main/java') + !patchedSrc.exists() || (patchedSrc.listFiles()?.length ?: 0) == 0 + } } -subprojects { - tasks.withType(JavaCompile).tap { - configureEach { - options.compilerArgs += ProjectConstants.COMPILER_JVM_ARGUMENTS - options.encoding = 'UTF-8' - } +test { + maxParallelForks = 1 + useJUnitPlatform() + testLogging { + events 'passed', 'skipped', 'failed' } + jvmArgs ProjectConstants.JVM_ARGUMENTS + ProjectConstants.COMPILER_JVM_ARGUMENTS } diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index a1b33044a..cb9d07752 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -4,7 +4,5 @@ repositories { } dependencies { - implementation 'org.ow2.asm:asm:9.9' - implementation 'org.ow2.asm:asm-tree:9.9' implementation 'com.palantir.gradle.gitversion:gradle-git-version:4.3.0' } diff --git a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/ProjectConstants.groovy b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/ProjectConstants.groovy index 5119e4f4f..83dac7fe1 100644 --- a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/ProjectConstants.groovy +++ b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/ProjectConstants.groovy @@ -12,10 +12,4 @@ interface ProjectConstants { '--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED', '--add-exports=java.base/jdk.internal.reflect=ALL-UNNAMED' ] - - Map PATCHER_POST_PROCESSOR = [ - tool: 'net.minecraftforge:mcpcleanup:2.3.2:fatjar', - repo: 'https://maven.minecraftforge.net/', - args: ['--input', '{input}', '--output', '{output}'] - ] } \ No newline at end of file diff --git a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/BytecodeFinder.groovy b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/BytecodeFinder.groovy deleted file mode 100644 index f779b3e92..000000000 --- a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/BytecodeFinder.groovy +++ /dev/null @@ -1,61 +0,0 @@ -package com.cleanroommc.gradle.helpers.tasks - -import groovy.json.JsonBuilder - -import org.gradle.api.DefaultTask -import org.gradle.api.tasks.InputFile -import org.gradle.api.tasks.OutputFile -import org.gradle.api.tasks.TaskAction - -import org.objectweb.asm.ClassReader -import org.objectweb.asm.Opcodes -import org.objectweb.asm.Type -import org.objectweb.asm.tree.ClassNode -import org.objectweb.asm.tree.FieldNode -import org.objectweb.asm.tree.MethodNode - -import java.util.zip.ZipEntry -import java.util.zip.ZipInputStream - -public abstract class BytecodeFinder extends DefaultTask { - @InputFile File jar - @OutputFile output = project.file("build/${name}/output.json") - - @TaskAction - protected void exec() { - Util.init() - - if (output.exists()) - output.delete() - - pre() - - jar.withInputStream { i -> - new ZipInputStream(i).withCloseable { zin -> - ZipEntry zein - while ((zein = zin.nextEntry) != null) { - if (zein.name.endsWith('.class')) { - def node = new ClassNode(Opcodes.ASM7) - new ClassReader(zin).accept(node, 0) - process(node) - } - } - } - } - - post() - output.text = new JsonBuilder(getData()).toPrettyString() - } - - - protected process(ClassNode node) { - if (node.fields != null) node.fields.each { process(node, it) } - if (node.methods != null) node.methods.each { process(node, it) } - } - - protected pre() {} - protected process(ClassNode parent, FieldNode node) {} - protected process(ClassNode parent, MethodNode node) {} - protected post() {} - protected abstract Object getData() -} diff --git a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CheckAccessTransformers.groovy b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CheckAccessTransformers.groovy deleted file mode 100644 index a3dbfe056..000000000 --- a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CheckAccessTransformers.groovy +++ /dev/null @@ -1,231 +0,0 @@ -package com.cleanroommc.gradle.helpers.tasks - -import java.util.ArrayList -import java.util.TreeMap - -import org.gradle.api.DefaultTask -import org.gradle.api.tasks.InputFile -import org.gradle.api.tasks.InputFiles -import org.gradle.api.tasks.TaskAction -import org.objectweb.asm.Opcodes - -public class CheckAccessTransformers extends DefaultTask { - @InputFile File inheritance - @InputFiles File[] ats - - @TaskAction - protected void exec() { - Util.init() - def parse = { line -> - def idx = line.indexOf('#') - def comment = idx == -1 ? null : line.substring(idx) - if (idx != -1) line = line.substring(0, idx - 1) - def (modifier, cls, desc) = (line.trim() + ' ').split(' ', -1) - def key = cls + (desc.isEmpty() ? '' : ' ' + desc) - return [modifier, cls, desc, comment, key] - } - def accessLevel = { access -> - if ((access & Opcodes.ACC_PUBLIC) != 0) return 3 - if ((access & Opcodes.ACC_PROTECTED) != 0) return 2 - if ((access & Opcodes.ACC_PRIVATE) != 0) return 0 - return 1 - } - def accessStr = { access -> - if (access.endsWith('-f') || access.endsWith('+f')) - return 4 - switch (access.toLowerCase()) { - case 'public': return 3 - case 'protected': return 2 - case 'default': return 1 - case 'private': return 0 - default: return -1 - } - } - def json = inheritance.json() - - ats.each { f -> - TreeMap lines = [:] - def group = null - for (def line : f.readLines()) { - if (line.isEmpty()) continue - if (line.startsWith('#group ')) { - def (modifier, cls, desc, comment, key) = parse.call(line.substring(7)) - - if (!desc.equals('*') && !desc.equals('*()') && !desc.equals('')) - throw new IllegalStateException('Invalid group: ' + line) - - group = [modifier: modifier, cls: cls, desc: desc, comment: comment, - 'existing': [] as Set, - 'children': [] as TreeSet, - group: true - ] - if (lines.containsKey(key)) - throw new IllegalStateException('Duplicate group: ' + line) - - lines[key] = group - } else if (group != null) { - if (line.startsWith('#endgroup')) { - group = null - } else { - def (modifier, cls, desc, comment, key) = parse.call(line) - group['existing'].add(key) - } - } else if (line.startsWith('#endgroup')) { - throw new IllegalStateException('Invalid group ending: ' + line) - } else if (line.startsWith('#')) { - //Nom - } else { - def (modifier, cls, desc, comment, key) = parse.call(line) - if (lines.containsKey(key)) { - println('Duplicate: ' + line) - continue - } - lines[key] = [modifier: modifier, cls: cls, desc: desc, comment: comment, group: false] - } - } - - // Process Groups, this will remove any entries outside the group that is covered by the group - for (def key : new ArrayList<>(lines.keySet())) { - def entry = lines.get(key) - if (entry != null && entry['group']) { - def cls = entry['cls'] - def jcls = json.get(cls.replaceAll('\\.', '/')) - if (jcls == null) { - lines.remove(key) - println('Invalid Group: ' + key) - } else if ('*'.equals(entry['desc'])) { - if (!jcls.containsKey('fields')) { - lines.remove(key) - println('Invalid Group, Class has no fields: ' + key) - } else { - jcls['fields'].each { field, value -> - def fkey = cls + ' ' + field - if (accessLevel.call(value['access']) < accessStr.call(entry['modifier'])) { - if (lines.containsKey(fkey)) { - lines.remove(fkey) - } else if (!entry['existing'].contains(fkey)) { - println('Added: ' + fkey) - } - entry['children'].add(fkey) - } else if (lines.containsKey(fkey)) { - lines.remove(fkey) - println('Removed: ' + fkey) - } - } - entry['existing'].stream().findAll{ !entry['children'].contains(it) }.each{ println('Removed: ' + it) } - } - } else if ('*()'.equals(entry['desc'])) { - if (!jcls.containsKey('methods')) { - lines.remove(key) - println('Invalid Group, Class has no methods: ' + key) - } else { - jcls['methods'].each{ mtd, value -> - if (mtd.startsWith('')) - return - key = cls + ' ' + mtd.replace(' ', '') - if (accessLevel.call(value['access']) < accessStr.call(entry['modifier'])) { - if (lines.containsKey(key)) { - lines.remove(key) - } else if (!entry['existing'].contains(key)) { - println('Added: ' + key) - } - entry['children'].add(key) - } else if (lines.containsKey(key)) { - lines.remove(key) - println('Removed: ' + key) - } - } - entry['existing'].stream().findAll{ !entry['children'].contains(it) }.each{ println('Removed: ' + it) } - } - } else if (''.equals(entry['desc'])) { //Make all public non-abstract subclasses - json.each{ tcls,value -> - if (!value.containsKey('methods') || ((value['access'] & Opcodes.ACC_ABSTRACT) != 0)) - return - def parents = [] as Set - def parent = tcls - while (parent != null && json.containsKey(parent)) { - parents.add(parent) - def p = json[parent] - parent = p == null ? null : p['superName'] - } - if (parents.contains(cls.replaceAll('\\.', '/'))) { - value['methods'].each{ mtd, v -> - if (mtd.startsWith('')) { - def child = tcls.replaceAll('/', '\\.') + ' ' + mtd.replace(' ', '') - if (accessLevel.call(v['access']) < 3) { - if (lines.containsKey(child)) { - lines.remove(child) - } else if (!entry['existing'].contains(child)) { - println('Added: ' + child) - } - entry['children'].add(child) - } else if (lines.containsKey(child)) { - lines.remove(child) - println('Removed: ' + child) - } - } - } - } - } - entry['existing'].stream().findAll{ !entry['children'].contains(it) }.each{ println('Removed: ' + it) } - } - } - } - - // Process normal lines, remove invalid and remove narrowing - for (def key : new ArrayList<>(lines.keySet())) { - def entry = lines.get(key) - if (entry != null && !entry['group']) { - def cls = entry['cls'] - def jcls = json.get(cls.replaceAll('\\.', '/')) - if (jcls == null) { - lines.remove(key) - println('Invalid: ' + key) - } else if (entry['desc'] == '') { - if (accessLevel.call(jcls['access']) >= accessStr.call(entry['modifier']) && (entry.comment == null || !entry.comment.startsWith('#force '))) { - lines.remove(key) - println('Invalid Narrowing: ' + key) - } - } else if (!entry['desc'].contains('(')) { - if (!jcls.containsKey('fields') || !jcls['fields'].containsKey(entry['desc'])) { - lines.remove(key) - println('Invalid: ' + key) - } else { - def value = jcls['fields'][entry['desc']] - if (accessLevel.call(value['access']) >= accessStr.call(entry['modifier']) && (entry.comment == null || !entry.comment.startsWith('#force '))) { - lines.remove(key) - println('Invalid Narrowing: ' + key) - println(entry.comment) - } - } - } else { - def jdesc = entry['desc'].replace('(', ' (') - if (!jcls.containsKey('methods') || !jcls['methods'].containsKey(jdesc)) { - lines.remove(key) - println('Invalid: ' + key) - } else { - def value = jcls['methods'][jdesc] - if (accessLevel.call(value['access']) >= accessStr.call(entry['modifier']) && (entry.comment == null || !entry.comment.startsWith('#force '))) { - lines.remove(key) - println('Invalid Narrowing: ' + key) - } - } - } - } - } - - - def data = [] - lines.each { key,value -> - if (!value.group) { - data.add(value.modifier + ' ' + key + (value.comment == null ? '' : ' ' + value.comment)) - } else { - data.add('#group ' + value.modifier + ' ' + key + (value.comment == null ? '' : ' ' + value.comment)) - value.children.each{ data.add(value.modifier + ' ' + it) } - data.add('#endgroup') - } - } - f.text = data.join('\n') - } - } -} diff --git a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CheckExcs.groovy b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CheckExcs.groovy deleted file mode 100644 index e1b482374..000000000 --- a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CheckExcs.groovy +++ /dev/null @@ -1,95 +0,0 @@ -package com.cleanroommc.gradle.helpers.tasks - -import java.util.ArrayList -import java.util.TreeMap - -import org.gradle.api.DefaultTask -import org.gradle.api.tasks.InputFile -import org.gradle.api.tasks.InputFiles -import org.gradle.api.tasks.TaskAction - -import org.objectweb.asm.ClassReader -import org.objectweb.asm.ClassVisitor -import org.objectweb.asm.MethodVisitor -import org.objectweb.asm.Opcodes -import org.objectweb.asm.Type - -import java.util.zip.ZipEntry -import java.util.zip.ZipInputStream - -public class CheckExcs extends DefaultTask { - @InputFile File binary - @InputFiles File[] excs - - @TaskAction - protected void exec() { - Util.init() - def known = [] - binary.withInputStream { i -> - new ZipInputStream(i).withCloseable { zin -> - def visitor = new ClassVisitor(Opcodes.ASM7) { - private String cls - @Override - public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { - this.cls = name - } - - @Override - public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { - known.add(this.cls + '.' + name + descriptor) - super.visitMethod(access, name, descriptor, signature, exceptions) - } - } - ZipEntry zein - while ((zein = zin.nextEntry) != null) { - if (zein.name.endsWith('.class')) { - ClassReader reader = new ClassReader(zin) - reader.accept(visitor, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES) - } - } - } - } - - excs.each { f -> - def lines = [] - f.eachLine { line -> - def idx = line.indexOf('#') - if (idx == 0 || line.isEmpty()) { - return - } - - def comment = idx == -1 ? null : line.substring(idx) - if (idx != -1) line = line.substring(0, idx - 1) - - if (!line.contains('=')) { - println('Invalid: ' + line) - return - } - - def (key, value) = line.split('=', 2) - if (!known.contains(key)) { - println(key) - println('Invalid: ' + line) - return - } - - def (cls, desc) = key.split('\\.', 2) - if (!desc.contains('(')) { - println('Invalid: ' + line) - return - } - def name = desc.split('\\(', 2)[0] - desc = '(' + desc.split('\\(', 2)[1] - - def (exceptions, args) = value.contains('|') ? value.split('|', 2) : [value, ''] - - if (args.split(',').length != Type.getArgumentTypes(desc).length) { - println('Invalid: ' + line) - return - } - lines.add(line) - } - f.text = lines.sort().join('\n') - } - } -} diff --git a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CheckPatches.groovy b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CheckPatches.groovy deleted file mode 100644 index 071de8837..000000000 --- a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CheckPatches.groovy +++ /dev/null @@ -1,218 +0,0 @@ -package com.cleanroommc.gradle.helpers.tasks - -import org.gradle.api.DefaultTask -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.InputDirectory -import org.gradle.api.tasks.TaskAction - -import java.nio.file.Files -import java.nio.file.Paths -import java.util.regex.Pattern - -public class CheckPatches extends DefaultTask { - @InputDirectory File patchDir - @Input boolean autoFix = false - - @TaskAction - protected void exec() { - def hasS2SArtifact = [ - Paths.get("patches/minecraft/net/minecraft/client/renderer/ViewFrustum.java.patch"), - Paths.get("patches/minecraft/net/minecraft/data/BlockModelDefinition.java.patch") - ] - - def verified = true; - project.fileTree(patchDir).each { patch -> - def patchPath = project.rootDir.toPath().relativize(patch.toPath()) - verified &= verifyPatch(patch, autoFix, patchPath.toString(), hasS2SArtifact.contains(patchPath)) - } - - if (!verified) - throw new RuntimeException('One or more patches failed verification. Check the log for errors.') - } - - def verifyPatch(patch, fix, patchPath, hasS2SArtifact) { - def hunk_start_pattern = Pattern.compile('^@@ -[0-9,]* \\+[0-9,]* @@$') - def white_space_pattern = Pattern.compile('^[+\\-]\\s*$') - def import_pattern = Pattern.compile('^[+\\-]\\s*import.*') - def field_pattern = Pattern.compile('^[+\\-][\\s]*((public|protected|private)[\\s]*)?(static[\\s]*)?(final)?([^=;]*)(=.*)?;\\s*$') - def method_pattern = Pattern.compile('^[+\\-][\\s]*((public|protected|private)[\\s]*)?(static[\\s]*)?(final)?([^(]*)[(]([^)]*)?[)]\\s*[{]\\s*$') - def class_pattern = Pattern.compile('^[+\\-][\\s]*((public|protected|private)[\\s]*)?(static[\\s]*)?(final[\\s]*)?(class|interface)([^{]*)[{]\\s*$') - - def accessMap = [("private"):0, (null):1, ("protected"):2, ("public"):3] - - def hasProblem = false; - def lines = patch.readLines() - - def hunksStart = 0 - def onlyWhiteSpace = false - - def didFix = false - def newLines = [] - def whiteSpaceErrors = [] - - // First two lines are file name ++/-- and we do not care - newLines.add(lines[0] + '\n') - newLines.add(lines[1] + '\n') - - int i = 2 - for (; i < lines.size(); ++i) { - def line = lines[i] - newLines.add(line + '\n') - - if (hunk_start_pattern.matcher(line).find()) { - if (onlyWhiteSpace) { - if (fix || hasS2SArtifact) { - logger.lifecycle("Removing white space hunk starting at line {}, file: {}", hunksStart + 1, patchPath) - def toRemove = i - hunksStart; - while (toRemove-- > 0) - newLines.remove(newLines.size() - 1) - didFix = true - } - else { - logger.lifecycle("Patch contains only white space hunk starting at line {}, file: {}", hunksStart + 1, patchPath) - hasProblem = true - } - } - else { - if (!whiteSpaceErrors.empty) - hasProblem = true - whiteSpaceErrors.each { error -> logger.lifecycle(error) } - whiteSpaceErrors.clear() - } - hunksStart = i - onlyWhiteSpace = true - continue - } - - if (line.startsWithAny('+','-')) { - def prefixChange = false - def prevLine = lines[i - 1] - - if (line.charAt(0) == (char)'+' && prevLine.charAt(0) == (char)'-') { - def prevTrim = prevLine.substring(1).replaceAll("\\s", "") - def currTrim = line.substring(1).replaceAll("\\s", "") - - if (prevTrim.equals(currTrim)) { - prefixChange = true - } - - def pMatcher = field_pattern.matcher(prevLine) - def cMatcher = field_pattern.matcher(line) - - if (pMatcher.find() && cMatcher.find() && - pMatcher.group(6) == cMatcher.group(6) && // = ... - pMatcher.group(5) == cMatcher.group(5) && // field name - pMatcher.group(3) == cMatcher.group(3) && // static - (accessMap[pMatcher.group(2)] < accessMap[cMatcher.group(2)] || pMatcher.group(4) != cMatcher.group(4))) { - logger.lifecycle("Patch contains access changes or final removal at line {}, file: {}", i + 1, patchPath) - hasProblem = true - } - - pMatcher = method_pattern.matcher(prevLine) - cMatcher = method_pattern.matcher(line) - - if (pMatcher.find() && cMatcher.find() && - pMatcher.group(6) == cMatcher.group(6) && // params - pMatcher.group(5) == cMatcher.group(5) && // void name - pMatcher.group(3) == cMatcher.group(3) && // static - (accessMap[pMatcher.group(2)] < accessMap[cMatcher.group(2)] || pMatcher.group(4) != cMatcher.group(4))) { - logger.lifecycle("Patch contains access changes or final removal at line {}, file: {}", i + 1, patchPath) - hasProblem = true - } - - pMatcher = class_pattern.matcher(prevLine) - cMatcher = class_pattern.matcher(line) - - if (pMatcher.find() && cMatcher.find() && - pMatcher.group(6) == cMatcher.group(6) && // ClassName<> extends ... - pMatcher.group(5) == cMatcher.group(5) && // class | interface - pMatcher.group(3) == cMatcher.group(3) && // static - (accessMap[pMatcher.group(2)] < accessMap[cMatcher.group(2)] || pMatcher.group(4) != cMatcher.group(4))) { - logger.lifecycle("Patch contains access changes or final removal at line {}, file: {}", i + 1, patchPath) - hasProblem = true - } - } - - if (line.charAt(0) == (char)'-' && i + 1 < lines.size()) { - def nextLine = lines[i + 1] - if (nextLine.charAt(0) == (char)'+') { - def nextTrim = nextLine.substring(1).replaceAll("\\s", "") - def currTrim = line.substring(1).replaceAll("\\s", "") - - if (nextTrim.equals(currTrim)) { - prefixChange = true - } - } - } - - def isWhiteSpaceChange = white_space_pattern.matcher(line).find() - - if (!prefixChange && !isWhiteSpaceChange) { - onlyWhiteSpace = hasS2SArtifact && import_pattern.matcher(line).find() - } - else if (isWhiteSpaceChange) { - def prevLineChange = prevLine.startsWithAny('+','-') - def nextLineChange = i + 1 < lines.size() && lines[i + 1].startsWithAny('+','-') - - if (!prevLineChange && !nextLineChange) { - whiteSpaceErrors.add(String.format("Patch contains white space change in valid hunk at line %d (cannot auto fix), file: %s", i + 1, patchPath)) - } - } - - if (line.contains("\t")) { - if (!fix) { - logger.lifecycle("Patch contains tabs on line {}, file: {}", i + 1, patchPath) - hasProblem = true - } - else { - logger.lifecycle("Fixing tabs on line {}, file: {}", i + 1, patchPath) - line = line.replaceAll('\t', ' ') - newLines.remove(newLines.size() - 1) - newLines.add(line + '\n') - didFix = true - } - } - - if (import_pattern.matcher(line).find() && !hasS2SArtifact) { - logger.lifecycle("Patch contains import change on line {}, file: {}", i + 1, patchPath) - hasProblem = true - } - } - } - - if (onlyWhiteSpace) { - if (fix || hasS2SArtifact) { - logger.lifecycle("Removing white space hunk starting at line {}, file: {}", hunksStart + 1, patchPath) - def toRemove = i - hunksStart; - while (toRemove-- > 0) - newLines.remove(newLines.size() - 1) - didFix = true - } - else { - logger.lifecycle("Patch contains only white space hunk starting at line {}, file: {}", hunksStart + 1, patchPath) - hasProblem = true - } - } - else { - if (!whiteSpaceErrors.empty) - hasProblem = true - whiteSpaceErrors.each { error -> logger.lifecycle(error) } - } - - if (didFix) { - if (newLines.size() <= 2) { - logger.lifecycle("Patch is now empty removing, file: {}", patchPath) - Files.delete(patch.toPath()) - } - else { - if (!hasS2SArtifact) - logger.lifecycle("*** Updating patch file. Please run setup then genPatches again. ***") - patch.withWriter('UTF-8') { writer -> - newLines.each { l -> writer.write(l) } - } - } - } - - return !hasProblem - } -} diff --git a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CheckSAS.groovy b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CheckSAS.groovy deleted file mode 100644 index d5c585a23..000000000 --- a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CheckSAS.groovy +++ /dev/null @@ -1,64 +0,0 @@ -package com.cleanroommc.gradle.helpers.tasks - -import java.util.ArrayList -import java.util.TreeMap - -import org.gradle.api.DefaultTask -import org.gradle.api.tasks.InputFile -import org.gradle.api.tasks.InputFiles -import org.gradle.api.tasks.TaskAction -import org.objectweb.asm.Opcodes - -public class CheckSAS extends DefaultTask { - @InputFile File inheritance - @InputFiles File[] sass - - @TaskAction - protected void exec() { - Util.init() - def json = inheritance.json() - - sass.each { f -> - def lines = [] - f.eachLine { line -> - if (line[0] == '\t') return //Skip any tabbed lines, those are ones we add - def idx = line.indexOf('#') - if (idx == 0 || line.isEmpty()) { - lines.add(line) - return - } - def comment = idx == -1 ? null : line.substring(idx) - if (idx != -1) line = line.substring(0, idx - 1) - def (cls, desc) = (line.trim() + ' ').split(' ', -1) - cls = cls.replaceAll('\\.', '/') - desc = desc.replace('(', ' (') - - if (json[cls] == null || (!desc.isEmpty() && (json[cls]['methods'] == null || json[cls]['methods'][desc] == null))) { - println('Invalid: ' + line) - return - } - - //Class SAS - if (desc.isEmpty()) { - lines.add(cls + (comment == null ? '' : ' ' + comment)) - if (json[cls]['methods'] != null) - (json[cls]['methods'] as TreeMap).each { - findChildMethods(json, cls, it.key).each { lines.add('\t' + it) } - } - return - } - - //Method SAS - lines.add(cls + ' ' + desc.replace(' ', '') + (comment == null ? '' : ' ' + comment)) - findChildMethods(json, cls, desc).each { lines.add('\t' + it) } - } - f.text = lines.join('\n') - } - } - - protected static findChildMethods(json, cls, desc) - { - return json.values().findAll{ it.methods != null && it.methods[desc] != null && it.methods[desc].override == cls} - .collect { it.name + ' ' + desc.replace(' ', '') } as TreeSet - } -} diff --git a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/ClosureHelper.groovy b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/ClosureHelper.groovy deleted file mode 100644 index 13f5cca6d..000000000 --- a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/ClosureHelper.groovy +++ /dev/null @@ -1,31 +0,0 @@ -package com.cleanroommc.gradle.helpers.tasks - -import java.util.function.BiConsumer - -public class ClosureHelper { - BiConsumer callback - - public ClosureHelper(Closure cl, BiConsumer callback) { - this.callback = callback - apply(this, cl) - } - - - def methodMissing(String name, Object args) { - if (!args.class.isArray()) return - Object[] aargs = (Object[])args - - if (aargs.length == 1 && aargs[0] instanceof Closure) { - this.callback.accept(name, (Closure)aargs[0]) - } else { - throw new IllegalArgumentException('Unknown method: "' + name + '" with arguments ' + args + ' for ' + this) - } - } - - static def apply(def obj, Closure cl) { - cl.delegate = obj - cl.resolveStrategy = Closure.DELEGATE_FIRST - cl() - return obj - } -} \ No newline at end of file diff --git a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CreateMMCPackTask.groovy b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CreateMMCPackTask.groovy deleted file mode 100644 index ccba9f944..000000000 --- a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CreateMMCPackTask.groovy +++ /dev/null @@ -1,138 +0,0 @@ -package com.cleanroommc.gradle.helpers.tasks - -import groovy.json.JsonSlurper -import groovy.json.JsonOutput -import org.gradle.api.DefaultTask -import org.gradle.api.file.RegularFileProperty -import org.gradle.api.file.DirectoryProperty -import org.gradle.api.provider.Property -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.InputDirectory -import org.gradle.api.tasks.InputFile -import org.gradle.api.tasks.OutputFile -import org.gradle.api.tasks.TaskAction - -abstract class CreateMMCPackTask extends DefaultTask { - @InputFile - abstract RegularFileProperty getVersionJson() - - @InputDirectory - abstract DirectoryProperty getTemplateDir() - - @InputFile - abstract RegularFileProperty getUniversalJarFile() - - @Input - abstract Property getCleanroomVersion() - - @Input - abstract Property getIsRelease() - - @OutputFile - abstract RegularFileProperty getOutputZip() - - @TaskAction - void create() { - def versionJsonFile = getVersionJson().get().asFile - def templateDir = getTemplateDir().get().asFile - def jarFile = getUniversalJarFile().get().asFile - def version = getCleanroomVersion().get() - def isRelease = getIsRelease().get() - - def outputDir = new File(getTemporaryDir(), 'mmc-output') - outputDir.deleteDir() - outputDir.mkdirs() - - project.copy { - from(templateDir) { - exclude 'patches/net.minecraft.json' - } - into outputDir - } - project.copy { - from new File(templateDir, 'patches/net.minecraft.json') - into new File(outputDir, 'patches') - } - - def versionJson = new JsonSlurper().parse(versionJsonFile) - def libraries = versionJson.libraries - def mainClass = versionJson.mainClass - def lwjglVersion = '' - def forgeLibraries = [] - def lwjglLibraries = [] - - libraries.each { lib -> - def libName = lib.name as String - if (libName.contains('org.lwjgl:')) { - if (!lwjglVersion) { - lwjglVersion = libName.split(':')[2] - } - if (libName.contains('-arm64')) { - def rules = lib.rules - if (rules && rules[0] && rules[0].os) { - def arm64Rule = [action: 'allow', os: [name: rules[0].os.name + '-arm64']] - ((List) rules).add(arm64Rule) - } - } - lwjglLibraries.add(lib) - } else { - def parts = libName.split(':') - if (parts.length >= 2 && parts[1] == 'cleanroom') { - if (isRelease) { - lib.downloads.artifact.url = "https://repo.cleanroommc.com/releases/com/cleanroommc/cleanroom/${version}/cleanroom-${version}-universal.jar" - forgeLibraries.add(lib) - } else { - forgeLibraries.add([ - name: "com.cleanroommc:cleanroom:${version}-universal", - 'MMC-hint': 'local' - ]) - } - } else { - forgeLibraries.add(lib) - } - } - } - - def forgePatchTemplate = new JsonSlurper().parse(new File(templateDir, 'patches/net.minecraftforge.json')) - forgePatchTemplate.libraries = forgeLibraries - forgePatchTemplate.mainClass = mainClass - forgePatchTemplate.version = version - new File(outputDir, 'patches/net.minecraftforge.json').text = JsonOutput.prettyPrint(JsonOutput.toJson(forgePatchTemplate)) - - def lwjglPatchTemplate = new JsonSlurper().parse(new File(templateDir, 'patches/org.lwjgl3.json')) - lwjglPatchTemplate.libraries = lwjglLibraries - lwjglPatchTemplate.version = lwjglVersion - new File(outputDir, 'patches/org.lwjgl3.json').text = JsonOutput.prettyPrint(JsonOutput.toJson(lwjglPatchTemplate)) - - def mmcPackFile = new File(outputDir, 'mmc-pack.json') - def mmcPack = new JsonSlurper().parse(mmcPackFile) - mmcPack.components.each { component -> - if (component.uid == 'org.lwjgl3') { - component.version = lwjglVersion - component.cachedVersion = lwjglVersion - } - if (component.uid == 'net.minecraft' && component.cachedRequires) { - component.cachedRequires[0].suggests = lwjglVersion - } - if (component.uid == 'net.minecraftforge') { - component.version = version - component.cachedVersion = version - } - } - mmcPackFile.text = JsonOutput.prettyPrint(JsonOutput.toJson(mmcPack)) - - if (!isRelease) { - def libsDir = new File(outputDir, 'libraries') - libsDir.mkdirs() - project.copy { - from jarFile - into libsDir - rename { "cleanroom-${version}-universal.jar" } - } - } - - def zipFile = getOutputZip().get().asFile - zipFile.parentFile.mkdirs() - project.ant.zip(destfile: zipFile.absolutePath, basedir: outputDir.absolutePath) - } -} diff --git a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CrowdinTask.groovy b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CrowdinTask.groovy deleted file mode 100644 index f1c4b36c5..000000000 --- a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/CrowdinTask.groovy +++ /dev/null @@ -1,65 +0,0 @@ -package com.cleanroommc.gradle.helpers.tasks - -import org.gradle.api.DefaultTask -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.TaskAction -import org.gradle.api.tasks.Optional -import org.gradle.api.tasks.OutputFile - -import java.util.zip.ZipEntry -import java.util.zip.ZipInputStream -import java.util.zip.ZipOutputStream -import java.net.URL - -public class CrowdinTask extends DefaultTask { - @Input String id = 'minecraft-forge' - @Input @Optional String key - @Input boolean json = true - @OutputFile output = project.file("build/${name}/output.zip") - @OutputFile export = project.file("build/${name}/export.json") - - CrowdinTask() { - outputs.upToDateWhen{ false } - } - - @TaskAction - def run() { - if (output.exists()) - output.delete() - - if (key == null) - return - - // Force an export - new URL("https://api.crowdin.com/api/project/${id}/export?key=${key}").withInputStream { i -> - export.withOutputStream { it << i } - } - - if (!export.text.contains('success')) { - throw new RuntimeException("Crowdin export failed, see ${export} for more info") - } - - new URL("https://api.crowdin.com/api/project/${id}/download/all.zip?key=${key}").withInputStream { i -> - new ZipInputStream(i).withCloseable { zin -> - output.withOutputStream { out -> - new ZipOutputStream(out).withCloseable { zout -> - ZipEntry zein - while ((zein = zin.nextEntry) != null) { - if (zein.isDirectory()) { - zout.putNextEntry(new ZipEntry(zein.name)) - } else { - // 1.13+ uses json - if (zein.name.endsWith('.json') == json) { - ZipEntry zeout = new ZipEntry(json ? zein.name.toLowerCase() : zein.name) - zeout.time = 1 - zout.putNextEntry(zeout) - zout << zin - } - } - } - } - } - } - } - } -} diff --git a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/DownloadLibrariesTask.groovy b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/DownloadLibrariesTask.groovy deleted file mode 100644 index 257458ee9..000000000 --- a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/DownloadLibrariesTask.groovy +++ /dev/null @@ -1,43 +0,0 @@ -package com.cleanroommc.gradle.helpers.tasks - -import org.gradle.api.DefaultTask -import org.gradle.api.tasks.InputFile -import org.gradle.api.tasks.TaskAction -import org.gradle.api.tasks.OutputDirectory - -import java.io.File -import java.util.HashSet -import java.util.Set -import java.net.URL - -public class DownloadLibrariesTask extends DefaultTask { - @InputFile File input - @OutputDirectory File output = project.file("build/${name}/") - Set libraries = new HashSet<>() - - @TaskAction - def run() { - Util.init() - - def json = input.json().libraries.each { lib -> - //TODO: Thread? - def artifacts = [lib.downloads.artifact] + lib.downloads.get('classifiers', [:]).values() - artifacts.each{ art -> - def target = new File(output, art.path) - libraries.add(target) - if (!target.exists() || !art.sha1.equals(target.sha1())) { - project.logger.lifecycle("Downloading ${art.url}") - if (!target.parentFile.exists()) { - target.parentFile.mkdirs() - } - new URL(art.url).withInputStream { i -> - target.withOutputStream { it << i } - } - if (!art.sha1.equals(target.sha1())) { - throw new IllegalStateException("Failed to download ${art.url} to ${target.canonicalPath} SHA Mismatch") - } - } - } - } - } -} diff --git a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/FieldCompareFinder.groovy b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/FieldCompareFinder.groovy deleted file mode 100644 index 2ecba7484..000000000 --- a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/FieldCompareFinder.groovy +++ /dev/null @@ -1,108 +0,0 @@ -package com.cleanroommc.gradle.helpers.tasks - -import groovy.transform.EqualsAndHashCode - -import java.util.ArrayList -import java.util.HashMap -import java.util.TreeMap -import java.util.TreeSet -import java.util.function.BiConsumer - -import org.gradle.api.DefaultTask -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.Nested -import org.gradle.api.tasks.Optional - -import org.objectweb.asm.Opcodes -import org.objectweb.asm.Type -import org.objectweb.asm.tree.ClassNode -import org.objectweb.asm.tree.FieldNode -import org.objectweb.asm.tree.MethodNode - -import static org.objectweb.asm.Opcodes.* - -public class FieldCompareFinder extends BytecodeFinder { - @Nested - Map fields = [:] as HashMap - Map fieldsReverse = [:] as HashMap - Map> targets = [:] as TreeMap - - @Override - protected pre() { - //fields.each{ k,v -> logger.lifecycle("Fields: " + k + ' ' + v) } - } - - @Override - protected process(ClassNode parent, MethodNode node) { - def last = null - def parentInstance = new ObjectTarget(owner: parent.name, name: '', desc: '') - for (int x = 0; x < node.instructions.size(); x++) { - def current = node.instructions.get(x) - if (current.opcode == IF_ACMPEQ || current.opcode == IF_ACMPNE) { - if (last != null && (last.opcode == GETSTATIC || last.opcode == GETFIELD)) { - def target = new Search(cls: last.owner, name: last.name) - def wanted = fieldsReverse.get(target) - def original = fields.get(wanted) - def instance = new ObjectTarget(owner: parent.name, name: node.name, desc: node.desc) - if (wanted != null && (original.blacklist == null || (!original.blacklist.contains(instance) && !original.blacklist.contains(parentInstance)))) { - targets.computeIfAbsent(wanted, { k -> new TreeSet() }).add(instance) - } - } - } - last = current - } - } - - @Override - protected Object getData() { - def ret = [:] as HashMap - targets.forEach{ k, v -> - def e = fields.get(k) - ret[k] = [ - cls: e.cls, - name: e.name, - replacement: e.replacement, - targets: v - ] - } - return ret - } - - @EqualsAndHashCode(excludes = ['replacement', 'blacklist']) - public static class Search { - @Input - String cls - - @Input - String name - - @Input - String replacement - - @Nested - @Optional - Set blacklist - - @Override - String toString() { - return cls + '.' + name - } - - def blacklist(def owner, def name, def desc) { - if (blacklist == null) - blacklist = new HashSet() - blacklist.add(new ObjectTarget(owner: owner, name: name, desc: desc)) - } - def blacklist(def owner) { - blacklist(owner, '', '') - } - } - - def fields(Closure cl) { - new ClosureHelper(cl, {name, ccl -> - def search = ClosureHelper.apply(new Search(), ccl) - this.fields.put(name, search) - this.fieldsReverse.put(search, name) - }) - } -} diff --git a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/GenVersionTask.groovy b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/GenVersionTask.groovy index 564574a17..fbbad3059 100644 --- a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/GenVersionTask.groovy +++ b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/GenVersionTask.groovy @@ -14,7 +14,7 @@ abstract class GenVersionTask extends DefaultTask { @InputFile final File template = new File("${getProject().rootProject.projectDir}/templates/CleanroomVersion.java") @OutputFile - final File versionClass = new File("${getProject().rootProject.projectDir}/src/main/java/com/cleanroommc/common/CleanroomVersion.java") + final File versionClass = new File("${getProject().rootProject.projectDir}/module/cleanroom/src/main/java/com/cleanroommc/common/CleanroomVersion.java") @TaskAction void action() { versionClass.withWriter { def writer -> diff --git a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/ObjectTarget.groovy b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/ObjectTarget.groovy deleted file mode 100644 index c9b95c30a..000000000 --- a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/ObjectTarget.groovy +++ /dev/null @@ -1,31 +0,0 @@ -package com.cleanroommc.gradle.helpers.tasks - -import groovy.transform.EqualsAndHashCode - -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.Optional - -@EqualsAndHashCode -public class ObjectTarget implements Comparable { - @Input - String owner - - @Input - String name - - @Input - @Optional - String desc - - @Override - String toString() { - if (desc == null) - return owner + '.' + name - return owner + '.' + name + desc - } - - @Override - int compareTo(ObjectTarget o) { - return toString().compareTo(o.toString()) - } -} diff --git a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/Util.groovy b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/Util.groovy index 783989b18..575f7b81e 100644 --- a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/Util.groovy +++ b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/Util.groovy @@ -1,179 +1,6 @@ package com.cleanroommc.gradle.helpers.tasks -import groovy.json.JsonSlurper -import org.gradle.api.GradleException -import org.gradle.api.artifacts.Configuration - -import java.security.MessageDigest -import java.text.SimpleDateFormat - class Util { - static void init() { - File.metaClass.sha1 = { -> - MessageDigest md = MessageDigest.getInstance('SHA-1') - delegate.eachByte 4096, {byte[] bytes, int size -> - md.update(bytes, 0, size) - } - return md.digest().collect {String.format "%02x", it}.join() - } - - File.metaClass.json = { -> new JsonSlurper().parseText(delegate.text as String) } - - Date.metaClass.iso8601 = { -> - def format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") - def result = format.format(delegate) - return result[0..21] + ':' + result[22..-1] - } - - String.metaClass.rsplit = { String del, int limit = -1 -> - def lst = new ArrayList() - def x = 0, idx - def tmp = delegate - while ((idx = tmp.lastIndexOf(del)) != -1 && (limit == -1 || x++ < limit)) { - lst.add(0, tmp.substring(idx + del.length(), tmp.length())) - tmp = tmp.substring(0, idx) - } - lst.add(0, tmp) - return lst - } - } - - static String[] getClasspath(project, libs, artifact) { - def ret = [] - artifactTree(project, artifact).each { key, lib -> - libs[lib.name] = lib - if (lib.name != artifact) - ret.add(lib.name) - } - return ret - } - - static def getArtifacts(Configuration config, boolean classifiers) { - def ret = [:] - config.resolvedConfiguration.resolvedArtifacts.each { - def art = [ - group: it.moduleVersion.id.group, - name: it.moduleVersion.id.name, - version: it.moduleVersion.id.version, - classifier: it.classifier, - extension: it.extension, - file: it.file - ] - def key = art.group + ':' + art.name - def folder = "${art.group.replace('.', '/')}/${art.name}/${art.version}/" - def filename = "${art.name}-${art.version}" - if (art.classifier != null) - filename += "-${art.classifier}" - filename += ".${art.extension}" - def path = "${folder}${filename}" - def url = getNativeURL(path, filename) - //TODO remove when Mojang launcher is updated - if (!classifiers && art.classifier != null) { - // Mojang launcher doesn't currently support classifiers, so... move it to part of the version, and force the extension to 'jar' - // However, keep the path normal so that our mirror system works. - art.version = "${art.version}-${art.classifier}" - art.classifier = null - art.extension = 'jar' - path = "${art.group.replace('.', '/')}/${art.name}/${art.version}/${art.name}-${art.version}.jar" - } - ret[key] = [ - name: "${art.group}:${art.name}:${art.version}" + (art.classifier == null ? '' : ":${art.classifier}") + (art.extension == 'jar' ? '' : "@${art.extension}"), - downloads: [ - artifact: [ - path: path, - url: url, - sha1: sha1(art.file as File), - size: art.file.length() - ] - ] - ] - } - return ret - } - - static def getLWJGLNatives(nativeConfig, compileConfig, natives, arch) { - def ret = [:] - def data = [ '' : [:]] - nativeConfig.resolvedConfiguration.resolvedArtifacts.each { - data.putIfAbsent(it.moduleVersion.id.name, [ - group : it.moduleVersion.id.group, - version : it.moduleVersion.id.version, - extension: it.extension, - ]) - } - compileConfig.files.each {file -> - try { - def name = natives.stream().filter(it -> file.getName().contains(it)).findFirst().get() - def classifier = arch.stream().filter(it -> file.getName().contains(it)).findFirst().get() - def art = [ - name : name, - group : data.get(name).get("group"), - version : data.get(name).get("version"), - extension : data.get(name).get("extension"), - classifier: classifier - ] - def key = art.group + ':' + art.name + ':' + art.classifier - def folder = "${art.group.replace('.', '/')}/${art.name}/${art.version}/" - def filename = "${art.name}-${art.version}" - if (art.classifier != null) - filename += "-${art.classifier}" - filename += ".${art.extension}" - def path = "${folder}${filename}" - def url = getNativeURL(path, filename) - ret[key] = [ - name: "${art.group}:${art.name}:${art.version}" + ":${art.classifier}" + (art.extension == 'jar' ? '' : "@${art.extension}"), - downloads: [ - artifact: [ - path: path, - url : url, - sha1: sha1(file as File), - size: file.length() - ] - ], - rules : [ - [ - action: "allow", - os : [ - name: getOSName(art.classifier) - ] - ] - ] - ] - } catch (ignored) {} - } - return ret - } - - // TODO: Change to standard maven - static def getNativeURL(path, filename) { - def urlList = [ - "https://repo.maven.apache.org/maven2/", - "https://libraries.minecraft.net/", - "https://repo.cleanroommc.com/releases/", - "https://maven.arcseekers.com/releases/", - "https://maven.minecraftforge.net/", - ] - try { - return urlList.stream().map(original -> original + path) - .filter((String it) -> this::checkExists(it)).findFirst().get() - } catch (NoSuchElementException ignored) { - throw new GradleException("Can't find " + filename + " from defined repositories.\n" - + "Please check and make sure all repositories are setup properly.\n" - + "At: com.cleanroommc.gradle.helpers.tasks.Util#getNativeURL(String, String)\n" - + "Current defined repositories: (Sort by order)\n" - + String.join("\n" , urlList) as String) - } - } - - static def getOSName(nativeClassifier) { - if (nativeClassifier.contains('natives-linux')) { - return 'linux' - } else if (nativeClassifier.contains('natives-macos')) { - return 'osx' - } else if (nativeClassifier.contains('natives-windows')) { - return 'windows' - } - } static def getCurrentArch() { def osName = System.getProperty("os.name").toLowerCase(); @@ -194,41 +21,4 @@ class Util { } } - static def iso8601Now() { - new Date().iso8601() - } - - static def sha1(File file) { - MessageDigest md = MessageDigest.getInstance('SHA-1') - file.eachByte 4096, {byte[] bytes, int size -> - md.update(bytes, 0, size) - } - return md.digest().collect {String.format "%02x", it}.join() - } - - private static def artifactTree(project, artifact) { - if (!project.ext.has('tree_resolver')) - project.ext.tree_resolver = 1 - def cfg = project.configurations.create('tree_resolver_' + project.ext.tree_resolver++) - def dep = project.dependencies.create(artifact) - cfg.dependencies.add(dep) - def files = cfg.resolve() - return getArtifacts(cfg, true) - } - - private static boolean checkExists(String url) { - try { - def code = new URI(url).toURL().openConnection().with { - requestMethod = 'HEAD' - connect() - responseCode - } - return code == 200 - } catch (Exception e) { - if (e.toString().contains('unable to find valid certification path to requested target')) - throw new RuntimeException('Failed to connect to ' + url + ': Missing certificate root authority, try updating java') - throw e - } - } - -} \ No newline at end of file +} diff --git a/gradle.properties b/gradle.properties index 20d0f6ab6..a6aec10fd 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,20 +1,6 @@ title = Cleanroom vendor = CleanroomMC -last_forge_version = 14.23.5.2864 - -# Minecraft & Mappings -mapping_channel = stable -mapping_version = 39-1.12 -minecraft_version = 1.12.2 -mcp_version = 20260220.202731 - -# Related Tooling -special_source = net.md-5:SpecialSource:1.9.0 -special_source_mcp = net.md-5:SpecialSource:1.8.5 -binary_patcher = net.minecraftforge:binarypatcher:1.1.1:fatjar -installer_tools_version = 1.4.5 - # Libraries asm_version = 9.10.1 asm_deprecated = 7.1 @@ -37,7 +23,8 @@ org.gradle.jvmargs = -Xmx4G org.gradle.parallel=true # Allow Gradle to cache build to avoid recompiling classes that did not change. org.gradle.caching=true +# Configuration cache: speeds up configuration by reusing the task graph. +org.gradle.configuration-cache=true +org.gradle.configuration-cache.problems=warn # Set java home when gradle refuse to respect IDE setting -# org.gradle.java.home=/usr/lib/jvm/java-1.17.0-openjdk-amd64 -# Daemon -org.gradle.daemon=false \ No newline at end of file +# org.gradle.java.home=/usr/lib/jvm/java-1.17.0-openjdk-amd64 \ No newline at end of file diff --git a/mmcpack-template/.packignore b/mmcpack-template/.packignore deleted file mode 100644 index cd4a8cd2b..000000000 --- a/mmcpack-template/.packignore +++ /dev/null @@ -1 +0,0 @@ -.minecraft \ No newline at end of file diff --git a/mmcpack-template/cleanroom.png b/mmcpack-template/cleanroom.png deleted file mode 100644 index a8ee31b3551bb10ae204191ceb65454732a69557..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47513 zcmcG#1wd5YyDz*c9ZE`4VutSS2I&@QC5NHAha8ZWR!StqK%`5$lm-DoMMOeU7?AF| z8{YT-o^$Va&OPV5-*-oWnZ4I~*0Y}YJ+ars>FKBv;?dv%06?g&rlb!5nBZGX0CEHT zvlsB?1pI^Rp=Rn00Qh8AKN!HX=TrcIXYXiW;$xz%B?)(T<+ZkTw?Xg*xO#x20YF+V zz{48ujPQZlAnYC8WEeM_+Zmybwla*yBHH}g9(NHAj%tBki2H#$2Jk>=3|6j5Aku9VN|$U5Ne{W2fgd=g@B6k^7Fv? z`GueY0;0UOws0{UxG*yBJ|2>MeE$Cay#7MG?q2qM0umAueEfoZf`UBY2p(^wn~!w>kDE8szbGgnyy0Gs z9zKrlZqO@=);8|GJ~E6TuYYaA)#D$sZr*NXJnf}F?w~s#J-$e7@m<|sAXR?QbyN|oKgZqCXgnw@TPonT~wEIsMyt?y0 z4MhYv{wG7P?))>t|2+Yr zWbK2HVFV3HkcVHCM^M~=UszH^TvCLei(f#JpZ~9++MsdTTKic4`@v#7{2~Sd0+J%& zc;WwPu)D3J9rC{%Y73XNbN6z!1{LS%YHg3;^Ki4jUQJtDQr*ql$Jz~!P*;*+1X<;E zbhMSUwc!^M7nBg=u@wgyMFw=1g!bt);4zhB6k0pujCH*y)vq+`G0ws ztvei~@sBnnMMUiQh3v#_c*I1kMR?$FVOt(?ei42iaRgk#MvNbBCjz(q7d2fkN6^Ww zUH(1QE3RxoiUJaXHgJRuoJUwp$d(5I7nb0$;kOk7$=X;83kV8}SPMxoLjP^uyY4RT zUfS-qpv;9Bp;y|L1j&P}T3`8>45Pr`7fr5A)y4O(i(-QO;EPY->i6IGP5+Dg|90EZ z%@Gu_AS3k3UL>#AzYl^J$bhJbh>*zN*Yz9&5H2Q4j-b@MuNe^$_}7%{Tc-cZtt&LU z@=-}OM{m&Tkbk4ieT3)V?_3lDhIzZ&`S@FVAr$OE8UL4l!S|mr?``e(zh_;{MnGIt$i|MxP6%$xBPbwj$73xd zV8bISYQryXV=aiVy;9wO#=3~4ps1v<;J>`+|Ah6wX~P|?-Ru!yAmU^EKi`ayjWq&c zCv3xGYa?OJBg`+%&toGl2yVs(fv~nkhzY|H@c(Et{~;v&U)~Jd-OUf-_3sSJ!`jOl z45kP#Zy82AFLzg{wTFj`BmCOG`25^#|Bg`qxFpoa9r|wo^q&gN7UAXi?`+`TuksHI z(ElIT`!6l-zlVqaPmBA%tR%jx6yYxz;QL<@;;+w2e@Rm1N;lV`SMoo?g8!}!g0WZ< z1owa7{{I~?|FypR|5t#&vYP9S|GQl2UzflH?CR}5xgYr9pX?Fg270O&m>W`VD_a9V z`FC|C1%rU+8|TO@W@98vLjIjbd)L;I2W4*ig>=lYT0oJskGlsou^rvHP}O@QC_&)6 z5FCHVCZXd-+@~JygEQHnGl7GIm6~vj1dQZP?jKDhEVb@sGtGfz3*kemjVDEYh*B9M{YSf(Cm@mZAmG0-&MP6atY5{nKY8T(ez_L8vW@d@APvx zUMYYg2Oa^M7mv*OfTtR-eStqa(wi$XBPCI@LA{=O+!VjWZvnI*4;{YKBdhUWZB0n{ z#eK7GaRF919Z;(*{YyzT6QS*7%%g%8WcxgFM(xKbJq2cDiakclxbO5O`Fj!x%4yd` zt>5CA)}$C8_qew{-~lEWR+8MuL>9SM`y2pfR**C90eSV&2QqAtP$~*&B#L+kg1THo z&d6~PQaw_|Gs4c=nDsHi0Js3HXqL;)Vm|p|15V(m)vf;Y*2u2tUSO-zR4EmH6lQ$4 zjnyfDx?D%jw5t<{ku^=R(GW~2wMwIDB2P>3jDQY2;E4b?rj@axCETnni1#UR> z-2{4i6*)sb?Iu=l0y13bGs+YhjQdz|u5wI6sGyk+|6@Gh9h^gOC1q3`RrJgy|C6v{ zgFxkqiRQuG7E0`{3V0S%ZH#;l@lJcCxayp3d3cw+e@=!!!N*FMk;tG7v1`q~v8L(^ zqe5e#^o#dwW)J1ST|Jf_8Em}}SBmVAhAp~RHaJ-sIa`hDa(*0@8mXb5KIC%$OUjS5 z&vWjpf)jlbH%}S7%@3ER-6r~*Lur&Uh(v*4ijE-Zkq4u6Ie$dmr~-c@zq~w^T_U{Z zSG{u4U5Bn?C-j`*PxC9A%lrxRnbKUN1&w z6?7SR7IT2U)XiJb{>^;RvX%%5SH(EXlx`D}e`IaeWd95p{Up>x;(q~$!)X{zak&5^ z3GU;S%`nIIi&@Jb6=5NjL9_gu=ETYlt566m2sm?_nWc_>M2_LK2F^r=FG-hO`DK$p zAEwpl8QaE$9D!mSB@9+@E`?=H@G&7U`vP(F`IAUBEKv5EsocuN{QOH$$(qw{heR(= z_lbTW-zus>_A=Upwx%T8g#Z&0Xi1BU9P+N=&%bAoU4A*W_)&3rH*du}VZIb z1UKApKNn*>^IO>sk`#ZJ>!IdUwwN@L-!)&4l?1lVfck6})jAVI$J(UC$;J2i-?*TE z?2TO;VsDkA3^Kjk4SM&LlbKT)kP7CWEgYaT%~k1TwG}E$pu=JIbB8h`QbkM|3M3eB zAh^>%Z8QkfD=`5h;CBQ$;C0TsF>#4I;p>hMPFt0`^-=508he)7kT-~*G?}~ADy2dPDeh@7Ib(%Uy{?Dr9NUt z5e4Q=^h;5UE2H9%v`h{waw=@Efv5nBm2|b>IBBZFGGmiDOX-Zes?QD1s5l2sK_3mH zR;PZg-6p9XQ5DlIzIJ4&I|1Wy$==ACKd8>+rt;I8X}9`}g9`%5p!uRs!3eq>bZFdWa+QrZ|=ng?|^`ObW{814L>%A8A@saq7w_e>W(ql zs3-u{3xQpJ-EFC0$9KbhgTU}1(#~ot3g@_%>>}>8ty8=^O@3$SdEQFv$K96w+ReDt zMLEc;eC!`VdhEABoUhvRWI@bQQ@!^LvdI6qcOEHijRTYdefSw?t7lhQc>tQ$q4~u0 zhn>(Yjf+QGC+Y=_d@$G?nPOW^_eK=kZW5DwzNG%<`-ze3=pb)Vi3y#u9}7J%4BchV z&(zJ3)S47m-S@wtr8$kJsux4jM{>mG%^n>!yipteh=($aP+-cEUf@aBxGbOA2p!#R z88nHL`{Zu1WO#BPnY>G1k`!z|#|4CHegkPd<7QjCp9vZLq+Bf@ME{ql_#Ij=Th1~x zUK<|YPTDR#K^xwc9*Lu0+2){m!tT?RCuV>bp0!DE#zJvO(swr8 z!N2zdc}BP!*)EN)zncHH2b$W>IlJU_tPkSca?>B@LeP&nkBPXp(Q7!Wk-(MYeyp=r z5TJ^4D6-9rNv}=noq!sq{QFt2#uma3^K$gXs}*F(={{QR91XoxfL@6Iruum6J>{(s z`#Gkz&Dq?8T#P4Uvq*EH`;qbLzEyv@0O=#eFV*K6gG;^_^OPr{!@Dg`V?ufUe3F|( zodu*}v^zgidD+QGFtfpZBhEsJu~7*-$YTQ#*ue0lQTl%764Wxop7drWm^c*4Onub4 z_^5PtZ?TF)yCE2gnGxAh1I&QfJo~QPIEEp^>rrSqD~J##7zLyy$^iE1eo)@w9Z)T{ zGUFdLE>}l+O9-`>Ul|Je>?IwlC2lz>>vJ823-C(9&jy#gIuFmKnx_9u znNJutS+=k4;uv8akIz`9M^d@)5de`XtpMm{)9#wZ{4aFK5dp#3!oTiC<+ofLwqBGq z1<-AiDxS3aAa7;*7jnifLpwM+@yr-&TlIw*WYmqdmKi&vU1+YUe9Qlak1fW|Z6m++ zOKB})K<9m2RFnjJ=3x6z^!}|{voc*DNjlb@m2j4@U3th0N&obTqN$C-X}6EN((|Vm zJZ+nDpod*Hg7DP8Hh6fxB!`Ts)0sgR@0{I8KhqBX1Q5WYs}3!BGcV2Sr_NK*O_|G$ zt`%|MhPbxb6uQ5Ql!R27JiHhNP!+_Ap;Nxok2u%TR@ss#FH2;;GN>HUva+%Yt5id{ zfN0{6%)r3Xjx#8i{D$%%?fR*uBm}YkW$7YAOS2L2-jhe=KE4hP1=^6~S>U1u-2^Ii zRJj!S>5SoN2$n4)m)o^g@d)ApwOv!*OfWDWO6!UzwR{_0G1a-bO{SROkg`itzueDD ztoVUCd`=3>zoA@;$1F2Jkb6mcwKZpJh$UQ1^e-xXtkKdzm!M6Xfi^v}>SM8tw8#(d zZw;ef+&pa)_z1j73869IH7DDkyE%o=hroUonbHny@lN={+l5lUrzx9)nVWGaAx`RV*1K$&`rvdo>>p0dt-QaGEFPq ziK^B^3MNsU%-A|4in1+x>-grx(<>}a6+e>yNTyj`VPi_7g8HQ~XZn8IX4qBI;%i?2 zjx!0|Z|!Q(OyDka7`5-J!-M&?A!ke)SB+`U=at0bijc;d@zr1z!-tGZyEB>cnc`nC zu0^Fqpt#xokT)6Yr~uT-)y`hLWUF{L+|qMqsEBy*(n~N$Yu0+oD(DvrtTLZ?=Vq=B z+kq4oqi=P_goK^k&=Z`O*I?fl*^gPEU;HI_HVh0F?k^@QELCVh?NV}#C|)p9-}p>r zAn!Nz(i*R?W-dUsa)(ktb)AS9X_hp(Mow32}i1f?NHR!7Oz_nWgGlh{)?xtVp;;ja_1! zdTrw}`kDPD-d z7Uk-vTpeer`HgIZ^%KcAl{2M-*i76Bqi$!xSmv!uFm1Z>7L2d0phZ=GIy`R%&15SJ{YZ_hVO6o& zg&4b@f=-hXYQQ=UH1XGbM0t#n!I8u}pZ%JrwYf6w`DFQCSjTU2Ul%8~^63EN0KMrW zDTi)y6OqQ{D`)%gAel2Lb*J<_BYKtRxae*sL{FyKQdx@x=HbI}C*>p;<9=Llir@|D zzswu8-qWgIoPc$-07iPva9v`60!;Ty{dSB+h)~^OGv0ubveMC^mCy^Y zEI1@noSAZ~zqBOZANx>#+vKkRNYLjrclUJvvI*U^z&#SZdgpBGd$o?fuqWvpG%bv( zTD|wnURVa9`*AFBz?H9U_?-@#E-B3uSBaIiXk2ed3HCA^EDSEeGQVwlx5c;feJkez zp7L$3DVUR9@=&U+qL(|h@hyQEroXFxMIlTQ8>%Z+i5 zGaVCFd6pY)R6>55i;*gB;)-1NJ${OFjZEzGtc$NFZ@e|&Y+q~o6ZCLmnqqy1tt9h# zuXqT(%z|_@;n3jN|MLrZjE1pUvmJL~Be$9>-zKl$%y!Oa&5VgvToH<7<&I<5=8LGds zs(Zx-7I<@ij7rj*EW>`jYH3*Dp3{Eu_-Q8f6Q|2}tQc$1%ePkgxY>hCO6bob&H2mX zC7ZFtCeX+;LfB$bR8&+=b`sT^@C#Z#+i&()!9p*}sV*=VETx_6%<8MwCm3$hwdy^| zI9fHsW1rVt!tRjnmnF!S>5^u{cy}A97P{TG`O%XWY{@Kb5`bcy1%7^Zsyk^D>Uh9b zQl`OxJR$rG(e8Y8+7}G-Y`-vWEPpVkJsSh#1Ofv0S$Vd{>wd^jga}a=GRli8WXoRY z!k^ThurXo}OC;@b0GsZ0X1U)npYCse-}#Q-QOCd5HMc>@SJ&$#@PqF(qdTX}Ey;}I z?Kfkl1Mg@>iDiuM|H&q}6r9SEUIDUXFGkQ(Cl5066<<`Ib;1<;I28L-f#BM&PQJS| zy9_<#nAgB|4J<~55 zSD&t!y)9_6(Hck}MAl~+EoZ*aD$VSuxS7|ZQU|E*klA8^iD;-|Ul1h)g-yFq2We&; z!tgo)?ud7)GusWhJO|C^Q#m?me0@eN786xpI?&+LRS-m7ux`(`X~3)NZXBIBupVAI z6#h0JbY>UF?vBiW^L}2ok`~TuKX$lRW`y6i*$#&ImT6z`pIc^-cF>pr#iE2tnKMNw zedxH0Z<^fZ=uMuT-=DYB~o=MAH9AQrHBEr()AusgZATIb+S0>h9 zHQ{PK-b`FDG=iDRgiet+#^9e2VZx(ITp-V@2}j;+({lge^J@?DobV&y?5F|LOI*yixyU@21QAgpz(UA1S|}T##dc5 zr&{^Y^q>W{ln@5EI^y2z4QP!ue`Yf1yz@%K5@UyU@N4?TNOixnpPW1OJx@|n%)wde zto;1V(_wj<8-_q-*L8Lsdl&S`$=By6{zV%zs`%uX@?SDJYR<48WaPbn*9ZtkV`$Nx zCMzyS${GcwlWi#tzM;!pHCFax{6P)E8VC!(s4wkG2^hscjf^m;5vCQ=Qy&zj+{?ep z1)x_9Gl3yo7wiUs0ZzKlsqbYkGH9>#z;l=M1`LsZsE0~|(R^KGkgtR2iQKdzhRCjp zrO&gi9%{TMg@nIf5Wkd%9OoV%A9G}6RTrf78XUjBig-tD$)J~(Y@Yhpo0Z)$pGaSm zD;6*okb_nrF(ms#h_O4MU>%S}QmzR6hUz_A;Fd)spO1eBvrYV@h2T68+;?|(?RRM@ z1_mh!OM#9x62NmpqQ$Zu-K1eQ^*ivSVL`fgY#mt*c_cb+8RhyzPibZs*y+Q}%EHhS zk>xYXm~gi+#rV+#f&EI5-^va5A08PQu{Y`~?`4%F8TV_@rH{T0=3pp&+YuijQ(8)o{%C8(pjAXmnlOSWShkCXR0xG4s6 zhcQeZ?AoUG3`>^Bs~IMr53Wtu9Nh}#yNzcJ^N1(*%3KilANlmj7mlz0jq7EClL-c@ zlNczRVEdFz9|@u zV@t#{N^2j-#E6{)avcups%?{CQNW*>5A=u{Y}C3l=xn_h!B_5Y(>$#+U6Ehs_LZ>K z1*7AcLZ5eWuDUFOu%BRo6PR8NBVj;lZ)r+qOnAh;9kHp31FR?1@<{ zW)qV4mJuMI4CsXne|4(6F?SBeX&w*^q7KoShKB_ZU}oo$@VFdbzBDGvzQKVCM?Q~i zIv_Yl{2+hAL;2_CYkk~w4Mey9jpdaUvUVZ)2kpFF-F2bofrP20U8DFY>5&SvG75~A z5|CfNqH)tZGw+Q>=V?|Oywh_dD6>~bY^2nL&UbgRd$TV1lP(_*-659AK)m!?pRJ{r z9jUTfwR)ikz!nvHJwyH7-2PlvpN!yh3xKjfV#==|L9m<`AC{8L)tL=FZ-PA%wjIXr z3!-a{ZH)uj6@26P1j8_CVdr49W?hSZR#&QL%`(P8tp+!=!hrMb1R4O_IDb58SLnRG zy$^dQmvKIylmb9AFiPis8w@ZYC|)RlHGUJUh9r{(FsZru1|OgZqAt0ql@r^Km*;Qt zw99aRPI+x9?(tWK5+b^Vi`r0J)1O)n>X1F!-sASj6#t=5pJWst5D^(1*I@$vnDYJ) zP2U=o$f3dTKeh4x>G_Ev%=ImF)6>x`ztFdjl%RCsH|sFYToolxW>gD~yajgm!UJ*z z^pIrVR<^HnALOWQmghE}B}-&W*`y1-nr~Kki$pITz>Nn?3se@Em0et=IGcB`Nlm^U5pMcitz#spftKF?6YT>(dE10dy4@_*`-D$AY;(T zS`djbVT&7|?7TVOLlLb=um}YbRqi^U*Mj%!kK4i~K75GSJ3sLak5O}ovskf}Gnd_^ z7t}*08Xf^Vbe9txfWZ)T!Lj*)?^r6Gb*o<_@fRl%15R>cMX-&O?@zmO`0UfNX-2?~ zym%7f9Z`n_TM{F{*6OOS2;$EJFiQ@-|B4J+qsm%xZzQNk65n)CV>YKD&`JaXO5X?r z+FV~c##a_HLw%DzpELNhji}cXEXgGl`z$4sc8Be1Bq|=QRIh=_{4yR21h%Nn(|m{e zsS5C?adRTy*V0yWt!4F8I4BoWzE1akG}NH{ZHgf;9*LrToiPWnvo3SYEZEK%rZ%`$!gp#2J&FX~bZBfe*XtAv^13YfyhWOz0=sO)dG_()bng zSCo9uPDUO8eOUx--bYLo&hIqlSm=@=;aEuvEk&OlAYt|>N)S%+0TVE-#{!{b;>X4T z)rjwC$i^7dJ64`TJ*pz}mf)KzF^LB$wlCrA@+?ZrxP4g#tdCM0lOG>+A-XwFf7<@M z2|&VBqbN)#8ug1o0Th~WfADa>&>ZT zm0}T4z)=zL({W&NI%wp9-l7C;0Uqc5OGm$Vf;Ty1aBRPFfaIs|n(nI1hY}eP+{VKJ zv&@18@%AYPVK6%?0FyVU97biW<>e;##zZ@ZV|(cI#9fN9Xox{VO-)7-i`1kk*7(?A z_4#Vv5+9!7sz1#gx@?Tkr6_KjVXmOmm4`THQ%-g9si`Eu7F}=Sgy(aAVVcC#x4GV6 z&b7z{%pag9LS`g8?+SZP40chkH$f~i#J59EaG!r<1q?_V9PeTY4&U|FmEA;Qdx|pJ zB!6uKONkKsf=L(I4+bQ6rSFKj8T@*NdzS}z_jPTgu{_AWXnazJyZI33P;Vq>628 z;=@yS5_>`|!qm4xY;DAZif5XY9Y}&tgKSd{(IZWKg4igv3Jc~N_b}wAG(|ndp(Bk% zZ|t!Ge$dYd%uC~1ypko^(Us)oqL}n%4(NXPEH}X(&m{P!qT*G{?Zen;hv&DftNzgu zw!HpOo!Q2Fiwb}LlCMoK#_v_HJ|W$j!6GLVA>yb`8t#TXTxl4*6n0eA4 zJVUZ3Hy9O~SS`B+XZ)c7?>s()VIXhhE0Cz!w1Gp1_yTH5Z5jfRZ zfN2R`{|nE%ha!X>Q@b$ucL3w_bm+eAddXxU$W(qw|*WQdo*)8_ESwQ9hII zwT-8t{&2TW?Pc8yWiaP4E4u-#;6;5X!i8<-im(UrI;v$FU7V0Yp{*|!lN$y|-RDs-EU zbnI|j@@ekZWCz+>(a&0u>Ov;cVB}Thgl}mn z=CVJ_z7;w#UFN9l>d|lKNKv@pygwiaN$Sn#Zs$C=J&u>+9jnQd`NsF-Pv#)vi&Gug zmYxB<^&-fO`dZ6i5%cLVZjRO~zs$SxQ7C}bFHki7S6)^4>7 zqxH$pXHT2YOwCB%%{`2iGt2R45mYm#n7sAD11KxIB>%C-=ZG%R8{byJMQOZN1ha%(zvf)9+9vhM zf6Q(&Z~WDyCJk?-62<_&vK@^@B3+&;$3QZGhq#^xB^2P(@R5ggPQlM}{oh^S*r zii}FEeSB_r9B&eUDxJ9rI`3Qy@b;^d`>Ky**yyScFW$Ahvy@>>7q6n9`9HUKMc_R7 zdr`?qe?SPQ{7J2EJnFX)=gz}E+V)J>9I;OObfLsWggHa@M10-3K__KtZrzn$J>IT} z57&e2ZaCGwTa?1$9_0ldPMjkreC0;n>it#YEd5;yN9o#!W}Xk+7TkOenBK)i+T;6Z zA3d&l-5M>tzbJvB8U0o-HI0Hr*i^=Y>@0R~#t`9S0&6C$m_SoeQ)9qhp~Z)d>A;fa zwf?V*VHA6O6X&h)qc+R!Kv_u(V`|5DEAwXy!)`U>fo!foXus)J>ifN#`FK4jvfnL6>Ad(k*9(1A)sdcO;tuX?qpv*|My>exAMO638XqNl0tzzm1`l+K!!P~QHmL#9~ zB<%011nFcD%-gW4N0F&TJd+%QJnfF|&g-`96CEy3W>!DSU#YO4-AA9gCmbd;J#iu1 zSir^|mQ$%k%m-tu?RP`o^hy=m_c`oF(B1JEe@)rdkSTU6&sXa!F*d%fcFO(Kd#Q$D z^h-#Ry)!KE3Cqz{ej^^IbE_5~0DkWWipvPatg7Indz>29=JENZ>QPKZc5{B z!j(Prlc$*?NnO9qACoD1TtZBLNbe^_M2b8%53KwVLu7)yQ6gpo?_CC3|^ zhPNYGSOT^RXvuHpN56>rays3)sb3RgmdQn=6Gl4>NC&*Hjx=Jtr@E%Qk=Xm4?c~<_ zM=Nn-M6&P0z-ME;@hh$mVkj+}Or_r}aW3W7^-;Zds_M{JQNf$-@(i?yTp5qFyTlUL zJ;TtVP7=}pfX9i5isq*z4(}`7YNJ;+e@3kKNGIjxk&t2z^jQde=JLQx379R-4zJXN zD*ge;su6&9?YW8zfPQ6^`q zeng^^>Ry~u@|HyHd`WwG&a(lMgOBqS%B2Sv=buMyj%ZYMsQocDedLgRo226@b?ld1 z2PO!~&TL30wp;Vshqe&b$oYFIUYQ)kJ|u{5XHn8C`ms;RIP$+NB)_M2Z1W|;$>IWR z#@<@gKYlW<{XCn;>SF-m#Cj8P(TIrW`Z{+zF;&-I$Wgl^*?9F?%4j{bXBHRc2N3Bd7(Dk?PK!2Nz-WQ`+m>;}8sUeobK1hyB+_ zbfCDvbl2)6rl`&rkNx2?ao_Ur;+mS@ugw=Ret(U5&e@4qm?j{dBKSrp2UmB$pPk}l zZHQ{O2sV+<3iH+d8kL04`E5Imp{-OyPuofSw(lOozWSv)&LMn=ALen|BXBnQb?R-u zCC=y3Z(Jbx(KLZ;oKUo>oSyZohM`e>v9&3!7Zh+JlWJztw$Gu1@oz zOBZ6TvwxFc8ykc|?%3SiKYThA(xLCe?+f9$JilV(rMRab1>2jPV4~Mee-1lN67Dz^ zm{OcR8D$Y9ynZ^w*C!SjH)vy1@3mm`dc09?M%H$ET# z+n4QU=<0q;meeeMBi_5*vETdYodm4=t;>wa7%$kzB2jY20y8D<;N#IDD> z3s$!xMh1;EKr)>%ewmd|+#melfNpB(Rmf$s9Sgmov7Itk?_`FtX`HLo(n<3(DRR z(R6%FaIhLTtth4fPL5LJzBj+=Hxibb5uIZ)JfTEVU=A=xr0xmbF_?`3p&-ys z9a5Uz@r}^gWATgd@bEA`c2o7ONxigI%T&%J+JiV^GI`NA&wX+4$~VuKA~Dh`7Y z3Lcu%wJ)L!H`j zlwbPXJY}3q`Fm2%Ev#`k_wtdqtd+p$FnSdeV96d8cvhODlg)}bLdvSngEWUncCdBAHd;i9w2VFiJ=fshHraX3FDk?cPQQh;? zw3^VgHO%6}Hvt9y{&KJq2Mu4pn0u;UV}IA>=w%Q+*q%T+G0V?%<1IsICC258O}du% zojrf`)QNlTaN9jABloL@O~Z#80&8WLxhN@Z*M$Mm9W$T1Mrjy40x=ib(_sI6PdKv% zhr=|UTW)YNVKl(w2XDk;Oos3#*}kBK|3{rK1Luo; zC7JAFWUr}rGt)_|I-w&Sl;k#^eoJ1|`+;;|N3yZE!l~jy0en!F#SD-_qxSAMcB}UK zdLGr*vtx^v_A1{A5)Yo|wp%vq$Kfc5_-!cvt*f&O_YrMi)6W8CvNS~MN9 zgJ7`K3lza_ln;_yuMD-`X2ho0=;RHpp>YNRN3;7PrRjYA;sg`xBcT4t2K$$aVMaC*RTPSVbiWgiT^|d6!zI zCkxLfr%7wt$D}uC!%mo~Sb!bYbMd`1`X6pYF(blyycC|laPCxnI`r7;G8JB#T0U6& zxG>>KJjv~FEEfScdQo1qbwi6|aY%8Elpf@6MPY`rU>m6nq+(+81wSn~XPk<+~OPXW_Hg=hwn58Ro9gYdJ? z({!b?mK2d~-NPd}s}z8E@=R6PJak00d0~EQ)%59OWtXWI+*d2V=Dtu1KcG9%@Xpdq zY3g<}BB~qtS)>au8uGYlW7l|pr7!al$)$ySU(y3^rD=hqIH{$Ad%ts-sXVi!ml>+f z-$DHf?M|q^r;)^6%JGTkA38P0PMEiok!ddG_lnCU5`Hp~E4ggx7g)P%blx;_l~saI z_l`~Ydn(c#v@gaO2*Ff*E$5>r5n_k|64~*B1?I8+4Sy8fBrfbr;q9piy;(@ zG+|VZTwKf@G09HFS6pE^s|++I?%Ger+F{%3^uQBSGfNHg?qaEzaA{hTrbO4k^i zI=G?6bm5_!E5bxvrs%@fn<%qf5N+;n-uW{rFVc*@3zM&MQLCVL< zU(own^OjY|Mz>;_e97WuaaACIqMDsEr`Ab)UQFKXM@5jSB58vG<%iYhiVeA;r*WksE>Jo-{DL;gSuzs&|VFrl{|c2%JEiZk$4%(^TpVvddO#7OcwEs^rhR*~bE;n0eQ-k^6^ zDX7qigXl-1MgzhaNEAzrE1&o1SSdB7g9% z_tCYB^qKQw5<*r9Kmn_5`68;#Gow4919VTr_y(s5Wrty&xw$XdV6tSGSbt z6FDf+Ty{fpTsZAo36Ag|A&4=y8f7-zFt&v!Cx$iX~B(Nm^fsKvVYRfpB&> zxfJ0WqpVxhUF|01okZp#Bz`Whn8MN>L(`XRb#5*0!{80_U!O-+f+s9cfvs(Yy_=_x zbB>4=BQw|gBh|Zj@OvOA1OA`)b8YjZL5(&V-Ml%q64mkZ=b4QP>afH>kZlGU9-KuN zrAA($;n;h#`e?H)9rzU&VR{RznlM_TP%~oQB_A9Ge^Xyv=flI@2qonCFQEO>33h zK19mV-??w~9w^YkQwxOHHmEmmUd-Eef}G*I674(T8gI-*t9ajv(Rr>=pQ)F%Vy(eg zi!EroPp&CX+Cv+@cbffma5H~<*ni`sOYytzHJ!B~^XM?I=6nWAcQC zD?`P9@+O8`s}~nE_7kTf+5gm@bO)x zTU#)Gd5Z&&cVkO$iQ(b8DVj1)CYc-Gm9C|0q~=BPP{sMS*3lg$Di}~LiaD^W8Q#cv z+quHu0+L`f7;y2La$$XlJ1OtEZ2mIbM|Yel`8@HpKZ9#9@JqlI^FpO`QwmF9@)3Cu zTmDb zt6>jc5|Pkbd~SMP{Ok)`b1wsN<1iAab-YlZ#Q1@OdYXv35w|Bairyd1+ANs#5-=;9 ze>Xkl;r2f6Wzn1Q`zN?58FaC`OEs=A+N0P5vzLW0+MlWELO&=K*L>5%wi+ce&Rg zB_^MtmnI+v!&8K;?Msqx*SPdOG0+iFf`lqljO)DstEH~+_#+lstaoCvzc|o`!NSW^ zS4U^{$9Rxe=C#xI5Sa5G)4SrdD3Nl|TpH2CA~J zTP>kUV4*Ap|d+ork8+;XOf`{Um_!#LR359kOahhB7ENN3)9gTN_NWKW+n z&eO@)wxlJQ{hU=;5K2aMr_|ZsrHimxOd!4gmO|)eW_NyqfmDSY`L3YtF+@$Gq?ZrA zB72YFS6;yFM;bGNAdafB*z3%Qdg`Jaw1gw9UK4xp8ANN+6 z;hv@M!r>{Alpb!(5d|*Tt z($zyPL{Ilc^>M5fFc!2>wTo?ZCI(|7HuimHB~PFbJ;KGrRp~-@;hxa}WL1k7e}GB~ zc&yf!Cg@R=|9F3kugyg$3Xu>NE?{poB^;D$jcv*pB{n^B2Mb-P@GyDyaAfmmFV?;J zOc<@n!~xqemGD(9-W9POikI4^(b{puJsKYlei1Im+1hWWv#XD)+)OBG+}_^9CNP6T zI^$CiY0ZjfBFV??ROd*1@v zn#gyFMxzsOtsiXA$6w}cUQ9k@|75=|fioGAaD$N>)23Y-!Ys#kdtUi>O-FcpmbW%H z<#0xq7M>P4l)CB_UGw?}k%s*Ne2gOlTzbQrOQh>=o(a3)vCfj7{Ilc+dbz=n6oI&8 zme+h(A653$`BeeEnUU~WGAIpMw@}8u$a@5A)CK$=VQIF>qeS$#xy5X6aqn^xuiLW^ zw8l8998YiC=tA70bl+|7snJ?1$+bMO@EzDuu6&n2lV*xL6WZ4dN{z4A zSaLr7UZSgY+}pIuR`R{pHv<*R^~6?JBEe%uJMf2GThf-?`Jy#;UTKGo-s&$sTXoVJ zEYBsO;O^tZkHgvvM=whF^beYfX-M_b$*ovCGSUf47xsh;HnydbYHTVlgkul35JmgO zntT@6D)_*CQOx+qcfYaeGm%Ge_3>*D<8kAM_h8~BJ*q>0vmS2}5f2Td5lU#=87Vic1RHuoQSDl!iv8aY8r=x*Svgl;yw zn`y*syzJQD4-#Jnbc;;AYV~7GtmPgXslE@x3mAC!{Fq_yD13J@Tjiqk72V-IdQ;8w z4=XhL#Wpti3F|0ae()<&Gi0cDw{Q`SQJAl(AVsfF*A7AgG!;8MXKInP6@>&iY!@~3NA)|Nefj<| zJ6uhoEB$ds;u*yXQ(*mk@C{MQ@;jX+<>t(nEq7#1pIq)xX^wCfNy?g?dL++!KJO9; zP2CR4*4$G%S0212i5x@;V9Mic=QOaPQlKeN?3VJF@kCxc9gG|?H;^;>q;rX0Z}a-LlbI{S}b9VowWvUzAm!HAyJ z6G^bb1fR(WieaVcoH+hr{&_zm5v3TVkJi0I0c1p?z=XqPvIX~nG-a=jE}WMc+lZLJ z{Uz;v(PFk|YCkXpl$9V)9Mq^)3P1xrmlEOvn?ISxx1fms!O>MlMb$;oVd(DemXK5$ zhDHQLr9tVG5|QrimJ&$`5s*eex;q4uHn0UYq9);bD8(vz31$+&)(;eA`x(5 z2`GCPzxncOlKc6W?BKNwl7v?4uW3q=u;G;C96gi(oTc$4n{e2_rB{8QE37)W-P`N} zwQ)fzIA%0<7phk_I=wRcw`f{*QaEg8EQ~C#*j)nyhF2wZ zDQFGqNmH4tFMPzUv0J42RYJ>(@2H-bEqup+v8ti|UP z9(48<@WdhHUp4#6k0&xoC@8-sqQw0v6k}vi^3zil8;x!Y9vHwSzD6L4#?x zDtrv?70RTnG#@p@uYlkY8CJdZo~3)HP;BOB#geH)l|`il0i?%|L+H;lIYlVC6n7;8 z(kKL~p~0m%JZysTmwKx&3EF)khOtnb9&6XjGRT*6OjO8FVYD|UU;%~`PxCqI^@r%b zpnaPI3!Yixow90%h})7WPEbomcCUVjgZb}Hw(Mj2lf5&Eh2*$veq=&>wQ*?O z<;gOrpg^Kz+YUTL1n1>)myK^i0O1&=-5c|`rNj0&N==%8&D!apZ*|YP2HPa2WB*_x zDTX-i57yh3=hiwz@`qacO#x}Au!D*8k8y0f7Jx^m{q~%}Z&s2`Po87X{W5J|3)!jn zw;dpN=#MAfl*=qts*}ODS29u*KpM&iUgL%$r1#MluToY%ue9p&RXcDpGB7~>yFZ$g zPj{yGBofRtQaTjHfM=ISO9Y)v59sTX%E>kk;NDNi)0c=E;cMJ1ZKZ zJi0@u%6xhMY={8GsV9K{3}(o+<}!UKUG^sDpJ*1ojBjVkR+Wf0OmBTONo%>Eu7ao) zGkXvBMlgavhdP=J!Wj-5EeKdpK|HF0YRXCnVn9Z)1B|VgSEK53CJcu#J^~>We=%>x z;Pbl+apl8gE5@f>kTDBXA~tfKU%Dn)Eo;WcUz*?W^@t`OdKB`7<1m(9(gKDxczUS< znK>C@**+->+zZf}{4%DJw$GRt;jNmS7C+Xuln(|MvV`qlNYA0cp0tL=r8BUp?rjvc z15=i*5hUpxYD|XmNtQtarR(w;DFHuITUhIpC(FFp0kq`yGJrU#)R=hx_Gk7tq(=U0 zoIs16<^#_=ps|@^*rR(tPLuc=%FD&Z zD?R;N*y+jTG@p#&*#zHb@H3W|zry*V*sVQe?6-*~PdHy%Dl?-~_PPr+8v-izIV!D^ zQIli9=nx1t{~$2DxJvZ5yy4-!xa{oW6`MEgR`Q0YQOC35aaWmq0#Mri`#9u88HP7W zjKdM^f65qu@(XwiC${r6ADM2Qmqk$q5L+#~$jLIWZe)e`c?aa%$!e=-$=|DGAmYy9 zJ_A}P98#%Qz9BOaHhrd3inrAXmqWccqQO4sE$<2x;Mw0&*A}g+HgV%R%xEm4yI^&$piKdzo(7w-urnY-^duM^C(F`la^ zu3k=PpyzE?oNGB~HAJHBFSL-Bg?P}2KgBKI>yEZ}27KGVS%m+QA7vHP$%)U3ZPgTV zEr4H~js)@L%?)_5GpiJ`4!{4(UVD1~yx4!*5OBasoK98=*l^&Qu{F(pmRY(ET(dw3 z4mw0DA|qJT<1y}41Ncm{VF@~}#$%{Ku1E}3xD|D@5RY3yDP|^{yPT#9fWxq*#`ez1 zLj0!{igi0i4#@LrEBwJ3{4w+4$?-%3gti^ZXnkRL$`(> zU3z;pl5mQf92^yG28`CxEY}uk*&(0wi%%j%W-?HZE?ipqpqR*j0&EQ)vLj~Rg#cVe zxOyr3`+~}ZBvEw#pE|tG(XgG1dOAPIT;`3g#!bq)jxgw-6=NdxgiTFad2#&6Tgz#? z3`m}gmhNCo5vZ)=_WdgPx;3mJHtcml=%8DSiHR?sM$u^Aw1IL}6soDO+>pI$8g{&V zj;0iHMlc1LU!Hmf+w8;_6-!DydL*piWvyw4&cX=&!m{au%vNG-L*ZFmc} z!L^;Nt|qHK&wYt5ckcf!v^MmLW!LcokICaIqL$JEpCBCHaYY?AmrM53!xukw=;-Oy zV-#42h#*ycM$5Bg>FRBba?5I|hW_OL=K2irmDE+ce{)dHzu*1sL_;78=m9=q;V{eU zbX~*lSaXm44`eFWRF+l~pVXNHC#tb8;aOW_$DWnFPO+}Sgs0oHwnmKa``6t%OdlOjs3T^1-<2!?>@I>HUq!f1MH*ic zxOS_&C?xWYz3Pv)D`m<@-UFQ)?;+_N1CfPpR-5zSjv%Kw^8P#O+f^1C*SIO9 z73yO`)X@2;Ua_pkWw011MG6R3K6umavwQcA*WF10XXM3w^L>aXR6mrNR@Or99bg6jYJVsy(APU+*;z9WrEiSnY)=+MwexqN)uDT2gMGVMqO z`m}%c-)X}H6#T>07*HTNFCUp>AyG5fmyW0yVCBvv}{?dsDZ283*GecEpM)R(fYBT$}L$>+an}~ zpxb0Z*p`44=QK_8B@3*vhfrbf+=o7ED}W$SHg`-|iJ`>qjfBm4sk~Z-z7;98@`kmY z#qhd=OXKChU*xoOTPv+EzPe8clqmxy1wIj93+$;~_o2WkK-tMq*)O zC-W&n!hMmY(=PQQt!6*8YzYMWM^@fQRFSLz0mW9k)0Y-eD3Ic*%Bu<@=wlcM*&WlZ z@v~isjJ0XF`9pv=_HuU}>5ENG;+?`;-gy=Tl`>$c%Es&_x{F@81)tlp0-z-D^Vyz! z$qUXx2NN=jSnANFV1~SAbasSbWp@zR@hgP*^AIu!A`^NCiu7Ti$RWolA_G&5rj)!O zGIu&OD;lcSP+z4dWqlYheR5pugYNXsm9Y$d*_*0u9)7xO!=7UKsc0DGbhgJ5`?|js z=xg;$at%vNS`Jozsb_YrDLp4Zo`5?D|y zt*k05Dk>zr+f@G445I2;%@nB}eT_-7x@71lhn#vZQ{&TiBna*}bFIGXPue!yTc?$J zMh$&-Os#bLBG+HPHd4PiR=c;edGt%iS0&437jS7fWJ4qnfj%Sm=a5cS+Y!rz0!E#N z&FnvhJ?{goY1_yA*F+wXVChy{4o5~yFT8GVbELBVeJ@ar%p?bC8oUjxy1zamq>&J% z7I{`@0bkG|G~!pJuaWdgiEdjRy=yIJ@ckKelPwye6g$*b+vUig!>0}jPizgPMLJnP zdRdD>LDGf!aO{BSwP%Ddhw%-i3J&s7;h_gcCR)@e(vf2vZD+NHpb5I_S-Misx^=<4QdSX5rpqQNkZ0C6ny1%Vhr|STLcgB0VhJO1 zE1xoA6DVq8$cLfj^>N+te*T`?JP1sGmk8qC54e%F9aBJTGvJ_ z;%#ClFzgG-ry)vsnV9G@I>K?w@d*g4(_RTLSix&qjCW^ZfQA(_B=^b|52B~30(Zol zPZq-R)Uval%a|Z4k}+`7)0yo+A{8fe9I(X)uCKs&8_wi!A^zNfR+$S$A3(yJUPmOk zZ@2Ay1H%^FeOMNm-|?2JfMvJP;&sPxu-{J#)q{e#8&Hcz=j=ix3W@``I6Kcb! zmk2`75>2;DI{K9u!)sxIrmNg~2t57w%S6XNxxp3^t-9->o@;>G=3cFdgZrPz$vDuw&^svA8``rW*E@ecAwU^H! zQoqqtdM<6BMn^~I&F`(ObWXS*wdoDHf$J&d0a6P2z9ouP^%B9aF@v@f*-f|KNeG)Z z8W(xM2q`#CK&|aGkDm`80aPO6;^@Ul(g89gOI$R{QPPv7Mtqzz`F-Fh>#%_2J1;0` z{<5xK9QUo*NVvbJa<*50q=+3Q6Y>hmKuUFv9*>8{XdH?0GDgCcKKf+GBPz!CW0mpO zacN)(q{-IFye2<$y8K9d4-e|xR+!BeI2+YuE0I99PThQ!9Fu}g=vThAHqN|NaoF|{ z{7dK_8frx3jDE!7Ff6KO({PMFX6!a(y$(h(CF8|Lm+g;Y)=#LwznW)}Bezy(3BhX< z&X?Cg=r{d-mG2AvI4piI@N;)3tp-8P^l6#DMs?j^j#H{ixuL0n<;fs8M39JORzKyg zZ0)e^*Da-rMg$$%Mf(FV+Wm|CzByXi4%5WkaH;f2 zi%3#|*5p{TWSUP*ATkSI!ovIu~@(^WxcmUhI#fJ5@-X3=;n{GfmB8{K|0MLXl#5 z78e`afqpbO$$d^I5;g1baF=ZObRaAYmF?rIw>B<)1kl1L|0ij6ME+#J5%2QWJu3|O zHvu8>yx=!GiuJ@r>CQbw8ERtL5>&n~>5uBRkyh7QKm7JXTy|ieO}5^yRfffv>~{zE zt2@BF79A7Qj(&8ii43l0b;0|70T&xP$`?p5bX&38+BWoEmy=jfR4MTKs2fLx>o=Wb z!N7ssacgdTT$X}E3ws3d`4oT);BHy-d`#R6PshzRmpij7{IrGocvh+NTUhx0EHUoB zHdb&aziFXa(z-uTj?1jd9&9+pU&`@8JWEZwTrXe{7#sbgY}f1)J)XA>4s z9ugbId+32zeR41(me|6QcDh1+J&-PYP;S)Ke2A=4j5uapUGl4nkVGFbZnOc3JP;kY z?kLt@AR=2)rKLX*BUR-zzF3^aO=(;cfKI&wwFEX-Fk}zjmM_xbtFN-|=ircVYvz_? zDM7Ba4F6I=F9Y@s5S4mEMl&5u4-wTO6LuH#`ntL=JGqe<8j?ojZ}VKL9quwT6lH}g zBRje@pQ7jXWrdMwS14R~Cu|8l1)R@thhxyI95m+Iwp7>lkHQ)8!dk9=avLlKj zKOH3i`X~ax>Gz&^47{@~5zg$l@KIPkp^^=w&URKpTfo;pO;J#vfko%QP zr3gZ^rdyA3YUUDbD z-yWhlmvBQXvIKcqw=Y-}%7FH~9~OsK-%;il7Ne?=vfu9?EsEnr3GRI8)s@GSjA2q) z2HQ=)OWmJaYkT-~9mhKjC%vY-hg{ht-}2rfh5YMEynj~~`oDxTnAvKxVyl7U%a@It zcV9z76vP0Z0u(fUaxk>~cj?(YevP?a)?oI@|8pByC-+=H?6P1a$l^|`dkvZ+r{45S zx9uiC9*9G)d-aI*?3Vf7>X~X;#VC9*IN0m;+uh^T0Sg*Q@wnzuHIsKe;HZT>r{IFP z_w>cE+*{ufDL^!)L~)SQBn;`LH_zMkFdmqj9K&)m2L~R0W=JqQ3iJU?NVu5_-Hod~ zKUPX*RgANe?iZ$Ex-SQ&*6BTvqeP^d{n6<}1B;!pD=k2(0uoFl0&GI)v>F0QKpv9B zg^ckOe_KMGGLVq~3M}JFii+S_089vmRo319q!$mhDzqf?!=@emGP!kQ7l>4RgJu!9 zHKJLfHEH|w6Bns!rU46L?P2$S2uXlSdmb9C{6wlxIVlK-B+DTQcy1S3Ju(k^`s2y` zQ7U>=_i7aZh5*!r@#u~{cCDY;>c(qt{Pf;5{?4f@Q>Ek3#v;Gt;+5X+u}(_3-=Ue3 z(??IKU!`C^!bb`Yh^fgoSo#8?j;+_p{_({B-!+oY4P`JOY@p1{%+^8~X&D)vlIk>_ zona%~WH{guYf=3q@^?M=*~bfnm#e2;s*luETts{o@&5mAzW`i*{*Sm(k0|3mnF!s~ zz;p=h+N}p>SQEP`m_xHM930urq^P8Hd^t&To~`#qcr40$PS}AWr~KUbHKPTNR7~45 zu570!{bFw7`(j0EuWXS}Ijc>9=X$!j>qu)T(%kNz_f)O;42=`?IhL8N|DODcytcTW zbg`Eh4chW>KkXA;xH(nU++%+9spLrP@e^v?)4+P!V+*zIHBsVpDi!G07s|w07V@rV3(&kjQK}cnh?mq_KaD3KmJDAZF0vlW<+=K8=U{M*WsdxD|J+IjJ)K%u(&d(><*aXfgQtGW!=*` z=%$|!*`-*FiGFv5k}?A8Hrr_Cmu_Ktv8J?5qtAu(5?t+L(v`aM#hS8}LRdvLX@u57 z)LY7;wiN!Rzm_NA92lOrK>0CoLhF4$&an@BYL$(Q9fi~eynU2r_mre#^g1(taOYzE zJgk_|(yj3_9hPmA&`0Brd)v_^gjrA`SwAT%zWO#felYZP*80=}MfU=-EYtAtrH?bv z1y6YXdF-QPNzT%2-#nNp2m+$nxH22(g=ki&G4ogb=FnMG{0m86qR}rEU5+OF;h-LT z7BF&%GPZwFu8V>Lb;_Xm`dyU#)jaXm=J7@|`m#%E%GE2w*ySrHah^ATywVhdDdoIT z_*s2Pxw_Gq(z2SmA$9EjX!CVLbV5RRSu`~^T}!k4ZSgF~1=wHt__=cEQ@?a)h|(Xi~EiJi=}QV+K?RKK%1pc8ClWRz-Z2v$MVT3gXWCSCj#w zN(x=-Rw`hpQ>pi$?d;8`NLJ0~tfyFC-w(K)&P5r~ziIIE&wh5f;+C(=X_9Yfw2)iz zf9cqfq=9?tc|KcPK|uyAGwwYrC*PxbmI!_(F*WZ_iOIZoZ3*ICXr;%d<((ISQspk+ zNQq^Rz{jKuH04Jr12ld-#tLWQvba6B7t*s0%xkbiq>BUHw@>@f<7* zhpxp2Og7gsk|Px|kB%ZNb7wysccY(wo&AsuBbICpb1jOAotJ6QR0PXTQ+DfGpe&x# zY<`YO&PEtSvR|^bZ*M=^6sK#sAF`2fvLk!@kl*B@v=|}szwgJZ7U=IIE-N}AmNKMQ zydNbVZc1AEVFfuEM*oFR4Nz-I*J=iDMd!Wz@pV3{_f2)>3?K^l1;ir9#|gPVHr883 zTuT1GVq5?*#3OdYYATsLVe2Y@N@JIgvS#Zqpa44VZk&G1YSX+N$TgJ5_!RX%laPe- zX}kmVLkx8BtiPYFcHf`bze>gg6JX>X)_I+)uQFreuN4(L-I+?~j%Q_Qpvv?rIp@?% zO8sxr1UHJ2L7@)(zJ#d60P@X&#h$r|bNQz2CrESbacUE( zgzh2&gL7LWAXGw;*&%RM8_TI${fQE`3%JYjuQ>Y7uVJIF=QAoejr$uyLb^G7zU!hc zcWz~sk~{cYl-(GWbui-E;yk^oqQbZv3@jV^c`Y@MARJ6}#K#hU-MO#XGv-&v|+ZDL}Af%Y20!sP5i(hcYM z+mo1A$^lS=6hH`QOYYlzo-MpZ7YFEm#p(N2*}?z`KcNuBO_&u^}LRm*)6cP z@}M%KZ8p+!88|Olo3o=RUs3z{wnf*^PnydQzq{8o<66Azt^Qr^Qb{e~Qgox{WS5BJtqci9E8e6F^I<8JHD#&e1az=R}9%Emotq3LwvieYcP_I_MetdB8 zG8N-L&uq3xJi8|Za%Yq%h6GW_u$RA$hFHsWR=3DXnPJrdqNwso6$YL;`6dm^6nX1RuA^|@d zoXq~TS193s)DD>Kbvq%@$e_OZU;RnQ3h`EGy;iNd%xRT;tE45Rdgqm0(_9ZNvdr2k0tiQ7A3CgNB9$Qb?$s&Y|u2A4A54uRGo z0VIknwH@NiA&0%>w#l>mAOX5;VRx&GtydQn{sdLuvpBGw`E@BFlw)UqEhcT@c5sjeNk@1ud*wo6^2n)u;f&j5iM1pg zY{f4^ecdsc8yd*wr+0tqeV2LGXkRc{CGaAHR>@Gr2MWzEkY2LZ5VDOpy$q@fTGXZ z@zCP~)`f&$qbKD)hN-UFy zrwTbT1sv6t(RbSZn2!xi@(uD{>itP4*%)|Ry&I0m`pBa<9ois8D37X8*l=)VpsV}P zWPpT6LHwPC{9cPwZatUH82DAnUrA%1;?GRB8OL3aJj^i9S6504{A#TfsO(;i0~c8$ zv4E#kE*Hn+zDSh4WI0>b*fXtXv#Bt5G%=CEW=4fDut5Xi{xelAq%O)Ryd0Ha2t_dT z(CG(0?<>;@dD`+;U-ai8C+pdt5Uuw+#4{HQ9ED=$`&^6#+*51uOq?R#`nkp+j-PTu z^r-LCpx=iByq_`p=^K1b%RfU*1k0_r?)7k9R#Lm>z2-F6Za8evs6X7{D4baxi6~LZ zJ{ONMqLgL47B9$DJ`4pVD`G4QN%!xMC%H=Mk_~Z8)D_k#heQxUcs{)Sb!aF=^Blp! z|B835*Kr}_od@ex?-_z#^ds7m*R5_T{l8;xEcyX^jUUyt_dhEt;*k!Z#;EQJ($8l_ zjQqtI+oqNa;lB*wR*Wi?&G+N)Fkx4DZ@=kO(GRo7zF0GeqkFrfMwT0Oxk9sL)&HDj z4p&!usG~!c9yIs->oKIguSEP5{fnk~U&kV;4qmf#@xOk&%5GSL%{=wG@BlE_m#OqL zg+}u{oH!rjid8<0N~E@RbeLM3WI-TZ^3pHqj-{ggBmY`}q%jG@)q8np_ZL3lUAqSE?MYBre9xU`dQ|uq+PONPZ}c@cS$gZpgc-A3-F>`kMW4 zBi$ya_UR5SNaB2GmX;7`e)L|L0_1EAB8zymg@YmYC#@6@ZdJ^+-!vDHL zE6w5fp7+3-ehfg>vWr(Sf7eu|LyF9&NM)Z{bgRO^E0CD6u_=IeFXBt!w{*7iE6jUE zS4mA{>-WioeyXCZNeCvPQZBkk)W8P~M#glsdF)2E1NX8D{(jgVYdp-BhSJ9M&r-TQ zs|B06x)=Z%x{@I8LMWLS{0D~pKD?u_7?LMvyXVdpczv(TvV|Ng_rKu<_@f13e*_op z)}k&XL2ZED5U;wBw|14gWHAI+uifZ-HgoI;K*OVGA_zp`In25jK8N~}$b27NdLt_3 zc4A+oFI$0z0Q%r3$3wDlbPhM`yHW$T?i$f*n zc8f^i5?@9y?Y|_fCPr1@QHFFAJ+PEejHi|n!DW(OXRT8myG}8EeHhz#5z9x_ZA7% zWa(7}2J$~NtxuQ4-hC{7o4Em>%y=7sw!X#v?rIHl)e&^0z_;pcxDq;fsqmcdlO;St zOfa;5$;RHMJ9fhx+%k+ILdYi$pYbcC)0Ic>_|u7y(GvVh2WMm}dmWnAp-u0ndw_Le z41jwWD9Z$6v>O>M91VNcVLbCVUUQLqolP`sdbOR9PucM9qC4cryNUefFE0cGAB*0?So|P%!lh}SQGr#KBcY0)TI-oxtH;7 z@wmom%<;SGgqmm41^cKBd|B#d)h>&VeAj`SjA@@fb>r&aTJO=!O7%y{t1n*noEYA- zDevmDM|cG3=InwWf=>`=YCyDv{F%ApQS<|HY;AICw2+|d>T*39)04;7du}w0N zBJkFWVh)Lq%Qcrz3slp&4)1!W6pnvcUmFg*gMiJYg$eRbTl@h2Puqnh$nQxJP6oux z2Y~~kaF5!(Y(SgK&l=wQBRMvOCO$ zRO)*a*r>+A8;Gkfd*s4W#WT3&vna&bb-QJE9TS$)d$06H5}4QulaaNN!AA828?`tC z@|gPZof;!b2cJDJL^}FZW3W1fkl{hZl`VC&*^oh=O(a1{g4G`9Mn65EUjKM=Sg z#|G)&&2-V)rN9Q~iasN&Q|Fv6hslqQY3s#Z5g{jbtKwZnI2BedgMEsh;$}BUnl2p} zNCXO-@-Rh4f^%v#q<%Z|iPiYu)Mh&o0-usaIru~jIYrzTamC-a%lm8`Q@~-Of^iSM z3B#YMH0p2el;yL~^n!ah$zJ=8W=`7N0eVxHyZspwB!;_AvO8d_3fi?bhnBa5|`M;$& z?V@=jr9ZXH%6A(63fvW^3pUDctxk2WU%Hh>r#@+o1+`EYLJ_?z>Y*YYJWO!bgg>d{GH!{Xu`yg4PbwIK;`O|CxJ!_%cOy@1 zBIW_OLIXK)(g)H3pn8qZ7mB_&S~&zwNegK{%DZRi?#C7xP6x5LT=u5_wB`>$CWVDn z57!Y~37*YNw2fz2rJtrcB+5*3}?tZA%n_Lto3-PZXdP?4AOOCFb?n9@}a0W;3|M z+Kzkc3sFh*3^;_L=sg&aWp8AKDFb|A<471XckMLG=gp#1xnE2S@7#vFsgDu|h0ALq znD0RroArWdOq}dfq7D3QK6Uaiyis-gD4%Jbu{+TLE}0OZ5v05r`ibd#icsuNL6x}V ztatMCBwhFr9f!A32IWmhO==xSs-WTXkZ}6a3%%h*+v)6gJd+vf-wk?>WM2CmE8d>X z{{_@EDl+i5e|ALTQ-eoQ^N1MfN}*6|6t9hbvRJd@U2H=8Y2-uL_xtJdMqbIK-f4QV zU}Scy;@u=!gpcK^`N%uoOz+fKix)J}SCWKP2Oyqmvx4=EBka7t95$C+UmLv%dPd}{ zgR(ivjF{~u*;Bm&eBf^FUozBf4p zZ<=}fixJ#6k8PEX8bK0T7D<=mU-E;C&`Ev#{N2zHzNLrt=+i)41TSgcdb$jvM)I1) zK)ihnux+T|xqi3s4>Y`-Tluxf746_@b0T&^OiIiX9oCLY8)rX1_Ro`F4(sA$NrB-*6UA@qHzeCQaXA zXY9I?)AzI|^AUMmgzmAhio&vkVzfz& z^DZEE46o7OUzDa%!MTalDzYg!)_NTlBHk6p>ve;U(Xy91jaj)t@GZw6Yj>9{qAJHU zk5Ra|2m|+jNZ9evU}w)#2$tUEYrm4^BFx+<*Jt3Xt7OVo*OL0^UaH*zG8^{U^K*N@ z)xIY!cYO)Te{FWjS?_U})Ju{g*Ezxn(!6$v?DbM`;5hgN2nP_Nz!V_}M7IHl@1Og( zTA~5Gt~(e`w-F*L@bfKd1U+OonaTII@Ga0V|Bkwn%97-d^7FWS&v_+C2pc|*$9;NL zjfeR%9v0_klT#L`y|7LT_Heg!I|fokbWV)v!j{pTonMH3ezb+Z#0k{<@>_D$O}e#H~Z-yGY3r`#6RpeRbmLz z>hH_q%^h4lxWNRQP2hwjnunnpzZ6s{B(+_=kQU6 zsZz6=!Bx|}RQYYqoW|yll=O4gj~~i!kma5jAeCE})C)oO%bB^c!2HW=bDYTE(T}I- z>v&0NZntB^E1jBB-gxg^XNw4fbR-J-Ij<7!$k5+9YVQ{Flb*M>{4j}Q^XZv8Ipc~;W2HZ@CPoOZ&a6fzkbgF+jOd^GjcNV|GyVZ^{~xB96(z@ci)92&IE*2Bl6NFV<5j4# zN1w?Jqs#UbR}bXYVgHv*u&}!61w%sp#Z?d}gz1in~c71}W zd6>Wtofp;9O3#&@Do-bECay~5WEPxpO36TeI|FmZP%wmFKyPl9tgcJQFg$?D9k%G* zP4>p;_&PbvOk1}`jIQPVlJC%vMLbNY9QJsmW(D&3x?$oH)2Z+}kKl=B%ru2J(23{DTame_4wJ4ifiRf!)w(R7hPFjjMio4;;3MP#O0qa^n!&~ z3mGCi;#ZzUAn18rnxhZzTd}&>#C#~Zh8jIv;=Hn@ka`)5r!&}I%sDGpsVqXpI)$Uu zwT-IwZTzg7@dWN-qbFaMKOsH{#U)prtTd7EfZN z9{XAtNPikZo7u^{r*lFhrmHawv-SPF#bvFIVL?qSGCQ^V1ba&?NY%eRLowM$hSzjp zcjcEQKM@2xZ>U>8^vmLc{!8%64FaA$<$rV)`9&};j@wJ$uO#BOx{Z^}`ZmH+|M$N3 zpjQgJs~uIR-_5X&acK%-7&j_eL`pKw=zl;ST3Gm13bGNVJX zY#^(40{n?GNG&HYAb`!F9wf@XDSdp%#TMkLJJJj>jad2 zp0-#u9#``=qqN?9o!-GSTRu9<6}%j7y~QIFJ6__-4e;Sj1fvx(%+k93OBqrBz)M{= zW;L`kJ4QK~nUmFtQ{Nfrb>fii9&we|6SX2bN2h6f+Dw+5i;n-a-ty>Y{`mJYza!Xf zLIjCGk!E~{BB@A*reQETxi`+vD_su9ro}uF7T1gePnCh!v<`~lW1qRt+m^ReJN{C2 zqd*Qr&ytK-Lin}(x}5!hHuKj{44|8FLp!Q|_<|-CQ>xm(C&%BonG*|B4^)J%1~1>H zRD_GO%{l8NdsMtcUb=AVRX2>wuD413_Yw{7Lc#^wdZM!wHh-{#r$ABI6a{SmcJj*U zAvJ0Z91vJU2?IjnHNvJ>mCcWAT-nRV+9&*vMFM@tMKZzi9n6o|(C0vC_!TZ)%gLqF z?R0BH*mIN_HwJ1sc8IR=@ArYvxW5aaRC%S^bd_Y>TKu84Qex&Y$9L-Ev~3ToxoB7> z@V;DHiZ=MMkjGfn-qR}KP2%Q_kUI6WgiQn;jo6SwRQGxs#)WvL>b>&JVy+p9(ZYUid=T_E=5wiIu0;?U+Dm#FdBCG>xNjt-v@mgWcOgk zBnmbEffEx}XRSIWArCsi%v-%(b4kCfYwm4Ec&yGK>g{a#V(6BmQPHEumG0CFx~?09 zFMeL?g4F!!gB&AZb3;Ied!5nH-MgfM^x&*$s@s5PkUb8j@AWD$IpMm9*3vj;IFG(+ z>7?=uO!#igsgTQ<3Ih#NZdaZp?J}U zK7Xfo10$#qtHOq{V4$CKnH$B?)uBYpulrHC=iY;!c&gqPX!;Nw0nH~u-@}b8%3&pT zb54uvqrWqB7)9jw1S@6q59+P&9wFeu4!w=zkq?{5@2-sfxVT(0QRQtX{2z!oVxQ_9 z`Xr3Bk#Yks6~c9eu1>m`4UEV9x0<-M(ZN8I*wMS|1B#NAk6{AuFBgRAd#zfJ)Bf?H zp#g^jC1HO_2X_+-lR(fue&Pc*Q{4jfWjZu`P`>`YMM)|V^~9$?J+p`>M{BM zOPu)mlK7pKvAcxv6Fl0*W58SKi6kJJcPAWP`ZJ{Q?dT7y?f&N}?V7D2jlc5nQLf}s zGw^O#ubJb(OzNYe`(vToqER2OM|G{k#Pm0CeBe!}w;QCwvdyYvo>y-@I{YcQXzl2C zVrv*ro5uvMuj+N1iA?;4ASYeoev*9XZjVM6%yzaZJiG3P3AGvg;<;Qg7=l> z!kLQj8m-@%aIZ_4bdbSEEQnbsM7}*~vrx@!P<3UZtJ~m3cRa-YjX>;4 z^xg@MT$((>W7@_G5frq1<`sN&u)KTljyYN0!T@zG)**=H&Ck#Gw0s`T%L5KLhrBf$w6~rd<9^D-n zb)rzcv9e~QUHx~_^bA0Kf{UZQtnFT8E!?t!N}m(~kC`+Eti;#|B7XHu3D=Y(bad{E zT^%DQ)=hmL#A=3XaYl$pbQW^FkoK@3kK^j4WSL{KQ^io`OM5}Pb>6S3Je+)`6nyxl z_Bs@;ca643p$0r!1j(RpcaG!F4Obpy2#&**HM1VLl!_|bH3^cykUB`?hU-YW`FEEe z-nbG<$Hvc|H=Pvyc%Yo`_eB|oi@JA#xh#jMFsZrpQZoj1aHupqzu6@ThW|04mAlfC z5&ip*r;Kfxj_!n;^K^)f73Sx=6%@V{k|=zt;dpv|))cyT6$Fh#mDYp;BfIVJ%TFun z+GsMCnNN!SR1mw2C$#E8YXtv4w9P?buCiWJcQ6+fg}1-rscKcfVOLS42ho!*9#4sK zGl9M@Q-+%-FVKjmrkAFhEWA~%%L@yO0`^Z-&38ok}_^Y>GS=8_5)i%miQt*NHct?)%ePIM@ zikP*LwHEI$Zo*svacPxX&VI=~4`b0D1GdLff0x|vz$p5t6H5XewZ{flGhYGVft_ z0HTb~$>96(>sO1px;Pl1xb1{Pt7L0Z%Og)a&%fKtS3^sC&68l*npOndSLKE%hvTTW zyO;Y0hM^#oxP+PWLx3j$hs!*lSiy_4$tB|Y2|rgn`BfB=a2zf6Re6)JHVcke-i7B) z=qv9{U|5?Qk1P!5Mg!%lzs!r?;^$oO>zCv6R<*>(Nv>bm&Dt_7#*`7?Jx@$vL6<-D zz9`K(`}C(^dS8Q&TGxJZ)+7sh7$;KJ{({=bg7xuVI^kh@(q*;7!G8x~_6i5!>w;HQ z><)VV)AgyG>Af5A#FOagHhnLBBPHcHFXp|gxBOTm*4&sI`!wT;Aql>{vw;hckvJ`jx3`-ZOt=q!Z@n@^w zM+hn`iQpA$tg!SAb1Y0f$*UT((ldP%V>Zpdsr0Q*=-_BdoyH{%fNjqWJfeBeQwgeW z@3*lNSTLaCq=Ag(Jpzv7IVvoDbbCd`ZZG??ds8lGxQC>(E_TTsnn{N1qF{Hsoefhq zCOlvVysCI|YEl`mCG;-CQfW;cr7;v$_rPLqLt&Z80=#Nde@UYCWYQ#o{^Q>u;Z`{3 zQ0<%Bd&D8}oM{CgvLY6QY+KdjL^c$>2#77AHMXh{kFk%*FWt0VmQJ-1;pn$mYhCx| zw)_xQB2I!G17NzUCx@nt@XE=jR0Ra5=N*#;dc>{8FltUrzbubx%Vsd-@Y-$K?8n9m zR}#8QnAw9Ru8pDdbOlK(U)_vL4C(P`v`p5z6y#zNx*QcM!Qw4Fwc%6m& zdY&|9$_e8iq9EfqPlb1kA~}Qyq<~i}%`Z!Nzl1*?rk`Ct8>A+-70v9Tr`h7jKKCL6 zvB>(IrGmKscd6pG=f#Qa>-~bjAlO~9!TW>QGf^e;TBk?TJ}OPKLc z&Q84yT6=Q#O@!w+7aa>cj(AXy!klTXC!WZQ%zC6;pJ#cZ)s-5wZ`7n@^eB+NqPFG8 zDljKmg-UD3y{(PocItzBrKo4ALTxEk5M%=F*MA?l`2}!1X)}6A6fI1^tBd1tNMlNN zv!qngCBk79E21OMmusZ-%qCX`6I)T+mh>S0wO>hZyUSZ?$bXcn#13@G1HrGVP5y6B zIOjyTgp@)Us=Uu26QV7)SILkAG%wi_?<sx%{ZD z=WbY5q9#V-u~Ufyw?!m|7G+@5v&=u_w&mG{hO>dPDZB~JM72LDxW5s&%?n4b3Of2y z{)yJizpmxO1`ANs$Y;wNGc`Mtf_*M#e*H=Br>axiyWX{+Fln2;Pg>dU0@|JF$b#^v z^fFa`sxE7^dSZjgs1`1|+aZKd;~8p>bY9N5mz3t>T9W44txab;On!guB12|hE-FW? z?jGzNM;LiR>bz3bpi;ZQ@NyXfOuhW?dDGciSsQMD%{=1$r~=o5 zF8`HjuPa}_TB!FT{)e~_{;E0lf}AYTc_0aL~7xeG@N&A8?Dn#Ay{cUa60+ z4ASD7yl!m3G@Zwn%e+k(vCQ|*dt}!S^O?M6^!j6_wJjW_%6$KRU~<~&!wb(Z&^o)W z_O8A*ecZb?n0SBG!SXw9b!yr$_yTcy#-NRigByKI5kC|<)J2Xt=8V@QD>JFME^^3E zC7zz=zXejL@EPULoS>ZxUYezcK993KK0RVJ=o(rTkH!qPO-DXXfVD?b1bBa9xgRMd z78$H`!`#Y=8{VF?5LYj<uGVWzdxIHIf2y_aq}~KfP)E}^x<d&s{^O?_co^$TAJoo)LhGN9Yym_RkiK>)W$Fu&BleRNT z-FLL`I%^t}+MmYD2W%6WO0`?Hs57k5_8t+BWh7`p{Z=L&DSes8Xn&i|nCkaGK`}kY z>DM6PhtY}&;U7Os-ulK1$}r|!Fa#Gv?7sBSej#c<_iN@`1G5oa;WuL6m;pdjZpUbL z-}%z?pu$Xac3y!AyRj~B2{nC~l8EAs))MNjW$z|=Bh_n-jvo|CEwNk8<(9#7&Roq8 z&)DY~FIRkab?EcetxhqT7&eA7-PqbOtBmi;*XVbT*~g(u$v8Zjp(Cdq*deM9{sAVl z4Gavz1eIJD7eM+}yw!zcE;Q({%n>ACNW{K~@Jt1kMF`#klOZQObTyf#wRUq}PDyU3 zs*eNphSx+a=1opnUep3k{WO$NfQS&TZdt;Ow7B>0x4rUk!-i6^V{r3cd!*o1>c>`* zDqO?RWbC{_%>EETXMLkj0pCTBuL-H=PdQ)Q(-$A&kshc|8+r)Leg1`tl2br~%>v4X z1x_Q1#U`g|0|i#X(y^VxaJ6SI;(METN&Rg*#p@aRwT7lZAU^7BvBk*4@v;xaymVZ>@jGOYCFR2(BKk{7?%#u9WG#I(F#2 zKFJyO<)k}-zk5sJ#wlE%qOUv&E7P)WW-XqKzKXrfvKrYj=X)wvF* zjJ}G8jmK4YW`@t0otixo^`8pdO<`a`@d^qyZ*SsV7J9SnLWNYekAf6;^DFhgJB9d< z^FMMtdNe)Bk~MBIGKGux7j9`Ui+=Pk!*yMqk=zX4F6Q-`6QMpDF^1h@Qr*lcGyi1y zJ?0z_3WE9l_RrUkn>#wP<8gVdLEI8T3h>f8r=mL?B8kXxRCBe6U$r|v%3j*9*WMB2 z5$R|TMuSwuukIFlo5Zo2)==+Li_1NB6ulPFf8Jir`f%nXn-Ey5_KCjo0A;dU>h=1j zCZ_(}y8)A}VYKy#qnEdd$iSH2JqfYK!VVYuCe)d;eh&l^7m6IMiNEaeRv{?17)pR} zr8Zh%52sV5H8=en(0$?s9u#}i$Q6$j(ERKFY8w0u-~Sg3ErsA(RRv#Ji3MdsLWWZ# zv%hn!gx8*El1}4@vHBR#%ySmy;Zt0<5E}!qh+eA0;jl%I-}0 zy+k66kH>c2sq;}W$&JBIwMB%1MD;`X#(Vt3`S^D2WmrB+=X^#BMTkUgG(xujQB23G z@hJPP!2O46e0b_AgPK1IXN3D8;$bv3OxUMEt{N|qx2IYDkL2U}>(E(*X}3Fy0~a1o zwN=5lExnnwVXxk%J`h?GAjw~-sWFhETU9UD_2tEv@9O5Qo^N9*#$kAIEZaGeBEfLh z_*G4BYHzUXgkWCPr8mxOXW63>2p%JLxRnHAf|G3#M^6!vEJB*mHCtkBqMn9)jD|Jd zHzqh2H7zHWQiH?M!5^-laC)v8^6E(3RWgHhYxETUuyfTxXP@clUke4}kp3V^^#$QB z@0VZ%Ue4)Hph4y}Jwa73@_zUN9q_XH?u#f94c)eli&heyDQ^_D9B*xIuZvAqKa1>2V(V5Ha#q;N?uq7JV{_##QZNv=@L%#%VS;o`=>yd!}(9B!!7o48>kT!ASuu&KDVprHR^=|(7 zd~&s>?fBeIExKxaWW9@1aLbuSB=@Fnm@xBek{Uf12hJi^<%7k(ALJ@na;<{N{244`3WQpu^ILk!5tGIi*e}x z(g61Z_q}Qs9J=40bm?F>xu9)t<++%X|H*~W-cIg-4jpc4Y6|_I>)$Ol`?^=u)va-UjLG0 zA^uZIs{2LvhlL#(f=2Oc@<|kTe2no=_0yU|9DJ(ALlMPx?`L_NS6e}qad5A&*UBqT z((=+#+NV;bMd^9o{aXpXsRs~WIBm)La0w`e!<9ownY{eCqPpgu6!r~Lrfb50=Q$-P zaDV?}S?T1f6J2jmOXch@8?Ua3N22qtSOj&7VgjGa-S;YL60y9jv7ESx2AwA?Xr^t! zgQz?Crg^xu<$9Yz8z3kr1fR`8Od#)xz28Xv!gd#KEau_pKK4>t&vX1&(<)WCca8?J zZ2g^D%z?+rjLGF%KMl3KWt#Scgj^Aj35<)LGQ`N=UbCwp)e?p`s0g)Vscl|)MT-Y( zhv{2)9i%JQ+uPgCfVHReu>LS!zo>_GiBav-MREV*RdK25eg;2m*AKfAMyWzw>#Fna zqntanU5OVW1ntaxFUrLS4g|J*%=R&@*)6w{A;jwX<4b(iIc|-0qEIk28Xm?-o|~Go zRtgOVwfQ%+qK)z2S5%hcw5K>>%uVydwxwdIADzkL?b~tk>SPxvchWNXsX!Y2k_S;3@zhG7wE>(wkaIrTnCnr2DM#s=sYo5OrAntoAx0Vg zA?1!N#tY-?IvbnV|4<7Ez6T{P?kA(06+Pkc46xdzu`> zZG_~@nHCU^{&KgB1FlgA0O0fhdA*rP9VzV*4Yf-(Cn@t{RLNoGo3o-WbE3PStYiv> zdt{V->-VuPE6k1b=h1&qPyyz0ctU~mz|J0 z(&_Y)F3enD(a2mp{7^vg>D+pP+{0~QP)vRJ6+hau}^4F@~-~Y_xWhY^mZzr1nZ9JjatLXOMp& zhFlRiCgJZDgnZlzPnndp7FycM90Y-|H_|${t|x}^fbW?w?`ZxQlm>)6a076vJt`?a zKHiNmTC>wwV@A*b>DR}3xSX79qf+$Xem`xMZAt$4LBwtT{_S<-QCU^ZE6M_m4-V~t zM|JEVY5@xhM#0~|CrJ#7N9zYaM0!#!;3BIoqBG>Ezqz$F6DU(i=qEb@XGQHM?91OF z4Yk{Qa=(pg-pnkB(pypVpt?6}vJFSg`eikBS?0VXUu4;mLQN&Xx?`zJ%|*m*n*-SX zt+*GdNJR1e8$$AaNZ*2jvtY314<05BRMI7B%*hSDt>^jeyZ#rXK)D|J0tG*Nivb=|$$pN;-&Sc~~v0QLNb1T!JY)hBlB zLU-Ty(MUIjB^fzAc8iJH1)oKI49Fco!I0kMdr5otKkKYv;3YM!;sLfGg{O1f$slta zYv!{xod)wK?wC)_aaim{zM3Bs@k;F!K#=hoekv;^D=)CCI9SH^K5ad;kn!4|(# z5=Wm9qd2ns3f~P&oEAl9VI~AcFvG@38}hw;l-L;l?E1*1=^n1@(X5@vtEw?H4Nev7 zAoN~Q&jM27E-!1(zpz%UJx!V8Tq6c#l*?x&R9wzQ1YBbNV zioe+t<+-IieV&VE-|Di=yi)Lqx~)aKwtZTvwoi@1aJvN2wmzeY&xU|e?S5`%W`>e> zIm~C`myR^`Y1y#18(rgF<3)>nUdWe1nTZ=qNAt|k`T~#+-?Oq6ZFt?V!=4~>G48*@ ziL;61e@fQ~Y_;=Pt?lza$go?Mcg> zQdNtM5brfW1wPh$tm}`4+J9T?i8^MVq!%t9dbu``FDL2#hUZ3iZIOHZyB4|qg;uhO z{l#r0AZXGn;yMovsH0J3?>EJ2P|$blQac7k#DL9J{PpyW!z57K*o9I$%-x_)5N|Ue}q)+C*{`-~Q!eH*@C6JburT|c}cX4r1`kwoAbgw7N zN^ee1S=Y@nZI#JB^8?M{|T|(QILkN ztAkH1@jDPrRtjqJvx*^4TN<*wC{N(Rg~zMyT7bUn7fhYd-?wrawwHbTg(X(?52%lp!1~kFZDSe-F6t76eniWfQrID;-%6ih;BG^|1yh87 z6%`j~D}NhP$|v5OQeAQv!U-`dyX-%i)wy=83MW0Okh?!P$&qQ3qY8OPuPLmVx;<6{ z3uD7CQq*XgXdTKzy=;zG9P)O&G1eM)>L&D)fFA(gpR3?Qc|Mz!ne5>P8meZwx6#uI zKb6Du={e`gUA)NFg_h!i&}t;T#aVsrPGDn`5M{Y}?8&<38^ z+3jQ4D%uU|{|(nZ@tc-Qg`=n6V}s2&ht@=i?i!xVYCK+JiTaGez3oRZD_eil^El+_ zhpT^9h2Sm>_LK$^#qOL8X0(%wdIwoPiY4})yKyL1m;VTp&+D4QDNKe-0pH!!d!^DA z*LI%-6&GuLe&HW=Cw>NXT(eR7%BF!rL<;3sFPv{4YiiP5=>t8l_;}3o z-Sre2-Rlp|KlK?Pd1pI@U1100+*Noso@}#II2W+sATeodQKF9@$ryh(sUZB{N&y_N z5k-GTLPMDk|Y z$-5?=d`!yhkl!ltuzS8%bK^H>S@rY}uX`piI|2cG?&55s;_`XcMJeLsqyuB-1k{xjG94R1vQm?yj`7k?q*M*&YUp6wM`IvN$6n;|npx z^=IOR_0gQX+HDB2s=Z(<6*zpK7XFsjwydk48b!u?{(hXVqFx*OoKu|MvE8?ms;DWv zf4CB0LDFit`#r&zg8Nq`1ohYdd7~I|mj-xZjbrw6M282ibXQCd=U(JTRvsSPxwv~z ze(b%6tEu`uPkAd0Q0Ev|e7}KQDo%RX$ZUm5dCm4TW#`2K8W=ns-=w2<%j+f=wSv&w zSUArxt$5}?#Ws@+biX1isxw7c75r!K#>NIeX2th#wVVC?xP#Xl6{cG?_W&ttyQ~aM z@4wAeZ+E5TgUW?d*jMThIEMQV#0;a?zo9i>!c+tluQ>cUO-&j#l$I;J!9T>8oyqKtyr)TD4p$56aC-rnnz}G|aCD zp`G~$YuDD&_GL6>W+%13B!?-6uD3#r?+OSZ7cJfyF7M;8VnPraMXE*-Cp}TswVIYl zRNU2c-`u-pmOeg0Vd!1*nA2D-l>k|a4~S?tFQY_EQchyT`(xemFjIs4?@}3sR_-0% z6GS_Rnvz1K#3d#=1|Pt#NO&k`=|-9k{c~AAiQ8LnR_7|YWPa6&5;L|w7UbaY1Eml7 zkA%F2c(to<=DAdovZ_ol1*!Olfa&)K=UIq53U2n)%Xv_F4@{shvuuf>rjEkb|L0O} zAB9;P!Eh=vuJ=mLgYIu~5d7)IK8W8+P(<`0u$is+Rw;MwTn8pBKr*08o=}ZHcXk?# zu9qNU%gp?ed_wU=gAWy}aN)v*D9srQjJDXdsEM*Bv={FYh7Xg>_=5*z7I?h5B!Ht& zRW;OaFQ?qK6jf?JKCfrneU__T|ooALX&12G#4FP6cY-By-y zDaTkMLz|oL2VtL^CnCPNTDSgJ&f)mkK%U8a!(Tm^8!~v@@;H$y?c|IB946p0vkz8g#tcbs|D^A=t_KKHv z7dA9k3#*;-Hd@fnf|9+DL z4yfVMhm919vXBq?Z{0}66T2B9#xDi?i_|{6`uRFsOLB#UZG^8xIY_wPtkq>yy9$FX z#--Q@mrUxBU_}o0w}=n7ehl%mMR^DHN)NI0U3t~%$pUqO z^U7!6Us)*hZqL@gtx|ZCtSC;(7UN@`B7UA!AhZwVp+i@IlxanD{giWdgj=Id@Jg_F zCnmY}TgZQeiu`x!CH(ySjZisxv@+iC(~nb?JPLwGHMeuT>7|>;DSFW8a5%Q7Fy#hU zeoLg*KE*Mc{@GLQF~7QsK<|F<7%49(5)10tJ5fZlR>5HI{VrlcZpyg=KPt4#<^B+1 zwn21H_){yxjX8VseXHv+=S%LHUuJ258Xn!WAri~~GwlSY%K3k${h-7j>ewOe2l-9d zHLN~w3$PPbg^&4r0f&;e;sDGd&8i+(frP>sH>fTEgM4D_9)4M;o}_-e{mCmbX;NVz z-$En*>7#}3@#mbqdVPeF zI(56z#)b=!h*(uI_FQ6u?8IzAnR!4DqZ*H{lb6j_r-tL_2Y0|{XXqv5)6HgUDymCY zU%zg-S=wiHKe&#`CD*$hu*F1oHYVd|^D8#{bj5bN3!a2ddO?O8QR7LHYivEe8a#M+ z#mf9YwV`~5kfiU5dz+1trA2{D*OKdQsbfRsGyKY2TG%oms*34j((dg!P~GkpViY}_ zRhp_LRBOGlyxxKI$M;;Mu#@WM6@Frn>bsAiU~sNyO_ovQtL{cQ5QYe`e?nYe?Y22@ zA}%+h_-jO_Q)1BQ!7*e%1IAfU3T9f*OKAAli$Y3zakff9&0#2dsGkimq>^vuELIus)c}XAdL8w=;l~F zo!xiRb#dS&fM{j%xF5C(DtC4Kf`ZiC+d0nyX5F(qS@K(AN%@G=x&o>nvUFT|)HaL6 zBgiW7n7yc}5%}*a2T$uCMMQRpZD|Mh0nzReIJ6N56BZTqR$|NYs?AKeWQ6$m8kR?@ z&Yn9ri3SvuQoY*3kDhcNt%4HgXg_|lKd?n2ZS`;#CS8~dBdRH-!^DnUbz?p0mI#O++OHIsk_n0SDMG|$zsYqYgw zz9`GgQ*cJDiBr9;?n3C3R#?6cxG{I+9V$NEx#O_~{9cUg)rjuZN9~Iiv-1JXMrJjb zQ4barxC6Rb8qkB#SskznQ+YyM9K?-0 z?mP{T`z$bX=f_mnIra~D`KVttmE{If8|4hhfm<%!Y||^`q>Cchi?&sa@yO0UAGW zo!$3k^Py~4SF>2yx$E@w=|&k?&1WJK86+(Y-+i?|?1zo zF!^_f*kC#}fhbV4xOQ-hXB(!>+Wdo5JODWTl<6K?Z%MzYyj2_4({tmV$9#HRaxzgE zOIg*gB{xfR5Rv3ur?RTsh9iD6r*e{IBaKju)sEdG8vmxPUNj7H{&X^&( z<)kv?z9@Rf_a5zPbT%0TjQGEC-*FbKkl@{}WA-?9*4<4?Qj&5t566Fl%kLy6qvai` z1^ux}xX>Q38$AJ9@}W{{C7C%dvArlheCb(IrS~fFxy?n_JapdK=HfzsBorD{$&^R` zOuK42=C0~o<+3SMm(fc*K3ca0PEw|(PlbNBXHo5qis4}kJKb0`Y%-Kbt8uOK@xk!; z(UXU)p6h+xHt8~kz4lkVWvFupSwyGzhz`TP(OZ(O!dNe;_8T}?E|m_C;+)FRwZ#Ey z7A28&j$<;oT^%u>Dh&FV{rRiG6CvGaq)S#7qZB{E$BC6x1{Z=@XlOxZ4nQd&}FH zo%1ahq7b#iAXjkKZZq0W`mT*+p_We8t#4X~P5ndoA#nbd4~>T8GofYQMR*b@a+I?;oJ3nFDyhH_@?y)e_fA$hCFSQbt~Vh zmBVqUn3bNC#3d!w5N)JA2fL&tCI8G3aPi>>W;bKc+$K?JU! z@FShxT3s>>dk>R)Rt2m#&7wlv1J8GI>Zt%l{#1{8 z>WTpz!>Y3)*cg)R)t|<$E(ON~^-r}v4z0#rX&SXuu&73yDKI*(Tl<^^ZF23BuFRE` zbX6WSJ#Rl`bnj(micjSeLJg_b+0k)v!lPz4(?9%zfq%j^jIwV;2K&)fG&dNO@Z>^4 zlQWR+9xLW#nA$wU@nG^~RrM8bWg8n-h|a6q`v|C&UIYE}^fqVdUFVujKd833ax(O6 zKP8)p-khq%ACuY}svr>LIiq zzR^QB_(#1YW%o5bY3x>KED5>dT_;lYvzq#83s*zH29ouW>dU1&o55R!cSd-x0MdWi z-=onP#k;18=Ju!-^#P7Usp=JVdO3{~O<6fd_vF;2vN0cxoW75v8uh&n<`cCv)C4CH zPg{YwF#ErV;)^Ofpyz@ffu|ThlN455^{tZ@06*!@j<_^jW(T=&|FCl%)ew#%J)v(> zVbTpWz2u!;M%_Os4{be3)Ku8wzr!v0jrTZ%`Gd3zZMAFSlNO@1GueF$YeI~k#Ko-^ zC~ua)+jv5cNZictGseWyNLx;)7Q{QpiopLF^myo@cE4C@1EpRnH%x8((n!FSF}!Xt z8l8UL@%~ZLtu5A_Y#hEET20-KaxOF~i8cb8T2LME;$K;3r9X4u$(vNkXN}7^eL7uf z^%++_^A*bg%p+qTy>%_m&>n|xo)4dQ1ohf4oR58_fPvhroU+z=Rz+oL48jLiPEoPa z3M_+@?bWy9H`}+!kOiZMtzo1Me@0jJqZmTv?udQ=554M_y z6yo*3FecVi_#MB-0 z3AShjLdB8&6Cztjdd=!|G2$#I)LG~`|0W(c8F5)CUJ;N>f>RxpNGcg#3Il&p&8!A{ z<=%8{xHAmpJX5J|L+}13(c7xF#q6gdeh;LxG7n*YCmO|s0B|$_ZnJt#--vmg*TRDF zobk1~Z-e@cV)Rn4-x<{y2fyYqvoZfWkCrODoytG7uB+$gK2^TC?EG_%ZKu*id|Q7&E}!J=gm0~ zGM69xOBYvOocB3owd)^l$ATgxz=nCritA7)L>{mQ%R_4Yo!q-eb5sqyd-_2^Y1VuH zed=7fv@*ThUGYTXYxUYy<(2w9W8_g%t=m#lQxiW7HTg&d9GHmIRSy7T*Bc{ALkuR& zrV(U+q|9x78f;E_@@uvDaWU>1&sL|G?PSE-?-8Wy6kmaON zPug)69Z! zn}$8^ih9O&;o0`hG*Kcwp1U+3`WMf=H+s-joBemuvz5zAv$L~f{Y$R6jyI=t6D6az zjx#kBPbxqx_acMWj^h+=6Lq395^hpL=PV3x#< zHsk~bU0l2N)tPRYRj#L#A@y!qoopR*-B~Kbc0U_|;(%-h1*liGFA3J)cVrNWSoFp%;(Y>M$AwLPXV4U{tZ>WQcdU)T9=RT;l{(x?a1p?D;yw zs~?JR@cpblz;gfZ2kTZdgN!*iOg2??_3YwcQCaPRVcyNc07Sm><$CDhh9K8=NF#1z zoX@G6Nl4uA497xvbH8Of!l()6D z{pvk^3bO^;4(o1}U#oO(dqY;(>5@2B2Np$`42qhe(Kll4)hc8C2J?Uz7+i&q?pu|1 zqZ+eTXs5n`uOiN2IPcL=Xly53mP z0HFDN^8hX-262n4y(@*_{WRL0mBu8D4ZLQA&({uw(nR*XCTK&biJ1TyVn0s z{*`3V(^tXs=H@QJhJW^p;Cpd#$-96YIo(h#OJrj)dh5U7VAt$c|@{oS=Pq*6j z(x9Lq9Vig05)`f}S$dX3a`2k46N{zojM2O{2Cw3qe-B*3>MQCWQrWGS%DHxAK&Y^e7XyS3}L_iZ+e^st;y>7=sd4!PniB{WvI@-e%vb&xwcC1 xAyqkD7oS@V?(Nd}F5^itb}hv@7Ywb^_PTshi)jC~au5N3+FI8%zp9)2{vXHA5cU87 diff --git a/mmcpack-template/instance.cfg b/mmcpack-template/instance.cfg deleted file mode 100644 index 5dd423dfd..000000000 --- a/mmcpack-template/instance.cfg +++ /dev/null @@ -1,17 +0,0 @@ -IgnoreJavaCompatibility=true -InstanceType=OneSix -JavaPath=Replace this with your java path -LogPrePostOutput=true -MCLaunchMethod=LauncherPart -ManagedPack=false -ManagedPackID= -ManagedPackName= -ManagedPackType= -ManagedPackVersionID= -ManagedPackVersionName= -iconKey=cleanroom -lastLaunchTime=0 -lastTimePlayed=0 -name=Cleanroom -notes= -totalTimePlayed=0 diff --git a/mmcpack-template/mmc-pack.json b/mmcpack-template/mmc-pack.json deleted file mode 100644 index e0826d759..000000000 --- a/mmcpack-template/mmc-pack.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "components": [ - { - "cachedName": "LWJGL 3", - "cachedVersion": "3.3.1", - "cachedVolatile": true, - "dependencyOnly": true, - "uid": "org.lwjgl3", - "version": "3.3.1" - }, - { - "cachedName": "Minecraft", - "cachedRequires": [ - { - "suggests": "3.3.1", - "uid": "org.lwjgl3" - } - ], - "cachedVersion": "1.12.2", - "important": true, - "uid": "net.minecraft", - "version": "1.12.2" - }, - { - "cachedName": "Cleanroom", - "cachedRequires": [ - { - "equals": "1.12.2", - "uid": "net.minecraft" - } - ], - "cachedVersion": "0.0.0.0", - "uid": "net.minecraftforge", - "version": "0.0.0.0" - } - ], - "formatVersion": 1 -} diff --git a/mmcpack-template/patches/net.minecraftforge.json b/mmcpack-template/patches/net.minecraftforge.json deleted file mode 100644 index 2ab0ae634..000000000 --- a/mmcpack-template/patches/net.minecraftforge.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "+tweakers": ["net.minecraftforge.fml.common.launcher.FMLTweaker"], - "+jvmArgs": ["-Dfile.encoding=UTF-8"], - "formatVersion": 1, - "libraries": [], - "mainClass": "com.cleanroommc.bouncepad.Bouncepad", - "name": "Cleanroom", - "releaseTime": "2021-12-13T04:40:03+00:00", - "requires": [ - { - "equals": "1.12.2", - "uid": "net.minecraft" - } - ], - "uid": "net.minecraftforge", - "version": "0" -} diff --git a/mmcpack-template/patches/org.lwjgl3.json b/mmcpack-template/patches/org.lwjgl3.json deleted file mode 100644 index 50326adcf..000000000 --- a/mmcpack-template/patches/org.lwjgl3.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "formatVersion": 1, - "libraries": [], - "name": "LWJGL 3", - "releaseTime": "2017-04-05T13:58:01+00:00", - "type": "release", - "uid": "org.lwjgl3", - "version": "0", - "volatile": true -} diff --git a/src/main/java/com/cleanroommc/boot/Main.java b/module/cleanroom/src/main/java/com/cleanroommc/boot/Main.java similarity index 100% rename from src/main/java/com/cleanroommc/boot/Main.java rename to module/cleanroom/src/main/java/com/cleanroommc/boot/Main.java diff --git a/src/main/java/com/cleanroommc/boot/MainClient.java b/module/cleanroom/src/main/java/com/cleanroommc/boot/MainClient.java similarity index 100% rename from src/main/java/com/cleanroommc/boot/MainClient.java rename to module/cleanroom/src/main/java/com/cleanroommc/boot/MainClient.java diff --git a/src/main/java/com/cleanroommc/boot/MainServer.java b/module/cleanroom/src/main/java/com/cleanroommc/boot/MainServer.java similarity index 100% rename from src/main/java/com/cleanroommc/boot/MainServer.java rename to module/cleanroom/src/main/java/com/cleanroommc/boot/MainServer.java diff --git a/src/main/java/com/cleanroommc/client/ICU4JInstances.java b/module/cleanroom/src/main/java/com/cleanroommc/client/ICU4JInstances.java similarity index 100% rename from src/main/java/com/cleanroommc/client/ICU4JInstances.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/ICU4JInstances.java diff --git a/src/main/java/com/cleanroommc/client/IMEHandler.java b/module/cleanroom/src/main/java/com/cleanroommc/client/IMEHandler.java similarity index 100% rename from src/main/java/com/cleanroommc/client/IMEHandler.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/IMEHandler.java diff --git a/src/main/java/com/cleanroommc/client/LoadingTracker.java b/module/cleanroom/src/main/java/com/cleanroommc/client/LoadingTracker.java similarity index 100% rename from src/main/java/com/cleanroommc/client/LoadingTracker.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/LoadingTracker.java diff --git a/src/main/java/com/cleanroommc/client/ime/DummyIMEHandler.java b/module/cleanroom/src/main/java/com/cleanroommc/client/ime/DummyIMEHandler.java similarity index 100% rename from src/main/java/com/cleanroommc/client/ime/DummyIMEHandler.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/ime/DummyIMEHandler.java diff --git a/src/main/java/com/cleanroommc/client/ime/WaylandIMEhandler.java b/module/cleanroom/src/main/java/com/cleanroommc/client/ime/WaylandIMEhandler.java similarity index 100% rename from src/main/java/com/cleanroommc/client/ime/WaylandIMEhandler.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/ime/WaylandIMEhandler.java diff --git a/src/main/java/com/cleanroommc/client/ime/WindowsIMEHandler.java b/module/cleanroom/src/main/java/com/cleanroommc/client/ime/WindowsIMEHandler.java similarity index 100% rename from src/main/java/com/cleanroommc/client/ime/WindowsIMEHandler.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/ime/WindowsIMEHandler.java diff --git a/src/main/java/com/cleanroommc/client/ime/X11IMEHandler.java b/module/cleanroom/src/main/java/com/cleanroommc/client/ime/X11IMEHandler.java similarity index 100% rename from src/main/java/com/cleanroommc/client/ime/X11IMEHandler.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/ime/X11IMEHandler.java diff --git a/src/main/java/com/cleanroommc/client/windows/DwmApi.java b/module/cleanroom/src/main/java/com/cleanroommc/client/windows/DwmApi.java similarity index 100% rename from src/main/java/com/cleanroommc/client/windows/DwmApi.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/windows/DwmApi.java diff --git a/src/main/java/com/cleanroommc/client/windows/NtDll.java b/module/cleanroom/src/main/java/com/cleanroommc/client/windows/NtDll.java similarity index 100% rename from src/main/java/com/cleanroommc/client/windows/NtDll.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/windows/NtDll.java diff --git a/src/main/java/com/cleanroommc/client/windows/TaskbarApi.java b/module/cleanroom/src/main/java/com/cleanroommc/client/windows/TaskbarApi.java similarity index 100% rename from src/main/java/com/cleanroommc/client/windows/TaskbarApi.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/windows/TaskbarApi.java diff --git a/src/main/java/com/cleanroommc/client/windows/WindowsProperties.java b/module/cleanroom/src/main/java/com/cleanroommc/client/windows/WindowsProperties.java similarity index 100% rename from src/main/java/com/cleanroommc/client/windows/WindowsProperties.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/windows/WindowsProperties.java diff --git a/src/main/java/com/cleanroommc/client/windows/WindowsTheme.java b/module/cleanroom/src/main/java/com/cleanroommc/client/windows/WindowsTheme.java similarity index 100% rename from src/main/java/com/cleanroommc/client/windows/WindowsTheme.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/windows/WindowsTheme.java diff --git a/src/main/java/com/cleanroommc/common/CleanroomContainer.java b/module/cleanroom/src/main/java/com/cleanroommc/common/CleanroomContainer.java similarity index 100% rename from src/main/java/com/cleanroommc/common/CleanroomContainer.java rename to module/cleanroom/src/main/java/com/cleanroommc/common/CleanroomContainer.java diff --git a/src/main/java/com/cleanroommc/common/CleanroomEnvironment.java b/module/cleanroom/src/main/java/com/cleanroommc/common/CleanroomEnvironment.java similarity index 100% rename from src/main/java/com/cleanroommc/common/CleanroomEnvironment.java rename to module/cleanroom/src/main/java/com/cleanroommc/common/CleanroomEnvironment.java diff --git a/src/main/java/com/cleanroommc/common/ConfigAnytimeContainer.java b/module/cleanroom/src/main/java/com/cleanroommc/common/ConfigAnytimeContainer.java similarity index 100% rename from src/main/java/com/cleanroommc/common/ConfigAnytimeContainer.java rename to module/cleanroom/src/main/java/com/cleanroommc/common/ConfigAnytimeContainer.java diff --git a/src/main/java/com/cleanroommc/common/PatchModPresentChecker.java b/module/cleanroom/src/main/java/com/cleanroommc/common/PatchModPresentChecker.java similarity index 100% rename from src/main/java/com/cleanroommc/common/PatchModPresentChecker.java rename to module/cleanroom/src/main/java/com/cleanroommc/common/PatchModPresentChecker.java diff --git a/src/main/java/com/cleanroommc/configanytime/ConfigAnytime.java b/module/cleanroom/src/main/java/com/cleanroommc/configanytime/ConfigAnytime.java similarity index 100% rename from src/main/java/com/cleanroommc/configanytime/ConfigAnytime.java rename to module/cleanroom/src/main/java/com/cleanroommc/configanytime/ConfigAnytime.java diff --git a/src/main/java/com/cleanroommc/hackery/Reflection.java b/module/cleanroom/src/main/java/com/cleanroommc/hackery/Reflection.java similarity index 100% rename from src/main/java/com/cleanroommc/hackery/Reflection.java rename to module/cleanroom/src/main/java/com/cleanroommc/hackery/Reflection.java diff --git a/src/main/java/com/cleanroommc/hackery/ReflectionHackery.java b/module/cleanroom/src/main/java/com/cleanroommc/hackery/ReflectionHackery.java similarity index 100% rename from src/main/java/com/cleanroommc/hackery/ReflectionHackery.java rename to module/cleanroom/src/main/java/com/cleanroommc/hackery/ReflectionHackery.java diff --git a/src/main/java/com/cleanroommc/hackery/enums/EnumHackery.java b/module/cleanroom/src/main/java/com/cleanroommc/hackery/enums/EnumHackery.java similarity index 100% rename from src/main/java/com/cleanroommc/hackery/enums/EnumHackery.java rename to module/cleanroom/src/main/java/com/cleanroommc/hackery/enums/EnumHackery.java diff --git a/src/main/java/com/cleanroommc/loader/LanguageAdapterRegistry.java b/module/cleanroom/src/main/java/com/cleanroommc/loader/LanguageAdapterRegistry.java similarity index 100% rename from src/main/java/com/cleanroommc/loader/LanguageAdapterRegistry.java rename to module/cleanroom/src/main/java/com/cleanroommc/loader/LanguageAdapterRegistry.java diff --git a/src/main/java/com/cleanroommc/loader/javafix/UUIDFix.java b/module/cleanroom/src/main/java/com/cleanroommc/loader/javafix/UUIDFix.java similarity index 100% rename from src/main/java/com/cleanroommc/loader/javafix/UUIDFix.java rename to module/cleanroom/src/main/java/com/cleanroommc/loader/javafix/UUIDFix.java diff --git a/src/main/java/com/cleanroommc/loader/scripting/CleanroomScriptEngineManager.java b/module/cleanroom/src/main/java/com/cleanroommc/loader/scripting/CleanroomScriptEngineManager.java similarity index 100% rename from src/main/java/com/cleanroommc/loader/scripting/CleanroomScriptEngineManager.java rename to module/cleanroom/src/main/java/com/cleanroommc/loader/scripting/CleanroomScriptEngineManager.java diff --git a/src/test/java/com/cleanroommc/hackery/EnumHackeryTest.java b/module/cleanroom/src/test/java/com/cleanroommc/hackery/EnumHackeryTest.java similarity index 100% rename from src/test/java/com/cleanroommc/hackery/EnumHackeryTest.java rename to module/cleanroom/src/test/java/com/cleanroommc/hackery/EnumHackeryTest.java diff --git a/src/main/java/ibxm/Channel.java b/module/forge/src/main/java/ibxm/Channel.java similarity index 100% rename from src/main/java/ibxm/Channel.java rename to module/forge/src/main/java/ibxm/Channel.java diff --git a/src/main/java/ibxm/Envelope.java b/module/forge/src/main/java/ibxm/Envelope.java similarity index 100% rename from src/main/java/ibxm/Envelope.java rename to module/forge/src/main/java/ibxm/Envelope.java diff --git a/src/main/java/ibxm/FastTracker2.java b/module/forge/src/main/java/ibxm/FastTracker2.java similarity index 100% rename from src/main/java/ibxm/FastTracker2.java rename to module/forge/src/main/java/ibxm/FastTracker2.java diff --git a/src/main/java/ibxm/IBXM.java b/module/forge/src/main/java/ibxm/IBXM.java similarity index 100% rename from src/main/java/ibxm/IBXM.java rename to module/forge/src/main/java/ibxm/IBXM.java diff --git a/src/main/java/ibxm/Instrument.java b/module/forge/src/main/java/ibxm/Instrument.java similarity index 100% rename from src/main/java/ibxm/Instrument.java rename to module/forge/src/main/java/ibxm/Instrument.java diff --git a/src/main/java/ibxm/LogTable.java b/module/forge/src/main/java/ibxm/LogTable.java similarity index 100% rename from src/main/java/ibxm/LogTable.java rename to module/forge/src/main/java/ibxm/LogTable.java diff --git a/src/main/java/ibxm/Module.java b/module/forge/src/main/java/ibxm/Module.java similarity index 100% rename from src/main/java/ibxm/Module.java rename to module/forge/src/main/java/ibxm/Module.java diff --git a/src/main/java/ibxm/Pattern.java b/module/forge/src/main/java/ibxm/Pattern.java similarity index 100% rename from src/main/java/ibxm/Pattern.java rename to module/forge/src/main/java/ibxm/Pattern.java diff --git a/src/main/java/ibxm/Player.java b/module/forge/src/main/java/ibxm/Player.java similarity index 100% rename from src/main/java/ibxm/Player.java rename to module/forge/src/main/java/ibxm/Player.java diff --git a/src/main/java/ibxm/ProTracker.java b/module/forge/src/main/java/ibxm/ProTracker.java similarity index 100% rename from src/main/java/ibxm/ProTracker.java rename to module/forge/src/main/java/ibxm/ProTracker.java diff --git a/src/main/java/ibxm/Sample.java b/module/forge/src/main/java/ibxm/Sample.java similarity index 100% rename from src/main/java/ibxm/Sample.java rename to module/forge/src/main/java/ibxm/Sample.java diff --git a/src/main/java/ibxm/ScreamTracker3.java b/module/forge/src/main/java/ibxm/ScreamTracker3.java similarity index 100% rename from src/main/java/ibxm/ScreamTracker3.java rename to module/forge/src/main/java/ibxm/ScreamTracker3.java diff --git a/src/main/java/net/minecraftforge/advancements/critereon/ItemPredicates.java b/module/forge/src/main/java/net/minecraftforge/advancements/critereon/ItemPredicates.java similarity index 100% rename from src/main/java/net/minecraftforge/advancements/critereon/ItemPredicates.java rename to module/forge/src/main/java/net/minecraftforge/advancements/critereon/ItemPredicates.java diff --git a/src/main/java/net/minecraftforge/advancements/critereon/OredictItemPredicate.java b/module/forge/src/main/java/net/minecraftforge/advancements/critereon/OredictItemPredicate.java similarity index 100% rename from src/main/java/net/minecraftforge/advancements/critereon/OredictItemPredicate.java rename to module/forge/src/main/java/net/minecraftforge/advancements/critereon/OredictItemPredicate.java diff --git a/src/main/java/net/minecraftforge/classloading/FMLForgePlugin.java b/module/forge/src/main/java/net/minecraftforge/classloading/FMLForgePlugin.java similarity index 100% rename from src/main/java/net/minecraftforge/classloading/FMLForgePlugin.java rename to module/forge/src/main/java/net/minecraftforge/classloading/FMLForgePlugin.java diff --git a/src/main/java/net/minecraftforge/client/ClientCommandHandler.java b/module/forge/src/main/java/net/minecraftforge/client/ClientCommandHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/client/ClientCommandHandler.java rename to module/forge/src/main/java/net/minecraftforge/client/ClientCommandHandler.java diff --git a/src/main/java/net/minecraftforge/client/CloudRenderer.java b/module/forge/src/main/java/net/minecraftforge/client/CloudRenderer.java similarity index 100% rename from src/main/java/net/minecraftforge/client/CloudRenderer.java rename to module/forge/src/main/java/net/minecraftforge/client/CloudRenderer.java diff --git a/src/main/java/net/minecraftforge/client/EnumHelperClient.java b/module/forge/src/main/java/net/minecraftforge/client/EnumHelperClient.java similarity index 100% rename from src/main/java/net/minecraftforge/client/EnumHelperClient.java rename to module/forge/src/main/java/net/minecraftforge/client/EnumHelperClient.java diff --git a/src/main/java/net/minecraftforge/client/FluidContainerColorer.java b/module/forge/src/main/java/net/minecraftforge/client/FluidContainerColorer.java similarity index 100% rename from src/main/java/net/minecraftforge/client/FluidContainerColorer.java rename to module/forge/src/main/java/net/minecraftforge/client/FluidContainerColorer.java diff --git a/src/main/java/net/minecraftforge/client/ForgeClientHandler.java b/module/forge/src/main/java/net/minecraftforge/client/ForgeClientHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/client/ForgeClientHandler.java rename to module/forge/src/main/java/net/minecraftforge/client/ForgeClientHandler.java diff --git a/src/main/java/net/minecraftforge/client/ForgeHooksClient.java b/module/forge/src/main/java/net/minecraftforge/client/ForgeHooksClient.java similarity index 100% rename from src/main/java/net/minecraftforge/client/ForgeHooksClient.java rename to module/forge/src/main/java/net/minecraftforge/client/ForgeHooksClient.java diff --git a/src/main/java/net/minecraftforge/client/GuiIngameForge.java b/module/forge/src/main/java/net/minecraftforge/client/GuiIngameForge.java similarity index 100% rename from src/main/java/net/minecraftforge/client/GuiIngameForge.java rename to module/forge/src/main/java/net/minecraftforge/client/GuiIngameForge.java diff --git a/src/main/java/net/minecraftforge/client/IClientCommand.java b/module/forge/src/main/java/net/minecraftforge/client/IClientCommand.java similarity index 100% rename from src/main/java/net/minecraftforge/client/IClientCommand.java rename to module/forge/src/main/java/net/minecraftforge/client/IClientCommand.java diff --git a/src/main/java/net/minecraftforge/client/IRenderContextHandler.java b/module/forge/src/main/java/net/minecraftforge/client/IRenderContextHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/client/IRenderContextHandler.java rename to module/forge/src/main/java/net/minecraftforge/client/IRenderContextHandler.java diff --git a/src/main/java/net/minecraftforge/client/IRenderHandler.java b/module/forge/src/main/java/net/minecraftforge/client/IRenderHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/client/IRenderHandler.java rename to module/forge/src/main/java/net/minecraftforge/client/IRenderHandler.java diff --git a/src/main/java/net/minecraftforge/client/ItemModelMesherForge.java b/module/forge/src/main/java/net/minecraftforge/client/ItemModelMesherForge.java similarity index 100% rename from src/main/java/net/minecraftforge/client/ItemModelMesherForge.java rename to module/forge/src/main/java/net/minecraftforge/client/ItemModelMesherForge.java diff --git a/src/main/java/net/minecraftforge/client/MinecraftForgeClient.java b/module/forge/src/main/java/net/minecraftforge/client/MinecraftForgeClient.java similarity index 100% rename from src/main/java/net/minecraftforge/client/MinecraftForgeClient.java rename to module/forge/src/main/java/net/minecraftforge/client/MinecraftForgeClient.java diff --git a/src/main/java/net/minecraftforge/client/event/ClientChatEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/ClientChatEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/ClientChatEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/ClientChatEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/ClientChatReceivedEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/ClientChatReceivedEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/ClientChatReceivedEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/ClientChatReceivedEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/ColorHandlerEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/ColorHandlerEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/ColorHandlerEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/ColorHandlerEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/DrawBlockHighlightEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/DrawBlockHighlightEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/DrawBlockHighlightEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/DrawBlockHighlightEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/EntityViewRenderEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/EntityViewRenderEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/EntityViewRenderEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/EntityViewRenderEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/FOVUpdateEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/FOVUpdateEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/FOVUpdateEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/FOVUpdateEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/GuiContainerEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/GuiContainerEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/GuiContainerEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/GuiContainerEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/GuiOpenEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/GuiOpenEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/GuiOpenEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/GuiOpenEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/GuiScreenEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/GuiScreenEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/GuiScreenEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/GuiScreenEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/InputUpdateEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/InputUpdateEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/InputUpdateEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/InputUpdateEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/ModelBakeEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/ModelBakeEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/ModelBakeEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/ModelBakeEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/ModelRegistryEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/ModelRegistryEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/ModelRegistryEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/ModelRegistryEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/MouseEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/MouseEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/MouseEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/MouseEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/PlayerSPPushOutOfBlocksEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/PlayerSPPushOutOfBlocksEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/PlayerSPPushOutOfBlocksEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/PlayerSPPushOutOfBlocksEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/RenderArmEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/RenderArmEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/RenderArmEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/RenderArmEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/RenderBlockOverlayEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/RenderBlockOverlayEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/RenderBlockOverlayEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/RenderBlockOverlayEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/RenderGameOverlayEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/RenderGameOverlayEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/RenderGameOverlayEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/RenderGameOverlayEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/RenderHandEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/RenderHandEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/RenderHandEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/RenderHandEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/RenderItemInFrameEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/RenderItemInFrameEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/RenderItemInFrameEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/RenderItemInFrameEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/RenderLivingEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/RenderLivingEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/RenderLivingEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/RenderLivingEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/RenderPlayerEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/RenderPlayerEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/RenderPlayerEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/RenderPlayerEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/RenderSpecificHandEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/RenderSpecificHandEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/RenderSpecificHandEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/RenderSpecificHandEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/RenderTooltipEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/RenderTooltipEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/RenderTooltipEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/RenderTooltipEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/RenderWorldLastEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/RenderWorldLastEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/RenderWorldLastEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/RenderWorldLastEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/ScreenshotEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/ScreenshotEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/ScreenshotEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/ScreenshotEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/TextureStitchEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/TextureStitchEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/TextureStitchEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/TextureStitchEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/sound/PlaySoundEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/sound/PlaySoundEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/sound/PlaySoundEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/sound/PlaySoundEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/sound/PlaySoundSourceEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/sound/PlaySoundSourceEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/sound/PlaySoundSourceEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/sound/PlaySoundSourceEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/sound/PlayStreamingSourceEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/sound/PlayStreamingSourceEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/sound/PlayStreamingSourceEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/sound/PlayStreamingSourceEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/sound/SoundEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/sound/SoundEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/sound/SoundEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/sound/SoundEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/sound/SoundLoadEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/sound/SoundLoadEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/sound/SoundLoadEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/sound/SoundLoadEvent.java diff --git a/src/main/java/net/minecraftforge/client/event/sound/SoundSetupEvent.java b/module/forge/src/main/java/net/minecraftforge/client/event/sound/SoundSetupEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/client/event/sound/SoundSetupEvent.java rename to module/forge/src/main/java/net/minecraftforge/client/event/sound/SoundSetupEvent.java diff --git a/src/main/java/net/minecraftforge/client/gui/ForgeGuiFactory.java b/module/forge/src/main/java/net/minecraftforge/client/gui/ForgeGuiFactory.java similarity index 100% rename from src/main/java/net/minecraftforge/client/gui/ForgeGuiFactory.java rename to module/forge/src/main/java/net/minecraftforge/client/gui/ForgeGuiFactory.java diff --git a/src/main/java/net/minecraftforge/client/gui/NotificationModUpdateScreen.java b/module/forge/src/main/java/net/minecraftforge/client/gui/NotificationModUpdateScreen.java similarity index 100% rename from src/main/java/net/minecraftforge/client/gui/NotificationModUpdateScreen.java rename to module/forge/src/main/java/net/minecraftforge/client/gui/NotificationModUpdateScreen.java diff --git a/src/main/java/net/minecraftforge/client/model/Attributes.java b/module/forge/src/main/java/net/minecraftforge/client/model/Attributes.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/Attributes.java rename to module/forge/src/main/java/net/minecraftforge/client/model/Attributes.java diff --git a/src/main/java/net/minecraftforge/client/model/BakedItemModel.java b/module/forge/src/main/java/net/minecraftforge/client/model/BakedItemModel.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/BakedItemModel.java rename to module/forge/src/main/java/net/minecraftforge/client/model/BakedItemModel.java diff --git a/src/main/java/net/minecraftforge/client/model/BakedModelWrapper.java b/module/forge/src/main/java/net/minecraftforge/client/model/BakedModelWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/BakedModelWrapper.java rename to module/forge/src/main/java/net/minecraftforge/client/model/BakedModelWrapper.java diff --git a/src/main/java/net/minecraftforge/client/model/BlockStateLoader.java b/module/forge/src/main/java/net/minecraftforge/client/model/BlockStateLoader.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/BlockStateLoader.java rename to module/forge/src/main/java/net/minecraftforge/client/model/BlockStateLoader.java diff --git a/src/main/java/net/minecraftforge/client/model/FancyMissingModel.java b/module/forge/src/main/java/net/minecraftforge/client/model/FancyMissingModel.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/FancyMissingModel.java rename to module/forge/src/main/java/net/minecraftforge/client/model/FancyMissingModel.java diff --git a/src/main/java/net/minecraftforge/client/model/ForgeBlockStateV1.java b/module/forge/src/main/java/net/minecraftforge/client/model/ForgeBlockStateV1.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/ForgeBlockStateV1.java rename to module/forge/src/main/java/net/minecraftforge/client/model/ForgeBlockStateV1.java diff --git a/src/main/java/net/minecraftforge/client/model/ICustomModelLoader.java b/module/forge/src/main/java/net/minecraftforge/client/model/ICustomModelLoader.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/ICustomModelLoader.java rename to module/forge/src/main/java/net/minecraftforge/client/model/ICustomModelLoader.java diff --git a/src/main/java/net/minecraftforge/client/model/IModel.java b/module/forge/src/main/java/net/minecraftforge/client/model/IModel.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/IModel.java rename to module/forge/src/main/java/net/minecraftforge/client/model/IModel.java diff --git a/src/main/java/net/minecraftforge/client/model/ISmartVariant.java b/module/forge/src/main/java/net/minecraftforge/client/model/ISmartVariant.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/ISmartVariant.java rename to module/forge/src/main/java/net/minecraftforge/client/model/ISmartVariant.java diff --git a/src/main/java/net/minecraftforge/client/model/ItemLayerModel.java b/module/forge/src/main/java/net/minecraftforge/client/model/ItemLayerModel.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/ItemLayerModel.java rename to module/forge/src/main/java/net/minecraftforge/client/model/ItemLayerModel.java diff --git a/src/main/java/net/minecraftforge/client/model/ItemTextureQuadConverter.java b/module/forge/src/main/java/net/minecraftforge/client/model/ItemTextureQuadConverter.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/ItemTextureQuadConverter.java rename to module/forge/src/main/java/net/minecraftforge/client/model/ItemTextureQuadConverter.java diff --git a/src/main/java/net/minecraftforge/client/model/MapModelState.java b/module/forge/src/main/java/net/minecraftforge/client/model/MapModelState.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/MapModelState.java rename to module/forge/src/main/java/net/minecraftforge/client/model/MapModelState.java diff --git a/src/main/java/net/minecraftforge/client/model/ModelDynBucket.java b/module/forge/src/main/java/net/minecraftforge/client/model/ModelDynBucket.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/ModelDynBucket.java rename to module/forge/src/main/java/net/minecraftforge/client/model/ModelDynBucket.java diff --git a/src/main/java/net/minecraftforge/client/model/ModelFluid.java b/module/forge/src/main/java/net/minecraftforge/client/model/ModelFluid.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/ModelFluid.java rename to module/forge/src/main/java/net/minecraftforge/client/model/ModelFluid.java diff --git a/src/main/java/net/minecraftforge/client/model/ModelLoader.java b/module/forge/src/main/java/net/minecraftforge/client/model/ModelLoader.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/ModelLoader.java rename to module/forge/src/main/java/net/minecraftforge/client/model/ModelLoader.java diff --git a/src/main/java/net/minecraftforge/client/model/ModelLoaderRegistry.java b/module/forge/src/main/java/net/minecraftforge/client/model/ModelLoaderRegistry.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/ModelLoaderRegistry.java rename to module/forge/src/main/java/net/minecraftforge/client/model/ModelLoaderRegistry.java diff --git a/src/main/java/net/minecraftforge/client/model/ModelStateComposition.java b/module/forge/src/main/java/net/minecraftforge/client/model/ModelStateComposition.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/ModelStateComposition.java rename to module/forge/src/main/java/net/minecraftforge/client/model/ModelStateComposition.java diff --git a/src/main/java/net/minecraftforge/client/model/MultiLayerModel.java b/module/forge/src/main/java/net/minecraftforge/client/model/MultiLayerModel.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/MultiLayerModel.java rename to module/forge/src/main/java/net/minecraftforge/client/model/MultiLayerModel.java diff --git a/src/main/java/net/minecraftforge/client/model/MultiModel.java b/module/forge/src/main/java/net/minecraftforge/client/model/MultiModel.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/MultiModel.java rename to module/forge/src/main/java/net/minecraftforge/client/model/MultiModel.java diff --git a/src/main/java/net/minecraftforge/client/model/MultiModelState.java b/module/forge/src/main/java/net/minecraftforge/client/model/MultiModelState.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/MultiModelState.java rename to module/forge/src/main/java/net/minecraftforge/client/model/MultiModelState.java diff --git a/src/main/java/net/minecraftforge/client/model/PerspectiveMapWrapper.java b/module/forge/src/main/java/net/minecraftforge/client/model/PerspectiveMapWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/PerspectiveMapWrapper.java rename to module/forge/src/main/java/net/minecraftforge/client/model/PerspectiveMapWrapper.java diff --git a/src/main/java/net/minecraftforge/client/model/SimpleModelFontRenderer.java b/module/forge/src/main/java/net/minecraftforge/client/model/SimpleModelFontRenderer.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/SimpleModelFontRenderer.java rename to module/forge/src/main/java/net/minecraftforge/client/model/SimpleModelFontRenderer.java diff --git a/src/main/java/net/minecraftforge/client/model/SimpleModelState.java b/module/forge/src/main/java/net/minecraftforge/client/model/SimpleModelState.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/SimpleModelState.java rename to module/forge/src/main/java/net/minecraftforge/client/model/SimpleModelState.java diff --git a/src/main/java/net/minecraftforge/client/model/animation/Animation.java b/module/forge/src/main/java/net/minecraftforge/client/model/animation/Animation.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/animation/Animation.java rename to module/forge/src/main/java/net/minecraftforge/client/model/animation/Animation.java diff --git a/src/main/java/net/minecraftforge/client/model/animation/AnimationItemOverrideList.java b/module/forge/src/main/java/net/minecraftforge/client/model/animation/AnimationItemOverrideList.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/animation/AnimationItemOverrideList.java rename to module/forge/src/main/java/net/minecraftforge/client/model/animation/AnimationItemOverrideList.java diff --git a/src/main/java/net/minecraftforge/client/model/animation/AnimationModelBase.java b/module/forge/src/main/java/net/minecraftforge/client/model/animation/AnimationModelBase.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/animation/AnimationModelBase.java rename to module/forge/src/main/java/net/minecraftforge/client/model/animation/AnimationModelBase.java diff --git a/src/main/java/net/minecraftforge/client/model/animation/AnimationTESR.java b/module/forge/src/main/java/net/minecraftforge/client/model/animation/AnimationTESR.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/animation/AnimationTESR.java rename to module/forge/src/main/java/net/minecraftforge/client/model/animation/AnimationTESR.java diff --git a/src/main/java/net/minecraftforge/client/model/animation/FastTESR.java b/module/forge/src/main/java/net/minecraftforge/client/model/animation/FastTESR.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/animation/FastTESR.java rename to module/forge/src/main/java/net/minecraftforge/client/model/animation/FastTESR.java diff --git a/src/main/java/net/minecraftforge/client/model/animation/ModelBlockAnimation.java b/module/forge/src/main/java/net/minecraftforge/client/model/animation/ModelBlockAnimation.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/animation/ModelBlockAnimation.java rename to module/forge/src/main/java/net/minecraftforge/client/model/animation/ModelBlockAnimation.java diff --git a/src/main/java/net/minecraftforge/client/model/animation/package-info.java b/module/forge/src/main/java/net/minecraftforge/client/model/animation/package-info.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/animation/package-info.java rename to module/forge/src/main/java/net/minecraftforge/client/model/animation/package-info.java diff --git a/src/main/java/net/minecraftforge/client/model/b3d/B3DClip.java b/module/forge/src/main/java/net/minecraftforge/client/model/b3d/B3DClip.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/b3d/B3DClip.java rename to module/forge/src/main/java/net/minecraftforge/client/model/b3d/B3DClip.java diff --git a/src/main/java/net/minecraftforge/client/model/b3d/B3DLoader.java b/module/forge/src/main/java/net/minecraftforge/client/model/b3d/B3DLoader.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/b3d/B3DLoader.java rename to module/forge/src/main/java/net/minecraftforge/client/model/b3d/B3DLoader.java diff --git a/src/main/java/net/minecraftforge/client/model/b3d/B3DModel.java b/module/forge/src/main/java/net/minecraftforge/client/model/b3d/B3DModel.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/b3d/B3DModel.java rename to module/forge/src/main/java/net/minecraftforge/client/model/b3d/B3DModel.java diff --git a/src/main/java/net/minecraftforge/client/model/b3d/package-info.java b/module/forge/src/main/java/net/minecraftforge/client/model/b3d/package-info.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/b3d/package-info.java rename to module/forge/src/main/java/net/minecraftforge/client/model/b3d/package-info.java diff --git a/src/main/java/net/minecraftforge/client/model/obj/OBJLoader.java b/module/forge/src/main/java/net/minecraftforge/client/model/obj/OBJLoader.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/obj/OBJLoader.java rename to module/forge/src/main/java/net/minecraftforge/client/model/obj/OBJLoader.java diff --git a/src/main/java/net/minecraftforge/client/model/obj/OBJModel.java b/module/forge/src/main/java/net/minecraftforge/client/model/obj/OBJModel.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/obj/OBJModel.java rename to module/forge/src/main/java/net/minecraftforge/client/model/obj/OBJModel.java diff --git a/src/main/java/net/minecraftforge/client/model/obj/package-info.java b/module/forge/src/main/java/net/minecraftforge/client/model/obj/package-info.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/obj/package-info.java rename to module/forge/src/main/java/net/minecraftforge/client/model/obj/package-info.java diff --git a/src/main/java/net/minecraftforge/client/model/package-info.java b/module/forge/src/main/java/net/minecraftforge/client/model/package-info.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/package-info.java rename to module/forge/src/main/java/net/minecraftforge/client/model/package-info.java diff --git a/src/main/java/net/minecraftforge/client/model/pipeline/BlockInfo.java b/module/forge/src/main/java/net/minecraftforge/client/model/pipeline/BlockInfo.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/pipeline/BlockInfo.java rename to module/forge/src/main/java/net/minecraftforge/client/model/pipeline/BlockInfo.java diff --git a/src/main/java/net/minecraftforge/client/model/pipeline/ForgeBlockModelRenderer.java b/module/forge/src/main/java/net/minecraftforge/client/model/pipeline/ForgeBlockModelRenderer.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/pipeline/ForgeBlockModelRenderer.java rename to module/forge/src/main/java/net/minecraftforge/client/model/pipeline/ForgeBlockModelRenderer.java diff --git a/src/main/java/net/minecraftforge/client/model/pipeline/IVertexConsumer.java b/module/forge/src/main/java/net/minecraftforge/client/model/pipeline/IVertexConsumer.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/pipeline/IVertexConsumer.java rename to module/forge/src/main/java/net/minecraftforge/client/model/pipeline/IVertexConsumer.java diff --git a/src/main/java/net/minecraftforge/client/model/pipeline/IVertexProducer.java b/module/forge/src/main/java/net/minecraftforge/client/model/pipeline/IVertexProducer.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/pipeline/IVertexProducer.java rename to module/forge/src/main/java/net/minecraftforge/client/model/pipeline/IVertexProducer.java diff --git a/src/main/java/net/minecraftforge/client/model/pipeline/LightUtil.java b/module/forge/src/main/java/net/minecraftforge/client/model/pipeline/LightUtil.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/pipeline/LightUtil.java rename to module/forge/src/main/java/net/minecraftforge/client/model/pipeline/LightUtil.java diff --git a/src/main/java/net/minecraftforge/client/model/pipeline/QuadGatheringTransformer.java b/module/forge/src/main/java/net/minecraftforge/client/model/pipeline/QuadGatheringTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/pipeline/QuadGatheringTransformer.java rename to module/forge/src/main/java/net/minecraftforge/client/model/pipeline/QuadGatheringTransformer.java diff --git a/src/main/java/net/minecraftforge/client/model/pipeline/TRSRTransformer.java b/module/forge/src/main/java/net/minecraftforge/client/model/pipeline/TRSRTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/pipeline/TRSRTransformer.java rename to module/forge/src/main/java/net/minecraftforge/client/model/pipeline/TRSRTransformer.java diff --git a/src/main/java/net/minecraftforge/client/model/pipeline/TransformerConsumer.java b/module/forge/src/main/java/net/minecraftforge/client/model/pipeline/TransformerConsumer.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/pipeline/TransformerConsumer.java rename to module/forge/src/main/java/net/minecraftforge/client/model/pipeline/TransformerConsumer.java diff --git a/src/main/java/net/minecraftforge/client/model/pipeline/UnpackedBakedQuad.java b/module/forge/src/main/java/net/minecraftforge/client/model/pipeline/UnpackedBakedQuad.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/pipeline/UnpackedBakedQuad.java rename to module/forge/src/main/java/net/minecraftforge/client/model/pipeline/UnpackedBakedQuad.java diff --git a/src/main/java/net/minecraftforge/client/model/pipeline/VertexBufferConsumer.java b/module/forge/src/main/java/net/minecraftforge/client/model/pipeline/VertexBufferConsumer.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/pipeline/VertexBufferConsumer.java rename to module/forge/src/main/java/net/minecraftforge/client/model/pipeline/VertexBufferConsumer.java diff --git a/src/main/java/net/minecraftforge/client/model/pipeline/VertexLighterFlat.java b/module/forge/src/main/java/net/minecraftforge/client/model/pipeline/VertexLighterFlat.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/pipeline/VertexLighterFlat.java rename to module/forge/src/main/java/net/minecraftforge/client/model/pipeline/VertexLighterFlat.java diff --git a/src/main/java/net/minecraftforge/client/model/pipeline/VertexLighterSmoothAo.java b/module/forge/src/main/java/net/minecraftforge/client/model/pipeline/VertexLighterSmoothAo.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/pipeline/VertexLighterSmoothAo.java rename to module/forge/src/main/java/net/minecraftforge/client/model/pipeline/VertexLighterSmoothAo.java diff --git a/src/main/java/net/minecraftforge/client/model/pipeline/VertexTransformer.java b/module/forge/src/main/java/net/minecraftforge/client/model/pipeline/VertexTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/pipeline/VertexTransformer.java rename to module/forge/src/main/java/net/minecraftforge/client/model/pipeline/VertexTransformer.java diff --git a/src/main/java/net/minecraftforge/client/model/pipeline/package-info.java b/module/forge/src/main/java/net/minecraftforge/client/model/pipeline/package-info.java similarity index 100% rename from src/main/java/net/minecraftforge/client/model/pipeline/package-info.java rename to module/forge/src/main/java/net/minecraftforge/client/model/pipeline/package-info.java diff --git a/src/main/java/net/minecraftforge/client/resource/IResourceType.java b/module/forge/src/main/java/net/minecraftforge/client/resource/IResourceType.java similarity index 100% rename from src/main/java/net/minecraftforge/client/resource/IResourceType.java rename to module/forge/src/main/java/net/minecraftforge/client/resource/IResourceType.java diff --git a/src/main/java/net/minecraftforge/client/resource/ISelectiveResourceReloadListener.java b/module/forge/src/main/java/net/minecraftforge/client/resource/ISelectiveResourceReloadListener.java similarity index 100% rename from src/main/java/net/minecraftforge/client/resource/ISelectiveResourceReloadListener.java rename to module/forge/src/main/java/net/minecraftforge/client/resource/ISelectiveResourceReloadListener.java diff --git a/src/main/java/net/minecraftforge/client/resource/ReloadRequirements.java b/module/forge/src/main/java/net/minecraftforge/client/resource/ReloadRequirements.java similarity index 100% rename from src/main/java/net/minecraftforge/client/resource/ReloadRequirements.java rename to module/forge/src/main/java/net/minecraftforge/client/resource/ReloadRequirements.java diff --git a/src/main/java/net/minecraftforge/client/resource/SelectiveReloadStateHandler.java b/module/forge/src/main/java/net/minecraftforge/client/resource/SelectiveReloadStateHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/client/resource/SelectiveReloadStateHandler.java rename to module/forge/src/main/java/net/minecraftforge/client/resource/SelectiveReloadStateHandler.java diff --git a/src/main/java/net/minecraftforge/client/resource/VanillaResourceType.java b/module/forge/src/main/java/net/minecraftforge/client/resource/VanillaResourceType.java similarity index 100% rename from src/main/java/net/minecraftforge/client/resource/VanillaResourceType.java rename to module/forge/src/main/java/net/minecraftforge/client/resource/VanillaResourceType.java diff --git a/src/main/java/net/minecraftforge/client/resource/package-info.java b/module/forge/src/main/java/net/minecraftforge/client/resource/package-info.java similarity index 100% rename from src/main/java/net/minecraftforge/client/resource/package-info.java rename to module/forge/src/main/java/net/minecraftforge/client/resource/package-info.java diff --git a/src/main/java/net/minecraftforge/client/settings/IKeyConflictContext.java b/module/forge/src/main/java/net/minecraftforge/client/settings/IKeyConflictContext.java similarity index 100% rename from src/main/java/net/minecraftforge/client/settings/IKeyConflictContext.java rename to module/forge/src/main/java/net/minecraftforge/client/settings/IKeyConflictContext.java diff --git a/src/main/java/net/minecraftforge/client/settings/KeyBindingMap.java b/module/forge/src/main/java/net/minecraftforge/client/settings/KeyBindingMap.java similarity index 100% rename from src/main/java/net/minecraftforge/client/settings/KeyBindingMap.java rename to module/forge/src/main/java/net/minecraftforge/client/settings/KeyBindingMap.java diff --git a/src/main/java/net/minecraftforge/client/settings/KeyConflictContext.java b/module/forge/src/main/java/net/minecraftforge/client/settings/KeyConflictContext.java similarity index 100% rename from src/main/java/net/minecraftforge/client/settings/KeyConflictContext.java rename to module/forge/src/main/java/net/minecraftforge/client/settings/KeyConflictContext.java diff --git a/src/main/java/net/minecraftforge/client/settings/KeyModifier.java b/module/forge/src/main/java/net/minecraftforge/client/settings/KeyModifier.java similarity index 100% rename from src/main/java/net/minecraftforge/client/settings/KeyModifier.java rename to module/forge/src/main/java/net/minecraftforge/client/settings/KeyModifier.java diff --git a/src/main/java/net/minecraftforge/common/BiomeDictionary.java b/module/forge/src/main/java/net/minecraftforge/common/BiomeDictionary.java similarity index 100% rename from src/main/java/net/minecraftforge/common/BiomeDictionary.java rename to module/forge/src/main/java/net/minecraftforge/common/BiomeDictionary.java diff --git a/src/main/java/net/minecraftforge/common/BiomeManager.java b/module/forge/src/main/java/net/minecraftforge/common/BiomeManager.java similarity index 100% rename from src/main/java/net/minecraftforge/common/BiomeManager.java rename to module/forge/src/main/java/net/minecraftforge/common/BiomeManager.java diff --git a/src/main/java/net/minecraftforge/common/DimensionManager.java b/module/forge/src/main/java/net/minecraftforge/common/DimensionManager.java similarity index 100% rename from src/main/java/net/minecraftforge/common/DimensionManager.java rename to module/forge/src/main/java/net/minecraftforge/common/DimensionManager.java diff --git a/src/main/java/net/minecraftforge/common/DungeonHooks.java b/module/forge/src/main/java/net/minecraftforge/common/DungeonHooks.java similarity index 100% rename from src/main/java/net/minecraftforge/common/DungeonHooks.java rename to module/forge/src/main/java/net/minecraftforge/common/DungeonHooks.java diff --git a/src/main/java/net/minecraftforge/common/EnumPlantType.java b/module/forge/src/main/java/net/minecraftforge/common/EnumPlantType.java similarity index 100% rename from src/main/java/net/minecraftforge/common/EnumPlantType.java rename to module/forge/src/main/java/net/minecraftforge/common/EnumPlantType.java diff --git a/src/main/java/net/minecraftforge/common/FarmlandWaterManager.java b/module/forge/src/main/java/net/minecraftforge/common/FarmlandWaterManager.java similarity index 100% rename from src/main/java/net/minecraftforge/common/FarmlandWaterManager.java rename to module/forge/src/main/java/net/minecraftforge/common/FarmlandWaterManager.java diff --git a/src/main/java/net/minecraftforge/common/ForgeChunkManager.java b/module/forge/src/main/java/net/minecraftforge/common/ForgeChunkManager.java similarity index 100% rename from src/main/java/net/minecraftforge/common/ForgeChunkManager.java rename to module/forge/src/main/java/net/minecraftforge/common/ForgeChunkManager.java diff --git a/src/main/java/net/minecraftforge/common/ForgeEarlyConfig.java b/module/forge/src/main/java/net/minecraftforge/common/ForgeEarlyConfig.java similarity index 100% rename from src/main/java/net/minecraftforge/common/ForgeEarlyConfig.java rename to module/forge/src/main/java/net/minecraftforge/common/ForgeEarlyConfig.java diff --git a/src/main/java/net/minecraftforge/common/ForgeHooks.java b/module/forge/src/main/java/net/minecraftforge/common/ForgeHooks.java similarity index 100% rename from src/main/java/net/minecraftforge/common/ForgeHooks.java rename to module/forge/src/main/java/net/minecraftforge/common/ForgeHooks.java diff --git a/src/main/java/net/minecraftforge/common/ForgeInternalHandler.java b/module/forge/src/main/java/net/minecraftforge/common/ForgeInternalHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/common/ForgeInternalHandler.java rename to module/forge/src/main/java/net/minecraftforge/common/ForgeInternalHandler.java diff --git a/src/main/java/net/minecraftforge/common/ForgeModContainer.java b/module/forge/src/main/java/net/minecraftforge/common/ForgeModContainer.java similarity index 100% rename from src/main/java/net/minecraftforge/common/ForgeModContainer.java rename to module/forge/src/main/java/net/minecraftforge/common/ForgeModContainer.java diff --git a/src/main/java/net/minecraftforge/common/ForgeVersion.java b/module/forge/src/main/java/net/minecraftforge/common/ForgeVersion.java similarity index 100% rename from src/main/java/net/minecraftforge/common/ForgeVersion.java rename to module/forge/src/main/java/net/minecraftforge/common/ForgeVersion.java diff --git a/src/main/java/net/minecraftforge/common/IMinecartCollisionHandler.java b/module/forge/src/main/java/net/minecraftforge/common/IMinecartCollisionHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/common/IMinecartCollisionHandler.java rename to module/forge/src/main/java/net/minecraftforge/common/IMinecartCollisionHandler.java diff --git a/src/main/java/net/minecraftforge/common/IPlantable.java b/module/forge/src/main/java/net/minecraftforge/common/IPlantable.java similarity index 100% rename from src/main/java/net/minecraftforge/common/IPlantable.java rename to module/forge/src/main/java/net/minecraftforge/common/IPlantable.java diff --git a/src/main/java/net/minecraftforge/common/IRarity.java b/module/forge/src/main/java/net/minecraftforge/common/IRarity.java similarity index 100% rename from src/main/java/net/minecraftforge/common/IRarity.java rename to module/forge/src/main/java/net/minecraftforge/common/IRarity.java diff --git a/src/main/java/net/minecraftforge/common/IShearable.java b/module/forge/src/main/java/net/minecraftforge/common/IShearable.java similarity index 100% rename from src/main/java/net/minecraftforge/common/IShearable.java rename to module/forge/src/main/java/net/minecraftforge/common/IShearable.java diff --git a/src/main/java/net/minecraftforge/common/ISpecialArmor.java b/module/forge/src/main/java/net/minecraftforge/common/ISpecialArmor.java similarity index 100% rename from src/main/java/net/minecraftforge/common/ISpecialArmor.java rename to module/forge/src/main/java/net/minecraftforge/common/ISpecialArmor.java diff --git a/src/main/java/net/minecraftforge/common/MinecraftForge.java b/module/forge/src/main/java/net/minecraftforge/common/MinecraftForge.java similarity index 100% rename from src/main/java/net/minecraftforge/common/MinecraftForge.java rename to module/forge/src/main/java/net/minecraftforge/common/MinecraftForge.java diff --git a/src/main/java/net/minecraftforge/common/UsernameCache.java b/module/forge/src/main/java/net/minecraftforge/common/UsernameCache.java similarity index 100% rename from src/main/java/net/minecraftforge/common/UsernameCache.java rename to module/forge/src/main/java/net/minecraftforge/common/UsernameCache.java diff --git a/src/main/java/net/minecraftforge/common/WorldSpecificSaveHandler.java b/module/forge/src/main/java/net/minecraftforge/common/WorldSpecificSaveHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/common/WorldSpecificSaveHandler.java rename to module/forge/src/main/java/net/minecraftforge/common/WorldSpecificSaveHandler.java diff --git a/src/main/java/net/minecraftforge/common/WorldWorkerManager.java b/module/forge/src/main/java/net/minecraftforge/common/WorldWorkerManager.java similarity index 100% rename from src/main/java/net/minecraftforge/common/WorldWorkerManager.java rename to module/forge/src/main/java/net/minecraftforge/common/WorldWorkerManager.java diff --git a/src/main/java/net/minecraftforge/common/animation/Event.java b/module/forge/src/main/java/net/minecraftforge/common/animation/Event.java similarity index 100% rename from src/main/java/net/minecraftforge/common/animation/Event.java rename to module/forge/src/main/java/net/minecraftforge/common/animation/Event.java diff --git a/src/main/java/net/minecraftforge/common/animation/IEventHandler.java b/module/forge/src/main/java/net/minecraftforge/common/animation/IEventHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/common/animation/IEventHandler.java rename to module/forge/src/main/java/net/minecraftforge/common/animation/IEventHandler.java diff --git a/src/main/java/net/minecraftforge/common/animation/ITimeValue.java b/module/forge/src/main/java/net/minecraftforge/common/animation/ITimeValue.java similarity index 100% rename from src/main/java/net/minecraftforge/common/animation/ITimeValue.java rename to module/forge/src/main/java/net/minecraftforge/common/animation/ITimeValue.java diff --git a/src/main/java/net/minecraftforge/common/animation/TimeValues.java b/module/forge/src/main/java/net/minecraftforge/common/animation/TimeValues.java similarity index 100% rename from src/main/java/net/minecraftforge/common/animation/TimeValues.java rename to module/forge/src/main/java/net/minecraftforge/common/animation/TimeValues.java diff --git a/src/main/java/net/minecraftforge/common/brewing/AbstractBrewingRecipe.java b/module/forge/src/main/java/net/minecraftforge/common/brewing/AbstractBrewingRecipe.java similarity index 100% rename from src/main/java/net/minecraftforge/common/brewing/AbstractBrewingRecipe.java rename to module/forge/src/main/java/net/minecraftforge/common/brewing/AbstractBrewingRecipe.java diff --git a/src/main/java/net/minecraftforge/common/brewing/BrewingOreRecipe.java b/module/forge/src/main/java/net/minecraftforge/common/brewing/BrewingOreRecipe.java similarity index 100% rename from src/main/java/net/minecraftforge/common/brewing/BrewingOreRecipe.java rename to module/forge/src/main/java/net/minecraftforge/common/brewing/BrewingOreRecipe.java diff --git a/src/main/java/net/minecraftforge/common/brewing/BrewingRecipe.java b/module/forge/src/main/java/net/minecraftforge/common/brewing/BrewingRecipe.java similarity index 100% rename from src/main/java/net/minecraftforge/common/brewing/BrewingRecipe.java rename to module/forge/src/main/java/net/minecraftforge/common/brewing/BrewingRecipe.java diff --git a/src/main/java/net/minecraftforge/common/brewing/BrewingRecipeRegistry.java b/module/forge/src/main/java/net/minecraftforge/common/brewing/BrewingRecipeRegistry.java similarity index 100% rename from src/main/java/net/minecraftforge/common/brewing/BrewingRecipeRegistry.java rename to module/forge/src/main/java/net/minecraftforge/common/brewing/BrewingRecipeRegistry.java diff --git a/src/main/java/net/minecraftforge/common/brewing/IBrewingRecipe.java b/module/forge/src/main/java/net/minecraftforge/common/brewing/IBrewingRecipe.java similarity index 100% rename from src/main/java/net/minecraftforge/common/brewing/IBrewingRecipe.java rename to module/forge/src/main/java/net/minecraftforge/common/brewing/IBrewingRecipe.java diff --git a/src/main/java/net/minecraftforge/common/brewing/VanillaBrewingRecipe.java b/module/forge/src/main/java/net/minecraftforge/common/brewing/VanillaBrewingRecipe.java similarity index 100% rename from src/main/java/net/minecraftforge/common/brewing/VanillaBrewingRecipe.java rename to module/forge/src/main/java/net/minecraftforge/common/brewing/VanillaBrewingRecipe.java diff --git a/src/main/java/net/minecraftforge/common/capabilities/Capability.java b/module/forge/src/main/java/net/minecraftforge/common/capabilities/Capability.java similarity index 100% rename from src/main/java/net/minecraftforge/common/capabilities/Capability.java rename to module/forge/src/main/java/net/minecraftforge/common/capabilities/Capability.java diff --git a/src/main/java/net/minecraftforge/common/capabilities/CapabilityDispatcher.java b/module/forge/src/main/java/net/minecraftforge/common/capabilities/CapabilityDispatcher.java similarity index 100% rename from src/main/java/net/minecraftforge/common/capabilities/CapabilityDispatcher.java rename to module/forge/src/main/java/net/minecraftforge/common/capabilities/CapabilityDispatcher.java diff --git a/src/main/java/net/minecraftforge/common/capabilities/CapabilityInject.java b/module/forge/src/main/java/net/minecraftforge/common/capabilities/CapabilityInject.java similarity index 100% rename from src/main/java/net/minecraftforge/common/capabilities/CapabilityInject.java rename to module/forge/src/main/java/net/minecraftforge/common/capabilities/CapabilityInject.java diff --git a/src/main/java/net/minecraftforge/common/capabilities/CapabilityManager.java b/module/forge/src/main/java/net/minecraftforge/common/capabilities/CapabilityManager.java similarity index 100% rename from src/main/java/net/minecraftforge/common/capabilities/CapabilityManager.java rename to module/forge/src/main/java/net/minecraftforge/common/capabilities/CapabilityManager.java diff --git a/src/main/java/net/minecraftforge/common/capabilities/ICapabilityProvider.java b/module/forge/src/main/java/net/minecraftforge/common/capabilities/ICapabilityProvider.java similarity index 100% rename from src/main/java/net/minecraftforge/common/capabilities/ICapabilityProvider.java rename to module/forge/src/main/java/net/minecraftforge/common/capabilities/ICapabilityProvider.java diff --git a/src/main/java/net/minecraftforge/common/capabilities/ICapabilitySerializable.java b/module/forge/src/main/java/net/minecraftforge/common/capabilities/ICapabilitySerializable.java similarity index 100% rename from src/main/java/net/minecraftforge/common/capabilities/ICapabilitySerializable.java rename to module/forge/src/main/java/net/minecraftforge/common/capabilities/ICapabilitySerializable.java diff --git a/src/main/java/net/minecraftforge/common/chunkio/ChunkIOExecutor.java b/module/forge/src/main/java/net/minecraftforge/common/chunkio/ChunkIOExecutor.java similarity index 100% rename from src/main/java/net/minecraftforge/common/chunkio/ChunkIOExecutor.java rename to module/forge/src/main/java/net/minecraftforge/common/chunkio/ChunkIOExecutor.java diff --git a/src/main/java/net/minecraftforge/common/chunkio/ChunkIOProvider.java b/module/forge/src/main/java/net/minecraftforge/common/chunkio/ChunkIOProvider.java similarity index 100% rename from src/main/java/net/minecraftforge/common/chunkio/ChunkIOProvider.java rename to module/forge/src/main/java/net/minecraftforge/common/chunkio/ChunkIOProvider.java diff --git a/src/main/java/net/minecraftforge/common/chunkio/ChunkIOThreadPoolExecutor.java b/module/forge/src/main/java/net/minecraftforge/common/chunkio/ChunkIOThreadPoolExecutor.java similarity index 100% rename from src/main/java/net/minecraftforge/common/chunkio/ChunkIOThreadPoolExecutor.java rename to module/forge/src/main/java/net/minecraftforge/common/chunkio/ChunkIOThreadPoolExecutor.java diff --git a/src/main/java/net/minecraftforge/common/chunkio/QueuedChunk.java b/module/forge/src/main/java/net/minecraftforge/common/chunkio/QueuedChunk.java similarity index 100% rename from src/main/java/net/minecraftforge/common/chunkio/QueuedChunk.java rename to module/forge/src/main/java/net/minecraftforge/common/chunkio/QueuedChunk.java diff --git a/src/main/java/net/minecraftforge/common/command/SelectorHandler.java b/module/forge/src/main/java/net/minecraftforge/common/command/SelectorHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/common/command/SelectorHandler.java rename to module/forge/src/main/java/net/minecraftforge/common/command/SelectorHandler.java diff --git a/src/main/java/net/minecraftforge/common/command/SelectorHandlerManager.java b/module/forge/src/main/java/net/minecraftforge/common/command/SelectorHandlerManager.java similarity index 100% rename from src/main/java/net/minecraftforge/common/command/SelectorHandlerManager.java rename to module/forge/src/main/java/net/minecraftforge/common/command/SelectorHandlerManager.java diff --git a/src/main/java/net/minecraftforge/common/config/Config.java b/module/forge/src/main/java/net/minecraftforge/common/config/Config.java similarity index 100% rename from src/main/java/net/minecraftforge/common/config/Config.java rename to module/forge/src/main/java/net/minecraftforge/common/config/Config.java diff --git a/src/main/java/net/minecraftforge/common/config/ConfigCategory.java b/module/forge/src/main/java/net/minecraftforge/common/config/ConfigCategory.java similarity index 100% rename from src/main/java/net/minecraftforge/common/config/ConfigCategory.java rename to module/forge/src/main/java/net/minecraftforge/common/config/ConfigCategory.java diff --git a/src/main/java/net/minecraftforge/common/config/ConfigElement.java b/module/forge/src/main/java/net/minecraftforge/common/config/ConfigElement.java similarity index 100% rename from src/main/java/net/minecraftforge/common/config/ConfigElement.java rename to module/forge/src/main/java/net/minecraftforge/common/config/ConfigElement.java diff --git a/src/main/java/net/minecraftforge/common/config/ConfigManager.java b/module/forge/src/main/java/net/minecraftforge/common/config/ConfigManager.java similarity index 100% rename from src/main/java/net/minecraftforge/common/config/ConfigManager.java rename to module/forge/src/main/java/net/minecraftforge/common/config/ConfigManager.java diff --git a/src/main/java/net/minecraftforge/common/config/Configuration.java b/module/forge/src/main/java/net/minecraftforge/common/config/Configuration.java similarity index 100% rename from src/main/java/net/minecraftforge/common/config/Configuration.java rename to module/forge/src/main/java/net/minecraftforge/common/config/Configuration.java diff --git a/src/main/java/net/minecraftforge/common/config/FieldWrapper.java b/module/forge/src/main/java/net/minecraftforge/common/config/FieldWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/common/config/FieldWrapper.java rename to module/forge/src/main/java/net/minecraftforge/common/config/FieldWrapper.java diff --git a/src/main/java/net/minecraftforge/common/config/IFieldWrapper.java b/module/forge/src/main/java/net/minecraftforge/common/config/IFieldWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/common/config/IFieldWrapper.java rename to module/forge/src/main/java/net/minecraftforge/common/config/IFieldWrapper.java diff --git a/src/main/java/net/minecraftforge/common/config/ITypeAdapter.java b/module/forge/src/main/java/net/minecraftforge/common/config/ITypeAdapter.java similarity index 100% rename from src/main/java/net/minecraftforge/common/config/ITypeAdapter.java rename to module/forge/src/main/java/net/minecraftforge/common/config/ITypeAdapter.java diff --git a/src/main/java/net/minecraftforge/common/config/Property.java b/module/forge/src/main/java/net/minecraftforge/common/config/Property.java similarity index 100% rename from src/main/java/net/minecraftforge/common/config/Property.java rename to module/forge/src/main/java/net/minecraftforge/common/config/Property.java diff --git a/src/main/java/net/minecraftforge/common/config/TypeAdapters.java b/module/forge/src/main/java/net/minecraftforge/common/config/TypeAdapters.java similarity index 100% rename from src/main/java/net/minecraftforge/common/config/TypeAdapters.java rename to module/forge/src/main/java/net/minecraftforge/common/config/TypeAdapters.java diff --git a/src/main/java/net/minecraftforge/common/crafting/CompoundIngredient.java b/module/forge/src/main/java/net/minecraftforge/common/crafting/CompoundIngredient.java similarity index 100% rename from src/main/java/net/minecraftforge/common/crafting/CompoundIngredient.java rename to module/forge/src/main/java/net/minecraftforge/common/crafting/CompoundIngredient.java diff --git a/src/main/java/net/minecraftforge/common/crafting/CraftingHelper.java b/module/forge/src/main/java/net/minecraftforge/common/crafting/CraftingHelper.java similarity index 100% rename from src/main/java/net/minecraftforge/common/crafting/CraftingHelper.java rename to module/forge/src/main/java/net/minecraftforge/common/crafting/CraftingHelper.java diff --git a/src/main/java/net/minecraftforge/common/crafting/IConditionFactory.java b/module/forge/src/main/java/net/minecraftforge/common/crafting/IConditionFactory.java similarity index 100% rename from src/main/java/net/minecraftforge/common/crafting/IConditionFactory.java rename to module/forge/src/main/java/net/minecraftforge/common/crafting/IConditionFactory.java diff --git a/src/main/java/net/minecraftforge/common/crafting/IIngredientFactory.java b/module/forge/src/main/java/net/minecraftforge/common/crafting/IIngredientFactory.java similarity index 100% rename from src/main/java/net/minecraftforge/common/crafting/IIngredientFactory.java rename to module/forge/src/main/java/net/minecraftforge/common/crafting/IIngredientFactory.java diff --git a/src/main/java/net/minecraftforge/common/crafting/IRecipeContainer.java b/module/forge/src/main/java/net/minecraftforge/common/crafting/IRecipeContainer.java similarity index 100% rename from src/main/java/net/minecraftforge/common/crafting/IRecipeContainer.java rename to module/forge/src/main/java/net/minecraftforge/common/crafting/IRecipeContainer.java diff --git a/src/main/java/net/minecraftforge/common/crafting/IRecipeFactory.java b/module/forge/src/main/java/net/minecraftforge/common/crafting/IRecipeFactory.java similarity index 100% rename from src/main/java/net/minecraftforge/common/crafting/IRecipeFactory.java rename to module/forge/src/main/java/net/minecraftforge/common/crafting/IRecipeFactory.java diff --git a/src/main/java/net/minecraftforge/common/crafting/IShapedRecipe.java b/module/forge/src/main/java/net/minecraftforge/common/crafting/IShapedRecipe.java similarity index 100% rename from src/main/java/net/minecraftforge/common/crafting/IShapedRecipe.java rename to module/forge/src/main/java/net/minecraftforge/common/crafting/IShapedRecipe.java diff --git a/src/main/java/net/minecraftforge/common/crafting/IngredientNBT.java b/module/forge/src/main/java/net/minecraftforge/common/crafting/IngredientNBT.java similarity index 100% rename from src/main/java/net/minecraftforge/common/crafting/IngredientNBT.java rename to module/forge/src/main/java/net/minecraftforge/common/crafting/IngredientNBT.java diff --git a/src/main/java/net/minecraftforge/common/crafting/JsonContext.java b/module/forge/src/main/java/net/minecraftforge/common/crafting/JsonContext.java similarity index 100% rename from src/main/java/net/minecraftforge/common/crafting/JsonContext.java rename to module/forge/src/main/java/net/minecraftforge/common/crafting/JsonContext.java diff --git a/src/main/java/net/minecraftforge/common/model/HiddenModelPart.java b/module/forge/src/main/java/net/minecraftforge/common/model/HiddenModelPart.java similarity index 100% rename from src/main/java/net/minecraftforge/common/model/HiddenModelPart.java rename to module/forge/src/main/java/net/minecraftforge/common/model/HiddenModelPart.java diff --git a/src/main/java/net/minecraftforge/common/model/IModelPart.java b/module/forge/src/main/java/net/minecraftforge/common/model/IModelPart.java similarity index 100% rename from src/main/java/net/minecraftforge/common/model/IModelPart.java rename to module/forge/src/main/java/net/minecraftforge/common/model/IModelPart.java diff --git a/src/main/java/net/minecraftforge/common/model/IModelState.java b/module/forge/src/main/java/net/minecraftforge/common/model/IModelState.java similarity index 100% rename from src/main/java/net/minecraftforge/common/model/IModelState.java rename to module/forge/src/main/java/net/minecraftforge/common/model/IModelState.java diff --git a/src/main/java/net/minecraftforge/common/model/ITransformation.java b/module/forge/src/main/java/net/minecraftforge/common/model/ITransformation.java similarity index 100% rename from src/main/java/net/minecraftforge/common/model/ITransformation.java rename to module/forge/src/main/java/net/minecraftforge/common/model/ITransformation.java diff --git a/src/main/java/net/minecraftforge/common/model/Models.java b/module/forge/src/main/java/net/minecraftforge/common/model/Models.java similarity index 100% rename from src/main/java/net/minecraftforge/common/model/Models.java rename to module/forge/src/main/java/net/minecraftforge/common/model/Models.java diff --git a/src/main/java/net/minecraftforge/common/model/TRSRTransformation.java b/module/forge/src/main/java/net/minecraftforge/common/model/TRSRTransformation.java similarity index 100% rename from src/main/java/net/minecraftforge/common/model/TRSRTransformation.java rename to module/forge/src/main/java/net/minecraftforge/common/model/TRSRTransformation.java diff --git a/src/main/java/net/minecraftforge/common/model/animation/AnimationStateMachine.java b/module/forge/src/main/java/net/minecraftforge/common/model/animation/AnimationStateMachine.java similarity index 100% rename from src/main/java/net/minecraftforge/common/model/animation/AnimationStateMachine.java rename to module/forge/src/main/java/net/minecraftforge/common/model/animation/AnimationStateMachine.java diff --git a/src/main/java/net/minecraftforge/common/model/animation/CapabilityAnimation.java b/module/forge/src/main/java/net/minecraftforge/common/model/animation/CapabilityAnimation.java similarity index 100% rename from src/main/java/net/minecraftforge/common/model/animation/CapabilityAnimation.java rename to module/forge/src/main/java/net/minecraftforge/common/model/animation/CapabilityAnimation.java diff --git a/src/main/java/net/minecraftforge/common/model/animation/Clips.java b/module/forge/src/main/java/net/minecraftforge/common/model/animation/Clips.java similarity index 100% rename from src/main/java/net/minecraftforge/common/model/animation/Clips.java rename to module/forge/src/main/java/net/minecraftforge/common/model/animation/Clips.java diff --git a/src/main/java/net/minecraftforge/common/model/animation/IAnimationStateMachine.java b/module/forge/src/main/java/net/minecraftforge/common/model/animation/IAnimationStateMachine.java similarity index 100% rename from src/main/java/net/minecraftforge/common/model/animation/IAnimationStateMachine.java rename to module/forge/src/main/java/net/minecraftforge/common/model/animation/IAnimationStateMachine.java diff --git a/src/main/java/net/minecraftforge/common/model/animation/IClip.java b/module/forge/src/main/java/net/minecraftforge/common/model/animation/IClip.java similarity index 100% rename from src/main/java/net/minecraftforge/common/model/animation/IClip.java rename to module/forge/src/main/java/net/minecraftforge/common/model/animation/IClip.java diff --git a/src/main/java/net/minecraftforge/common/model/animation/IJoint.java b/module/forge/src/main/java/net/minecraftforge/common/model/animation/IJoint.java similarity index 100% rename from src/main/java/net/minecraftforge/common/model/animation/IJoint.java rename to module/forge/src/main/java/net/minecraftforge/common/model/animation/IJoint.java diff --git a/src/main/java/net/minecraftforge/common/model/animation/IJointClip.java b/module/forge/src/main/java/net/minecraftforge/common/model/animation/IJointClip.java similarity index 100% rename from src/main/java/net/minecraftforge/common/model/animation/IJointClip.java rename to module/forge/src/main/java/net/minecraftforge/common/model/animation/IJointClip.java diff --git a/src/main/java/net/minecraftforge/common/model/animation/JointClips.java b/module/forge/src/main/java/net/minecraftforge/common/model/animation/JointClips.java similarity index 100% rename from src/main/java/net/minecraftforge/common/model/animation/JointClips.java rename to module/forge/src/main/java/net/minecraftforge/common/model/animation/JointClips.java diff --git a/src/main/java/net/minecraftforge/common/network/DimensionMessageHandler.java b/module/forge/src/main/java/net/minecraftforge/common/network/DimensionMessageHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/common/network/DimensionMessageHandler.java rename to module/forge/src/main/java/net/minecraftforge/common/network/DimensionMessageHandler.java diff --git a/src/main/java/net/minecraftforge/common/network/FluidIdRegistryMessageHandler.java b/module/forge/src/main/java/net/minecraftforge/common/network/FluidIdRegistryMessageHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/common/network/FluidIdRegistryMessageHandler.java rename to module/forge/src/main/java/net/minecraftforge/common/network/FluidIdRegistryMessageHandler.java diff --git a/src/main/java/net/minecraftforge/common/network/ForgeMessage.java b/module/forge/src/main/java/net/minecraftforge/common/network/ForgeMessage.java similarity index 100% rename from src/main/java/net/minecraftforge/common/network/ForgeMessage.java rename to module/forge/src/main/java/net/minecraftforge/common/network/ForgeMessage.java diff --git a/src/main/java/net/minecraftforge/common/network/ForgeNetworkHandler.java b/module/forge/src/main/java/net/minecraftforge/common/network/ForgeNetworkHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/common/network/ForgeNetworkHandler.java rename to module/forge/src/main/java/net/minecraftforge/common/network/ForgeNetworkHandler.java diff --git a/src/main/java/net/minecraftforge/common/network/ForgeRuntimeCodec.java b/module/forge/src/main/java/net/minecraftforge/common/network/ForgeRuntimeCodec.java similarity index 100% rename from src/main/java/net/minecraftforge/common/network/ForgeRuntimeCodec.java rename to module/forge/src/main/java/net/minecraftforge/common/network/ForgeRuntimeCodec.java diff --git a/src/main/java/net/minecraftforge/common/network/ServerToClientConnectionEstablishedHandler.java b/module/forge/src/main/java/net/minecraftforge/common/network/ServerToClientConnectionEstablishedHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/common/network/ServerToClientConnectionEstablishedHandler.java rename to module/forge/src/main/java/net/minecraftforge/common/network/ServerToClientConnectionEstablishedHandler.java diff --git a/src/main/java/net/minecraftforge/common/property/ExtendedBlockState.java b/module/forge/src/main/java/net/minecraftforge/common/property/ExtendedBlockState.java similarity index 100% rename from src/main/java/net/minecraftforge/common/property/ExtendedBlockState.java rename to module/forge/src/main/java/net/minecraftforge/common/property/ExtendedBlockState.java diff --git a/src/main/java/net/minecraftforge/common/property/IExtendedBlockState.java b/module/forge/src/main/java/net/minecraftforge/common/property/IExtendedBlockState.java similarity index 100% rename from src/main/java/net/minecraftforge/common/property/IExtendedBlockState.java rename to module/forge/src/main/java/net/minecraftforge/common/property/IExtendedBlockState.java diff --git a/src/main/java/net/minecraftforge/common/property/IUnlistedProperty.java b/module/forge/src/main/java/net/minecraftforge/common/property/IUnlistedProperty.java similarity index 100% rename from src/main/java/net/minecraftforge/common/property/IUnlistedProperty.java rename to module/forge/src/main/java/net/minecraftforge/common/property/IUnlistedProperty.java diff --git a/src/main/java/net/minecraftforge/common/property/Properties.java b/module/forge/src/main/java/net/minecraftforge/common/property/Properties.java similarity index 100% rename from src/main/java/net/minecraftforge/common/property/Properties.java rename to module/forge/src/main/java/net/minecraftforge/common/property/Properties.java diff --git a/src/main/java/net/minecraftforge/common/property/PropertyFloat.java b/module/forge/src/main/java/net/minecraftforge/common/property/PropertyFloat.java similarity index 100% rename from src/main/java/net/minecraftforge/common/property/PropertyFloat.java rename to module/forge/src/main/java/net/minecraftforge/common/property/PropertyFloat.java diff --git a/src/main/java/net/minecraftforge/common/ticket/AABBTicket.java b/module/forge/src/main/java/net/minecraftforge/common/ticket/AABBTicket.java similarity index 100% rename from src/main/java/net/minecraftforge/common/ticket/AABBTicket.java rename to module/forge/src/main/java/net/minecraftforge/common/ticket/AABBTicket.java diff --git a/src/main/java/net/minecraftforge/common/ticket/ChunkTicketManager.java b/module/forge/src/main/java/net/minecraftforge/common/ticket/ChunkTicketManager.java similarity index 100% rename from src/main/java/net/minecraftforge/common/ticket/ChunkTicketManager.java rename to module/forge/src/main/java/net/minecraftforge/common/ticket/ChunkTicketManager.java diff --git a/src/main/java/net/minecraftforge/common/ticket/ITicketGetter.java b/module/forge/src/main/java/net/minecraftforge/common/ticket/ITicketGetter.java similarity index 100% rename from src/main/java/net/minecraftforge/common/ticket/ITicketGetter.java rename to module/forge/src/main/java/net/minecraftforge/common/ticket/ITicketGetter.java diff --git a/src/main/java/net/minecraftforge/common/ticket/ITicketManager.java b/module/forge/src/main/java/net/minecraftforge/common/ticket/ITicketManager.java similarity index 100% rename from src/main/java/net/minecraftforge/common/ticket/ITicketManager.java rename to module/forge/src/main/java/net/minecraftforge/common/ticket/ITicketManager.java diff --git a/src/main/java/net/minecraftforge/common/ticket/MultiTicketManager.java b/module/forge/src/main/java/net/minecraftforge/common/ticket/MultiTicketManager.java similarity index 100% rename from src/main/java/net/minecraftforge/common/ticket/MultiTicketManager.java rename to module/forge/src/main/java/net/minecraftforge/common/ticket/MultiTicketManager.java diff --git a/src/main/java/net/minecraftforge/common/ticket/SimpleTicket.java b/module/forge/src/main/java/net/minecraftforge/common/ticket/SimpleTicket.java similarity index 100% rename from src/main/java/net/minecraftforge/common/ticket/SimpleTicket.java rename to module/forge/src/main/java/net/minecraftforge/common/ticket/SimpleTicket.java diff --git a/src/main/java/net/minecraftforge/common/util/BlockSnapshot.java b/module/forge/src/main/java/net/minecraftforge/common/util/BlockSnapshot.java similarity index 100% rename from src/main/java/net/minecraftforge/common/util/BlockSnapshot.java rename to module/forge/src/main/java/net/minecraftforge/common/util/BlockSnapshot.java diff --git a/src/main/java/net/minecraftforge/common/util/ChunkCoordComparator.java b/module/forge/src/main/java/net/minecraftforge/common/util/ChunkCoordComparator.java similarity index 100% rename from src/main/java/net/minecraftforge/common/util/ChunkCoordComparator.java rename to module/forge/src/main/java/net/minecraftforge/common/util/ChunkCoordComparator.java diff --git a/src/main/java/net/minecraftforge/common/util/CompoundDataFixer.java b/module/forge/src/main/java/net/minecraftforge/common/util/CompoundDataFixer.java similarity index 100% rename from src/main/java/net/minecraftforge/common/util/CompoundDataFixer.java rename to module/forge/src/main/java/net/minecraftforge/common/util/CompoundDataFixer.java diff --git a/src/main/java/net/minecraftforge/common/util/Constants.java b/module/forge/src/main/java/net/minecraftforge/common/util/Constants.java similarity index 100% rename from src/main/java/net/minecraftforge/common/util/Constants.java rename to module/forge/src/main/java/net/minecraftforge/common/util/Constants.java diff --git a/src/main/java/net/minecraftforge/common/util/EnumHelper.java b/module/forge/src/main/java/net/minecraftforge/common/util/EnumHelper.java similarity index 100% rename from src/main/java/net/minecraftforge/common/util/EnumHelper.java rename to module/forge/src/main/java/net/minecraftforge/common/util/EnumHelper.java diff --git a/src/main/java/net/minecraftforge/common/util/FakePlayer.java b/module/forge/src/main/java/net/minecraftforge/common/util/FakePlayer.java similarity index 100% rename from src/main/java/net/minecraftforge/common/util/FakePlayer.java rename to module/forge/src/main/java/net/minecraftforge/common/util/FakePlayer.java diff --git a/src/main/java/net/minecraftforge/common/util/FakePlayerFactory.java b/module/forge/src/main/java/net/minecraftforge/common/util/FakePlayerFactory.java similarity index 100% rename from src/main/java/net/minecraftforge/common/util/FakePlayerFactory.java rename to module/forge/src/main/java/net/minecraftforge/common/util/FakePlayerFactory.java diff --git a/src/main/java/net/minecraftforge/common/util/IDataFixerData.java b/module/forge/src/main/java/net/minecraftforge/common/util/IDataFixerData.java similarity index 100% rename from src/main/java/net/minecraftforge/common/util/IDataFixerData.java rename to module/forge/src/main/java/net/minecraftforge/common/util/IDataFixerData.java diff --git a/src/main/java/net/minecraftforge/common/util/INBTSerializable.java b/module/forge/src/main/java/net/minecraftforge/common/util/INBTSerializable.java similarity index 100% rename from src/main/java/net/minecraftforge/common/util/INBTSerializable.java rename to module/forge/src/main/java/net/minecraftforge/common/util/INBTSerializable.java diff --git a/src/main/java/net/minecraftforge/common/util/ITeleporter.java b/module/forge/src/main/java/net/minecraftforge/common/util/ITeleporter.java similarity index 100% rename from src/main/java/net/minecraftforge/common/util/ITeleporter.java rename to module/forge/src/main/java/net/minecraftforge/common/util/ITeleporter.java diff --git a/src/main/java/net/minecraftforge/common/util/JsonUtils.java b/module/forge/src/main/java/net/minecraftforge/common/util/JsonUtils.java similarity index 100% rename from src/main/java/net/minecraftforge/common/util/JsonUtils.java rename to module/forge/src/main/java/net/minecraftforge/common/util/JsonUtils.java diff --git a/src/main/java/net/minecraftforge/common/util/ModFixs.java b/module/forge/src/main/java/net/minecraftforge/common/util/ModFixs.java similarity index 100% rename from src/main/java/net/minecraftforge/common/util/ModFixs.java rename to module/forge/src/main/java/net/minecraftforge/common/util/ModFixs.java diff --git a/src/main/java/net/minecraftforge/common/util/PacketUtil.java b/module/forge/src/main/java/net/minecraftforge/common/util/PacketUtil.java similarity index 100% rename from src/main/java/net/minecraftforge/common/util/PacketUtil.java rename to module/forge/src/main/java/net/minecraftforge/common/util/PacketUtil.java diff --git a/src/main/java/net/minecraftforge/common/util/RecipeMatcher.java b/module/forge/src/main/java/net/minecraftforge/common/util/RecipeMatcher.java similarity index 100% rename from src/main/java/net/minecraftforge/common/util/RecipeMatcher.java rename to module/forge/src/main/java/net/minecraftforge/common/util/RecipeMatcher.java diff --git a/src/main/java/net/minecraftforge/common/util/TextTable.java b/module/forge/src/main/java/net/minecraftforge/common/util/TextTable.java similarity index 100% rename from src/main/java/net/minecraftforge/common/util/TextTable.java rename to module/forge/src/main/java/net/minecraftforge/common/util/TextTable.java diff --git a/src/main/java/net/minecraftforge/common/util/WorldCapabilityData.java b/module/forge/src/main/java/net/minecraftforge/common/util/WorldCapabilityData.java similarity index 100% rename from src/main/java/net/minecraftforge/common/util/WorldCapabilityData.java rename to module/forge/src/main/java/net/minecraftforge/common/util/WorldCapabilityData.java diff --git a/src/main/java/net/minecraftforge/energy/CapabilityEnergy.java b/module/forge/src/main/java/net/minecraftforge/energy/CapabilityEnergy.java similarity index 100% rename from src/main/java/net/minecraftforge/energy/CapabilityEnergy.java rename to module/forge/src/main/java/net/minecraftforge/energy/CapabilityEnergy.java diff --git a/src/main/java/net/minecraftforge/energy/EnergyStorage.java b/module/forge/src/main/java/net/minecraftforge/energy/EnergyStorage.java similarity index 100% rename from src/main/java/net/minecraftforge/energy/EnergyStorage.java rename to module/forge/src/main/java/net/minecraftforge/energy/EnergyStorage.java diff --git a/src/main/java/net/minecraftforge/energy/IEnergyStorage.java b/module/forge/src/main/java/net/minecraftforge/energy/IEnergyStorage.java similarity index 100% rename from src/main/java/net/minecraftforge/energy/IEnergyStorage.java rename to module/forge/src/main/java/net/minecraftforge/energy/IEnergyStorage.java diff --git a/src/main/java/net/minecraftforge/event/AnvilUpdateEvent.java b/module/forge/src/main/java/net/minecraftforge/event/AnvilUpdateEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/AnvilUpdateEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/AnvilUpdateEvent.java diff --git a/src/main/java/net/minecraftforge/event/AttachCapabilitiesEvent.java b/module/forge/src/main/java/net/minecraftforge/event/AttachCapabilitiesEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/AttachCapabilitiesEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/AttachCapabilitiesEvent.java diff --git a/src/main/java/net/minecraftforge/event/CommandEvent.java b/module/forge/src/main/java/net/minecraftforge/event/CommandEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/CommandEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/CommandEvent.java diff --git a/src/main/java/net/minecraftforge/event/DifficultyChangeEvent.java b/module/forge/src/main/java/net/minecraftforge/event/DifficultyChangeEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/DifficultyChangeEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/DifficultyChangeEvent.java diff --git a/src/main/java/net/minecraftforge/event/ForgeEventFactory.java b/module/forge/src/main/java/net/minecraftforge/event/ForgeEventFactory.java similarity index 100% rename from src/main/java/net/minecraftforge/event/ForgeEventFactory.java rename to module/forge/src/main/java/net/minecraftforge/event/ForgeEventFactory.java diff --git a/src/main/java/net/minecraftforge/event/GameRuleChangeEvent.java b/module/forge/src/main/java/net/minecraftforge/event/GameRuleChangeEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/GameRuleChangeEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/GameRuleChangeEvent.java diff --git a/src/main/java/net/minecraftforge/event/LootTableLoadEvent.java b/module/forge/src/main/java/net/minecraftforge/event/LootTableLoadEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/LootTableLoadEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/LootTableLoadEvent.java diff --git a/src/main/java/net/minecraftforge/event/RegistryEvent.java b/module/forge/src/main/java/net/minecraftforge/event/RegistryEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/RegistryEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/RegistryEvent.java diff --git a/src/main/java/net/minecraftforge/event/ServerChatEvent.java b/module/forge/src/main/java/net/minecraftforge/event/ServerChatEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/ServerChatEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/ServerChatEvent.java diff --git a/src/main/java/net/minecraftforge/event/brewing/PlayerBrewedPotionEvent.java b/module/forge/src/main/java/net/minecraftforge/event/brewing/PlayerBrewedPotionEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/brewing/PlayerBrewedPotionEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/brewing/PlayerBrewedPotionEvent.java diff --git a/src/main/java/net/minecraftforge/event/brewing/PotionBrewEvent.java b/module/forge/src/main/java/net/minecraftforge/event/brewing/PotionBrewEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/brewing/PotionBrewEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/brewing/PotionBrewEvent.java diff --git a/src/main/java/net/minecraftforge/event/enchanting/EnchantmentLevelSetEvent.java b/module/forge/src/main/java/net/minecraftforge/event/enchanting/EnchantmentLevelSetEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/enchanting/EnchantmentLevelSetEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/enchanting/EnchantmentLevelSetEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/EntityEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/EntityEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/EntityEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/EntityEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/EntityJoinWorldEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/EntityJoinWorldEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/EntityJoinWorldEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/EntityJoinWorldEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/EntityMobGriefingEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/EntityMobGriefingEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/EntityMobGriefingEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/EntityMobGriefingEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/EntityMountEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/EntityMountEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/EntityMountEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/EntityMountEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/EntityStruckByLightningEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/EntityStruckByLightningEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/EntityStruckByLightningEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/EntityStruckByLightningEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/EntityTravelToDimensionEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/EntityTravelToDimensionEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/EntityTravelToDimensionEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/EntityTravelToDimensionEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/PlaySoundAtEntityEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/PlaySoundAtEntityEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/PlaySoundAtEntityEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/PlaySoundAtEntityEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/ProjectileImpactEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/ProjectileImpactEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/ProjectileImpactEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/ProjectileImpactEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/ThrowableImpactEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/ThrowableImpactEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/ThrowableImpactEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/ThrowableImpactEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/item/ItemEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/item/ItemEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/item/ItemEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/item/ItemEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/item/ItemExpireEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/item/ItemExpireEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/item/ItemExpireEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/item/ItemExpireEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/item/ItemTossEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/item/ItemTossEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/item/ItemTossEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/item/ItemTossEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/AnimalTameEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/AnimalTameEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/AnimalTameEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/AnimalTameEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/BabyEntitySpawnEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/BabyEntitySpawnEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/BabyEntitySpawnEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/BabyEntitySpawnEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/EnderTeleportEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/EnderTeleportEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/EnderTeleportEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/EnderTeleportEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingAttackEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingAttackEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/LivingAttackEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingAttackEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingDamageEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingDamageEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/LivingDamageEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingDamageEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingDeathEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingDeathEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/LivingDeathEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingDeathEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingDestroyBlockEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingDestroyBlockEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/LivingDestroyBlockEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingDestroyBlockEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingDropsEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingDropsEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/LivingDropsEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingDropsEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingEntityUseItemEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingEntityUseItemEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/LivingEntityUseItemEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingEntityUseItemEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingEquipmentChangeEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingEquipmentChangeEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/LivingEquipmentChangeEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingEquipmentChangeEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/LivingEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingExperienceDropEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingExperienceDropEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/LivingExperienceDropEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingExperienceDropEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingFallEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingFallEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/LivingFallEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingFallEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingHealEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingHealEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/LivingHealEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingHealEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingHurtEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingHurtEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/LivingHurtEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingHurtEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingKnockBackEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingKnockBackEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/LivingKnockBackEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingKnockBackEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingPackSizeEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingPackSizeEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/LivingPackSizeEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingPackSizeEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingSetAttackTargetEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingSetAttackTargetEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/LivingSetAttackTargetEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingSetAttackTargetEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingSpawnEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingSpawnEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/LivingSpawnEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/LivingSpawnEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/LootingLevelEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/LootingLevelEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/LootingLevelEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/LootingLevelEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/PotionColorCalculationEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/PotionColorCalculationEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/PotionColorCalculationEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/PotionColorCalculationEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/PotionEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/PotionEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/PotionEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/PotionEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/living/ZombieEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/living/ZombieEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/living/ZombieEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/living/ZombieEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/minecart/MinecartCollisionEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/minecart/MinecartCollisionEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/minecart/MinecartCollisionEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/minecart/MinecartCollisionEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/minecart/MinecartEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/minecart/MinecartEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/minecart/MinecartEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/minecart/MinecartEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/minecart/MinecartInteractEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/minecart/MinecartInteractEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/minecart/MinecartInteractEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/minecart/MinecartInteractEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/minecart/MinecartUpdateEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/minecart/MinecartUpdateEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/minecart/MinecartUpdateEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/minecart/MinecartUpdateEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/AdvancementEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/AdvancementEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/AdvancementEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/AdvancementEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/AnvilRepairEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/AnvilRepairEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/AnvilRepairEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/AnvilRepairEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/ArrowLooseEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/ArrowLooseEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/ArrowLooseEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/ArrowLooseEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/ArrowNockEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/ArrowNockEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/ArrowNockEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/ArrowNockEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/AttackEntityEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/AttackEntityEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/AttackEntityEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/AttackEntityEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/BonemealEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/BonemealEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/BonemealEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/BonemealEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/CriticalHitEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/CriticalHitEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/CriticalHitEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/CriticalHitEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/EntityItemPickupEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/EntityItemPickupEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/EntityItemPickupEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/EntityItemPickupEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/FillBucketEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/FillBucketEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/FillBucketEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/FillBucketEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/ItemFishedEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/ItemFishedEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/ItemFishedEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/ItemFishedEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/ItemTooltipEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/ItemTooltipEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/ItemTooltipEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/ItemTooltipEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/PlayerContainerEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerContainerEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/PlayerContainerEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerContainerEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/PlayerDestroyItemEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerDestroyItemEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/PlayerDestroyItemEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerDestroyItemEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/PlayerDropsEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerDropsEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/PlayerDropsEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerDropsEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/PlayerEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/PlayerEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/PlayerFlyableFallEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerFlyableFallEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/PlayerFlyableFallEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerFlyableFallEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/PlayerInteractEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerInteractEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/PlayerInteractEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerInteractEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/PlayerPickupXpEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerPickupXpEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/PlayerPickupXpEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerPickupXpEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/PlayerSetSpawnEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerSetSpawnEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/PlayerSetSpawnEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerSetSpawnEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/PlayerSleepInBedEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerSleepInBedEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/PlayerSleepInBedEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerSleepInBedEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/PlayerWakeUpEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerWakeUpEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/PlayerWakeUpEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/PlayerWakeUpEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/SleepingLocationCheckEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/SleepingLocationCheckEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/SleepingLocationCheckEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/SleepingLocationCheckEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/SleepingTimeCheckEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/SleepingTimeCheckEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/SleepingTimeCheckEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/SleepingTimeCheckEvent.java diff --git a/src/main/java/net/minecraftforge/event/entity/player/UseHoeEvent.java b/module/forge/src/main/java/net/minecraftforge/event/entity/player/UseHoeEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/entity/player/UseHoeEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/entity/player/UseHoeEvent.java diff --git a/src/main/java/net/minecraftforge/event/furnace/FurnaceFuelBurnTimeEvent.java b/module/forge/src/main/java/net/minecraftforge/event/furnace/FurnaceFuelBurnTimeEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/furnace/FurnaceFuelBurnTimeEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/furnace/FurnaceFuelBurnTimeEvent.java diff --git a/src/main/java/net/minecraftforge/event/terraingen/BiomeEvent.java b/module/forge/src/main/java/net/minecraftforge/event/terraingen/BiomeEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/terraingen/BiomeEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/terraingen/BiomeEvent.java diff --git a/src/main/java/net/minecraftforge/event/terraingen/ChunkGeneratorEvent.java b/module/forge/src/main/java/net/minecraftforge/event/terraingen/ChunkGeneratorEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/terraingen/ChunkGeneratorEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/terraingen/ChunkGeneratorEvent.java diff --git a/src/main/java/net/minecraftforge/event/terraingen/DecorateBiomeEvent.java b/module/forge/src/main/java/net/minecraftforge/event/terraingen/DecorateBiomeEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/terraingen/DecorateBiomeEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/terraingen/DecorateBiomeEvent.java diff --git a/src/main/java/net/minecraftforge/event/terraingen/DeferredBiomeDecorator.java b/module/forge/src/main/java/net/minecraftforge/event/terraingen/DeferredBiomeDecorator.java similarity index 100% rename from src/main/java/net/minecraftforge/event/terraingen/DeferredBiomeDecorator.java rename to module/forge/src/main/java/net/minecraftforge/event/terraingen/DeferredBiomeDecorator.java diff --git a/src/main/java/net/minecraftforge/event/terraingen/InitMapGenEvent.java b/module/forge/src/main/java/net/minecraftforge/event/terraingen/InitMapGenEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/terraingen/InitMapGenEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/terraingen/InitMapGenEvent.java diff --git a/src/main/java/net/minecraftforge/event/terraingen/InitNoiseGensEvent.java b/module/forge/src/main/java/net/minecraftforge/event/terraingen/InitNoiseGensEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/terraingen/InitNoiseGensEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/terraingen/InitNoiseGensEvent.java diff --git a/src/main/java/net/minecraftforge/event/terraingen/OreGenEvent.java b/module/forge/src/main/java/net/minecraftforge/event/terraingen/OreGenEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/terraingen/OreGenEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/terraingen/OreGenEvent.java diff --git a/src/main/java/net/minecraftforge/event/terraingen/PopulateChunkEvent.java b/module/forge/src/main/java/net/minecraftforge/event/terraingen/PopulateChunkEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/terraingen/PopulateChunkEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/terraingen/PopulateChunkEvent.java diff --git a/src/main/java/net/minecraftforge/event/terraingen/SaplingGrowTreeEvent.java b/module/forge/src/main/java/net/minecraftforge/event/terraingen/SaplingGrowTreeEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/terraingen/SaplingGrowTreeEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/terraingen/SaplingGrowTreeEvent.java diff --git a/src/main/java/net/minecraftforge/event/terraingen/TerrainGen.java b/module/forge/src/main/java/net/minecraftforge/event/terraingen/TerrainGen.java similarity index 100% rename from src/main/java/net/minecraftforge/event/terraingen/TerrainGen.java rename to module/forge/src/main/java/net/minecraftforge/event/terraingen/TerrainGen.java diff --git a/src/main/java/net/minecraftforge/event/terraingen/WorldTypeEvent.java b/module/forge/src/main/java/net/minecraftforge/event/terraingen/WorldTypeEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/terraingen/WorldTypeEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/terraingen/WorldTypeEvent.java diff --git a/src/main/java/net/minecraftforge/event/village/MerchantTradeOffersEvent.java b/module/forge/src/main/java/net/minecraftforge/event/village/MerchantTradeOffersEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/village/MerchantTradeOffersEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/village/MerchantTradeOffersEvent.java diff --git a/src/main/java/net/minecraftforge/event/village/VillageSiegeEvent.java b/module/forge/src/main/java/net/minecraftforge/event/village/VillageSiegeEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/village/VillageSiegeEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/village/VillageSiegeEvent.java diff --git a/src/main/java/net/minecraftforge/event/world/BlockEvent.java b/module/forge/src/main/java/net/minecraftforge/event/world/BlockEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/world/BlockEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/world/BlockEvent.java diff --git a/src/main/java/net/minecraftforge/event/world/ChunkDataEvent.java b/module/forge/src/main/java/net/minecraftforge/event/world/ChunkDataEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/world/ChunkDataEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/world/ChunkDataEvent.java diff --git a/src/main/java/net/minecraftforge/event/world/ChunkEvent.java b/module/forge/src/main/java/net/minecraftforge/event/world/ChunkEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/world/ChunkEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/world/ChunkEvent.java diff --git a/src/main/java/net/minecraftforge/event/world/ChunkWatchEvent.java b/module/forge/src/main/java/net/minecraftforge/event/world/ChunkWatchEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/world/ChunkWatchEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/world/ChunkWatchEvent.java diff --git a/src/main/java/net/minecraftforge/event/world/ExplosionEvent.java b/module/forge/src/main/java/net/minecraftforge/event/world/ExplosionEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/world/ExplosionEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/world/ExplosionEvent.java diff --git a/src/main/java/net/minecraftforge/event/world/GetCollisionBoxesEvent.java b/module/forge/src/main/java/net/minecraftforge/event/world/GetCollisionBoxesEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/world/GetCollisionBoxesEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/world/GetCollisionBoxesEvent.java diff --git a/src/main/java/net/minecraftforge/event/world/NoteBlockEvent.java b/module/forge/src/main/java/net/minecraftforge/event/world/NoteBlockEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/world/NoteBlockEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/world/NoteBlockEvent.java diff --git a/src/main/java/net/minecraftforge/event/world/WorldEvent.java b/module/forge/src/main/java/net/minecraftforge/event/world/WorldEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/event/world/WorldEvent.java rename to module/forge/src/main/java/net/minecraftforge/event/world/WorldEvent.java diff --git a/src/main/java/net/minecraftforge/fluids/BlockFluidBase.java b/module/forge/src/main/java/net/minecraftforge/fluids/BlockFluidBase.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/BlockFluidBase.java rename to module/forge/src/main/java/net/minecraftforge/fluids/BlockFluidBase.java diff --git a/src/main/java/net/minecraftforge/fluids/BlockFluidClassic.java b/module/forge/src/main/java/net/minecraftforge/fluids/BlockFluidClassic.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/BlockFluidClassic.java rename to module/forge/src/main/java/net/minecraftforge/fluids/BlockFluidClassic.java diff --git a/src/main/java/net/minecraftforge/fluids/BlockFluidFinite.java b/module/forge/src/main/java/net/minecraftforge/fluids/BlockFluidFinite.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/BlockFluidFinite.java rename to module/forge/src/main/java/net/minecraftforge/fluids/BlockFluidFinite.java diff --git a/src/main/java/net/minecraftforge/fluids/DispenseFluidContainer.java b/module/forge/src/main/java/net/minecraftforge/fluids/DispenseFluidContainer.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/DispenseFluidContainer.java rename to module/forge/src/main/java/net/minecraftforge/fluids/DispenseFluidContainer.java diff --git a/src/main/java/net/minecraftforge/fluids/Fluid.java b/module/forge/src/main/java/net/minecraftforge/fluids/Fluid.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/Fluid.java rename to module/forge/src/main/java/net/minecraftforge/fluids/Fluid.java diff --git a/src/main/java/net/minecraftforge/fluids/FluidActionResult.java b/module/forge/src/main/java/net/minecraftforge/fluids/FluidActionResult.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/FluidActionResult.java rename to module/forge/src/main/java/net/minecraftforge/fluids/FluidActionResult.java diff --git a/src/main/java/net/minecraftforge/fluids/FluidEvent.java b/module/forge/src/main/java/net/minecraftforge/fluids/FluidEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/FluidEvent.java rename to module/forge/src/main/java/net/minecraftforge/fluids/FluidEvent.java diff --git a/src/main/java/net/minecraftforge/fluids/FluidRegistry.java b/module/forge/src/main/java/net/minecraftforge/fluids/FluidRegistry.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/FluidRegistry.java rename to module/forge/src/main/java/net/minecraftforge/fluids/FluidRegistry.java diff --git a/src/main/java/net/minecraftforge/fluids/FluidStack.java b/module/forge/src/main/java/net/minecraftforge/fluids/FluidStack.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/FluidStack.java rename to module/forge/src/main/java/net/minecraftforge/fluids/FluidStack.java diff --git a/src/main/java/net/minecraftforge/fluids/FluidTank.java b/module/forge/src/main/java/net/minecraftforge/fluids/FluidTank.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/FluidTank.java rename to module/forge/src/main/java/net/minecraftforge/fluids/FluidTank.java diff --git a/src/main/java/net/minecraftforge/fluids/FluidTankInfo.java b/module/forge/src/main/java/net/minecraftforge/fluids/FluidTankInfo.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/FluidTankInfo.java rename to module/forge/src/main/java/net/minecraftforge/fluids/FluidTankInfo.java diff --git a/src/main/java/net/minecraftforge/fluids/FluidUtil.java b/module/forge/src/main/java/net/minecraftforge/fluids/FluidUtil.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/FluidUtil.java rename to module/forge/src/main/java/net/minecraftforge/fluids/FluidUtil.java diff --git a/src/main/java/net/minecraftforge/fluids/IFluidBlock.java b/module/forge/src/main/java/net/minecraftforge/fluids/IFluidBlock.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/IFluidBlock.java rename to module/forge/src/main/java/net/minecraftforge/fluids/IFluidBlock.java diff --git a/src/main/java/net/minecraftforge/fluids/IFluidTank.java b/module/forge/src/main/java/net/minecraftforge/fluids/IFluidTank.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/IFluidTank.java rename to module/forge/src/main/java/net/minecraftforge/fluids/IFluidTank.java diff --git a/src/main/java/net/minecraftforge/fluids/UniversalBucket.java b/module/forge/src/main/java/net/minecraftforge/fluids/UniversalBucket.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/UniversalBucket.java rename to module/forge/src/main/java/net/minecraftforge/fluids/UniversalBucket.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/CapabilityFluidHandler.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/CapabilityFluidHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/CapabilityFluidHandler.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/CapabilityFluidHandler.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/FluidTankProperties.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/FluidTankProperties.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/FluidTankProperties.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/FluidTankProperties.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/FluidTankPropertiesWrapper.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/FluidTankPropertiesWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/FluidTankPropertiesWrapper.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/FluidTankPropertiesWrapper.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/IFluidHandler.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/IFluidHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/IFluidHandler.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/IFluidHandler.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/IFluidHandlerItem.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/IFluidHandlerItem.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/IFluidHandlerItem.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/IFluidHandlerItem.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/IFluidTankProperties.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/IFluidTankProperties.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/IFluidTankProperties.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/IFluidTankProperties.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/ItemFluidContainer.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/ItemFluidContainer.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/ItemFluidContainer.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/ItemFluidContainer.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/TileFluidHandler.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/TileFluidHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/TileFluidHandler.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/TileFluidHandler.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/templates/EmptyFluidHandler.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/templates/EmptyFluidHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/templates/EmptyFluidHandler.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/templates/EmptyFluidHandler.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerConcatenate.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerConcatenate.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerConcatenate.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerConcatenate.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerFluidMap.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerFluidMap.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerFluidMap.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerFluidMap.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerItemStack.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerItemStack.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerItemStack.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerItemStack.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerItemStackSimple.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerItemStackSimple.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerItemStackSimple.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/templates/FluidHandlerItemStackSimple.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/templates/VoidFluidHandler.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/templates/VoidFluidHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/templates/VoidFluidHandler.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/templates/VoidFluidHandler.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/wrappers/BlockLiquidWrapper.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/wrappers/BlockLiquidWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/wrappers/BlockLiquidWrapper.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/wrappers/BlockLiquidWrapper.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/wrappers/BlockWrapper.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/wrappers/BlockWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/wrappers/BlockWrapper.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/wrappers/BlockWrapper.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/wrappers/FluidBlockWrapper.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/wrappers/FluidBlockWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/wrappers/FluidBlockWrapper.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/wrappers/FluidBlockWrapper.java diff --git a/src/main/java/net/minecraftforge/fluids/capability/wrappers/FluidBucketWrapper.java b/module/forge/src/main/java/net/minecraftforge/fluids/capability/wrappers/FluidBucketWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/fluids/capability/wrappers/FluidBucketWrapper.java rename to module/forge/src/main/java/net/minecraftforge/fluids/capability/wrappers/FluidBucketWrapper.java diff --git a/src/main/java/net/minecraftforge/fml/client/CustomModLoadingErrorDisplayException.java b/module/forge/src/main/java/net/minecraftforge/fml/client/CustomModLoadingErrorDisplayException.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/CustomModLoadingErrorDisplayException.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/CustomModLoadingErrorDisplayException.java diff --git a/src/main/java/net/minecraftforge/fml/client/DefaultGuiFactory.java b/module/forge/src/main/java/net/minecraftforge/fml/client/DefaultGuiFactory.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/DefaultGuiFactory.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/DefaultGuiFactory.java diff --git a/src/main/java/net/minecraftforge/fml/client/ExtendedServerListData.java b/module/forge/src/main/java/net/minecraftforge/fml/client/ExtendedServerListData.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/ExtendedServerListData.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/ExtendedServerListData.java diff --git a/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java diff --git a/src/main/java/net/minecraftforge/fml/client/FMLConfigGuiFactory.java b/module/forge/src/main/java/net/minecraftforge/fml/client/FMLConfigGuiFactory.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/FMLConfigGuiFactory.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/FMLConfigGuiFactory.java diff --git a/src/main/java/net/minecraftforge/fml/client/FMLFileResourcePack.java b/module/forge/src/main/java/net/minecraftforge/fml/client/FMLFileResourcePack.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/FMLFileResourcePack.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/FMLFileResourcePack.java diff --git a/src/main/java/net/minecraftforge/fml/client/FMLFolderResourcePack.java b/module/forge/src/main/java/net/minecraftforge/fml/client/FMLFolderResourcePack.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/FMLFolderResourcePack.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/FMLFolderResourcePack.java diff --git a/src/main/java/net/minecraftforge/fml/client/GuiAccessDenied.java b/module/forge/src/main/java/net/minecraftforge/fml/client/GuiAccessDenied.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/GuiAccessDenied.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/GuiAccessDenied.java diff --git a/src/main/java/net/minecraftforge/fml/client/GuiBackupFailed.java b/module/forge/src/main/java/net/minecraftforge/fml/client/GuiBackupFailed.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/GuiBackupFailed.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/GuiBackupFailed.java diff --git a/src/main/java/net/minecraftforge/fml/client/GuiConfirmation.java b/module/forge/src/main/java/net/minecraftforge/fml/client/GuiConfirmation.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/GuiConfirmation.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/GuiConfirmation.java diff --git a/src/main/java/net/minecraftforge/fml/client/GuiCustomModLoadingErrorScreen.java b/module/forge/src/main/java/net/minecraftforge/fml/client/GuiCustomModLoadingErrorScreen.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/GuiCustomModLoadingErrorScreen.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/GuiCustomModLoadingErrorScreen.java diff --git a/src/main/java/net/minecraftforge/fml/client/GuiDupesFound.java b/module/forge/src/main/java/net/minecraftforge/fml/client/GuiDupesFound.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/GuiDupesFound.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/GuiDupesFound.java diff --git a/src/main/java/net/minecraftforge/fml/client/GuiErrorBase.java b/module/forge/src/main/java/net/minecraftforge/fml/client/GuiErrorBase.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/GuiErrorBase.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/GuiErrorBase.java diff --git a/src/main/java/net/minecraftforge/fml/client/GuiModList.java b/module/forge/src/main/java/net/minecraftforge/fml/client/GuiModList.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/GuiModList.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/GuiModList.java diff --git a/src/main/java/net/minecraftforge/fml/client/GuiModsMissing.java b/module/forge/src/main/java/net/minecraftforge/fml/client/GuiModsMissing.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/GuiModsMissing.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/GuiModsMissing.java diff --git a/src/main/java/net/minecraftforge/fml/client/GuiModsMissingForServer.java b/module/forge/src/main/java/net/minecraftforge/fml/client/GuiModsMissingForServer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/GuiModsMissingForServer.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/GuiModsMissingForServer.java diff --git a/src/main/java/net/minecraftforge/fml/client/GuiMultipleModsErrored.java b/module/forge/src/main/java/net/minecraftforge/fml/client/GuiMultipleModsErrored.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/GuiMultipleModsErrored.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/GuiMultipleModsErrored.java diff --git a/src/main/java/net/minecraftforge/fml/client/GuiNotification.java b/module/forge/src/main/java/net/minecraftforge/fml/client/GuiNotification.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/GuiNotification.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/GuiNotification.java diff --git a/src/main/java/net/minecraftforge/fml/client/GuiOldSaveLoadConfirm.java b/module/forge/src/main/java/net/minecraftforge/fml/client/GuiOldSaveLoadConfirm.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/GuiOldSaveLoadConfirm.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/GuiOldSaveLoadConfirm.java diff --git a/src/main/java/net/minecraftforge/fml/client/GuiScrollingList.java b/module/forge/src/main/java/net/minecraftforge/fml/client/GuiScrollingList.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/GuiScrollingList.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/GuiScrollingList.java diff --git a/src/main/java/net/minecraftforge/fml/client/GuiSlotModList.java b/module/forge/src/main/java/net/minecraftforge/fml/client/GuiSlotModList.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/GuiSlotModList.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/GuiSlotModList.java diff --git a/src/main/java/net/minecraftforge/fml/client/GuiSortingProblem.java b/module/forge/src/main/java/net/minecraftforge/fml/client/GuiSortingProblem.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/GuiSortingProblem.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/GuiSortingProblem.java diff --git a/src/main/java/net/minecraftforge/fml/client/GuiWrongMinecraft.java b/module/forge/src/main/java/net/minecraftforge/fml/client/GuiWrongMinecraft.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/GuiWrongMinecraft.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/GuiWrongMinecraft.java diff --git a/src/main/java/net/minecraftforge/fml/client/IDisplayableError.java b/module/forge/src/main/java/net/minecraftforge/fml/client/IDisplayableError.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/IDisplayableError.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/IDisplayableError.java diff --git a/src/main/java/net/minecraftforge/fml/client/IModGuiFactory.java b/module/forge/src/main/java/net/minecraftforge/fml/client/IModGuiFactory.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/IModGuiFactory.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/IModGuiFactory.java diff --git a/src/main/java/net/minecraftforge/fml/client/SplashProgress.java b/module/forge/src/main/java/net/minecraftforge/fml/client/SplashProgress.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/SplashProgress.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/SplashProgress.java diff --git a/src/main/java/net/minecraftforge/fml/client/config/ConfigGuiType.java b/module/forge/src/main/java/net/minecraftforge/fml/client/config/ConfigGuiType.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/config/ConfigGuiType.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/config/ConfigGuiType.java diff --git a/src/main/java/net/minecraftforge/fml/client/config/DummyConfigElement.java b/module/forge/src/main/java/net/minecraftforge/fml/client/config/DummyConfigElement.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/config/DummyConfigElement.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/config/DummyConfigElement.java diff --git a/src/main/java/net/minecraftforge/fml/client/config/GuiButtonExt.java b/module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiButtonExt.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/config/GuiButtonExt.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiButtonExt.java diff --git a/src/main/java/net/minecraftforge/fml/client/config/GuiCheckBox.java b/module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiCheckBox.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/config/GuiCheckBox.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiCheckBox.java diff --git a/src/main/java/net/minecraftforge/fml/client/config/GuiConfig.java b/module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiConfig.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/config/GuiConfig.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiConfig.java diff --git a/src/main/java/net/minecraftforge/fml/client/config/GuiConfigEntries.java b/module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiConfigEntries.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/config/GuiConfigEntries.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiConfigEntries.java diff --git a/src/main/java/net/minecraftforge/fml/client/config/GuiEditArray.java b/module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiEditArray.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/config/GuiEditArray.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiEditArray.java diff --git a/src/main/java/net/minecraftforge/fml/client/config/GuiEditArrayEntries.java b/module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiEditArrayEntries.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/config/GuiEditArrayEntries.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiEditArrayEntries.java diff --git a/src/main/java/net/minecraftforge/fml/client/config/GuiMessageDialog.java b/module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiMessageDialog.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/config/GuiMessageDialog.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiMessageDialog.java diff --git a/src/main/java/net/minecraftforge/fml/client/config/GuiSelectString.java b/module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiSelectString.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/config/GuiSelectString.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiSelectString.java diff --git a/src/main/java/net/minecraftforge/fml/client/config/GuiSelectStringEntries.java b/module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiSelectStringEntries.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/config/GuiSelectStringEntries.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiSelectStringEntries.java diff --git a/src/main/java/net/minecraftforge/fml/client/config/GuiSlider.java b/module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiSlider.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/config/GuiSlider.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiSlider.java diff --git a/src/main/java/net/minecraftforge/fml/client/config/GuiUnicodeGlyphButton.java b/module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiUnicodeGlyphButton.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/config/GuiUnicodeGlyphButton.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiUnicodeGlyphButton.java diff --git a/src/main/java/net/minecraftforge/fml/client/config/GuiUtils.java b/module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiUtils.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/config/GuiUtils.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/config/GuiUtils.java diff --git a/src/main/java/net/minecraftforge/fml/client/config/HoverChecker.java b/module/forge/src/main/java/net/minecraftforge/fml/client/config/HoverChecker.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/config/HoverChecker.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/config/HoverChecker.java diff --git a/src/main/java/net/minecraftforge/fml/client/config/IConfigElement.java b/module/forge/src/main/java/net/minecraftforge/fml/client/config/IConfigElement.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/config/IConfigElement.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/config/IConfigElement.java diff --git a/src/main/java/net/minecraftforge/fml/client/event/ConfigChangedEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/client/event/ConfigChangedEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/event/ConfigChangedEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/event/ConfigChangedEvent.java diff --git a/src/main/java/net/minecraftforge/fml/client/registry/ClientRegistry.java b/module/forge/src/main/java/net/minecraftforge/fml/client/registry/ClientRegistry.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/registry/ClientRegistry.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/registry/ClientRegistry.java diff --git a/src/main/java/net/minecraftforge/fml/client/registry/IRenderFactory.java b/module/forge/src/main/java/net/minecraftforge/fml/client/registry/IRenderFactory.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/registry/IRenderFactory.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/registry/IRenderFactory.java diff --git a/src/main/java/net/minecraftforge/fml/client/registry/RenderingRegistry.java b/module/forge/src/main/java/net/minecraftforge/fml/client/registry/RenderingRegistry.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/client/registry/RenderingRegistry.java rename to module/forge/src/main/java/net/minecraftforge/fml/client/registry/RenderingRegistry.java diff --git a/src/main/java/net/minecraftforge/fml/common/API.java b/module/forge/src/main/java/net/minecraftforge/fml/common/API.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/API.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/API.java diff --git a/src/main/java/net/minecraftforge/fml/common/AutomaticEventSubscriber.java b/module/forge/src/main/java/net/minecraftforge/fml/common/AutomaticEventSubscriber.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/AutomaticEventSubscriber.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/AutomaticEventSubscriber.java diff --git a/src/main/java/net/minecraftforge/fml/common/CertificateHelper.java b/module/forge/src/main/java/net/minecraftforge/fml/common/CertificateHelper.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/CertificateHelper.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/CertificateHelper.java diff --git a/src/main/java/net/minecraftforge/fml/common/ClassNameUtils.java b/module/forge/src/main/java/net/minecraftforge/fml/common/ClassNameUtils.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/ClassNameUtils.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/ClassNameUtils.java diff --git a/src/main/java/net/minecraftforge/fml/common/DummyModContainer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/DummyModContainer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/DummyModContainer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/DummyModContainer.java diff --git a/src/main/java/net/minecraftforge/fml/common/DuplicateModsFoundException.java b/module/forge/src/main/java/net/minecraftforge/fml/common/DuplicateModsFoundException.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/DuplicateModsFoundException.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/DuplicateModsFoundException.java diff --git a/src/main/java/net/minecraftforge/fml/common/EnhancedRuntimeException.java b/module/forge/src/main/java/net/minecraftforge/fml/common/EnhancedRuntimeException.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/EnhancedRuntimeException.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/EnhancedRuntimeException.java diff --git a/src/main/java/net/minecraftforge/fml/common/FMLCommonHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/FMLCommonHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/FMLCommonHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/FMLCommonHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/FMLContainer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/FMLContainer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/FMLContainer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/FMLContainer.java diff --git a/src/main/java/net/minecraftforge/fml/common/FMLContainerHolder.java b/module/forge/src/main/java/net/minecraftforge/fml/common/FMLContainerHolder.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/FMLContainerHolder.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/FMLContainerHolder.java diff --git a/src/main/java/net/minecraftforge/fml/common/FMLLog.java b/module/forge/src/main/java/net/minecraftforge/fml/common/FMLLog.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/FMLLog.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/FMLLog.java diff --git a/src/main/java/net/minecraftforge/fml/common/FMLModContainer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/FMLModContainer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/FMLModContainer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/FMLModContainer.java diff --git a/src/main/java/net/minecraftforge/fml/common/ICrashCallable.java b/module/forge/src/main/java/net/minecraftforge/fml/common/ICrashCallable.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/ICrashCallable.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/ICrashCallable.java diff --git a/src/main/java/net/minecraftforge/fml/common/IEntitySelectorFactory.java b/module/forge/src/main/java/net/minecraftforge/fml/common/IEntitySelectorFactory.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/IEntitySelectorFactory.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/IEntitySelectorFactory.java diff --git a/src/main/java/net/minecraftforge/fml/common/IFMLHandledException.java b/module/forge/src/main/java/net/minecraftforge/fml/common/IFMLHandledException.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/IFMLHandledException.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/IFMLHandledException.java diff --git a/src/main/java/net/minecraftforge/fml/common/IFMLSidedHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/IFMLSidedHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/IFMLSidedHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/IFMLSidedHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/IFuelHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/IFuelHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/IFuelHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/IFuelHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/ILanguageAdapter.java b/module/forge/src/main/java/net/minecraftforge/fml/common/ILanguageAdapter.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/ILanguageAdapter.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/ILanguageAdapter.java diff --git a/src/main/java/net/minecraftforge/fml/common/IWorldGenerator.java b/module/forge/src/main/java/net/minecraftforge/fml/common/IWorldGenerator.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/IWorldGenerator.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/IWorldGenerator.java diff --git a/src/main/java/net/minecraftforge/fml/common/InjectedModContainer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/InjectedModContainer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/InjectedModContainer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/InjectedModContainer.java diff --git a/src/main/java/net/minecraftforge/fml/common/LoadController.java b/module/forge/src/main/java/net/minecraftforge/fml/common/LoadController.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/LoadController.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/LoadController.java diff --git a/src/main/java/net/minecraftforge/fml/common/Loader.java b/module/forge/src/main/java/net/minecraftforge/fml/common/Loader.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/Loader.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/Loader.java diff --git a/src/main/java/net/minecraftforge/fml/common/LoaderException.java b/module/forge/src/main/java/net/minecraftforge/fml/common/LoaderException.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/LoaderException.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/LoaderException.java diff --git a/src/main/java/net/minecraftforge/fml/common/LoaderExceptionModCrash.java b/module/forge/src/main/java/net/minecraftforge/fml/common/LoaderExceptionModCrash.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/LoaderExceptionModCrash.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/LoaderExceptionModCrash.java diff --git a/src/main/java/net/minecraftforge/fml/common/LoaderState.java b/module/forge/src/main/java/net/minecraftforge/fml/common/LoaderState.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/LoaderState.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/LoaderState.java diff --git a/src/main/java/net/minecraftforge/fml/common/MCPDummyContainer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/MCPDummyContainer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/MCPDummyContainer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/MCPDummyContainer.java diff --git a/src/main/java/net/minecraftforge/fml/common/MetadataCollection.java b/module/forge/src/main/java/net/minecraftforge/fml/common/MetadataCollection.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/MetadataCollection.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/MetadataCollection.java diff --git a/src/main/java/net/minecraftforge/fml/common/MinecraftDummyContainer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/MinecraftDummyContainer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/MinecraftDummyContainer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/MinecraftDummyContainer.java diff --git a/src/main/java/net/minecraftforge/fml/common/MissingModsException.java b/module/forge/src/main/java/net/minecraftforge/fml/common/MissingModsException.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/MissingModsException.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/MissingModsException.java diff --git a/src/main/java/net/minecraftforge/fml/common/Mod.java b/module/forge/src/main/java/net/minecraftforge/fml/common/Mod.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/Mod.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/Mod.java diff --git a/src/main/java/net/minecraftforge/fml/common/ModAPIManager.java b/module/forge/src/main/java/net/minecraftforge/fml/common/ModAPIManager.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/ModAPIManager.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/ModAPIManager.java diff --git a/src/main/java/net/minecraftforge/fml/common/ModClassLoader.java b/module/forge/src/main/java/net/minecraftforge/fml/common/ModClassLoader.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/ModClassLoader.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/ModClassLoader.java diff --git a/src/main/java/net/minecraftforge/fml/common/ModContainer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/ModContainer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/ModContainer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/ModContainer.java diff --git a/src/main/java/net/minecraftforge/fml/common/ModContainerFactory.java b/module/forge/src/main/java/net/minecraftforge/fml/common/ModContainerFactory.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/ModContainerFactory.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/ModContainerFactory.java diff --git a/src/main/java/net/minecraftforge/fml/common/ModMetadata.java b/module/forge/src/main/java/net/minecraftforge/fml/common/ModMetadata.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/ModMetadata.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/ModMetadata.java diff --git a/src/main/java/net/minecraftforge/fml/common/MultipleModsErrored.java b/module/forge/src/main/java/net/minecraftforge/fml/common/MultipleModsErrored.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/MultipleModsErrored.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/MultipleModsErrored.java diff --git a/src/main/java/net/minecraftforge/fml/common/ObfuscationReflectionHelper.java b/module/forge/src/main/java/net/minecraftforge/fml/common/ObfuscationReflectionHelper.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/ObfuscationReflectionHelper.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/ObfuscationReflectionHelper.java diff --git a/src/main/java/net/minecraftforge/fml/common/Optional.java b/module/forge/src/main/java/net/minecraftforge/fml/common/Optional.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/Optional.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/Optional.java diff --git a/src/main/java/net/minecraftforge/fml/common/ProgressManager.java b/module/forge/src/main/java/net/minecraftforge/fml/common/ProgressManager.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/ProgressManager.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/ProgressManager.java diff --git a/src/main/java/net/minecraftforge/fml/common/ProxyInjector.java b/module/forge/src/main/java/net/minecraftforge/fml/common/ProxyInjector.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/ProxyInjector.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/ProxyInjector.java diff --git a/src/main/java/net/minecraftforge/fml/common/SaveInspectionHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/SaveInspectionHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/SaveInspectionHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/SaveInspectionHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/SidedProxy.java b/module/forge/src/main/java/net/minecraftforge/fml/common/SidedProxy.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/SidedProxy.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/SidedProxy.java diff --git a/src/main/java/net/minecraftforge/fml/common/StartupQuery.java b/module/forge/src/main/java/net/minecraftforge/fml/common/StartupQuery.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/StartupQuery.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/StartupQuery.java diff --git a/src/main/java/net/minecraftforge/fml/common/TracingPrintStream.java b/module/forge/src/main/java/net/minecraftforge/fml/common/TracingPrintStream.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/TracingPrintStream.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/TracingPrintStream.java diff --git a/src/main/java/net/minecraftforge/fml/common/WorldAccessContainer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/WorldAccessContainer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/WorldAccessContainer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/WorldAccessContainer.java diff --git a/src/main/java/net/minecraftforge/fml/common/WrongMinecraftVersionException.java b/module/forge/src/main/java/net/minecraftforge/fml/common/WrongMinecraftVersionException.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/WrongMinecraftVersionException.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/WrongMinecraftVersionException.java diff --git a/src/main/java/net/minecraftforge/fml/common/ZipperUtil.java b/module/forge/src/main/java/net/minecraftforge/fml/common/ZipperUtil.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/ZipperUtil.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/ZipperUtil.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/ASMTransformerWrapper.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/ASMTransformerWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/ASMTransformerWrapper.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/ASMTransformerWrapper.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/FMLSanityChecker.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/FMLSanityChecker.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/FMLSanityChecker.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/FMLSanityChecker.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/ReobfuscationMarker.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/ReobfuscationMarker.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/ReobfuscationMarker.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/ReobfuscationMarker.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/AccessTransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/AccessTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/AccessTransformer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/AccessTransformer.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/DeobfuscationTransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/DeobfuscationTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/DeobfuscationTransformer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/DeobfuscationTransformer.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/EventSubscriberTransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/EventSubscriberTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/EventSubscriberTransformer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/EventSubscriberTransformer.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/EventSubscriptionTransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/EventSubscriptionTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/EventSubscriptionTransformer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/EventSubscriptionTransformer.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/FieldRedirectTransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/FieldRedirectTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/FieldRedirectTransformer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/FieldRedirectTransformer.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemBlockSpecialTransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemBlockSpecialTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemBlockSpecialTransformer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemBlockSpecialTransformer.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemBlockTransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemBlockTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemBlockTransformer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemBlockTransformer.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemStackTransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemStackTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemStackTransformer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemStackTransformer.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/LWJGLTransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/LWJGLTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/LWJGLTransformer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/LWJGLTransformer.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/MarkerTransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/MarkerTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/MarkerTransformer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/MarkerTransformer.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/ModAPITransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/ModAPITransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/ModAPITransformer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/ModAPITransformer.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/ModAccessTransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/ModAccessTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/ModAccessTransformer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/ModAccessTransformer.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/PatchingTransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/PatchingTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/PatchingTransformer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/PatchingTransformer.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/PotionEffectTransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/PotionEffectTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/PotionEffectTransformer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/PotionEffectTransformer.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/SideTransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/SideTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/SideTransformer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/SideTransformer.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/SoundEngineFixTransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/SoundEngineFixTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/SoundEngineFixTransformer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/SoundEngineFixTransformer.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/TerminalTransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/TerminalTransformer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/TerminalTransformer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/TerminalTransformer.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/deobf/FMLRemappingAdapter.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/deobf/FMLRemappingAdapter.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/deobf/FMLRemappingAdapter.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/deobf/FMLRemappingAdapter.java diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/deobf/LZMAInputSupplier.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/deobf/LZMAInputSupplier.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/asm/transformers/deobf/LZMAInputSupplier.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/deobf/LZMAInputSupplier.java diff --git a/src/main/java/net/minecraftforge/fml/common/discovery/ASMDataTable.java b/module/forge/src/main/java/net/minecraftforge/fml/common/discovery/ASMDataTable.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/discovery/ASMDataTable.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/discovery/ASMDataTable.java diff --git a/src/main/java/net/minecraftforge/fml/common/discovery/ContainerType.java b/module/forge/src/main/java/net/minecraftforge/fml/common/discovery/ContainerType.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/discovery/ContainerType.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/discovery/ContainerType.java diff --git a/src/main/java/net/minecraftforge/fml/common/discovery/DirectoryDiscoverer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/discovery/DirectoryDiscoverer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/discovery/DirectoryDiscoverer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/discovery/DirectoryDiscoverer.java diff --git a/src/main/java/net/minecraftforge/fml/common/discovery/ITypeDiscoverer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/discovery/ITypeDiscoverer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/discovery/ITypeDiscoverer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/discovery/ITypeDiscoverer.java diff --git a/src/main/java/net/minecraftforge/fml/common/discovery/JarDiscoverer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/discovery/JarDiscoverer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/discovery/JarDiscoverer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/discovery/JarDiscoverer.java diff --git a/src/main/java/net/minecraftforge/fml/common/discovery/ModCandidate.java b/module/forge/src/main/java/net/minecraftforge/fml/common/discovery/ModCandidate.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/discovery/ModCandidate.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/discovery/ModCandidate.java diff --git a/src/main/java/net/minecraftforge/fml/common/discovery/ModDiscoverer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/discovery/ModDiscoverer.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/discovery/ModDiscoverer.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/discovery/ModDiscoverer.java diff --git a/src/main/java/net/minecraftforge/fml/common/discovery/asm/ASMModParser.java b/module/forge/src/main/java/net/minecraftforge/fml/common/discovery/asm/ASMModParser.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/discovery/asm/ASMModParser.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/discovery/asm/ASMModParser.java diff --git a/src/main/java/net/minecraftforge/fml/common/discovery/asm/ModAnnotation.java b/module/forge/src/main/java/net/minecraftforge/fml/common/discovery/asm/ModAnnotation.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/discovery/asm/ModAnnotation.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/discovery/asm/ModAnnotation.java diff --git a/src/main/java/net/minecraftforge/fml/common/discovery/asm/ModAnnotationVisitor.java b/module/forge/src/main/java/net/minecraftforge/fml/common/discovery/asm/ModAnnotationVisitor.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/discovery/asm/ModAnnotationVisitor.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/discovery/asm/ModAnnotationVisitor.java diff --git a/src/main/java/net/minecraftforge/fml/common/discovery/asm/ModClassVisitor.java b/module/forge/src/main/java/net/minecraftforge/fml/common/discovery/asm/ModClassVisitor.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/discovery/asm/ModClassVisitor.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/discovery/asm/ModClassVisitor.java diff --git a/src/main/java/net/minecraftforge/fml/common/discovery/asm/ModFieldVisitor.java b/module/forge/src/main/java/net/minecraftforge/fml/common/discovery/asm/ModFieldVisitor.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/discovery/asm/ModFieldVisitor.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/discovery/asm/ModFieldVisitor.java diff --git a/src/main/java/net/minecraftforge/fml/common/discovery/asm/ModMethodVisitor.java b/module/forge/src/main/java/net/minecraftforge/fml/common/discovery/asm/ModMethodVisitor.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/discovery/asm/ModMethodVisitor.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/discovery/asm/ModMethodVisitor.java diff --git a/src/main/java/net/minecraftforge/fml/common/discovery/json/ASMInfo.java b/module/forge/src/main/java/net/minecraftforge/fml/common/discovery/json/ASMInfo.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/discovery/json/ASMInfo.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/discovery/json/ASMInfo.java diff --git a/src/main/java/net/minecraftforge/fml/common/discovery/json/JsonAnnotationLoader.java b/module/forge/src/main/java/net/minecraftforge/fml/common/discovery/json/JsonAnnotationLoader.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/discovery/json/JsonAnnotationLoader.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/discovery/json/JsonAnnotationLoader.java diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLConstructionEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLConstructionEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/event/FMLConstructionEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLConstructionEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/event/FMLEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLFingerprintViolationEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLFingerprintViolationEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/event/FMLFingerprintViolationEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLFingerprintViolationEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLInitializationEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLInitializationEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/event/FMLInitializationEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLInitializationEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLInterModComms.java b/module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLInterModComms.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/event/FMLInterModComms.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLInterModComms.java diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLLoadCompleteEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLLoadCompleteEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/event/FMLLoadCompleteEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLLoadCompleteEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLLoadEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLLoadEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/event/FMLLoadEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLLoadEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLModDisabledEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLModDisabledEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/event/FMLModDisabledEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLModDisabledEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLModIdMappingEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLModIdMappingEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/event/FMLModIdMappingEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLModIdMappingEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLPostInitializationEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLPostInitializationEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/event/FMLPostInitializationEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLPostInitializationEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLPreInitializationEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLPreInitializationEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/event/FMLPreInitializationEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLPreInitializationEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLServerAboutToStartEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLServerAboutToStartEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/event/FMLServerAboutToStartEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLServerAboutToStartEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLServerStartedEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLServerStartedEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/event/FMLServerStartedEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLServerStartedEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLServerStartingEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLServerStartingEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/event/FMLServerStartingEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLServerStartingEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLServerStoppedEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLServerStoppedEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/event/FMLServerStoppedEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLServerStoppedEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLServerStoppingEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLServerStoppingEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/event/FMLServerStoppingEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLServerStoppingEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLStateEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLStateEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/event/FMLStateEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/event/FMLStateEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/eventhandler/ASMEventHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/ASMEventHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/eventhandler/ASMEventHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/ASMEventHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/eventhandler/Cancelable.java b/module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/Cancelable.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/eventhandler/Cancelable.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/Cancelable.java diff --git a/src/main/java/net/minecraftforge/fml/common/eventhandler/Event.java b/module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/Event.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/eventhandler/Event.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/Event.java diff --git a/src/main/java/net/minecraftforge/fml/common/eventhandler/EventBus.java b/module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/EventBus.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/eventhandler/EventBus.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/EventBus.java diff --git a/src/main/java/net/minecraftforge/fml/common/eventhandler/EventListenerFactory.java b/module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/EventListenerFactory.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/eventhandler/EventListenerFactory.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/EventListenerFactory.java diff --git a/src/main/java/net/minecraftforge/fml/common/eventhandler/EventPriority.java b/module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/EventPriority.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/eventhandler/EventPriority.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/EventPriority.java diff --git a/src/main/java/net/minecraftforge/fml/common/eventhandler/FMLThrowingEventBus.java b/module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/FMLThrowingEventBus.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/eventhandler/FMLThrowingEventBus.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/FMLThrowingEventBus.java diff --git a/src/main/java/net/minecraftforge/fml/common/eventhandler/GenericEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/GenericEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/eventhandler/GenericEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/GenericEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/eventhandler/IContextSetter.java b/module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/IContextSetter.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/eventhandler/IContextSetter.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/IContextSetter.java diff --git a/src/main/java/net/minecraftforge/fml/common/eventhandler/IEventExceptionHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/IEventExceptionHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/eventhandler/IEventExceptionHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/IEventExceptionHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/eventhandler/IEventListener.java b/module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/IEventListener.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/eventhandler/IEventListener.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/IEventListener.java diff --git a/src/main/java/net/minecraftforge/fml/common/eventhandler/IGenericEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/IGenericEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/eventhandler/IGenericEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/IGenericEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/eventhandler/ListenerList.java b/module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/ListenerList.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/eventhandler/ListenerList.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/ListenerList.java diff --git a/src/main/java/net/minecraftforge/fml/common/eventhandler/SubscribeEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/SubscribeEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/eventhandler/SubscribeEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/eventhandler/SubscribeEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/gameevent/InputEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/gameevent/InputEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/gameevent/InputEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/gameevent/InputEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/gameevent/PlayerEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/gameevent/PlayerEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/gameevent/PlayerEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/gameevent/PlayerEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/gameevent/TickEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/gameevent/TickEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/gameevent/TickEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/gameevent/TickEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/launcher/FMLDeobfTweaker.java b/module/forge/src/main/java/net/minecraftforge/fml/common/launcher/FMLDeobfTweaker.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/launcher/FMLDeobfTweaker.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/launcher/FMLDeobfTweaker.java diff --git a/src/main/java/net/minecraftforge/fml/common/launcher/FMLInjectionAndSortingTweaker.java b/module/forge/src/main/java/net/minecraftforge/fml/common/launcher/FMLInjectionAndSortingTweaker.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/launcher/FMLInjectionAndSortingTweaker.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/launcher/FMLInjectionAndSortingTweaker.java diff --git a/src/main/java/net/minecraftforge/fml/common/launcher/FMLServerTweaker.java b/module/forge/src/main/java/net/minecraftforge/fml/common/launcher/FMLServerTweaker.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/launcher/FMLServerTweaker.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/launcher/FMLServerTweaker.java diff --git a/src/main/java/net/minecraftforge/fml/common/launcher/FMLTweaker.java b/module/forge/src/main/java/net/minecraftforge/fml/common/launcher/FMLTweaker.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/launcher/FMLTweaker.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/launcher/FMLTweaker.java diff --git a/src/main/java/net/minecraftforge/fml/common/launcher/Yggdrasil.java b/module/forge/src/main/java/net/minecraftforge/fml/common/launcher/Yggdrasil.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/launcher/Yggdrasil.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/launcher/Yggdrasil.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/ByteBufUtils.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/ByteBufUtils.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/ByteBufUtils.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/ByteBufUtils.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/FMLEmbeddedChannel.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/FMLEmbeddedChannel.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/FMLEmbeddedChannel.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/FMLEmbeddedChannel.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/FMLEventChannel.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/FMLEventChannel.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/FMLEventChannel.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/FMLEventChannel.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/FMLIndexedMessageToMessageCodec.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/FMLIndexedMessageToMessageCodec.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/FMLIndexedMessageToMessageCodec.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/FMLIndexedMessageToMessageCodec.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/FMLNetworkEvent.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/FMLNetworkEvent.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/FMLNetworkEvent.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/FMLNetworkEvent.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/FMLNetworkException.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/FMLNetworkException.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/FMLNetworkException.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/FMLNetworkException.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/FMLOutboundHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/FMLOutboundHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/FMLOutboundHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/FMLOutboundHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/IGuiHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/IGuiHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/IGuiHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/IGuiHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/NetworkCheckHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/NetworkCheckHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/NetworkCheckHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/NetworkCheckHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/NetworkEventFiringHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/NetworkEventFiringHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/NetworkEventFiringHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/NetworkEventFiringHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/NetworkHandshakeEstablished.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/NetworkHandshakeEstablished.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/NetworkHandshakeEstablished.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/NetworkHandshakeEstablished.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/NetworkRegistry.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/NetworkRegistry.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/NetworkRegistry.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/NetworkRegistry.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/PacketLoggingHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/PacketLoggingHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/PacketLoggingHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/PacketLoggingHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/handshake/ChannelRegistrationHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/ChannelRegistrationHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/handshake/ChannelRegistrationHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/ChannelRegistrationHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeClientState.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeClientState.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeClientState.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeClientState.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeCodec.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeCodec.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeCodec.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeCodec.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeMessage.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeMessage.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeMessage.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeMessage.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeServerState.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeServerState.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeServerState.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeServerState.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/handshake/HandshakeInjector.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/HandshakeInjector.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/handshake/HandshakeInjector.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/HandshakeInjector.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/handshake/HandshakeMessageHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/HandshakeMessageHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/handshake/HandshakeMessageHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/HandshakeMessageHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/handshake/IHandshakeState.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/IHandshakeState.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/handshake/IHandshakeState.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/IHandshakeState.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/handshake/NetworkDispatcher.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/NetworkDispatcher.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/handshake/NetworkDispatcher.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/handshake/NetworkDispatcher.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/internal/EntitySpawnHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/internal/EntitySpawnHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/internal/EntitySpawnHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/internal/EntitySpawnHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/internal/FMLMessage.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/internal/FMLMessage.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/internal/FMLMessage.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/internal/FMLMessage.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/internal/FMLNetworkHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/internal/FMLNetworkHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/internal/FMLNetworkHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/internal/FMLNetworkHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/internal/FMLProxyPacket.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/internal/FMLProxyPacket.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/internal/FMLProxyPacket.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/internal/FMLProxyPacket.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/internal/FMLRuntimeCodec.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/internal/FMLRuntimeCodec.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/internal/FMLRuntimeCodec.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/internal/FMLRuntimeCodec.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/internal/HandshakeCompletionHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/internal/HandshakeCompletionHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/internal/HandshakeCompletionHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/internal/HandshakeCompletionHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/internal/NetworkModHolder.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/internal/NetworkModHolder.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/internal/NetworkModHolder.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/internal/NetworkModHolder.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/internal/OpenGuiHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/internal/OpenGuiHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/internal/OpenGuiHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/internal/OpenGuiHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/IMessage.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/IMessage.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/simpleimpl/IMessage.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/IMessage.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/IMessageHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/IMessageHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/simpleimpl/IMessageHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/IMessageHandler.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/MessageContext.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/MessageContext.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/simpleimpl/MessageContext.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/MessageContext.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleChannelHandlerWrapper.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleChannelHandlerWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleChannelHandlerWrapper.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleChannelHandlerWrapper.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleIndexedCodec.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleIndexedCodec.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleIndexedCodec.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleIndexedCodec.java diff --git a/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleNetworkWrapper.java b/module/forge/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleNetworkWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleNetworkWrapper.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/network/simpleimpl/SimpleNetworkWrapper.java diff --git a/src/main/java/net/minecraftforge/fml/common/patcher/ClassPatch.java b/module/forge/src/main/java/net/minecraftforge/fml/common/patcher/ClassPatch.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/patcher/ClassPatch.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/patcher/ClassPatch.java diff --git a/src/main/java/net/minecraftforge/fml/common/patcher/ClassPatchManager.java b/module/forge/src/main/java/net/minecraftforge/fml/common/patcher/ClassPatchManager.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/patcher/ClassPatchManager.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/patcher/ClassPatchManager.java diff --git a/src/main/java/net/minecraftforge/fml/common/patcher/GenDiffSet.java b/module/forge/src/main/java/net/minecraftforge/fml/common/patcher/GenDiffSet.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/patcher/GenDiffSet.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/patcher/GenDiffSet.java diff --git a/src/main/java/net/minecraftforge/fml/common/registry/EntityEntry.java b/module/forge/src/main/java/net/minecraftforge/fml/common/registry/EntityEntry.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/registry/EntityEntry.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/registry/EntityEntry.java diff --git a/src/main/java/net/minecraftforge/fml/common/registry/EntityEntryBuilder.java b/module/forge/src/main/java/net/minecraftforge/fml/common/registry/EntityEntryBuilder.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/registry/EntityEntryBuilder.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/registry/EntityEntryBuilder.java diff --git a/src/main/java/net/minecraftforge/fml/common/registry/EntityRegistry.java b/module/forge/src/main/java/net/minecraftforge/fml/common/registry/EntityRegistry.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/registry/EntityRegistry.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/registry/EntityRegistry.java diff --git a/src/main/java/net/minecraftforge/fml/common/registry/ExistingSubstitutionException.java b/module/forge/src/main/java/net/minecraftforge/fml/common/registry/ExistingSubstitutionException.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/registry/ExistingSubstitutionException.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/registry/ExistingSubstitutionException.java diff --git a/src/main/java/net/minecraftforge/fml/common/registry/ForgeRegistries.java b/module/forge/src/main/java/net/minecraftforge/fml/common/registry/ForgeRegistries.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/registry/ForgeRegistries.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/registry/ForgeRegistries.java diff --git a/src/main/java/net/minecraftforge/fml/common/registry/GameRegistry.java b/module/forge/src/main/java/net/minecraftforge/fml/common/registry/GameRegistry.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/registry/GameRegistry.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/registry/GameRegistry.java diff --git a/src/main/java/net/minecraftforge/fml/common/registry/IEntityAdditionalSpawnData.java b/module/forge/src/main/java/net/minecraftforge/fml/common/registry/IEntityAdditionalSpawnData.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/registry/IEntityAdditionalSpawnData.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/registry/IEntityAdditionalSpawnData.java diff --git a/src/main/java/net/minecraftforge/fml/common/registry/IThrowableEntity.java b/module/forge/src/main/java/net/minecraftforge/fml/common/registry/IThrowableEntity.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/registry/IThrowableEntity.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/registry/IThrowableEntity.java diff --git a/src/main/java/net/minecraftforge/fml/common/registry/ItemStackHolderInjector.java b/module/forge/src/main/java/net/minecraftforge/fml/common/registry/ItemStackHolderInjector.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/registry/ItemStackHolderInjector.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/registry/ItemStackHolderInjector.java diff --git a/src/main/java/net/minecraftforge/fml/common/registry/ItemStackHolderRef.java b/module/forge/src/main/java/net/minecraftforge/fml/common/registry/ItemStackHolderRef.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/registry/ItemStackHolderRef.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/registry/ItemStackHolderRef.java diff --git a/src/main/java/net/minecraftforge/fml/common/registry/VillagerRegistry.java b/module/forge/src/main/java/net/minecraftforge/fml/common/registry/VillagerRegistry.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/registry/VillagerRegistry.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/registry/VillagerRegistry.java diff --git a/src/main/java/net/minecraftforge/fml/common/thread/SidedThreadGroup.java b/module/forge/src/main/java/net/minecraftforge/fml/common/thread/SidedThreadGroup.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/thread/SidedThreadGroup.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/thread/SidedThreadGroup.java diff --git a/src/main/java/net/minecraftforge/fml/common/thread/SidedThreadGroups.java b/module/forge/src/main/java/net/minecraftforge/fml/common/thread/SidedThreadGroups.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/thread/SidedThreadGroups.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/thread/SidedThreadGroups.java diff --git a/src/main/java/net/minecraftforge/fml/common/toposort/ModSorter.java b/module/forge/src/main/java/net/minecraftforge/fml/common/toposort/ModSorter.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/toposort/ModSorter.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/toposort/ModSorter.java diff --git a/src/main/java/net/minecraftforge/fml/common/toposort/ModSortingException.java b/module/forge/src/main/java/net/minecraftforge/fml/common/toposort/ModSortingException.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/toposort/ModSortingException.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/toposort/ModSortingException.java diff --git a/src/main/java/net/minecraftforge/fml/common/toposort/TopologicalSort.java b/module/forge/src/main/java/net/minecraftforge/fml/common/toposort/TopologicalSort.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/toposort/TopologicalSort.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/toposort/TopologicalSort.java diff --git a/src/main/java/net/minecraftforge/fml/common/versioning/ArtifactVersion.java b/module/forge/src/main/java/net/minecraftforge/fml/common/versioning/ArtifactVersion.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/versioning/ArtifactVersion.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/versioning/ArtifactVersion.java diff --git a/src/main/java/net/minecraftforge/fml/common/versioning/ComparableVersion.java b/module/forge/src/main/java/net/minecraftforge/fml/common/versioning/ComparableVersion.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/versioning/ComparableVersion.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/versioning/ComparableVersion.java diff --git a/src/main/java/net/minecraftforge/fml/common/versioning/DefaultArtifactVersion.java b/module/forge/src/main/java/net/minecraftforge/fml/common/versioning/DefaultArtifactVersion.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/versioning/DefaultArtifactVersion.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/versioning/DefaultArtifactVersion.java diff --git a/src/main/java/net/minecraftforge/fml/common/versioning/DependencyParser.java b/module/forge/src/main/java/net/minecraftforge/fml/common/versioning/DependencyParser.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/versioning/DependencyParser.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/versioning/DependencyParser.java diff --git a/src/main/java/net/minecraftforge/fml/common/versioning/InvalidVersionSpecificationException.java b/module/forge/src/main/java/net/minecraftforge/fml/common/versioning/InvalidVersionSpecificationException.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/versioning/InvalidVersionSpecificationException.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/versioning/InvalidVersionSpecificationException.java diff --git a/src/main/java/net/minecraftforge/fml/common/versioning/Restriction.java b/module/forge/src/main/java/net/minecraftforge/fml/common/versioning/Restriction.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/versioning/Restriction.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/versioning/Restriction.java diff --git a/src/main/java/net/minecraftforge/fml/common/versioning/VersionParser.java b/module/forge/src/main/java/net/minecraftforge/fml/common/versioning/VersionParser.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/versioning/VersionParser.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/versioning/VersionParser.java diff --git a/src/main/java/net/minecraftforge/fml/common/versioning/VersionRange.java b/module/forge/src/main/java/net/minecraftforge/fml/common/versioning/VersionRange.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/common/versioning/VersionRange.java rename to module/forge/src/main/java/net/minecraftforge/fml/common/versioning/VersionRange.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/CoreModManager.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/CoreModManager.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/CoreModManager.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/CoreModManager.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/FMLCorePlugin.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/FMLCorePlugin.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/FMLCorePlugin.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/FMLCorePlugin.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/FMLInjectionData.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/FMLInjectionData.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/FMLInjectionData.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/FMLInjectionData.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/FMLLaunchHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/FMLLaunchHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/FMLLaunchHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/FMLLaunchHandler.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/FMLRelaunchLog.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/FMLRelaunchLog.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/FMLRelaunchLog.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/FMLRelaunchLog.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/FileListHelper.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/FileListHelper.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/FileListHelper.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/FileListHelper.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/IFMLCallHook.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/IFMLCallHook.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/IFMLCallHook.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/IFMLCallHook.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/IFMLLoadingPlugin.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/IFMLLoadingPlugin.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/IFMLLoadingPlugin.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/IFMLLoadingPlugin.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/ReflectionHelper.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/ReflectionHelper.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/ReflectionHelper.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/ReflectionHelper.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/ServerLaunchWrapper.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/ServerLaunchWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/ServerLaunchWrapper.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/ServerLaunchWrapper.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/Side.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/Side.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/Side.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/Side.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/SideOnly.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/SideOnly.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/SideOnly.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/SideOnly.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/libraries/Artifact.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/libraries/Artifact.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/libraries/Artifact.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/libraries/Artifact.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/libraries/LibraryManager.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/libraries/LibraryManager.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/libraries/LibraryManager.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/libraries/LibraryManager.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/libraries/LinkRepository.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/libraries/LinkRepository.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/libraries/LinkRepository.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/libraries/LinkRepository.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/libraries/MemoryModList.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/libraries/MemoryModList.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/libraries/MemoryModList.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/libraries/MemoryModList.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/libraries/ModList.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/libraries/ModList.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/libraries/ModList.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/libraries/ModList.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/libraries/Repository.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/libraries/Repository.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/libraries/Repository.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/libraries/Repository.java diff --git a/src/main/java/net/minecraftforge/fml/relauncher/libraries/SnapshotJson.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/libraries/SnapshotJson.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/relauncher/libraries/SnapshotJson.java rename to module/forge/src/main/java/net/minecraftforge/fml/relauncher/libraries/SnapshotJson.java diff --git a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/ByteBufferSeekableSource.java b/module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/ByteBufferSeekableSource.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/ByteBufferSeekableSource.java rename to module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/ByteBufferSeekableSource.java diff --git a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/Checksum.java b/module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/Checksum.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/Checksum.java rename to module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/Checksum.java diff --git a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/DebugDiffWriter.java b/module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/DebugDiffWriter.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/DebugDiffWriter.java rename to module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/DebugDiffWriter.java diff --git a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/Delta.java b/module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/Delta.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/Delta.java rename to module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/Delta.java diff --git a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/DiffWriter.java b/module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/DiffWriter.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/DiffWriter.java rename to module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/DiffWriter.java diff --git a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/GDiffPatcher.java b/module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/GDiffPatcher.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/GDiffPatcher.java rename to module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/GDiffPatcher.java diff --git a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/GDiffWriter.java b/module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/GDiffWriter.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/GDiffWriter.java rename to module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/GDiffWriter.java diff --git a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/PatchException.java b/module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/PatchException.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/PatchException.java rename to module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/PatchException.java diff --git a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/RandomAccessFileSeekableSource.java b/module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/RandomAccessFileSeekableSource.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/RandomAccessFileSeekableSource.java rename to module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/RandomAccessFileSeekableSource.java diff --git a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/SeekableSource.java b/module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/SeekableSource.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/SeekableSource.java rename to module/forge/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/SeekableSource.java diff --git a/src/main/java/net/minecraftforge/fml/server/FMLServerHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/server/FMLServerHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/fml/server/FMLServerHandler.java rename to module/forge/src/main/java/net/minecraftforge/fml/server/FMLServerHandler.java diff --git a/src/main/java/net/minecraftforge/items/CapabilityItemHandler.java b/module/forge/src/main/java/net/minecraftforge/items/CapabilityItemHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/items/CapabilityItemHandler.java rename to module/forge/src/main/java/net/minecraftforge/items/CapabilityItemHandler.java diff --git a/src/main/java/net/minecraftforge/items/IItemHandler.java b/module/forge/src/main/java/net/minecraftforge/items/IItemHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/items/IItemHandler.java rename to module/forge/src/main/java/net/minecraftforge/items/IItemHandler.java diff --git a/src/main/java/net/minecraftforge/items/IItemHandlerModifiable.java b/module/forge/src/main/java/net/minecraftforge/items/IItemHandlerModifiable.java similarity index 100% rename from src/main/java/net/minecraftforge/items/IItemHandlerModifiable.java rename to module/forge/src/main/java/net/minecraftforge/items/IItemHandlerModifiable.java diff --git a/src/main/java/net/minecraftforge/items/ItemHandlerHelper.java b/module/forge/src/main/java/net/minecraftforge/items/ItemHandlerHelper.java similarity index 100% rename from src/main/java/net/minecraftforge/items/ItemHandlerHelper.java rename to module/forge/src/main/java/net/minecraftforge/items/ItemHandlerHelper.java diff --git a/src/main/java/net/minecraftforge/items/ItemStackHandler.java b/module/forge/src/main/java/net/minecraftforge/items/ItemStackHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/items/ItemStackHandler.java rename to module/forge/src/main/java/net/minecraftforge/items/ItemStackHandler.java diff --git a/src/main/java/net/minecraftforge/items/SlotItemHandler.java b/module/forge/src/main/java/net/minecraftforge/items/SlotItemHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/items/SlotItemHandler.java rename to module/forge/src/main/java/net/minecraftforge/items/SlotItemHandler.java diff --git a/src/main/java/net/minecraftforge/items/VanillaDoubleChestItemHandler.java b/module/forge/src/main/java/net/minecraftforge/items/VanillaDoubleChestItemHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/items/VanillaDoubleChestItemHandler.java rename to module/forge/src/main/java/net/minecraftforge/items/VanillaDoubleChestItemHandler.java diff --git a/src/main/java/net/minecraftforge/items/VanillaHopperItemHandler.java b/module/forge/src/main/java/net/minecraftforge/items/VanillaHopperItemHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/items/VanillaHopperItemHandler.java rename to module/forge/src/main/java/net/minecraftforge/items/VanillaHopperItemHandler.java diff --git a/src/main/java/net/minecraftforge/items/VanillaInventoryCodeHooks.java b/module/forge/src/main/java/net/minecraftforge/items/VanillaInventoryCodeHooks.java similarity index 100% rename from src/main/java/net/minecraftforge/items/VanillaInventoryCodeHooks.java rename to module/forge/src/main/java/net/minecraftforge/items/VanillaInventoryCodeHooks.java diff --git a/src/main/java/net/minecraftforge/items/wrapper/CombinedInvWrapper.java b/module/forge/src/main/java/net/minecraftforge/items/wrapper/CombinedInvWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/items/wrapper/CombinedInvWrapper.java rename to module/forge/src/main/java/net/minecraftforge/items/wrapper/CombinedInvWrapper.java diff --git a/src/main/java/net/minecraftforge/items/wrapper/EmptyHandler.java b/module/forge/src/main/java/net/minecraftforge/items/wrapper/EmptyHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/items/wrapper/EmptyHandler.java rename to module/forge/src/main/java/net/minecraftforge/items/wrapper/EmptyHandler.java diff --git a/src/main/java/net/minecraftforge/items/wrapper/EntityArmorInvWrapper.java b/module/forge/src/main/java/net/minecraftforge/items/wrapper/EntityArmorInvWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/items/wrapper/EntityArmorInvWrapper.java rename to module/forge/src/main/java/net/minecraftforge/items/wrapper/EntityArmorInvWrapper.java diff --git a/src/main/java/net/minecraftforge/items/wrapper/EntityEquipmentInvWrapper.java b/module/forge/src/main/java/net/minecraftforge/items/wrapper/EntityEquipmentInvWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/items/wrapper/EntityEquipmentInvWrapper.java rename to module/forge/src/main/java/net/minecraftforge/items/wrapper/EntityEquipmentInvWrapper.java diff --git a/src/main/java/net/minecraftforge/items/wrapper/EntityHandsInvWrapper.java b/module/forge/src/main/java/net/minecraftforge/items/wrapper/EntityHandsInvWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/items/wrapper/EntityHandsInvWrapper.java rename to module/forge/src/main/java/net/minecraftforge/items/wrapper/EntityHandsInvWrapper.java diff --git a/src/main/java/net/minecraftforge/items/wrapper/InvWrapper.java b/module/forge/src/main/java/net/minecraftforge/items/wrapper/InvWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/items/wrapper/InvWrapper.java rename to module/forge/src/main/java/net/minecraftforge/items/wrapper/InvWrapper.java diff --git a/src/main/java/net/minecraftforge/items/wrapper/PlayerArmorInvWrapper.java b/module/forge/src/main/java/net/minecraftforge/items/wrapper/PlayerArmorInvWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/items/wrapper/PlayerArmorInvWrapper.java rename to module/forge/src/main/java/net/minecraftforge/items/wrapper/PlayerArmorInvWrapper.java diff --git a/src/main/java/net/minecraftforge/items/wrapper/PlayerInvWrapper.java b/module/forge/src/main/java/net/minecraftforge/items/wrapper/PlayerInvWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/items/wrapper/PlayerInvWrapper.java rename to module/forge/src/main/java/net/minecraftforge/items/wrapper/PlayerInvWrapper.java diff --git a/src/main/java/net/minecraftforge/items/wrapper/PlayerMainInvWrapper.java b/module/forge/src/main/java/net/minecraftforge/items/wrapper/PlayerMainInvWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/items/wrapper/PlayerMainInvWrapper.java rename to module/forge/src/main/java/net/minecraftforge/items/wrapper/PlayerMainInvWrapper.java diff --git a/src/main/java/net/minecraftforge/items/wrapper/PlayerOffhandInvWrapper.java b/module/forge/src/main/java/net/minecraftforge/items/wrapper/PlayerOffhandInvWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/items/wrapper/PlayerOffhandInvWrapper.java rename to module/forge/src/main/java/net/minecraftforge/items/wrapper/PlayerOffhandInvWrapper.java diff --git a/src/main/java/net/minecraftforge/items/wrapper/RangedWrapper.java b/module/forge/src/main/java/net/minecraftforge/items/wrapper/RangedWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/items/wrapper/RangedWrapper.java rename to module/forge/src/main/java/net/minecraftforge/items/wrapper/RangedWrapper.java diff --git a/src/main/java/net/minecraftforge/items/wrapper/SidedInvWrapper.java b/module/forge/src/main/java/net/minecraftforge/items/wrapper/SidedInvWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/items/wrapper/SidedInvWrapper.java rename to module/forge/src/main/java/net/minecraftforge/items/wrapper/SidedInvWrapper.java diff --git a/src/main/java/net/minecraftforge/oredict/DyeUtils.java b/module/forge/src/main/java/net/minecraftforge/oredict/DyeUtils.java similarity index 100% rename from src/main/java/net/minecraftforge/oredict/DyeUtils.java rename to module/forge/src/main/java/net/minecraftforge/oredict/DyeUtils.java diff --git a/src/main/java/net/minecraftforge/oredict/OreDictionary.java b/module/forge/src/main/java/net/minecraftforge/oredict/OreDictionary.java similarity index 100% rename from src/main/java/net/minecraftforge/oredict/OreDictionary.java rename to module/forge/src/main/java/net/minecraftforge/oredict/OreDictionary.java diff --git a/src/main/java/net/minecraftforge/oredict/OreIngredient.java b/module/forge/src/main/java/net/minecraftforge/oredict/OreIngredient.java similarity index 100% rename from src/main/java/net/minecraftforge/oredict/OreIngredient.java rename to module/forge/src/main/java/net/minecraftforge/oredict/OreIngredient.java diff --git a/src/main/java/net/minecraftforge/oredict/RecipeSorter.java b/module/forge/src/main/java/net/minecraftforge/oredict/RecipeSorter.java similarity index 100% rename from src/main/java/net/minecraftforge/oredict/RecipeSorter.java rename to module/forge/src/main/java/net/minecraftforge/oredict/RecipeSorter.java diff --git a/src/main/java/net/minecraftforge/oredict/ShapedOreRecipe.java b/module/forge/src/main/java/net/minecraftforge/oredict/ShapedOreRecipe.java similarity index 100% rename from src/main/java/net/minecraftforge/oredict/ShapedOreRecipe.java rename to module/forge/src/main/java/net/minecraftforge/oredict/ShapedOreRecipe.java diff --git a/src/main/java/net/minecraftforge/oredict/ShapelessOreRecipe.java b/module/forge/src/main/java/net/minecraftforge/oredict/ShapelessOreRecipe.java similarity index 100% rename from src/main/java/net/minecraftforge/oredict/ShapelessOreRecipe.java rename to module/forge/src/main/java/net/minecraftforge/oredict/ShapelessOreRecipe.java diff --git a/src/main/java/net/minecraftforge/registries/DataSerializerEntry.java b/module/forge/src/main/java/net/minecraftforge/registries/DataSerializerEntry.java similarity index 100% rename from src/main/java/net/minecraftforge/registries/DataSerializerEntry.java rename to module/forge/src/main/java/net/minecraftforge/registries/DataSerializerEntry.java diff --git a/src/main/java/net/minecraftforge/registries/ForgeRegistry.java b/module/forge/src/main/java/net/minecraftforge/registries/ForgeRegistry.java similarity index 100% rename from src/main/java/net/minecraftforge/registries/ForgeRegistry.java rename to module/forge/src/main/java/net/minecraftforge/registries/ForgeRegistry.java diff --git a/src/main/java/net/minecraftforge/registries/GameData.java b/module/forge/src/main/java/net/minecraftforge/registries/GameData.java similarity index 100% rename from src/main/java/net/minecraftforge/registries/GameData.java rename to module/forge/src/main/java/net/minecraftforge/registries/GameData.java diff --git a/src/main/java/net/minecraftforge/registries/IForgeRegistry.java b/module/forge/src/main/java/net/minecraftforge/registries/IForgeRegistry.java similarity index 100% rename from src/main/java/net/minecraftforge/registries/IForgeRegistry.java rename to module/forge/src/main/java/net/minecraftforge/registries/IForgeRegistry.java diff --git a/src/main/java/net/minecraftforge/registries/IForgeRegistryEntry.java b/module/forge/src/main/java/net/minecraftforge/registries/IForgeRegistryEntry.java similarity index 100% rename from src/main/java/net/minecraftforge/registries/IForgeRegistryEntry.java rename to module/forge/src/main/java/net/minecraftforge/registries/IForgeRegistryEntry.java diff --git a/src/main/java/net/minecraftforge/registries/IForgeRegistryInternal.java b/module/forge/src/main/java/net/minecraftforge/registries/IForgeRegistryInternal.java similarity index 100% rename from src/main/java/net/minecraftforge/registries/IForgeRegistryInternal.java rename to module/forge/src/main/java/net/minecraftforge/registries/IForgeRegistryInternal.java diff --git a/src/main/java/net/minecraftforge/registries/IForgeRegistryModifiable.java b/module/forge/src/main/java/net/minecraftforge/registries/IForgeRegistryModifiable.java similarity index 100% rename from src/main/java/net/minecraftforge/registries/IForgeRegistryModifiable.java rename to module/forge/src/main/java/net/minecraftforge/registries/IForgeRegistryModifiable.java diff --git a/src/main/java/net/minecraftforge/registries/ILockableRegistry.java b/module/forge/src/main/java/net/minecraftforge/registries/ILockableRegistry.java similarity index 100% rename from src/main/java/net/minecraftforge/registries/ILockableRegistry.java rename to module/forge/src/main/java/net/minecraftforge/registries/ILockableRegistry.java diff --git a/src/main/java/net/minecraftforge/registries/IRegistryDelegate.java b/module/forge/src/main/java/net/minecraftforge/registries/IRegistryDelegate.java similarity index 100% rename from src/main/java/net/minecraftforge/registries/IRegistryDelegate.java rename to module/forge/src/main/java/net/minecraftforge/registries/IRegistryDelegate.java diff --git a/src/main/java/net/minecraftforge/registries/NamespacedDefaultedWrapper.java b/module/forge/src/main/java/net/minecraftforge/registries/NamespacedDefaultedWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/registries/NamespacedDefaultedWrapper.java rename to module/forge/src/main/java/net/minecraftforge/registries/NamespacedDefaultedWrapper.java diff --git a/src/main/java/net/minecraftforge/registries/NamespacedWrapper.java b/module/forge/src/main/java/net/minecraftforge/registries/NamespacedWrapper.java similarity index 100% rename from src/main/java/net/minecraftforge/registries/NamespacedWrapper.java rename to module/forge/src/main/java/net/minecraftforge/registries/NamespacedWrapper.java diff --git a/src/main/java/net/minecraftforge/registries/ObjectHolderRef.java b/module/forge/src/main/java/net/minecraftforge/registries/ObjectHolderRef.java similarity index 100% rename from src/main/java/net/minecraftforge/registries/ObjectHolderRef.java rename to module/forge/src/main/java/net/minecraftforge/registries/ObjectHolderRef.java diff --git a/src/main/java/net/minecraftforge/registries/ObjectHolderRegistry.java b/module/forge/src/main/java/net/minecraftforge/registries/ObjectHolderRegistry.java similarity index 100% rename from src/main/java/net/minecraftforge/registries/ObjectHolderRegistry.java rename to module/forge/src/main/java/net/minecraftforge/registries/ObjectHolderRegistry.java diff --git a/src/main/java/net/minecraftforge/registries/RegistryBuilder.java b/module/forge/src/main/java/net/minecraftforge/registries/RegistryBuilder.java similarity index 100% rename from src/main/java/net/minecraftforge/registries/RegistryBuilder.java rename to module/forge/src/main/java/net/minecraftforge/registries/RegistryBuilder.java diff --git a/src/main/java/net/minecraftforge/registries/RegistryDelegate.java b/module/forge/src/main/java/net/minecraftforge/registries/RegistryDelegate.java similarity index 100% rename from src/main/java/net/minecraftforge/registries/RegistryDelegate.java rename to module/forge/src/main/java/net/minecraftforge/registries/RegistryDelegate.java diff --git a/src/main/java/net/minecraftforge/registries/RegistryManager.java b/module/forge/src/main/java/net/minecraftforge/registries/RegistryManager.java similarity index 100% rename from src/main/java/net/minecraftforge/registries/RegistryManager.java rename to module/forge/src/main/java/net/minecraftforge/registries/RegistryManager.java diff --git a/src/main/java/net/minecraftforge/server/ForgeTimeTracker.java b/module/forge/src/main/java/net/minecraftforge/server/ForgeTimeTracker.java similarity index 100% rename from src/main/java/net/minecraftforge/server/ForgeTimeTracker.java rename to module/forge/src/main/java/net/minecraftforge/server/ForgeTimeTracker.java diff --git a/src/main/java/net/minecraftforge/server/command/ChunkGenWorker.java b/module/forge/src/main/java/net/minecraftforge/server/command/ChunkGenWorker.java similarity index 100% rename from src/main/java/net/minecraftforge/server/command/ChunkGenWorker.java rename to module/forge/src/main/java/net/minecraftforge/server/command/ChunkGenWorker.java diff --git a/src/main/java/net/minecraftforge/server/command/CommandDimensions.java b/module/forge/src/main/java/net/minecraftforge/server/command/CommandDimensions.java similarity index 100% rename from src/main/java/net/minecraftforge/server/command/CommandDimensions.java rename to module/forge/src/main/java/net/minecraftforge/server/command/CommandDimensions.java diff --git a/src/main/java/net/minecraftforge/server/command/CommandEntity.java b/module/forge/src/main/java/net/minecraftforge/server/command/CommandEntity.java similarity index 100% rename from src/main/java/net/minecraftforge/server/command/CommandEntity.java rename to module/forge/src/main/java/net/minecraftforge/server/command/CommandEntity.java diff --git a/src/main/java/net/minecraftforge/server/command/CommandGenerate.java b/module/forge/src/main/java/net/minecraftforge/server/command/CommandGenerate.java similarity index 100% rename from src/main/java/net/minecraftforge/server/command/CommandGenerate.java rename to module/forge/src/main/java/net/minecraftforge/server/command/CommandGenerate.java diff --git a/src/main/java/net/minecraftforge/server/command/CommandSetDimension.java b/module/forge/src/main/java/net/minecraftforge/server/command/CommandSetDimension.java similarity index 100% rename from src/main/java/net/minecraftforge/server/command/CommandSetDimension.java rename to module/forge/src/main/java/net/minecraftforge/server/command/CommandSetDimension.java diff --git a/src/main/java/net/minecraftforge/server/command/CommandTps.java b/module/forge/src/main/java/net/minecraftforge/server/command/CommandTps.java similarity index 100% rename from src/main/java/net/minecraftforge/server/command/CommandTps.java rename to module/forge/src/main/java/net/minecraftforge/server/command/CommandTps.java diff --git a/src/main/java/net/minecraftforge/server/command/CommandTrack.java b/module/forge/src/main/java/net/minecraftforge/server/command/CommandTrack.java similarity index 100% rename from src/main/java/net/minecraftforge/server/command/CommandTrack.java rename to module/forge/src/main/java/net/minecraftforge/server/command/CommandTrack.java diff --git a/src/main/java/net/minecraftforge/server/command/CommandTreeBase.java b/module/forge/src/main/java/net/minecraftforge/server/command/CommandTreeBase.java similarity index 100% rename from src/main/java/net/minecraftforge/server/command/CommandTreeBase.java rename to module/forge/src/main/java/net/minecraftforge/server/command/CommandTreeBase.java diff --git a/src/main/java/net/minecraftforge/server/command/CommandTreeHelp.java b/module/forge/src/main/java/net/minecraftforge/server/command/CommandTreeHelp.java similarity index 100% rename from src/main/java/net/minecraftforge/server/command/CommandTreeHelp.java rename to module/forge/src/main/java/net/minecraftforge/server/command/CommandTreeHelp.java diff --git a/src/main/java/net/minecraftforge/server/command/ForgeCommand.java b/module/forge/src/main/java/net/minecraftforge/server/command/ForgeCommand.java similarity index 100% rename from src/main/java/net/minecraftforge/server/command/ForgeCommand.java rename to module/forge/src/main/java/net/minecraftforge/server/command/ForgeCommand.java diff --git a/src/main/java/net/minecraftforge/server/command/TextComponentHelper.java b/module/forge/src/main/java/net/minecraftforge/server/command/TextComponentHelper.java similarity index 100% rename from src/main/java/net/minecraftforge/server/command/TextComponentHelper.java rename to module/forge/src/main/java/net/minecraftforge/server/command/TextComponentHelper.java diff --git a/src/main/java/net/minecraftforge/server/command/package-info.java b/module/forge/src/main/java/net/minecraftforge/server/command/package-info.java similarity index 100% rename from src/main/java/net/minecraftforge/server/command/package-info.java rename to module/forge/src/main/java/net/minecraftforge/server/command/package-info.java diff --git a/src/main/java/net/minecraftforge/server/console/ConsoleCommandCompleter.java b/module/forge/src/main/java/net/minecraftforge/server/console/ConsoleCommandCompleter.java similarity index 100% rename from src/main/java/net/minecraftforge/server/console/ConsoleCommandCompleter.java rename to module/forge/src/main/java/net/minecraftforge/server/console/ConsoleCommandCompleter.java diff --git a/src/main/java/net/minecraftforge/server/console/TerminalHandler.java b/module/forge/src/main/java/net/minecraftforge/server/console/TerminalHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/server/console/TerminalHandler.java rename to module/forge/src/main/java/net/minecraftforge/server/console/TerminalHandler.java diff --git a/src/main/java/net/minecraftforge/server/permission/DefaultPermissionHandler.java b/module/forge/src/main/java/net/minecraftforge/server/permission/DefaultPermissionHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/server/permission/DefaultPermissionHandler.java rename to module/forge/src/main/java/net/minecraftforge/server/permission/DefaultPermissionHandler.java diff --git a/src/main/java/net/minecraftforge/server/permission/DefaultPermissionLevel.java b/module/forge/src/main/java/net/minecraftforge/server/permission/DefaultPermissionLevel.java similarity index 100% rename from src/main/java/net/minecraftforge/server/permission/DefaultPermissionLevel.java rename to module/forge/src/main/java/net/minecraftforge/server/permission/DefaultPermissionLevel.java diff --git a/src/main/java/net/minecraftforge/server/permission/IPermissionHandler.java b/module/forge/src/main/java/net/minecraftforge/server/permission/IPermissionHandler.java similarity index 100% rename from src/main/java/net/minecraftforge/server/permission/IPermissionHandler.java rename to module/forge/src/main/java/net/minecraftforge/server/permission/IPermissionHandler.java diff --git a/src/main/java/net/minecraftforge/server/permission/PermissionAPI.java b/module/forge/src/main/java/net/minecraftforge/server/permission/PermissionAPI.java similarity index 100% rename from src/main/java/net/minecraftforge/server/permission/PermissionAPI.java rename to module/forge/src/main/java/net/minecraftforge/server/permission/PermissionAPI.java diff --git a/src/main/java/net/minecraftforge/server/permission/context/AreaContext.java b/module/forge/src/main/java/net/minecraftforge/server/permission/context/AreaContext.java similarity index 100% rename from src/main/java/net/minecraftforge/server/permission/context/AreaContext.java rename to module/forge/src/main/java/net/minecraftforge/server/permission/context/AreaContext.java diff --git a/src/main/java/net/minecraftforge/server/permission/context/BlockPosContext.java b/module/forge/src/main/java/net/minecraftforge/server/permission/context/BlockPosContext.java similarity index 100% rename from src/main/java/net/minecraftforge/server/permission/context/BlockPosContext.java rename to module/forge/src/main/java/net/minecraftforge/server/permission/context/BlockPosContext.java diff --git a/src/main/java/net/minecraftforge/server/permission/context/Context.java b/module/forge/src/main/java/net/minecraftforge/server/permission/context/Context.java similarity index 100% rename from src/main/java/net/minecraftforge/server/permission/context/Context.java rename to module/forge/src/main/java/net/minecraftforge/server/permission/context/Context.java diff --git a/src/main/java/net/minecraftforge/server/permission/context/ContextKey.java b/module/forge/src/main/java/net/minecraftforge/server/permission/context/ContextKey.java similarity index 100% rename from src/main/java/net/minecraftforge/server/permission/context/ContextKey.java rename to module/forge/src/main/java/net/minecraftforge/server/permission/context/ContextKey.java diff --git a/src/main/java/net/minecraftforge/server/permission/context/ContextKeys.java b/module/forge/src/main/java/net/minecraftforge/server/permission/context/ContextKeys.java similarity index 100% rename from src/main/java/net/minecraftforge/server/permission/context/ContextKeys.java rename to module/forge/src/main/java/net/minecraftforge/server/permission/context/ContextKeys.java diff --git a/src/main/java/net/minecraftforge/server/permission/context/IContext.java b/module/forge/src/main/java/net/minecraftforge/server/permission/context/IContext.java similarity index 100% rename from src/main/java/net/minecraftforge/server/permission/context/IContext.java rename to module/forge/src/main/java/net/minecraftforge/server/permission/context/IContext.java diff --git a/src/main/java/net/minecraftforge/server/permission/context/PlayerContext.java b/module/forge/src/main/java/net/minecraftforge/server/permission/context/PlayerContext.java similarity index 100% rename from src/main/java/net/minecraftforge/server/permission/context/PlayerContext.java rename to module/forge/src/main/java/net/minecraftforge/server/permission/context/PlayerContext.java diff --git a/src/main/java/net/minecraftforge/server/permission/context/TargetContext.java b/module/forge/src/main/java/net/minecraftforge/server/permission/context/TargetContext.java similarity index 100% rename from src/main/java/net/minecraftforge/server/permission/context/TargetContext.java rename to module/forge/src/main/java/net/minecraftforge/server/permission/context/TargetContext.java diff --git a/src/main/java/net/minecraftforge/server/permission/context/WorldContext.java b/module/forge/src/main/java/net/minecraftforge/server/permission/context/WorldContext.java similarity index 100% rename from src/main/java/net/minecraftforge/server/permission/context/WorldContext.java rename to module/forge/src/main/java/net/minecraftforge/server/permission/context/WorldContext.java diff --git a/src/main/java/net/minecraftforge/server/permission/context/package-info.java b/module/forge/src/main/java/net/minecraftforge/server/permission/context/package-info.java similarity index 100% rename from src/main/java/net/minecraftforge/server/permission/context/package-info.java rename to module/forge/src/main/java/net/minecraftforge/server/permission/context/package-info.java diff --git a/src/main/java/net/minecraftforge/server/permission/package-info.java b/module/forge/src/main/java/net/minecraftforge/server/permission/package-info.java similarity index 100% rename from src/main/java/net/minecraftforge/server/permission/package-info.java rename to module/forge/src/main/java/net/minecraftforge/server/permission/package-info.java diff --git a/src/main/java/net/minecraftforge/server/terminalconsole/HighlightErrorConverter.java b/module/forge/src/main/java/net/minecraftforge/server/terminalconsole/HighlightErrorConverter.java similarity index 100% rename from src/main/java/net/minecraftforge/server/terminalconsole/HighlightErrorConverter.java rename to module/forge/src/main/java/net/minecraftforge/server/terminalconsole/HighlightErrorConverter.java diff --git a/src/main/java/net/minecraftforge/server/terminalconsole/MinecraftFormattingConverter.java b/module/forge/src/main/java/net/minecraftforge/server/terminalconsole/MinecraftFormattingConverter.java similarity index 100% rename from src/main/java/net/minecraftforge/server/terminalconsole/MinecraftFormattingConverter.java rename to module/forge/src/main/java/net/minecraftforge/server/terminalconsole/MinecraftFormattingConverter.java diff --git a/src/main/java/net/minecraftforge/server/terminalconsole/TerminalConsoleAppender.java b/module/forge/src/main/java/net/minecraftforge/server/terminalconsole/TerminalConsoleAppender.java similarity index 100% rename from src/main/java/net/minecraftforge/server/terminalconsole/TerminalConsoleAppender.java rename to module/forge/src/main/java/net/minecraftforge/server/terminalconsole/TerminalConsoleAppender.java diff --git a/src/main/java/net/minecraftforge/server/terminalconsole/package-info.java b/module/forge/src/main/java/net/minecraftforge/server/terminalconsole/package-info.java similarity index 100% rename from src/main/java/net/minecraftforge/server/terminalconsole/package-info.java rename to module/forge/src/main/java/net/minecraftforge/server/terminalconsole/package-info.java diff --git a/src/main/java/net/minecraftforge/server/terminalconsole/util/LoggerNamePatternSelector.java b/module/forge/src/main/java/net/minecraftforge/server/terminalconsole/util/LoggerNamePatternSelector.java similarity index 100% rename from src/main/java/net/minecraftforge/server/terminalconsole/util/LoggerNamePatternSelector.java rename to module/forge/src/main/java/net/minecraftforge/server/terminalconsole/util/LoggerNamePatternSelector.java diff --git a/src/main/java/net/minecraftforge/server/terminalconsole/util/package-info.java b/module/forge/src/main/java/net/minecraftforge/server/terminalconsole/util/package-info.java similarity index 100% rename from src/main/java/net/minecraftforge/server/terminalconsole/util/package-info.java rename to module/forge/src/main/java/net/minecraftforge/server/terminalconsole/util/package-info.java diff --git a/src/main/java/net/minecraftforge/server/timings/ForgeTimings.java b/module/forge/src/main/java/net/minecraftforge/server/timings/ForgeTimings.java similarity index 100% rename from src/main/java/net/minecraftforge/server/timings/ForgeTimings.java rename to module/forge/src/main/java/net/minecraftforge/server/timings/ForgeTimings.java diff --git a/src/main/java/net/minecraftforge/server/timings/TimeTracker.java b/module/forge/src/main/java/net/minecraftforge/server/timings/TimeTracker.java similarity index 100% rename from src/main/java/net/minecraftforge/server/timings/TimeTracker.java rename to module/forge/src/main/java/net/minecraftforge/server/timings/TimeTracker.java diff --git a/src/main/java/paulscode/sound/codecs/CodecIBXM.java b/module/forge/src/main/java/paulscode/sound/codecs/CodecIBXM.java similarity index 100% rename from src/main/java/paulscode/sound/codecs/CodecIBXM.java rename to module/forge/src/main/java/paulscode/sound/codecs/CodecIBXM.java diff --git a/src/main/resources/META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat b/module/forge/src/main/resources/META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat similarity index 100% rename from src/main/resources/META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat rename to module/forge/src/main/resources/META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat diff --git a/src/main/resources/META-INF/services/org.spongepowered.asm.service.IMixinService b/module/forge/src/main/resources/META-INF/services/org.spongepowered.asm.service.IMixinService similarity index 100% rename from src/main/resources/META-INF/services/org.spongepowered.asm.service.IMixinService rename to module/forge/src/main/resources/META-INF/services/org.spongepowered.asm.service.IMixinService diff --git a/src/main/resources/META-INF/services/org.spongepowered.asm.service.IMixinServiceBootstrap b/module/forge/src/main/resources/META-INF/services/org.spongepowered.asm.service.IMixinServiceBootstrap similarity index 100% rename from src/main/resources/META-INF/services/org.spongepowered.asm.service.IMixinServiceBootstrap rename to module/forge/src/main/resources/META-INF/services/org.spongepowered.asm.service.IMixinServiceBootstrap diff --git a/src/main/resources/assets/cleanroom/background.png b/module/forge/src/main/resources/assets/cleanroom/background.png similarity index 100% rename from src/main/resources/assets/cleanroom/background.png rename to module/forge/src/main/resources/assets/cleanroom/background.png diff --git a/src/main/resources/assets/cleanroom/banner.png b/module/forge/src/main/resources/assets/cleanroom/banner.png similarity index 100% rename from src/main/resources/assets/cleanroom/banner.png rename to module/forge/src/main/resources/assets/cleanroom/banner.png diff --git a/src/main/resources/assets/cleanroom/icon.png b/module/forge/src/main/resources/assets/cleanroom/icon.png similarity index 100% rename from src/main/resources/assets/cleanroom/icon.png rename to module/forge/src/main/resources/assets/cleanroom/icon.png diff --git a/src/main/resources/assets/cleanroom/lang/de_de.lang b/module/forge/src/main/resources/assets/cleanroom/lang/de_de.lang similarity index 100% rename from src/main/resources/assets/cleanroom/lang/de_de.lang rename to module/forge/src/main/resources/assets/cleanroom/lang/de_de.lang diff --git a/src/main/resources/assets/cleanroom/lang/en_au.lang b/module/forge/src/main/resources/assets/cleanroom/lang/en_au.lang similarity index 100% rename from src/main/resources/assets/cleanroom/lang/en_au.lang rename to module/forge/src/main/resources/assets/cleanroom/lang/en_au.lang diff --git a/src/main/resources/assets/cleanroom/lang/en_us.lang b/module/forge/src/main/resources/assets/cleanroom/lang/en_us.lang similarity index 100% rename from src/main/resources/assets/cleanroom/lang/en_us.lang rename to module/forge/src/main/resources/assets/cleanroom/lang/en_us.lang diff --git a/src/main/resources/assets/cleanroom/lang/pl_pl.lang b/module/forge/src/main/resources/assets/cleanroom/lang/pl_pl.lang similarity index 100% rename from src/main/resources/assets/cleanroom/lang/pl_pl.lang rename to module/forge/src/main/resources/assets/cleanroom/lang/pl_pl.lang diff --git a/src/main/resources/assets/cleanroom/lang/ru_ru.lang b/module/forge/src/main/resources/assets/cleanroom/lang/ru_ru.lang similarity index 100% rename from src/main/resources/assets/cleanroom/lang/ru_ru.lang rename to module/forge/src/main/resources/assets/cleanroom/lang/ru_ru.lang diff --git a/src/main/resources/assets/cleanroom/lang/zh_cn.lang b/module/forge/src/main/resources/assets/cleanroom/lang/zh_cn.lang similarity index 100% rename from src/main/resources/assets/cleanroom/lang/zh_cn.lang rename to module/forge/src/main/resources/assets/cleanroom/lang/zh_cn.lang diff --git a/src/main/resources/assets/cleanroom/textures/gui/checkbox.png b/module/forge/src/main/resources/assets/cleanroom/textures/gui/checkbox.png similarity index 100% rename from src/main/resources/assets/cleanroom/textures/gui/checkbox.png rename to module/forge/src/main/resources/assets/cleanroom/textures/gui/checkbox.png diff --git a/src/main/resources/assets/cleanroom/textures/gui/icons.png b/module/forge/src/main/resources/assets/cleanroom/textures/gui/icons.png similarity index 100% rename from src/main/resources/assets/cleanroom/textures/gui/icons.png rename to module/forge/src/main/resources/assets/cleanroom/textures/gui/icons.png diff --git a/src/main/resources/assets/cleanroom/textures/gui/minecraft.png b/module/forge/src/main/resources/assets/cleanroom/textures/gui/minecraft.png similarity index 100% rename from src/main/resources/assets/cleanroom/textures/gui/minecraft.png rename to module/forge/src/main/resources/assets/cleanroom/textures/gui/minecraft.png diff --git a/src/main/resources/assets/cleanroom/textures/gui/missing_background.png b/module/forge/src/main/resources/assets/cleanroom/textures/gui/missing_background.png similarity index 100% rename from src/main/resources/assets/cleanroom/textures/gui/missing_background.png rename to module/forge/src/main/resources/assets/cleanroom/textures/gui/missing_background.png diff --git a/src/main/resources/assets/cleanroom/textures/gui/missing_banner.png b/module/forge/src/main/resources/assets/cleanroom/textures/gui/missing_banner.png similarity index 100% rename from src/main/resources/assets/cleanroom/textures/gui/missing_banner.png rename to module/forge/src/main/resources/assets/cleanroom/textures/gui/missing_banner.png diff --git a/src/main/resources/assets/cleanroom/textures/gui/sprites/dropdown/item.png b/module/forge/src/main/resources/assets/cleanroom/textures/gui/sprites/dropdown/item.png similarity index 100% rename from src/main/resources/assets/cleanroom/textures/gui/sprites/dropdown/item.png rename to module/forge/src/main/resources/assets/cleanroom/textures/gui/sprites/dropdown/item.png diff --git a/src/main/resources/assets/cleanroom/textures/gui/sprites/dropdown/item_highlighted.png b/module/forge/src/main/resources/assets/cleanroom/textures/gui/sprites/dropdown/item_highlighted.png similarity index 100% rename from src/main/resources/assets/cleanroom/textures/gui/sprites/dropdown/item_highlighted.png rename to module/forge/src/main/resources/assets/cleanroom/textures/gui/sprites/dropdown/item_highlighted.png diff --git a/src/main/resources/assets/cleanroom/textures/gui/sprites/widget/button.png b/module/forge/src/main/resources/assets/cleanroom/textures/gui/sprites/widget/button.png similarity index 100% rename from src/main/resources/assets/cleanroom/textures/gui/sprites/widget/button.png rename to module/forge/src/main/resources/assets/cleanroom/textures/gui/sprites/widget/button.png diff --git a/src/main/resources/assets/cleanroom/textures/gui/sprites/widget/button_disabled.png b/module/forge/src/main/resources/assets/cleanroom/textures/gui/sprites/widget/button_disabled.png similarity index 100% rename from src/main/resources/assets/cleanroom/textures/gui/sprites/widget/button_disabled.png rename to module/forge/src/main/resources/assets/cleanroom/textures/gui/sprites/widget/button_disabled.png diff --git a/src/main/resources/assets/cleanroom/textures/gui/sprites/widget/button_highlighted.png b/module/forge/src/main/resources/assets/cleanroom/textures/gui/sprites/widget/button_highlighted.png similarity index 100% rename from src/main/resources/assets/cleanroom/textures/gui/sprites/widget/button_highlighted.png rename to module/forge/src/main/resources/assets/cleanroom/textures/gui/sprites/widget/button_highlighted.png diff --git a/src/main/resources/assets/configanytime/icon.png b/module/forge/src/main/resources/assets/configanytime/icon.png similarity index 100% rename from src/main/resources/assets/configanytime/icon.png rename to module/forge/src/main/resources/assets/configanytime/icon.png diff --git a/src/main/resources/assets/fml/textures/gui/forge.png b/module/forge/src/main/resources/assets/fml/textures/gui/forge.png similarity index 100% rename from src/main/resources/assets/fml/textures/gui/forge.png rename to module/forge/src/main/resources/assets/fml/textures/gui/forge.png diff --git a/src/main/resources/assets/fml/textures/gui/icons.png b/module/forge/src/main/resources/assets/fml/textures/gui/icons.png similarity index 100% rename from src/main/resources/assets/fml/textures/gui/icons.png rename to module/forge/src/main/resources/assets/fml/textures/gui/icons.png diff --git a/src/main/resources/assets/forge/blockstates/dynbucket.json b/module/forge/src/main/resources/assets/forge/blockstates/dynbucket.json similarity index 100% rename from src/main/resources/assets/forge/blockstates/dynbucket.json rename to module/forge/src/main/resources/assets/forge/blockstates/dynbucket.json diff --git a/src/main/resources/assets/forge/lang/README.txt b/module/forge/src/main/resources/assets/forge/lang/README.txt similarity index 100% rename from src/main/resources/assets/forge/lang/README.txt rename to module/forge/src/main/resources/assets/forge/lang/README.txt diff --git a/src/main/resources/assets/forge/lang/en_pt.lang b/module/forge/src/main/resources/assets/forge/lang/en_pt.lang similarity index 100% rename from src/main/resources/assets/forge/lang/en_pt.lang rename to module/forge/src/main/resources/assets/forge/lang/en_pt.lang diff --git a/src/main/resources/assets/forge/lang/en_us.lang b/module/forge/src/main/resources/assets/forge/lang/en_us.lang similarity index 100% rename from src/main/resources/assets/forge/lang/en_us.lang rename to module/forge/src/main/resources/assets/forge/lang/en_us.lang diff --git a/src/main/resources/assets/forge/lang/es_es.lang b/module/forge/src/main/resources/assets/forge/lang/es_es.lang similarity index 100% rename from src/main/resources/assets/forge/lang/es_es.lang rename to module/forge/src/main/resources/assets/forge/lang/es_es.lang diff --git a/src/main/resources/assets/forge/lang/fr_fr.lang b/module/forge/src/main/resources/assets/forge/lang/fr_fr.lang similarity index 100% rename from src/main/resources/assets/forge/lang/fr_fr.lang rename to module/forge/src/main/resources/assets/forge/lang/fr_fr.lang diff --git a/src/main/resources/assets/forge/lang/ja_jp.lang b/module/forge/src/main/resources/assets/forge/lang/ja_jp.lang similarity index 100% rename from src/main/resources/assets/forge/lang/ja_jp.lang rename to module/forge/src/main/resources/assets/forge/lang/ja_jp.lang diff --git a/src/main/resources/assets/forge/lang/ko_kr.lang b/module/forge/src/main/resources/assets/forge/lang/ko_kr.lang similarity index 100% rename from src/main/resources/assets/forge/lang/ko_kr.lang rename to module/forge/src/main/resources/assets/forge/lang/ko_kr.lang diff --git a/src/main/resources/assets/forge/lang/ru_ru.lang b/module/forge/src/main/resources/assets/forge/lang/ru_ru.lang similarity index 100% rename from src/main/resources/assets/forge/lang/ru_ru.lang rename to module/forge/src/main/resources/assets/forge/lang/ru_ru.lang diff --git a/src/main/resources/assets/forge/lang/zh_cn.lang b/module/forge/src/main/resources/assets/forge/lang/zh_cn.lang similarity index 100% rename from src/main/resources/assets/forge/lang/zh_cn.lang rename to module/forge/src/main/resources/assets/forge/lang/zh_cn.lang diff --git a/src/main/resources/assets/forge/lang/zh_tw.lang b/module/forge/src/main/resources/assets/forge/lang/zh_tw.lang similarity index 100% rename from src/main/resources/assets/forge/lang/zh_tw.lang rename to module/forge/src/main/resources/assets/forge/lang/zh_tw.lang diff --git a/src/main/resources/assets/forge/models/item/bucket.json b/module/forge/src/main/resources/assets/forge/models/item/bucket.json similarity index 100% rename from src/main/resources/assets/forge/models/item/bucket.json rename to module/forge/src/main/resources/assets/forge/models/item/bucket.json diff --git a/src/main/resources/assets/forge/models/item/bucket_milk.json b/module/forge/src/main/resources/assets/forge/models/item/bucket_milk.json similarity index 100% rename from src/main/resources/assets/forge/models/item/bucket_milk.json rename to module/forge/src/main/resources/assets/forge/models/item/bucket_milk.json diff --git a/src/main/resources/assets/forge/textures/gui/version_check_icons.png b/module/forge/src/main/resources/assets/forge/textures/gui/version_check_icons.png similarity index 100% rename from src/main/resources/assets/forge/textures/gui/version_check_icons.png rename to module/forge/src/main/resources/assets/forge/textures/gui/version_check_icons.png diff --git a/src/main/resources/assets/forge/textures/items/bucket_fluid.png b/module/forge/src/main/resources/assets/forge/textures/items/bucket_fluid.png similarity index 100% rename from src/main/resources/assets/forge/textures/items/bucket_fluid.png rename to module/forge/src/main/resources/assets/forge/textures/items/bucket_fluid.png diff --git a/src/main/resources/assets/forge/textures/items/vanilla_bucket_cover_mask.png b/module/forge/src/main/resources/assets/forge/textures/items/vanilla_bucket_cover_mask.png similarity index 100% rename from src/main/resources/assets/forge/textures/items/vanilla_bucket_cover_mask.png rename to module/forge/src/main/resources/assets/forge/textures/items/vanilla_bucket_cover_mask.png diff --git a/src/main/resources/assets/mixinbooter/icon.png b/module/forge/src/main/resources/assets/mixinbooter/icon.png similarity index 100% rename from src/main/resources/assets/mixinbooter/icon.png rename to module/forge/src/main/resources/assets/mixinbooter/icon.png diff --git a/src/main/resources/cleanmix.info b/module/forge/src/main/resources/cleanmix.info similarity index 100% rename from src/main/resources/cleanmix.info rename to module/forge/src/main/resources/cleanmix.info diff --git a/src/main/resources/forge.exc b/module/forge/src/main/resources/forge.exc similarity index 100% rename from src/main/resources/forge.exc rename to module/forge/src/main/resources/forge.exc diff --git a/src/main/resources/forge.srg b/module/forge/src/main/resources/forge.srg similarity index 100% rename from src/main/resources/forge.srg rename to module/forge/src/main/resources/forge.srg diff --git a/src/main/resources/forge_at.cfg b/module/forge/src/main/resources/forge_at.cfg similarity index 100% rename from src/main/resources/forge_at.cfg rename to module/forge/src/main/resources/forge_at.cfg diff --git a/src/main/resources/forge_logo.png b/module/forge/src/main/resources/forge_logo.png similarity index 100% rename from src/main/resources/forge_logo.png rename to module/forge/src/main/resources/forge_logo.png diff --git a/src/main/resources/log4j2.xml b/module/forge/src/main/resources/log4j2.xml similarity index 100% rename from src/main/resources/log4j2.xml rename to module/forge/src/main/resources/log4j2.xml diff --git a/src/main/resources/log4j2_server.xml b/module/forge/src/main/resources/log4j2_server.xml similarity index 100% rename from src/main/resources/log4j2_server.xml rename to module/forge/src/main/resources/log4j2_server.xml diff --git a/src/main/resources/logging.properties b/module/forge/src/main/resources/logging.properties similarity index 100% rename from src/main/resources/logging.properties rename to module/forge/src/main/resources/logging.properties diff --git a/src/main/resources/mcplogo.png b/module/forge/src/main/resources/mcplogo.png similarity index 100% rename from src/main/resources/mcplogo.png rename to module/forge/src/main/resources/mcplogo.png diff --git a/src/main/resources/mcpmod.info b/module/forge/src/main/resources/mcpmod.info similarity index 100% rename from src/main/resources/mcpmod.info rename to module/forge/src/main/resources/mcpmod.info diff --git a/src/main/resources/mixinbooter.info b/module/forge/src/main/resources/mixinbooter.info similarity index 100% rename from src/main/resources/mixinbooter.info rename to module/forge/src/main/resources/mixinbooter.info diff --git a/src/main/resources/pack.mcmeta b/module/forge/src/main/resources/pack.mcmeta similarity index 100% rename from src/main/resources/pack.mcmeta rename to module/forge/src/main/resources/pack.mcmeta diff --git a/src/main/resources/url.png b/module/forge/src/main/resources/url.png similarity index 100% rename from src/main/resources/url.png rename to module/forge/src/main/resources/url.png diff --git a/src/test/java/net/minecraftforge/debug/PotionEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/PotionEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/PotionEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/PotionEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/block/BasePlaceEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/block/BasePlaceEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/block/BasePlaceEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/block/BasePlaceEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/block/FarmlandTrampleEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/block/FarmlandTrampleEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/block/FarmlandTrampleEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/block/FarmlandTrampleEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/block/FarmlandWaterTest.java b/module/forge/src/test/java/net/minecraftforge/debug/block/FarmlandWaterTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/block/FarmlandWaterTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/block/FarmlandWaterTest.java diff --git a/src/test/java/net/minecraftforge/debug/block/MaterialFogColorTest.java b/module/forge/src/test/java/net/minecraftforge/debug/block/MaterialFogColorTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/block/MaterialFogColorTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/block/MaterialFogColorTest.java diff --git a/src/test/java/net/minecraftforge/debug/block/NeighborNotifyEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/block/NeighborNotifyEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/block/NeighborNotifyEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/block/NeighborNotifyEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/block/ParticleEffectsTest.java b/module/forge/src/test/java/net/minecraftforge/debug/block/ParticleEffectsTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/block/ParticleEffectsTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/block/ParticleEffectsTest.java diff --git a/src/test/java/net/minecraftforge/debug/block/PathNodeTypeTest.java b/module/forge/src/test/java/net/minecraftforge/debug/block/PathNodeTypeTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/block/PathNodeTypeTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/block/PathNodeTypeTest.java diff --git a/src/test/java/net/minecraftforge/debug/block/PlaceEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/block/PlaceEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/block/PlaceEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/block/PlaceEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/block/PortalSpawnEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/block/PortalSpawnEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/block/PortalSpawnEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/block/PortalSpawnEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/block/SlipperinessTest.java b/module/forge/src/test/java/net/minecraftforge/debug/block/SlipperinessTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/block/SlipperinessTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/block/SlipperinessTest.java diff --git a/src/test/java/net/minecraftforge/debug/block/StickyBlockTest.java b/module/forge/src/test/java/net/minecraftforge/debug/block/StickyBlockTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/block/StickyBlockTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/block/StickyBlockTest.java diff --git a/src/test/java/net/minecraftforge/debug/block/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/block/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/block/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/block/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/chat/ClientChatEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/chat/ClientChatEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/chat/ClientChatEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/chat/ClientChatEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/chat/ClientCommandTest.java b/module/forge/src/test/java/net/minecraftforge/debug/chat/ClientCommandTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/chat/ClientCommandTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/chat/ClientCommandTest.java diff --git a/src/test/java/net/minecraftforge/debug/chat/CommandTreeBaseTest.java b/module/forge/src/test/java/net/minecraftforge/debug/chat/CommandTreeBaseTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/chat/CommandTreeBaseTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/chat/CommandTreeBaseTest.java diff --git a/src/test/java/net/minecraftforge/debug/chat/EntitySelectorFactoryTest.java b/module/forge/src/test/java/net/minecraftforge/debug/chat/EntitySelectorFactoryTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/chat/EntitySelectorFactoryTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/chat/EntitySelectorFactoryTest.java diff --git a/src/test/java/net/minecraftforge/debug/chat/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/chat/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/chat/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/chat/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/client/CustomTextureAtlasSpriteTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/CustomTextureAtlasSpriteTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/CustomTextureAtlasSpriteTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/CustomTextureAtlasSpriteTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/FOVModifierEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/FOVModifierEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/FOVModifierEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/FOVModifierEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/SearchableCreativeTabTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/SearchableCreativeTabTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/SearchableCreativeTabTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/SearchableCreativeTabTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/gui/ContainerDrawForegroundEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/gui/ContainerDrawForegroundEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/gui/ContainerDrawForegroundEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/gui/ContainerDrawForegroundEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/gui/TooltipColorEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/gui/TooltipColorEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/gui/TooltipColorEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/gui/TooltipColorEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/model/AnimatedModelTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/model/AnimatedModelTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/model/AnimatedModelTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/model/AnimatedModelTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/model/BlockstateRetextureTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/model/BlockstateRetextureTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/model/BlockstateRetextureTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/model/BlockstateRetextureTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/model/ForgeBlockStatesLoaderTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/model/ForgeBlockStatesLoaderTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/model/ForgeBlockStatesLoaderTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/model/ForgeBlockStatesLoaderTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/model/ItemLayerModelTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/model/ItemLayerModelTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/model/ItemLayerModelTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/model/ItemLayerModelTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/model/ItemModelConflictTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/model/ItemModelConflictTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/model/ItemModelConflictTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/model/ItemModelConflictTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/model/ItemModelGenerationTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/model/ItemModelGenerationTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/model/ItemModelGenerationTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/model/ItemModelGenerationTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/model/ModelBakeEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/model/ModelBakeEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/model/ModelBakeEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/model/ModelBakeEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/model/ModelFluidTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/model/ModelFluidTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/model/ModelFluidTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/model/ModelFluidTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/model/ModelLoaderRegistryTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/model/ModelLoaderRegistryTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/model/ModelLoaderRegistryTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/model/ModelLoaderRegistryTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/model/MultiLayerModelTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/model/MultiLayerModelTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/model/MultiLayerModelTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/model/MultiLayerModelTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/model/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/client/model/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/model/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/model/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/client/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/client/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/client/rendering/FastTESRTransparentTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/rendering/FastTESRTransparentTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/rendering/FastTESRTransparentTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/rendering/FastTESRTransparentTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/rendering/ItemTESRTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/rendering/ItemTESRTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/rendering/ItemTESRTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/rendering/ItemTESRTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/rendering/VertexBufferNormalTest.java b/module/forge/src/test/java/net/minecraftforge/debug/client/rendering/VertexBufferNormalTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/rendering/VertexBufferNormalTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/rendering/VertexBufferNormalTest.java diff --git a/src/test/java/net/minecraftforge/debug/client/rendering/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/client/rendering/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/client/rendering/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/client/rendering/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/entity/BlockEntityUpdateTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/BlockEntityUpdateTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/BlockEntityUpdateTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/BlockEntityUpdateTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/EntityTravelToDimensionEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/EntityTravelToDimensionEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/EntityTravelToDimensionEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/EntityTravelToDimensionEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/GetCollisionBoxesEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/GetCollisionBoxesEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/GetCollisionBoxesEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/GetCollisionBoxesEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/ProjectileImpactEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/ProjectileImpactEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/ProjectileImpactEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/ProjectileImpactEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/living/AnimalTameEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/living/AnimalTameEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/living/AnimalTameEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/living/AnimalTameEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/living/AttackEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/living/AttackEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/living/AttackEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/living/AttackEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/living/BabyEntitySpawnEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/living/BabyEntitySpawnEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/living/BabyEntitySpawnEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/living/BabyEntitySpawnEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/living/CheckSpawnEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/living/CheckSpawnEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/living/CheckSpawnEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/living/CheckSpawnEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/living/CustomSpawnPlacementTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/living/CustomSpawnPlacementTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/living/CustomSpawnPlacementTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/living/CustomSpawnPlacementTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/living/DamageEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/living/DamageEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/living/DamageEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/living/DamageEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/living/EquipmentChangeEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/living/EquipmentChangeEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/living/EquipmentChangeEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/living/EquipmentChangeEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/living/KnockBackEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/living/KnockBackEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/living/KnockBackEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/living/KnockBackEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/living/MobGriefingEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/living/MobGriefingEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/living/MobGriefingEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/living/MobGriefingEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/living/SpecialSpawnTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/living/SpecialSpawnTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/living/SpecialSpawnTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/living/SpecialSpawnTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/living/VillagerProfessionTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/living/VillagerProfessionTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/living/VillagerProfessionTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/living/VillagerProfessionTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/living/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/living/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/living/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/living/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/entity/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/entity/player/CriticalHitEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/player/CriticalHitEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/player/CriticalHitEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/player/CriticalHitEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/player/DamageReworkTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/player/DamageReworkTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/player/DamageReworkTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/player/DamageReworkTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/player/ItemPickupEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/player/ItemPickupEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/player/ItemPickupEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/player/ItemPickupEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/player/PlayerInteractEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/player/PlayerInteractEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/player/PlayerInteractEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/player/PlayerInteractEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/player/PlayerSetSpawnTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/player/PlayerSetSpawnTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/player/PlayerSetSpawnTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/player/PlayerSetSpawnTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/player/ReachDistanceAttributeTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/player/ReachDistanceAttributeTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/player/ReachDistanceAttributeTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/player/ReachDistanceAttributeTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/player/SwimSpeedAttributeTest.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/player/SwimSpeedAttributeTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/player/SwimSpeedAttributeTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/player/SwimSpeedAttributeTest.java diff --git a/src/test/java/net/minecraftforge/debug/entity/player/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/entity/player/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/entity/player/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/entity/player/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/fluid/ColoredFluidTest.java b/module/forge/src/test/java/net/minecraftforge/debug/fluid/ColoredFluidTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/fluid/ColoredFluidTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/fluid/ColoredFluidTest.java diff --git a/src/test/java/net/minecraftforge/debug/fluid/CreateFluidSourceEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/fluid/CreateFluidSourceEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/fluid/CreateFluidSourceEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/fluid/CreateFluidSourceEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/fluid/DynBucketTest.java b/module/forge/src/test/java/net/minecraftforge/debug/fluid/DynBucketTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/fluid/DynBucketTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/fluid/DynBucketTest.java diff --git a/src/test/java/net/minecraftforge/debug/fluid/FluidPlaceBlockEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/fluid/FluidPlaceBlockEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/fluid/FluidPlaceBlockEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/fluid/FluidPlaceBlockEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/fluid/FluidPlacementTest.java b/module/forge/src/test/java/net/minecraftforge/debug/fluid/FluidPlacementTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/fluid/FluidPlacementTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/fluid/FluidPlacementTest.java diff --git a/src/test/java/net/minecraftforge/debug/fluid/ItemFluidHandlerTest.java b/module/forge/src/test/java/net/minecraftforge/debug/fluid/ItemFluidHandlerTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/fluid/ItemFluidHandlerTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/fluid/ItemFluidHandlerTest.java diff --git a/src/test/java/net/minecraftforge/debug/fluid/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/fluid/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/fluid/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/fluid/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/AnytimeSleepingTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/AnytimeSleepingTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/AnytimeSleepingTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/AnytimeSleepingTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/BrewingRecipeRegistryTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/BrewingRecipeRegistryTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/BrewingRecipeRegistryTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/BrewingRecipeRegistryTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/ConstantLoadingTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/ConstantLoadingTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/ConstantLoadingTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/ConstantLoadingTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/CraftingSystemTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/CraftingSystemTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/CraftingSystemTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/CraftingSystemTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/DifficultyChangeEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/DifficultyChangeEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/DifficultyChangeEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/DifficultyChangeEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/DynamicBannerTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/DynamicBannerTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/DynamicBannerTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/DynamicBannerTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/EnchantmentLevelSetEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/EnchantmentLevelSetEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/EnchantmentLevelSetEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/EnchantmentLevelSetEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/FurnaceFuelBurnTimeEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/FurnaceFuelBurnTimeEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/FurnaceFuelBurnTimeEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/FurnaceFuelBurnTimeEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/GiveItemToPlayerTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/GiveItemToPlayerTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/GiveItemToPlayerTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/GiveItemToPlayerTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/InputUpdateEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/InputUpdateEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/InputUpdateEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/InputUpdateEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/NoBedSleepingTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/NoBedSleepingTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/NoBedSleepingTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/NoBedSleepingTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/PotionRegistryTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/PotionRegistryTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/PotionRegistryTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/PotionRegistryTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/RecipeMatchingTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/RecipeMatchingTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/RecipeMatchingTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/RecipeMatchingTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/advancement/AdvancementCriterionTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/advancement/AdvancementCriterionTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/advancement/AdvancementCriterionTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/advancement/AdvancementCriterionTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/advancement/AdvancementEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/advancement/AdvancementEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/advancement/AdvancementEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/advancement/AdvancementEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/advancement/AdvancementsPaginationTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/advancement/AdvancementsPaginationTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/advancement/AdvancementsPaginationTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/advancement/AdvancementsPaginationTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/advancement/OredictTriggerTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/advancement/OredictTriggerTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/advancement/OredictTriggerTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/advancement/OredictTriggerTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/advancement/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/advancement/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/advancement/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/advancement/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/loot/LootContextTweaksTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/loot/LootContextTweaksTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/loot/LootContextTweaksTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/loot/LootContextTweaksTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/loot/LootTableLoadEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/loot/LootTableLoadEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/loot/LootTableLoadEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/loot/LootTableLoadEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/loot/LootTableTest.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/loot/LootTableTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/loot/LootTableTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/loot/LootTableTest.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/loot/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/loot/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/loot/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/loot/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/gameplay/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/gameplay/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/gameplay/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/gameplay/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/item/BonemealEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/item/BonemealEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/item/BonemealEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/item/BonemealEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/item/CanApplyAtEnchantingTableTest.java b/module/forge/src/test/java/net/minecraftforge/debug/item/CanApplyAtEnchantingTableTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/item/CanApplyAtEnchantingTableTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/item/CanApplyAtEnchantingTableTest.java diff --git a/src/test/java/net/minecraftforge/debug/item/CanDestroyBlocksInCreativeTest.java b/module/forge/src/test/java/net/minecraftforge/debug/item/CanDestroyBlocksInCreativeTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/item/CanDestroyBlocksInCreativeTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/item/CanDestroyBlocksInCreativeTest.java diff --git a/src/test/java/net/minecraftforge/debug/item/ContinuousUseItemTest.java b/module/forge/src/test/java/net/minecraftforge/debug/item/ContinuousUseItemTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/item/ContinuousUseItemTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/item/ContinuousUseItemTest.java diff --git a/src/test/java/net/minecraftforge/debug/item/CustomRarityTest.java b/module/forge/src/test/java/net/minecraftforge/debug/item/CustomRarityTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/item/CustomRarityTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/item/CustomRarityTest.java diff --git a/src/test/java/net/minecraftforge/debug/item/HorseArmorTest.java b/module/forge/src/test/java/net/minecraftforge/debug/item/HorseArmorTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/item/HorseArmorTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/item/HorseArmorTest.java diff --git a/src/test/java/net/minecraftforge/debug/item/IsBookEnchantableTest.java b/module/forge/src/test/java/net/minecraftforge/debug/item/IsBookEnchantableTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/item/IsBookEnchantableTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/item/IsBookEnchantableTest.java diff --git a/src/test/java/net/minecraftforge/debug/item/ItemFishedEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/item/ItemFishedEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/item/ItemFishedEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/item/ItemFishedEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/item/MapDataTest.java b/module/forge/src/test/java/net/minecraftforge/debug/item/MapDataTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/item/MapDataTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/item/MapDataTest.java diff --git a/src/test/java/net/minecraftforge/debug/item/MendingRepairTest.java b/module/forge/src/test/java/net/minecraftforge/debug/item/MendingRepairTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/item/MendingRepairTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/item/MendingRepairTest.java diff --git a/src/test/java/net/minecraftforge/debug/item/NBTShareTagTest.java b/module/forge/src/test/java/net/minecraftforge/debug/item/NBTShareTagTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/item/NBTShareTagTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/item/NBTShareTagTest.java diff --git a/src/test/java/net/minecraftforge/debug/item/OnItemUseFirstTest.java b/module/forge/src/test/java/net/minecraftforge/debug/item/OnItemUseFirstTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/item/OnItemUseFirstTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/item/OnItemUseFirstTest.java diff --git a/src/test/java/net/minecraftforge/debug/item/PotionCurabilityTest.java b/module/forge/src/test/java/net/minecraftforge/debug/item/PotionCurabilityTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/item/PotionCurabilityTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/item/PotionCurabilityTest.java diff --git a/src/test/java/net/minecraftforge/debug/item/PotionShouldRenderTest.java b/module/forge/src/test/java/net/minecraftforge/debug/item/PotionShouldRenderTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/item/PotionShouldRenderTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/item/PotionShouldRenderTest.java diff --git a/src/test/java/net/minecraftforge/debug/item/ShieldTest.java b/module/forge/src/test/java/net/minecraftforge/debug/item/ShieldTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/item/ShieldTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/item/ShieldTest.java diff --git a/src/test/java/net/minecraftforge/debug/item/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/item/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/item/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/item/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/misc/EnumPlantTypeTest.java b/module/forge/src/test/java/net/minecraftforge/debug/misc/EnumPlantTypeTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/misc/EnumPlantTypeTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/misc/EnumPlantTypeTest.java diff --git a/src/test/java/net/minecraftforge/debug/misc/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/misc/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/misc/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/misc/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/mod/CapabilityTest.java b/module/forge/src/test/java/net/minecraftforge/debug/mod/CapabilityTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/mod/CapabilityTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/mod/CapabilityTest.java diff --git a/src/test/java/net/minecraftforge/debug/mod/ClientLoadingExceptionTest.java b/module/forge/src/test/java/net/minecraftforge/debug/mod/ClientLoadingExceptionTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/mod/ClientLoadingExceptionTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/mod/ClientLoadingExceptionTest.java diff --git a/src/test/java/net/minecraftforge/debug/mod/ConfigAnnotationTest.java b/module/forge/src/test/java/net/minecraftforge/debug/mod/ConfigAnnotationTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/mod/ConfigAnnotationTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/mod/ConfigAnnotationTest.java diff --git a/src/test/java/net/minecraftforge/debug/mod/ObjectHolderAnnotationTest.java b/module/forge/src/test/java/net/minecraftforge/debug/mod/ObjectHolderAnnotationTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/mod/ObjectHolderAnnotationTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/mod/ObjectHolderAnnotationTest.java diff --git a/src/test/java/net/minecraftforge/debug/mod/PermissionTest.java b/module/forge/src/test/java/net/minecraftforge/debug/mod/PermissionTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/mod/PermissionTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/mod/PermissionTest.java diff --git a/src/test/java/net/minecraftforge/debug/mod/RegistryOverrideTest.java b/module/forge/src/test/java/net/minecraftforge/debug/mod/RegistryOverrideTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/mod/RegistryOverrideTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/mod/RegistryOverrideTest.java diff --git a/src/test/java/net/minecraftforge/debug/mod/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/mod/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/mod/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/mod/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/network/BigNetworkMessageTest.java b/module/forge/src/test/java/net/minecraftforge/debug/network/BigNetworkMessageTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/network/BigNetworkMessageTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/network/BigNetworkMessageTest.java diff --git a/src/test/java/net/minecraftforge/debug/network/TrackingTargetTest.java b/module/forge/src/test/java/net/minecraftforge/debug/network/TrackingTargetTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/network/TrackingTargetTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/network/TrackingTargetTest.java diff --git a/src/test/java/net/minecraftforge/debug/network/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/network/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/network/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/network/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/util/ModNameTooltip.java b/module/forge/src/test/java/net/minecraftforge/debug/util/ModNameTooltip.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/util/ModNameTooltip.java rename to module/forge/src/test/java/net/minecraftforge/debug/util/ModNameTooltip.java diff --git a/src/test/java/net/minecraftforge/debug/util/RotatingWrench.java b/module/forge/src/test/java/net/minecraftforge/debug/util/RotatingWrench.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/util/RotatingWrench.java rename to module/forge/src/test/java/net/minecraftforge/debug/util/RotatingWrench.java diff --git a/src/test/java/net/minecraftforge/debug/util/TextureDumper.java b/module/forge/src/test/java/net/minecraftforge/debug/util/TextureDumper.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/util/TextureDumper.java rename to module/forge/src/test/java/net/minecraftforge/debug/util/TextureDumper.java diff --git a/src/test/java/net/minecraftforge/debug/util/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/util/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/util/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/util/package-info.java diff --git a/src/test/java/net/minecraftforge/debug/village/MerchantTradeOffersEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/village/MerchantTradeOffersEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/village/MerchantTradeOffersEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/village/MerchantTradeOffersEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/village/VillageSiegeEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/village/VillageSiegeEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/village/VillageSiegeEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/village/VillageSiegeEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/world/ChunkCapabilityTest.java b/module/forge/src/test/java/net/minecraftforge/debug/world/ChunkCapabilityTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/world/ChunkCapabilityTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/world/ChunkCapabilityTest.java diff --git a/src/test/java/net/minecraftforge/debug/world/ChunkWatchEventTest.java b/module/forge/src/test/java/net/minecraftforge/debug/world/ChunkWatchEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/world/ChunkWatchEventTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/world/ChunkWatchEventTest.java diff --git a/src/test/java/net/minecraftforge/debug/world/DecorateEventDebug.java b/module/forge/src/test/java/net/minecraftforge/debug/world/DecorateEventDebug.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/world/DecorateEventDebug.java rename to module/forge/src/test/java/net/minecraftforge/debug/world/DecorateEventDebug.java diff --git a/src/test/java/net/minecraftforge/debug/world/SpawnDimensionTest.java b/module/forge/src/test/java/net/minecraftforge/debug/world/SpawnDimensionTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/world/SpawnDimensionTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/world/SpawnDimensionTest.java diff --git a/src/test/java/net/minecraftforge/debug/world/TileEntityLoadingTest.java b/module/forge/src/test/java/net/minecraftforge/debug/world/TileEntityLoadingTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/world/TileEntityLoadingTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/world/TileEntityLoadingTest.java diff --git a/src/test/java/net/minecraftforge/debug/world/WorldCapabilityTest.java b/module/forge/src/test/java/net/minecraftforge/debug/world/WorldCapabilityTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/world/WorldCapabilityTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/world/WorldCapabilityTest.java diff --git a/src/test/java/net/minecraftforge/debug/world/WorldProviderCanSleepAtTest.java b/module/forge/src/test/java/net/minecraftforge/debug/world/WorldProviderCanSleepAtTest.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/world/WorldProviderCanSleepAtTest.java rename to module/forge/src/test/java/net/minecraftforge/debug/world/WorldProviderCanSleepAtTest.java diff --git a/src/test/java/net/minecraftforge/debug/world/package-info.java b/module/forge/src/test/java/net/minecraftforge/debug/world/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/debug/world/package-info.java rename to module/forge/src/test/java/net/minecraftforge/debug/world/package-info.java diff --git a/src/test/java/net/minecraftforge/fml/common/eventhandler/EventBusTest.java b/module/forge/src/test/java/net/minecraftforge/fml/common/eventhandler/EventBusTest.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/common/eventhandler/EventBusTest.java rename to module/forge/src/test/java/net/minecraftforge/fml/common/eventhandler/EventBusTest.java diff --git a/src/test/java/net/minecraftforge/fml/common/eventhandler/impl/AbnormalListeners.java b/module/forge/src/test/java/net/minecraftforge/fml/common/eventhandler/impl/AbnormalListeners.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/common/eventhandler/impl/AbnormalListeners.java rename to module/forge/src/test/java/net/minecraftforge/fml/common/eventhandler/impl/AbnormalListeners.java diff --git a/src/test/java/net/minecraftforge/fml/common/eventhandler/impl/ExampleEvent.java b/module/forge/src/test/java/net/minecraftforge/fml/common/eventhandler/impl/ExampleEvent.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/common/eventhandler/impl/ExampleEvent.java rename to module/forge/src/test/java/net/minecraftforge/fml/common/eventhandler/impl/ExampleEvent.java diff --git a/src/test/java/net/minecraftforge/fml/common/eventhandler/impl/InstanceListeners.java b/module/forge/src/test/java/net/minecraftforge/fml/common/eventhandler/impl/InstanceListeners.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/common/eventhandler/impl/InstanceListeners.java rename to module/forge/src/test/java/net/minecraftforge/fml/common/eventhandler/impl/InstanceListeners.java diff --git a/src/test/java/net/minecraftforge/fml/common/eventhandler/impl/StaticListeners.java b/module/forge/src/test/java/net/minecraftforge/fml/common/eventhandler/impl/StaticListeners.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/common/eventhandler/impl/StaticListeners.java rename to module/forge/src/test/java/net/minecraftforge/fml/common/eventhandler/impl/StaticListeners.java diff --git a/src/test/java/net/minecraftforge/fml/common/registry/BlockStateMappingsTest.java b/module/forge/src/test/java/net/minecraftforge/fml/common/registry/BlockStateMappingsTest.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/common/registry/BlockStateMappingsTest.java rename to module/forge/src/test/java/net/minecraftforge/fml/common/registry/BlockStateMappingsTest.java diff --git a/src/test/java/net/minecraftforge/fml/common/registry/DummyBlockReplacementTest.java b/module/forge/src/test/java/net/minecraftforge/fml/common/registry/DummyBlockReplacementTest.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/common/registry/DummyBlockReplacementTest.java rename to module/forge/src/test/java/net/minecraftforge/fml/common/registry/DummyBlockReplacementTest.java diff --git a/src/test/java/net/minecraftforge/fml/common/registry/ForgeTestRunner.java b/module/forge/src/test/java/net/minecraftforge/fml/common/registry/ForgeTestRunner.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/common/registry/ForgeTestRunner.java rename to module/forge/src/test/java/net/minecraftforge/fml/common/registry/ForgeTestRunner.java diff --git a/src/test/java/net/minecraftforge/fml/common/registry/FreezingTests.java b/module/forge/src/test/java/net/minecraftforge/fml/common/registry/FreezingTests.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/common/registry/FreezingTests.java rename to module/forge/src/test/java/net/minecraftforge/fml/common/registry/FreezingTests.java diff --git a/src/test/java/net/minecraftforge/fml/common/registry/ItemBlockSubstitutionRemoveRestoreTest.java b/module/forge/src/test/java/net/minecraftforge/fml/common/registry/ItemBlockSubstitutionRemoveRestoreTest.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/common/registry/ItemBlockSubstitutionRemoveRestoreTest.java rename to module/forge/src/test/java/net/minecraftforge/fml/common/registry/ItemBlockSubstitutionRemoveRestoreTest.java diff --git a/src/test/java/net/minecraftforge/fml/common/registry/RegistryTestSuite.java b/module/forge/src/test/java/net/minecraftforge/fml/common/registry/RegistryTestSuite.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/common/registry/RegistryTestSuite.java rename to module/forge/src/test/java/net/minecraftforge/fml/common/registry/RegistryTestSuite.java diff --git a/src/test/java/net/minecraftforge/fml/common/registry/SubstitutionInjectionTest.java b/module/forge/src/test/java/net/minecraftforge/fml/common/registry/SubstitutionInjectionTest.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/common/registry/SubstitutionInjectionTest.java rename to module/forge/src/test/java/net/minecraftforge/fml/common/registry/SubstitutionInjectionTest.java diff --git a/src/test/java/net/minecraftforge/fml/common/registry/SubstitutionRemoveRestoreTest.java b/module/forge/src/test/java/net/minecraftforge/fml/common/registry/SubstitutionRemoveRestoreTest.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/common/registry/SubstitutionRemoveRestoreTest.java rename to module/forge/src/test/java/net/minecraftforge/fml/common/registry/SubstitutionRemoveRestoreTest.java diff --git a/src/test/java/net/minecraftforge/fml/common/registry/VanillaRegistryTests.java b/module/forge/src/test/java/net/minecraftforge/fml/common/registry/VanillaRegistryTests.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/common/registry/VanillaRegistryTests.java rename to module/forge/src/test/java/net/minecraftforge/fml/common/registry/VanillaRegistryTests.java diff --git a/src/test/java/net/minecraftforge/fml/debug/FaultyCoreMod.java b/module/forge/src/test/java/net/minecraftforge/fml/debug/FaultyCoreMod.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/debug/FaultyCoreMod.java rename to module/forge/src/test/java/net/minecraftforge/fml/debug/FaultyCoreMod.java diff --git a/src/test/java/net/minecraftforge/fml/test/DependencyParserTest.java b/module/forge/src/test/java/net/minecraftforge/fml/test/DependencyParserTest.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/test/DependencyParserTest.java rename to module/forge/src/test/java/net/minecraftforge/fml/test/DependencyParserTest.java diff --git a/src/test/java/net/minecraftforge/fml/test/ForgeNetworkTestMod.java b/module/forge/src/test/java/net/minecraftforge/fml/test/ForgeNetworkTestMod.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/test/ForgeNetworkTestMod.java rename to module/forge/src/test/java/net/minecraftforge/fml/test/ForgeNetworkTestMod.java diff --git a/src/test/java/net/minecraftforge/fml/test/SpecialSpawnEventTest.java b/module/forge/src/test/java/net/minecraftforge/fml/test/SpecialSpawnEventTest.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/test/SpecialSpawnEventTest.java rename to module/forge/src/test/java/net/minecraftforge/fml/test/SpecialSpawnEventTest.java diff --git a/src/test/java/net/minecraftforge/fml/test/TestNetStuff.java b/module/forge/src/test/java/net/minecraftforge/fml/test/TestNetStuff.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/test/TestNetStuff.java rename to module/forge/src/test/java/net/minecraftforge/fml/test/TestNetStuff.java diff --git a/src/test/java/net/minecraftforge/fml/test/networkhandshake/TestNetworkHandshake.java b/module/forge/src/test/java/net/minecraftforge/fml/test/networkhandshake/TestNetworkHandshake.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/test/networkhandshake/TestNetworkHandshake.java rename to module/forge/src/test/java/net/minecraftforge/fml/test/networkhandshake/TestNetworkHandshake.java diff --git a/src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetHandler1.java b/module/forge/src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetHandler1.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetHandler1.java rename to module/forge/src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetHandler1.java diff --git a/src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetHandler2.java b/module/forge/src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetHandler2.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetHandler2.java rename to module/forge/src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetHandler2.java diff --git a/src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetTestMessage1.java b/module/forge/src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetTestMessage1.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetTestMessage1.java rename to module/forge/src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetTestMessage1.java diff --git a/src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetTestMessage2.java b/module/forge/src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetTestMessage2.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetTestMessage2.java rename to module/forge/src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetTestMessage2.java diff --git a/src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetTester.java b/module/forge/src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetTester.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetTester.java rename to module/forge/src/test/java/net/minecraftforge/fml/test/simplenet/SimpleNetTester.java diff --git a/src/test/java/net/minecraftforge/test/BiomeSpawnableListTest.java b/module/forge/src/test/java/net/minecraftforge/test/BiomeSpawnableListTest.java similarity index 100% rename from src/test/java/net/minecraftforge/test/BiomeSpawnableListTest.java rename to module/forge/src/test/java/net/minecraftforge/test/BiomeSpawnableListTest.java diff --git a/src/test/java/net/minecraftforge/test/BufferBuilderExpansionTest.java b/module/forge/src/test/java/net/minecraftforge/test/BufferBuilderExpansionTest.java similarity index 100% rename from src/test/java/net/minecraftforge/test/BufferBuilderExpansionTest.java rename to module/forge/src/test/java/net/minecraftforge/test/BufferBuilderExpansionTest.java diff --git a/src/test/java/net/minecraftforge/test/ConfigurationTest.java b/module/forge/src/test/java/net/minecraftforge/test/ConfigurationTest.java similarity index 100% rename from src/test/java/net/minecraftforge/test/ConfigurationTest.java rename to module/forge/src/test/java/net/minecraftforge/test/ConfigurationTest.java diff --git a/src/test/java/net/minecraftforge/test/EnumHelperTest.java b/module/forge/src/test/java/net/minecraftforge/test/EnumHelperTest.java similarity index 100% rename from src/test/java/net/minecraftforge/test/EnumHelperTest.java rename to module/forge/src/test/java/net/minecraftforge/test/EnumHelperTest.java diff --git a/src/test/java/net/minecraftforge/test/SelectorHandlerTest.java b/module/forge/src/test/java/net/minecraftforge/test/SelectorHandlerTest.java similarity index 100% rename from src/test/java/net/minecraftforge/test/SelectorHandlerTest.java rename to module/forge/src/test/java/net/minecraftforge/test/SelectorHandlerTest.java diff --git a/src/test/java/net/minecraftforge/test/SliderConfigElementTest.java b/module/forge/src/test/java/net/minecraftforge/test/SliderConfigElementTest.java similarity index 100% rename from src/test/java/net/minecraftforge/test/SliderConfigElementTest.java rename to module/forge/src/test/java/net/minecraftforge/test/SliderConfigElementTest.java diff --git a/src/test/java/net/minecraftforge/test/TestAnnotationParser.java b/module/forge/src/test/java/net/minecraftforge/test/TestAnnotationParser.java similarity index 100% rename from src/test/java/net/minecraftforge/test/TestAnnotationParser.java rename to module/forge/src/test/java/net/minecraftforge/test/TestAnnotationParser.java diff --git a/src/test/java/net/minecraftforge/test/TextTableTest.java b/module/forge/src/test/java/net/minecraftforge/test/TextTableTest.java similarity index 100% rename from src/test/java/net/minecraftforge/test/TextTableTest.java rename to module/forge/src/test/java/net/minecraftforge/test/TextTableTest.java diff --git a/src/test/java/net/minecraftforge/test/package-info.java b/module/forge/src/test/java/net/minecraftforge/test/package-info.java similarity index 100% rename from src/test/java/net/minecraftforge/test/package-info.java rename to module/forge/src/test/java/net/minecraftforge/test/package-info.java diff --git a/src/test/resources/assets/advancementcriteriontest/advancements/root.json b/module/forge/src/test/resources/assets/advancementcriteriontest/advancements/root.json similarity index 100% rename from src/test/resources/assets/advancementcriteriontest/advancements/root.json rename to module/forge/src/test/resources/assets/advancementcriteriontest/advancements/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a1/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a1/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a1/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a1/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a10/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a10/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a10/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a10/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a11/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a11/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a11/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a11/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a12/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a12/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a12/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a12/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a13/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a13/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a13/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a13/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a14/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a14/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a14/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a14/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a15/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a15/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a15/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a15/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a16/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a16/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a16/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a16/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a17/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a17/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a17/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a17/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a18/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a18/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a18/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a18/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a19/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a19/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a19/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a19/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a2/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a2/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a2/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a2/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a20/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a20/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a20/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a20/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a21/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a21/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a21/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a21/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a22/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a22/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a22/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a22/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a23/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a23/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a23/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a23/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a24/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a24/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a24/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a24/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a25/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a25/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a25/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a25/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a26/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a26/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a26/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a26/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a27/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a27/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a27/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a27/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a28/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a28/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a28/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a28/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a29/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a29/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a29/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a29/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a3/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a3/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a3/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a3/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a30/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a30/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a30/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a30/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a31/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a31/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a31/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a31/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a32/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a32/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a32/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a32/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a33/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a33/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a33/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a33/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a34/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a34/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a34/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a34/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a35/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a35/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a35/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a35/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a36/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a36/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a36/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a36/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a37/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a37/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a37/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a37/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a38/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a38/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a38/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a38/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a39/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a39/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a39/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a39/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a4/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a4/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a4/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a4/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a40/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a40/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a40/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a40/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a41/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a41/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a41/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a41/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a42/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a42/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a42/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a42/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a43/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a43/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a43/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a43/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a44/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a44/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a44/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a44/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a45/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a45/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a45/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a45/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a46/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a46/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a46/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a46/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a47/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a47/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a47/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a47/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a48/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a48/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a48/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a48/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a49/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a49/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a49/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a49/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a5/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a5/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a5/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a5/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a50/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a50/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a50/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a50/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a51/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a51/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a51/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a51/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a52/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a52/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a52/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a52/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a53/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a53/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a53/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a53/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a54/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a54/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a54/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a54/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a55/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a55/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a55/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a55/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a56/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a56/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a56/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a56/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a57/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a57/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a57/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a57/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a58/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a58/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a58/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a58/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a59/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a59/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a59/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a59/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a6/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a6/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a6/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a6/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a60/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a60/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a60/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a60/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a61/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a61/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a61/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a61/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a62/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a62/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a62/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a62/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a63/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a63/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a63/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a63/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a64/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a64/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a64/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a64/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a7/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a7/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a7/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a7/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a8/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a8/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a8/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a8/root.json diff --git a/src/test/resources/assets/advancements_pagination/advancements/a9/root.json b/module/forge/src/test/resources/assets/advancements_pagination/advancements/a9/root.json similarity index 100% rename from src/test/resources/assets/advancements_pagination/advancements/a9/root.json rename to module/forge/src/test/resources/assets/advancements_pagination/advancements/a9/root.json diff --git a/src/test/resources/assets/collisionboxexeventtest/blockstates/box_block.json b/module/forge/src/test/resources/assets/collisionboxexeventtest/blockstates/box_block.json similarity index 100% rename from src/test/resources/assets/collisionboxexeventtest/blockstates/box_block.json rename to module/forge/src/test/resources/assets/collisionboxexeventtest/blockstates/box_block.json diff --git a/src/test/resources/assets/config_test/lang/en_US.lang b/module/forge/src/test/resources/assets/config_test/lang/en_US.lang similarity index 100% rename from src/test/resources/assets/config_test/lang/en_US.lang rename to module/forge/src/test/resources/assets/config_test/lang/en_US.lang diff --git a/src/test/resources/assets/constantloadingtest/test/_constants.json b/module/forge/src/test/resources/assets/constantloadingtest/test/_constants.json similarity index 100% rename from src/test/resources/assets/constantloadingtest/test/_constants.json rename to module/forge/src/test/resources/assets/constantloadingtest/test/_constants.json diff --git a/src/test/resources/assets/crafting_system_test/recipes/_factories.json b/module/forge/src/test/resources/assets/crafting_system_test/recipes/_factories.json similarity index 100% rename from src/test/resources/assets/crafting_system_test/recipes/_factories.json rename to module/forge/src/test/resources/assets/crafting_system_test/recipes/_factories.json diff --git a/src/test/resources/assets/crafting_system_test/recipes/conditions_property_not_array.json b/module/forge/src/test/resources/assets/crafting_system_test/recipes/conditions_property_not_array.json similarity index 100% rename from src/test/resources/assets/crafting_system_test/recipes/conditions_property_not_array.json rename to module/forge/src/test/resources/assets/crafting_system_test/recipes/conditions_property_not_array.json diff --git a/src/test/resources/assets/crafting_system_test/recipes/oak_planks_from_logs.json b/module/forge/src/test/resources/assets/crafting_system_test/recipes/oak_planks_from_logs.json similarity index 100% rename from src/test/resources/assets/crafting_system_test/recipes/oak_planks_from_logs.json rename to module/forge/src/test/resources/assets/crafting_system_test/recipes/oak_planks_from_logs.json diff --git a/src/test/resources/assets/custom_sprite_test/blockstates/custom_sprite_block.json b/module/forge/src/test/resources/assets/custom_sprite_test/blockstates/custom_sprite_block.json similarity index 100% rename from src/test/resources/assets/custom_sprite_test/blockstates/custom_sprite_block.json rename to module/forge/src/test/resources/assets/custom_sprite_test/blockstates/custom_sprite_block.json diff --git a/src/test/resources/assets/custom_sprite_test/models/block/custom_sprite_block.json b/module/forge/src/test/resources/assets/custom_sprite_test/models/block/custom_sprite_block.json similarity index 100% rename from src/test/resources/assets/custom_sprite_test/models/block/custom_sprite_block.json rename to module/forge/src/test/resources/assets/custom_sprite_test/models/block/custom_sprite_block.json diff --git a/src/test/resources/assets/dynbuckettest/blockstates/simpletank.json b/module/forge/src/test/resources/assets/dynbuckettest/blockstates/simpletank.json similarity index 100% rename from src/test/resources/assets/dynbuckettest/blockstates/simpletank.json rename to module/forge/src/test/resources/assets/dynbuckettest/blockstates/simpletank.json diff --git a/src/test/resources/assets/farmlandwatertest/blockstates/test_block.json b/module/forge/src/test/resources/assets/farmlandwatertest/blockstates/test_block.json similarity index 100% rename from src/test/resources/assets/farmlandwatertest/blockstates/test_block.json rename to module/forge/src/test/resources/assets/farmlandwatertest/blockstates/test_block.json diff --git a/src/test/resources/assets/fluidadditionalfields/blockstates/slime.json b/module/forge/src/test/resources/assets/fluidadditionalfields/blockstates/slime.json similarity index 100% rename from src/test/resources/assets/fluidadditionalfields/blockstates/slime.json rename to module/forge/src/test/resources/assets/fluidadditionalfields/blockstates/slime.json diff --git a/src/test/resources/assets/fluidadditionalfields/textures/slime_flow.png b/module/forge/src/test/resources/assets/fluidadditionalfields/textures/slime_flow.png similarity index 100% rename from src/test/resources/assets/fluidadditionalfields/textures/slime_flow.png rename to module/forge/src/test/resources/assets/fluidadditionalfields/textures/slime_flow.png diff --git a/src/test/resources/assets/fluidadditionalfields/textures/slime_flow.png.mcmeta b/module/forge/src/test/resources/assets/fluidadditionalfields/textures/slime_flow.png.mcmeta similarity index 100% rename from src/test/resources/assets/fluidadditionalfields/textures/slime_flow.png.mcmeta rename to module/forge/src/test/resources/assets/fluidadditionalfields/textures/slime_flow.png.mcmeta diff --git a/src/test/resources/assets/fluidadditionalfields/textures/slime_overlay.png b/module/forge/src/test/resources/assets/fluidadditionalfields/textures/slime_overlay.png similarity index 100% rename from src/test/resources/assets/fluidadditionalfields/textures/slime_overlay.png rename to module/forge/src/test/resources/assets/fluidadditionalfields/textures/slime_overlay.png diff --git a/src/test/resources/assets/fluidadditionalfields/textures/slime_still.png b/module/forge/src/test/resources/assets/fluidadditionalfields/textures/slime_still.png similarity index 100% rename from src/test/resources/assets/fluidadditionalfields/textures/slime_still.png rename to module/forge/src/test/resources/assets/fluidadditionalfields/textures/slime_still.png diff --git a/src/test/resources/assets/fluidadditionalfields/textures/slime_still.png.mcmeta b/module/forge/src/test/resources/assets/fluidadditionalfields/textures/slime_still.png.mcmeta similarity index 100% rename from src/test/resources/assets/fluidadditionalfields/textures/slime_still.png.mcmeta rename to module/forge/src/test/resources/assets/fluidadditionalfields/textures/slime_still.png.mcmeta diff --git a/src/test/resources/assets/fogcolorinsidematerialtest/blockstates/slime.json b/module/forge/src/test/resources/assets/fogcolorinsidematerialtest/blockstates/slime.json similarity index 100% rename from src/test/resources/assets/fogcolorinsidematerialtest/blockstates/slime.json rename to module/forge/src/test/resources/assets/fogcolorinsidematerialtest/blockstates/slime.json diff --git a/src/test/resources/assets/fogcolorinsidematerialtest/pack.mcmeta b/module/forge/src/test/resources/assets/fogcolorinsidematerialtest/pack.mcmeta similarity index 100% rename from src/test/resources/assets/fogcolorinsidematerialtest/pack.mcmeta rename to module/forge/src/test/resources/assets/fogcolorinsidematerialtest/pack.mcmeta diff --git a/src/test/resources/assets/fogcolorinsidematerialtest/test_fluid.json b/module/forge/src/test/resources/assets/fogcolorinsidematerialtest/test_fluid.json similarity index 100% rename from src/test/resources/assets/fogcolorinsidematerialtest/test_fluid.json rename to module/forge/src/test/resources/assets/fogcolorinsidematerialtest/test_fluid.json diff --git a/src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_flow.png b/module/forge/src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_flow.png similarity index 100% rename from src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_flow.png rename to module/forge/src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_flow.png diff --git a/src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_flow.png.mcmeta b/module/forge/src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_flow.png.mcmeta similarity index 100% rename from src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_flow.png.mcmeta rename to module/forge/src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_flow.png.mcmeta diff --git a/src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_overlay.png b/module/forge/src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_overlay.png similarity index 100% rename from src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_overlay.png rename to module/forge/src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_overlay.png diff --git a/src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_still.png b/module/forge/src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_still.png similarity index 100% rename from src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_still.png rename to module/forge/src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_still.png diff --git a/src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_still.png.mcmeta b/module/forge/src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_still.png.mcmeta similarity index 100% rename from src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_still.png.mcmeta rename to module/forge/src/test/resources/assets/fogcolorinsidematerialtest/textures/slime_still.png.mcmeta diff --git a/src/test/resources/assets/forge/blockstates/dynbottle.json b/module/forge/src/test/resources/assets/forge/blockstates/dynbottle.json similarity index 100% rename from src/test/resources/assets/forge/blockstates/dynbottle.json rename to module/forge/src/test/resources/assets/forge/blockstates/dynbottle.json diff --git a/src/test/resources/assets/forge/recipes/_constants.json b/module/forge/src/test/resources/assets/forge/recipes/_constants.json similarity index 100% rename from src/test/resources/assets/forge/recipes/_constants.json rename to module/forge/src/test/resources/assets/forge/recipes/_constants.json diff --git a/src/test/resources/assets/forge/recipes/ore_shaped.json b/module/forge/src/test/resources/assets/forge/recipes/ore_shaped.json similarity index 100% rename from src/test/resources/assets/forge/recipes/ore_shaped.json rename to module/forge/src/test/resources/assets/forge/recipes/ore_shaped.json diff --git a/src/test/resources/assets/forge/recipes/shapeless.json b/module/forge/src/test/resources/assets/forge/recipes/shapeless.json similarity index 100% rename from src/test/resources/assets/forge/recipes/shapeless.json rename to module/forge/src/test/resources/assets/forge/recipes/shapeless.json diff --git a/src/test/resources/assets/forge/recipes/shapeless_constant.json b/module/forge/src/test/resources/assets/forge/recipes/shapeless_constant.json similarity index 100% rename from src/test/resources/assets/forge/recipes/shapeless_constant.json rename to module/forge/src/test/resources/assets/forge/recipes/shapeless_constant.json diff --git a/src/test/resources/assets/forge/recipes/shapeless_damageable.json b/module/forge/src/test/resources/assets/forge/recipes/shapeless_damageable.json similarity index 100% rename from src/test/resources/assets/forge/recipes/shapeless_damageable.json rename to module/forge/src/test/resources/assets/forge/recipes/shapeless_damageable.json diff --git a/src/test/resources/assets/forge/recipes/shapeless_ore.json b/module/forge/src/test/resources/assets/forge/recipes/shapeless_ore.json similarity index 100% rename from src/test/resources/assets/forge/recipes/shapeless_ore.json rename to module/forge/src/test/resources/assets/forge/recipes/shapeless_ore.json diff --git a/src/test/resources/assets/forge/recipes/shapeless_wildcard.json b/module/forge/src/test/resources/assets/forge/recipes/shapeless_wildcard.json similarity index 100% rename from src/test/resources/assets/forge/recipes/shapeless_wildcard.json rename to module/forge/src/test/resources/assets/forge/recipes/shapeless_wildcard.json diff --git a/src/test/resources/assets/forge/textures/blocks/milk_flow.png b/module/forge/src/test/resources/assets/forge/textures/blocks/milk_flow.png similarity index 100% rename from src/test/resources/assets/forge/textures/blocks/milk_flow.png rename to module/forge/src/test/resources/assets/forge/textures/blocks/milk_flow.png diff --git a/src/test/resources/assets/forge/textures/blocks/milk_flow.png.mcmeta b/module/forge/src/test/resources/assets/forge/textures/blocks/milk_flow.png.mcmeta similarity index 100% rename from src/test/resources/assets/forge/textures/blocks/milk_flow.png.mcmeta rename to module/forge/src/test/resources/assets/forge/textures/blocks/milk_flow.png.mcmeta diff --git a/src/test/resources/assets/forge/textures/blocks/milk_still.png b/module/forge/src/test/resources/assets/forge/textures/blocks/milk_still.png similarity index 100% rename from src/test/resources/assets/forge/textures/blocks/milk_still.png rename to module/forge/src/test/resources/assets/forge/textures/blocks/milk_still.png diff --git a/src/test/resources/assets/forge/textures/blocks/milk_still.png.mcmeta b/module/forge/src/test/resources/assets/forge/textures/blocks/milk_still.png.mcmeta similarity index 100% rename from src/test/resources/assets/forge/textures/blocks/milk_still.png.mcmeta rename to module/forge/src/test/resources/assets/forge/textures/blocks/milk_still.png.mcmeta diff --git a/src/test/resources/assets/forgeblockstatesloader/blockstates/cobblestone_wall.json b/module/forge/src/test/resources/assets/forgeblockstatesloader/blockstates/cobblestone_wall.json similarity index 100% rename from src/test/resources/assets/forgeblockstatesloader/blockstates/cobblestone_wall.json rename to module/forge/src/test/resources/assets/forgeblockstatesloader/blockstates/cobblestone_wall.json diff --git a/src/test/resources/assets/forgeblockstatesloader/blockstates/mossy_cobblestone_wall.json b/module/forge/src/test/resources/assets/forgeblockstatesloader/blockstates/mossy_cobblestone_wall.json similarity index 100% rename from src/test/resources/assets/forgeblockstatesloader/blockstates/mossy_cobblestone_wall.json rename to module/forge/src/test/resources/assets/forgeblockstatesloader/blockstates/mossy_cobblestone_wall.json diff --git a/src/test/resources/assets/forgeblockstatesloader/models/block/wall_connect.json b/module/forge/src/test/resources/assets/forgeblockstatesloader/models/block/wall_connect.json similarity index 100% rename from src/test/resources/assets/forgeblockstatesloader/models/block/wall_connect.json rename to module/forge/src/test/resources/assets/forgeblockstatesloader/models/block/wall_connect.json diff --git a/src/test/resources/assets/forgedebugcustomslimeblock/blockstates/custom_slime_block.json b/module/forge/src/test/resources/assets/forgedebugcustomslimeblock/blockstates/custom_slime_block.json similarity index 100% rename from src/test/resources/assets/forgedebugcustomslimeblock/blockstates/custom_slime_block.json rename to module/forge/src/test/resources/assets/forgedebugcustomslimeblock/blockstates/custom_slime_block.json diff --git a/src/test/resources/assets/forgedebugcustomslimeblock/lang/en_US.lang b/module/forge/src/test/resources/assets/forgedebugcustomslimeblock/lang/en_US.lang similarity index 100% rename from src/test/resources/assets/forgedebugcustomslimeblock/lang/en_US.lang rename to module/forge/src/test/resources/assets/forgedebugcustomslimeblock/lang/en_US.lang diff --git a/src/test/resources/assets/forgedebugcustomslimeblock/models/block/blue_slime_block.json b/module/forge/src/test/resources/assets/forgedebugcustomslimeblock/models/block/blue_slime_block.json similarity index 100% rename from src/test/resources/assets/forgedebugcustomslimeblock/models/block/blue_slime_block.json rename to module/forge/src/test/resources/assets/forgedebugcustomslimeblock/models/block/blue_slime_block.json diff --git a/src/test/resources/assets/forgedebugcustomslimeblock/models/block/obsidian_slime_block.json b/module/forge/src/test/resources/assets/forgedebugcustomslimeblock/models/block/obsidian_slime_block.json similarity index 100% rename from src/test/resources/assets/forgedebugcustomslimeblock/models/block/obsidian_slime_block.json rename to module/forge/src/test/resources/assets/forgedebugcustomslimeblock/models/block/obsidian_slime_block.json diff --git a/src/test/resources/assets/forgedebugcustomslimeblock/models/item/blue_slime_block.json b/module/forge/src/test/resources/assets/forgedebugcustomslimeblock/models/item/blue_slime_block.json similarity index 100% rename from src/test/resources/assets/forgedebugcustomslimeblock/models/item/blue_slime_block.json rename to module/forge/src/test/resources/assets/forgedebugcustomslimeblock/models/item/blue_slime_block.json diff --git a/src/test/resources/assets/forgedebugcustomslimeblock/models/item/obsidian_slime_block.json b/module/forge/src/test/resources/assets/forgedebugcustomslimeblock/models/item/obsidian_slime_block.json similarity index 100% rename from src/test/resources/assets/forgedebugcustomslimeblock/models/item/obsidian_slime_block.json rename to module/forge/src/test/resources/assets/forgedebugcustomslimeblock/models/item/obsidian_slime_block.json diff --git a/src/test/resources/assets/forgedebugcustomslimeblock/textures/blocks/blue_slime_block.png b/module/forge/src/test/resources/assets/forgedebugcustomslimeblock/textures/blocks/blue_slime_block.png similarity index 100% rename from src/test/resources/assets/forgedebugcustomslimeblock/textures/blocks/blue_slime_block.png rename to module/forge/src/test/resources/assets/forgedebugcustomslimeblock/textures/blocks/blue_slime_block.png diff --git a/src/test/resources/assets/forgedebugcustomslimeblock/textures/blocks/obsidian_slime_block.png b/module/forge/src/test/resources/assets/forgedebugcustomslimeblock/textures/blocks/obsidian_slime_block.png similarity index 100% rename from src/test/resources/assets/forgedebugcustomslimeblock/textures/blocks/obsidian_slime_block.png rename to module/forge/src/test/resources/assets/forgedebugcustomslimeblock/textures/blocks/obsidian_slime_block.png diff --git a/src/test/resources/assets/forgedebugfluidplacement/blockstates/finite_fluid_block.json b/module/forge/src/test/resources/assets/forgedebugfluidplacement/blockstates/finite_fluid_block.json similarity index 100% rename from src/test/resources/assets/forgedebugfluidplacement/blockstates/finite_fluid_block.json rename to module/forge/src/test/resources/assets/forgedebugfluidplacement/blockstates/finite_fluid_block.json diff --git a/src/test/resources/assets/forgedebugitemlayermodel/blockstates/test_item.json b/module/forge/src/test/resources/assets/forgedebugitemlayermodel/blockstates/test_item.json similarity index 100% rename from src/test/resources/assets/forgedebugitemlayermodel/blockstates/test_item.json rename to module/forge/src/test/resources/assets/forgedebugitemlayermodel/blockstates/test_item.json diff --git a/src/test/resources/assets/forgedebugitemtile/blockstates/custom_model_block.json b/module/forge/src/test/resources/assets/forgedebugitemtile/blockstates/custom_model_block.json similarity index 100% rename from src/test/resources/assets/forgedebugitemtile/blockstates/custom_model_block.json rename to module/forge/src/test/resources/assets/forgedebugitemtile/blockstates/custom_model_block.json diff --git a/src/test/resources/assets/forgedebugmodelanimation/armatures/block/engine_ring.json b/module/forge/src/test/resources/assets/forgedebugmodelanimation/armatures/block/engine_ring.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelanimation/armatures/block/engine_ring.json rename to module/forge/src/test/resources/assets/forgedebugmodelanimation/armatures/block/engine_ring.json diff --git a/src/test/resources/assets/forgedebugmodelanimation/armatures/block/rotatest.json b/module/forge/src/test/resources/assets/forgedebugmodelanimation/armatures/block/rotatest.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelanimation/armatures/block/rotatest.json rename to module/forge/src/test/resources/assets/forgedebugmodelanimation/armatures/block/rotatest.json diff --git a/src/test/resources/assets/forgedebugmodelanimation/asms/block/chest.json b/module/forge/src/test/resources/assets/forgedebugmodelanimation/asms/block/chest.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelanimation/asms/block/chest.json rename to module/forge/src/test/resources/assets/forgedebugmodelanimation/asms/block/chest.json diff --git a/src/test/resources/assets/forgedebugmodelanimation/asms/block/engine.json b/module/forge/src/test/resources/assets/forgedebugmodelanimation/asms/block/engine.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelanimation/asms/block/engine.json rename to module/forge/src/test/resources/assets/forgedebugmodelanimation/asms/block/engine.json diff --git a/src/test/resources/assets/forgedebugmodelanimation/asms/block/engine2.json b/module/forge/src/test/resources/assets/forgedebugmodelanimation/asms/block/engine2.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelanimation/asms/block/engine2.json rename to module/forge/src/test/resources/assets/forgedebugmodelanimation/asms/block/engine2.json diff --git a/src/test/resources/assets/forgedebugmodelanimation/asms/block/rotatest.json b/module/forge/src/test/resources/assets/forgedebugmodelanimation/asms/block/rotatest.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelanimation/asms/block/rotatest.json rename to module/forge/src/test/resources/assets/forgedebugmodelanimation/asms/block/rotatest.json diff --git a/src/test/resources/assets/forgedebugmodelanimation/blockstates/rotatest.json b/module/forge/src/test/resources/assets/forgedebugmodelanimation/blockstates/rotatest.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelanimation/blockstates/rotatest.json rename to module/forge/src/test/resources/assets/forgedebugmodelanimation/blockstates/rotatest.json diff --git a/src/test/resources/assets/forgedebugmodelanimation/blockstates/test_animation_block.json b/module/forge/src/test/resources/assets/forgedebugmodelanimation/blockstates/test_animation_block.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelanimation/blockstates/test_animation_block.json rename to module/forge/src/test/resources/assets/forgedebugmodelanimation/blockstates/test_animation_block.json diff --git a/src/test/resources/assets/forgedebugmodelanimation/models/block/engine.json b/module/forge/src/test/resources/assets/forgedebugmodelanimation/models/block/engine.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelanimation/models/block/engine.json rename to module/forge/src/test/resources/assets/forgedebugmodelanimation/models/block/engine.json diff --git a/src/test/resources/assets/forgedebugmodelanimation/models/block/engine_ring.json b/module/forge/src/test/resources/assets/forgedebugmodelanimation/models/block/engine_ring.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelanimation/models/block/engine_ring.json rename to module/forge/src/test/resources/assets/forgedebugmodelanimation/models/block/engine_ring.json diff --git a/src/test/resources/assets/forgedebugmodelanimation/models/block/rotatest.json b/module/forge/src/test/resources/assets/forgedebugmodelanimation/models/block/rotatest.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelanimation/models/block/rotatest.json rename to module/forge/src/test/resources/assets/forgedebugmodelanimation/models/block/rotatest.json diff --git a/src/test/resources/assets/forgedebugmodelfluid/blockstates/test_fluid_block.json b/module/forge/src/test/resources/assets/forgedebugmodelfluid/blockstates/test_fluid_block.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelfluid/blockstates/test_fluid_block.json rename to module/forge/src/test/resources/assets/forgedebugmodelfluid/blockstates/test_fluid_block.json diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/custom_model_block.json b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/custom_model_block.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/custom_model_block.json rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/custom_model_block.json diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_custom_data_block.json b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_custom_data_block.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_custom_data_block.json rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_custom_data_block.json diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_direction_block.json b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_direction_block.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_direction_block.json rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_direction_block.json diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_direction_eye.json b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_direction_eye.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_direction_eye.json rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_direction_eye.json diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_dynamic_eye.json b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_dynamic_eye.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_dynamic_eye.json rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_dynamic_eye.json diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_tesseract_block.json b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_tesseract_block.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_tesseract_block.json rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_tesseract_block.json diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_vertex_coloring1.json b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_vertex_coloring1.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_vertex_coloring1.json rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_vertex_coloring1.json diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_vertex_coloring2.json b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_vertex_coloring2.json similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_vertex_coloring2.json rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/obj_vertex_coloring2.json diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/chest.b3d b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/chest.b3d similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/models/block/chest.b3d rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/chest.b3d diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/direction_test.mtl b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/direction_test.mtl similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/models/block/direction_test.mtl rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/direction_test.mtl diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/direction_test.obj b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/direction_test.obj similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/models/block/direction_test.obj rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/direction_test.obj diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/eye.mtl b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/eye.mtl similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/models/block/eye.mtl rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/eye.mtl diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/eye.obj b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/eye.obj similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/models/block/eye.obj rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/eye.obj diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/fancy_fence.mtl b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/fancy_fence.mtl similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/models/block/fancy_fence.mtl rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/fancy_fence.mtl diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/fancy_fence.obj b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/fancy_fence.obj similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/models/block/fancy_fence.obj rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/fancy_fence.obj diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/tesseract.mtl b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/tesseract.mtl similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/models/block/tesseract.mtl rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/tesseract.mtl diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/tesseract.obj b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/tesseract.obj similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/models/block/tesseract.obj rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/tesseract.obj diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/untitled2.b3d b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/untitled2.b3d similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/models/block/untitled2.b3d rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/untitled2.b3d diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/vertex_coloring.mtl b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/vertex_coloring.mtl similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/models/block/vertex_coloring.mtl rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/vertex_coloring.mtl diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/vertex_coloring.obj b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/vertex_coloring.obj similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/models/block/vertex_coloring.obj rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/vertex_coloring.obj diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_arrow.png b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_arrow.png similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_arrow.png rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_arrow.png diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_arrow_top.png b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_arrow_top.png similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_arrow_top.png rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_arrow_top.png diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_back.png b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_back.png similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_back.png rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_back.png diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_front.png b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_front.png similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_front.png rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/textures/direction_test_front.png diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/textures/eye.png b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/textures/eye.png similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/textures/eye.png rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/textures/eye.png diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/textures/eye128.png b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/textures/eye128.png similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/textures/eye128.png rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/textures/eye128.png diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/textures/texture.png b/module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/textures/texture.png similarity index 100% rename from src/test/resources/assets/forgedebugmodelloaderregistry/textures/texture.png rename to module/forge/src/test/resources/assets/forgedebugmodelloaderregistry/textures/texture.png diff --git a/src/test/resources/assets/forgedebugmultilayermodel/blockstates/test_layer_block.json b/module/forge/src/test/resources/assets/forgedebugmultilayermodel/blockstates/test_layer_block.json similarity index 100% rename from src/test/resources/assets/forgedebugmultilayermodel/blockstates/test_layer_block.json rename to module/forge/src/test/resources/assets/forgedebugmultilayermodel/blockstates/test_layer_block.json diff --git a/src/test/resources/assets/forgedebugnobedsleeping/models/item/sleeping_pill.json b/module/forge/src/test/resources/assets/forgedebugnobedsleeping/models/item/sleeping_pill.json similarity index 100% rename from src/test/resources/assets/forgedebugnobedsleeping/models/item/sleeping_pill.json rename to module/forge/src/test/resources/assets/forgedebugnobedsleeping/models/item/sleeping_pill.json diff --git a/src/test/resources/assets/furnacefuelburntimeeventtest/models/item/flammable_gold_shovel.json b/module/forge/src/test/resources/assets/furnacefuelburntimeeventtest/models/item/flammable_gold_shovel.json similarity index 100% rename from src/test/resources/assets/furnacefuelburntimeeventtest/models/item/flammable_gold_shovel.json rename to module/forge/src/test/resources/assets/furnacefuelburntimeeventtest/models/item/flammable_gold_shovel.json diff --git a/src/test/resources/assets/furnacefuelburntimeeventtest/models/item/unburnable_wood_shovel.json b/module/forge/src/test/resources/assets/furnacefuelburntimeeventtest/models/item/unburnable_wood_shovel.json similarity index 100% rename from src/test/resources/assets/furnacefuelburntimeeventtest/models/item/unburnable_wood_shovel.json rename to module/forge/src/test/resources/assets/furnacefuelburntimeeventtest/models/item/unburnable_wood_shovel.json diff --git a/src/test/resources/assets/horse_armor_test/lang/en_US.lang b/module/forge/src/test/resources/assets/horse_armor_test/lang/en_US.lang similarity index 100% rename from src/test/resources/assets/horse_armor_test/lang/en_US.lang rename to module/forge/src/test/resources/assets/horse_armor_test/lang/en_US.lang diff --git a/src/test/resources/assets/horse_armor_test/models/item/test_armor.json b/module/forge/src/test/resources/assets/horse_armor_test/models/item/test_armor.json similarity index 100% rename from src/test/resources/assets/horse_armor_test/models/item/test_armor.json rename to module/forge/src/test/resources/assets/horse_armor_test/models/item/test_armor.json diff --git a/src/test/resources/assets/horse_armor_test/textures/entity/horse/armor/test.png b/module/forge/src/test/resources/assets/horse_armor_test/textures/entity/horse/armor/test.png similarity index 100% rename from src/test/resources/assets/horse_armor_test/textures/entity/horse/armor/test.png rename to module/forge/src/test/resources/assets/horse_armor_test/textures/entity/horse/armor/test.png diff --git a/src/test/resources/assets/horse_armor_test/textures/items/test_armor.png b/module/forge/src/test/resources/assets/horse_armor_test/textures/items/test_armor.png similarity index 100% rename from src/test/resources/assets/horse_armor_test/textures/items/test_armor.png rename to module/forge/src/test/resources/assets/horse_armor_test/textures/items/test_armor.png diff --git a/src/test/resources/assets/item_can_destroy_blocks_in_creative_test/models/item/item_test.json b/module/forge/src/test/resources/assets/item_can_destroy_blocks_in_creative_test/models/item/item_test.json similarity index 100% rename from src/test/resources/assets/item_can_destroy_blocks_in_creative_test/models/item/item_test.json rename to module/forge/src/test/resources/assets/item_can_destroy_blocks_in_creative_test/models/item/item_test.json diff --git a/src/test/resources/assets/item_model_conflict_test/blockstates/test.json b/module/forge/src/test/resources/assets/item_model_conflict_test/blockstates/test.json similarity index 100% rename from src/test/resources/assets/item_model_conflict_test/blockstates/test.json rename to module/forge/src/test/resources/assets/item_model_conflict_test/blockstates/test.json diff --git a/src/test/resources/assets/item_model_conflict_test/models/block/test.json b/module/forge/src/test/resources/assets/item_model_conflict_test/models/block/test.json similarity index 100% rename from src/test/resources/assets/item_model_conflict_test/models/block/test.json rename to module/forge/src/test/resources/assets/item_model_conflict_test/models/block/test.json diff --git a/src/test/resources/assets/item_model_conflict_test/models/item/test.json b/module/forge/src/test/resources/assets/item_model_conflict_test/models/item/test.json similarity index 100% rename from src/test/resources/assets/item_model_conflict_test/models/item/test.json rename to module/forge/src/test/resources/assets/item_model_conflict_test/models/item/test.json diff --git a/src/test/resources/assets/item_model_generation_test/models/item/animation_test.json b/module/forge/src/test/resources/assets/item_model_generation_test/models/item/animation_test.json similarity index 100% rename from src/test/resources/assets/item_model_generation_test/models/item/animation_test.json rename to module/forge/src/test/resources/assets/item_model_generation_test/models/item/animation_test.json diff --git a/src/test/resources/assets/item_model_generation_test/models/item/intersection_test.json b/module/forge/src/test/resources/assets/item_model_generation_test/models/item/intersection_test.json similarity index 100% rename from src/test/resources/assets/item_model_generation_test/models/item/intersection_test.json rename to module/forge/src/test/resources/assets/item_model_generation_test/models/item/intersection_test.json diff --git a/src/test/resources/assets/item_model_generation_test/models/item/opacity_test.json b/module/forge/src/test/resources/assets/item_model_generation_test/models/item/opacity_test.json similarity index 100% rename from src/test/resources/assets/item_model_generation_test/models/item/opacity_test.json rename to module/forge/src/test/resources/assets/item_model_generation_test/models/item/opacity_test.json diff --git a/src/test/resources/assets/item_model_generation_test/models/item/overlap_test.json b/module/forge/src/test/resources/assets/item_model_generation_test/models/item/overlap_test.json similarity index 100% rename from src/test/resources/assets/item_model_generation_test/models/item/overlap_test.json rename to module/forge/src/test/resources/assets/item_model_generation_test/models/item/overlap_test.json diff --git a/src/test/resources/assets/item_model_generation_test/models/item/pattern_test.json b/module/forge/src/test/resources/assets/item_model_generation_test/models/item/pattern_test.json similarity index 100% rename from src/test/resources/assets/item_model_generation_test/models/item/pattern_test.json rename to module/forge/src/test/resources/assets/item_model_generation_test/models/item/pattern_test.json diff --git a/src/test/resources/assets/item_model_generation_test/textures/items/animation_test.png b/module/forge/src/test/resources/assets/item_model_generation_test/textures/items/animation_test.png similarity index 100% rename from src/test/resources/assets/item_model_generation_test/textures/items/animation_test.png rename to module/forge/src/test/resources/assets/item_model_generation_test/textures/items/animation_test.png diff --git a/src/test/resources/assets/item_model_generation_test/textures/items/animation_test.png.mcmeta b/module/forge/src/test/resources/assets/item_model_generation_test/textures/items/animation_test.png.mcmeta similarity index 100% rename from src/test/resources/assets/item_model_generation_test/textures/items/animation_test.png.mcmeta rename to module/forge/src/test/resources/assets/item_model_generation_test/textures/items/animation_test.png.mcmeta diff --git a/src/test/resources/assets/item_model_generation_test/textures/items/intersection_test.png b/module/forge/src/test/resources/assets/item_model_generation_test/textures/items/intersection_test.png similarity index 100% rename from src/test/resources/assets/item_model_generation_test/textures/items/intersection_test.png rename to module/forge/src/test/resources/assets/item_model_generation_test/textures/items/intersection_test.png diff --git a/src/test/resources/assets/item_model_generation_test/textures/items/opacity_test.png b/module/forge/src/test/resources/assets/item_model_generation_test/textures/items/opacity_test.png similarity index 100% rename from src/test/resources/assets/item_model_generation_test/textures/items/opacity_test.png rename to module/forge/src/test/resources/assets/item_model_generation_test/textures/items/opacity_test.png diff --git a/src/test/resources/assets/item_model_generation_test/textures/items/overlap_test.png b/module/forge/src/test/resources/assets/item_model_generation_test/textures/items/overlap_test.png similarity index 100% rename from src/test/resources/assets/item_model_generation_test/textures/items/overlap_test.png rename to module/forge/src/test/resources/assets/item_model_generation_test/textures/items/overlap_test.png diff --git a/src/test/resources/assets/item_model_generation_test/textures/items/pattern_test.png b/module/forge/src/test/resources/assets/item_model_generation_test/textures/items/pattern_test.png similarity index 100% rename from src/test/resources/assets/item_model_generation_test/textures/items/pattern_test.png rename to module/forge/src/test/resources/assets/item_model_generation_test/textures/items/pattern_test.png diff --git a/src/test/resources/assets/loot_context_tweaks_test/advancements/test/root.json b/module/forge/src/test/resources/assets/loot_context_tweaks_test/advancements/test/root.json similarity index 100% rename from src/test/resources/assets/loot_context_tweaks_test/advancements/test/root.json rename to module/forge/src/test/resources/assets/loot_context_tweaks_test/advancements/test/root.json diff --git a/src/test/resources/assets/loottable_load_event_test/loot_tables/chests/custom_spawn_bonus_chest.json b/module/forge/src/test/resources/assets/loottable_load_event_test/loot_tables/chests/custom_spawn_bonus_chest.json similarity index 100% rename from src/test/resources/assets/loottable_load_event_test/loot_tables/chests/custom_spawn_bonus_chest.json rename to module/forge/src/test/resources/assets/loottable_load_event_test/loot_tables/chests/custom_spawn_bonus_chest.json diff --git a/src/test/resources/assets/nbtsharetagitemtest/models/item/nbt_share_tag_item.json b/module/forge/src/test/resources/assets/nbtsharetagitemtest/models/item/nbt_share_tag_item.json similarity index 100% rename from src/test/resources/assets/nbtsharetagitemtest/models/item/nbt_share_tag_item.json rename to module/forge/src/test/resources/assets/nbtsharetagitemtest/models/item/nbt_share_tag_item.json diff --git a/src/test/resources/assets/onitemusefirsttest/models/item/test_item.json b/module/forge/src/test/resources/assets/onitemusefirsttest/models/item/test_item.json similarity index 100% rename from src/test/resources/assets/onitemusefirsttest/models/item/test_item.json rename to module/forge/src/test/resources/assets/onitemusefirsttest/models/item/test_item.json diff --git a/src/test/resources/assets/oredict_predicate/advancements/recipes/wood_unlock_tnt.json b/module/forge/src/test/resources/assets/oredict_predicate/advancements/recipes/wood_unlock_tnt.json similarity index 100% rename from src/test/resources/assets/oredict_predicate/advancements/recipes/wood_unlock_tnt.json rename to module/forge/src/test/resources/assets/oredict_predicate/advancements/recipes/wood_unlock_tnt.json diff --git a/src/test/resources/assets/professiontest/textures/entity/test_villager.png b/module/forge/src/test/resources/assets/professiontest/textures/entity/test_villager.png similarity index 100% rename from src/test/resources/assets/professiontest/textures/entity/test_villager.png rename to module/forge/src/test/resources/assets/professiontest/textures/entity/test_villager.png diff --git a/src/test/resources/assets/professiontest/textures/entity/zombie_test_villager.png b/module/forge/src/test/resources/assets/professiontest/textures/entity/zombie_test_villager.png similarity index 100% rename from src/test/resources/assets/professiontest/textures/entity/zombie_test_villager.png rename to module/forge/src/test/resources/assets/professiontest/textures/entity/zombie_test_villager.png diff --git a/src/test/resources/assets/recipetest/recipes/tool_complex.json b/module/forge/src/test/resources/assets/recipetest/recipes/tool_complex.json similarity index 100% rename from src/test/resources/assets/recipetest/recipes/tool_complex.json rename to module/forge/src/test/resources/assets/recipetest/recipes/tool_complex.json diff --git a/src/test/resources/assets/recipetest/recipes/tool_simple.json b/module/forge/src/test/resources/assets/recipetest/recipes/tool_simple.json similarity index 100% rename from src/test/resources/assets/recipetest/recipes/tool_simple.json rename to module/forge/src/test/resources/assets/recipetest/recipes/tool_simple.json diff --git a/src/test/resources/assets/shield_test/lang/en_US.lang b/module/forge/src/test/resources/assets/shield_test/lang/en_US.lang similarity index 100% rename from src/test/resources/assets/shield_test/lang/en_US.lang rename to module/forge/src/test/resources/assets/shield_test/lang/en_US.lang diff --git a/src/test/resources/assets/shield_test/models/item/diamond_shield.json b/module/forge/src/test/resources/assets/shield_test/models/item/diamond_shield.json similarity index 100% rename from src/test/resources/assets/shield_test/models/item/diamond_shield.json rename to module/forge/src/test/resources/assets/shield_test/models/item/diamond_shield.json diff --git a/src/test/resources/assets/shield_test/models/item/diamond_shield_blocking.json b/module/forge/src/test/resources/assets/shield_test/models/item/diamond_shield_blocking.json similarity index 100% rename from src/test/resources/assets/shield_test/models/item/diamond_shield_blocking.json rename to module/forge/src/test/resources/assets/shield_test/models/item/diamond_shield_blocking.json diff --git a/src/test/resources/assets/wrenchrotatedebug/models/item/test_wrench.json b/module/forge/src/test/resources/assets/wrenchrotatedebug/models/item/test_wrench.json similarity index 100% rename from src/test/resources/assets/wrenchrotatedebug/models/item/test_wrench.json rename to module/forge/src/test/resources/assets/wrenchrotatedebug/models/item/test_wrench.json diff --git a/src/test/resources/assets/wrenchrotatedebug/textures/items/test_wrench.png b/module/forge/src/test/resources/assets/wrenchrotatedebug/textures/items/test_wrench.png similarity index 100% rename from src/test/resources/assets/wrenchrotatedebug/textures/items/test_wrench.png rename to module/forge/src/test/resources/assets/wrenchrotatedebug/textures/items/test_wrench.png diff --git a/src/test/resources/mcmod.info b/module/forge/src/test/resources/mcmod.info similarity index 100% rename from src/test/resources/mcmod.info rename to module/forge/src/test/resources/mcmod.info diff --git a/projects/kirino b/module/kirino similarity index 100% rename from projects/kirino rename to module/kirino diff --git a/src/main/java/zone/rong/mixinbooter/Context.java b/module/mixinbooter/src/main/java/zone/rong/mixinbooter/Context.java similarity index 100% rename from src/main/java/zone/rong/mixinbooter/Context.java rename to module/mixinbooter/src/main/java/zone/rong/mixinbooter/Context.java diff --git a/src/main/java/zone/rong/mixinbooter/IEarlyMixinLoader.java b/module/mixinbooter/src/main/java/zone/rong/mixinbooter/IEarlyMixinLoader.java similarity index 100% rename from src/main/java/zone/rong/mixinbooter/IEarlyMixinLoader.java rename to module/mixinbooter/src/main/java/zone/rong/mixinbooter/IEarlyMixinLoader.java diff --git a/src/main/java/zone/rong/mixinbooter/ILateMixinLoader.java b/module/mixinbooter/src/main/java/zone/rong/mixinbooter/ILateMixinLoader.java similarity index 100% rename from src/main/java/zone/rong/mixinbooter/ILateMixinLoader.java rename to module/mixinbooter/src/main/java/zone/rong/mixinbooter/ILateMixinLoader.java diff --git a/src/main/java/zone/rong/mixinbooter/IMixinConfigHijacker.java b/module/mixinbooter/src/main/java/zone/rong/mixinbooter/IMixinConfigHijacker.java similarity index 100% rename from src/main/java/zone/rong/mixinbooter/IMixinConfigHijacker.java rename to module/mixinbooter/src/main/java/zone/rong/mixinbooter/IMixinConfigHijacker.java diff --git a/src/main/java/zone/rong/mixinbooter/MixinBooterModContainer.java b/module/mixinbooter/src/main/java/zone/rong/mixinbooter/MixinBooterModContainer.java similarity index 100% rename from src/main/java/zone/rong/mixinbooter/MixinBooterModContainer.java rename to module/mixinbooter/src/main/java/zone/rong/mixinbooter/MixinBooterModContainer.java diff --git a/src/main/java/zone/rong/mixinbooter/MixinBooterPlugin.java b/module/mixinbooter/src/main/java/zone/rong/mixinbooter/MixinBooterPlugin.java similarity index 100% rename from src/main/java/zone/rong/mixinbooter/MixinBooterPlugin.java rename to module/mixinbooter/src/main/java/zone/rong/mixinbooter/MixinBooterPlugin.java diff --git a/src/main/java/zone/rong/mixinbooter/MixinLoader.java b/module/mixinbooter/src/main/java/zone/rong/mixinbooter/MixinLoader.java similarity index 100% rename from src/main/java/zone/rong/mixinbooter/MixinLoader.java rename to module/mixinbooter/src/main/java/zone/rong/mixinbooter/MixinLoader.java diff --git a/src/main/java/zone/rong/mixinbooter/Tags.java b/module/mixinbooter/src/main/java/zone/rong/mixinbooter/Tags.java similarity index 100% rename from src/main/java/zone/rong/mixinbooter/Tags.java rename to module/mixinbooter/src/main/java/zone/rong/mixinbooter/Tags.java diff --git a/src/main/java/zone/rong/mixinbooter/service/ModDiscoverer.java b/module/mixinbooter/src/main/java/zone/rong/mixinbooter/service/ModDiscoverer.java similarity index 100% rename from src/main/java/zone/rong/mixinbooter/service/ModDiscoverer.java rename to module/mixinbooter/src/main/java/zone/rong/mixinbooter/service/ModDiscoverer.java diff --git a/src/main/java/zone/rong/mixinbooter/util/Environment.java b/module/mixinbooter/src/main/java/zone/rong/mixinbooter/util/Environment.java similarity index 100% rename from src/main/java/zone/rong/mixinbooter/util/Environment.java rename to module/mixinbooter/src/main/java/zone/rong/mixinbooter/util/Environment.java diff --git a/projects/cleanroom/build.gradle b/projects/cleanroom/build.gradle deleted file mode 100644 index 8d9c9a8fa..000000000 --- a/projects/cleanroom/build.gradle +++ /dev/null @@ -1,1105 +0,0 @@ -import com.cleanroommc.gradle.helpers.ProjectConstants -import com.cleanroommc.gradle.helpers.tasks.GenVersionTask -import com.cleanroommc.gradle.helpers.tasks.CreateMMCPackTask -import com.cleanroommc.gradle.helpers.tasks.Util -import com.palantir.gradle.gitversion.VersionDetails -import groovy.json.JsonBuilder -import groovy.json.JsonSlurper -import net.minecraftforge.gradle.common.tasks.ApplyBinPatches -import net.minecraftforge.gradle.common.tasks.DownloadMavenArtifact -import net.minecraftforge.gradle.common.tasks.ExtractInheritance -import net.minecraftforge.gradle.common.tasks.ExtractMCPData -import net.minecraftforge.gradle.patcher.tasks.GenerateBinPatches -import net.minecraftforge.gradle.patcher.tasks.GeneratePatches -import net.minecraftforge.gradle.patcher.tasks.ReobfuscateJar -import net.minecraftforge.srgutils.IMappingFile -import org.apache.commons.compress.compressors.lzma.LZMACompressorOutputStream -import org.objectweb.asm.ClassReader -import org.objectweb.asm.ClassVisitor -import org.objectweb.asm.FieldVisitor -import org.objectweb.asm.MethodVisitor -import org.objectweb.asm.Opcodes - -import java.nio.file.Files -import java.util.zip.ZipFile - -def props = project.properties -def spec_version = versionDetails().lastTag - -evaluationDependsOn(':minecraft') -apply plugin: 'java-library' -apply plugin: 'maven-publish' -apply plugin: 'top.outlands.gradle.patcher' - -// = 'net.minecraftforge' -group = 'com.cleanroommc' -version = rootProject.version - -tasks.register("genVersion", GenVersionTask.class) - -compileJava { - dependsOn tasks.genVersion -} - -java { - toolchain.languageVersion = JavaLanguageVersion.of(25) -} - -sourceSets { - main { - java { - srcDirs = ["$rootDir/src/main/java", "$rootDir/projects/kirino/src/main/java"] - } - resources { - srcDirs = ["$rootDir/src/main/resources", "$rootDir/projects/kirino/src/main/resources"] - } - } - test { - compileClasspath += sourceSets.main.runtimeClasspath - runtimeClasspath += sourceSets.main.runtimeClasspath - java { - srcDirs = ["$rootDir/src/test/java", "$rootDir/projects/kirino/src/test/java"] - } - resources { - srcDirs = ["$rootDir/src/test/resources"] - } - } - userdev { - compileClasspath += sourceSets.main.runtimeClasspath - runtimeClasspath += sourceSets.main.runtimeClasspath - } - userdevTest { - compileClasspath += sourceSets.userdev.runtimeClasspath - runtimeClasspath += sourceSets.userdev.runtimeClasspath - compileClasspath += sourceSets.test.runtimeClasspath - runtimeClasspath += sourceSets.test.runtimeClasspath - } -} - -repositories { - mavenLocal() - mavenCentral() - maven { - name = 'Cleanroom Maven' - url = 'https://repo.cleanroommc.com/releases/' - } - maven { - url = "https://maven.arcseekers.com/releases/" - } -} - -ext { - version_json = project(':mcp').file('build/mcp/downloadJson/version.json') - lwjglArch = Util.getCurrentArch() - // Do not change the order unless it is required so - lwjglLibraries = [ - [ - 'lwjgl-glfw', 'lwjgl-jemalloc', 'lwjgl-openal', - 'lwjgl-opengl', 'lwjgl-stb', 'lwjgl-tinyfd', 'lwjgl' - ], - - [ - 'natives-linux-arm64', 'natives-linux-arm32', 'natives-linux', - 'natives-macos-arm64', 'natives-macos', - 'natives-windows-arm64', 'natives-windows-x86', 'natives-windows' - ] - ] -} - -patcher { - removeDefaultRuns() - excs.from file("$rootDir/src/main/resources/forge.exc") - parent = project(':minecraft') - patches = file("$rootDir/patches/minecraft") - patchedSrc = file('src/main/java') - srgPatches = false - notchObf = true - accessTransformer = file("$rootDir/src/main/resources/forge_at.cfg") - // sideAnnotationStripper = file("$rootDir/src/main/resources/forge.sas") - processor = ProjectConstants.PATCHER_POST_PROCESSOR - - runs { - - cleanroomClient { - client = true - taskName 'cleanroomClient' - ideaModule "${rootProject.name}.${project.name}.main" - main 'com.cleanroommc.boot.MainClient' - workingDirectory project.file('run') - - environment 'target', 'fmldevclient' - environment 'tweakClass', 'net.minecraftforge.fml.common.launcher.FMLTweaker' - environment 'mainClass', 'top.outlands.foundation.boot.Foundation' - environment 'assetIndex', '{asset_index}' - environment 'assetDirectory', downloadAssets.output - environment 'nativesDirectory', extractNatives.output.get().asFile - environment 'MC_VERSION', props.minecraft_version - environment 'MCP_VERSION', props.mcp_version - environment 'MCP_MAPPINGS', '{mcp_mappings}' - environment 'MCP_TO_SRG', createSrg2Mcp.getOutput().get().getAsFile().getAbsolutePath() - environment 'FORGE_GROUP', project.group - environment 'FORGE_VERSION', props.last_forge_version - - jvmArgs ProjectConstants.JVM_ARGUMENTS + '-Dmixin.debug.export=true' + '-Dmixin.checks.interfaces=true' - - def legacyVanillaClasspathExclusions = [ - '^patchy-.*$', - '^oshi-core-1.*$', - '^jna-4.*$', - '^icu4j-core-mojang-51.*$', - '^netty-all-4.*$', - '^lwjgl-2.*$', - '^lwjgl_util-2.*$', - '^lwjgl-platform-2.*$', - '^java-objc-bridge-1.0.*$' - ] - - classpathExclude(*legacyVanillaClasspathExclusions) - //jvmArgs jvm_arguments - - // Lazily supply the Mappings target, createSrg2Mcp.getMappings() doesn't get populated until later - lazyToken 'mcp_mappings', { -> - createSrg2Mcp.getMappings().get() - } - - mods { - cleanroom { - source sourceSets.main - } - } - } - - cleanroomTestClient { - parent runs.cleanroomClient - taskName 'cleanroomTestClient' - - environment 'MOD_CLASSES', 'dummy' // Needed to work around FG limitation, FG will replace this! - - ideaModule "${rootProject.name}.${project.name}.userdevTest" - - mods { - cleanroom { - source sourceSets.main - } - tests { - sources sourceSets.test - } - } - } - - cleanroomServer { - client false - taskName 'cleanroomServer' - ideaModule "${rootProject.name}.${project.name}.main" - main 'com.cleanroommc.boot.MainServer' - workingDirectory project.file('run') - - environment 'target', 'fmldevserver' - environment 'tweakClass', 'net.minecraftforge.fml.common.launcher.FMLServerTweaker' - environment 'mainClass', 'top.outlands.foundation.boot.Foundation' - environment 'MC_VERSION', props.minecraft_version - environment 'MCP_VERSION', props.mcp_version - environment 'MCP_MAPPINGS', '{mcp_mappings}' - environment 'MCP_TO_SRG', createSrg2Mcp.getOutput().get().getAsFile().getAbsolutePath() - environment 'FORGE_GROUP', project.group - environment 'FORGE_VERSION', props.last_forge_version - - // Lazily supply the Mappings target, createSrg2Mcp.getMappings() doesn't get populated until later - lazyToken 'mcp_mappings', { -> - createSrg2Mcp.getMappings().get() - } - - mods { - cleanroom { - source sourceSets.main - } - } - } - - cleanroomTestServer { - parent runs.cleanroomServer - taskName 'cleanroomTestServer' - - environment 'MOD_CLASSES', 'dummy' // Needed to work around FG limitation, FG will replace this! - - ideaModule "${rootProject.name}.${project.name}.userdevTest" - - mods { - cleanroom { - source sourceSets.main - } - tests { - sources sourceSets.test - } - } - } - } - -} - -// Patches -applyPatches { - originalPrefix = 'before/' - modifiedPrefix = 'after/' - printSummary = true -} - -genPatches { - originalPrefix = 'before/' - modifiedPrefix = 'after/' -} - -// Dependencies -configurations { - configureEach { // LWJGL2 isn't friendly with us, so pye pye - exclude group: 'org.lwjgl.lwjgl' - exclude group: 'com.ibm.icu', module: 'icu4j-core-mojang' - } - - // Don't pull all libraries, if we're missing something, add it to the installer list so the installer knows to download it. - installer { - transitive = false - } - api.extendsFrom(installer) - - lwjglNatives { - transitive = false - } - - testCompile.extendsFrom(lwjglNatives) -} - -dependencies { - // LWJGL - compileOnly "com.cleanroommc:lwjglx:1.0.0" - installer "com.cleanroommc:lwjglxx:1.1.22" - lwjglLibraries[0].each { - if (it == 'lwjgl') { - installer "org.lwjgl:$it:$props.lwjgl_version:unsafe" - } - else { - installer "org.lwjgl:$it:$props.lwjgl_version" - } - runtimeOnly "org.lwjgl:$it::$lwjglArch" - - lwjglLibraries[1].each { arch -> - lwjglNatives "org.lwjgl:$it:$props.lwjgl_version:$arch" - } - } - - // ASM - installer "org.ow2.asm:asm:$props.asm_version" - installer "org.ow2.asm:asm-commons:$props.asm_version" - installer "org.ow2.asm:asm-tree:$props.asm_version" - installer "org.ow2.asm:asm-util:$props.asm_version" - installer "org.ow2.asm:asm-analysis:$props.asm_version" - // Added back deprecated features for mods to load up properly, hosted on outlands - installer "org.ow2.asm:asm-deprecated:$props.asm_deprecated" - - // Hacks - installer "top.outlands:foundation:0.19.11" - installer 'net.lenni0451:Reflect:1.6.4' - installer 'net.lenni0451.commons:unchecked:1.9.2' - installer 'org.javassist:javassist:3.30.2-GA' - //installer "zone.rong:imaginebreaker:2.1" - - // Regular deps - installer 'com.ibm.icu:icu4j:78.3' - installer 'org.jline:jline:4.1.3' - installer 'org.jline:jline-native:4.1.3' - installer 'net.java.jinput:jinput:2.0.10' - - installer 'lzma:lzma:0.0.1' - installer 'java3d:vecmath:1.5.2' - installer 'net.sf.trove4j:core:3.1.0' - installer 'net.sf.trove4j:experimental:3.1.0' - - installer 'net.sf.jopt-simple:jopt-simple:5.0.4' - - installer 'com.github.oshi:oshi-core-ffm:7.3.2' - installer 'com.github.oshi:oshi-common:7.3.2' - installer 'net.java.dev.jna:jna:5.19.1' - installer 'net.java.dev.jna:jna-platform:5.19.1' - - installer 'it.unimi.dsi:fastutil:8.5.18' - - installer 'com.google.guava:guava:33.6.0-jre' - installer 'com.google.guava:failureaccess:1.0.2' - installer 'com.google.code.gson:gson:2.14.0' - - installer 'org.apache.commons:commons-lang3:3.20.0' - installer 'org.apache.commons:commons-compress:1.28.0' - installer 'commons-codec:commons-codec:1.22.0' - installer 'commons-io:commons-io:2.22.0' - installer 'commons-logging:commons-logging:1.4.0' - installer 'org.apache.maven:maven-artifact:3.9.16' - installer 'org.apache.commons:commons-text:1.15.0' // Some old classes in lang3 moved to here, wtf - - // xz in common-compress need this to work - installer 'org.tukaani:xz:1.12' - - installer 'com.google.code.findbugs:jsr305:3.0.2' - installer 'org.jspecify:jspecify:1.0.0' - - // Apache HTTP, 4 and 5 - installer 'org.apache.httpcomponents.core5:httpcore5:5.4.3' - installer 'org.apache.httpcomponents.core5:httpcore5-h2:5.4.3' - installer 'org.apache.httpcomponents.client5:httpclient5:5.6.1' - - installer 'org.apache.httpcomponents:httpclient:4.5.14' - installer 'org.apache.httpcomponents:httpcore:4.4.16' - - // Netty - installer "io.netty:netty-codec-base:$props.netty_version" - installer "io.netty:netty-buffer:$props.netty_version" - installer "io.netty:netty-common:$props.netty_version" - installer "io.netty:netty-handler:$props.netty_version" - installer "io.netty:netty-resolver:$props.netty_version" - installer "io.netty:netty-transport:$props.netty_version" - installer "io.netty:netty-transport-native-unix-common:$props.netty_version:linux-x86_64" - installer "io.netty:netty-transport-classes-epoll:$props.netty_version" - installer "io.netty:netty-transport-native-epoll:$props.netty_version:linux-x86_64" - installer "io.netty:netty-codec-http:$props.netty_version" - installer "io.netty:netty-codec-http2:$props.netty_version" - installer "io.netty:netty-codec-dns:$props.netty_version" - installer "io.netty:netty-codec-compression:$props.netty_version" - installer "io.netty:netty-resolver-dns:$props.netty_version" - - // Jakarta (javax in Java 8) - installer 'jakarta.xml.ws:jakarta.xml.ws-api:4.0.3' - installer 'jakarta.activation:jakarta.activation-api:2.1.4' - installer 'jakarta.annotation:jakarta.annotation-api:3.0.0' - installer 'jakarta.xml.bind:jakarta.xml.bind-api:4.0.5' - installer 'jakarta.inject:jakarta.inject-api:2.0.1' - - // Logging - installer 'org.apache.logging.log4j:log4j-api:2.26.0' - installer 'org.apache.logging.log4j:log4j-core:2.26.0' - installer 'org.apache.logging.log4j:log4j-slf4j2-impl:2.26.0' - installer 'org.slf4j:slf4j-api:2.0.18' - - // Scripts - installer 'org.glassfish.jaxb:jaxb-runtime:4.0.9' - installer 'org.glassfish.jaxb:jaxb-core:4.0.9' - installer 'com.sun.istack:istack-commons-runtime:4.2.0' - installer 'org.glassfish.corba:glassfish-corba-omgapi:5.0.2' - installer 'org.openjdk.nashorn:nashorn-core:15.7' - - // Mac - installer 'ca.weblite:java-objc-bridge:1.2' - - // Kirino Engine - installer 'org.joml:joml:1.10.9' - installer 'io.github.classgraph:classgraph:4.8.184' - - // Mixin - installer "com.cleanroommc:cleanmix:$props.cleanmix_version" - installer annotationProcessor('com.cleanroommc:mixinextras-common:0.5.5') - - testImplementation platform('org.junit:junit-bom:6.1.0') - testImplementation 'org.junit.jupiter:junit-jupiter' - testImplementation 'org.junit.vintage:junit-vintage-engine' - testRuntimeOnly 'org.junit.platform:junit-platform-launcher' -} - -processResources { - inputs.property 'cleanmix_version', props.cleanmix_version - filesMatching('cleanmix.info') { - expand cleanmix_version: props.cleanmix_version - } -} - -test { - maxParallelForks = 1 - useJUnitPlatform() - testLogging { - events 'passed', 'skipped', 'failed' - } - jvmArgs ProjectConstants.JVM_ARGUMENTS + ProjectConstants.COMPILER_JVM_ARGUMENTS -} - -// TODO: Include? -def extra_files = [ - rootProject.file('CREDITS.txt'), - rootProject.file('LICENSE.txt'), - rootProject.file('LICENSE-Paulscode IBXM Library.txt'), - rootProject.file('LICENSE-Paulscode SoundSystem CodecIBXM.txt') -] - -def changelog = rootProject.file('build/changelog.txt') -if (changelog.exists()) { - extra_files += changelog -} - -// Binary Patching - -// We apply the bin patches we just created to make a jar that is JUST our changes -['Client', 'Server', 'Joined'].each { side -> - def gen = tasks.getByName("gen${side}BinPatches") - gen.tool = props.binary_patcher - tasks.register("apply${side}BinPatches", ApplyBinPatches) { - dependsOn gen - clean = gen.cleanJar - patch = gen.output - tool = props.binary_patcher - } -} - -tasks.register('genRuntimeBinPatches', GenerateBinPatches) { - dependsOn genClientBinPatches, genServerBinPatches - tool = props.binary_patcher -} - -afterEvaluate { p -> - genRuntimeBinPatches { - cleanJar = genClientBinPatches.cleanJar - dirtyJar = genClientBinPatches.dirtyJar - srg = genClientBinPatches.srg - patchSets.setFrom(genClientBinPatches.patchSets) - getArgs().set([ - '--output', '{output}', - '--patches', '{patches}', - '--srg', '{srg}', - // '--legacy', - '--clean', '{clean}', - '--dirty', '{dirty}', - '--prefix', 'binpatch/client', - '--clean', genServerBinPatches.cleanJar.get().asFile.path, - '--dirty', genServerBinPatches.dirtyJar.get().asFile.path, - '--prefix', 'binpatch/server', - ]) - } - - if (!patcher.srgPatches) { - srg2mcpClean { - dependsOn = [] - input = project(':minecraft').postProcess.output - } - userdevJar { - onlyIf = { t -> true } - } - def patches = project.file('build/genPatchesForUserdev/output/') - patches.mkdirs() - def genPatchesForUserdev = tasks.register('genPatchesForUserdev', GeneratePatches){ - base = project(':minecraft').postProcess.output - modified = applyRangeMapBase.output - originalPrefix = genPatches.originalPrefix - modifiedPrefix = genPatches.modifiedPrefix - output = patches - autoHeader = true - lineEnding = '\n' - } - bakePatches { - dependsOn = [] - input = genPatchesForUserdev.get().output - } - } -} - -tasks.register('downloadLibraries') { - dependsOn ':mcp:setupMCP' - inputs.file version_json - doLast { - def json = version_json.json() - json.libraries.each { lib -> - def artifacts = [lib.downloads.artifact] + lib.downloads.get('archiveClassifier', [:]).values() - artifacts.each { art -> - def target = file('build/libraries/' + art.path) - if (!target.exists()) { - download { - src art.url - dest target - } - } - } - } - } -} - -tasks.register('extractInheritance', ExtractInheritance) { - dependsOn genJoinedBinPatches, downloadLibraries - input = genJoinedBinPatches.cleanJar - doFirst { - def json = version_json.json() - json.libraries.each { lib -> - def artifacts = [lib.downloads.artifact] + lib.downloads.get('archiveClassifier', [:]).values() - artifacts.each { art -> - def target = file('build/libraries/' + art.path) - if (target.exists()) { - addLibrary(target) - } - } - } - } -} - -tasks.register('checkAccessTransformers') { - dependsOn genJoinedBinPatches - inputs.file { - genJoinedBinPatches.cleanJar - } - inputs.files patcher.accessTransformers - doLast { - def vanilla = [:] - def zip = new ZipFile(genJoinedBinPatches.cleanJar.get().asFile) - zip.entries().findAll { - !it.directory && it.name.endsWith('.class') - }.each { entry -> - new ClassReader(zip.getInputStream(entry)).accept(new ClassVisitor(Opcodes.ASM9) { - - String name - - void visit(int version, int access, String name, String sig, String superName, String[] interfaces) { - this.name = name - vanilla[name] = access - } - - FieldVisitor visitField(int access, String name, String desc, String sig, Object value) { - vanilla[this.name + ' ' + name] = access - return null - } - - MethodVisitor visitMethod(int access, String name, String desc, String sig, String[] excs) { - vanilla[this.name + ' ' + name + desc] = access - return null - } - - }, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES) - } - patcher.accessTransformers.each { f -> - TreeMap lines = [:] - f.eachLine { line -> - def idx = line.indexOf('#') - if (idx == 0 || line.isEmpty()) { - return - } - def comment = idx == -1 ? null : line.substring(idx) - if (idx != -1) { - line = line.substring(0, idx - 1) - } - def (modifier, cls, desc) = (line.trim() + ' ').split(' ', -1) - def key = cls + (desc.isEmpty() ? '' : ' ' + desc) - def access = vanilla[key.replace('.', '/')] - if (access == null) { - if ((desc == '*' || desc == '*()') && vanilla[cls.replace('.', '/')] != null) { - println('Warning: ' + line) - } else { - println('Invalid: ' + line) - return - } - } - // TODO: Check access actually changes, and expand inheritance? - lines[key] = [modifier: modifier, comment: comment] - } - f.text = lines.collect { it.value.modifier + ' ' + it.key + (it.value.comment == null ? '' : ' ' + it.value.comment) }.join('\n') - } - } -} - -tasks.register('checkSAS') { - dependsOn extractInheritance - inputs.file { - extractInheritance.output - } - inputs.files patcher.sideAnnotationStrippers - doLast { - def json = extractInheritance.output.json() - patcher.sideAnnotationStrippers.each { f -> - def lines = [] - f.eachLine { line -> - if (line[0] == '\t') { - return // Skip any tabbed lines, those are ones we add - } - def idx = line.indexOf('#') - if (idx == 0 || line.isEmpty()) { - lines.add(line) - return - } - def comment = idx == -1 ? null : line.substring(idx) - if (idx != -1) line = line.substring(0, idx - 1) - - def (cls, desc) = (line.trim() + ' ').split(' ', -1) - cls = cls.replaceAll('\\.', '/') - desc = desc.replace('(', ' (') - if (desc.isEmpty() || json[cls] == null || json[cls]['methods'] == null || json[cls]['methods'][desc] == null) { - println('Invalid: ' + line) - return - } -// def mtd = json[cls]['methods'][desc] - lines.add(cls + ' ' + desc.replace(' ', '') + (comment == null ? '' : ' ' + comment)) - def children = json.values() - .findAll { it.methods?[desc]?.override == cls } - .collect { it.name + ' ' + desc.replace(' ', '') } - as TreeSet - children.each { lines.add('\t' + it) } - } - f.text = lines.join('\n') - } - } -} - -tasks.register('resolveInstallerArtifacts') { - inputs.files(project.configurations.installer) - inputs.files(project.configurations.lwjglNatives) - inputs.files(project.configurations.testCompile) - - ext.outputFile = file('build/installerArtifacts.json') - outputs.file(outputFile) - - doLast { - def result = [ - artifacts : Util.getArtifacts(project.configurations.installer, true), - lwjglNatives : Util.getLWJGLNatives( - project.configurations.lwjglNatives, - project.configurations.testCompile, - lwjglLibraries[0], - lwjglLibraries[1] - ) - ] - outputFile.text = new JsonBuilder(result).toPrettyString() - } -} - -tasks.register('launcherJson') { - dependsOn universalJar, resolveInstallerArtifacts - inputs.file { - universalJar.archiveFile - } - ext { - output = file('build/version.json') - mmcVanilla = rootProject.file('mmcpack-template/patches/net.minecraft.json') - timestamp = Util.iso8601Now() - comment = [ - 'Please do not automate the download and installation of Cleanroom.', - 'Our efforts are supported by ads from the download page.' - // TODO: Donation Page? (Was LexManos') - ] - id = "1.12.2-Cleanroom-${project.version}" - } - inputs.file mmcVanilla - inputs.file resolveInstallerArtifacts.outputFile - outputs.file output - doLast { - def json_vanilla = mmcVanilla.json() - def json = [ - _comment_ : comment, - id : id, - time : timestamp, - releaseTime : timestamp, - type : 'release', - mainClass : 'top.outlands.foundation.boot.Foundation', - assetIndex : json_vanilla.assetIndex, - assets : json_vanilla.assetIndex.id, - downloads : [ - client: [ - url : 'https://piston-data.mojang.com/v1/objects/0f275bc1547d01fa5f56ba34bdc87d981ee12daf/client.jar', - sha1: '0f275bc1547d01fa5f56ba34bdc87d981ee12daf', - size: 10180113 - ], - server: [ - url : 'https://piston-data.mojang.com/v1/objects/886945bfb2b978778c3a0288fd7fab09d315b25f/server.jar', - sha1: '886945bfb2b978778c3a0288fd7fab09d315b25f', - size: 30222121 - ] - ], - javaVersion : [ - component : 'java-runtime-epsilon', - majorVersion: 25 - ], - complianceLevel : 1, - minimumLauncherVersion : 18, - minecraftArguments : [ - '--username', '${auth_player_name}', - '--version', '${version_name}', - '--gameDir', '${game_directory}', - '--assetsDir', '${assets_root}', - '--assetIndex', '${assets_index_name}', - '--uuid', '${auth_uuid}', - '--accessToken', '${auth_access_token}', - '--userType', '${user_type}', - '--tweakClass', 'net.minecraftforge.fml.common.launcher.FMLTweaker', - '--versionType', 'Forge' - ].join(' '), - libraries : new ArrayList(json_vanilla.libraries) - ] - - json.libraries.add([ - name : "${project.group}:${project.name}:${project.version}", - downloads: [ - artifact: [ - path: "${project.group.replace('.', '/')}/${project.name}/${project.version}/${project.name}-${project.version}.jar", - url : '', - sha1: Util.sha1(universalJar.archiveFile.get().asFile), - size: universalJar.archiveFile.get().asFile.length() - ] - ] - ]) - - def cache = new JsonSlurper().parse(resolveInstallerArtifacts.outputFile) - cache.artifacts.each { key, lib -> - def nameParts = (lib.name as String).split(':') - if (nameParts.length >= 4) { - def rawClassifier = nameParts[3].contains('@') ? nameParts[3].split('@')[0] : nameParts[3] - def mergedVersion = "${nameParts[2]}-${rawClassifier}" - def mergedName = "${nameParts[0]}:${nameParts[1]}:${mergedVersion}" - json.libraries.add([ - name : mergedName, - downloads: [ - artifact: [ - path: lib.downloads.artifact.path, - url : lib.downloads.artifact.url, - sha1: lib.downloads.artifact.sha1, - size: lib.downloads.artifact.size - ] - ] - ]) - } else { - json.libraries.add(lib) - } - } - cache.lwjglNatives.each { key, lib -> - json.libraries.add(lib) - } - - output.text = new JsonBuilder(json).toPrettyString() - } -} - -tasks.register('installerJson') { - dependsOn launcherJson, genClientBinPatches/*, createClientSRG, createServerSRG*/ - ext { - output = file('build/install_profile.json') - installer_tools = "net.minecraftforge:installertools:$props.installer_tools_version" - } - inputs.file universalJar.archiveFile - inputs.file genClientBinPatches.toolJar - inputs.file launcherJson.output - outputs.file output - doLast { - def libs = [ - "${project.group}:${project.name}:${project.version}": [ - name : "${project.group}:${project.name}:${project.version}", - downloads: [ - artifact: [ - path: "${project.group.replace('.', '/')}/${project.name}/${project.version}/${project.name}-${project.version}.jar", - // Do not include the URL so that the installer/launcher won't grab it. This is also why we don't have the universal classifier - url : '', - sha1: Util.sha1(universalJar.archiveFile.get().asFile), - size: universalJar.archiveFile.get().asFile.length() - ] - ] - ] - ] - def json = [ - _comment_ : launcherJson.comment, - spec : 0, - profile : rootProject.name, - version : launcherJson.id, - icon : 'data:image/png;base64,' + new String(Base64.getEncoder().encode(Files.readAllBytes(rootProject.file('icon.ico').toPath()))), - json : '/version.json', - path : "${project.group}:${project.name}:${project.version}", - logo : '/big_logo.png', - minecraft : props.minecraft_version, - welcome : 'installer.welcome.message', - data : [] as Map, - processors: [] - ] - Util.getClasspath(project, libs, project(':mcp').mcp.config.get().descriptor) // Tell it to download mcp_config - json.libraries = libs.values().sort { a, b -> a.name.compareTo(b.name) } - - output.text = new JsonBuilder(json).toPrettyString() - } -} - -tasks.register('extractObf2Srg', ExtractMCPData) { - dependsOn ':mcp:downloadConfig' - config = project(':mcp').downloadConfig.output -} - -tasks.register('deobfDataLzma') { - dependsOn extractObf2Srg - ext { - output_srg = file('build/deobfDataLzma/data.srg') - output = file('build/deobfDataLzma/data.lzma') - } - - doLast { - IMappingFile.load(extractObf2Srg.output.get().getAsFile()).write(output_srg.toPath(), IMappingFile.Format.SRG, false) - output_srg.withInputStream { ins -> - output.withOutputStream { outs -> - def lz = new LZMACompressorOutputStream(outs) - - def buf = new byte[0x100] - while ((i = ins.read(buf)) != -1) - lz.write(buf, 0, i) - - lz.close() - } - } - } -} - -universalJar { - from(extra_files) - dependsOn(extractObf2Srg) - from(extractObf2Srg.output) { - rename { - "deobf_data-${props.minecraft_version}.tsrg" // TODO: Spacing? - } - } - dependsOn(genRuntimeBinPatches) - from(genRuntimeBinPatches.output) { - rename { - 'binpatches.pack.lzma' - } - } - doFirst { - def classpath = new StringBuilder() - def artifacts = Util.getArtifacts(project.configurations.installer, false) - artifacts.each { key, lib -> - classpath.append("libraries/${lib.downloads.artifact.path} ") - } - classpath += "minecraft_server.${props.minecraft_version}.jar" - manifest.attributes([ - 'Timestamp' : new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"), - 'Main-Class' : 'net.minecraftforge.fml.relauncher.ServerLaunchWrapper', - 'Class-Path' : classpath.toString(), - 'Tweak-Class': 'net.minecraftforge.fml.common.launcher.FMLTweaker' - ]) - manifest.attributes([ - 'Specification-Title' : props.title, - 'Specification-Vendor' : props.vendor, - 'Specification-Version' : spec_version, - 'Implementation-Title' : project.group, - 'Implementation-Version': props.last_forge_version, - 'Implementation-Vendor' : props.vendor - ], 'net/minecraftforge/common/') - } - - archiveClassifier = 'universal' -} - -tasks.register('downloadInstaller', DownloadMavenArtifact) { - artifact = 'com.cleanroommc:installer:2.0.+:shrunk' - changing = true -} - -tasks.register('installerJar', Zip) { - dependsOn downloadInstaller, installerJson, launcherJson, genClientBinPatches, genServerBinPatches -/*, 'signUniversalJar'*/ - archiveClassifier = 'installer' - archiveExtension = 'jar' //Needs to be Zip task to not override Manifest, so set extension - destinationDirectory = file('build/libs') - from(extra_files) - from(rootProject.file('/src/main/resources/forge_logo.png')) { - rename { 'big_logo.png' } - } - from(rootProject.file('/src/main/resources/url.png')) - from(universalJar) { - into("/maven/${project.group.replace('.', '/')}/${project.name}/${project.version}/") - rename { "${project.name}-${project.version}.jar" } - } - from(installerJson.output) - from(launcherJson.output) - from(zipTree(downloadInstaller.output)) { - duplicatesStrategy = DuplicatesStrategy.EXCLUDE - } -} - -def versionDetailsClosure = rootProject.extensions.extraProperties.get('versionDetails') -def details = ((Closure) versionDetailsClosure).call() - -tasks.register('createMMCPack', CreateMMCPackTask) { - dependsOn launcherJson, universalJar - group = 'build' - description = 'Creates a MultiMC/Prism instance package for Cleanroom' - - versionJson = launcherJson.output - templateDir = rootProject.layout.projectDirectory.dir('mmcpack-template') - universalJarFile = universalJar.archiveFile - cleanroomVersion = rootProject.version.toString() - isRelease = !rootProject.version.toString().contains('+') - - def verStr = rootProject.version.toString() - def isRel = !verStr.contains('+') - def isCI = verStr.contains('.run.') - def suffix = '' - if (!isRel && !isCI) { - suffix = details.isCleanTag ? '-local' : '-dirty-local' - } - outputZip = layout.buildDirectory.file("libs/cleanroom-${verStr}${suffix}.zip") -} - -publish.dependsOn createMMCPack - -// TODO: Signing -/* -[universalJar, installerJar].each { t -> - task "sign${t.name.capitalize()}"(type: SignJar, dependsOn: t) { - onlyIf { - JAR_SIGNER != null && t.state.failure == null - } - def jarsigner = JAR_SIGNER == null ? [: ] : JAR_SIGNER - alias = 'forge' - storePass = jarsigner.storepass - keyPass = jarsigner.keypass - keyStore = jarsigner.keystore - inputFile = t.archivePath - outputFile = t.archivePath - doFirst { - project.logger.lifecycle('Signing: ' + inputFile) - } - } - t.finalizedBy(tasks.getByName("sign${t.name.capitalize()}")) -} - */ - -// TODO: MDK Task - -userdevConfig { - dependsOn resolveInstallerArtifacts - //noinspection GroovyAssignabilityCheck - libraries.addAll(project.provider { - def cache = new JsonSlurper().parse(resolveInstallerArtifacts.outputFile) - cache.artifacts.values().collect { it.name } - }) - libraries.add('net.minecraftforge:legacydev:0.2.3.+:fatjar') - universalFilters.add('^(?!binpatches\\.pack\\.lzma$).*$') - runs { - client { - main 'com.cleanroommc.boot.MainClient' - - environment 'tweakClass', 'net.minecraftforge.fml.common.launcher.FMLTweaker' - environment 'mainClass', 'top.outlands.foundation.boot.Foundation' - environment 'assetIndex', '{asset_index}' - environment 'assetDirectory', '{assets_root}' - environment 'nativesDirectory', '{natives}' - environment 'MC_VERSION', props.minecraft_version - environment 'MCP_MAPPINGS', '{mcp_mappings}' - environment 'MCP_TO_SRG', '{mcp_to_srg}' - environment 'FORGE_GROUP', project.group - environment 'FORGE_VERSION', props.last_forge_version - } - - server { - main 'com.cleanroommc.boot.MainServer' - - environment 'tweakClass', 'net.minecraftforge.fml.common.launcher.FMLServerTweaker' - environment 'mainClass', 'top.outlands.foundation.boot.Foundation' - environment 'MC_VERSION', props.minecraft_version - environment 'MCP_MAPPINGS', '{mcp_mappings}' - environment 'MCP_TO_SRG', '{mcp_to_srg}' - environment 'FORGE_GROUP', project.group - environment 'FORGE_VERSION', props.last_forge_version - } - } -} - -tasks.register('userdevExtras', Jar) { - dependsOn classes - from sourceSets.userdev.output - archiveClassifier = 'userdev-temp' -} - -tasks.register('userdevExtrasReobf', ReobfuscateJar) { - dependsOn userdevExtras, createMcp2Srg - input = tasks.userdevExtras.archiveFile - srg = tasks.createMcp2Srg.output -} - -tasks.register("cleanroomClientNsight", Exec) { - group 'forgegradle runs' - dependsOn { - tasks.cleanroomClient.dependsOn - } - doFirst { - def os = org.gradle.internal.os.OperatingSystem.current() - if (!os.isWindows() && !os.isLinux()) { - throw new GradleException("$it.name is only supported on Windows and Linux") - } - os = os.isWindows() ? "Windows" : "Linux" - - def activity = props.nsight_activity - if (!activity) { - throw new InvalidUserDataException("\"nsight_activity\" from \"gradle.properties\" must not be empty!") - } - - def ngfxPath = props.nsight_ngfx_path - if (!ngfxPath) { - throw new InvalidUserDataException("\"nsight_ngfx_path\" from \"gradle.properties\" must not be empty!") - } - - def javaExec = tasks.cleanroomClient.javaLauncher.get().executablePath.asFile.absolutePath - def args = [ - "-classpath", rootProject.layout.projectDirectory.file('gradle/wrapper/gradle-wrapper.jar'), - "org.gradle.wrapper.GradleWrapperMain", - tasks.cleanroomClient.name - ] - - logger.lifecycle "\nJava Executable: $javaExec" - logger.lifecycle "Nsight Graphics NGFX Path: $ngfxPath\n" - - commandLine = [ - ngfxPath, - "--activity", activity, - "--platform", os, - "--wait-hotkey", - "--dir", workingDir, - "--output-dir", workingDir, - "--exe", javaExec, - "--args", args.join(" ") - ] - } -} - -userdevJar { - dependsOn userdevExtrasReobf - from(zipTree(tasks.userdevExtrasReobf.output)) { - into '/inject/' - } - from(sourceSets.userdev.output.resourcesDir) { - into '/inject/' - } - archiveClassifier = 'userdev' // Should be 'userdev' but FG5 hardcoded pre1.13 versions to userdev3 -} - -if (project.hasProperty('UPDATE_MAPPINGS')) { - extractRangeMap { - sources sourceSets.test.java.srcDirs - } - applyRangeMap { - sources sourceSets.test.java.srcDirs - } - sourceSets.test.java.srcDirs.each { extractMappedNew.addTarget it } -} - -tasks.named("assemble") { - dependsOn(universalJar, installerJar, createMMCPack) -} - - -publishing { - repositories { - maven { - name = "cleanroom" - url = 'https://repo.cleanroommc.com/releases' - credentials(PasswordCredentials) - authentication { - basic(BasicAuthentication) - } - } - } - publications { - maven(MavenPublication) { - groupId = "com.cleanroommc" - artifactId = "cleanroom" - version = rootProject.version - from components.java - artifact userdevJar - artifact universalJar - artifact sourcesJar - artifact installerJar - artifact createMMCPack.outputZip - } - } -} diff --git a/projects/mcp/build.gradle b/projects/mcp/build.gradle deleted file mode 100644 index 80825a06b..000000000 --- a/projects/mcp/build.gradle +++ /dev/null @@ -1,16 +0,0 @@ - -def props = project.properties - -apply plugin: 'top.outlands.gradle.mcp' - -repositories { - maven { - name = "outlandsReleases" - url = "https://maven.outlands.top/releases" - } -} - -mcp { - config = props.minecraft_version + '-' + props.mcp_version - pipeline = 'joined' -} \ No newline at end of file diff --git a/projects/minecraft/build.gradle b/projects/minecraft/build.gradle deleted file mode 100644 index a5828ce67..000000000 --- a/projects/minecraft/build.gradle +++ /dev/null @@ -1,59 +0,0 @@ -import com.cleanroommc.gradle.helpers.ProjectConstants - -def props = project.properties - -evaluationDependsOn(':mcp') -apply plugin: 'top.outlands.gradle.patcher' - -repositories { - mavenLocal() - maven { - name = "outlandsReleases" - url = "https://maven.outlands.top/releases" - } - mavenCentral() -} - -dependencies { - implementation ('net.minecraftforge:mergetool:0.2.3.3:forge') { - exclude group: 'org.ow2.asm', module: 'asm-tree' - exclude group: 'org.ow2.asm', module: 'asm-util' - exclude group: 'org.ow2.asm', module: 'asm' - } -} - -patcher { - removeDefaultRuns() - parent = project(':mcp') - mcVersion = props.minecraft_version - patchedSrc = file('src/main/java') - - mappings channel: props.mapping_channel, version: props.mapping_version - processor = ProjectConstants.PATCHER_POST_PROCESSOR - - runs { - minecraftClient { - client true - taskName 'minecraftClient' - ideaModule "${rootProject.name}.${project.name}.main" - - main 'net.minecraft.client.main.Main' - workingDirectory project.file('run') - - args '--gameDir', '.' - args '--version', props.minecraft_version - args '--assetsDir', downloadAssets.output - args '--assetIndex', '{asset_index}' - args '--accessToken', '0' - } - - minecraftServer { - client false - taskName 'minecraftServer' - ideaModule "${rootProject.name}.${project.name}.main" - - main 'net.minecraft.server.MinecraftServer' - workingDirectory project.file('run') - } - } -} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 929ed81dd..ab7e11204 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,10 +1,18 @@ -rootProject.name = 'Cleanroom' - -include ':mcp' -include ':minecraft' -include ':cleanroom' - -project(":mcp").projectDir = file("projects/mcp") -project(":minecraft").projectDir = file("projects/minecraft") -project(":cleanroom").projectDir = file("projects/cleanroom") +pluginManagement { + repositories { + maven { + name = 'CleanroomMC' + url = 'https://repo.cleanroommc.com/releases' + } + // MinecraftForge hosts CleanroomGradle's transitive plugin deps (srgutils + renamer-gradle). + maven { + name = 'MinecraftForge' + url = 'https://maven.minecraftforge.net/' + } + gradlePluginPortal() + } +} +plugins { + id 'org.gradle.toolchains.foojay-resolver-convention' version '1.0.0' +} From 2ba255272a706fc3de1e6d3577d2571f8f322ff2 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Sat, 18 Jul 2026 03:03:39 +0100 Subject: [PATCH 05/99] Step 1 of Rewrite - CG 0.2.0 - Beginning rewriting `build.gradle` - Redirected Cleanroom Feature Proposal Guidelines to index rather than local MD file - Removed said `CFP_GUIDELINES.md` - Changed paths of some actions' routines - Modified gitignore a little - Removed `buildSrc/` - Rewritten versioning, though still similar to before - Removed icon, fetch from `Resources` repository in the future - Moved Forge's `LICENSE` back to Forge's directory - "Mock" modules to simulate "subprojects" --- .github/DISCUSSION_TEMPLATE/draft.yml | 2 +- .github/workflows/BuildTest.yml | 11 +- .gitignore | 5 +- CFP_GUIDELINES.md | 8 - build.gradle | 413 +++++------------- buildSrc/build.gradle | 8 - .../gradle/helpers/ProjectConstants.groovy | 15 - .../helpers/tasks/GenVersionTask.groovy | 28 -- .../gradle/helpers/tasks/Util.groovy | 24 - gradle.properties | 29 +- icon.ico | Bin 47492 -> 0 bytes .../java/zone/rong/mixinbooter/Context.java | 116 ++--- .../rong/mixinbooter/IEarlyMixinLoader.java | 0 .../rong/mixinbooter/ILateMixinLoader.java | 0 .../mixinbooter/IMixinConfigHijacker.java | 66 +-- .../mixinbooter/MixinBooterModContainer.java | 0 .../rong/mixinbooter/MixinBooterPlugin.java | 0 .../zone/rong/mixinbooter/MixinLoader.java | 0 .../main/java/zone/rong/mixinbooter/Tags.java | 0 .../mixinbooter/service/ModDiscoverer.java | 0 .../rong/mixinbooter/util/Environment.java | 0 LICENSE => module/forge/LICENSE | 0 settings.gradle | 2 +- 23 files changed, 224 insertions(+), 503 deletions(-) delete mode 100644 CFP_GUIDELINES.md delete mode 100644 buildSrc/build.gradle delete mode 100644 buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/ProjectConstants.groovy delete mode 100644 buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/GenVersionTask.groovy delete mode 100644 buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/Util.groovy delete mode 100644 icon.ico rename module/{ => builtin}/mixinbooter/src/main/java/zone/rong/mixinbooter/Context.java (95%) rename module/{ => builtin}/mixinbooter/src/main/java/zone/rong/mixinbooter/IEarlyMixinLoader.java (100%) rename module/{ => builtin}/mixinbooter/src/main/java/zone/rong/mixinbooter/ILateMixinLoader.java (100%) rename module/{ => builtin}/mixinbooter/src/main/java/zone/rong/mixinbooter/IMixinConfigHijacker.java (96%) rename module/{ => builtin}/mixinbooter/src/main/java/zone/rong/mixinbooter/MixinBooterModContainer.java (100%) rename module/{ => builtin}/mixinbooter/src/main/java/zone/rong/mixinbooter/MixinBooterPlugin.java (100%) rename module/{ => builtin}/mixinbooter/src/main/java/zone/rong/mixinbooter/MixinLoader.java (100%) rename module/{ => builtin}/mixinbooter/src/main/java/zone/rong/mixinbooter/Tags.java (100%) rename module/{ => builtin}/mixinbooter/src/main/java/zone/rong/mixinbooter/service/ModDiscoverer.java (100%) rename module/{ => builtin}/mixinbooter/src/main/java/zone/rong/mixinbooter/util/Environment.java (100%) rename LICENSE => module/forge/LICENSE (100%) diff --git a/.github/DISCUSSION_TEMPLATE/draft.yml b/.github/DISCUSSION_TEMPLATE/draft.yml index b83a1aa88..d648fcf31 100644 --- a/.github/DISCUSSION_TEMPLATE/draft.yml +++ b/.github/DISCUSSION_TEMPLATE/draft.yml @@ -50,7 +50,7 @@ body: attributes: label: Guidelines description: | - View the guidelines here: [Cleanroom Feature Proposal Guidelines](../blob/main/CFP_GUIDELINES.md) + View the guidelines here: [Cleanroom Feature Proposal Guidelines](https://github.com/CleanroomMC/Cleanroom/discussions/63#discussion-6236162) options: - label: I have and will continue to adhere to the guidelines required: true diff --git a/.github/workflows/BuildTest.yml b/.github/workflows/BuildTest.yml index a8578f99d..409d93f45 100644 --- a/.github/workflows/BuildTest.yml +++ b/.github/workflows/BuildTest.yml @@ -10,12 +10,11 @@ name: Build and Upload Test Artifact on: push: paths: - - 'src/**' + - 'module/**' - 'buildSrc/**' - 'patches/**' - - 'projects/**/build.gradle' - - 'projects/kirino' - 'build.gradle' + - 'settings.gradle' - 'gradle.properties' - 'script/**' - '.github/**' @@ -69,17 +68,17 @@ jobs: - name: Upload Universal Jar uses: actions/upload-artifact@v7 with: - path: projects/cleanroom/build/libs/*-universal.jar + path: build/libs/*-universal.jar archive: false - name: Upload Installer Jar uses: actions/upload-artifact@v7 with: - path: projects/cleanroom/build/libs/*-installer.jar + path: build/libs/*-installer.jar archive: false - name: Upload MMC pack zip uses: actions/upload-artifact@v7 with: - path: projects/cleanroom/build/libs/*.zip + path: build/libs/*.zip archive: false diff --git a/.gitignore b/.gitignore index 3b84fb0a4..6fb5d12ea 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,14 @@ /.idea/* /.run/ /.gradle/ +/build/ /run/ # Patched Minecraft source /module/minecraft/ /buildSrc/.gradle/ /buildSrc/build/ /buildSrc/out/ -/logs/ -build/ -version.txt + module/cleanroom/src/main/java/com/cleanroommc/common/CleanroomVersion.java !/.idea/icon.svg diff --git a/CFP_GUIDELINES.md b/CFP_GUIDELINES.md deleted file mode 100644 index d109bfed2..000000000 --- a/CFP_GUIDELINES.md +++ /dev/null @@ -1,8 +0,0 @@ -# Cleanroom Feature Proposal Guidelines - -1. Be as descriptive as possible! -2. Keep the content sensible. -3. Keep the profanities to a minimal level. -4. Don't spam proposals that are still in draft stage, the triage will take a look at it in due time! -5. Or, just don't spam at all! -6. Feel free to ping a triage member whenever the proposal has moved to a new stage, but only once! \ No newline at end of file diff --git a/build.gradle b/build.gradle index 043f81331..2a244400b 100644 --- a/build.gradle +++ b/build.gradle @@ -1,334 +1,155 @@ -import com.cleanroommc.gradle.helpers.ProjectConstants -import com.cleanroommc.gradle.helpers.tasks.Util -import com.palantir.gradle.gitversion.VersionDetails - plugins { id 'java-library' + id 'com.cleanroommc.gradle' id 'idea' id 'maven-publish' - id 'com.cleanroommc.gradle' version '0.0.1' } -// buildSrc path -apply plugin: 'com.palantir.git-version' - -def props = project.properties -def sysProps = System.getProperties() -VersionDetails details = versionDetails() - group = 'com.cleanroommc' - -if (project.hasProperty("release")) { - version = details.lastTag -} else if (!project.hasProperty("run_number")) { - version = "${details.lastTag}+build.${details.commitDistance}" -} else { - version = "${details.lastTag}+build.${details.commitDistance}.run.${props.run_number}" -} - -def version_txt = new File(project.projectDir, "version.txt") -version_txt.write(version.toString()) - -println "Setting up Cleanroom $version" -if (project.hasProperty('run_number')) println("On GitHub runs #${props.run_number}") -println "Java: ${ -> sysProps['java.version']} | JVM: ${ -> sysProps['java.vm.version']} | Vendor: ${ -> sysProps['java.vendor']} | Architecture: ${ -> sysProps['os.arch']}" +com.cleanroommc.gradle.api.Versioning.apply(project) java { - toolchain.languageVersion = JavaLanguageVersion.of(25) + toolchain.languageVersion = JavaLanguageVersion.of(providers.gradleProperty('java_major').get()) + withSourcesJar() } -tasks.withType(JavaCompile).configureEach { - options.compilerArgs += ProjectConstants.COMPILER_JVM_ARGUMENTS - options.encoding = 'UTF-8' -} +def modules = ['minecraft', 'forge', 'cleanroom', 'kirino', 'builtin/mixinbooter'] sourceSets { main { - java { - srcDirs = [ - "$rootDir/module/cleanroom/src/main/java", - "$rootDir/module/forge/src/main/java", - "$rootDir/module/mixinbooter/src/main/java", - "$rootDir/module/minecraft/src/main/java", - "$rootDir/module/kirino/src/main/java" - ] - } - resources { - srcDirs = [ - // module/cleanroom has no resources yet; Gradle ignores missing dirs. - "$rootDir/module/cleanroom/src/main/resources", - "$rootDir/module/forge/src/main/resources", - "$rootDir/module/kirino/src/main/resources" - ] - } + java.srcDirs = modules.collect { "module/${it}/src/main/java" } + resources.srcDirs = modules.collect { "module/${it}/src/main/resources" } } test { - compileClasspath += sourceSets.main.runtimeClasspath - runtimeClasspath += sourceSets.main.runtimeClasspath - java { - srcDirs = [ - "$rootDir/module/cleanroom/src/test/java", - "$rootDir/module/forge/src/test/java", - "$rootDir/module/kirino/src/test/java" - ] - } - resources { - srcDirs = [ - "$rootDir/module/cleanroom/src/test/resources", - "$rootDir/module/forge/src/test/resources" - ] - } + java.srcDirs = modules.collect { "module/${it}/src/test/java" } + resources.srcDirs = modules.collect { "module/${it}/src/test/resources" } } } -cleanroom { - patchDev { - minecraft { - source.set(cleanroom.localCacheDirectory.map { it.dir('sourceSets/mcp/sources').asFile }) - dependsOn 'remapSrg2Mcp' +var open_arguments = [ + '--add-opens=java.base/jdk.internal.loader=ALL-UNNAMED', + '--add-opens=java.base/jdk.internal.reflect=ALL-UNNAMED', + '--add-opens=java.base/java.lang=ALL-UNNAMED', + '--add-opens=java.base/java.lang.reflect=ALL-UNNAMED' +] + +var export_arguments = [ + '--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED', + '--add-exports=java.base/jdk.internal.reflect=ALL-UNNAMED' +] + +def asm_version = providers.gradleProperty('asm_version').get() + +configurations.configureEach { + resolutionStrategy.eachDependency { details -> + switch ("${details.requested.group}:${details.requested.name}") { + case 'com.google.guava:guava': details.useVersion '33.6.0-jre'; break + case 'com.google.code.gson:gson': details.useVersion '2.14.0'; break + case 'it.unimi.dsi:fastutil': details.useVersion '8.5.18'; break + case 'org.apache.commons:commons-lang3': details.useVersion '3.20.0'; break + case 'commons-io:commons-io': details.useVersion '2.22.0'; break + case 'commons-codec:commons-codec': details.useVersion '1.22.0'; break + case 'org.apache.commons:commons-compress': details.useVersion '1.28.0'; break + case 'commons-logging:commons-logging': details.useVersion '1.4.0'; break + case 'org.apache.httpcomponents:httpclient': details.useVersion '4.5.14'; break + case 'org.apache.httpcomponents:httpcore': details.useVersion '4.4.16'; break + case 'org.apache.logging.log4j:log4j-api': details.useVersion '2.26.0'; break + case 'org.apache.logging.log4j:log4j-core': details.useVersion '2.26.0'; break + case 'net.sf.jopt-simple:jopt-simple': details.useVersion '5.0.4'; break + case 'net.java.dev.jna:jna': details.useVersion '5.19.1'; break + case 'net.java.jinput:jinput': details.useVersion '2.0.10'; break + case 'ca.weblite:java-objc-bridge': details.useVersion '1.2'; break + case 'io.netty:netty-all': details.useVersion '4.2.16.Final'; break } - } -} - -afterEvaluate { - def patchedSrc = file('module/minecraft/src/main/java') - - sourceSets.named('minecraftPatchDev') { - java.srcDirs = [patchedSrc] - } - - // TODO - // The patch-dev source set only feeds diff/copy tasks and can't compile standalone - tasks.named('compileMinecraftPatchDevJava') { enabled = false } - tasks.named('minecraftPatchDevClasses') { enabled = false } - tasks.named('processMinecraftPatchDevResources') { enabled = false } - - tasks.named('copyMinecraftToSourceSet') { - onlyIf { - !patchedSrc.exists() || (patchedSrc.listFiles()?.length ?: 0) == 0 + if (details.requested.version != details.target.version) { + details.because 'Cleanroom Libraries Update' } } } -repositories { - mavenCentral() - maven { - name = 'Cleanroom Maven' - url = 'https://repo.cleanroommc.com/releases/' - } - maven { - url = 'https://maven.arcseekers.com/releases/' - } - maven { - name = 'Outlands' - url = 'https://maven.outlands.top/releases' - } -} - -// TODO: fix on CG side -def mojangRepo = repositories.findByName('Mojang') -if (mojangRepo != null) { - repositories.remove(mojangRepo) - repositories.add(mojangRepo) -} - -ext { - lwjglArch = Util.getCurrentArch() - // Do not change the order unless it is required so - lwjglLibraries = [ - [ - 'lwjgl-glfw', 'lwjgl-jemalloc', 'lwjgl-openal', - 'lwjgl-opengl', 'lwjgl-stb', 'lwjgl-tinyfd', 'lwjgl' - ], - - [ - 'natives-linux-arm64', 'natives-linux-arm32', 'natives-linux', - 'natives-macos-arm64', 'natives-macos', - 'natives-windows-arm64', 'natives-windows-x86', 'natives-windows' - ] - ] -} - -configurations { - configureEach { // LWJGL2 isn't friendly with us, so pye pye - exclude group: 'org.lwjgl.lwjgl' - exclude group: 'com.ibm.icu', module: 'icu4j-core-mojang' - } - - // Don't pull all libraries, if we're missing something, add it to the installer list so the installer knows to download it - installer { - transitive = false - } - api.extendsFrom(installer) - - lwjglNatives { - transitive = false - } - - // Make the joint `main` compile see the Minecraft libraries resolved by CleanroomGradle - implementation.extendsFrom(vanilla) -} - -// TODO: entire dep tree needs to be re-evaluated dependencies { - mcpConfig 'de.oceanlabs.mcp:mcp_config:1.12.2-20260220.202731' - - // TODO - // LWJGL - compileOnly "com.cleanroommc:lwjglx:1.0.0" - installer "com.cleanroommc:lwjglxx:1.1.21" - lwjglLibraries[0].each { - if (it == 'lwjgl') { - installer "org.lwjgl:$it:$props.lwjgl_version:unsafe" - } - else { - installer "org.lwjgl:$it:$props.lwjgl_version" - } - runtimeOnly "org.lwjgl:$it::$lwjglArch" - - lwjglLibraries[1].each { arch -> - lwjglNatives "org.lwjgl:$it:$props.lwjgl_version:$arch" - } - } - // ASM - installer "org.ow2.asm:asm:$props.asm_version" - installer "org.ow2.asm:asm-commons:$props.asm_version" - installer "org.ow2.asm:asm-tree:$props.asm_version" - installer "org.ow2.asm:asm-util:$props.asm_version" - installer "org.ow2.asm:asm-analysis:$props.asm_version" - // Added back deprecated features for mods to load up properly, hosted on outlands - installer "org.ow2.asm:asm-deprecated:$props.asm_deprecated" - - // Hacks - installer "top.outlands:foundation:0.19.8" - installer 'net.lenni0451:Reflect:1.6.4' - installer 'net.lenni0451.commons:unchecked:1.9.2' - installer 'org.javassist:javassist:3.30.2-GA' - - // Regular deps - installer 'com.ibm.icu:icu4j:78.3' - installer 'org.jline:jline:4.1.3' - installer 'org.jline:jline-native:4.1.3' - installer 'net.java.jinput:jinput:2.0.10' - - installer 'lzma:lzma:0.0.1' - installer 'java3d:vecmath:1.5.2' - installer 'net.sf.trove4j:core:3.1.0' - installer 'net.sf.trove4j:experimental:3.1.0' - - installer 'net.sf.jopt-simple:jopt-simple:5.0.4' - - installer 'com.github.oshi:oshi-core-ffm:7.3.2' - installer 'com.github.oshi:oshi-common:7.3.2' - installer 'net.java.dev.jna:jna:5.19.1' - installer 'net.java.dev.jna:jna-platform:5.19.1' - - installer 'it.unimi.dsi:fastutil:8.5.18' - - installer 'com.google.guava:guava:33.6.0-jre' - installer 'com.google.guava:failureaccess:1.0.2' - installer 'com.google.code.gson:gson:2.14.0' - - installer 'org.apache.commons:commons-lang3:3.20.0' - installer 'org.apache.commons:commons-compress:1.28.0' - installer 'commons-codec:commons-codec:1.22.0' - installer 'commons-io:commons-io:2.22.0' - installer 'commons-logging:commons-logging:1.4.0' - installer 'org.apache.maven:maven-artifact:3.9.16' - installer 'org.apache.commons:commons-text:1.15.0' // Some old classes in lang3 moved to here, wtf - - // xz in common-compress need this to work - installer 'org.tukaani:xz:1.12' - - installer 'com.google.code.findbugs:jsr305:3.0.2' - installer 'org.jspecify:jspecify:1.0.0' - - // Apache HTTP, 4 and 5 - installer 'org.apache.httpcomponents.core5:httpcore5:5.4.3' - installer 'org.apache.httpcomponents.core5:httpcore5-h2:5.4.3' - installer 'org.apache.httpcomponents.client5:httpclient5:5.6.1' - - installer 'org.apache.httpcomponents:httpclient:4.5.14' - installer 'org.apache.httpcomponents:httpcore:4.4.16' - - // Netty - installer "io.netty:netty-codec-base:$props.netty_version" - installer "io.netty:netty-buffer:$props.netty_version" - installer "io.netty:netty-common:$props.netty_version" - installer "io.netty:netty-handler:$props.netty_version" - installer "io.netty:netty-resolver:$props.netty_version" - installer "io.netty:netty-transport:$props.netty_version" - installer "io.netty:netty-transport-native-unix-common:$props.netty_version:linux-x86_64" - installer "io.netty:netty-transport-classes-epoll:$props.netty_version" - installer "io.netty:netty-transport-native-epoll:$props.netty_version:linux-x86_64" - installer "io.netty:netty-codec-http:$props.netty_version" - installer "io.netty:netty-codec-http2:$props.netty_version" - installer "io.netty:netty-codec-dns:$props.netty_version" - installer "io.netty:netty-codec-compression:$props.netty_version" - installer "io.netty:netty-resolver-dns:$props.netty_version" - - // Jakarta (javax in Java 8) - installer 'jakarta.xml.ws:jakarta.xml.ws-api:4.0.3' - installer 'jakarta.activation:jakarta.activation-api:2.1.4' - installer 'jakarta.annotation:jakarta.annotation-api:3.0.0' - installer 'jakarta.xml.bind:jakarta.xml.bind-api:4.0.5' - installer 'jakarta.inject:jakarta.inject-api:2.0.1' - - // Logging - installer 'org.apache.logging.log4j:log4j-api:2.26.0' - installer 'org.apache.logging.log4j:log4j-core:2.26.0' - installer 'org.apache.logging.log4j:log4j-slf4j2-impl:2.26.0' - installer 'org.slf4j:slf4j-api:2.0.18' - - // Scripts - installer 'org.glassfish.jaxb:jaxb-runtime:4.0.9' - installer 'org.glassfish.jaxb:jaxb-core:4.0.9' - installer 'com.sun.istack:istack-commons-runtime:4.2.0' - installer 'org.glassfish.corba:glassfish-corba-omgapi:5.0.2' - installer 'org.openjdk.nashorn:nashorn-core:15.7' - - // Mac - installer 'ca.weblite:java-objc-bridge:1.2' - - // Kirino Engine - installer 'org.joml:joml:1.10.9' - installer 'io.github.classgraph:classgraph:4.8.184' + implementation "org.ow2.asm:asm:${asm_version}" + implementation "org.ow2.asm:asm-commons:${asm_version}" + implementation "org.ow2.asm:asm-tree:${asm_version}" + implementation "org.ow2.asm:asm-util:${asm_version}" + implementation "org.ow2.asm:asm-analysis:${asm_version}" + implementation "org.ow2.asm:asm-deprecated:7.1" // Mixin - installer 'com.cleanroommc:sponge-mixin:0.20.12+mixin.0.8.7' - installer annotationProcessor('io.github.llamalad7:mixinextras-common:0.5.4') + implementation 'com.cleanroommc:cleanmix:0.4.6' + implementation 'io.github.llamalad7:mixinextras-common:0.5.4' + + + api 'top.outlands:foundation:0.19.8' + api 'net.lenni0451:Reflect:1.6.4' + api 'net.lenni0451.commons:unchecked:1.9.2' + api 'org.javassist:javassist:3.30.2-GA' + api 'com.google.guava:failureaccess:1.0.2' + api 'com.google.code.findbugs:jsr305:3.0.2' + api 'org.jspecify:jspecify:1.0.0' + api 'lzma:lzma:0.0.1' + api 'java3d:vecmath:1.5.2' + api 'net.sf.trove4j:core:3.1.0' + api 'net.sf.trove4j:experimental:3.1.0' + api 'org.apache.maven:maven-artifact:3.9.16' + api 'org.apache.commons:commons-text:1.15.0' + api 'org.tukaani:xz:1.12' + api 'com.ibm.icu:icu4j:78.3' + api 'org.apache.logging.log4j:log4j-slf4j2-impl:2.26.0' + api 'org.slf4j:slf4j-api:2.0.18' + + // Apache HTTP 5 + api 'org.apache.httpcomponents.core5:httpcore5:5.4.3' + api 'org.apache.httpcomponents.core5:httpcore5-h2:5.4.3' + api 'org.apache.httpcomponents.client5:httpclient5:5.6.1' + + // Jakarta (replaces javax) + api 'jakarta.xml.ws:jakarta.xml.ws-api:4.0.3' + api 'jakarta.activation:jakarta.activation-api:2.1.4' + api 'jakarta.annotation:jakarta.annotation-api:3.0.0' + api 'jakarta.xml.bind:jakarta.xml.bind-api:4.0.5' + api 'jakarta.inject:jakarta.inject-api:2.0.1' + + // Script engines / XML binding + api 'org.glassfish.jaxb:jaxb-runtime:4.0.9' + api 'org.glassfish.jaxb:jaxb-core:4.0.9' + api 'com.sun.istack:istack-commons-runtime:4.2.0' + api 'org.glassfish.corba:glassfish-corba-omgapi:5.0.2' + api 'org.openjdk.nashorn:nashorn-core:15.7' + + // cleanroom + api 'org.jline:jline:4.1.3' + api 'org.jline:jline-native:4.1.3' + api 'com.github.oshi:oshi-core-ffm:7.3.2' + api 'com.github.oshi:oshi-common:7.3.2' + api 'net.java.dev.jna:jna-platform:5.19.1' + + // kirino + // TODO + // compileOnly 'com.cleanroommc:lwjglx:1.0.0' + // api 'com.cleanroommc:lwjglxx:1.1.21' + api 'org.joml:joml:1.10.9' + api 'io.github.classgraph:classgraph:4.8.184' + // test testImplementation platform('org.junit:junit-bom:6.1.0') testImplementation 'org.junit.jupiter:junit-jupiter' testImplementation 'org.junit.vintage:junit-vintage-engine' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' } -tasks.register("genVersion", com.cleanroommc.gradle.helpers.tasks.GenVersionTask) - -tasks.named('compileJava') { - dependsOn tasks.named('genVersion') -} - -tasks.register('setup') { - group = 'setup' - description = 'Materializes the patched Minecraft source base (fresh clones) and generates the version class.' - dependsOn 'copyMinecraftToSourceSet' - dependsOn 'genVersion' - // TODO: move to CG + more robust way to see if setup is needed as switching between branches will be a pain - // Keeps `setup` a no-op once the source base exists; copy task self-guards too. - onlyIf { - def patchedSrc = file('module/minecraft/src/main/java') - !patchedSrc.exists() || (patchedSrc.listFiles()?.length ?: 0) == 0 +tasks.register('printBuildInfo') { + def v = version.toString() + outputs.upToDateWhen { false } + doLast { + logger.lifecycle("Cleanroom ${v}") + logger.lifecycle("Java: ${System.getProperty('java.version')} | JVM: ${System.getProperty('java.vm.version')} | Vendor: ${System.getProperty('java.vendor')} | Arch: ${System.getProperty('os.arch')}") } } -test { - maxParallelForks = 1 - useJUnitPlatform() - testLogging { - events 'passed', 'skipped', 'failed' - } - jvmArgs ProjectConstants.JVM_ARGUMENTS + ProjectConstants.COMPILER_JVM_ARGUMENTS -} +tasks.withType(JavaCompile).configureEach { + dependsOn 'printBuildInfo' + options.encoding = 'UTF-8' + options.compilerArgs += export_arguments +} \ No newline at end of file diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle deleted file mode 100644 index cb9d07752..000000000 --- a/buildSrc/build.gradle +++ /dev/null @@ -1,8 +0,0 @@ -repositories { - gradlePluginPortal() - mavenCentral() -} - -dependencies { - implementation 'com.palantir.gradle.gitversion:gradle-git-version:4.3.0' -} diff --git a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/ProjectConstants.groovy b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/ProjectConstants.groovy deleted file mode 100644 index 83dac7fe1..000000000 --- a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/ProjectConstants.groovy +++ /dev/null @@ -1,15 +0,0 @@ -package com.cleanroommc.gradle.helpers - -interface ProjectConstants { - List JVM_ARGUMENTS = [ - '--add-opens=java.base/jdk.internal.loader=ALL-UNNAMED', - '--add-opens=java.base/jdk.internal.reflect=ALL-UNNAMED', - '--add-opens=java.base/java.lang=ALL-UNNAMED', - '--add-opens=java.base/java.lang.reflect=ALL-UNNAMED' - ] - - List COMPILER_JVM_ARGUMENTS = [ - '--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED', - '--add-exports=java.base/jdk.internal.reflect=ALL-UNNAMED' - ] -} \ No newline at end of file diff --git a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/GenVersionTask.groovy b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/GenVersionTask.groovy deleted file mode 100644 index fbbad3059..000000000 --- a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/GenVersionTask.groovy +++ /dev/null @@ -1,28 +0,0 @@ -package com.cleanroommc.gradle.helpers.tasks - -import com.palantir.gradle.gitversion.VersionDetails; -import org.gradle.api.DefaultTask; -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.InputFile; -import org.gradle.api.tasks.OutputFile; -import org.gradle.api.tasks.TaskAction; - - -abstract class GenVersionTask extends DefaultTask { - @Input - final String lastTag = ((Closure)getProject().rootProject.getExtensions().getExtraProperties().get('versionDetails')).call().lastTag - @InputFile - final File template = new File("${getProject().rootProject.projectDir}/templates/CleanroomVersion.java") - @OutputFile - final File versionClass = new File("${getProject().rootProject.projectDir}/module/cleanroom/src/main/java/com/cleanroommc/common/CleanroomVersion.java") - @TaskAction - void action() { - versionClass.withWriter { def writer -> - template.eachLine { def line -> - def newLine = line.replace("%VERSION%", lastTag) - .replace("%BUILD_VERSION%", getProject().rootProject.version.toString()) - writer.write(newLine + "\n") - } - } - } -} diff --git a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/Util.groovy b/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/Util.groovy deleted file mode 100644 index 575f7b81e..000000000 --- a/buildSrc/src/main/groovy/com/cleanroommc/gradle/helpers/tasks/Util.groovy +++ /dev/null @@ -1,24 +0,0 @@ -package com.cleanroommc.gradle.helpers.tasks - -class Util { - - static def getCurrentArch() { - def osName = System.getProperty("os.name").toLowerCase(); - if (osName.contains("linux")) { - def osArch = System.getProperty("os.arch") - return osArch.startsWith("arm") || osArch.startsWith("aarch64") - ? "natives-linux-${osArch.contains("64") || osArch.startsWith("armv8") ? "arm64" : "arm32"}" - : "natives-linux" - } - if (osName.contains("mac os x") || osName.contains("darwin") || osName.contains("osx")) { - return System.getProperty("os.arch").startsWith("aarch64") ? "natives-macos-arm64" : "natives-macos" - } - if (osName.contains("windows")) { - def osArch = System.getProperty("os.arch") - return osArch.contains("64") - ? "natives-windows${osArch.startsWith("aarch64") ? "-arm64" : ""}" - : "natives-windows-x86" - } - } - -} diff --git a/gradle.properties b/gradle.properties index a6aec10fd..b138773a6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,30 +1,15 @@ -title = Cleanroom -vendor = CleanroomMC +# Project +version = 0.6.0 +# Stage only accepts 'alpha', 'beta', 'rc' or 'release' +version_stage = alpha +java_major = 25 # Libraries asm_version = 9.10.1 -asm_deprecated = 7.1 -netty_version = 4.2.15.Final -lwjgl_version = 3.4.1 -cleanmix_version = 0.7.2 -# Nsight Graphics -# Check https://docs.nvidia.com/nsight-graphics/UserGuide/launch-application-overview.html#cli-arguments-details for details -# Available Activities: -# Frame Debugger | Graphics Capture | GPU Trace Profiler -nsight_activity = Frame Debugger -# NGFX path should be something like this on Windows: C:\\Program Files\\NVIDIA Corporation\\Nsight Graphics 2025.5.0\\host\\windows-desktop-nomad-x64\\ngfx.exe -nsight_ngfx_path = - -# Sets default memory used for Gradle commands. Can be overridden by user or command line properties. -# This is required to provide enough memory for the Minecraft decompilation process. -org.gradle.jvmargs = -Xmx4G -# Allow Gradle to use multi threading. +# Gradle +org.gradle.jvmargs = -Xmx3G org.gradle.parallel=true -# Allow Gradle to cache build to avoid recompiling classes that did not change. org.gradle.caching=true -# Configuration cache: speeds up configuration by reusing the task graph. org.gradle.configuration-cache=true org.gradle.configuration-cache.problems=warn -# Set java home when gradle refuse to respect IDE setting -# org.gradle.java.home=/usr/lib/jvm/java-1.17.0-openjdk-amd64 \ No newline at end of file diff --git a/icon.ico b/icon.ico deleted file mode 100644 index 7e9e449f129cbe443d7ed768c7f41d38d3c03c9b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47492 zcmXV11yodB7kx9-00KjIqbQ9cBF)etB@#-fbhp6JCEZGiARvu&qrec#5CQ@sE#2M! z!|!J;7Ocg3cg{WcoPGA*?-Hr5Do=n%g9iWrfue$pCICReU!edD8~kzT_46G3foUc6 zObP(1;_xp`umAv0(OOzs-BnW_!K5fFEy({=P>}l}4?h4XL}oqr)J-~}5T8A4+Bg|&V@J6l^96BjKjnJbrr-e@8uG0DAzzj-#mQ_WCO;a`k#Y6@L_tw<=j!W}M{=i^T!N}zs zX`d@LatduwfB+o>DL>MbM;?(iqzut`?(fbmFfV+yt3sGiK7d=|F0o{$y=Ns=Siw*k zyaNCLK5*Sf0yR}TCUjb9Cqhj+wMBDh%@iaUbno3Vghhg^v;yg^71%_6ADu4 z-fmm`3YgLcUeBHxJetPMeTg^Za~AC_bScS@{XxA~l%5U`AAjqv>4#Rn#c1)HNAr$z z(f-HaU$3Wqb^+&ik{M+kAA_%)O&mPRHDgx>FcJI?Co8PisL+6`*ayQ40#*84q>s2mmdsRQg59lqx+i0FcQIEst8SeYZy58QB~ z#5ShN{z}ynhKniH3nMjQ7LFh`js3+k2&2r1#bhy25J*JkGp$9CX|Qzny5vKP5jF`1 z3atCwE@V$*^d-;Zr+b+mMqNg=$nz%$R%>AVgt|*M7BSL9_2jw^y9p2(AXD>fhiPgU z#E^A)g~Q6L?rwlzRIC|tn4i${?WBqR+i+RqNL`wHC-N)K-kIm?HpLmedc4V9E zz}TSCNYYK1VF>)IT~K_yysnC_bkW^S)*6x~m=11m2>(}hmZT!Jn!7$EXI);V!d3CQ za;5jSnHiX~?;5fbk{Tr`uo3npE~(-%-;IB$h_7g?Fs;Cy|2$uO1a6(Fa&IHvzVFWx ztQuL$l$KB*PZY0~c+vN5sh&)@J7PfvH;+v-Kbb`7v4zAkW-XRDh2u3NG-lw*u_N6YQs;B17Q2B&4nwHV4#W(SgHp42NDBbaeF2^y)8}fvH zk`&<-?G*o%mCsr)Twh3xd4I;&DtSRvVyNx+N$$lL^~GY`pA;oy#q=+liv`OEH9a-s z)X^G7AKQ$sg3iqds>4F%a>EopYMIsdP{%M+^gOiK(?yKCXk%<}*`_};eN}z7sp5fk zLF>WmtMXjh^|NKEWrAhaU*{hX!k((R-KUe8N`uUU1cScZ7~B%vRpT~gmSz5BPo{jP z+NMmmT(&5-Hl}vmow6jexU!Cf?S)U=ahn92G@3%2rrpu&;-h98-fOr={YQjrGsE&n z_J<#jDA#w!cZM0C@Cm>KO6Yq1aai#qd&9l$ zaI3|~UXB}e%p$gm|8!a&hN_aUTS;rBiZ(yWz%rYsN47Ny)PjnZYzb|GL zzAyZG5Wm7}=wYa5c+twB_9gRP_Bfw??{wFzxz+(+V_|VIi}S%X4DlXuXpT=#c-yBo zmRYejR{wGT41b)<>?;d3?z0*o{Gb>;I zo!3bDcWrPW+f!8Uv0nTeq0n@av}%dvU?zk*FO}MIp~EwJ(*2P4p=z>ic`m?&tHeB$+`DD!d27c^iH5oY-BxnrY$r6rxZQuJjwkuIWsx)qb7lM zY7OTEU;X`hHA_y;B!VUHzxMsKN#Xq`ORQ(E2h-$sp(?{4Yc$K%2`N-~i#WYrQN8kN zP-sFXu!Em$C&HH=>(5Kj(6)$&n9iX!@U{0 zhPzEiryj>!l%9CoD!&bU;=C#@+orD8an6a>18T0TEIRDxPK`T^(ckolb_j99v#*nH zM#JYv%b>T|-lxm5!D+vphMlHaR4Ze~{Y%Mf^@HJaGgRS_+KKqe zo9j#7laPZ8Zh0XzNHUqs6f~a!fX_VuK!yOoE$>9G0)RUo0IVAWfN(khP&#EcX^4V< zz;#m4a|Hl=(%Wwc@Gg@I0Llv#Wu&ycGPhd2Guh<5?_J7`8~CZB%bp5^%dsa85g7Kt5_r0pB+%TZk?V#FynJzuy78l}R zE%46Q$I_>%u=#WI=Z9Z7+9jI4uyb<8HLz9-XU{tNKYD)FL+fa`C%V^@(0d@t_urSU zUT+Cuu3<$9VJAQe`=D~6W01q+jscM2g=S^1_+bNvf$(!W;PB}AXCJDQ*qR-N zk1`0Yo?zqPq>RUD&B9rMY6x}6-6XOX#Ff}x?Zm*gJKYMUNR}#d+JF>K8U`Q~3qQ|a z@y>BJn5Y>cRv**uFV&GV`219!oeE-%i9F_8%GvUP0C=Hases>GP1_ZX<*#ttPEswT z#B*>4ssVtIIb_?7ZYBD&=@_*frg>p3R|gDW1#09a3a($oSDG#`Vj|<3%P%}8+;I~B zoaDkKVXZKL5qu;7+g^82*8SBtQjWob92rRoF?=pQDEM@lNw0*jJM?y=EWq#irftXO za*?QuY}SwtMhZz71hJ|JoJvo)-zdKBh!@l3W07>c(L)jga=>eR>Fdd2v^+>rAsvjh z(_1Ia<;|Z)*Se-Yb*B$3Gv%N!>f)ds0Uib?vqE9-@y51D3D52GvcES~I|ayo{TH}w zI}Dj3d42YVfjPv#aK<5E$bBY8qf3oeM-t`*`@jh8xX_=N`9{WfSF2vfc~yrPOq1@v zWTo;gRd^amfnf*CI@C-2ZQ7nRSy-WdE(xn4M$CrGGVgNLzVGo8jNp?->u$oHjpe@n%`>SK%HlaEX@pI%4~`vqa3Qvu5wao&R1mmd z#@VKC|ALj4IJ~~dxWo_rYAc*II8(mS_M6?G{2N`M80JgZha22zS4>p}0ygO9X@N=p z!*A7M^xGMD|AN(C#o6CM`G7(!^ed+*x_QEV##VnK#V~*jfiQ+JA9_|c*chu?8|P+g zoqzD;`NA-EqKx$x;DbtXrvGdgcR#&PhL`4*eL{_LcCf3TPTf3rhQAco#X#}`9rF4U z_C>MJ+-WC>#N4QlirUmTz$6g^QyuZ(lK|JwL_ozxlf+7sgX)u!I4I(NL&ne@;5QE7 z+34So;6L|fmtcifq;(sm&Qz9%vg+$ zLQ(XETl0+epRcsUxsLRo&lCjz#fne0uVaK7@xMB0D8DGV_P=T(4bXg(y%HMQ!3;Ev zx*Kq}JsPSIIkPAu9HYx8kprk8xmYs9&m`bqR)xXL@NtnW?)zT}!zIvEZhT`6zuIh%{ln)dCdywwaNkvb9ar^bnQqy*X(n8t`M+KND7H}im#^%?zpEBcDXPGNU?hBs z00>~Z5W&y@k6eWwe3C)|J$ifY$t(jHk6xcYTgAk(>toS52;=w;Dg znm=>S;{Rg06Lz_L#!H6RKIu?@!`5OHFg_?v21Vq4Im`;2eSVe&0a&44DJxs@f-*h! zw`bIEeD6B)q_xKAhFyO`OlRExN{{*KK4wTq)cGKCTX{n}2&PW_{v%RRkk|2&}$jKP#pI7O<(WOm|Ig*H?;vK{Aqc`SEyT z#UT7nPE*J13;5t0t2vDFjcjdVWo;QG4+8PHew9R;<%9E zf%w+W1bVvtPJmvZh2B6wYTKh-J>axqqp5CF*NqawvM_2g({9tYKyX`j@r3k|0=8|p zQ7(%R3KL5xaLIwk*vePfCDqiX6gdrirliSBRJGyKaufnU$o1bSUZ&Rb7haec^Qk#2aFdWhS-!t}S{iZ{H8Y5g)RJe*v{1zQd% zg`3A1oA+6X)#S#5IJ`+UTtND@0z2CTgHhH{ZUEq==x zmj3-?YfON_tIPJbQoow`+{}oB#ZwDT+o`%O+o>%#`ZZI? zH7(y8E6H%OhW^PL;mmf0h^Qa8JsQHQ43#u54Mogrq7QDzF7||b*{(B9PAPvCLUyy7 zSrc~q=@ll)io_m7mv04@DB6ck zO3F7<7qguwTVGFR1ecNokeP2Otfb-M-p0K8&_4$Y(($o{D<|(?VScR~@%e{kzujl* zL8kD`rw*J>7m=sm;;SA!t8C$griOHY2x>Cn-px5HchLTm~)*Nz7@QsARG951o!!fBguP z_-`&DhR{%u8?X*kgS{{_Z7?w-Sskg?o^YeYbj>G&5BdEg1dMy%6PpfYay^KQ;zFvJ zSoB;se|QP#uHD1NKF`(VYAYLE+jJCse==G3Oy*huqymg^gzgH@{&~%`{p;G7b4@(^ zqC3Lq1BM?f2RHin$#|HKmc9S%GiETAB^~=jiMDekwG;ADBgJJTj<2J;7us#>r*pvO zO8ai_>z>J5sTnCj$kJ1;xOH%L35Ej9y@Gw1b){QDMl^YyC-7g)=AWaP-Vm~~vPQA! zg%AUN5&k4Vx9Q%vNAuN6?4tgNLw&JXA7VWx`SQwh0v7Zq?8S>FVLpK&1ni0zI7P=U z=KEVol2`S=JIhJ&!|;N#JKQ4STx=-}$(GY?>g;`s6d8;0wPA*qPszLD;3IibsgE6= zB^gM8!$Pc^E7d`Zq>=C+0JvF_i6Yp}2#-B~r?Ar(KuJaNYY)Yn^@j zl=}<=Mwai5Xz%QSsC^j3jroEtLcghJO60hn(y$-)lNezHMG`%YB?V{HBvf*|TEgJX zDpl}pr8voI``nncgEMp1cKR3{cCuj=BQ3X+Gx2yN^imN{9v6jc&xO+4O6m`J2z>b9R#Ca40)5B1hlnID;o*{lK)Aa!cNwUh!WAmiH>1w`*~f9gFUa#xAz> zIcHWE37H>XJCB~!9QCsWFt``LewDYL{1`&;q`*N>TOCFx2b-~&K3- zt{EKi$3Cu~8K8J&gvsUSv}zqP#5h@Z^(@;xG5HZxlHqprB5B=JZqk$rGFQCoK>{z1 za@O_~rr%0i8ct3j{uq0bMrj^H8?EB^<$Q42Mg2Y*007Japd|5|t}|bbs zd@AWQz7aRcrgs$*1&6Ts3`jL2;Z7iJ2fM?tWbEttAmDHXjxtW}8KNQDgVoidcao{b zn36e?7Uy7DU+aVO>C2q|RjK&L{-OMmFQUXwcM}5Od67~wyy@~3Oh4p76#z%v;4>fQ zyegxp-?`KKlBf8y_+&@q@a?o{kPHRxrzll`^#3FTEa<(y>2MWDhp$)g$!5Szu0EDyWYIs4 zna*r`36}L1h+1vhB}Y>YSLfb8zYQ2#3LBXlaD?5}k|t{`%EVwYO$WH`d0W^pRarx> zq0DYpC1cgrehY|C#_%=e&;Z7N{eNe;^+vO}1}sQlyJ^*#ikt$5KgSO@NXg$9ErWy% z=AwBQDnqDzI*rfk=e^5@SbYxrpjQ8~%tP~OMyr<|LYi_`=wGv0Mv&YN2@pZRK67y* zG1O8EsbkPM=2}*?*Bc+D-B%0aAZGIMXpcxoAm(~C1)26lFq%lbQy*g2{I|fa!*At+ z5kBBD!+yGbO^6U=xYd}Fd=&IL7`vaX3XAW~6yFq8KHt3jNMJ9-cI;h33g4Oj=&)P-;R}?Y9wEJiCM;r#*GE&gyFMCZdq*@&HJ>->o(n|qh8CiH3#yWy2^Fe(#^meYj z`(e4{iLJZ9R9jG`vz)~Kuas~#NcR)%{F0RlJcVKph*8dUr_CpO>vspJ3e$!krSjXw zYoV21-7w-1FLqR?oXf>dhIhkYrjmAt8#uZ?d zJ88$jbc80MRW|s1#)&IbMSW{dkb$A)Y`6&rI7}aRYfK-1BDfooy~J*dV2YvdJ3C!V+>U1s^15<+)-V6g9p?b`Qp_)YiAj$pL_Z| zINhei`)8s|A+by$+cp9;C+rk#Z-c|R(bfO)ORf891K+Y&u5Me`dfH3vRw1oN;YGZ`glE7>rQnM1^Y_Ie4<#Sv0R4<-MgV>h*Uo;jw4$MkMOD!xNXa^m4$KGxkG zPhMZ`@t{gt6#nIoqJPjqn z7~djzN&Y zhu7IxuurxU6+(8NKqQ~5)&dIaSJBzF%mZngk;o=BfUMRB*~Pol2nBQ3zx)tDf>?!% zSUmyDk+tC{p{vJ+m)3bNCMHHPHlG%>$lhue9}-TuOPEd{r{>RGjBI~UfJin^A;&4w z;4j`zeED@Z^08hLyX^Tsvn!X*i*tz|a^su+Qx8iQ*qAU=+aFa{Rt_Cx1+tmH0OEW8 z4Q4TLa5=u5stB+e+4gIIGXuJQYYzuz>+h~vN58}GFr$*3sJh|vQe9=OrF;sBtF;?( z&i0ozXaAZNXj%m;(8L9DLF}$4M(h~q>i){1Vv`dS-PG$W5x?c1x^l%@=Z&`Vf0@@A0t|(Fe^8OJh97gQ~D_rQpOKuu^^t&zry#uIL zqAvxeBtLtJwJM{b>I_D~23kE(uf`vVxAnblogC z?UY2s3vFw;ez3_%B-6NSKWU1Xu> z$-~8U2+HZ6-^3Z9*T@R#xOfTTlL>H|5BB`9O)bgE27B2nH;f;zfOt!|IZy3qAA1FJ zhQB^muJ9FlL3$jsy}_(HOj_6PFE}bwl&;w$PC$!VS6BD6xeGz1{=?N7TsIJa`+=;r z5ehKc*1p{FptHK)U?fq|^o0d@Jz!=1shulF0E)D1C}PAyevfnzXmh8#NPDbLeB}E< z9pqO(kFo+oLqmV<+?gA%z;kvkGi-ec+Ig$K5T=7m5E2*war5cpoyodZjs|;PN14YX z8Y}%GSm=kNIbDLvkFG4vlKDT)#x34(9boIm6--9ZT}+gPtGRwR5(aH*fcY@pLN9<% zLgFSs@oE5SeFxM$Bmf8cqb?TPGw#n1>G^M*m+9d!0vTG@D0SRzrh2%1>-6Av$KtOVZ|L}pG z0BWSOMUdsa2)1G!R0gw4o?IXuT%7J7{o_oFQ_5tgQ-US?P(AS$2X3y zA_<@82D!ckiY98=FPOlP(V)ezR{OFn+RJg8lUB6vzEasiRG{14z|TKhOWy{nKqNUS zl9-f$(vYfvapwTdo4mniqnb5; zf{+<>QjcfwfR~V9vYilCF5#$7a>g>Ir z=bLqWk?$$dNE0*53Mut2*m2hvt0ch$BE^b_J6SY0W;* zg3wet6%hmPaFHMu?bz48l$f=tEjrmiVQn2zHX6PUHD2`j{n>K=poVxp&Rvh`fw{`m z+u))<5{}gx3Dm|%DBQ)Vh1@}$F~E=v z0QR~2EgIX@`iHu;`|Izvj4KlGJ50Urd1CK9gN5V>5G{|6n8zL87tMAjUqqKKTYQ?* z!vuED@L6P}NB9#Th9V%~2qcS^m4wmPa&0Ug`CPdQ?CpYFI|>WgZWQok@{(Y>juZ?& z^sOz;V`knrncYwD&5yNT#5dzX;>~$QNZ~x33*J_1-CsUkgTTs=H19ibbio;G8XmXuZ>LZ zh%XxaWK1Mn2bf+e>Wfmn4JbX|g%;CgKL^om3_x;Mgrh;Bc@P|fVCW#d2l>D)c59W4 zwaMudhi&b%{Pz zt-q2>l|Y5CcMffZZ?Ekig`YduQGp<}O0^KP)Ej36ak+QrP6TKICt`MhFGkvL^+(ff z+Zz!XD$uaN`3F^BGNf&KSrND?&mJ5X`lL#5$`s5x+i96&>wbZ@MCfTBBmU}R=})^f z-oe1Y0Dx=@JtA<*UcW3m=BsnX1|yaNWVR+M&Rbptg}u%zPm6u@>jkkWuk(WUDXGxK zGa!P^X(kNYD>HmGyJgcGQ$vu;H11~`$V=W>f$uvd6t##=L~SR^$>$kp{kQ?J&ntvu zUDNERMJ_B(#BcnI^#^6wgC`zJO^P|(2oXNms1}I-iDOHxz5BXXHnBOPx|EIEML{Z= z_xEDyHzA>;{7y*G-xSsXDyhlLE_Nl{uB1YHTyfs3QU8A=8y zvOot-f>8o=Y~9@uqGNL14&I&w-qnSByw$x2Vjl`|?Tqs7{^}cxS(dI`y|||W;cCNx zFoQ0dpS|_#IVx)v&=o==fUa)+Vl9VNP|kyLg46z0?T<8@EiF#m#ZVhfr;=pR311JDela==fU zpHB)ki!*n;|M>l|Jou|!V&O~}L-Vj_Wj>Lau=(9OlE~#>S_4J9nrcl1uCaUhTbgvp0hsiEyv+>eA`OwnuZ`45hE?Rdu<9 zhBN^%<9RFIj5YQbt!3KyzPH*`Ttd668_mkixcurkL_+_)af_%z8s(&=i4ZWM9ZF?P zKikdCszev@9j}PVduk)%pm}xA|BoJo;&hf8^!Jc(pYNb(6@BvLgx5rb6@Wr>wK$kT zPrZH2=I-{t@W0|Ep2|KR&(B9Z;_6Ux;|!dWC9YGIhPL!dl+ob_?rzU7rp`aj%vF{{ zo*XT&1>@wcgS+Pw5`qC%ZIAe#JgL9Tg0KRqw>kH&x1SEMn?AM-XulRJip?MwU5K+S zvPP}x^~a|YsHw8uy_@mCDJ8#56Eh@7BXuQc1aiT_Q zbsOkM`b(FLy#yI>`@PzIAQ>Ndc6L?)j@ZtME%DQC0#@=OZh`rsK0PP>>b)BaSX)9i zQ=XBFYFP3y9XGX1_uB*7?e~czs28GiP-U*j191Sd<^iD5+Y+_dgrOa++`1_aE>2!%pXe*r@ z;EY^-aOHD<-XeyD|INf^$lR<%NYk6=XGbmN$zkD&p!PvlCfuMyHmE%)y#0dLG)VY| zHrh}*YMY%f(g8MDV9^)0R(X{;uLi3K6H*J`y~&d1UL!WCs>3{Y7ViXWSMm((v2T?o z3!ZfB?&aYsubF{2H6r#xPhW+v`C#;faX1Yh$2c{$0pV(y*iTepd@M;aM9P?p1p?i= zcPNjkotc8ToDAff@Wn61y-81F*gj$+I*!6~n>&r4Wn7@O-wj3GU01(~Y~6!h=+3tJ z!7*1jHmhQl)Xb(rorhETy}HW@Hu<@A`gTh7dMah3u@WDOYMu(mj*hYj<=o@DU<3x? z?L-D)i!~$w5FKMt*qTgS^u)xj63RQ>Mr>(=?__S1stALz`gY3jc02&0j-S1whBaZr z5<~#vs-aW1pF*vz%KfL88$aD!O{s(hY2m^|jAD8B5U_Zem@!{e?;R%$9*AjjO!d=% zQI3Y=mKcLVmWN}5h@Tui$1lF;O;~S3h-A8nWiQJ&pabH9c^^UnNtmoaJYavKB4>Q0 zDQE2Cz!0nYLrP>m&$3E~m&LM_3zA}1!S0UkF1%4=V3XnRg5Mj@j&x;~zZTnI_S!sD zaI2t4@wh7hNFLX38Xd!gqw~k-A2$cZY{|;ok-TRI`nXJ{dG8!ZF<+#mY_Y0b!kC@t zpI=(@PA`9KeB?xKSZBtX`R;u<>+`}7qkY;H+3dqOk@Cq%-Aj2N zBEdh3Z#bsq)ri{JW0$gR(O$xR(K(26fq|vGOspNXdR->AlbTYg29+QfQ~#Zi_1Iby zO#HJQeF^9jeJ^daIH}4WOri0B47}g`(Ed8;dm|awvTi@>==7VtT%zNcG~^r)86og_ z+TmMdhH&P)fzEgHc>2|gTP(We z>!;iNsT`WT zNOeP&(7u1$zApz?v!7I*6DLH@(_`>}RN)Q*0ryS&j05WU)Hwvnv3eJ95>B2Aoc5SM zRiXd%*QL@UA4=&si^;AwVeH~VD6B~N6r=SV`J8!`g@fT62Cmt9L&mO5PKfD;!og(z z06Lc~LEIwWQXV%g^@P~8%OQ&wmo_BdI*UHCizG2TV<}=Z3&IV2H9^>k)^EXje<=$m zaPZT6|4ZJc#I!p9HKSBK9DIj6Yovj@34Wpa7hHDR+`xq?~2OWULiSsZnBdh<#3L_KQ5-)h|Ir#i-V zRA9E@-3>2;p^5#ty*1NB3uMD&_%G(bf_5|1rLEXJp3fo>w#3oYS z>Bq;cuo-?{tWAS1QA0h4lER@1{4g(OG(g3uI=N9b}@|xctypo$!>q3L9&t7kH6jY$K6O z^)-h=kNeCBxev`ToH(PM!kVolm$jE#)MbxV9e(|rtt2azl zy=IA&39oWtFb(XEJyDM)R3_w1!6V%ZPhi8;ssMl?1;987#{toC(BW(#By14;<~Eox z<8SN4LV}O+*{wE~AWGX~2Zw!!4|D=bg>AkvnW%X_=vd+pSO8d4AtcGqX6$(tLh_}d z5cvjaXq)|r;8&oPp^66I+c-SLl z!x-s(mh$|-lLJka+ZUhAm|3bgQ}+JThZ`e{MAD5w2MfDW*lwCxqXR9NE9M+@=XnD2 zuLeuZ*i2D^!oPog@hw7En>pv!<1Jbw^s$kq)y67#)AA#9LB9;&gjD47-_*EykHmN6 zagy0axN<*##L2&aC3{KhX&7v@tX;dkp(BxzO(iFP>=@b!V~>%g4ez0gm~zl*0N#B$s3Qp z(-3;&g8gZQf(p7-9{eQ4e5YBno0!Ol=Hf``&LwI17U{_8z|B4C6E$3WJw85%;`ahI z@vH1|n3)fvS&|j&?Mq>>u0@>`b$e57CJs9~b%~D;5Ihl8og^*WQTFQnE1LS%1qHGN zmy7=FF*@v39qZ5k!sVzy&HH(b1C;BZ7$nv{J#UHxt}ub&U5TgsT=;>-G)o6he^uJJ z>A}ALq>=IW3hI7Em%x3olp^;wqT1>;GUNq@d9sqeBFcFMo}a(xjJkAwb0!TPkj4JB8qj)WhZLN zzc}u}dL}{s4ax|0j+E3buYz-H!AlJ>B1uLF@-a!rj_H{zCSlHJDdwDTf)brhJzJg5 zdD2n7SB@T&d)S_F#Ea|m=Mfe9TJZ^^KyR<@Fv0pg41H6=OWNj>te{rvHbQ}_9!Cr?aR^OO(E-H`VX}t$r|Z;OnnthW4V?^DosE&kl6^jx6>9;I% zrR8Hg!|6b2RH2DS8?_M}gC)Wc)9V@C+bli>XMA5+v^HOeUnn}o<&|mb8HQM3!80-y zDulv&E`=6F^|-2BE5dJ2TURzB(S6{$KqI@-L#gE(;}gd@V<7kJ=I z&IbRn;JbYK+tDd8L$m9q2*4f-c)a(V;vlqRzL-UGgdLH|i*8^nLtCz+?D=$gLR2Q7Us>0&gp(?CntjiC(z#E!LAlHd-a2Aa z8<}Lj>tGNePWTcRn9OGkjhzTg9SxK&v{C=QGGBURYZATkHE?lM-RSk&bO}+ck$j-V zm)zwWzF0l1rtI&ue0Sp?;quELEwK6(oZ+5FF-;VaV<>WBQ3S-UEu)eZ>0)suDEXle zRt>2%v(IcE5LL9hh}_YM4rFkWdkk{)i+5?fPEDAB_Sl0HG>?9s_2{D4v>61XM9A6S;)nVYU7n+DG!4#N$1g$>E!H^F`;^hpZ z-PKjd%!RB;OhO*9!8h2g(^=#&xhS_D#{5#`TN-K)OVESx9zN-L6WFUp623^pVr_wi z<25JM7$1IHWFIkPtrst?1xu+R*-3i}X8Ct*6ISB?#?`2Rrn^mTlgcF^S!>})qU&?k zfO;X-2q<7_m`Y}jfMph#Ki zr{0o@v@~H2zQkP9x^G(<@i=g`LH^cDi)}XMGZ>@4iddWGLul0m|LH7}LrL{S`Xm_6 zZ^U#OPuohR+1!dn#AW4aPOh6aJcHODZAQDsvnI-R`{CmOSPoO0SM zIGc#PuQ`#hx|n+_EDGvAeb47z^n(Px;Jxx3(sHImv2N0LMWSo_NQgE8M6izHcrk2bzx z3%rm0wxS3qR*=wQ%lYze&J%pZhz`d}5Rc`yMknjM%Q`U^qM2<{QGL5Fi@4Od0eJ(l zWYZ4v^?gb}ky0|;BCz2$v>H1hp=Cs)F4ACHP^x4y1nk+4SW;-_i-m`bY-cgl80`D9 zr$anwkGLj&%$dF3pEZn(f4#8`JVW7&?5Rtvmq184C0It593(6H@WWNo6(Y94QP%fg z;J;ngD1J43{+xXJF?N)MgEz3#SCdhZKHma-m5L8dJB9Qr3S@p&qZmRQHuueffZ}zzAWRpp}6NiW$3EaC}6}!dQmNTYV!In z5JAfj<`JdCO1XmC@TwfDna|xqG^U5+*Et4-_L#~6ITf`y3z$c z%{;&7{qU7nB9p3iZnGp3^S*-r*(|R08@l;~bQ9fu>N-^49k(rkbX}8&Uho^!7cl?7 z3qLCDxf#x)RSu%LP_8aaWkd|$u=4(LVP4((m)a!;V*cn?zq@dlyIRcS*xgth42R?Z zwxGG}&ukZLZo>5Gj#Ey#?sBm2XkIQ$%-8Ko-L4A+UGYR!AAw@1aY4;T482QFv=VYo zrc)qXeDeGo-TYlCjk?Gx?rucm?+O&!g^B6_lSJlQ_4{noKZzGzRY9_k(T-vqOUu>E@Ks=N8IL z?d%m@iDz^*P=p*!jyyGZOGdM}qoZS?pGabCM;dc)w0v6a0QFExopSX7z_(pi$B8-8 zQ<-+X?L}Yo#zy7Fu(Oi#Ao5%+_Eb?JnM@$*8aRy%5tuIvzCWZ4w!)^~cqtL+3hcvuj{YFYrF%a1=T4V6#$|rSF7c zhlA#lcg>~83D)V#n*N*eaRm$a7UTAe=M|%LX2Ch~Ff8sq-rdw`oWBW0u#x!2@7U?)j4pj_e zeoflX6tWRP&jag8TKI;e3g!GUh~gZa26(5NXui4hNuUlNaR&Ciqw94U%)gd-w!S#C zcoM0!3ax}=Pg9)I}Ys#VpX$Z z{o@xHc%lTJ9Bc9UL?gbQm9{cNgM9DTLxlX7cXiEA&)eVTj(H7iiIbC^I*4-W zc2h<~>hm@G=IABeMRV}Z&b?}B3Soq^7wdfg5-IHamH&Dg7xa8aEEdUC@xmAP(X!W|kdRw-QDq;&f zJ95JtqXR#eDf2DFvm_m?wQ6XI0|JK~{7V$i&SV7n5%;`PtugR0>g@Y>OsvNRk7lK? z5Y&ryZ6>n0SgcNCfkVWg$J_;tTf;6c!cVvvFPAnUI9@@`k7u}6xe_wLq7_Z^E`X5j z`)Em-t&{;tH;1aNLiTBnsDrkTplCV$seZz@51p&P2$KczdIU63cu`%Br>1U>eBUa5 zONpw}@n1{}|9HKSbRgF-3%y7j)kMTu>Lb$H4l29a@-i=&Ev(g+qnQcvucjR#qBnt@ z;!pa4zLo|JBxoFKzlt8PWAt1n-2IHJ-R*CACEAq!ocSKvXwq`#xrisei!6V5>+t9- z>m;lw#H?pOO#O@PLFi>|WeN}~hMi`{DnZ_@wg&llv|*O~2M#90Z_Y-T**ACL#Vur| zsfF~iqKbyRUpu#6+S_AUIH1tt|Mt<;Lz?-{4y(UjNEJ^37XBR5B}NBrLyED?N3K*f zH8jR}CEQ@{O;^{Y)MetiRwlrya9C_mO$@65np*GRV_u)3p9lxq^7bq$q^Lo(mBB|R zaER>`P)>cJOt;7WyHf>B%l(lz8--A^g7J}NV?3qRq6Ix=83g`Z; zJZLg_<}RUEsQzJtF-A$SS~SOWVI@yC3?AwyRI?iKHyn7#NIFywC3>E72?YC#8~>q; z3ZjMSrNj6(jk<5OxQ+~N?j+Lid$el20Wt_q&BE=H{=K z64$mh&)!rPUvG;A7(A1u-BGvpzyfWT;))Qj)4{zYr>7=OAlCjqDZW94z4zIAV+{Tl zRBn85TvIyGiL?#eFS~ZGCG*4nQf8GNBf`L8eqAD(zOPza?^JV?o>0h)j7OziGNryQ z#}O~0?c&4pDd>60)kcG{1~--qT+w1FW1t3oR}RgG>6MpbpS|TGuT~1_DX%?PMMIy^ z<@i1bE!dkk%l!rnfNu7qtY0wSEn|byFs7lS;-+%M$6Gv(W~I(9)FTNAEoDWlufF^` zl;>X_4%9j5&6q+DGkzt5r`o%Scvh^xXM4pGW);uxEW*L3(KJsRK@TY`*jC#mH7wC= zF%1H@Mr$w+Rl~SGRDhS%*i(HUO)N!LJbEKPp;CH z6ofQ;(VQ|#lqG5UpvWH!1L|88n0w^W<$qKmM%1vOK_%}%u4*0Crg9O}x<|K)t!`4L z8Qm1WZ?5%qR!9IKyg+ua1l!lXwi!{><9JvW5j5Aw81pQucFTQFT=nTA%xXYH4=lyx z{_fiOPE}m-FT<4(D)_53>9r8X`uIU$o?Gx>boAxW=dUeTayroQ zO0QVqFT+1Roh#3qeHRq5W%2?&`>(hRQvG*OV<%%8zx|pZWGABZen?B9gXk9wj3L6s&Ic(p6@2WQtVGmt~`p>Z+YXemn@(l>wH zG0MLAQZWCs5ry(9Q_DO_G>*hmy*+HLpBXvru%NBHvlgEBT)P5lnwg3_=YMp}uT}HG zh8u!xwtJ`y?Uac(nY*Aw74MGbAS!7psBInYHt*h=_(tvRxwH)Ep zANA1&#tCL}xEfZ3?;!eV=UjHG3ykUN3)9fSQUI(=d-TJx3G5@yw@0z>!Pm)+fIft& zO(atj5kKGu#RDlYj*mrSaO1gx z!6Qpa)t}$|OVp{$+Y|t>=Bj4sQkO%!?Sx)?wK=B7~XI$OFq{+jlOG}B!KLA5+#hU?fI@E z;eN&RO1S1i_v_6^+np0>Nhb-+%|e{Jp-KE9p=#U~r61NsE&{3GH1Qz!KjTz_M|bSYKFb^M81r>8v7@V|ET>e-9PZ$ zk!^bfC&<1>y*lCk$~0F6?yBHb>!w^b1va!*(94XYC`W3i@aOdbdpfOHtLXlHva=QS z7-5^8X|br{R5eMhk>r5U<^?;`*zum!D;k zG%4_7bSC)9Df2UdoFl48)m8bB*MF4zH~iE7!313K;k$wOSG2aO-z`HJDlY-`2c!c| zVt}m*<{HdU0~L{^4x#6TD&o_l$m$($wKfd+GV{egKHgQPj58!9FcMYa9D14Zn zs5!zW!z+G87(ht8K;W5~)!g^5S|e!R)kV*q$<4fa@tC|cY5mbKX2YyN#s0mp zq%cagSJCl6h%>1|>~dU>5|L-SqOXd1o1UB1i)643t0E89`eXAGZn5PeS2Q7kVZ2cY zoU#DIj+qHs=>( zqHWpOaO;OFAtSt4k1TmKOkkSmTM$cr0|uyGZQxDQASmY8L@klm$#5IdZKgJUe45YK zR01+P1FO$2gWiFB^1EBuBRdF~fIz-)+>UoO0?D`T{TK``l%gDJ;E8Y)d}j+R|5Oxs zLY8n+ZCm~AjGxvft5F~ z3Ch~cB!gz{wxZMD3atZ`u5McUhvFbLCo%~LPePJAkaIU%Qb!JZZpHx&WjM&Qi7e1L zROKa$H646$RH^ulc`x*#u8Je!?3pOQ)eL>MUlpjO;L<59j5uIU%Z#~1N+0s0^zLXV zKig?(*zz60XNAOtHVA-{aQ}}5{v6${oBu8_3R9WU2Rf^bGBEl@9%;nE!Zqy8VBkJd z5GsUEIe$IaF4wW#PEzg=DuOpzf-{>ovv!U_c5I2GAi%OfKI(WRNau}S7DzK zdAB6RmKia%)Jyo*t+LK6F$AL*`kxYS;+QEdi($T3y-`@Q0kn};8{8tJC8PPL3qqZaQ=?=b?g6p)tad!vql*S^*}s3hV^ zgkxE;uhaw__*}IKQGxlE8cmj-%umtFF-J6fZg#yE7+Glh z&dOw4Tj>#F$b?iM*OG-{kNy!pMGfv&^NgyPy(oX8cB3!zR2_JfS^A7d`>a%SOQ)i} zUl68oulVmy9k4y=3cXi9YF@o3zvPn{757nfeV zhQJ;JP~Vj^H~uISjjC0{4cCpd{#6)B9aa0y$XND_vQzq1ZKVhmLUmx}nRQ4A*Xn+N zi$A?W>d&#iBB^_qdiy%A<*37qyl9U8ZDut2D5P{U3j@woTTVPHQ*T+LV&yIeUTqe< zz7TH2RWg-1OL+`^kr8vgS5H%CB~N;)*Vf2L79498vMCm-X7=|4jv14~yh`91{s>rI z;`p1iR@EG$l=rQwz9%_9(6jN~Uw^L3$qffyaVaSnD2OdnZ4wfiDnq}uq*-D3?m=DY zng8Xt-p=32!Fb3}-*cprd+T>0+Gi=DQ{pfmk)sb1v~U=SaFOO%!Amr9^9K80D$lO!cw)@jdyLBe}k zKQV2ur7~#;LaY%)P0z3VU#K z{z(!ABfmtrma?t^*QvJ9D}IC{b0CdT3^Jof?8AxhC6HV?YQEVyS7YZDbwpE%HGyKt zkE!@Wx*dW{zg`R2_6#vj;4dH9@aL-jN(JWye^bc|HrRc;JmBL9`%JZ})>gHdhhXHv7TUz{Z+~ z0c4y<+yQY$r1rLydH3PlXaqvSM~q*G{;kMzt*B}G@J&t7sIy~YJUh-?CGwB+Z!m7o zrRhO+FVB2~5Ib;!)1y`DMYX^GR&8MC}O+I z;TM+lnr>=3(rmLorgDX$`203$Fmq|F@izoNBlNF8{T}fU&4BJ^>t$>-*l7HB%% zNH3uM0VDVxV4)zRq-|R4RW#wGf9Z3c(Wg_~sBRR$Q@ub` zsw!*Y$vy(rAW|;OAv-M;ekXX2>a2(#jMUUpVGU4J_+4xS#<)WN5s4p~a`DRT$H8qB zSWpW5ScK3^^t16h${51Oc8YVz!h*5VSdWvd!u5#p%9FDo*n` z;&FoWG`llxo7Zp{cRPGE{yb3m(C_h(o$@3k4U9DBNlH)~A$%-6Mz8;m7V}O6 zWrDc!-`#U_6MdQp(9Z3c+AfDn2cy-NWle)<0piBWd;I*O%K*e6STR|eBFXW1?-=r% z@g%HN#m~ZG4?lqemv=fx$ejgYF$fYf%U!W|n;+vbjY+5%2)L^8NzN4ol>9D| zh7O6OKyxWxqK1~Zu{AgIpP`qN{0>4?3*fxq8_@q^((E%SP8_^;w4wsOfin<`pe*c0 zlIox*Wic##TE+Jzoq8-JS=2!tsZSkEjRh?z+O9(2H1PRpr|NDTi>I&0e4$*k$V)x| zmvz1J+fDi^=D~u{qH&DhJRP?hT;-cQFzkHktq=LZdQMa)T_38)$*$erI{6mp{{AeA zr5-swr>{!8qpX|1@;cNI_h;JedqyOx%rrtZue3f-|NU=7Rb`TQaOlKD$e=4GN7jRq zYdVl`M)036FT2%FH+6DqNPlQr?0MOhd3VsuEqh(K)#L_Y9y-wvQ-o-TA?_?8((>o< z3E5VM7FFxvPxpFQv5#(s9M)CJ+oNfz&l4AxGFyl6xZTd$oc7A6J!uPk7)FKG3XPjH zji!A%9*A-ZP>wWw=h7z<5?qx6eklBAspEMiZ%Fthk_{L}YKM6mBDAjhn<4uueQw}o z9$HU{;|pE|#8dhrmz%-a4DqNjO*ZxXP3^!#?XkdhDZ+B5-H(1tShL+|_qJt42`raC z7*ilYyhBPxMwU0d(!?132v>GCRBFvWFJo#3^3tWrjnZv7#*TN`g`Ny?n}ukA=XnZB z{=g|wI~*YOWpX1lcz_uy_2zIuuWw<41i%$Adf}UlGyz|s2YC#M+cj-wAEI58fKS7# z4BLVD#XMHO^(N}x?-n0eXsF96zkrU6X`QZ#6Q+t{rsrXk^x=-*S*eXn2=Obo{$dht z^7)d2vY7mS|LVekF(>hFVRSCzqtM|o>1SXIJ3v9;b%LvBx5>6>)3 z!RsioW3kJ6`~3yFsS05QeilJI80P{?lJK~;^WGG*SAHu@e?a%k0$^@Kc`jEj_QxKj zty(|q&KOyaV}gL)G%r!OTiOHBYqcPIX?$I!%oH|RW#i^X%hB1q!+OgL>59Y(a0{@X zzkTJ}b+fPD_+^dXJP@jg0HyFC0h#A8KU)#X=KO2%^s#m6;05h1?UDL3 z=h;3c{szWdYh$fpG09QM1{4MTVzcE%5EHJPB~_f_{#cMSC^c|%$T%>V>#`J$%G?M_ zQBN|^)K|Rs=@JVEOGF|$e(JZ`t1%>v7Y%sl$PBR+FdBn{ z`9O{W)IM?XV%{_e-90~zVT4yuNe4X%LQ1{elyG(Td{cMCg(OQ^P_7v3m;Nb>9GN(8 zANmY75`X}W3#b=23y(b;@(9TD-HgIwRmAp~fc#lf9^BI_3V2Tjs5~`!SJdk6eu@7J z#AE3<`k#l>qsit659_7RDNa6tvHajDV-|N7WMd{+>_?HW7)QN>l%s-J& z$(>ug=t-~lOPtb!fc!#wN(WfJ{?vNZ;3Rv`eSdxRd#;QCkuQq&eIR_jVr<@~2y84eZA~KgX@2ttlOq`TAg+B#VLSrAa;mqnmlY&s>8A0yOUmEPX6(Cp~MGlu?EE;I|Sm6 zpge#a{i}5|L$CR#+=Zbk<|P3!82z1$-w@{NefP$cYdxt-TsVnn-s}9}FId~yK)|#i z1EKZim|JlK1Rc|zv@KM+B`&TNH3H>fC|)c9>yqj>c8&g`ZyD3kfGt2^=m-BD97YWurbm@W)=b=~;G%4@ zt$0L4(>2c-?c=bUn%BNAai1VnY(MoV{}Q9O-PHCk>a@Cgd9G^@8s8{IkyZgleQI@8 zbFj7d_SY-N(Q8Xrp)sG*#i?_5{eIA8Pm&k%UWF0zu+HBo!8UAgBnAc-fx?6a&x_YT z3lcs4ouIQFopB{9sSwpA!=ZXE2KKyuG08I(0S`&0c(Q2oN^v?yskF2;jSXfN^;D4NNfwha2zoGa&gE0lUx+8O(-)g>c zKR+XNa<#ku^~amKH5O6M1<-aw3PH3O!@0!8OEAnU0B|#>%tx-kr@uiIe5gfzAc?DX zla+FYCqek9^wHnuAmv687$F{|5C0ESOwFy#%mm1uHL}>da~Lc!>;@XLe#I+Zy|I6! zqtk{Y?$OIiRwP@FG&NxqDw%+kfxSuKPvE&wWHFAhRx-CX1n@p(g@qeuaSZ7_=4C6muXpWdb++55AJ zzTOt!+)B@){nsclL#M!D9%=TZ`KUs34p(&i!Vrv>lDSzx4D9Zf)!ZS()c1r0QPF4R z{raK$nPTv#TIsKAVQaPcKXXI)0V<(f3r>th8THrch=4C-oXD@JAScF?$9)k?;~D8O zjTYCNjlYo6DTY$h>ivr2egrlcHQknmVR&Mu5|WlO00-4?S}|dX5)k|)YBYCt)P+%C z$m3YCs$AVKuP;8o^!PiQ{^!wmYgC2j+IG)h*Lm!c2e5YQm(RdK|b^cgBjtE_K}P=T@MhQ}nm5q1vn!mHkQr`erbf z2FbHz;g`*>H&8!JtPU<^5D!!KBE-xEX_f?zXfv)~iqq$0!GQVR(5^HAU!*-2+5$R$ zY#)dmx}X_JB=o-y?YJ2RD70-`W0EZe9;RjJ^)?@JBP(D1vwHnu3n@$-0O{ap)jZ(1 zo5wV=Js!+_71X+&S^<_xQlWG-W_F8Q@782OshAHQ(z?Ti{I94Ch^F^Ai9`y#l_(@hL+DxB#gO ze8g!=_}9E1Mnb0?%wef$(7$&kE^g`s!iMAz=QSg(55zkDDVudeU(La`K~Z|NdlEOs z2QObJGU&@eZqXSTWTOo?Cg-_djA8GFM@*}SNXpLnF%S~suMbo9-m>sJ%494(tOosK zxQHq{q>1!;BO|6_w$YkCnRI?c?zVxKXiHTmTC7Q?^DunU^1;7oe>uWZXBnpl2RSG` z%#?$+OIB{Q_anqczwKRWlsYWyB#~f#t^wZOsqX3#k2!LkwwzZ#KvNlD%VYvn1@YS) z^0+C%Ro&O0niqsa6jMxQiykmGY%l9rD`ctH9Z~iXHpXaW58ffJUZ%wTC2ziNlItqg z6y)jzwKP_&zIhI*trGou>miui3e6q=yzuPd$|ylnfX4pU30f^Z3QB!6zZXQ+aL}dv zST4?-n5s<9<);K4BB68XB0|WV5XH8asO%i+ab`jRy*;en8HxQSVL9$@3U%hh;)#HZU7}FPF$}{d#n`Dc~ z8w4uNcg3wryhBgiuW_BffrW>Mms;21(|#D?*MG}B24SW6vN<^EqA8U~mr+1GLU%>8 zk_}M3>uR*A!++B}0Ilh+WM8Cp%%Sd>KSzt`cECpnxl2Z;gjQOiDbr=Yz$r!OP` zd+zU14C#7#9W!x*g@pz4VH&Gx`8KLBsV~bc)7sj4;IQj0fTR5VpoN;G*mTT|{Nmkv zIDgd^V9=nrQ?j5^F%0Xe$~CpGs+t!8zXqWg$#ioaOPa0iR0l>sRF&NFoUo;5aT9rm%pA5 z=MR8>iX~e?KHMs5ZcgjQlWYZW32J*ipi9^3!|*r5q0jP%JNIy!{Tz{nw0G?$*GjKj z|E$4+`|o&eN{Yj3Dw&Cm0lNqvf?=1Xdyi%xIyJTPH6JD^^P0k zUG_KE2H;UST(YEe$}+4A$+!M@1Tx67Fd(azkxjS#NQ|wp@f0E@Op-09NP-MH(W?Ej z?AQk<1&={yZwSDhO#N$&{|p>_)*slYx0Ll^BkuofE&6V@_%)<$V2uI9b&tbzDKVz` zUlUtQl{F?!ZC?yup|U|mXC(Hw9C9IHoc#+!rw4?_Hr<1p{ck{E%utyLW05n;u@2)h zQu=Y*e&4pTLMox``Ao@2Q22k(({%)Fkoh9>_Pc4QJ8HU-e4fATE`f7Yw20WW_4f|x z%u^%UupB4~?tR9oepFa`*ElmCFI}MiahnO_(RKI`bqJ%nhaJ0@3vS$~r zlrO!@KQ;>I#qn1xJWKd@zV@0GS?2CXyN`zP`$KAdupTzE;M-@3cIHLkHN38os!UrW zG~RiZz8A>wxO*9z(l3LaRSZfw0x#{q6Y8-6D>dL1kI7%lHtv*t$aq}aXL_yO_dO4S ze|!367cQPSQaDApbe&VHcjW9pvCF;ufC8iSPWQ37UF<#mJK1E9II0?XcTS;_7&V^j z+8?aoqEt)G{2d~13!7Q(ec%}Kpr@B5s$$d#0@ogzlvY}I z{@I)yi^ZBgehG=uP@TxSLY2H4&R|Nc{x$vkvu39EvWJoeJo2MW0`A;D^~;L(ZM8pg z`wQPBlfh&ixGyQl1S$5mJJn(v8NguPHA!xM-Caao?&`%Yn<6o8)=elrB3`dCBBi0p*VoE6~G-=8V? z^Lf{0r`UxypTsm$!{jEZw&}GtH;^9zMH`O?Pt=|K%r>swet2Dml3uRj;l62gFN+rM zbrKc6>w`Qu*-Ho2!(w(HI*krsI6=&53>NZdqpyZE?cE)cUAyC4pSzYASsQM0by+IJ zC70`;@>h<>H-N{TxFX+^1xWKaX}W`zRKv+jk@vX^HJ`>9Ri#a?&+YB{AMV!dGwx-= zv=nN@4iFuhq3;N!SfjV^ZWLUWe*5TbH*CECd;OpGvb6k2 z{W!*V%W8D5aWf%<(x$nhcylyE2%)OZeks!>viVMU2o&S@Ln};jLID6ad`*YEYH<7~&0zuYtbpfd z4cB?77|+Vp;g4igNk|m0=8&M?8s23eJ)AD6Z}nX4-Elw}wk*jR=sikDWh7wZLD&+$ zlzQ82bT)pH{bLv?DvNtTfi0>aI0-U^wH-s9eo{x84?ky%>kBxs+OL^YEi|5~-6Tl*T7FR{kc^o)}zAuhhm{g@vB#s*JJ z9o`df7*gj~eg~Z#1^8EEe@D4lqMZ6CtXnE4qO&ZCG_muHOZ0p2wD?rO_;_-~;86MO z`3kS!K^L_Nr-4Lg7J1x_m+1I4c89np_lt~iv5$HVO7{^O? zRo+Y$8N}q+lR~KZ^(Kb5{>JBMP~%^v+IOcxC3~rv1kJg^cU~#q(%6}$Gx3f0YZ9rA zN{X{v01@=dKL+#wpcEXk*ga10+^~NkOzV1mqr7A6X|);jxoHft{DrY}q)Yf%wKHJp z+kUal!q0>wkPlsKHu~wUiCwg`h38ar1=&7?jS5gitorJFRueGPGU#>SAAVsKv>73Ugv>c7`6qaI>8ig{VUrS2WB( zWp3y{Z~x^!1V3@4$!zUPy9i<4>HO9n8*9FW)Rv7PDo7iL<$xVXFDPsNTtBRT#=sR~ zlX|u4qu0CD-$G}J3mMV+@bg5c!l61FYil0v?wdf*($4xqmq(^)_8R{ezCU0W*Sr z;%=J#726HT^h-Cz#r4U5zyP2Qj#=I@AXWl*!7-s6keKv+<Phx6v||6(nTck;aqE zLXLA*Ap!7ESB1~w`br=AekyHSfazX%Lu3dPz}$r${pFpAzKr-?r+dBg^+_i$RWDb_ zRM{N~I%Mdu4@=SI_tWGt#HOEYgk3vw-q_PJNoIq_G-}V}y(**C=O>)L!tf;6fB)7w@Cf7?o#ugO^7Nz6 zUk*s5$oiuneSnOb6#9Z9brkz@CIp`%{*{{vGNwj?z(>nDVp!`t?C&KbwI6zR8U>sm zza_oco9Rs^G%;i=bY~BGL1$HO=-E;mcniHLKonRTS{27uUu3f=!I+gv7z*0aI_pe%OKxojcl)vK zGFBfTzHg^=bN_PC*&J9@m4`6DjeX;-h{P)-nGs{Fm{=)p65Xw>5m6@K$N%^Xw!Yhy z`#=_9T&EE0V3(hYXkYzEYzqpQw_%%CPnh0JamXCZy^}rTt$Xb4*$ML8|IceXxc)6d* zhr=y@u0L;RgU(WdK?St>_J`qqdvy1kVu5wfD$usXO)ngx4uI_tNiUTshx}<^ZB9Ef zI@=Zq4Xad6Oxk=x2bh*QFD9&V4$=-IKPW-{0K*ooKrnyLRSfUV?rSr!b-?+mE?!(!FL2W*oB@ z?C~hZjzOjjfyeSC{*Hll9K3Kq1OH;N^)9xFS-vCJ{q{8+A$MxNg7p0CxEBB>=(cNr zZ}o@S(?Y(vI%|auokXaDo3nOMtpTkT0Rc?MF&Z~@c@cYYyKexzDR1tjW6eEVUpE%) z8?o_0HR4?0G|0TofXrLNLPg5HZPM26>ffDLj0hs26O=EBAvkyGa)Y|49( z)V%{%SKj0I@|^0k>lbGl;ZUopcDBvV3Y`RU8FtV|m(GJ>4Uc_EliNkv2D#7k@c~pg(vcp-T^>i6}F2H50&?@$N%=LGJ65C*Wc)gE$J!suU1;JJaf4WaLK!%{gL=rF7` zRCPe@N^&<{)ssK7fZ-omN*-d@Q^gJ281G;Dq%$7FK35m}lS8Mb5~smTWjYY8eox)l z(bfdRRNR6QKTCAb*=Bc}zKsBLG!W_qMX+BtV~0>cO0wBR^U}srkEl7#Z|O%_RR<`% z*r~bMY1?%UCPw%Hue2Wxo!OAX!^OJrmc>3|I z3sXwALu@8LD;;YhmbJdY-0K4rjGsGl70B*{p5Ubj_{{e|8YsS|Ro*&%v9KlJW84Gr zjD-5=-sS=MDPwS*AU__TFstexal+Zsl}%;S#W&mJc5lR=j(TXA#sM3aPzvdK|*I$)RsLqJ~ zu!=_q(xM6%yiYs(`h?PM`l=@F+|~Y5*~+0L@oJ_HY;yp>x*-tPhJ88GiGWW3n@%X8 zR6+f*E_@o-W*OS$lS$Z>J39Vc)jDQfGbt5DNb2it{oZkCmx828F)Adc!CyvLwT5V^ z(?sdxqN5+fs5-A_4@_tUsP-te~xksDNhY@u9he zxL!gBHNXsAed;btF`a^tyUS{^)6WYlsS9F%`^`D`zx6)dnqvpOTNR@UQTxY{K-<@w7p{nwh*M(TKo?hA0ctDmxxDf#Yy#A;gPsr+$ zG?UNQ|DSl8*qD(Y{7QOvm77Gs7Ms76sI#iuO3kFqs1eJ&>wXdC$%A32I}dW4t3s=> zYI(C}q|n1f!2eUu2aZI2cVfFxm2KTKJNkf63IrF} zcZv{R?xGOSwRbwj;Gv6oF6_~o63g=u35g#%iPRu*97t7mHDlNT>mCa|(ycY@n*Xi$ zW2I@7YnpujgW7GP(>4F@KS&e0%#Q42jQUZjCrlk!QXE&Qb^KM=2h5AQ9Dt!BcEwV?HhdH?nI>!Z1Knx*{fPDc!L*}udxwnrD zn}g2rxU`ySBS*-|wn+esQm0E6q0MHFF1AsQ6P$Dn6-xkz^1UTAkws~@dNwm)*VB8K zMLFiP*hEZ2$j~Vmu6e+Y9n9_x;GK4eK`W^vG<^)2coBfkl|5MwxD@VMT1_|!r68|m zcD5(8g<;6C$;Cz*q#fchX1Bns2t#rM)+AX!FdJcYZZ4uqzyjCwwFzYhTum1}5Ni(R zypDNoF7Znc0L+)H5fubpJz-fgP?ZnGE!K^BEr zzM(2^!GkdVA=+0&lsZlLOa{ugt5o{R4Wn&CcBUl!=5b6WKPnf|6->$3UUJi0@tOX- z8A$f5DG9rn)U#!jl}QE?+&RjvZ^Yk?|-VEP$&;ZwA7|hUI>i!y9(0I z`NcS*V}pgd*8Zv!dmZKxGV4vL0q8i1zrHg*k0f(JmWtyd);h8Y6`uiN)&yv7B^SNQ zt;#eK#-1CT55Vy#G8W%BpC3QlnXT9oP$ab2J5M{=_iC_MBZPfe#~0By?4$3|0^T5t zMxqOrIY7^{M^zR2DT4^nKP--6+mT{ODC1_m+R|_Jjk7z_!ub-KLy;62a&XmuT4XWF zOjJ~mVP}byo{^?VTS?_HOCI>t5fM)z$+Fub0x*VXiaw^*+kWYdkFlt+j`Cz>ljEkj zygQH?zx|7J$o;e;+7U;N=Gr_+G(rj=7b5%(vrGk&=9JH;9-UIT@cWC9JK@Th_h&AB1PTJ|{ z3}w`ypm)gyF&O>J4zv{7t;=47+}=%>@%a$gfRDPC6Q0xPtPoF=z7Qvxa+b0p53;(D z$ALfcS=r;XcF?@Tm3GxV^L%Sd>dU50wLkn=xu;HOj=^n$!A{m3;`{BMF*|TDLeE6% z)ae<_Ko;qAJAIXIg8Av?`ngXV;D`YRtDuz=ZsZSOcIpTBTOT3m2Hn)qq{$f;Clg+Q zFoE0gwH_5Lrc3cDP9QB|$_ir9pd&_tq0ouMbF6i+NawZd0^(Qr&pt}}_k@jF)o@D3 zo4kJrix>qvd}jUj3N&^Kc|thY9Ts!cUkljBtmUK<7CyH#cI7kjTww42*`dUGY=|e# zYg!#hFn)DK=!i1o7cUIdzDt9+FQ$qv`CRu0sa5FWmB%%%U)vJxS`)yTIB4E;7V>Ea zmYcLi5`srpF3HAvYaCysKEJ`5ScHnwZ?R7aRLqCA;J8X1$h+Gt-?3ItF>W^w~vZvV5y(NYwGM_?Z(SzOeqjJNfx{rZNmW_uNmQSP*9c0 z%^gDj@ACSySq>wj?BC3vjh)_NHmMVx?HYqdop+bgXh{wFCBz?qIJF(r9^m-LWF^*j zxwBWq9`JN+Zj*=B9uN{dF6Q;oX%?40o)8V%mtQP7mbhc$K zQ>hJDw?BWA)g-Xmc8^40d;ZT8YaWWx^#^q3Bh(+*=ZjeuFl`T1CDbPbH{B)^ifaB@ z_LfF~>;+!ic|(g}cnkbiR9{dD7q3#lNq*CV9j!UXr6~I9pw5Xuwes2IbU!>eM5wM< zy1$k6?7z|{>PfZCG%KL29lTxMd6u;&kKa=e*T*^+aXlGzH$@so-fG=GwZS*d8F{}- z=qhGyvpfIE7PNT(Ys41{KFs~e*oC;oEZsm&iFIym>f7Qkr~q#F+Jm>f3<_d+zpk_( zQ+RU%vn$`Hw0qPs*ZV7|*Qn5TV&J&Gky~H|I@e^W7 zJ2LklTXkT_rub5r<3ZSi)-Mo4BOCqu`EW8iOs6$M7ijn-eP-5QeH14vod=d!tYRzTud~_Md8M+T}Ab$*a z=|0-BGB$gd_Y#2f=_a0eZ2RZXC2+r$tZvIv|8%BBRBTiI^UdZ9)o2y>Or8j?zT);= zT%$MRi?|5^)0^N3o>e^eRw$s?cgr}s+!ll+1A7n5Vl}1xIy8iNJYua(N~|1rmJDRB z6%CECF2{kL$k@}_W9O^?UdohZwqVn4`7NE%HT4c6o{RoC4~e{t7W$Q--HnLpr6E9$oiK^D1q)0V2>s}a}JF(v%LN9Xr_K7U!kPW(IVgsi3%75Ww zzt<1O0IG_ids6kMR7gxfh3|Vwwyy35hm9ZR5>S*Qo`JOP5*soSPruVAqL|r}@r)u`ey_3J zL8khpl2F*)x-arfUkB!<|L6fQdW~n-I~F|=8k>rC1>3EY*-HquRI%(uv|WEV!9Q7X zbF03u6{R?HTC0P*A@laLe0=ZRZ)SAU)>$L+0l`HMqPvA;1t)wy5tEL!cXGQAv+Az0Fn) zyJUXjBN8gV_r)6ILV(Sq(`iJ*;=l2ZXcH(8rL0&6t*uIwU*7hOmh^9L7Pv>`W0>tB@UekY<%10F&%LU=Y3X_y#F^5hQ?>YZC!-$>ZNvoI66-C=*N|sQa zzG6dAo*u;Su^7IPlpn;(a_!E0X-I8%%LttH7j!3?Q-R&?s>;#YYy(9Hna(G*pB%&k z>=Mpv*5B~X!?T@D5K>%!QRR$Rv@(S7h8>y3yplN{YHKyO#$o=|Q=5?a6mv(35l8Nd z8;gFVz2bE=f0%<63)*rTwy`JcCdJU*bCRJ)WSZn}YuNUu9hn85)oU9H99Mvpet*WB zuGoFsTn1(rOVXUs!vuZNf5y?Na)eV7i{MfNsMY~nJQdE+EQ!#`z;5` zOB1zz2@lgI$`9T;b+2g=%MFjE4$gQgPdUYA8_0RO9^tFO~RxcOfV3 zLbdn4!f{-X&qrAFZ^#2surA#+-ROU#{@gvJ_^i*jc1~wD^tLx#wpyM;V0F*p$Wnbuu^Y{|42`^uR5gBhW^65*53$#0agn($MXocwrd zc20GbDG3w44@GGmeTWbr)YFog?blS+4J%C<4esf+tfgvea)7qou++kieB$iF$z@jZ zpHmdSrO$2?6$4g^p{+5HGt`6+>2~1vhfwzhw+zfjY7;i_0DdWGLo!}J5vqhd(S=ii zs&~;e_K2WC3Cl&XfK4FQs(-ha4~WH$9|YkuzG4D~u;&$lNSPcmVel$rw3hV_>gO46 zUGBYE(UN*#a+fHjuR*MDdkx`^sU3ksruP3mvCjMZe>GisJk;Iy9}>zoQYy<>vQ%W^ z5weZ!Qk2S886{hhCCk`mY+1AAL9&;UeGS=$?8(0G%h1T!83r@scjx)Oe)Ip_&;5Mv zx#ynqKKH!eKe5U#rn>x$6pq4B$liC=7-Rf=jDyBRc%H*wIf|~_g z;zXwoq%x`jr&l7$;CcM#yYreCZ}5m!9~OkNTAjLHpm;Wj z^%l6@82BwIe#tuVV7vU#TFB3=Wn;1rW-?7MJW2~$b|F}v6IP5*bU+F2PbWq_3KAv# zthHbR^iz54t%8@pDY@IlqI-J8qT%uY$3$f1v+mQeFx*|L2sG{1^+l}fJXVLGlfU`a z6U#FaWBe%eMJyelbv`_&JP=->0=Ar~-^zz`v0BuEmb+F!n`(N$EiAa;l5cTU(Z%3i zED&e8VQO?X?v^nqkaV~z8ay$j$S`L3v=f2z5Ye=b)uN?9y28~WMs438rTJw>1&P@_ zN~Rn6P1g(a9dI#gU_IcC4gBMW^=&sN{l=iqopnvNTVWH?ICzky!C}sbie#T)r3+W# zP%`G7u&C-;j3KngV(B3KTTCv~2fXvW7+iv-+4xaSUVtfh6ovJE@=4B%^fMatA`Nyi z{n=!kLzw}!z=P2{z;n{2OEhKP3hRC2#U=}Zkv@yq?oW#*KOsjN39aYSgao@qI!Zo^ zBGQ*or%zd^9AsN%6M3Fxifhg!A*)~V0@@r>3&Maozgh4xSis-}DRsMpSgYMUm=e1tIp(7wc!#-u8N_O8AFeevDg9b@asX^SN0QL_q;e}+;`qypLLr%KEU=~ zjciimu)6}$&6Ih2mjy;O^Ig`YUj4PA2;^zWUJ)lxp!@zFVmB)Fvq1M6hPtRVoOR(c zNb55P^@UF7oyz#C4BtNAPq4j`BD#&gaULQscA}y0;NvBR%`A-P$=~u%Nh2+E!}Av| z14kTdy{xJ%7_sZ(U?!f~`TIhL2qrCrgOwz#KRUjntOju&O(_mJNIb!z?EcVQm+^F_ z@5M|6-F0Qod!Ea>)QZvfEvnsee-#W=?3Y{?nkoG9urrwK1{7z#5XOrcYisth_GhU% zcc2e?$GqBR)cfuIi~rUBwWnCL4u6)8Es*Eg%&`^HafuJ~$W)h)+j`iXTj#)0W$3Gv zDA|2GIL{Nwz3?2qC`pQ}LNWp9@7hh_6T_hB#t^qR5LcI7Q`c7@UD9Hpe^}A7A<&+y z)8dk7;gZ;axGk9@)TOB%r7F57JC}<5@geAF*6T#7=g7CzOx6m2a5*|3+TYRf8@jnt z8o3uI#;%7p+|i5I6TD{CG3zg`JA2gRO4mSIH)*bP*P#C_({~E!9EF6nJ#sUo`Spc; zN4x0wGYUn90~a2VWEPzuYO`h#2-uQ=aLP!O^GM!R{5Mv&;6!@0B<-uY;&7QLU0l4o zssFG%d|`jh&bQ_p4EqJ`5O#lp%&teLdV8^)wrDWz2_K#jd<+#@ul&y`5QYIzzpyf@1_vAE z*4!CC&>gbdqqVyjzcTkX-ga8Kl`fY*ii3x~wJ_eq@6$=fZm$b31U{83*2+aU;%8j= zSrb`)u3W#z0-Bew@v zssA3bE&`OboH#EbpCcxTE< z-gz7r&1TAd+*`=|El7@D@b5EmQF-&narFn;hxT2iEnkF{8s8^!4-*V`?yf{u@I}Ej zs1%koUBtUli<*n7hg~KR8JhHS~t1pW;~RhZ=v@YEUqUeYE_qkma@Ff3|RZIYhXy#;t|W3cd}= z=m5SKOK8p3gG7SoEdZS(DLW5N3(L#_@KkNo?fextAxxqIDpoZ*Y8huQrL4TcQM)@ZhfG63T#TRj5<- zFCy0ve2Z{&O?oyy5ZV}u{_9G+V+u++rz3uWKXXE=*|^oe5vsC7{4qC@6uNh*4M!mSfnZI3F z?4RFj)(&oCB?HR`DvNgv3{?Ggm-{1u*!1ITT@%HMV&ohE_0LphtFNF@bWj5D6Mxvw9UKNbv0=evACr+|XaN%P3YDjcFq!boSe0PQj#&uPr+;{djbQ5- zJX^^tTv&-BD~VQ3xG%~5%)x>6WA|52Fhw6Q#YFWiXK~2yZLu4(#@33lIfh0H_+gy* zcPpZ3-YC30r)N;0hbVk7orw^7qYJJJ`orr8jALas_ip`h$1>$LQ}0m)n%YYNF>hBV#rhs4{X$1Tgq-w~*~7TgzJI6X8^^L z*Ts(BbCInki>^O1Hj7wt9$ua1sS1U# zUHL`NvHi6$CP#(CsJ--ACo@T|qTRkTWA}o@!Oot2ruakRUNaH5uuy2VnSAVg4H#O$ z{fm8Imxk%*YO5?#v2T9xy?ghract}YpOVLF28V#^RC%acb!xpd)Rcr&Y5_VFc{&%LLs+o%KU2de= zEwHs{n9AXjM{PY&*=rCG%68+Rn}O$ctU}oS64c4cD}p!MKH3X%auwi1k7{ib>Fike zbrBbsBrN>qwMm1>`ZJOel%s2muCb@+VncwE5A6%vl>g;d^(D;!+UGB(k~87Zk4y6c z;s6jRD?9wmc}iIiVb}G%`F5Ftoa|4v;4x@FL3}I!qbaL*77NgdxEPA}+AN39(hD56 zc0q8wuNlvPw#i1FA5Zp@*e60c1gOrr4=0Q+pIz5sz7gn=t@2`KPLwB*ikdj6lmSXz zGAs@JYtrW1;wnWS$!xojUJrk9R2$bGQGe7Sbbr?4)cILPhh+&mK=c0`khUJ`Gra@bJpe9(Afnpn7(77UvDd=a~}oM|1opsl~I^ z&(7Bo{;*UJTd6UDaCar(k`PX0vZ?77&3aRnyJ^dE*zBClVA>A~{ z6wMFE2(P>-9v&+{;>>QW7xt9$jjSC+lf|9~V5Eu2%I7jSVfTGbMgW`|U};?1iUSBEuKA63PC%KS(&bI_^> zihf>+)_wv)y8#kT#}f<||2m*(tP|QdO2LNu7S`m#_igxP-^=foM|*2P?H6wdp1pT@ zGPC*~abZ&`qZOtS9reuu^O4_PIj>W|@;(G?5P$1y(G1$*%bQLLa`zicrJ)=NYe^CB zVC&LAjOiV;hVp9?yQfhgc=K5+i$B<+mkWVHQ`6KGU%}H_?u6T4_JP`(PtKqjJWsVh zxO*^EDm&Wh^W$Q~y65<)Q0M6K@?};I4h^ZQY7JhgAGk1jJ_Ms{rlQpqBTF2~@Mc4M zSpmo0J9o(OPUlmxvAd7^F#r0c79Q{O&TNLXR9mYZh^P$%B9Ib~HFMCFKa-^qx-OA$ z`!NvZPD`{-`?`fku)1J?%5Kns|icv~t(Qu#@_eP0iwZ zO7C~?4DvNAP~TabIeD*^wo3^J2y6%)S63=6!`Cmc9}of?&Oov`Y&H%5w`Z8x`AE*C zrc>sU+=x)9x!_hOi!9Z&h0*?I>Ul$vt(?|ax75%^AyF^>&J5%1*cNNS^O9+7e6u3b zC1dlkO4bxO(76*(>Gc^Wkw~*lYoKw#gGs7eDvIpxg{&|;2|al%JfF?s^>hq0<$i~`=r^3Z%(VeG#e40SldH_&+0bdy8pt;SIhgrn>0JY}6eyvZK84`_zVl^(n@g7eAjj^8lIfN5sR=(OY#$WzK?8 z=F_TBKlo8FDF>>a!RT*jc;`;VC*~i6f88h<*-ROlEBD*ogfS2{1_+BL@($otM4>K# z0^i(Nsg(~Nk4IL4XGs8i^ozz>ZU|*YknIUeT2Ja$HCdRr1@bx&xlPYuvQ~kxA@wvwRa#p5eheX8hq(8-0}=jP&xfKI?tcd$x?#1_iPlXW9n7Gd));q5 z$3vbc$|UVg&&^_YK5m%1i>Ng((bL@5 zOc*UdlgNUVmaCf9&3nOsY6i`_N=izi;^X7@*Tzb5RG^altleb>ETDG$ud*SD8c9Rp zw$ewO=M4ilJh$=Fl?EL^2)!Trx zFDy{%Jd1er?Jx98t``kb6`u9>^ngIRCoKc;if1_U;T_Wqa<1lC%urGCtct|tK?ju0 z30+5BLXwcSvu{Z(>Uv1RRYumW2MPO-IiE!9Y1*0xX#AN^$D}$wImjL>8w0A~kLfZ` z=)UGtXQq{n%?p2qbBVtM>T4TdS>AlxgU$`BMV5@l4Y{nMxauM-umvBSpLuV)^(Bz> z9L_;$67Ip!!?~8077iDmEs(IKw`6#zDrUkNAg?t5H^b_U`~tjGG^=L#L~D!#kE{PvE_y?#08nG?jhh3Tt}T5Cm4`bLEEWpaM9$+{Umnq`w8rH52(|Qrg_eInJ7kURD`NssOx!P zqj*oVUYI$tk~J!AebLE#pKKYHp=h&Gd$VmY zMC9$|ZSxBy8Y9GW$u}Mj;V`F!c5{Hkar#`jcK0ZyMO7-X8dt3@$X-+b24ItyTd$t3 zAmVqtOv`Q9fC?MUFTMtPw2O5+JwB0+lcqk*%W89y)~4Z4&u#5|OOaz7ucyi)KgrNH zDI5tA1Z$$+_j5uMPU&B%twSE;Vi2#xkU(1oG92q?711gTR0i2Uc8je}R&8|g%D-Nn z(D0XonW;y3s+ftRpVUgmW6V|Rl9=0W>9}ORfoFWJ6JE#wO1wZ2_RbWVQh;fvaG#sK zEr=G7Fo$&1-JGuhg1Qc4C3JuA_ibJZ$WN(tIzdyg7rr(`Ik z`igqO`Gm@K;I#n-VzdC_b%v_nVKYA6XI&gTN8Di&or3qu^*5te# z#b)0u{Gg(Qem^aN?kUft$Y%8YHw#ELX21Tj0z~qM4+{J@p7lbpe85dpPc}^tm;map zMi>{ccP1uEG5d&(t?ld^>H&WCZ_Vpb82zWPva+(r?)S(nFhBgC~u?w9!HS z$IAp|7f@Bc2_zW_=bt#!?ZN0}iFqq)@k50VdQo2hB5%4`BcMEs1Vfi2F?=q(3rT<{ z$Y1K79#xh6C8)W%ndU6(fsU>__nu<~H@I)9FoW7qci77gH^E~;pfy}zQO`r0 zHPvK|p<72s#MuVh-gJTay)hRb zie!rb75j2wRO>Rpj-7p$T`EP|?XxsI8j*@)cCwZmGxbPSLP0sz2Z&NS@_PM1R3HTK%5&SIYcTxc>ND1~BmyImbY&_UQ3m#4$Nk zBH`DF>ksnHt}<>r--U^VvH6i}T_H)u71}~Y@)|}VvSMda(Dv1C3^99wLpl>jkw?C* zoUhc!{eYJ4^iEx*-?lh~t0)IFe&!5@SLpjxIa9m6Rh+xZ$GSqcSs`##x@rc4O>Vrb z>hVsqK9av64eTtH^H1IS(~1b_iORJl6$U#B@bmWtOWr%1_i8?TqU`8Acl3AP!k16; zJ21{u#HdsT8+XeRUU{SU!y}hVvt_adDi- z`9bmJ<>gpvSyKJ#CGeDy%C!ulGKa)u^BE0ppIv|raUqSmpg zGQoH)X($xy=IrKnb`PW$wHC$Lm4!$+x)7(}Ia%pf`p#4{_AH0%!&_v<2?ocbx7B7@ z8obRrewKEIcp%p+tiEgo4)C1M%#%<=TD<|lINYjHbyoKh_`}pegS@GP&c2Fa92(@V&3(dgN4knn zbU9EH7DK1X%+ES^&Oj0Tz`@@StGzkj_BEpe(b@3uYExSjZ&tru;|{Q-gzgl1%y*+) za*^X?Rn_Dgo1}YWS?hQFtwu^8LA>g0lgM({aP8GPxmz{9kEr@uVc2O zW5l$lWb(o?lAOln7^knda6kemhvH&l>7Qwg@(YQlj%~t_QsCnCoYt3d3Wp~F$rHA6 zH+Pe(QUEkV18haXbur9uWhghs0<5BEZPC%G$;#Q0zixR2?h(R%e6^BLgdy@Oj~Lc~ zU*<#}ug%kN#8P!A^iWEDc`rOXTt)T;>`|yws0P`kJ)WGC%9R);MEwV>LLgL+Cy%o7 zksq+Dga9~1!EO1Tqm9iU71|P{MdPNdCijX_0V)idXX0L~So3>R>ijwb@twR<_x#o` zic**Udku832KhclXT1CjhIAZ4YSoaS%Vc>Nd&3Zu?JgXgh(Od~j;Wo=$;nl9ns=+Cz$I6K2;bL4cB{ShjOP>-%TsWH zE>q_2)j_7ndTX;1Z{kbL-?^Fb@$pHi+SM`%$H|7#$~BYDcZTPGcAM8_$BtXszFi5q zncu>pe?$aBku~^!yg!2-FUBHb&FK8!ltb0cbGE&XaKm#z&BV0oH9ufK`^f^YE2#y_ zCZ6NgNz>0K_f(>Bk{iIu=j8E@uYBl9>etPMo^0AVQ*RV{_NvzFk540FfN$|Dn0|dc z-O{2d9^t^Ym5*t7s4hVlJH*^FJ`Z|9$6s_$p4UrD$KL|VP;9(%Gze$z2R{91hD;`l zCO!2SPXV*<0tb@{L)mR|nIr1x{gTdEw{XLUN|ypiF+k?m7DPwIhf$=#Ro%(z1a?OT z$Xat_t%ZQFk5EN}>2ph=4@S8RG*9{V?Mc+1WZQ-^u%C+ASy{;-P=8i&=Z5p z#7~A{$Fl0n<;+=zAP)qjQiBKP;lSJ;`tNIGKDcx(?-t7hD~Lzu<^=f^-8#}gemq?6 zLQ=PDpN>*A^M@m*HT=J*a`TQ8|9;rUuSu-RMxL8C1o5O%>gHvUOss6VB^O^gv7cVA3ohUfB1VSr1(&C ztfMH#_KpmtWGFvgZJBGq38c#MU?JU}KVMKVTxh?-Wh-Ev;wH%+LRtc4-?>?Z)V526 zMR>|tXTSL|k`FTt+KYrYDBS$#pPfXBqUuk!906!?tN860rp{VPMaDR5(+#-xK@sH; z*CD3|Y2lA4yU{Xx479BKl$GlU!-X*ZPK2GU88;2aFfKGd39sAy`JXu#)ouThcwA__ z3Sum)mC-|I!CKX)Stqv2VNCvew0$wSKAIuMyb!I`Y8QsZfNttOA?w_DxH0AvPoqK# z5UApnbMOZoV5q%uTThS*S$GnMO=bsxCfOcTFbdukd@cT+Jq4AX+6&qFc0&BK;CqtS z_%qV8iDE=l#s4ygEvt0k;@ALSyzGo~6UCfC%A8_o|9bCoqnT~mNh>Rm7z`R>iYVFKsoL;I~_n5(dy>tMAEb*-`gJUWX{?1qu&bl{%L?^WC1O(H$_!gMLV7-QA zIYQLUW40|@URrd&JW;Y;5Tx@&*rGb~E@0)k_PDYUa62k*wQwQF8~l7g{FYrxELUrM z`zs_?Q?ielW%%NaWZ*z?V7;K8SgLa|qFdELCuLo}Wmcf$9i;JL_b*V}xIeH1VrjnNRp>BK^Zeq|;fj3P`da z>Q103_k*3nX8pNykzQPE<7{xLKsXN^Bjb0Hmu2FO(3Qwn@_?TU0K5JtnApc+RQASn z@`qPOZhzUn8Qe$T={FKb)+;*4v5D3;Q{&O+x$@07NiU;V;qe^=+#H}X%DuHBcc>sO z#TyRz@ViUimeq_y4Q*w+D&X7ZC+h>Y)0HkEuO>rMYh&jZm z@&TM-InF(eZ4BJA3)2|kz4IuUg|kv}3AZZQ6?o&-2uYtw+%Qd%nE0yb$Dhx@^N%{n zIh};)i*Dg23PrZ}l__FOA-7W2o_}xNb)gq>P^J;~)S%wy~-%DTLI+!wuL%L`DVaewpdd-Xq9?FE@5%6TV@ZCEg zYL>))KL(N zoKaskY-?|~ZC-L=Po`~WIM7U(5=2NH_R2~{#+dZz+L-z(rwYPGHVuEu>^fM zn1QC*`}QxBhV5?f02Bw^K(+DJ1KX2&*>4|5w?@y+Q~}H34erwcV;cr{0UX}GeZeve zi=aUi-jGksW-kt(?rP`)j)*H=(QH*ufU!GHRyL8z%F26VR><)mZ}28eOiY-nafg}p zn%4`!@V7c)+>LLeo0$~cw|eNq&?5?Gu&>NUFgnbBC|_T)WwmlNBus(}FMh=syo4Tb zu%<>1b%dd&3s`ZW*b929M!rdEQSEEk2*YRr@rYqP4Dn3!V`U)Fu60ausO*xhYF zXGrR(gWTJ4-dcUuwX3n9Z@iII2@CGqhSB$`>`yHY4Gldms^6Q4nW(I<3x(LLTn)b9 zgsAh|Qu_$Kw?*zFol0$g9o)wRg0+V8s%>KwRQuYCgD$R_Pa>IYA42yqO(y)Z|$4si{JUq+}<^JloUXkDXYwK^mi?~_*UUEI2*{Rd_-H!2T zADB_$tNk{%5G|f?>88%atCr_ZnXri$kcY|&b%e$F7?WOY&3YLh`iiZ8f#uh@OVG|H zn9pkI#_-GU`bD+tHS+Q)-L-t}<5HKT#v4%WBHM!v759d4$eCgc*s5I0i9{IYV_Kd^ zhZ-%EMK6EfM9pgscXq`v2MEd}f-I5dFwF}YaX1|E=Kj^>@VcTC`-6@l&J`<(--<>WifC~q!+UyZ>_N`-8042zK ziwphkd3#!uxTTXb^=LDz2t8{~by@%ma?J0z_89Db4Wa0$8st#`Kt}E<7q>{TbE01y zLU&9pLb7OJ@66gcI z)ET}2XwzHT;SZufF~fA_gAv}>)$`HD`R*G7F!~<}x2bi0J5P>!<4E0T%7^PMv$Q5> z-!Sh!yFnX;2Gh()`2A$Yi}YdNrMs3~OI&c;G|)}?U@_i@b~GH)2K!~4PfWHcKe!69 z`~_|_$9NrN>Fw-)RICEdz_0+ zchavf7?EC(eKP4Imwhh#vg$xI4;F8c=a0b-z8CPD8FG%}TLhzNRr==@3v7f?3V*GJC# z85=sSZ(>J$qLkV$jmRPth$K1YtQ^-LQ}DI%a{Sc{vfj+#^_w~4TCLok%DH@( zar*>OgZJpw+ASU-4n7Hyoo~XVw*>v(AL^26S2D8K0MvuM9k%%;bpad3h z$3+%}AYJXatyOHAc)dT0JV-W8JV_WS45HcQ;olr_!&HT>5niV{7vLFtcUrDgzhE4DSsnms@B^5Hy>#cB;cg|C?x@Dv3}B^{-2e7pz%6L< z8Ay%XN3%WAly^tr9sSXpqP2W?&G?JrFC%UtK{XDPd-won>1M~J7+)ed zxsfv(jV`HUAjl(do#f0#zprUp9gU%}+*b5?T+BRv&V+QfK!Y^RCwl&sx{ssXuhOAh z!VUb}%Sb@<<~-wtZ~FcF-Tr1X$MMqK9MG1?%0hH5x&9-(!ZjbcUz^0;K9EsqZFa1b z)b;ebwDeYr>Vb~Rewu;!mLK4L!1G6x#niy`+6Q{#cQ0`GoCvy3yK*e}S9H@y+DuI7 z8~~^*%<3_pKYymtrPGYhZ*{CxsR&Cw^x77u2arbAuy65gIjiBATeDOIa2D+9 z%O1dH>fwNX_Juj5qyZ&aDMS9Y`Ne9r=0Ip`X|fQYu5E2?v~)TDu7N?rK5!J|YR5@W zxTK`zno#Cp1IZf29N`_NcUrPpvoU|l%j^uK;Xpd=g}6N5oK3Hi6fW%WJ7iFK?? zk3@GHAbykrVPapLCF*ctUPtRsP!62m>L)S5CcbMaaUY5zZ?*6LXNBQ z3C5;aw94vux$XY$?k*tr?SA#2RRaG=vj8<7Y?w4AxX&WEj~{?)NcQ#@VHqJU^!$44QfF%d`VK>#6`ta1uvk*bEk{C4{{D5Q2ogWHQ2i`_t4 zMj%0h-Ni*LO9RAb(ReR>6nOueWCI-eREFXEr$aZ}`32kVOqb|Zpe2s)apG;0L_ax=|ZL0C^&B90=Dwc1@&t4m5Y zXTX)02$Ltb7DSSNhYB&-!l~+_e z4eW9gY@$h>7+5_n1e{{+E~&NL+}tzkUKWcm`U>eU;gD2CsJeS_AD&a)bA6`XM=r{e zMuq)N>+4DX=*6bNq;S0=fhWi^!eek@sKEUD>2$xn@d;2XpYa*IEAKbuk_u{FXTOp` zyaksL zhq#FdJ@rfeKsxN7=K*lmScN?ot*!;bkhki^4by!o-SV@(*5%{mJD>ZPL50gURY>ChAL?58Yq**ARgEvyE!1GNNEKj`W5*cU&oRhXY$YXHTC5X;9?x!Tj{#;Na-2 zYu7dPJt)L9{n8vLaRfmR8=FBe`oJ7fef+hPdk$=Dx%XDefJo}0;6LDq(l%}XfI5_s z{_DjS*Z^u{z%87Ra~OlfC~tS{gQ60={@_mv#u3yFrP^IQHuHMR3YfsMHfnIF>|Vc{ zs&Fjd;$$g!eu4!u&1;$F``=4S?bXD` zOKpcx)AvUk)#NI=AWEZe$w%qDs zRWtTMiZq}O`mc$lgRAuA2kOjCA8)*x1896mP6oPWuUUY)S%2x$B|Ny8;5%McVBE0> z1X_+9dv|({It|g=OPl2hLy_&JY{xLqbYX9D!&CD#h3hKlAatPdMF>AncL7O8dW-lO zcVlj;w@h-ZAEp1_uNbifsudWf@^R8sAEA-9bf^zNm0IBuV0wvr=cldeLQ gRRX))^e^d{ZV0L!7k96)8UlWLS_Ya$>Xw232QU?b1poj5 diff --git a/module/mixinbooter/src/main/java/zone/rong/mixinbooter/Context.java b/module/builtin/mixinbooter/src/main/java/zone/rong/mixinbooter/Context.java similarity index 95% rename from module/mixinbooter/src/main/java/zone/rong/mixinbooter/Context.java rename to module/builtin/mixinbooter/src/main/java/zone/rong/mixinbooter/Context.java index d5887cd41..947071cb1 100644 --- a/module/mixinbooter/src/main/java/zone/rong/mixinbooter/Context.java +++ b/module/builtin/mixinbooter/src/main/java/zone/rong/mixinbooter/Context.java @@ -1,61 +1,61 @@ -package zone.rong.mixinbooter; - -import zone.rong.mixinbooter.service.ModDiscoverer; -import zone.rong.mixinbooter.util.Environment; - -import java.util.Collection; - -/** - * This class contains loading context for callers - * - * @since 10.0 - * @deprecated since 11.0, use {@link Environment#inDev()} and {@link ModDiscoverer#getPresentMods()} instead. - */ -@Deprecated -public final class Context { - - public enum ModLoader { - - FORGE, - CLEANROOM; - - } - - private final String mixinConfig; - private final Collection presentMods; - - public Context(String mixinConfig, Collection presentMods) { - this.mixinConfig = mixinConfig; - this.presentMods = presentMods; - } - - /** - * @return the current mod loader - */ +package zone.rong.mixinbooter; + +import zone.rong.mixinbooter.service.ModDiscoverer; +import zone.rong.mixinbooter.util.Environment; + +import java.util.Collection; + +/** + * This class contains loading context for callers + * + * @since 10.0 + * @deprecated since 11.0, use {@link Environment#inDev()} and {@link ModDiscoverer#getPresentMods()} instead. + */ +@Deprecated +public final class Context { + + public enum ModLoader { + + FORGE, + CLEANROOM; + + } + + private final String mixinConfig; + private final Collection presentMods; + + public Context(String mixinConfig, Collection presentMods) { + this.mixinConfig = mixinConfig; + this.presentMods = presentMods; + } + + /** + * @return the current mod loader + */ public ModLoader modLoader() { return ModLoader.CLEANROOM; } - - /** - * @return if the current environment is in-dev - */ - public boolean inDev() { - return Environment.inDev(); - } - - /** - * @return name of the mixin config that is currently being processed - */ - public String mixinConfig() { - return mixinConfig; - } - - /** - * @param modId to check against the list of present mods in the context - * @return whether the mod is present - */ - public boolean isModPresent(String modId) { - return presentMods.contains(modId); - } - -} + + /** + * @return if the current environment is in-dev + */ + public boolean inDev() { + return Environment.inDev(); + } + + /** + * @return name of the mixin config that is currently being processed + */ + public String mixinConfig() { + return mixinConfig; + } + + /** + * @param modId to check against the list of present mods in the context + * @return whether the mod is present + */ + public boolean isModPresent(String modId) { + return presentMods.contains(modId); + } + +} diff --git a/module/mixinbooter/src/main/java/zone/rong/mixinbooter/IEarlyMixinLoader.java b/module/builtin/mixinbooter/src/main/java/zone/rong/mixinbooter/IEarlyMixinLoader.java similarity index 100% rename from module/mixinbooter/src/main/java/zone/rong/mixinbooter/IEarlyMixinLoader.java rename to module/builtin/mixinbooter/src/main/java/zone/rong/mixinbooter/IEarlyMixinLoader.java diff --git a/module/mixinbooter/src/main/java/zone/rong/mixinbooter/ILateMixinLoader.java b/module/builtin/mixinbooter/src/main/java/zone/rong/mixinbooter/ILateMixinLoader.java similarity index 100% rename from module/mixinbooter/src/main/java/zone/rong/mixinbooter/ILateMixinLoader.java rename to module/builtin/mixinbooter/src/main/java/zone/rong/mixinbooter/ILateMixinLoader.java diff --git a/module/mixinbooter/src/main/java/zone/rong/mixinbooter/IMixinConfigHijacker.java b/module/builtin/mixinbooter/src/main/java/zone/rong/mixinbooter/IMixinConfigHijacker.java similarity index 96% rename from module/mixinbooter/src/main/java/zone/rong/mixinbooter/IMixinConfigHijacker.java rename to module/builtin/mixinbooter/src/main/java/zone/rong/mixinbooter/IMixinConfigHijacker.java index 9b3a7041d..844d4d252 100644 --- a/module/mixinbooter/src/main/java/zone/rong/mixinbooter/IMixinConfigHijacker.java +++ b/module/builtin/mixinbooter/src/main/java/zone/rong/mixinbooter/IMixinConfigHijacker.java @@ -1,33 +1,33 @@ -package zone.rong.mixinbooter; - -import java.util.Set; - -/** - * Hijackers are used to stop certain mixin configurations from ever being applied. - * Usage is similar to {@link IEarlyMixinLoader}, implement it in your coremod class. - * Requested by: @Desoroxxx - * - * @since 9.0 - * @deprecated since 11.0, use {@link org.spongepowered.asm.mixin.transformer.Config#blacklist(String)} - */ -@Deprecated -public interface IMixinConfigHijacker { - - /** - * Return a set of mixin config names to not be loaded by the mixin environment. - * - * @since 9.0 - */ - Set getHijackedMixinConfigs(); - - /** - * Return a set of mixin config names to not be loaded by the mixin environment. - * - * @since 10.3 - * @param context current context of the loading process. Mixin config will be null as it is not applicable. - */ - default Set getHijackedMixinConfigs(Context context) { - return getHijackedMixinConfigs(); - } - -} +package zone.rong.mixinbooter; + +import java.util.Set; + +/** + * Hijackers are used to stop certain mixin configurations from ever being applied. + * Usage is similar to {@link IEarlyMixinLoader}, implement it in your coremod class. + * Requested by: @Desoroxxx + * + * @since 9.0 + * @deprecated since 11.0, use {@link org.spongepowered.asm.mixin.transformer.Config#blacklist(String)} + */ +@Deprecated +public interface IMixinConfigHijacker { + + /** + * Return a set of mixin config names to not be loaded by the mixin environment. + * + * @since 9.0 + */ + Set getHijackedMixinConfigs(); + + /** + * Return a set of mixin config names to not be loaded by the mixin environment. + * + * @since 10.3 + * @param context current context of the loading process. Mixin config will be null as it is not applicable. + */ + default Set getHijackedMixinConfigs(Context context) { + return getHijackedMixinConfigs(); + } + +} diff --git a/module/mixinbooter/src/main/java/zone/rong/mixinbooter/MixinBooterModContainer.java b/module/builtin/mixinbooter/src/main/java/zone/rong/mixinbooter/MixinBooterModContainer.java similarity index 100% rename from module/mixinbooter/src/main/java/zone/rong/mixinbooter/MixinBooterModContainer.java rename to module/builtin/mixinbooter/src/main/java/zone/rong/mixinbooter/MixinBooterModContainer.java diff --git a/module/mixinbooter/src/main/java/zone/rong/mixinbooter/MixinBooterPlugin.java b/module/builtin/mixinbooter/src/main/java/zone/rong/mixinbooter/MixinBooterPlugin.java similarity index 100% rename from module/mixinbooter/src/main/java/zone/rong/mixinbooter/MixinBooterPlugin.java rename to module/builtin/mixinbooter/src/main/java/zone/rong/mixinbooter/MixinBooterPlugin.java diff --git a/module/mixinbooter/src/main/java/zone/rong/mixinbooter/MixinLoader.java b/module/builtin/mixinbooter/src/main/java/zone/rong/mixinbooter/MixinLoader.java similarity index 100% rename from module/mixinbooter/src/main/java/zone/rong/mixinbooter/MixinLoader.java rename to module/builtin/mixinbooter/src/main/java/zone/rong/mixinbooter/MixinLoader.java diff --git a/module/mixinbooter/src/main/java/zone/rong/mixinbooter/Tags.java b/module/builtin/mixinbooter/src/main/java/zone/rong/mixinbooter/Tags.java similarity index 100% rename from module/mixinbooter/src/main/java/zone/rong/mixinbooter/Tags.java rename to module/builtin/mixinbooter/src/main/java/zone/rong/mixinbooter/Tags.java diff --git a/module/mixinbooter/src/main/java/zone/rong/mixinbooter/service/ModDiscoverer.java b/module/builtin/mixinbooter/src/main/java/zone/rong/mixinbooter/service/ModDiscoverer.java similarity index 100% rename from module/mixinbooter/src/main/java/zone/rong/mixinbooter/service/ModDiscoverer.java rename to module/builtin/mixinbooter/src/main/java/zone/rong/mixinbooter/service/ModDiscoverer.java diff --git a/module/mixinbooter/src/main/java/zone/rong/mixinbooter/util/Environment.java b/module/builtin/mixinbooter/src/main/java/zone/rong/mixinbooter/util/Environment.java similarity index 100% rename from module/mixinbooter/src/main/java/zone/rong/mixinbooter/util/Environment.java rename to module/builtin/mixinbooter/src/main/java/zone/rong/mixinbooter/util/Environment.java diff --git a/LICENSE b/module/forge/LICENSE similarity index 100% rename from LICENSE rename to module/forge/LICENSE diff --git a/settings.gradle b/settings.gradle index ab7e11204..87c43f334 100644 --- a/settings.gradle +++ b/settings.gradle @@ -14,5 +14,5 @@ pluginManagement { } plugins { - id 'org.gradle.toolchains.foojay-resolver-convention' version '1.0.0' + id 'com.cleanroommc.gradle.settings' version '0.2.0' } From 2f1679f93c2759135799b9a060a47bad1cb7d382 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Mon, 20 Jul 2026 01:45:57 +0100 Subject: [PATCH 06/99] CG 0.3.0, notes in dependencies block --- build.gradle | 62 +++++++++++++++++++++++++++++++++++-------------- settings.gradle | 2 +- 2 files changed, 46 insertions(+), 18 deletions(-) diff --git a/build.gradle b/build.gradle index 2a244400b..6c1d01348 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ plugins { id 'java-library' - id 'com.cleanroommc.gradle' + id 'com.cleanroommc.cleanroomgradle' id 'idea' id 'maven-publish' } @@ -13,6 +13,22 @@ java { withSourcesJar() } +cleanroom { + loaderProject = true + accessTransformers.from file('module/forge/src/main/resources/forge_at.cfg') + patchDev { + minecraft { + source = layout.buildDirectory.dir('cleanroom_gradle/sourceSets/mcp/sources').get().asFile + patchesDirectory = file('module/minecraft/patches') + dependsOn 'remapSrg2Mcp' + } + } +} + +afterEvaluate { + sourceSets.minecraftPatchDev.java.srcDir 'module/minecraft/src/main/java' +} + def modules = ['minecraft', 'forge', 'cleanroom', 'kirino', 'builtin/mixinbooter'] sourceSets { @@ -38,8 +54,6 @@ var export_arguments = [ '--add-exports=java.base/jdk.internal.reflect=ALL-UNNAMED' ] -def asm_version = providers.gradleProperty('asm_version').get() - configurations.configureEach { resolutionStrategy.eachDependency { details -> switch ("${details.requested.group}:${details.requested.name}") { @@ -69,6 +83,7 @@ configurations.configureEach { dependencies { // ASM + def asm_version = providers.gradleProperty('asm_version').get() implementation "org.ow2.asm:asm:${asm_version}" implementation "org.ow2.asm:asm-commons:${asm_version}" implementation "org.ow2.asm:asm-tree:${asm_version}" @@ -80,16 +95,14 @@ dependencies { implementation 'com.cleanroommc:cleanmix:0.4.6' implementation 'io.github.llamalad7:mixinextras-common:0.5.4' - - api 'top.outlands:foundation:0.19.8' - api 'net.lenni0451:Reflect:1.6.4' - api 'net.lenni0451.commons:unchecked:1.9.2' - api 'org.javassist:javassist:3.30.2-GA' - api 'com.google.guava:failureaccess:1.0.2' - api 'com.google.code.findbugs:jsr305:3.0.2' api 'org.jspecify:jspecify:1.0.0' + api 'top.outlands:foundation:0.19.8' + api 'net.lenni0451:Reflect:1.6.4' // FIXME + api 'net.lenni0451.commons:unchecked:1.9.2' // FIXME + api 'org.javassist:javassist:3.30.2-GA' // FIXME + api 'com.google.code.findbugs:jsr305:3.0.2' // FIXME api 'lzma:lzma:0.0.1' - api 'java3d:vecmath:1.5.2' + api 'java3d:vecmath:1.5.2' // TODO: joml api 'net.sf.trove4j:core:3.1.0' api 'net.sf.trove4j:experimental:3.1.0' api 'org.apache.maven:maven-artifact:3.9.16' @@ -99,6 +112,7 @@ dependencies { api 'org.apache.logging.log4j:log4j-slf4j2-impl:2.26.0' api 'org.slf4j:slf4j-api:2.0.18' + // TODO reconsider // Apache HTTP 5 api 'org.apache.httpcomponents.core5:httpcore5:5.4.3' api 'org.apache.httpcomponents.core5:httpcore5-h2:5.4.3' @@ -111,6 +125,7 @@ dependencies { api 'jakarta.xml.bind:jakarta.xml.bind-api:4.0.5' api 'jakarta.inject:jakarta.inject-api:2.0.1' + // TODO reconsider // Script engines / XML binding api 'org.glassfish.jaxb:jaxb-runtime:4.0.9' api 'org.glassfish.jaxb:jaxb-core:4.0.9' @@ -118,21 +133,30 @@ dependencies { api 'org.glassfish.corba:glassfish-corba-omgapi:5.0.2' api 'org.openjdk.nashorn:nashorn-core:15.7' - // cleanroom + // Others api 'org.jline:jline:4.1.3' api 'org.jline:jline-native:4.1.3' api 'com.github.oshi:oshi-core-ffm:7.3.2' api 'com.github.oshi:oshi-common:7.3.2' api 'net.java.dev.jna:jna-platform:5.19.1' - // kirino - // TODO - // compileOnly 'com.cleanroommc:lwjglx:1.0.0' - // api 'com.cleanroommc:lwjglxx:1.1.21' + // LWJGL + api platform('org.lwjgl:lwjgl-bom:3.4.1') + api 'org.lwjgl:lwjgl' + api 'org.lwjgl:lwjgl-opengl' + api 'org.lwjgl:lwjgl-openal' + api 'org.lwjgl:lwjgl-sdl' + runtimeOnly 'org.lwjgl:lwjgl::natives-windows' + runtimeOnly 'org.lwjgl:lwjgl-opengl::natives-windows' + runtimeOnly 'org.lwjgl:lwjgl-openal::natives-windows' + runtimeOnly 'org.lwjgl:lwjgl-sdl::natives-windows' + // runtimeOnly 'com.cleanroommc:lwjgly:1.0.0' + + // Kirino api 'org.joml:joml:1.10.9' api 'io.github.classgraph:classgraph:4.8.184' - // test + // Test testImplementation platform('org.junit:junit-bom:6.1.0') testImplementation 'org.junit.jupiter:junit-jupiter' testImplementation 'org.junit.vintage:junit-vintage-engine' @@ -152,4 +176,8 @@ tasks.withType(JavaCompile).configureEach { dependsOn 'printBuildInfo' options.encoding = 'UTF-8' options.compilerArgs += export_arguments +} + +tasks.withType(com.cleanroommc.gradle.api.task.mc.RunMinecraft).configureEach { + jvmArgs '-Dmixin.debug.export=true', '-Dmixin.checks.interfaces=true' } \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 87c43f334..28f540333 100644 --- a/settings.gradle +++ b/settings.gradle @@ -14,5 +14,5 @@ pluginManagement { } plugins { - id 'com.cleanroommc.gradle.settings' version '0.2.0' + id 'com.cleanroommc.cleanroomgradle.settings' version '0.3.0' } From e7b005ec61a78fe80c584445a119ca3c4a7c80e9 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Tue, 11 Aug 2026 15:28:35 +0100 Subject: [PATCH 07/99] Update CG to 0.4.2 --- settings.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle b/settings.gradle index 28f540333..bb2c6e128 100644 --- a/settings.gradle +++ b/settings.gradle @@ -14,5 +14,5 @@ pluginManagement { } plugins { - id 'com.cleanroommc.cleanroomgradle.settings' version '0.3.0' + id 'com.cleanroommc.cleanroomgradle.settings' version '0.4.2' } From 7ef5a3f956ac558cc1542aa63227a30659d0789c Mon Sep 17 00:00:00 2001 From: Rongmario Date: Tue, 11 Aug 2026 15:33:37 +0100 Subject: [PATCH 08/99] Added CleanMix, MixinExtras versions to gradle.properties --- build.gradle | 4 ++-- gradle.properties | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 6c1d01348..fae336323 100644 --- a/build.gradle +++ b/build.gradle @@ -92,8 +92,8 @@ dependencies { implementation "org.ow2.asm:asm-deprecated:7.1" // Mixin - implementation 'com.cleanroommc:cleanmix:0.4.6' - implementation 'io.github.llamalad7:mixinextras-common:0.5.4' + implementation "com.cleanroommc:cleanmix:${providers.gradleProperty('cleanmix_version').get()}" + implementation "com.cleanroommc:mixinextras-common:${providers.gradleProperty('mixinextras_version').get()}" api 'org.jspecify:jspecify:1.0.0' api 'top.outlands:foundation:0.19.8' diff --git a/gradle.properties b/gradle.properties index b138773a6..ef93edba7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,6 +6,8 @@ java_major = 25 # Libraries asm_version = 9.10.1 +cleanmix_version = 0.7.2 +mixinextras_version = 0.5.5 # Gradle org.gradle.jvmargs = -Xmx3G From 2b449a3ec2620f3b8a79098a7c20ef46bcdf24a4 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Tue, 11 Aug 2026 15:34:59 +0100 Subject: [PATCH 09/99] Exclude `com.ibm.icu:icu4j-core-mojang`, `com.mojang:patchy` dependencies --- build.gradle | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/build.gradle b/build.gradle index fae336323..878a54e73 100644 --- a/build.gradle +++ b/build.gradle @@ -55,6 +55,11 @@ var export_arguments = [ ] configurations.configureEach { + exclude group: 'com.ibm.icu', module: 'icu4j-core-mojang' + // patchy ships its own copy of io.netty.bootstrap.Bootstrap + // Against 4.2 netty it shadows the real class and dies on a superclass method that no longer exists + exclude group: 'com.mojang', module: 'patchy' + resolutionStrategy.eachDependency { details -> switch ("${details.requested.group}:${details.requested.name}") { case 'com.google.guava:guava': details.useVersion '33.6.0-jre'; break From b8060abbb24006ba6d7a7ae205d4b93479993aeb Mon Sep 17 00:00:00 2001 From: Rongmario Date: Tue, 11 Aug 2026 15:36:21 +0100 Subject: [PATCH 10/99] Refrain from using afterEvaluate --- build.gradle | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 878a54e73..17fdc5601 100644 --- a/build.gradle +++ b/build.gradle @@ -25,15 +25,11 @@ cleanroom { } } -afterEvaluate { - sourceSets.minecraftPatchDev.java.srcDir 'module/minecraft/src/main/java' -} - def modules = ['minecraft', 'forge', 'cleanroom', 'kirino', 'builtin/mixinbooter'] sourceSets { main { - java.srcDirs = modules.collect { "module/${it}/src/main/java" } + java.srcDirs = modules.collect { "module/${it}/src/main/java" } + 'module/minecraft/injected/java' resources.srcDirs = modules.collect { "module/${it}/src/main/resources" } } test { From 8b42158989bb617b834dec24c9d596dccac46bcf Mon Sep 17 00:00:00 2001 From: Rongmario Date: Tue, 11 Aug 2026 15:36:44 +0100 Subject: [PATCH 11/99] Specify directories for patch development --- build.gradle | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 17fdc5601..86926ac86 100644 --- a/build.gradle +++ b/build.gradle @@ -15,11 +15,13 @@ java { cleanroom { loaderProject = true + developInitialPatches = false accessTransformers.from file('module/forge/src/main/resources/forge_at.cfg') patchDev { minecraft { - source = layout.buildDirectory.dir('cleanroom_gradle/sourceSets/mcp/sources').get().asFile - patchesDirectory = file('module/minecraft/patches') + input = layout.buildDirectory.dir('cleanroom_gradle/sourceSets/mcp/sources') + patches = layout.projectDirectory.dir('module/minecraft/patches') + output = layout.projectDirectory.dir('module/minecraft/src/main/java') dependsOn 'remapSrg2Mcp' } } From 561fadc73d7bf7af33d931b5c241f8b7508964da Mon Sep 17 00:00:00 2001 From: Rongmario Date: Tue, 11 Aug 2026 15:37:15 +0100 Subject: [PATCH 12/99] Exclude LWJGL 2 natives from runtime --- build.gradle | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/build.gradle b/build.gradle index 86926ac86..0dd82128d 100644 --- a/build.gradle +++ b/build.gradle @@ -84,6 +84,19 @@ configurations.configureEach { } } +configurations.named('vanillaNatives') { + exclude group: 'ca.weblite', module: 'java-objc-bridge' + // LWJGL 2's natives are never loaded: LWJGLY reaches LWJGL 3's instead. + exclude group: 'org.lwjgl.lwjgl' +} + +// TODO: Needed? +['runtimeClasspath', 'testRuntimeClasspath'].each { name -> + configurations.named(name) { + exclude group: 'org.lwjgl.lwjgl' + } +} + dependencies { // ASM def asm_version = providers.gradleProperty('asm_version').get() From bb730efd63720b1f2541bbf6d059f5c945d38f7c Mon Sep 17 00:00:00 2001 From: Rongmario Date: Tue, 11 Aug 2026 15:39:13 +0100 Subject: [PATCH 13/99] Remove google's jsr305 dep, documented jakarta/java 8's javax differences --- build.gradle | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 0dd82128d..95aa88024 100644 --- a/build.gradle +++ b/build.gradle @@ -112,11 +112,10 @@ dependencies { implementation "com.cleanroommc:mixinextras-common:${providers.gradleProperty('mixinextras_version').get()}" api 'org.jspecify:jspecify:1.0.0' - api 'top.outlands:foundation:0.19.8' + api 'top.outlands:foundation:0.19.11' api 'net.lenni0451:Reflect:1.6.4' // FIXME api 'net.lenni0451.commons:unchecked:1.9.2' // FIXME api 'org.javassist:javassist:3.30.2-GA' // FIXME - api 'com.google.code.findbugs:jsr305:3.0.2' // FIXME api 'lzma:lzma:0.0.1' api 'java3d:vecmath:1.5.2' // TODO: joml api 'net.sf.trove4j:core:3.1.0' @@ -134,11 +133,16 @@ dependencies { api 'org.apache.httpcomponents.core5:httpcore5-h2:5.4.3' api 'org.apache.httpcomponents.client5:httpclient5:5.6.1' - // Jakarta (replaces javax) + // Jakarta replacements for APIs that were bundled with Java 8 SE, except javax.inject. + // Java 8 SE packages: javax.xml.ws and javax.jws api 'jakarta.xml.ws:jakarta.xml.ws-api:4.0.3' + // Java 8 SE package: javax.activation api 'jakarta.activation:jakarta.activation-api:2.1.4' + // Java 8 SE package: javax.annotation api 'jakarta.annotation:jakarta.annotation-api:3.0.0' + // Java 8 SE packages: javax.xml.bind and its subpackages api 'jakarta.xml.bind:jakarta.xml.bind-api:4.0.5' + // TODO: javax.inject was the external JSR-330 API, *NOT* part of Java 8 SE api 'jakarta.inject:jakarta.inject-api:2.0.1' // TODO reconsider From 28eb98f5e31ae988a0645ff19f5b6d19c419985f Mon Sep 17 00:00:00 2001 From: Rongmario Date: Tue, 11 Aug 2026 15:39:54 +0100 Subject: [PATCH 14/99] Added `ca.weblite:java-objc-bridge:1.2` back --- build.gradle | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.gradle b/build.gradle index 95aa88024..6ca464291 100644 --- a/build.gradle +++ b/build.gradle @@ -159,6 +159,8 @@ dependencies { api 'com.github.oshi:oshi-core-ffm:7.3.2' api 'com.github.oshi:oshi-common:7.3.2' api 'net.java.dev.jna:jna-platform:5.19.1' + // java-objc-bridge bumped here for updated OSX arm64 natives + api 'ca.weblite:java-objc-bridge:1.2' // LWJGL api platform('org.lwjgl:lwjgl-bom:3.4.1') From 2c452ff3a561249b452ce66fbcfafa9dd2452ec1 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Tue, 11 Aug 2026 15:44:08 +0100 Subject: [PATCH 15/99] Updated LWJGL to 3.4.2 and clarified bindings --- build.gradle | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 6ca464291..20e9ee251 100644 --- a/build.gradle +++ b/build.gradle @@ -162,17 +162,25 @@ dependencies { // java-objc-bridge bumped here for updated OSX arm64 natives api 'ca.weblite:java-objc-bridge:1.2' - // LWJGL - api platform('org.lwjgl:lwjgl-bom:3.4.1') + api platform('org.lwjgl:lwjgl-bom:3.4.2') api 'org.lwjgl:lwjgl' + api 'org.lwjgl:lwjgl-jemalloc' api 'org.lwjgl:lwjgl-opengl' api 'org.lwjgl:lwjgl-openal' + api 'org.lwjgl:lwjgl-stb' + api 'org.lwjgl:lwjgl-tinyfd' api 'org.lwjgl:lwjgl-sdl' + + // TODO + // compileOnly 'com.cleanroommc:lwjgly-spi:1.0.0' + // runtimeOnly 'com.cleanroommc:lwjgly:1.0.0' runtimeOnly 'org.lwjgl:lwjgl::natives-windows' + runtimeOnly 'org.lwjgl:lwjgl-jemalloc::natives-windows' runtimeOnly 'org.lwjgl:lwjgl-opengl::natives-windows' runtimeOnly 'org.lwjgl:lwjgl-openal::natives-windows' + runtimeOnly 'org.lwjgl:lwjgl-stb::natives-windows' + runtimeOnly 'org.lwjgl:lwjgl-tinyfd::natives-windows' runtimeOnly 'org.lwjgl:lwjgl-sdl::natives-windows' - // runtimeOnly 'com.cleanroommc:lwjgly:1.0.0' // Kirino api 'org.joml:joml:1.10.9' From a608e89227ed49a576e4089d1333944d7e5cdd71 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Tue, 11 Aug 2026 15:44:51 +0100 Subject: [PATCH 16/99] Stop all `RunMinecraft` tasks from inheriting mixin debug args by default --- build.gradle | 4 ---- 1 file changed, 4 deletions(-) diff --git a/build.gradle b/build.gradle index 20e9ee251..ef78f62ba 100644 --- a/build.gradle +++ b/build.gradle @@ -207,7 +207,3 @@ tasks.withType(JavaCompile).configureEach { options.encoding = 'UTF-8' options.compilerArgs += export_arguments } - -tasks.withType(com.cleanroommc.gradle.api.task.mc.RunMinecraft).configureEach { - jvmArgs '-Dmixin.debug.export=true', '-Dmixin.checks.interfaces=true' -} \ No newline at end of file From 14cc475ad99afa5d04bf371ba5354431afc7bbe9 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Tue, 11 Aug 2026 15:45:05 +0100 Subject: [PATCH 17/99] Added a test task --- build.gradle | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/build.gradle b/build.gradle index ef78f62ba..7ce36f9b5 100644 --- a/build.gradle +++ b/build.gradle @@ -193,6 +193,13 @@ dependencies { testRuntimeOnly 'org.junit.platform:junit-platform-launcher' } +tasks.named('test', Test) { + maxParallelForks = 1 + useJUnitPlatform() + testLogging.events 'passed', 'skipped', 'failed' + jvmArgs open_arguments + export_arguments +} + tasks.register('printBuildInfo') { def v = version.toString() outputs.upToDateWhen { false } From f7d077ae0869bf18befe0cb91c2c02c4772a558c Mon Sep 17 00:00:00 2001 From: Rongmario Date: Tue, 11 Aug 2026 15:59:37 +0100 Subject: [PATCH 18/99] Cleaner gitignore --- .gitignore | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 6fb5d12ea..964d1a49b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,14 +1,11 @@ -/.idea/* -/.run/ -/.gradle/ -/build/ -/run/ -# Patched Minecraft source -/module/minecraft/ -/buildSrc/.gradle/ -/buildSrc/build/ -/buildSrc/out/ +**/.idea/* +**/.run/ +**/.gradle/ +**/build/ +**/run/ +/module/minecraft/src/ +# TODO module/cleanroom/src/main/java/com/cleanroommc/common/CleanroomVersion.java !/.idea/icon.svg From 70f4fd7f66ddd2621c4de8174484a000802b2c7a Mon Sep 17 00:00:00 2001 From: Rongmario Date: Tue, 11 Aug 2026 16:14:55 +0100 Subject: [PATCH 19/99] BREAKING: Renamed kirino submodule - If you aren't re-cloning you need to - Deinit all submodules - Remove all files in `.git/modules/projects/` and `projects/kirino` - Remove `submodule.projects/kirino` section from git config - Update and init `module/kirino` submodule again --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 65e31ed30..19a8a6b85 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "projects/kirino"] +[submodule "kirino"] path = module/kirino url = https://github.com/CleanroomMC/Kirino-Engine.git From 08d4baec7f1f1624baea992942f471f6d49b98d4 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Tue, 11 Aug 2026 16:20:02 +0100 Subject: [PATCH 20/99] Moved new files from the rebase --- .../src}/main/java/com/cleanroommc/cleanmix/CleanMixHooks.java | 0 .../main/java/com/cleanroommc/cleanmix/CleanMixModContainer.java | 0 .../java/com/cleanroommc/cleanmix/service/CleanMixBootstrap.java | 0 .../java/com/cleanroommc/cleanmix/service/CleanMixService.java | 0 .../cleanroommc/cleanmix/service/FoundationBytecodeProvider.java | 0 .../com/cleanroommc/cleanmix/service/FoundationClassProvider.java | 0 .../com/cleanroommc/cleanmix/service/FoundationClassTracker.java | 0 .../cleanmix/service/FoundationTransformerProvider.java | 0 .../com/cleanroommc/client/chat/suggestion/SuggestionList.java | 0 .../com/cleanroommc/client/chat/suggestion/SuggestionUpdater.java | 0 .../src}/main/java/com/cleanroommc/client/modlist/ImageInfo.java | 0 .../src}/main/java/com/cleanroommc/client/modlist/ImageType.java | 0 .../java/com/cleanroommc/client/modlist/LegacyModListScreen.java | 0 .../main/java/com/cleanroommc/client/modlist/ModListConfig.java | 0 .../java/com/cleanroommc/client/modlist/ModListConstants.java | 0 .../main/java/com/cleanroommc/client/modlist/PlatformUtils.java | 0 .../main/java/com/cleanroommc/client/modlist/RenderUtils.java | 0 .../com/cleanroommc/client/modlist/data/CleanroomModData.java | 0 .../main/java/com/cleanroommc/client/modlist/data/IModData.java | 0 .../com/cleanroommc/client/modlist/data/MinecraftModData.java | 0 .../java/com/cleanroommc/client/modlist/data/OptiFineModData.java | 0 .../cleanroommc/client/modlist/screen/DropdownMenuHandler.java | 0 .../java/com/cleanroommc/client/modlist/screen/ModListScreen.java | 0 .../cleanroommc/client/modlist/screen/widget/DropdownMenu.java | 0 .../cleanroommc/client/modlist/screen/widget/ModListExtended.java | 0 .../client/modlist/screen/widget/ModListIconButton.java | 0 .../client/modlist/screen/widget/ModListSelection.java | 0 .../client/modlist/screen/widget/ModListTextButton.java | 0 .../client/modlist/screen/widget/ModListTextField.java | 0 .../java/com/cleanroommc/discovery/CleanroomModDiscoverer.java | 0 .../src}/main/java/com/cleanroommc/discovery/DiscoveredMod.java | 0 .../src}/main/java/com/cleanroommc/discovery/IdentifiedMods.java | 0 .../src}/main/java/com/cleanroommc/util/CleanroomLog.java | 0 .../net/minecraftforge/fml/common/discovery/ASMDataTableTest.java | 0 34 files changed, 0 insertions(+), 0 deletions(-) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/cleanmix/CleanMixHooks.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/cleanmix/CleanMixModContainer.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/cleanmix/service/CleanMixBootstrap.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/cleanmix/service/CleanMixService.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/cleanmix/service/FoundationBytecodeProvider.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/cleanmix/service/FoundationClassProvider.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/cleanmix/service/FoundationClassTracker.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/cleanmix/service/FoundationTransformerProvider.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/chat/suggestion/SuggestionList.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/chat/suggestion/SuggestionUpdater.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/modlist/ImageInfo.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/modlist/ImageType.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/modlist/LegacyModListScreen.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/modlist/ModListConfig.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/modlist/ModListConstants.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/modlist/PlatformUtils.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/modlist/RenderUtils.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/modlist/data/CleanroomModData.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/modlist/data/IModData.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/modlist/data/MinecraftModData.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/modlist/data/OptiFineModData.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/modlist/screen/DropdownMenuHandler.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/modlist/screen/ModListScreen.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/modlist/screen/widget/DropdownMenu.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/modlist/screen/widget/ModListExtended.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/modlist/screen/widget/ModListIconButton.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/modlist/screen/widget/ModListSelection.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/modlist/screen/widget/ModListTextButton.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/client/modlist/screen/widget/ModListTextField.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/discovery/CleanroomModDiscoverer.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/discovery/DiscoveredMod.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/discovery/IdentifiedMods.java (100%) rename {src => module/cleanroom/src}/main/java/com/cleanroommc/util/CleanroomLog.java (100%) rename {src => module/forge/src}/test/java/net/minecraftforge/fml/common/discovery/ASMDataTableTest.java (100%) diff --git a/src/main/java/com/cleanroommc/cleanmix/CleanMixHooks.java b/module/cleanroom/src/main/java/com/cleanroommc/cleanmix/CleanMixHooks.java similarity index 100% rename from src/main/java/com/cleanroommc/cleanmix/CleanMixHooks.java rename to module/cleanroom/src/main/java/com/cleanroommc/cleanmix/CleanMixHooks.java diff --git a/src/main/java/com/cleanroommc/cleanmix/CleanMixModContainer.java b/module/cleanroom/src/main/java/com/cleanroommc/cleanmix/CleanMixModContainer.java similarity index 100% rename from src/main/java/com/cleanroommc/cleanmix/CleanMixModContainer.java rename to module/cleanroom/src/main/java/com/cleanroommc/cleanmix/CleanMixModContainer.java diff --git a/src/main/java/com/cleanroommc/cleanmix/service/CleanMixBootstrap.java b/module/cleanroom/src/main/java/com/cleanroommc/cleanmix/service/CleanMixBootstrap.java similarity index 100% rename from src/main/java/com/cleanroommc/cleanmix/service/CleanMixBootstrap.java rename to module/cleanroom/src/main/java/com/cleanroommc/cleanmix/service/CleanMixBootstrap.java diff --git a/src/main/java/com/cleanroommc/cleanmix/service/CleanMixService.java b/module/cleanroom/src/main/java/com/cleanroommc/cleanmix/service/CleanMixService.java similarity index 100% rename from src/main/java/com/cleanroommc/cleanmix/service/CleanMixService.java rename to module/cleanroom/src/main/java/com/cleanroommc/cleanmix/service/CleanMixService.java diff --git a/src/main/java/com/cleanroommc/cleanmix/service/FoundationBytecodeProvider.java b/module/cleanroom/src/main/java/com/cleanroommc/cleanmix/service/FoundationBytecodeProvider.java similarity index 100% rename from src/main/java/com/cleanroommc/cleanmix/service/FoundationBytecodeProvider.java rename to module/cleanroom/src/main/java/com/cleanroommc/cleanmix/service/FoundationBytecodeProvider.java diff --git a/src/main/java/com/cleanroommc/cleanmix/service/FoundationClassProvider.java b/module/cleanroom/src/main/java/com/cleanroommc/cleanmix/service/FoundationClassProvider.java similarity index 100% rename from src/main/java/com/cleanroommc/cleanmix/service/FoundationClassProvider.java rename to module/cleanroom/src/main/java/com/cleanroommc/cleanmix/service/FoundationClassProvider.java diff --git a/src/main/java/com/cleanroommc/cleanmix/service/FoundationClassTracker.java b/module/cleanroom/src/main/java/com/cleanroommc/cleanmix/service/FoundationClassTracker.java similarity index 100% rename from src/main/java/com/cleanroommc/cleanmix/service/FoundationClassTracker.java rename to module/cleanroom/src/main/java/com/cleanroommc/cleanmix/service/FoundationClassTracker.java diff --git a/src/main/java/com/cleanroommc/cleanmix/service/FoundationTransformerProvider.java b/module/cleanroom/src/main/java/com/cleanroommc/cleanmix/service/FoundationTransformerProvider.java similarity index 100% rename from src/main/java/com/cleanroommc/cleanmix/service/FoundationTransformerProvider.java rename to module/cleanroom/src/main/java/com/cleanroommc/cleanmix/service/FoundationTransformerProvider.java diff --git a/src/main/java/com/cleanroommc/client/chat/suggestion/SuggestionList.java b/module/cleanroom/src/main/java/com/cleanroommc/client/chat/suggestion/SuggestionList.java similarity index 100% rename from src/main/java/com/cleanroommc/client/chat/suggestion/SuggestionList.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/chat/suggestion/SuggestionList.java diff --git a/src/main/java/com/cleanroommc/client/chat/suggestion/SuggestionUpdater.java b/module/cleanroom/src/main/java/com/cleanroommc/client/chat/suggestion/SuggestionUpdater.java similarity index 100% rename from src/main/java/com/cleanroommc/client/chat/suggestion/SuggestionUpdater.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/chat/suggestion/SuggestionUpdater.java diff --git a/src/main/java/com/cleanroommc/client/modlist/ImageInfo.java b/module/cleanroom/src/main/java/com/cleanroommc/client/modlist/ImageInfo.java similarity index 100% rename from src/main/java/com/cleanroommc/client/modlist/ImageInfo.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/modlist/ImageInfo.java diff --git a/src/main/java/com/cleanroommc/client/modlist/ImageType.java b/module/cleanroom/src/main/java/com/cleanroommc/client/modlist/ImageType.java similarity index 100% rename from src/main/java/com/cleanroommc/client/modlist/ImageType.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/modlist/ImageType.java diff --git a/src/main/java/com/cleanroommc/client/modlist/LegacyModListScreen.java b/module/cleanroom/src/main/java/com/cleanroommc/client/modlist/LegacyModListScreen.java similarity index 100% rename from src/main/java/com/cleanroommc/client/modlist/LegacyModListScreen.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/modlist/LegacyModListScreen.java diff --git a/src/main/java/com/cleanroommc/client/modlist/ModListConfig.java b/module/cleanroom/src/main/java/com/cleanroommc/client/modlist/ModListConfig.java similarity index 100% rename from src/main/java/com/cleanroommc/client/modlist/ModListConfig.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/modlist/ModListConfig.java diff --git a/src/main/java/com/cleanroommc/client/modlist/ModListConstants.java b/module/cleanroom/src/main/java/com/cleanroommc/client/modlist/ModListConstants.java similarity index 100% rename from src/main/java/com/cleanroommc/client/modlist/ModListConstants.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/modlist/ModListConstants.java diff --git a/src/main/java/com/cleanroommc/client/modlist/PlatformUtils.java b/module/cleanroom/src/main/java/com/cleanroommc/client/modlist/PlatformUtils.java similarity index 100% rename from src/main/java/com/cleanroommc/client/modlist/PlatformUtils.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/modlist/PlatformUtils.java diff --git a/src/main/java/com/cleanroommc/client/modlist/RenderUtils.java b/module/cleanroom/src/main/java/com/cleanroommc/client/modlist/RenderUtils.java similarity index 100% rename from src/main/java/com/cleanroommc/client/modlist/RenderUtils.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/modlist/RenderUtils.java diff --git a/src/main/java/com/cleanroommc/client/modlist/data/CleanroomModData.java b/module/cleanroom/src/main/java/com/cleanroommc/client/modlist/data/CleanroomModData.java similarity index 100% rename from src/main/java/com/cleanroommc/client/modlist/data/CleanroomModData.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/modlist/data/CleanroomModData.java diff --git a/src/main/java/com/cleanroommc/client/modlist/data/IModData.java b/module/cleanroom/src/main/java/com/cleanroommc/client/modlist/data/IModData.java similarity index 100% rename from src/main/java/com/cleanroommc/client/modlist/data/IModData.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/modlist/data/IModData.java diff --git a/src/main/java/com/cleanroommc/client/modlist/data/MinecraftModData.java b/module/cleanroom/src/main/java/com/cleanroommc/client/modlist/data/MinecraftModData.java similarity index 100% rename from src/main/java/com/cleanroommc/client/modlist/data/MinecraftModData.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/modlist/data/MinecraftModData.java diff --git a/src/main/java/com/cleanroommc/client/modlist/data/OptiFineModData.java b/module/cleanroom/src/main/java/com/cleanroommc/client/modlist/data/OptiFineModData.java similarity index 100% rename from src/main/java/com/cleanroommc/client/modlist/data/OptiFineModData.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/modlist/data/OptiFineModData.java diff --git a/src/main/java/com/cleanroommc/client/modlist/screen/DropdownMenuHandler.java b/module/cleanroom/src/main/java/com/cleanroommc/client/modlist/screen/DropdownMenuHandler.java similarity index 100% rename from src/main/java/com/cleanroommc/client/modlist/screen/DropdownMenuHandler.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/modlist/screen/DropdownMenuHandler.java diff --git a/src/main/java/com/cleanroommc/client/modlist/screen/ModListScreen.java b/module/cleanroom/src/main/java/com/cleanroommc/client/modlist/screen/ModListScreen.java similarity index 100% rename from src/main/java/com/cleanroommc/client/modlist/screen/ModListScreen.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/modlist/screen/ModListScreen.java diff --git a/src/main/java/com/cleanroommc/client/modlist/screen/widget/DropdownMenu.java b/module/cleanroom/src/main/java/com/cleanroommc/client/modlist/screen/widget/DropdownMenu.java similarity index 100% rename from src/main/java/com/cleanroommc/client/modlist/screen/widget/DropdownMenu.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/modlist/screen/widget/DropdownMenu.java diff --git a/src/main/java/com/cleanroommc/client/modlist/screen/widget/ModListExtended.java b/module/cleanroom/src/main/java/com/cleanroommc/client/modlist/screen/widget/ModListExtended.java similarity index 100% rename from src/main/java/com/cleanroommc/client/modlist/screen/widget/ModListExtended.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/modlist/screen/widget/ModListExtended.java diff --git a/src/main/java/com/cleanroommc/client/modlist/screen/widget/ModListIconButton.java b/module/cleanroom/src/main/java/com/cleanroommc/client/modlist/screen/widget/ModListIconButton.java similarity index 100% rename from src/main/java/com/cleanroommc/client/modlist/screen/widget/ModListIconButton.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/modlist/screen/widget/ModListIconButton.java diff --git a/src/main/java/com/cleanroommc/client/modlist/screen/widget/ModListSelection.java b/module/cleanroom/src/main/java/com/cleanroommc/client/modlist/screen/widget/ModListSelection.java similarity index 100% rename from src/main/java/com/cleanroommc/client/modlist/screen/widget/ModListSelection.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/modlist/screen/widget/ModListSelection.java diff --git a/src/main/java/com/cleanroommc/client/modlist/screen/widget/ModListTextButton.java b/module/cleanroom/src/main/java/com/cleanroommc/client/modlist/screen/widget/ModListTextButton.java similarity index 100% rename from src/main/java/com/cleanroommc/client/modlist/screen/widget/ModListTextButton.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/modlist/screen/widget/ModListTextButton.java diff --git a/src/main/java/com/cleanroommc/client/modlist/screen/widget/ModListTextField.java b/module/cleanroom/src/main/java/com/cleanroommc/client/modlist/screen/widget/ModListTextField.java similarity index 100% rename from src/main/java/com/cleanroommc/client/modlist/screen/widget/ModListTextField.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/modlist/screen/widget/ModListTextField.java diff --git a/src/main/java/com/cleanroommc/discovery/CleanroomModDiscoverer.java b/module/cleanroom/src/main/java/com/cleanroommc/discovery/CleanroomModDiscoverer.java similarity index 100% rename from src/main/java/com/cleanroommc/discovery/CleanroomModDiscoverer.java rename to module/cleanroom/src/main/java/com/cleanroommc/discovery/CleanroomModDiscoverer.java diff --git a/src/main/java/com/cleanroommc/discovery/DiscoveredMod.java b/module/cleanroom/src/main/java/com/cleanroommc/discovery/DiscoveredMod.java similarity index 100% rename from src/main/java/com/cleanroommc/discovery/DiscoveredMod.java rename to module/cleanroom/src/main/java/com/cleanroommc/discovery/DiscoveredMod.java diff --git a/src/main/java/com/cleanroommc/discovery/IdentifiedMods.java b/module/cleanroom/src/main/java/com/cleanroommc/discovery/IdentifiedMods.java similarity index 100% rename from src/main/java/com/cleanroommc/discovery/IdentifiedMods.java rename to module/cleanroom/src/main/java/com/cleanroommc/discovery/IdentifiedMods.java diff --git a/src/main/java/com/cleanroommc/util/CleanroomLog.java b/module/cleanroom/src/main/java/com/cleanroommc/util/CleanroomLog.java similarity index 100% rename from src/main/java/com/cleanroommc/util/CleanroomLog.java rename to module/cleanroom/src/main/java/com/cleanroommc/util/CleanroomLog.java diff --git a/src/test/java/net/minecraftforge/fml/common/discovery/ASMDataTableTest.java b/module/forge/src/test/java/net/minecraftforge/fml/common/discovery/ASMDataTableTest.java similarity index 100% rename from src/test/java/net/minecraftforge/fml/common/discovery/ASMDataTableTest.java rename to module/forge/src/test/java/net/minecraftforge/fml/common/discovery/ASMDataTableTest.java From 077c9ae3d155e643f0f9c429fd9e308f36614c5c Mon Sep 17 00:00:00 2001 From: Rongmario Date: Tue, 11 Aug 2026 16:22:39 +0100 Subject: [PATCH 21/99] Move ConfigAnytime to builtin module --- build.gradle | 9 ++++++++- .../com/cleanroommc/configanytime/ConfigAnytime.java | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-) rename module/{cleanroom => builtin/configanytime}/src/main/java/com/cleanroommc/configanytime/ConfigAnytime.java (99%) diff --git a/build.gradle b/build.gradle index 7ce36f9b5..c5aa31a50 100644 --- a/build.gradle +++ b/build.gradle @@ -27,7 +27,14 @@ cleanroom { } } -def modules = ['minecraft', 'forge', 'cleanroom', 'kirino', 'builtin/mixinbooter'] +def modules = [ + 'minecraft', + 'forge', + 'cleanroom', + 'kirino', + 'builtin/mixinbooter', + 'builtin/configanytime' +] sourceSets { main { diff --git a/module/cleanroom/src/main/java/com/cleanroommc/configanytime/ConfigAnytime.java b/module/builtin/configanytime/src/main/java/com/cleanroommc/configanytime/ConfigAnytime.java similarity index 99% rename from module/cleanroom/src/main/java/com/cleanroommc/configanytime/ConfigAnytime.java rename to module/builtin/configanytime/src/main/java/com/cleanroommc/configanytime/ConfigAnytime.java index 895dc6074..329f675a3 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/configanytime/ConfigAnytime.java +++ b/module/builtin/configanytime/src/main/java/com/cleanroommc/configanytime/ConfigAnytime.java @@ -5,6 +5,7 @@ @Deprecated public class ConfigAnytime { + /** * A wrapper of {@link ConfigManager#register(Class)}, created for compatibility. * @param configClass configuration class that is annotated with {@link Config} @@ -12,4 +13,5 @@ public class ConfigAnytime { public static void register(Class configClass) { ConfigManager.register(configClass); } + } From 92901f27f650ceba61daf766cdd1f587cf9f605b Mon Sep 17 00:00:00 2001 From: Rongmario Date: Tue, 11 Aug 2026 23:17:15 +0100 Subject: [PATCH 22/99] Update CG to 0.4.3, tidied up natives --- build.gradle | 22 ++++++++-------------- settings.gradle | 2 +- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/build.gradle b/build.gradle index c5aa31a50..6fbec2b92 100644 --- a/build.gradle +++ b/build.gradle @@ -97,13 +97,6 @@ configurations.named('vanillaNatives') { exclude group: 'org.lwjgl.lwjgl' } -// TODO: Needed? -['runtimeClasspath', 'testRuntimeClasspath'].each { name -> - configurations.named(name) { - exclude group: 'org.lwjgl.lwjgl' - } -} - dependencies { // ASM def asm_version = providers.gradleProperty('asm_version').get() @@ -181,17 +174,18 @@ dependencies { // TODO // compileOnly 'com.cleanroommc:lwjgly-spi:1.0.0' // runtimeOnly 'com.cleanroommc:lwjgly:1.0.0' - runtimeOnly 'org.lwjgl:lwjgl::natives-windows' - runtimeOnly 'org.lwjgl:lwjgl-jemalloc::natives-windows' - runtimeOnly 'org.lwjgl:lwjgl-opengl::natives-windows' - runtimeOnly 'org.lwjgl:lwjgl-openal::natives-windows' - runtimeOnly 'org.lwjgl:lwjgl-stb::natives-windows' - runtimeOnly 'org.lwjgl:lwjgl-tinyfd::natives-windows' - runtimeOnly 'org.lwjgl:lwjgl-sdl::natives-windows' + lwjglNative 'org.lwjgl:lwjgl' + lwjglNative 'org.lwjgl:lwjgl-jemalloc' + lwjglNative 'org.lwjgl:lwjgl-opengl' + lwjglNative 'org.lwjgl:lwjgl-openal' + lwjglNative 'org.lwjgl:lwjgl-stb' + lwjglNative 'org.lwjgl:lwjgl-tinyfd' + lwjglNative 'org.lwjgl:lwjgl-sdl' // Kirino api 'org.joml:joml:1.10.9' api 'io.github.classgraph:classgraph:4.8.184' + lwjglNative 'org.lwjgl:lwjgl-freetype' // Test testImplementation platform('org.junit:junit-bom:6.1.0') diff --git a/settings.gradle b/settings.gradle index bb2c6e128..851709564 100644 --- a/settings.gradle +++ b/settings.gradle @@ -14,5 +14,5 @@ pluginManagement { } plugins { - id 'com.cleanroommc.cleanroomgradle.settings' version '0.4.2' + id 'com.cleanroommc.cleanroomgradle.settings' version '0.4.3' } From 5405f3df63089b59753bad042042d9612d6be312 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Wed, 12 Aug 2026 10:45:01 +0100 Subject: [PATCH 23/99] Update buildscript and CG --- build.gradle | 12 ++---------- settings.gradle | 2 +- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/build.gradle b/build.gradle index 6fbec2b92..f6aee8aab 100644 --- a/build.gradle +++ b/build.gradle @@ -17,14 +17,6 @@ cleanroom { loaderProject = true developInitialPatches = false accessTransformers.from file('module/forge/src/main/resources/forge_at.cfg') - patchDev { - minecraft { - input = layout.buildDirectory.dir('cleanroom_gradle/sourceSets/mcp/sources') - patches = layout.projectDirectory.dir('module/minecraft/patches') - output = layout.projectDirectory.dir('module/minecraft/src/main/java') - dependsOn 'remapSrg2Mcp' - } - } } def modules = [ @@ -172,8 +164,8 @@ dependencies { api 'org.lwjgl:lwjgl-sdl' // TODO - // compileOnly 'com.cleanroommc:lwjgly-spi:1.0.0' - // runtimeOnly 'com.cleanroommc:lwjgly:1.0.0' + compileOnly 'com.cleanroommc:lwjgly-spi:1.0.0' + runtimeOnly 'com.cleanroommc:lwjgly:1.0.0' lwjglNative 'org.lwjgl:lwjgl' lwjglNative 'org.lwjgl:lwjgl-jemalloc' lwjglNative 'org.lwjgl:lwjgl-opengl' diff --git a/settings.gradle b/settings.gradle index 851709564..3483b536f 100644 --- a/settings.gradle +++ b/settings.gradle @@ -14,5 +14,5 @@ pluginManagement { } plugins { - id 'com.cleanroommc.cleanroomgradle.settings' version '0.4.3' + id 'com.cleanroommc.cleanroomgradle.settings' version '0.4.4' } From 31c13dba943ffe091739ba6d5b16d83707c49c84 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Thu, 13 Aug 2026 16:46:24 +0100 Subject: [PATCH 24/99] Update CG + configure to auto download sources/javadocs --- build.gradle | 7 +++++++ settings.gradle | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index f6aee8aab..57ac27613 100644 --- a/build.gradle +++ b/build.gradle @@ -13,6 +13,13 @@ java { withSourcesJar() } +idea { + module { + downloadSources = true + downloadJavadoc = true + } +} + cleanroom { loaderProject = true developInitialPatches = false diff --git a/settings.gradle b/settings.gradle index 3483b536f..51f7ef479 100644 --- a/settings.gradle +++ b/settings.gradle @@ -14,5 +14,5 @@ pluginManagement { } plugins { - id 'com.cleanroommc.cleanroomgradle.settings' version '0.4.4' + id 'com.cleanroommc.cleanroomgradle.settings' version '0.6.0' } From bad7f27f0f9f98e5db004294f6105d6c8aca3c64 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Thu, 13 Aug 2026 16:49:06 +0100 Subject: [PATCH 25/99] Ported Patches Pt. 1 --- module/minecraft/patches/.mappings.json | 4 + .../AdvancementManager.java.patch | 10 + .../AdvancementRewards.java.patch | 11 + .../advancements/DisplayInfo.java.patch | 13 + .../PlayerAdvancements.java.patch | 21 + .../critereon/ItemPredicate.java.patch | 15 + .../net/minecraft/block/Block.java.patch | 1507 +++++++++++++++++ .../minecraft/block/BlockBanner.java.patch | 43 + .../net/minecraft/block/BlockBed.java.patch | 13 + .../net/minecraft/block/BlockBush.java.patch | 68 + .../minecraft/block/BlockButton.java.patch | 11 + .../minecraft/block/BlockCactus.java.patch | 66 + .../net/minecraft/block/BlockChest.java.patch | 30 + .../block/BlockChorusFlower.java.patch | 28 + .../net/minecraft/block/BlockCocoa.java.patch | 40 + .../net/minecraft/block/BlockCrops.java.patch | 74 + .../minecraft/block/BlockDeadBush.java.patch | 26 + .../net/minecraft/block/BlockDoor.java.patch | 29 + .../block/BlockDoublePlant.java.patch | 82 + .../minecraft/block/BlockDragonEgg.java.patch | 38 + .../minecraft/block/BlockDropper.java.patch | 12 + .../block/BlockDynamicLiquid.java.patch | 67 + .../block/BlockEnchantmentTable.java.patch | 12 + .../block/BlockEnderChest.java.patch | 11 + .../minecraft/block/BlockFalling.java.patch | 25 + .../minecraft/block/BlockFarmland.java.patch | 33 + .../net/minecraft/block/BlockFence.java.patch | 48 + .../minecraft/block/BlockFenceGate.java.patch | 51 + .../net/minecraft/block/BlockFire.java.patch | 221 +++ .../minecraft/block/BlockFlowerPot.java.patch | 61 + .../net/minecraft/block/BlockGrass.java.patch | 42 + .../block/BlockHugeMushroom.java.patch | 30 + .../net/minecraft/block/BlockIce.java.patch | 29 + .../minecraft/block/BlockLadder.java.patch | 14 + .../minecraft/block/BlockLeaves.java.patch | 131 ++ .../minecraft/block/BlockLiquid.java.patch | 52 + .../net/minecraft/block/BlockLog.java.patch | 31 + .../block/BlockMobSpawner.java.patch | 18 + .../minecraft/block/BlockMushroom.java.patch | 13 + .../minecraft/block/BlockMycelium.java.patch | 25 + .../block/BlockNetherWart.java.patch | 57 + .../minecraft/block/BlockNewLeaf.java.patch | 12 + .../net/minecraft/block/BlockNote.java.patch | 23 + .../minecraft/block/BlockObserver.java.patch | 14 + .../minecraft/block/BlockOldLeaf.java.patch | 17 + .../net/minecraft/block/BlockOre.java.patch | 37 + .../net/minecraft/block/BlockPane.java.patch | 61 + .../block/BlockPistonBase.java.patch | 45 + .../block/BlockPistonMoving.java.patch | 34 + .../minecraft/block/BlockPortal.java.patch | 19 + .../minecraft/block/BlockPotato.java.patch | 24 + .../minecraft/block/BlockPumpkin.java.patch | 13 + .../minecraft/block/BlockQuartz.java.patch | 37 + .../minecraft/block/BlockRailBase.java.patch | 228 +++ .../block/BlockRailDetector.java.patch | 11 + .../block/BlockRailPowered.java.patch | 28 + .../block/BlockRedstoneComparator.java.patch | 24 + .../block/BlockRedstoneDiode.java.patch | 59 + .../block/BlockRedstoneOre.java.patch | 20 + .../block/BlockRedstoneTorch.java.patch | 11 + .../block/BlockRedstoneWire.java.patch | 71 + .../net/minecraft/block/BlockReed.java.patch | 56 + .../block/BlockRotatedPillar.java.patch | 21 + .../minecraft/block/BlockSapling.java.patch | 19 + .../net/minecraft/block/BlockSkull.java.patch | 54 + .../net/minecraft/block/BlockSlab.java.patch | 65 + .../net/minecraft/block/BlockSnow.java.patch | 59 + .../minecraft/block/BlockStairs.java.patch | 32 + .../block/BlockStaticLiquid.java.patch | 36 + .../net/minecraft/block/BlockStem.java.patch | 65 + .../minecraft/block/BlockTallGrass.java.patch | 51 + .../net/minecraft/block/BlockTorch.java.patch | 19 + .../minecraft/block/BlockTrapDoor.java.patch | 20 + .../net/minecraft/block/BlockVine.java.patch | 55 + .../net/minecraft/block/BlockWall.java.patch | 41 + .../net/minecraft/block/BlockWeb.java.patch | 28 + .../net/minecraft/block/SoundType.java.patch | 18 + .../BlockPistonStructureHelper.java.patch | 49 + .../block/state/BlockStateBase.java.patch | 12 + .../state/BlockStateContainer.java.patch | 137 ++ .../block/state/IBlockProperties.java.patch | 31 + .../client/ClientBrandRetriever.java.patch | 10 + .../client/LoadingScreenRenderer.java.patch | 26 + .../net/minecraft/client/Minecraft.java.patch | 625 +++++++ .../client/audio/SoundHandler.java.patch | 47 + .../client/audio/SoundManager.java.patch | 106 ++ .../entity/AbstractClientPlayer.java.patch | 19 + .../entity/EntityOtherPlayerMP.java.patch | 10 + .../client/entity/EntityPlayerSP.java.patch | 123 ++ .../client/gui/FontRenderer.java.patch | 254 +++ .../client/gui/GuiBossOverlay.java.patch | 22 + .../minecraft/client/gui/GuiButton.java.patch | 21 + .../client/gui/GuiControls.java.patch | 46 + .../client/gui/GuiCreateWorld.java.patch | 61 + .../client/gui/GuiEnchantment.java.patch | 27 + .../client/gui/GuiGameOver.java.patch | 11 + .../minecraft/client/gui/GuiIngame.java.patch | 38 + .../client/gui/GuiIngameMenu.java.patch | 57 + .../client/gui/GuiKeyBindingList.java.patch | 78 + .../client/gui/GuiLanguage.java.patch | 11 + .../gui/GuiListWorldSelectionEntry.java.patch | 11 + .../client/gui/GuiMainMenu.java.patch | 149 ++ .../client/gui/GuiMultiplayer.java.patch | 19 + .../client/gui/GuiOptions.java.patch | 11 + .../client/gui/GuiOverlayDebug.java.patch | 50 + .../minecraft/client/gui/GuiScreen.java.patch | 114 ++ .../client/gui/GuiScreenBook.java.patch | 10 + .../client/gui/GuiScreenDemo.java.patch | 40 + .../client/gui/GuiSleepMP.java.patch | 11 + .../minecraft/client/gui/GuiSlot.java.patch | 62 + .../client/gui/GuiSpectator.java.patch | 12 + .../client/gui/GuiTextField.java.patch | 18 + .../gui/GuiUtilRenderComponents.java.patch | 27 + .../client/gui/GuiVideoSettings.java.patch | 14 + .../client/gui/MapItemRenderer.java.patch | 11 + .../client/gui/ScaledResolution.java.patch | 11 + .../gui/ServerListEntryNormal.java.patch | 23 + .../advancements/GuiAdvancementTab.java.patch | 37 + .../GuiScreenAdvancements.java.patch | 85 + .../gui/inventory/GuiContainer.java.patch | 158 ++ .../inventory/GuiContainerCreative.java.patch | 296 ++++ .../gui/recipebook/GuiRecipeBook.java.patch | 30 + .../recipebook/GuiRecipeOverlay.java.patch | 18 + .../client/gui/toasts/RecipeToast.java.patch | 11 + .../client/model/ModelBase.java.patch | 10 + .../client/model/ModelBox.java.patch | 18 + .../client/model/ModelRenderer.java.patch | 44 + .../client/model/ModelSkeleton.java.patch | 22 + .../model/PositionTextureVertex.java.patch | 13 + .../client/model/TexturedQuad.java.patch | 19 + .../ChunkProviderClient.java.patch | 34 + .../multiplayer/GuiConnecting.java.patch | 11 + .../multiplayer/PlayerControllerMP.java.patch | 332 ++++ .../client/multiplayer/WorldClient.java.patch | 22 + .../NetHandlerHandshakeMemory.java.patch | 10 + .../network/NetHandlerLoginClient.java.patch | 14 + .../network/NetHandlerPlayClient.java.patch | 184 ++ .../client/network/ServerPinger.java.patch | 19 + .../client/particle/Particle.java.patch | 22 + .../particle/ParticleItemPickup.java.patch | 12 + .../particle/ParticleManager.java.patch | 31 + .../renderer/ActiveRenderInfo.java.patch | 36 + .../renderer/BlockFluidRenderer.java.patch | 13 + .../renderer/BlockModelRenderer.java.patch | 49 + .../renderer/BlockModelShapes.java.patch | 9 + .../BlockRendererDispatcher.java.patch | 31 + .../client/renderer/BufferBuilder.java.patch | 69 + .../client/renderer/ChestRenderer.java.patch | 11 + .../client/renderer/EntityRenderer.java.patch | 351 ++++ .../InventoryEffectRenderer.java.patch | 37 + .../renderer/ItemModelMesher.java.patch | 13 + .../client/renderer/ItemRenderer.java.patch | 101 ++ .../client/renderer/OpenGlHelper.java.patch | 48 + .../client/renderer/RenderGlobal.java.patch | 183 ++ .../client/renderer/RenderItem.java.patch | 126 ++ .../WorldVertexBufferUploader.java.patch | 57 + .../renderer/block/model/BakedQuad.java.patch | 49 + .../model/BakedQuadRetextured.java.patch | 40 + .../block/model/FaceBakery.java.patch | 142 ++ .../block/model/IBakedModel.java.patch | 22 + .../model/ItemCameraTransforms.java.patch | 45 + .../block/model/ItemOverrideList.java.patch | 29 + .../block/model/ItemTransformVec3f.java.patch | 17 + .../block/model/ModelBakery.java.patch | 173 ++ .../model/ModelBlockDefinition.java.patch | 17 + .../block/model/ModelManager.java.patch | 14 + .../model/ModelResourceLocation.java.patch | 14 + .../block/model/ModelRotation.java.patch | 21 + .../block/model/SimpleBakedModel.java.patch | 11 + .../renderer/block/model/Variant.java.patch | 36 + .../block/model/WeightedBakedModel.java.patch | 14 + .../block/statemap/StateMap.java.patch | 11 + .../chunk/ChunkRenderDispatcher.java.patch | 19 + .../chunk/ChunkRenderWorker.java.patch | 11 + .../renderer/chunk/RenderChunk.java.patch | 77 + .../renderer/color/BlockColors.java.patch | 45 + .../renderer/color/ItemColors.java.patch | 44 + .../entity/RenderEntityItem.java.patch | 82 + .../renderer/entity/RenderFish.java.patch | 12 + .../entity/RenderItemFrame.java.patch | 42 + .../entity/RenderLivingBase.java.patch | 71 + .../renderer/entity/RenderManager.java.patch | 28 + .../renderer/entity/RenderPlayer.java.patch | 45 + .../renderer/entity/RenderVillager.java.patch | 25 + .../entity/RenderZombieVillager.java.patch | 10 + .../entity/layers/LayerArmorBase.java.patch | 85 + .../entity/layers/LayerBipedArmor.java.patch | 20 + .../entity/layers/LayerHeldItem.java.patch | 17 + .../layers/LayerHeldItemWitch.java.patch | 11 + .../LayeredColorMaskTexture.java.patch | 12 + .../renderer/texture/Stitcher.java.patch | 53 + .../texture/TextureAtlasSprite.java.patch | 57 + .../texture/TextureManager.java.patch | 29 + .../renderer/texture/TextureMap.java.patch | 251 +++ .../renderer/texture/TextureUtil.java.patch | 46 + .../TileEntityItemStackRenderer.java.patch | 14 + .../TileEntityPistonRenderer.java.patch | 16 + .../TileEntityRendererDispatcher.java.patch | 86 + .../TileEntitySpecialRenderer.java.patch | 11 + .../renderer/vertex/VertexFormat.java.patch | 39 + .../vertex/VertexFormatElement.java.patch | 21 + .../resources/AbstractResourcePack.java.patch | 20 + .../FallbackResourceManager.java.patch | 10 + .../IResourceManagerReloadListener.java.patch | 14 + .../client/resources/Language.java.patch | 24 + .../resources/LegacyV2Adapter.java.patch | 11 + .../client/resources/Locale.java.patch | 35 + .../client/resources/ResourceIndex.java.patch | 11 + .../ResourcePackRepository.java.patch | 32 + ...SimpleReloadableResourceManager.java.patch | 43 + .../resources/SimpleResource.java.patch | 11 + .../client/settings/GameSettings.java.patch | 156 ++ .../client/settings/KeyBinding.java.patch | 182 ++ .../client/shader/Framebuffer.java.patch | 52 + .../client/shader/ShaderGroup.java.patch | 26 + .../client/shader/ShaderLoader.java.patch | 12 + .../client/shader/ShaderManager.java.patch | 20 + .../client/util/RecipeBookClient.java.patch | 19 + .../client/util/RecipeItemHelper.java.patch | 17 + .../minecraft/command/CommandBase.java.patch | 12 + .../minecraft/command/CommandFill.java.patch | 28 + .../command/CommandGameRule.java.patch | 10 + .../command/CommandHandler.java.patch | 18 + .../command/EntitySelector.java.patch | 43 + .../command/server/CommandSetBlock.java.patch | 11 + .../minecraft/crash/CrashReport.java.patch | 26 + .../crash/CrashReportCategory.java.patch | 25 + .../creativetab/CreativeTabs.java.patch | 84 + .../enchantment/Enchantment.java.patch | 49 + .../EnchantmentFrostWalker.java.patch | 14 + .../enchantment/EnchantmentHelper.java.patch | 67 + .../enchantment/EnchantmentThorns.java.patch | 38 + .../EnumEnchantmentType.java.patch | 18 + .../net/minecraft/entity/Entity.java.patch | 445 +++++ .../minecraft/entity/EntityAgeable.java.patch | 20 + .../minecraft/entity/EntityFlying.java.patch | 53 + .../minecraft/entity/EntityHanging.java.patch | 11 + .../entity/EntityLeashKnot.java.patch | 10 + .../minecraft/entity/EntityList.java.patch | 177 ++ .../minecraft/entity/EntityLiving.java.patch | 81 + .../entity/EntityLivingBase.java.patch | 540 ++++++ .../EntitySpawnPlacementRegistry.java.patch | 17 + .../minecraft/entity/EntityTracker.java.patch | 36 + .../entity/EntityTrackerEntry.java.patch | 42 + .../minecraft/entity/NpcMerchant.java.patch | 11 + .../entity/SharedMonsterAttributes.java.patch | 11 + .../entity/ai/EntityAIAttackMelee.java.patch | 54 + .../ai/EntityAIAttackRangedBow.java.patch | 11 + .../entity/ai/EntityAIBreakDoor.java.patch | 29 + .../entity/ai/EntityAIEatGrass.java.patch | 20 + .../ai/EntityAIHarvestFarmland.java.patch | 23 + .../entity/ai/EntityAIMate.java.patch | 22 + .../ai/EntityAIRunAroundLikeCrazy.java.patch | 12 + .../entity/ai/EntityAIVillagerMate.java.patch | 19 + .../entity/boss/EntityDragon.java.patch | 23 + .../entity/boss/EntityWither.java.patch | 49 + .../phase/PhaseSittingFlaming.java.patch | 11 + .../effect/EntityLightningBolt.java.patch | 12 + .../entity/item/EntityArmorStand.java.patch | 11 + .../entity/item/EntityBoat.java.patch | 78 + .../entity/item/EntityEnderPearl.java.patch | 43 + .../entity/item/EntityFallingBlock.java.patch | 30 + .../entity/item/EntityItem.java.patch | 146 ++ .../entity/item/EntityItemFrame.java.patch | 17 + .../entity/item/EntityMinecart.java.patch | 460 +++++ .../EntityMinecartCommandBlock.java.patch | 10 + .../item/EntityMinecartContainer.java.patch | 59 + .../item/EntityMinecartEmpty.java.patch | 11 + .../item/EntityMinecartFurnace.java.patch | 12 + .../item/EntityMinecartHopper.java.patch | 10 + .../item/EntityMinecartMobSpawner.java.patch | 13 + .../entity/item/EntityXPOrb.java.patch | 56 + .../monster/AbstractSkeleton.java.patch | 21 + .../entity/monster/EntityCreeper.java.patch | 11 + .../entity/monster/EntityEnderman.java.patch | 67 + .../entity/monster/EntityEvoker.java.patch | 11 + .../monster/EntityIllusionIllager.java.patch | 11 + .../entity/monster/EntityIronGolem.java.patch | 11 + .../entity/monster/EntityMagmaCube.java.patch | 10 + .../entity/monster/EntityMob.java.patch | 19 + .../entity/monster/EntityShulker.java.patch | 23 + .../monster/EntitySilverfish.java.patch | 20 + .../entity/monster/EntitySlime.java.patch | 44 + .../entity/monster/EntitySnowman.java.patch | 48 + .../entity/monster/EntitySpider.java.patch | 16 + .../entity/monster/EntityZombie.java.patch | 74 + .../monster/EntityZombieVillager.java.patch | 89 + .../entity/passive/AbstractHorse.java.patch | 31 + .../entity/passive/EntityHorse.java.patch | 81 + .../entity/passive/EntityLlama.java.patch | 12 + .../entity/passive/EntityMooshroom.java.patch | 53 + .../entity/passive/EntityOcelot.java.patch | 21 + .../entity/passive/EntityParrot.java.patch | 130 ++ .../entity/passive/EntityRabbit.java.patch | 11 + .../entity/passive/EntitySheep.java.patch | 47 + .../entity/passive/EntityVillager.java.patch | 228 +++ .../entity/passive/EntityWolf.java.patch | 11 + .../entity/passive/HorseArmorType.java.patch | 47 + .../entity/player/EntityPlayer.java.patch | 648 +++++++ .../entity/player/EntityPlayerMP.java.patch | 143 ++ .../entity/player/InventoryPlayer.java.patch | 35 + .../entity/projectile/EntityArrow.java.patch | 11 + .../projectile/EntityFireball.java.patch | 12 + .../projectile/EntityFishHook.java.patch | 77 + .../projectile/EntityLargeFireball.java.patch | 11 + .../projectile/EntityLlamaSpit.java.patch | 11 + .../projectile/EntityShulkerBullet.java.patch | 12 + .../projectile/EntitySmallFireball.java.patch | 11 + .../projectile/EntityThrowable.java.patch | 11 + .../projectile/EntityWitherSkull.java.patch | 21 + .../net/minecraft/init/Bootstrap.java.patch | 28 + .../minecraft/inventory/Container.java.patch | 44 + .../inventory/ContainerBeacon.java.patch | 25 + .../ContainerBrewingStand.java.patch | 29 + .../inventory/ContainerEnchantment.java.patch | 95 ++ .../inventory/ContainerPlayer.java.patch | 11 + .../inventory/ContainerRepair.java.patch | 113 ++ .../net/minecraft/inventory/Slot.java.patch | 79 + .../inventory/SlotCrafting.java.patch | 20 + .../inventory/SlotFurnaceOutput.java.patch | 9 + .../net/minecraft/item/EnumRarity.java.patch | 26 + .../net/minecraft/item/Item.java.patch | 838 +++++++++ .../net/minecraft/item/ItemArmor.java.patch | 70 + .../net/minecraft/item/ItemArrow.java.patch | 12 + .../net/minecraft/item/ItemAxe.java.patch | 15 + .../net/minecraft/item/ItemBed.java.patch | 11 + .../net/minecraft/item/ItemBlock.java.patch | 82 + .../item/ItemBlockSpecial.java.patch | 39 + .../net/minecraft/item/ItemBow.java.patch | 53 + .../net/minecraft/item/ItemBucket.java.patch | 26 + .../minecraft/item/ItemBucketMilk.java.patch | 32 + .../net/minecraft/item/ItemDoor.java.patch | 11 + .../net/minecraft/item/ItemDye.java.patch | 60 + .../item/ItemFlintAndSteel.java.patch | 11 + .../net/minecraft/item/ItemHoe.java.patch | 16 + .../net/minecraft/item/ItemLilyPad.java.patch | 17 + .../net/minecraft/item/ItemMap.java.patch | 44 + .../minecraft/item/ItemMinecart.java.patch | 29 + .../item/ItemMonsterPlacer.java.patch | 10 + .../minecraft/item/ItemRedstone.java.patch | 13 + .../minecraft/item/ItemSeedFood.java.patch | 42 + .../net/minecraft/item/ItemSeeds.java.patch | 42 + .../net/minecraft/item/ItemShears.java.patch | 74 + .../net/minecraft/item/ItemSkull.java.patch | 20 + .../net/minecraft/item/ItemSlab.java.patch | 28 + .../net/minecraft/item/ItemSnow.java.patch | 26 + .../net/minecraft/item/ItemStack.java.patch | 402 +++++ .../net/minecraft/item/ItemSword.java.patch | 13 + .../net/minecraft/item/ItemTool.java.patch | 62 + .../item/crafting/CraftingManager.java.patch | 40 + .../item/crafting/FurnaceRecipes.java.patch | 20 + .../item/crafting/IRecipe.java.patch | 42 + .../item/crafting/Ingredient.java.patch | 102 ++ .../crafting/RecipeBookCloning.java.patch | 24 + .../item/crafting/RecipeFireworks.java.patch | 66 + .../item/crafting/RecipeRepairItem.java.patch | 85 + .../crafting/RecipeTippedArrow.java.patch | 24 + .../item/crafting/RecipesArmorDyes.java.patch | 58 + .../item/crafting/RecipesBanners.java.patch | 91 + .../crafting/RecipesMapCloning.java.patch | 35 + .../item/crafting/ShapedRecipes.java.patch | 81 + .../item/crafting/ShapelessRecipes.java.patch | 100 ++ .../item/crafting/ShieldRecipes.java.patch | 23 + .../crafting/ShulkerBoxRecipes.java.patch | 48 + .../nbt/CompressedStreamTools.java.patch | 50 + .../minecraft/nbt/NBTSizeTracker.java.patch | 35 + .../minecraft/nbt/NBTTagCompound.java.patch | 26 + .../net/minecraft/nbt/NBTTagList.java.patch | 17 + .../net/minecraft/nbt/NBTTagString.java.patch | 11 + .../network/NetHandlerPlayServer.java.patch | 115 ++ .../network/NettyPacketEncoder.java.patch | 11 + .../network/NetworkManager.java.patch | 58 + .../network/NetworkSystem.java.patch | 93 + .../minecraft/network/PacketBuffer.java.patch | 20 + .../network/ServerStatusResponse.java.patch | 90 + .../datasync/DataSerializers.java.patch | 24 + .../datasync/EntityDataManager.java.patch | 18 + .../handshake/client/C00Handshake.java.patch | 48 + .../server/SPacketLoginSuccess.java.patch | 11 + .../play/client/CPacketClickWindow.java.patch | 11 + .../CPacketCreativeInventoryAction.java.patch | 11 + .../client/CPacketCustomPayload.java.patch | 14 + .../server/SPacketCustomPayload.java.patch | 21 + .../play/server/SPacketSpawnMob.java.patch | 11 + .../FlyingNodeProcessor.java.patch | 29 + .../PathNavigateClimber.java.patch | 12 + .../pathfinding/WalkNodeProcessor.java.patch | 68 + .../net/minecraft/potion/Potion.java.patch | 141 ++ .../minecraft/potion/PotionEffect.java.patch | 146 ++ .../minecraft/potion/PotionHelper.java.patch | 67 + .../minecraft/potion/PotionType.java.patch | 15 + .../minecraft/profiler/Profiler.java.patch | 18 + .../minecraft/realms/RealmsConnect.java.patch | 19 + .../server/MinecraftServer.java.patch | 317 ++++ .../dedicated/DedicatedServer.java.patch | 77 + .../dedicated/ServerHangWatchdog.java.patch | 11 + .../server/gui/MinecraftServerGui.java.patch | 22 + .../integrated/IntegratedServer.java.patch | 75 + .../management/PlayerChunkMapEntry.java.patch | 147 ++ .../PlayerInteractionManager.java.patch | 263 +++ .../server/management/PlayerList.java.patch | 259 +++ .../network/NetHandlerHandshakeTCP.java.patch | 11 + .../network/NetHandlerLoginServer.java.patch | 29 + .../net/minecraft/stats/RecipeBook.java.patch | 19 + .../stats/RecipeBookServer.java.patch | 23 + .../net/minecraft/stats/StatList.java.patch | 135 ++ .../stats/StatisticsManagerServer.java.patch | 12 + .../tileentity/MobSpawnerBaseLogic.java.patch | 26 + .../tileentity/TileEntity.java.patch | 254 +++ .../tileentity/TileEntityBeacon.java.patch | 50 + .../TileEntityBrewingStand.java.patch | 85 + .../tileentity/TileEntityChest.java.patch | 46 + .../tileentity/TileEntityFurnace.java.patch | 94 + .../tileentity/TileEntityHopper.java.patch | 62 + .../tileentity/TileEntityLockable.java.patch | 27 + .../TileEntityLockableLoot.java.patch | 11 + .../tileentity/TileEntityNote.java.patch | 12 + .../tileentity/TileEntityPiston.java.patch | 11 + .../TileEntityShulkerBox.java.patch | 11 + .../tileentity/TileEntitySign.java.patch | 11 + .../minecraft/util/ActionResult.java.patch | 12 + .../util/BlockRenderLayer.java.patch | 12 + .../util/ChatAllowedCharacters.java.patch | 10 + .../util/ClassInheritanceMultiMap.java.patch | 12 + .../net/minecraft/util/EnumFacing.java.patch | 71 + .../util/IntIdentityHashBiMap.java.patch | 10 + .../net/minecraft/util/MouseHelper.java.patch | 10 + .../util/ScreenShotHelper.java.patch | 17 + .../util/ServerRecipeBookHelper.java.patch | 28 + .../net/minecraft/util/Session.java.patch | 54 + .../net/minecraft/util/SoundEvent.java.patch | 13 + .../minecraft/util/TabCompleter.java.patch | 37 + .../util/datafix/DataFixesManager.java.patch | 10 + .../minecraft/util/math/ChunkPos.java.patch | 17 + .../util/math/RayTraceResult.java.patch | 15 + .../net/minecraft/util/math/Vec2f.java.patch | 12 + .../net/minecraft/util/math/Vec3d.java.patch | 44 + .../util/text/ITextComponent.java.patch | 11 + .../net/minecraft/util/text/Style.java.patch | 29 + .../util/text/TextComponentBase.java.patch | 11 + .../text/translation/LanguageMap.java.patch | 51 + .../net/minecraft/village/Village.java.patch | 187 ++ .../village/VillageCollection.java.patch | 10 + .../minecraft/village/VillageSiege.java.patch | 10 + .../net/minecraft/world/BossInfo.java.patch | 27 + .../minecraft/world/BossInfoServer.java.patch | 27 + .../net/minecraft/world/ChunkCache.java.patch | 72 + .../minecraft/world/DimensionType.java.patch | 37 + .../net/minecraft/world/Explosion.java.patch | 54 + .../minecraft/world/IBlockAccess.java.patch | 17 + .../world/ServerWorldEventHandler.java.patch | 56 + .../net/minecraft/world/Teleporter.java.patch | 24 + .../net/minecraft/world/World.java.patch | 1479 ++++++++++++++++ .../world/WorldEntitySpawner.java.patch | 101 ++ .../minecraft/world/WorldProvider.java.patch | 391 +++++ .../world/WorldProviderEnd.java.patch | 39 + .../world/WorldProviderSurface.java.patch | 10 + .../minecraft/world/WorldServer.java.patch | 339 ++++ .../world/WorldServerMulti.java.patch | 63 + .../net/minecraft/world/WorldType.java.patch | 133 ++ .../minecraft/world/biome/Biome.java.patch | 168 ++ .../world/biome/BiomeDecorator.java.patch | 227 +++ .../world/biome/BiomeDesert.java.patch | 19 + .../world/biome/BiomeForest.java.patch | 48 + .../world/biome/BiomeHills.java.patch | 55 + .../world/biome/BiomeJungle.java.patch | 19 + .../world/biome/BiomeMesa.java.patch | 26 + .../world/biome/BiomePlains.java.patch | 39 + .../world/biome/BiomeProvider.java.patch | 33 + .../world/biome/BiomeSavanna.java.patch | 10 + .../world/biome/BiomeSnow.java.patch | 11 + .../world/biome/BiomeSwamp.java.patch | 34 + .../world/biome/BiomeTaiga.java.patch | 19 + .../world/border/WorldBorder.java.patch | 11 + .../chunk/BlockStateContainer.java.patch | 38 + .../minecraft/world/chunk/Chunk.java.patch | 464 +++++ .../chunk/storage/AnvilChunkLoader.java.patch | 217 +++ .../chunk/storage/AnvilSaveHandler.java.patch | 20 + .../storage/ExtendedBlockStorage.java.patch | 11 + .../world/chunk/storage/RegionFile.java.patch | 107 ++ .../world/end/DragonFightManager.java.patch | 33 + .../world/gen/ChunkGeneratorEnd.java.patch | 73 + .../world/gen/ChunkGeneratorFlat.java.patch | 29 + .../world/gen/ChunkGeneratorHell.java.patch | 130 ++ .../gen/ChunkGeneratorOverworld.java.patch | 113 ++ .../world/gen/ChunkProviderServer.java.patch | 82 + .../world/gen/MapGenCaves.java.patch | 105 ++ .../world/gen/MapGenRavine.java.patch | 110 ++ .../feature/WorldGenAbstractTree.java.patch | 12 + .../feature/WorldGenBigMushroom.java.patch | 32 + .../gen/feature/WorldGenBigTree.java.patch | 51 + .../gen/feature/WorldGenBirchTree.java.patch | 53 + .../world/gen/feature/WorldGenBush.java.patch | 13 + .../gen/feature/WorldGenCanopyTree.java.patch | 69 + .../gen/feature/WorldGenDeadBush.java.patch | 11 + .../gen/feature/WorldGenDungeons.java.patch | 10 + .../gen/feature/WorldGenGlowStone1.java.patch | 11 + .../gen/feature/WorldGenGlowStone2.java.patch | 11 + .../gen/feature/WorldGenHellLava.java.patch | 11 + .../gen/feature/WorldGenHugeTrees.java.patch | 68 + .../gen/feature/WorldGenIceSpike.java.patch | 29 + .../gen/feature/WorldGenLakes.java.patch | 12 + .../gen/feature/WorldGenLiquids.java.patch | 11 + .../gen/feature/WorldGenMegaJungle.java.patch | 49 + .../feature/WorldGenMegaPineTree.java.patch | 52 + .../gen/feature/WorldGenMinable.java.patch | 13 + .../feature/WorldGenSavannaTree.java.patch | 60 + .../gen/feature/WorldGenShrub.java.patch | 34 + .../gen/feature/WorldGenSwamp.java.patch | 122 ++ .../gen/feature/WorldGenTaiga1.java.patch | 47 + .../gen/feature/WorldGenTaiga2.java.patch | 63 + .../gen/feature/WorldGenTallGrass.java.patch | 11 + .../gen/feature/WorldGenTrees.java.patch | 86 + .../gen/feature/WorldGenerator.java.patch | 12 + .../WorldGeneratorBonusChest.java.patch | 35 + .../world/gen/layer/GenLayer.java.patch | 47 + .../world/gen/layer/GenLayerBiome.java.patch | 89 + .../gen/structure/MapGenStronghold.java.patch | 30 + .../gen/structure/MapGenStructure.java.patch | 16 + .../structure/StructureComponent.java.patch | 12 + .../gen/structure/StructureStart.java.patch | 22 + .../StructureVillagePieces.java.patch | 123 ++ .../structure/template/Template.java.patch | 19 + .../world/storage/DerivedWorldInfo.java.patch | 26 + .../world/storage/MapData.java.patch | 41 + .../world/storage/MapDecoration.java.patch | 19 + .../world/storage/SaveFormatOld.java.patch | 24 + .../world/storage/SaveHandler.java.patch | 64 + .../world/storage/WorldInfo.java.patch | 100 ++ .../world/storage/WorldSavedData.java.patch | 25 + .../world/storage/loot/LootContext.java.patch | 17 + .../world/storage/loot/LootEntry.java.patch | 50 + .../storage/loot/LootEntryEmpty.java.patch | 25 + .../storage/loot/LootEntryItem.java.patch | 42 + .../storage/loot/LootEntryTable.java.patch | 27 + .../world/storage/loot/LootPool.java.patch | 97 ++ .../world/storage/loot/LootTable.java.patch | 65 + .../storage/loot/LootTableManager.java.patch | 20 + .../LootConditionManager.java.patch | 17 + .../RandomChanceWithLooting.java.patch | 14 + .../functions/LootingEnchantBonus.java.patch | 12 + 541 files changed, 32026 insertions(+) create mode 100644 module/minecraft/patches/.mappings.json create mode 100644 module/minecraft/patches/net/minecraft/advancements/AdvancementManager.java.patch create mode 100644 module/minecraft/patches/net/minecraft/advancements/AdvancementRewards.java.patch create mode 100644 module/minecraft/patches/net/minecraft/advancements/DisplayInfo.java.patch create mode 100644 module/minecraft/patches/net/minecraft/advancements/PlayerAdvancements.java.patch create mode 100644 module/minecraft/patches/net/minecraft/advancements/critereon/ItemPredicate.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/Block.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockBanner.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockBed.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockBush.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockButton.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockCactus.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockChest.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockChorusFlower.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockCocoa.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockCrops.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockDeadBush.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockDoor.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockDoublePlant.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockDragonEgg.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockDropper.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockDynamicLiquid.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockEnchantmentTable.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockEnderChest.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockFalling.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockFarmland.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockFence.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockFenceGate.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockFire.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockFlowerPot.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockGrass.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockHugeMushroom.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockIce.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockLadder.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockLeaves.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockLiquid.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockLog.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockMobSpawner.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockMushroom.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockMycelium.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockNetherWart.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockNewLeaf.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockNote.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockObserver.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockOldLeaf.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockOre.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockPane.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockPistonBase.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockPistonMoving.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockPortal.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockPotato.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockPumpkin.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockQuartz.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockRailBase.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockRailDetector.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockRailPowered.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockRedstoneComparator.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockRedstoneDiode.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockRedstoneOre.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockRedstoneTorch.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockRedstoneWire.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockReed.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockRotatedPillar.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockSapling.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockSkull.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockSlab.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockSnow.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockStairs.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockStaticLiquid.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockStem.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockTallGrass.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockTorch.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockTrapDoor.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockVine.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockWall.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/BlockWeb.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/SoundType.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/state/BlockPistonStructureHelper.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/state/BlockStateBase.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/state/BlockStateContainer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/block/state/IBlockProperties.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/ClientBrandRetriever.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/LoadingScreenRenderer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/Minecraft.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/audio/SoundHandler.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/audio/SoundManager.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/entity/AbstractClientPlayer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/entity/EntityOtherPlayerMP.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/entity/EntityPlayerSP.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/gui/FontRenderer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/gui/GuiBossOverlay.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/gui/GuiButton.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/gui/GuiControls.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/gui/GuiCreateWorld.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/gui/GuiEnchantment.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/gui/GuiGameOver.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/gui/GuiIngame.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/gui/GuiIngameMenu.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/gui/GuiKeyBindingList.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/gui/GuiLanguage.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/gui/GuiListWorldSelectionEntry.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/gui/GuiMainMenu.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/gui/GuiMultiplayer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/gui/GuiOptions.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/gui/GuiOverlayDebug.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/gui/GuiScreen.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/gui/GuiScreenBook.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/gui/GuiScreenDemo.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/gui/GuiSleepMP.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/gui/GuiSlot.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/gui/GuiSpectator.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/gui/GuiTextField.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/gui/GuiUtilRenderComponents.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/gui/GuiVideoSettings.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/gui/MapItemRenderer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/gui/ScaledResolution.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/gui/ServerListEntryNormal.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/gui/advancements/GuiAdvancementTab.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/gui/advancements/GuiScreenAdvancements.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/gui/inventory/GuiContainer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/gui/inventory/GuiContainerCreative.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/gui/recipebook/GuiRecipeBook.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/gui/recipebook/GuiRecipeOverlay.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/gui/toasts/RecipeToast.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/model/ModelBase.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/model/ModelBox.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/model/ModelRenderer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/model/ModelSkeleton.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/model/PositionTextureVertex.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/model/TexturedQuad.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/multiplayer/ChunkProviderClient.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/multiplayer/GuiConnecting.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/multiplayer/PlayerControllerMP.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/multiplayer/WorldClient.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/network/NetHandlerHandshakeMemory.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/network/NetHandlerLoginClient.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/network/NetHandlerPlayClient.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/network/ServerPinger.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/particle/Particle.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/particle/ParticleItemPickup.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/particle/ParticleManager.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/ActiveRenderInfo.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/BlockFluidRenderer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/BlockModelRenderer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/BlockModelShapes.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/BlockRendererDispatcher.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/BufferBuilder.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/ChestRenderer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/EntityRenderer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/InventoryEffectRenderer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/ItemModelMesher.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/ItemRenderer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/OpenGlHelper.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/RenderGlobal.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/RenderItem.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/WorldVertexBufferUploader.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/block/model/BakedQuad.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/block/model/BakedQuadRetextured.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/block/model/FaceBakery.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/block/model/IBakedModel.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/block/model/ItemCameraTransforms.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/block/model/ItemOverrideList.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/block/model/ItemTransformVec3f.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/block/model/ModelBakery.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/block/model/ModelBlockDefinition.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/block/model/ModelManager.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/block/model/ModelResourceLocation.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/block/model/ModelRotation.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/block/model/SimpleBakedModel.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/block/model/Variant.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/block/model/WeightedBakedModel.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/block/statemap/StateMap.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/chunk/ChunkRenderDispatcher.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/chunk/ChunkRenderWorker.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/chunk/RenderChunk.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/color/BlockColors.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/color/ItemColors.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/entity/RenderEntityItem.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/entity/RenderFish.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/entity/RenderItemFrame.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/entity/RenderLivingBase.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/entity/RenderManager.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/entity/RenderPlayer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/entity/RenderVillager.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/entity/RenderZombieVillager.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/entity/layers/LayerArmorBase.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/entity/layers/LayerBipedArmor.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/entity/layers/LayerHeldItem.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/entity/layers/LayerHeldItemWitch.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/texture/LayeredColorMaskTexture.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/texture/Stitcher.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/texture/TextureAtlasSprite.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/texture/TextureManager.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/texture/TextureMap.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/texture/TextureUtil.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/tileentity/TileEntityItemStackRenderer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/tileentity/TileEntityPistonRenderer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/tileentity/TileEntityRendererDispatcher.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/tileentity/TileEntitySpecialRenderer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/vertex/VertexFormat.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/vertex/VertexFormatElement.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/resources/AbstractResourcePack.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/resources/FallbackResourceManager.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/resources/IResourceManagerReloadListener.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/resources/Language.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/resources/LegacyV2Adapter.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/resources/Locale.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/resources/ResourceIndex.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/resources/ResourcePackRepository.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/resources/SimpleReloadableResourceManager.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/resources/SimpleResource.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/settings/GameSettings.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/settings/KeyBinding.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/shader/Framebuffer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/shader/ShaderGroup.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/shader/ShaderLoader.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/shader/ShaderManager.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/util/RecipeBookClient.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/util/RecipeItemHelper.java.patch create mode 100644 module/minecraft/patches/net/minecraft/command/CommandBase.java.patch create mode 100644 module/minecraft/patches/net/minecraft/command/CommandFill.java.patch create mode 100644 module/minecraft/patches/net/minecraft/command/CommandGameRule.java.patch create mode 100644 module/minecraft/patches/net/minecraft/command/CommandHandler.java.patch create mode 100644 module/minecraft/patches/net/minecraft/command/EntitySelector.java.patch create mode 100644 module/minecraft/patches/net/minecraft/command/server/CommandSetBlock.java.patch create mode 100644 module/minecraft/patches/net/minecraft/crash/CrashReport.java.patch create mode 100644 module/minecraft/patches/net/minecraft/crash/CrashReportCategory.java.patch create mode 100644 module/minecraft/patches/net/minecraft/creativetab/CreativeTabs.java.patch create mode 100644 module/minecraft/patches/net/minecraft/enchantment/Enchantment.java.patch create mode 100644 module/minecraft/patches/net/minecraft/enchantment/EnchantmentFrostWalker.java.patch create mode 100644 module/minecraft/patches/net/minecraft/enchantment/EnchantmentHelper.java.patch create mode 100644 module/minecraft/patches/net/minecraft/enchantment/EnchantmentThorns.java.patch create mode 100644 module/minecraft/patches/net/minecraft/enchantment/EnumEnchantmentType.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/Entity.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/EntityAgeable.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/EntityFlying.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/EntityHanging.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/EntityLeashKnot.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/EntityList.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/EntityLiving.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/EntityLivingBase.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/EntitySpawnPlacementRegistry.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/EntityTracker.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/EntityTrackerEntry.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/NpcMerchant.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/SharedMonsterAttributes.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/ai/EntityAIAttackMelee.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/ai/EntityAIAttackRangedBow.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/ai/EntityAIBreakDoor.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/ai/EntityAIEatGrass.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/ai/EntityAIHarvestFarmland.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/ai/EntityAIMate.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/ai/EntityAIRunAroundLikeCrazy.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/ai/EntityAIVillagerMate.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/boss/EntityDragon.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/boss/EntityWither.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/boss/dragon/phase/PhaseSittingFlaming.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/effect/EntityLightningBolt.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/item/EntityArmorStand.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/item/EntityBoat.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/item/EntityEnderPearl.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/item/EntityFallingBlock.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/item/EntityItem.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/item/EntityItemFrame.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/item/EntityMinecart.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/item/EntityMinecartCommandBlock.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/item/EntityMinecartContainer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/item/EntityMinecartEmpty.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/item/EntityMinecartFurnace.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/item/EntityMinecartHopper.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/item/EntityMinecartMobSpawner.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/item/EntityXPOrb.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/monster/AbstractSkeleton.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/monster/EntityCreeper.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/monster/EntityEnderman.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/monster/EntityEvoker.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/monster/EntityIllusionIllager.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/monster/EntityIronGolem.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/monster/EntityMagmaCube.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/monster/EntityMob.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/monster/EntityShulker.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/monster/EntitySilverfish.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/monster/EntitySlime.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/monster/EntitySnowman.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/monster/EntitySpider.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/monster/EntityZombie.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/monster/EntityZombieVillager.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/passive/AbstractHorse.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/passive/EntityHorse.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/passive/EntityLlama.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/passive/EntityMooshroom.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/passive/EntityOcelot.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/passive/EntityParrot.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/passive/EntityRabbit.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/passive/EntitySheep.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/passive/EntityVillager.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/passive/EntityWolf.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/passive/HorseArmorType.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/player/EntityPlayer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/player/EntityPlayerMP.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/player/InventoryPlayer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/projectile/EntityArrow.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/projectile/EntityFireball.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/projectile/EntityFishHook.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/projectile/EntityLargeFireball.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/projectile/EntityLlamaSpit.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/projectile/EntityShulkerBullet.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/projectile/EntitySmallFireball.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/projectile/EntityThrowable.java.patch create mode 100644 module/minecraft/patches/net/minecraft/entity/projectile/EntityWitherSkull.java.patch create mode 100644 module/minecraft/patches/net/minecraft/init/Bootstrap.java.patch create mode 100644 module/minecraft/patches/net/minecraft/inventory/Container.java.patch create mode 100644 module/minecraft/patches/net/minecraft/inventory/ContainerBeacon.java.patch create mode 100644 module/minecraft/patches/net/minecraft/inventory/ContainerBrewingStand.java.patch create mode 100644 module/minecraft/patches/net/minecraft/inventory/ContainerEnchantment.java.patch create mode 100644 module/minecraft/patches/net/minecraft/inventory/ContainerPlayer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/inventory/ContainerRepair.java.patch create mode 100644 module/minecraft/patches/net/minecraft/inventory/Slot.java.patch create mode 100644 module/minecraft/patches/net/minecraft/inventory/SlotCrafting.java.patch create mode 100644 module/minecraft/patches/net/minecraft/inventory/SlotFurnaceOutput.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/EnumRarity.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/Item.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/ItemArmor.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/ItemArrow.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/ItemAxe.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/ItemBed.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/ItemBlock.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/ItemBlockSpecial.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/ItemBow.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/ItemBucket.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/ItemBucketMilk.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/ItemDoor.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/ItemDye.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/ItemFlintAndSteel.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/ItemHoe.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/ItemLilyPad.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/ItemMap.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/ItemMinecart.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/ItemMonsterPlacer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/ItemRedstone.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/ItemSeedFood.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/ItemSeeds.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/ItemShears.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/ItemSkull.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/ItemSlab.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/ItemSnow.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/ItemStack.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/ItemSword.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/ItemTool.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/crafting/CraftingManager.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/crafting/FurnaceRecipes.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/crafting/IRecipe.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/crafting/Ingredient.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/crafting/RecipeBookCloning.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/crafting/RecipeFireworks.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/crafting/RecipeRepairItem.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/crafting/RecipeTippedArrow.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/crafting/RecipesArmorDyes.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/crafting/RecipesBanners.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/crafting/RecipesMapCloning.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/crafting/ShapedRecipes.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/crafting/ShapelessRecipes.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/crafting/ShieldRecipes.java.patch create mode 100644 module/minecraft/patches/net/minecraft/item/crafting/ShulkerBoxRecipes.java.patch create mode 100644 module/minecraft/patches/net/minecraft/nbt/CompressedStreamTools.java.patch create mode 100644 module/minecraft/patches/net/minecraft/nbt/NBTSizeTracker.java.patch create mode 100644 module/minecraft/patches/net/minecraft/nbt/NBTTagCompound.java.patch create mode 100644 module/minecraft/patches/net/minecraft/nbt/NBTTagList.java.patch create mode 100644 module/minecraft/patches/net/minecraft/nbt/NBTTagString.java.patch create mode 100644 module/minecraft/patches/net/minecraft/network/NetHandlerPlayServer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/network/NettyPacketEncoder.java.patch create mode 100644 module/minecraft/patches/net/minecraft/network/NetworkManager.java.patch create mode 100644 module/minecraft/patches/net/minecraft/network/NetworkSystem.java.patch create mode 100644 module/minecraft/patches/net/minecraft/network/PacketBuffer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/network/ServerStatusResponse.java.patch create mode 100644 module/minecraft/patches/net/minecraft/network/datasync/DataSerializers.java.patch create mode 100644 module/minecraft/patches/net/minecraft/network/datasync/EntityDataManager.java.patch create mode 100644 module/minecraft/patches/net/minecraft/network/handshake/client/C00Handshake.java.patch create mode 100644 module/minecraft/patches/net/minecraft/network/login/server/SPacketLoginSuccess.java.patch create mode 100644 module/minecraft/patches/net/minecraft/network/play/client/CPacketClickWindow.java.patch create mode 100644 module/minecraft/patches/net/minecraft/network/play/client/CPacketCreativeInventoryAction.java.patch create mode 100644 module/minecraft/patches/net/minecraft/network/play/client/CPacketCustomPayload.java.patch create mode 100644 module/minecraft/patches/net/minecraft/network/play/server/SPacketCustomPayload.java.patch create mode 100644 module/minecraft/patches/net/minecraft/network/play/server/SPacketSpawnMob.java.patch create mode 100644 module/minecraft/patches/net/minecraft/pathfinding/FlyingNodeProcessor.java.patch create mode 100644 module/minecraft/patches/net/minecraft/pathfinding/PathNavigateClimber.java.patch create mode 100644 module/minecraft/patches/net/minecraft/pathfinding/WalkNodeProcessor.java.patch create mode 100644 module/minecraft/patches/net/minecraft/potion/Potion.java.patch create mode 100644 module/minecraft/patches/net/minecraft/potion/PotionEffect.java.patch create mode 100644 module/minecraft/patches/net/minecraft/potion/PotionHelper.java.patch create mode 100644 module/minecraft/patches/net/minecraft/potion/PotionType.java.patch create mode 100644 module/minecraft/patches/net/minecraft/profiler/Profiler.java.patch create mode 100644 module/minecraft/patches/net/minecraft/realms/RealmsConnect.java.patch create mode 100644 module/minecraft/patches/net/minecraft/server/MinecraftServer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/server/dedicated/DedicatedServer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/server/dedicated/ServerHangWatchdog.java.patch create mode 100644 module/minecraft/patches/net/minecraft/server/gui/MinecraftServerGui.java.patch create mode 100644 module/minecraft/patches/net/minecraft/server/integrated/IntegratedServer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/server/management/PlayerChunkMapEntry.java.patch create mode 100644 module/minecraft/patches/net/minecraft/server/management/PlayerInteractionManager.java.patch create mode 100644 module/minecraft/patches/net/minecraft/server/management/PlayerList.java.patch create mode 100644 module/minecraft/patches/net/minecraft/server/network/NetHandlerHandshakeTCP.java.patch create mode 100644 module/minecraft/patches/net/minecraft/server/network/NetHandlerLoginServer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/stats/RecipeBook.java.patch create mode 100644 module/minecraft/patches/net/minecraft/stats/RecipeBookServer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/stats/StatList.java.patch create mode 100644 module/minecraft/patches/net/minecraft/stats/StatisticsManagerServer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/tileentity/MobSpawnerBaseLogic.java.patch create mode 100644 module/minecraft/patches/net/minecraft/tileentity/TileEntity.java.patch create mode 100644 module/minecraft/patches/net/minecraft/tileentity/TileEntityBeacon.java.patch create mode 100644 module/minecraft/patches/net/minecraft/tileentity/TileEntityBrewingStand.java.patch create mode 100644 module/minecraft/patches/net/minecraft/tileentity/TileEntityChest.java.patch create mode 100644 module/minecraft/patches/net/minecraft/tileentity/TileEntityFurnace.java.patch create mode 100644 module/minecraft/patches/net/minecraft/tileentity/TileEntityHopper.java.patch create mode 100644 module/minecraft/patches/net/minecraft/tileentity/TileEntityLockable.java.patch create mode 100644 module/minecraft/patches/net/minecraft/tileentity/TileEntityLockableLoot.java.patch create mode 100644 module/minecraft/patches/net/minecraft/tileentity/TileEntityNote.java.patch create mode 100644 module/minecraft/patches/net/minecraft/tileentity/TileEntityPiston.java.patch create mode 100644 module/minecraft/patches/net/minecraft/tileentity/TileEntityShulkerBox.java.patch create mode 100644 module/minecraft/patches/net/minecraft/tileentity/TileEntitySign.java.patch create mode 100644 module/minecraft/patches/net/minecraft/util/ActionResult.java.patch create mode 100644 module/minecraft/patches/net/minecraft/util/BlockRenderLayer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/util/ChatAllowedCharacters.java.patch create mode 100644 module/minecraft/patches/net/minecraft/util/ClassInheritanceMultiMap.java.patch create mode 100644 module/minecraft/patches/net/minecraft/util/EnumFacing.java.patch create mode 100644 module/minecraft/patches/net/minecraft/util/IntIdentityHashBiMap.java.patch create mode 100644 module/minecraft/patches/net/minecraft/util/MouseHelper.java.patch create mode 100644 module/minecraft/patches/net/minecraft/util/ScreenShotHelper.java.patch create mode 100644 module/minecraft/patches/net/minecraft/util/ServerRecipeBookHelper.java.patch create mode 100644 module/minecraft/patches/net/minecraft/util/Session.java.patch create mode 100644 module/minecraft/patches/net/minecraft/util/SoundEvent.java.patch create mode 100644 module/minecraft/patches/net/minecraft/util/TabCompleter.java.patch create mode 100644 module/minecraft/patches/net/minecraft/util/datafix/DataFixesManager.java.patch create mode 100644 module/minecraft/patches/net/minecraft/util/math/ChunkPos.java.patch create mode 100644 module/minecraft/patches/net/minecraft/util/math/RayTraceResult.java.patch create mode 100644 module/minecraft/patches/net/minecraft/util/math/Vec2f.java.patch create mode 100644 module/minecraft/patches/net/minecraft/util/math/Vec3d.java.patch create mode 100644 module/minecraft/patches/net/minecraft/util/text/ITextComponent.java.patch create mode 100644 module/minecraft/patches/net/minecraft/util/text/Style.java.patch create mode 100644 module/minecraft/patches/net/minecraft/util/text/TextComponentBase.java.patch create mode 100644 module/minecraft/patches/net/minecraft/util/text/translation/LanguageMap.java.patch create mode 100644 module/minecraft/patches/net/minecraft/village/Village.java.patch create mode 100644 module/minecraft/patches/net/minecraft/village/VillageCollection.java.patch create mode 100644 module/minecraft/patches/net/minecraft/village/VillageSiege.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/BossInfo.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/BossInfoServer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/ChunkCache.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/DimensionType.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/Explosion.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/IBlockAccess.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/ServerWorldEventHandler.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/Teleporter.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/World.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/WorldEntitySpawner.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/WorldProvider.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/WorldProviderEnd.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/WorldProviderSurface.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/WorldServer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/WorldServerMulti.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/WorldType.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/biome/Biome.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/biome/BiomeDecorator.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/biome/BiomeDesert.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/biome/BiomeForest.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/biome/BiomeHills.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/biome/BiomeJungle.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/biome/BiomeMesa.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/biome/BiomePlains.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/biome/BiomeProvider.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/biome/BiomeSavanna.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/biome/BiomeSnow.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/biome/BiomeSwamp.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/biome/BiomeTaiga.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/border/WorldBorder.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/chunk/BlockStateContainer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/chunk/Chunk.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/chunk/storage/AnvilChunkLoader.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/chunk/storage/AnvilSaveHandler.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/chunk/storage/ExtendedBlockStorage.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/chunk/storage/RegionFile.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/end/DragonFightManager.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/ChunkGeneratorEnd.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/ChunkGeneratorFlat.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/ChunkGeneratorHell.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/ChunkGeneratorOverworld.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/ChunkProviderServer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/MapGenCaves.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/MapGenRavine.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenAbstractTree.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenBigMushroom.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenBigTree.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenBirchTree.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenBush.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenCanopyTree.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenDeadBush.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenDungeons.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenGlowStone1.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenGlowStone2.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenHellLava.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenHugeTrees.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenIceSpike.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenLakes.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenLiquids.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenMegaJungle.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenMegaPineTree.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenMinable.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenSavannaTree.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenShrub.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenSwamp.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenTaiga1.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenTaiga2.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenTallGrass.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenTrees.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenerator.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/feature/WorldGeneratorBonusChest.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/layer/GenLayer.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/layer/GenLayerBiome.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/structure/MapGenStronghold.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/structure/MapGenStructure.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/structure/StructureComponent.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/structure/StructureStart.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/structure/StructureVillagePieces.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/gen/structure/template/Template.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/storage/DerivedWorldInfo.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/storage/MapData.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/storage/MapDecoration.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/storage/SaveFormatOld.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/storage/SaveHandler.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/storage/WorldInfo.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/storage/WorldSavedData.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/storage/loot/LootContext.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/storage/loot/LootEntry.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/storage/loot/LootEntryEmpty.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/storage/loot/LootEntryItem.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/storage/loot/LootEntryTable.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/storage/loot/LootPool.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/storage/loot/LootTable.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/storage/loot/LootTableManager.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/storage/loot/conditions/LootConditionManager.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/storage/loot/conditions/RandomChanceWithLooting.java.patch create mode 100644 module/minecraft/patches/net/minecraft/world/storage/loot/functions/LootingEnchantBonus.java.patch diff --git a/module/minecraft/patches/.mappings.json b/module/minecraft/patches/.mappings.json new file mode 100644 index 000000000..399a75fa1 --- /dev/null +++ b/module/minecraft/patches/.mappings.json @@ -0,0 +1,4 @@ +{ + "names": "mcp:stable_39-1.12", + "mcpConfig": "1.12.2-20201025.185735" +} \ No newline at end of file diff --git a/module/minecraft/patches/net/minecraft/advancements/AdvancementManager.java.patch b/module/minecraft/patches/net/minecraft/advancements/AdvancementManager.java.patch new file mode 100644 index 000000000..ea8c64625 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/advancements/AdvancementManager.java.patch @@ -0,0 +1,10 @@ +--- original/net/minecraft/advancements/AdvancementManager.java ++++ modified/net/minecraft/advancements/AdvancementManager.java +@@ -69,6 +69,7 @@ + ADVANCEMENT_LIST.clear(); + Map map = this.loadCustomAdvancements(); + this.loadBuiltInAdvancements(map); ++ this.hasErrored |= net.minecraftforge.common.ForgeHooks.loadAdvancements(map); + ADVANCEMENT_LIST.loadAdvancements(map); + + for (Advancement advancement : ADVANCEMENT_LIST.getRoots()) { diff --git a/module/minecraft/patches/net/minecraft/advancements/AdvancementRewards.java.patch b/module/minecraft/patches/net/minecraft/advancements/AdvancementRewards.java.patch new file mode 100644 index 000000000..2a691fe04 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/advancements/AdvancementRewards.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/advancements/AdvancementRewards.java ++++ modified/net/minecraft/advancements/AdvancementRewards.java +@@ -47,7 +47,7 @@ + + public void apply(final EntityPlayerMP player) { + player.addExperience(this.experience); +- LootContext lootcontext = new LootContext.Builder(player.getServerWorld()).withLootedEntity(player).build(); ++ LootContext lootcontext = new LootContext.Builder(player.getServerWorld()).withLootedEntity(player).withPlayer(player).withLuck(player.getLuck()).build(); // Forge: add player & luck to LootContext + boolean flag = false; + + for (ResourceLocation resourcelocation : this.loot) { diff --git a/module/minecraft/patches/net/minecraft/advancements/DisplayInfo.java.patch b/module/minecraft/patches/net/minecraft/advancements/DisplayInfo.java.patch new file mode 100644 index 000000000..2a387669a --- /dev/null +++ b/module/minecraft/patches/net/minecraft/advancements/DisplayInfo.java.patch @@ -0,0 +1,13 @@ +--- original/net/minecraft/advancements/DisplayInfo.java ++++ modified/net/minecraft/advancements/DisplayInfo.java +@@ -120,7 +120,9 @@ + + Item item = JsonUtils.getItem(object, "item"); + int i = JsonUtils.getInt(object, "data", 0); +- return new ItemStack(item, 1, i); ++ ItemStack ret = new ItemStack(item, 1, i); ++ ret.setTagCompound(net.minecraftforge.common.util.JsonUtils.readNBT(object, "nbt")); ++ return ret; + } + + public void write(PacketBuffer buf) { diff --git a/module/minecraft/patches/net/minecraft/advancements/PlayerAdvancements.java.patch b/module/minecraft/patches/net/minecraft/advancements/PlayerAdvancements.java.patch new file mode 100644 index 000000000..746a8b8b4 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/advancements/PlayerAdvancements.java.patch @@ -0,0 +1,21 @@ +--- original/net/minecraft/advancements/PlayerAdvancements.java ++++ modified/net/minecraft/advancements/PlayerAdvancements.java +@@ -161,6 +161,9 @@ + } + + public boolean grantCriterion(Advancement p_192750_1_, String p_192750_2_) { ++ // Forge: don't grant advancements for fake players ++ if (this.player instanceof net.minecraftforge.common.util.FakePlayer) return false; ++ + boolean flag = false; + AdvancementProgress advancementprogress = this.getProgress(p_192750_1_); + boolean flag1 = advancementprogress.isDone(); +@@ -183,6 +186,8 @@ + ) + ); + } ++ ++ net.minecraftforge.common.ForgeHooks.onAdvancement(this.player, p_192750_1_); + } + } + diff --git a/module/minecraft/patches/net/minecraft/advancements/critereon/ItemPredicate.java.patch b/module/minecraft/patches/net/minecraft/advancements/critereon/ItemPredicate.java.patch new file mode 100644 index 000000000..7bc096321 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/advancements/critereon/ItemPredicate.java.patch @@ -0,0 +1,15 @@ +--- original/net/minecraft/advancements/critereon/ItemPredicate.java ++++ modified/net/minecraft/advancements/critereon/ItemPredicate.java +@@ -93,6 +93,12 @@ + public static ItemPredicate deserialize(@Nullable JsonElement element) { + if (element != null && !element.isJsonNull()) { + JsonObject jsonobject = JsonUtils.getJsonObject(element, "item"); ++ if (jsonobject.has("type")) { ++ final ResourceLocation rl = new ResourceLocation(JsonUtils.getString(jsonobject, "type")); ++ final Map> map = net.minecraftforge.advancements.critereon.ItemPredicates.getPredicates(); ++ if (map.containsKey(rl)) return map.get(rl).apply(jsonobject); ++ else throw new JsonSyntaxException("There is no ItemPredicate of type "+rl); ++ } + MinMaxBounds minmaxbounds = MinMaxBounds.deserialize(jsonobject.get("count")); + MinMaxBounds minmaxbounds1 = MinMaxBounds.deserialize(jsonobject.get("durability")); + Integer integer = jsonobject.has("data") ? JsonUtils.getInt(jsonobject, "data") : null; diff --git a/module/minecraft/patches/net/minecraft/block/Block.java.patch b/module/minecraft/patches/net/minecraft/block/Block.java.patch new file mode 100644 index 000000000..c2a80e3d8 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/Block.java.patch @@ -0,0 +1,1507 @@ +--- original/net/minecraft/block/Block.java ++++ modified/net/minecraft/block/Block.java +@@ -8,6 +8,7 @@ + import net.minecraft.block.material.EnumPushReaction; + import net.minecraft.block.material.MapColor; + import net.minecraft.block.material.Material; ++import net.minecraft.block.properties.IProperty; + import net.minecraft.block.state.BlockFaceShape; + import net.minecraft.block.state.BlockStateContainer; + import net.minecraft.block.state.IBlockState; +@@ -50,11 +51,11 @@ + import net.minecraftforge.fml.relauncher.Side; + import net.minecraftforge.fml.relauncher.SideOnly; + +-public class Block { +- /** ResourceLocation for the Air block */ ++public class Block extends net.minecraftforge.registries.IForgeRegistryEntry.Impl { + private static final ResourceLocation AIR_ID = new ResourceLocation("air"); +- public static final RegistryNamespacedDefaultedByKey REGISTRY = new RegistryNamespacedDefaultedByKey<>(AIR_ID); +- public static final ObjectIntIdentityMap BLOCK_STATE_IDS = new ObjectIntIdentityMap<>(); ++ public static final RegistryNamespacedDefaultedByKey REGISTRY = net.minecraftforge.registries.GameData.getWrapperDefaulted(Block.class); ++ @Deprecated //Modders: DO NOT use this! Use GameRegistry ++ public static final ObjectIntIdentityMap BLOCK_STATE_IDS = net.minecraftforge.registries.GameData.getBlockStateIDMap(); + public static final AxisAlignedBB FULL_BLOCK_AABB = new AxisAlignedBB(0.0, 0.0, 0.0, 1.0, 1.0, 1.0); + @Nullable + public static final AxisAlignedBB NULL_AABB = null; +@@ -82,7 +83,7 @@ + protected final Material material; + /** The Block's MapColor */ + protected final MapColor blockMapColor; +- /** Determines how much velocity is maintained while moving on top of this block */ ++ @Deprecated // Forge: State/world/pos/entity sensitive version below + public float slipperiness = 0.6F; + protected final BlockStateContainer blockState; + private IBlockState defaultBlockState; +@@ -359,7 +360,7 @@ + + /** Whether this Block can be replaced directly by other blocks (true for e.g. tall grass) */ + public boolean isReplaceable(IBlockAccess worldIn, BlockPos pos) { +- return false; ++ return worldIn.getBlockState(pos).getMaterial().isReplaceable(); + } + + /** Sets how many hits it takes to break a block. */ +@@ -394,8 +395,9 @@ + return this.needsRandomTick; + } + ++ @Deprecated //Forge: New State sensitive version. + public boolean hasTileEntity() { +- return this.hasTileEntity; ++ return hasTileEntity(getDefaultState()); + } + + /** @deprecated call via {@link IBlockState#getBoundingBox(IBlockAccess,BlockPos)} whenever possible. Implementing/overriding is fine. */ +@@ -408,11 +410,12 @@ + @Deprecated + @SideOnly(Side.CLIENT) + public int getPackedLightmapCoords(IBlockState state, IBlockAccess source, BlockPos pos) { +- int i = source.getCombinedLight(pos, state.getLightValue()); ++ int i = source.getCombinedLight(pos, state.getLightValue(source, pos)); ++ + if (i == 0 && state.getBlock() instanceof BlockSlab) { + pos = pos.down(); + state = source.getBlockState(pos); +- return source.getCombinedLight(pos, state.getLightValue()); ++ return source.getCombinedLight(pos, state.getLightValue(source, pos)); + } else { + return i; + } +@@ -455,7 +458,7 @@ + } + } + +- return !blockAccess.getBlockState(pos.offset(side)).isOpaqueCube(); ++ return !blockAccess.getBlockState(pos.offset(side)).doesSideBlockRendering(blockAccess, pos.offset(side), side.getOpposite()); + } + + /** +@@ -562,6 +565,9 @@ + + /** Called serverside after this block is replaced with another in Chunk, but before the Tile Entity is updated */ + public void breakBlock(World worldIn, BlockPos pos, IBlockState state) { ++ if (hasTileEntity(state) && !(this instanceof BlockContainer)) { ++ worldIn.removeTileEntity(pos); ++ } + } + + /** Returns the quantity of items to drop on block destruction. */ +@@ -580,14 +586,7 @@ + */ + @Deprecated + public float getPlayerRelativeBlockHardness(IBlockState state, EntityPlayer player, World worldIn, BlockPos pos) { +- float f = state.getBlockHardness(worldIn, pos); +- if (f < 0.0F) { +- return 0.0F; +- } else { +- return !player.canHarvestBlock(state) +- ? player.getDigSpeed(state) / f / 100.0F +- : player.getDigSpeed(state) / f / 30.0F; +- } ++ return net.minecraftforge.common.ForgeHooks.blockStrength(state, player, worldIn, pos); + } + + /** Spawn this Block's drops into the World as EntityItems */ +@@ -597,15 +596,13 @@ + + /** Spawns this Block's drops into the World as EntityItems. */ + public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, IBlockState state, float chance, int fortune) { +- if (!worldIn.isRemote) { +- int i = this.quantityDroppedWithBonus(fortune, worldIn.rand); ++ if (!worldIn.isRemote && !worldIn.restoringBlockSnapshots) { // do not drop items while restoring blockstates, prevents item dupe ++ List drops = getDrops(worldIn, pos, state, fortune); // use the old method until it gets removed, for backward compatibility ++ chance = net.minecraftforge.event.ForgeEventFactory.fireBlockHarvesting(drops, worldIn, pos, state, fortune, chance, false, harvesters.get()); + +- for (int j = 0; j < i; j++) { +- if (!(worldIn.rand.nextFloat() > chance)) { +- Item item = this.getItemDropped(state, worldIn.rand, fortune); +- if (item != Items.AIR) { +- spawnAsEntity(worldIn, pos, new ItemStack(item, 1, this.damageDropped(state))); +- } ++ for (ItemStack drop : drops) { ++ if (worldIn.rand.nextFloat() <= chance) { ++ spawnAsEntity(worldIn, pos, drop); + } + } + } +@@ -613,7 +610,11 @@ + + /** Spawns the given ItemStack as an EntityItem into the World at the given position */ + public static void spawnAsEntity(World worldIn, BlockPos pos, ItemStack stack) { +- if (!worldIn.isRemote && !stack.isEmpty() && worldIn.getGameRules().getBoolean("doTileDrops")) { ++ if (!worldIn.isRemote && !stack.isEmpty() && worldIn.getGameRules().getBoolean("doTileDrops")&& !worldIn.restoringBlockSnapshots) { // do not drop items while restoring blockstates, prevents item dupe ++ if (captureDrops.get()) { ++ capturedDrops.get().add(stack); ++ return; ++ } + float f = 0.5F; + double d0 = worldIn.rand.nextFloat() * 0.5F + 0.25; + double d1 = worldIn.rand.nextFloat() * 0.5F + 0.25; +@@ -644,7 +645,7 @@ + return 0; + } + +- /** Returns how much this block can resist explosions from the passed in entity. */ ++ @Deprecated //Forge: State sensitive version + public float getExplosionResistance(Entity exploder) { + return this.blockResistance / 5.0F; + } +@@ -690,7 +691,7 @@ + + /** Checks if this block can be placed exactly at the given position. */ + public boolean canPlaceBlockAt(World worldIn, BlockPos pos) { +- return worldIn.getBlockState(pos).getBlock().material.isReplaceable(); ++ return worldIn.getBlockState(pos).getBlock().isReplaceable(worldIn, pos); + } + + /** Called when the block is right clicked by a player. */ +@@ -712,7 +713,8 @@ + public void onEntityWalk(World worldIn, BlockPos pos, Entity entityIn) { + } + +- /** Called by ItemBlocks just before a block is actually set in the world, to allow for adjustments to the IBlockstate */ ++ // Forge: use getStateForPlacement ++ @Deprecated + public IBlockState getStateForPlacement( + World worldIn, + BlockPos pos, +@@ -764,17 +766,30 @@ + ) { + player.addStat(StatList.getBlockStats(this)); + player.addExhaustion(0.005F); +- if (this.canSilkHarvest() && EnchantmentHelper.getEnchantmentLevel(Enchantments.SILK_TOUCH, stack) > 0) { ++ ++ if (this.canSilkHarvest(worldIn, pos, state, player) && EnchantmentHelper.getEnchantmentLevel(Enchantments.SILK_TOUCH, stack) > 0) { ++ java.util.List items = new java.util.ArrayList(); + ItemStack itemstack = this.getSilkTouchDrop(state); +- spawnAsEntity(worldIn, pos, itemstack); ++ ++ if (!itemstack.isEmpty()) { ++ items.add(itemstack); ++ } ++ ++ net.minecraftforge.event.ForgeEventFactory.fireBlockHarvesting(items, worldIn, pos, state, 0, 1.0f, true, player); ++ for (ItemStack item : items) { ++ spawnAsEntity(worldIn, pos, item); ++ } + } else { ++ harvesters.set(player); + int i = EnchantmentHelper.getEnchantmentLevel(Enchantments.FORTUNE, stack); + this.dropBlockAsItem(worldIn, pos, state, i); ++ harvesters.set(null); + } + } + ++ @Deprecated //Forge: State sensitive version + protected boolean canSilkHarvest() { +- return this.getDefaultState().isFullCube() && !this.hasTileEntity; ++ return this.getDefaultState().isFullCube() && !this.hasTileEntity(silk_check_state.get()); + } + + protected ItemStack getSilkTouchDrop(IBlockState state) { +@@ -858,6 +873,7 @@ + entityIn.motionY = 0.0; + } + ++ @Deprecated // Forge: Use more sensitive version below: getPickBlock + public ItemStack getItem(World worldIn, BlockPos pos, IBlockState state) { + return new ItemStack(Item.getItemFromBlock(this), 1, this.damageDropped(state)); + } +@@ -956,6 +972,7 @@ + ); + } + ++ @Deprecated // Forge - World/state/pos/entity sensitive version below + public SoundType getSoundType() { + return this.blockSoundType; + } +@@ -969,6 +986,1256 @@ + public void addInformation(ItemStack stack, @Nullable World worldIn, List tooltip, ITooltipFlag flagIn) { + } + ++ /* ======================================== FORGE START =====================================*/ ++ //For ForgeInternal use Only! ++ protected ThreadLocal harvesters = new ThreadLocal(); ++ private ThreadLocal silk_check_state = new ThreadLocal(); ++ protected static java.util.Random RANDOM = new java.util.Random(); // Useful for random things without a seed. ++ ++ /** ++ * Gets the slipperiness at the given location at the given state. Normally ++ * between 0 and 1. ++ *

++ * Note that entities may reduce slipperiness by a certain factor of their own; ++ * for {@link net.minecraft.entity.EntityLivingBase}, this is {@code .91}. ++ * {@link net.minecraft.entity.item.EntityItem} uses {@code .98}, and ++ * {@link net.minecraft.entity.projectile.EntityFishHook} uses {@code .92}. ++ * ++ * @param state state of the block ++ * @param world the world ++ * @param pos the position in the world ++ * @param entity the entity in question ++ * @return the factor by which the entity's motion should be multiplied ++ */ ++ public float getSlipperiness(IBlockState state, IBlockAccess world, BlockPos pos, @Nullable Entity entity) { ++ return slipperiness; ++ } ++ ++ /** ++ * Sets the base slipperiness level. Normally between 0 and 1. ++ *

++ * Calling this method may have no effect on the function of this block, ++ * or may not have the expected result. This block is free to caclculate ++ * its slipperiness arbitrarily. This method is guaranteed to work on the ++ * base {@code Block} class. ++ * ++ * @param slipperiness the base slipperiness of this block ++ * @see #getSlipperiness(IBlockState, IBlockAccess, BlockPos, Entity) ++ */ ++ public void setDefaultSlipperiness(float slipperiness) { ++ this.slipperiness = slipperiness; ++ } ++ ++ /** ++ * Get a light value for this block, taking into account the given state and coordinates, normal ranges are between 0 and 15 ++ * ++ * @param state Block state ++ * @param world The current world ++ * @param pos Block position in world ++ * @return The light value ++ */ ++ public int getLightValue(IBlockState state, IBlockAccess world, BlockPos pos) { ++ return state.getLightValue(); ++ } ++ ++ /** ++ * Checks if a player or entity can use this block to 'climb' like a ladder. ++ * ++ * @param state The current state ++ * @param world The current world ++ * @param pos Block position in world ++ * @param entity The entity trying to use the ladder, CAN be null. ++ * @return True if the block should act like a ladder ++ */ ++ public boolean isLadder(IBlockState state, IBlockAccess world, BlockPos pos, EntityLivingBase entity) { return false; } ++ ++ /** ++ * Return true if the block is a normal, solid cube. This ++ * determines indirect power state, entity ejection from blocks, and a few ++ * others. ++ * ++ * @param state The current state ++ * @param world The current world ++ * @param pos Block position in world ++ * @return True if the block is a full cube ++ */ ++ public boolean isNormalCube(IBlockState state, IBlockAccess world, BlockPos pos) { ++ return state.isNormalCube(); ++ } ++ ++ /** ++ * Check if the face of a block should block rendering. ++ * ++ * Faces which are fully opaque should return true, faces with transparency ++ * or faces which do not span the full size of the block should return false. ++ * ++ * @param state The current block state ++ * @param world The current world ++ * @param pos Block position in world ++ * @param face The side to check ++ * @return True if the block is opaque on the specified side. ++ */ ++ public boolean doesSideBlockRendering(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing face) { ++ return state.isOpaqueCube(); ++ } ++ ++ /** ++ * Checks if the block is a solid face on the given side, used by placement logic. ++ * ++ * @param base_state The base state, getActualState should be called first ++ * @param world The current world ++ * @param pos Block position in world ++ * @param side The side to check ++ * @return True if the block is solid on the specified side. ++ */ ++ @Deprecated //Use IBlockState.getBlockFaceShape ++ public boolean isSideSolid(IBlockState base_state, IBlockAccess world, BlockPos pos, EnumFacing side) { ++ if (base_state.isTopSolid() && side == EnumFacing.UP) // Short circuit to vanilla function if its true ++ return true; ++ ++ if (this instanceof BlockSlab) { ++ IBlockState state = this.getActualState(base_state, world, pos); ++ return base_state.isFullBlock() ++ || (state.getValue(BlockSlab.HALF) == BlockSlab.EnumBlockHalf.TOP && side == EnumFacing.UP ) ++ || (state.getValue(BlockSlab.HALF) == BlockSlab.EnumBlockHalf.BOTTOM && side == EnumFacing.DOWN); ++ } else if (this instanceof BlockFarmland) { ++ return (side != EnumFacing.DOWN && side != EnumFacing.UP); ++ } else if (this instanceof BlockStairs) { ++ IBlockState state = this.getActualState(base_state, world, pos); ++ boolean flipped = state.getValue(BlockStairs.HALF) == BlockStairs.EnumHalf.TOP; ++ BlockStairs.EnumShape shape = (BlockStairs.EnumShape)state.getValue(BlockStairs.SHAPE); ++ EnumFacing facing = (EnumFacing)state.getValue(BlockStairs.FACING); ++ if (side == EnumFacing.UP) return flipped; ++ if (side == EnumFacing.DOWN) return !flipped; ++ if (facing == side) return true; ++ if (flipped) { ++ if (shape == BlockStairs.EnumShape.INNER_LEFT ) return side == facing.rotateYCCW(); ++ if (shape == BlockStairs.EnumShape.INNER_RIGHT) return side == facing.rotateY(); ++ } else { ++ if (shape == BlockStairs.EnumShape.INNER_LEFT ) return side == facing.rotateY(); ++ if (shape == BlockStairs.EnumShape.INNER_RIGHT) return side == facing.rotateYCCW(); ++ } ++ return false; ++ } else if (this instanceof BlockSnow) { ++ IBlockState state = this.getActualState(base_state, world, pos); ++ return ((Integer)state.getValue(BlockSnow.LAYERS)) >= 8; ++ } else if (this instanceof BlockHopper && side == EnumFacing.UP) { ++ return true; ++ } else if (this instanceof BlockCompressedPowered) { ++ return true; ++ } ++ return isNormalCube(base_state, world, pos); ++ } ++ ++ /** ++ * Determines if this block should set fire and deal fire damage ++ * to entities coming into contact with it. ++ * ++ * @param world The current world ++ * @param pos Block position in world ++ * @return True if the block should deal damage ++ */ ++ public boolean isBurning(IBlockAccess world, BlockPos pos) { ++ return false; ++ } ++ ++ /** ++ * Determines this block should be treated as an air block ++ * by the rest of the code. This method is primarily ++ * useful for creating pure logic-blocks that will be invisible ++ * to the player and otherwise interact as air would. ++ * ++ * @param state The current state ++ * @param world The current world ++ * @param pos Block position in world ++ * @return True if the block considered air ++ */ ++ public boolean isAir(IBlockState state, IBlockAccess world, BlockPos pos) { ++ return state.getMaterial() == Material.AIR; ++ } ++ ++ /** ++ * Determines if the player can harvest this block, obtaining it's drops when the block is destroyed. ++ * ++ * @param player The player damaging the block ++ * @param pos The block's current position ++ * @return True to spawn the drops ++ */ ++ public boolean canHarvestBlock(IBlockAccess world, BlockPos pos, EntityPlayer player) { ++ return net.minecraftforge.common.ForgeHooks.canHarvestBlock(this, player, world, pos); ++ } ++ ++ /** ++ * Called when a player removes a block. This is responsible for ++ * actually destroying the block, and the block is intact at time of call. ++ * This is called regardless of whether the player can harvest the block or ++ * not. ++ * ++ * Return true if the block is actually destroyed. ++ * ++ * Note: When used in multiplayer, this is called on both client and ++ * server sides! ++ * ++ * @param state The current state. ++ * @param world The current world ++ * @param player The player damaging the block, may be null ++ * @param pos Block position in world ++ * @param willHarvest True if Block.harvestBlock will be called after this, if the return in true. ++ * Can be useful to delay the destruction of tile entities till after harvestBlock ++ * @return True if the block is actually destroyed. ++ */ ++ public boolean removedByPlayer(IBlockState state, World world, BlockPos pos, EntityPlayer player, boolean willHarvest) { ++ this.onBlockHarvested(world, pos, state, player); ++ return world.setBlockState(pos, net.minecraft.init.Blocks.AIR.getDefaultState(), world.isRemote ? 11 : 3); ++ } ++ ++ /** ++ * Chance that fire will spread and consume this block. ++ * 300 being a 100% chance, 0, being a 0% chance. ++ * ++ * @param world The current world ++ * @param pos Block position in world ++ * @param face The face that the fire is coming from ++ * @return A number ranging from 0 to 300 relating used to determine if the block will be consumed by fire ++ */ ++ public int getFlammability(IBlockAccess world, BlockPos pos, EnumFacing face) { ++ return net.minecraft.init.Blocks.FIRE.getFlammability(this); ++ } ++ ++ /** ++ * Called when fire is updating, checks if a block face can catch fire. ++ * ++ * ++ * @param world The current world ++ * @param pos Block position in world ++ * @param face The face that the fire is coming from ++ * @return True if the face can be on fire, false otherwise. ++ */ ++ public boolean isFlammable(IBlockAccess world, BlockPos pos, EnumFacing face) { ++ return getFlammability(world, pos, face) > 0; ++ } ++ ++ /** ++ * Called when fire is updating on a neighbor block. ++ * The higher the number returned, the faster fire will spread around this block. ++ * ++ * @param world The current world ++ * @param pos Block position in world ++ * @param face The face that the fire is coming from ++ * @return A number that is used to determine the speed of fire growth around the block ++ */ ++ public int getFireSpreadSpeed(IBlockAccess world, BlockPos pos, EnumFacing face) { ++ return net.minecraft.init.Blocks.FIRE.getEncouragement(this); ++ } ++ ++ /** ++ * Currently only called by fire when it is on top of this block. ++ * Returning true will prevent the fire from naturally dying during updating. ++ * Also prevents firing from dying from rain. ++ * ++ * @param world The current world ++ * @param pos Block position in world ++ * @param side The face that the fire is coming from ++ * @return True if this block sustains fire, meaning it will never go out. ++ */ ++ public boolean isFireSource(World world, BlockPos pos, EnumFacing side) { ++ if (side != EnumFacing.UP) ++ return false; ++ if (this == Blocks.NETHERRACK || this == Blocks.MAGMA) ++ return true; ++ if ((world.provider instanceof net.minecraft.world.WorldProviderEnd) && this == Blocks.BEDROCK) ++ return true; ++ return false; ++ } ++ ++ private boolean isTileProvider = this instanceof ITileEntityProvider; ++ /** ++ * Called throughout the code as a replacement for block instanceof BlockContainer ++ * Moving this to the Block base class allows for mods that wish to extend vanilla ++ * blocks, and also want to have a tile entity on that block, may. ++ * ++ * Return true from this function to specify this block has a tile entity. ++ * ++ * @param state State of the current block ++ * @return True if block has a tile entity, false otherwise ++ */ ++ public boolean hasTileEntity(IBlockState state) { ++ return isTileProvider; ++ } ++ ++ /** ++ * Called throughout the code as a replacement for ITileEntityProvider.createNewTileEntity ++ * Return the same thing you would from that function. ++ * This will fall back to ITileEntityProvider.createNewTileEntity(World) if this block is a ITileEntityProvider ++ * ++ * @param state The state of the current block ++ * @return A instance of a class extending TileEntity ++ */ ++ @Nullable ++ public TileEntity createTileEntity(World world, IBlockState state) { ++ if (isTileProvider) { ++ return ((ITileEntityProvider)this).createNewTileEntity(world, getMetaFromState(state)); ++ } ++ return null; ++ } ++ ++ /** ++ * State and fortune sensitive version, this replaces the old (int meta, Random rand) ++ * version in 1.1. ++ * ++ * @param state Current state ++ * @param fortune Current item fortune level ++ * @param random Random number generator ++ * @return The number of items to drop ++ */ ++ public int quantityDropped(IBlockState state, int fortune, Random random) { ++ return quantityDroppedWithBonus(fortune, random); ++ } ++ ++ /** ++ * @deprecated use {@link #getDrops(NonNullList, IBlockAccess, BlockPos, IBlockState, int)} ++ */ ++ @Deprecated ++ public List getDrops(IBlockAccess world, BlockPos pos, IBlockState state, int fortune) { ++ NonNullList ret = NonNullList.create(); ++ getDrops(ret, world, pos, state, fortune); ++ return ret; ++ } ++ ++ /** ++ * This gets a complete list of items dropped from this block. ++ * ++ * @param drops add all items this block drops to this drops list ++ * @param world The current world ++ * @param pos Block position in world ++ * @param state Current state ++ * @param fortune Breakers fortune level ++ */ ++ public void getDrops(NonNullList drops, IBlockAccess world, BlockPos pos, IBlockState state, int fortune) { ++ Random rand = world instanceof World ? ((World)world).rand : RANDOM; ++ ++ int count = quantityDropped(state, fortune, rand); ++ for (int i = 0; i < count; i++) { ++ Item item = this.getItemDropped(state, rand, fortune); ++ if (item != Items.AIR) { ++ drops.add(new ItemStack(item, 1, this.damageDropped(state))); ++ } ++ } ++ } ++ ++ /** ++ * Return true from this function if the player with silk touch can harvest this block directly, and not it's normal drops. ++ * ++ * @param world The world ++ * @param pos Block position in world ++ * @param state current block state ++ * @param player The player doing the harvesting ++ * @return True if the block can be directly harvested using silk touch ++ */ ++ public boolean canSilkHarvest(World world, BlockPos pos, IBlockState state, EntityPlayer player) { ++ silk_check_state.set(state);; ++ boolean ret = this.canSilkHarvest(); ++ silk_check_state.set(null); ++ return ret; ++ } ++ ++ /** ++ * Determines if a specified mob type can spawn on this block, returning false will ++ * prevent any mob from spawning on the block. ++ * ++ * @param state The current state ++ * @param world The current world ++ * @param pos Block position in world ++ * @param type The Mob Category Type ++ * @return True to allow a mob of the specified category to spawn, false to prevent it. ++ */ ++ public boolean canCreatureSpawn(IBlockState state, IBlockAccess world, BlockPos pos, net.minecraft.entity.EntityLiving.SpawnPlacementType type) { ++ return isSideSolid(state, world, pos, EnumFacing.UP); ++ } ++ ++ /** ++ * Determines if this block is classified as a Bed, Allowing ++ * players to sleep in it, though the block has to specifically ++ * perform the sleeping functionality in it's activated event. ++ * ++ * @param state The current state ++ * @param world The current world ++ * @param pos Block position in world ++ * @param player The player or camera entity, null in some cases. ++ * @return True to treat this as a bed ++ */ ++ public boolean isBed(IBlockState state, IBlockAccess world, BlockPos pos, @Nullable Entity player) { ++ return this == net.minecraft.init.Blocks.BED; ++ } ++ ++ /** ++ * Returns the position that the player is moved to upon ++ * waking up, or respawning at the bed. ++ * ++ * @param state The current state ++ * @param world The current world ++ * @param pos Block position in world ++ * @param player The player or camera entity, null in some cases. ++ * @return The spawn position ++ */ ++ @Nullable ++ public BlockPos getBedSpawnPosition(IBlockState state, IBlockAccess world, BlockPos pos, @Nullable EntityPlayer player) { ++ if (world instanceof World) ++ return BlockBed.getSafeExitLocation((World)world, pos, 0); ++ return null; ++ } ++ ++ /** ++ * Called when a user either starts or stops sleeping in the bed. ++ * ++ * @param world The current world ++ * @param pos Block position in world ++ * @param player The player or camera entity, null in some cases. ++ * @param occupied True if we are occupying the bed, or false if they are stopping use of the bed ++ */ ++ public void setBedOccupied(IBlockAccess world, BlockPos pos, EntityPlayer player, boolean occupied) { ++ if (world instanceof World) { ++ IBlockState state = world.getBlockState(pos); ++ state = state.getBlock().getActualState(state, world, pos); ++ state = state.withProperty(BlockBed.OCCUPIED, occupied); ++ ((World)world).setBlockState(pos, state, 4); ++ } ++ } ++ ++ /** ++ * Returns the direction of the block. Same values that ++ * are returned by BlockDirectional ++ * ++ * @param state The current state ++ * @param world The current world ++ * @param pos Block position in world ++ * @return Bed direction ++ */ ++ public EnumFacing getBedDirection(IBlockState state, IBlockAccess world, BlockPos pos) { ++ return (EnumFacing)getActualState(state, world, pos).getValue(BlockHorizontal.FACING); ++ } ++ ++ /** ++ * Determines if the current block is the foot half of the bed. ++ * ++ * @param world The current world ++ * @param pos Block position in world ++ * @return True if the current block is the foot side of a bed. ++ */ ++ public boolean isBedFoot(IBlockAccess world, BlockPos pos) { ++ return getActualState(world.getBlockState(pos), world, pos).getValue(BlockBed.PART) == BlockBed.EnumPartType.FOOT; ++ } ++ ++ /** ++ * Called when a leaf should start its decay process. ++ * ++ * @param state The current state ++ * @param world The current world ++ * @param pos Block position in world ++ */ ++ public void beginLeavesDecay(IBlockState state, World world, BlockPos pos){} ++ ++ /** ++ * Determines if this block can prevent leaves connected to it from decaying. ++ * @param state The current state ++ * @param world The current world ++ * @param pos Block position in world ++ * @return true if the presence this block can prevent leaves from decaying. ++ */ ++ public boolean canSustainLeaves(IBlockState state, IBlockAccess world, BlockPos pos) { ++ return false; ++ } ++ ++ /** ++ * Determines if this block is considered a leaf block, used to apply the leaf decay and generation system. ++ * ++ * @param state The current state ++ * @param world The current world ++ * @param pos Block position in world ++ * @return true if this block is considered leaves. ++ */ ++ public boolean isLeaves(IBlockState state, IBlockAccess world, BlockPos pos) { ++ return state.getMaterial() == Material.LEAVES; ++ } ++ ++ /** ++ * Used during tree growth to determine if newly generated leaves can replace this block. ++ * ++ * @param state The current state ++ * @param world The current world ++ * @param pos Block position in world ++ * @return true if this block can be replaced by growing leaves. ++ */ ++ public boolean canBeReplacedByLeaves(IBlockState state, IBlockAccess world, BlockPos pos) { ++ return isAir(state, world, pos) || isLeaves(state, world, pos); //!state.isFullBlock(); ++ } ++ ++ /** ++ * ++ * @param world The current world ++ * @param pos Block position in world ++ * @return true if the block is wood (logs) ++ */ ++ public boolean isWood(IBlockAccess world, BlockPos pos) { ++ return false; ++ } ++ ++ /** ++ * Determines if the current block is replaceable by Ore veins during world generation. ++ * ++ * @param state The current state ++ * @param world The current world ++ * @param pos Block position in world ++ * @param target The generic target block the gen is looking for, Standards define stone ++ * for overworld generation, and neatherack for the nether. ++ * @return True to allow this block to be replaced by a ore ++ */ ++ public boolean isReplaceableOreGen(IBlockState state, IBlockAccess world, BlockPos pos, com.google.common.base.Predicate target) { ++ return target.apply(state); ++ } ++ ++ /** ++ * Location sensitive version of getExplosionResistance ++ * ++ * @param world The current world ++ * @param pos Block position in world ++ * @param exploder The entity that caused the explosion, can be null ++ * @param explosion The explosion ++ * @return The amount of the explosion absorbed. ++ */ ++ public float getExplosionResistance(World world, BlockPos pos, @Nullable Entity exploder, Explosion explosion) { ++ return getExplosionResistance(exploder); ++ } ++ ++ /** ++ * Called when the block is destroyed by an explosion. ++ * Useful for allowing the block to take into account tile entities, ++ * state, etc. when exploded, before it is removed. ++ * ++ * @param world The current world ++ * @param pos Block position in world ++ * @param explosion The explosion instance affecting the block ++ */ ++ public void onBlockExploded(World world, BlockPos pos, Explosion explosion) { ++ world.setBlockToAir(pos); ++ onExplosionDestroy(world, pos, explosion); ++ } ++ ++ /** ++ * Determine if this block can make a redstone connection on the side provided, ++ * Useful to control which sides are inputs and outputs for redstone wires. ++ * ++ * @param state The current state ++ * @param world The current world ++ * @param pos Block position in world ++ * @param side The side that is trying to make the connection, CAN BE NULL ++ * @return True to make the connection ++ */ ++ public boolean canConnectRedstone(IBlockState state, IBlockAccess world, BlockPos pos, @Nullable EnumFacing side) { ++ return state.canProvidePower() && side != null; ++ } ++ ++ /** ++ * Determines if a torch can be placed on the top surface of this block. ++ * Useful for creating your own block that torches can be on, such as fences. ++ * ++ * @param state The current state ++ * @param world The current world ++ * @param pos Block position in world ++ * @return True to allow the torch to be placed ++ */ ++ public boolean canPlaceTorchOnTop(IBlockState state, IBlockAccess world, BlockPos pos) { ++ if (this == Blocks.END_GATEWAY || this == Blocks.LIT_PUMPKIN) { ++ return false; ++ } else if (state.isTopSolid() || this instanceof BlockFence || this == Blocks.GLASS || this == Blocks.COBBLESTONE_WALL || this == Blocks.STAINED_GLASS) { ++ return true; ++ } else { ++ BlockFaceShape shape = state.getBlockFaceShape(world, pos, EnumFacing.UP); ++ return (shape == BlockFaceShape.SOLID || shape == BlockFaceShape.CENTER || shape == BlockFaceShape.CENTER_BIG) && !isExceptionBlockForAttaching(this); ++ } ++ } ++ ++ /** ++ * Called when a user uses the creative pick block button on this block ++ * ++ * @param target The full target the player is looking at ++ * @return A ItemStack to add to the player's inventory, empty itemstack if nothing should be added. ++ */ ++ public ItemStack getPickBlock(IBlockState state, RayTraceResult target, World world, BlockPos pos, EntityPlayer player) { ++ return getItem(world, pos, state); ++ } ++ ++ /** ++ * Used by getTopSolidOrLiquidBlock while placing biome decorations, villages, etc ++ * Also used to determine if the player can spawn on this block. ++ * ++ * @return False to disallow spawning ++ */ ++ public boolean isFoliage(IBlockAccess world, BlockPos pos) { ++ return false; ++ } ++ ++ /** ++ * Allows a block to override the standard EntityLivingBase.updateFallState ++ * particles, this is a server side method that spawns particles with ++ * WorldServer.spawnParticle ++ * ++ * @param world The current Server world ++ * @param blockPosition of the block that the entity landed on. ++ * @param iblockstate State at the specific world/pos ++ * @param entity the entity that hit landed on the block. ++ * @param numberOfParticles that vanilla would have spawned. ++ * @return True to prevent vanilla landing particles form spawning. ++ */ ++ public boolean addLandingEffects(IBlockState state, net.minecraft.world.WorldServer worldObj, BlockPos blockPosition, IBlockState iblockstate, EntityLivingBase entity, int numberOfParticles ) { ++ return false; ++ } ++ ++ /** ++ * Allows a block to override the standard vanilla running particles. ++ * This is called from {@link Entity#spawnRunningParticles} and is called both, ++ * Client and server side, it's up to the implementor to client check / server check. ++ * By default vanilla spawns particles only on the client and the server methods no-op. ++ * ++ * @param state The BlockState the entity is running on. ++ * @param world The world. ++ * @param pos The position at the entities feet. ++ * @param entity The entity running on the block. ++ * @return True to prevent vanilla running particles from spawning. ++ */ ++ public boolean addRunningEffects(IBlockState state, World world, BlockPos pos, Entity entity) { ++ return false; ++ } ++ ++ /** ++ * Spawn a digging particle effect in the world, this is a wrapper ++ * around EffectRenderer.addBlockHitEffects to allow the block more ++ * control over the particles. Useful when you have entirely different ++ * texture sheets for different sides/locations in the world. ++ * ++ * @param state The current state ++ * @param world The current world ++ * @param target The target the player is looking at {x/y/z/side/sub} ++ * @param manager A reference to the current particle manager. ++ * @return True to prevent vanilla digging particles form spawning. ++ */ ++ @SideOnly(Side.CLIENT) ++ public boolean addHitEffects(IBlockState state, World worldObj, RayTraceResult target, net.minecraft.client.particle.ParticleManager manager) { ++ return false; ++ } ++ ++ /** ++ * Spawn particles for when the block is destroyed. Due to the nature ++ * of how this is invoked, the x/y/z locations are not always guaranteed ++ * to host your block. So be sure to do proper sanity checks before assuming ++ * that the location is this block. ++ * ++ * @param world The current world ++ * @param pos Position to spawn the particle ++ * @param manager A reference to the current particle manager. ++ * @return True to prevent vanilla break particles from spawning. ++ */ ++ @SideOnly(Side.CLIENT) ++ public boolean addDestroyEffects(World world, BlockPos pos, net.minecraft.client.particle.ParticleManager manager) { ++ return false; ++ } ++ ++ /** ++ * Determines if this block can support the passed in plant, allowing it to be planted and grow. ++ * Some examples: ++ * Reeds check if its a reed, or if its sand/dirt/grass and adjacent to water ++ * Cacti checks if its a cacti, or if its sand ++ * Nether types check for soul sand ++ * Crops check for tilled soil ++ * Caves check if it's a solid surface ++ * Plains check if its grass or dirt ++ * Water check if its still water ++ * ++ * @param state The Current state ++ * @param world The current world ++ * @param pos Block position in world ++ * @param direction The direction relative to the given position the plant wants to be, typically its UP ++ * @param plantable The plant that wants to check ++ * @return True to allow the plant to be planted/stay. ++ */ ++ public boolean canSustainPlant(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing direction, net.minecraftforge.common.IPlantable plantable) { ++ IBlockState plant = plantable.getPlant(world, pos.offset(direction)); ++ net.minecraftforge.common.EnumPlantType plantType = plantable.getPlantType(world, pos.offset(direction)); ++ ++ if (plant.getBlock() == net.minecraft.init.Blocks.CACTUS) { ++ return this == net.minecraft.init.Blocks.CACTUS || this == net.minecraft.init.Blocks.SAND; ++ } ++ ++ if (plant.getBlock() == net.minecraft.init.Blocks.REEDS && this == net.minecraft.init.Blocks.REEDS) { ++ return true; ++ } ++ ++ if (plantable instanceof BlockBush && ((BlockBush)plantable).canSustainBush(state)) { ++ return true; ++ } ++ ++ switch (plantType) { ++ case Desert: return this == net.minecraft.init.Blocks.SAND || this == net.minecraft.init.Blocks.HARDENED_CLAY || this == net.minecraft.init.Blocks.STAINED_HARDENED_CLAY; ++ case Nether: return this == net.minecraft.init.Blocks.SOUL_SAND; ++ case Crop: return this == net.minecraft.init.Blocks.FARMLAND; ++ case Cave: return state.isSideSolid(world, pos, EnumFacing.UP); ++ case Plains: return this == net.minecraft.init.Blocks.GRASS || this == net.minecraft.init.Blocks.DIRT || this == net.minecraft.init.Blocks.FARMLAND; ++ case Water: return state.getMaterial() == Material.WATER && state.getValue(BlockLiquid.LEVEL) == 0; ++ case Beach: ++ boolean isBeach = this == net.minecraft.init.Blocks.GRASS || this == net.minecraft.init.Blocks.DIRT || this == net.minecraft.init.Blocks.SAND; ++ boolean hasWater = (world.getBlockState(pos.east()).getMaterial() == Material.WATER || ++ world.getBlockState(pos.west()).getMaterial() == Material.WATER || ++ world.getBlockState(pos.north()).getMaterial() == Material.WATER || ++ world.getBlockState(pos.south()).getMaterial() == Material.WATER); ++ return isBeach && hasWater; ++ } ++ ++ return false; ++ } ++ ++ /** ++ * Called when a plant grows on this block, only implemented for saplings using the WorldGen*Trees classes right now. ++ * Modder may implement this for custom plants. ++ * This does not use ForgeDirection, because large/huge trees can be located in non-representable direction, ++ * so the source location is specified. ++ * Currently this just changes the block to dirt if it was grass. ++ * ++ * Note: This happens DURING the generation, the generation may not be complete when this is called. ++ * ++ * @param state The current state ++ * @param world Current world ++ * @param pos Block position in world ++ * @param source Source plant's position in world ++ */ ++ public void onPlantGrow(IBlockState state, World world, BlockPos pos, BlockPos source) { ++ if (this == net.minecraft.init.Blocks.GRASS || this == net.minecraft.init.Blocks.FARMLAND) { ++ world.setBlockState(pos, net.minecraft.init.Blocks.DIRT.getDefaultState(), 2); ++ } ++ } ++ ++ /** ++ * Checks if this soil is fertile, typically this means that growth rates ++ * of plants on this soil will be slightly sped up. ++ * Only vanilla case is tilledField when it is within range of water. ++ * ++ * @param world The current world ++ * @param pos Block position in world ++ * @return True if the soil should be considered fertile. ++ */ ++ public boolean isFertile(World world, BlockPos pos) { ++ if (this == net.minecraft.init.Blocks.FARMLAND) { ++ return ((Integer)world.getBlockState(pos).getValue(BlockFarmland.MOISTURE)) > 0; ++ } ++ ++ return false; ++ } ++ ++ /** ++ * Location aware and overrideable version of the lightOpacity array, ++ * return the number to subtract from the light value when it passes through this block. ++ * ++ * This is not guaranteed to have the tile entity in place before this is called, so it is ++ * Recommended that you have your tile entity call relight after being placed if you ++ * rely on it for light info. ++ * ++ * @param state The Block state ++ * @param world The current world ++ * @param pos Block position in world ++ * @return The amount of light to block, 0 for air, 255 for fully opaque. ++ */ ++ public int getLightOpacity(IBlockState state, IBlockAccess world, BlockPos pos) { ++ return state.getLightOpacity(); ++ } ++ ++ /** ++ * Determines if this block is can be destroyed by the specified entities normal behavior. ++ * ++ * @param state The current state ++ * @param world The current world ++ * @param pos Block position in world ++ * @return True to allow the ender dragon to destroy this block ++ */ ++ public boolean canEntityDestroy(IBlockState state, IBlockAccess world, BlockPos pos, Entity entity) { ++ if (entity instanceof net.minecraft.entity.boss.EntityDragon) { ++ return this != net.minecraft.init.Blocks.BARRIER && ++ this != net.minecraft.init.Blocks.OBSIDIAN && ++ this != net.minecraft.init.Blocks.END_STONE && ++ this != net.minecraft.init.Blocks.BEDROCK && ++ this != net.minecraft.init.Blocks.END_PORTAL && ++ this != net.minecraft.init.Blocks.END_PORTAL_FRAME && ++ this != net.minecraft.init.Blocks.COMMAND_BLOCK && ++ this != net.minecraft.init.Blocks.REPEATING_COMMAND_BLOCK && ++ this != net.minecraft.init.Blocks.CHAIN_COMMAND_BLOCK && ++ this != net.minecraft.init.Blocks.IRON_BARS && ++ this != net.minecraft.init.Blocks.END_GATEWAY; ++ } else if ((entity instanceof net.minecraft.entity.boss.EntityWither) || ++ (entity instanceof net.minecraft.entity.projectile.EntityWitherSkull)) { ++ return net.minecraft.entity.boss.EntityWither.canDestroyBlock(this); ++ } ++ ++ return true; ++ } ++ ++ /** ++ * Determines if this block can be used as the base of a beacon. ++ * ++ * @param world The current world ++ * @param pos Block position in world ++ * @param beacon Beacon position in world ++ * @return True, to support the beacon, and make it active with this block. ++ */ ++ public boolean isBeaconBase(IBlockAccess worldObj, BlockPos pos, BlockPos beacon) { ++ return this == net.minecraft.init.Blocks.EMERALD_BLOCK || this == net.minecraft.init.Blocks.GOLD_BLOCK || this == net.minecraft.init.Blocks.DIAMOND_BLOCK || this == net.minecraft.init.Blocks.IRON_BLOCK; ++ } ++ ++ /** ++ * Rotate the block. For vanilla blocks this rotates around the axis passed in (generally, it should be the "face" that was hit). ++ * Note: for mod blocks, this is up to the block and modder to decide. It is not mandated that it be a rotation around the ++ * face, but could be a rotation to orient *to* that face, or a visiting of possible rotations. ++ * The method should return true if the rotation was successful though. ++ * ++ * @param world The world ++ * @param pos Block position in world ++ * @param axis The axis to rotate around ++ * @return True if the rotation was successful, False if the rotation failed, or is not possible ++ */ ++ public boolean rotateBlock(World world, BlockPos pos, EnumFacing axis) { ++ IBlockState state = world.getBlockState(pos); ++ for (IProperty prop : state.getProperties().keySet()) { ++ if ((prop.getName().equals("facing") || prop.getName().equals("rotation")) && prop.getValueClass() == EnumFacing.class) { ++ Block block = state.getBlock(); ++ if (!(block instanceof BlockBed) && !(block instanceof BlockPistonExtension)) { ++ IBlockState newState; ++ //noinspection unchecked ++ IProperty facingProperty = (IProperty) prop; ++ EnumFacing facing = state.getValue(facingProperty); ++ java.util.Collection validFacings = facingProperty.getAllowedValues(); ++ ++ // rotate horizontal facings clockwise ++ if (validFacings.size() == 4 && !validFacings.contains(EnumFacing.UP) && !validFacings.contains(EnumFacing.DOWN)) { ++ newState = state.withProperty(facingProperty, facing.rotateY()); ++ } else { ++ // rotate other facings about the axis ++ EnumFacing rotatedFacing = facing.rotateAround(axis.getAxis()); ++ if (validFacings.contains(rotatedFacing)) { ++ newState = state.withProperty(facingProperty, rotatedFacing); ++ } else { // abnormal facing property, just cycle it ++ newState = state.cycleProperty(facingProperty); ++ } ++ } ++ ++ world.setBlockState(pos, newState); ++ return true; ++ } ++ } ++ } ++ return false; ++ } ++ ++ /** ++ * Get the rotations that can apply to the block at the specified coordinates. Null means no rotations are possible. ++ * Note, this is up to the block to decide. It may not be accurate or representative. ++ * @param world The world ++ * @param pos Block position in world ++ * @return An array of valid axes to rotate around, or null for none or unknown ++ */ ++ @Nullable ++ public EnumFacing[] getValidRotations(World world, BlockPos pos) { ++ IBlockState state = world.getBlockState(pos); ++ for (IProperty prop : state.getProperties().keySet()) { ++ if ((prop.getName().equals("facing") || prop.getName().equals("rotation")) && prop.getValueClass() == EnumFacing.class) { ++ @SuppressWarnings("unchecked") ++ java.util.Collection values = ((java.util.Collection)prop.getAllowedValues()); ++ return values.toArray(new EnumFacing[values.size()]); ++ } ++ } ++ return null; ++ } ++ ++ /** ++ * Determines the amount of enchanting power this block can provide to an enchanting table. ++ * @param world The World ++ * @param pos Block position in world ++ * @return The amount of enchanting power this block produces. ++ */ ++ public float getEnchantPowerBonus(World world, BlockPos pos) { ++ return this == net.minecraft.init.Blocks.BOOKSHELF ? 1 : 0; ++ } ++ ++ /** ++ * Common way to recolor a block with an external tool ++ * @param world The world ++ * @param pos Block position in world ++ * @param side The side hit with the coloring tool ++ * @param color The color to change to ++ * @return If the recoloring was successful ++ */ ++ @SuppressWarnings({ "unchecked", "rawtypes" }) ++ public boolean recolorBlock(World world, BlockPos pos, EnumFacing side, net.minecraft.item.EnumDyeColor color) { ++ IBlockState state = world.getBlockState(pos); ++ for (IProperty prop : state.getProperties().keySet()) { ++ if (prop.getName().equals("color") && prop.getValueClass() == net.minecraft.item.EnumDyeColor.class) { ++ net.minecraft.item.EnumDyeColor current = (net.minecraft.item.EnumDyeColor)state.getValue(prop); ++ if (current != color && prop.getAllowedValues().contains(color)) { ++ world.setBlockState(pos, state.withProperty(prop, color)); ++ return true; ++ } ++ } ++ } ++ return false; ++ } ++ ++ /** ++ * Gathers how much experience this block drops when broken. ++ * ++ * @param state The current state ++ * @param world The world ++ * @param pos Block position ++ * @param fortune ++ * @return Amount of XP from breaking this block. ++ */ ++ public int getExpDrop(IBlockState state, IBlockAccess world, BlockPos pos, int fortune) { ++ return 0; ++ } ++ ++ /** ++ * Called when a tile entity on a side of this block changes is created or is destroyed. ++ * @param world The world ++ * @param pos Block position in world ++ * @param neighbor Block position of neighbor ++ */ ++ public void onNeighborChange(IBlockAccess world, BlockPos pos, BlockPos neighbor){} ++ ++ /** ++ * Called on an Observer block whenever an update for an Observer is received. ++ * ++ * @param observerState The Observer block's state. ++ * @param world The current world. ++ * @param observerPos The Observer block's position. ++ * @param changedBlock The updated block. ++ * @param changedBlockPos The updated block's position. ++ */ ++ public void observedNeighborChange(IBlockState observerState, World world, BlockPos observerPos, Block changedBlock, BlockPos changedBlockPos){} ++ ++ /** ++ * Called to determine whether to allow the a block to handle its own indirect power rather than using the default rules. ++ * @param world The world ++ * @param pos Block position in world ++ * @param side The INPUT side of the block to be powered - ie the opposite of this block's output side ++ * @return Whether Block#isProvidingWeakPower should be called when determining indirect power ++ */ ++ public boolean shouldCheckWeakPower(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing side) { ++ return state.isNormalCube(); ++ } ++ ++ /** ++ * If this block should be notified of weak changes. ++ * Weak changes are changes 1 block away through a solid block. ++ * Similar to comparators. ++ * ++ * @param world The current world ++ * @param pos Block position in world ++ * @return true To be notified of changes ++ */ ++ public boolean getWeakChanges(IBlockAccess world, BlockPos pos) { ++ return false; ++ } ++ ++ private String[] harvestTool = new String[16];; ++ private int[] harvestLevel = new int[]{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; ++ /** ++ * Sets or removes the tool and level required to harvest this block. ++ * ++ * @param toolClass Class ++ * @param level Harvest level: ++ * Wood: 0 ++ * Stone: 1 ++ * Iron: 2 ++ * Diamond: 3 ++ * Gold: 0 ++ */ ++ public void setHarvestLevel(String toolClass, int level) { ++ java.util.Iterator itr = getBlockState().getValidStates().iterator(); ++ while (itr.hasNext()) { ++ setHarvestLevel(toolClass, level, itr.next()); ++ } ++ } ++ ++ /** ++ * Sets or removes the tool and level required to harvest this block. ++ * ++ * @param toolClass Class ++ * @param level Harvest level: ++ * Wood: 0 ++ * Stone: 1 ++ * Iron: 2 ++ * Diamond: 3 ++ * Gold: 0 ++ * @param state The specific state. ++ */ ++ public void setHarvestLevel(String toolClass, int level, IBlockState state) { ++ int idx = this.getMetaFromState(state); ++ this.harvestTool[idx] = toolClass; ++ this.harvestLevel[idx] = level; ++ } ++ ++ /** ++ * Queries the class of tool required to harvest this block, if null is returned ++ * we assume that anything can harvest this block. ++ */ ++ @Nullable public String getHarvestTool(IBlockState state) { ++ return harvestTool[getMetaFromState(state)]; ++ } ++ ++ /** ++ * Queries the harvest level of this item stack for the specified tool class, ++ * Returns -1 if this tool is not of the specified type ++ * ++ * @return Harvest level, or -1 if not the specified tool type. ++ */ ++ public int getHarvestLevel(IBlockState state) { ++ return harvestLevel[getMetaFromState(state)]; ++ } ++ ++ /** ++ * Checks if the specified tool type is efficient on this block, ++ * meaning that it digs at full speed. ++ */ ++ public boolean isToolEffective(String type, IBlockState state) { ++ if ("pickaxe".equals(type) && (this == net.minecraft.init.Blocks.REDSTONE_ORE || this == net.minecraft.init.Blocks.LIT_REDSTONE_ORE || this == net.minecraft.init.Blocks.OBSIDIAN)) ++ return false; ++ return type != null && type.equals(getHarvestTool(state)); ++ } ++ ++ /** ++ * Can return IExtendedBlockState ++ */ ++ public IBlockState getExtendedState(IBlockState state, IBlockAccess world, BlockPos pos) { ++ return state; ++ } ++ ++ /** ++ * Called when the entity is inside this block, may be used to determined if the entity can breathing, ++ * display material overlays, or if the entity can swim inside a block. ++ * ++ * @param world that is being tested. ++ * @param blockpos position thats being tested. ++ * @param iblockstate state at world/blockpos ++ * @param entity that is being tested. ++ * @param yToTest, primarily for testingHead, which sends the the eye level of the entity, other wise it sends a y that can be tested vs liquid height. ++ * @param materialIn to test for. ++ * @param testingHead when true, its testing the entities head for vision, breathing ect... otherwise its testing the body, for swimming and movement adjustment. ++ * @return null for default behavior, true if the entity is within the material, false if it was not. ++ */ ++ @Nullable ++ public Boolean isEntityInsideMaterial(IBlockAccess world, BlockPos blockpos, IBlockState iblockstate, Entity entity, double yToTest, Material materialIn, boolean testingHead) { ++ return null; ++ } ++ ++ /** ++ * Called when boats or fishing hooks are inside the block to check if they are inside ++ * the material requested. ++ * ++ * @param world world that is being tested. ++ * @param pos block thats being tested. ++ * @param boundingBox box to test, generally the bounds of an entity that are besting tested. ++ * @param materialIn to check for. ++ * @return null for default behavior, true if the box is within the material, false if it was not. ++ */ ++ @Nullable ++ public Boolean isAABBInsideMaterial(World world, BlockPos pos, AxisAlignedBB boundingBox, Material materialIn) { ++ return null; ++ } ++ ++ /** ++ * Called when entities are moving to check if they are inside a liquid ++ * ++ * @param world world that is being tested. ++ * @param pos block thats being tested. ++ * @param boundingBox box to test, generally the bounds of an entity that are besting tested. ++ * @return null for default behavior, true if the box is within the material, false if it was not. ++ */ ++ @Nullable ++ public Boolean isAABBInsideLiquid(World world, BlockPos pos, AxisAlignedBB boundingBox) { ++ return null; ++ } ++ ++ /** ++ * Called when entities are swimming in the given liquid and returns the relative height (used by {@link net.minecraft.entity.item.EntityBoat}) ++ * ++ * @param world world that is being tested. ++ * @param pos block thats being tested. ++ * @param state state at world/pos ++ * @param material liquid thats being tested. ++ * @return relative height of the given liquid (material), a value between 0 and 1 ++ */ ++ public float getBlockLiquidHeight(World world, BlockPos pos, IBlockState state, Material material) { ++ return 0; ++ } ++ ++ /** ++ * Queries if this block should render in a given layer. ++ * ISmartBlockModel can use {@link net.minecraftforge.client.MinecraftForgeClient#getRenderLayer()} to alter their model based on layer. ++ */ ++ public boolean canRenderInLayer(IBlockState state, BlockRenderLayer layer) { ++ return getRenderLayer() == layer; ++ } ++ // For Internal use only to capture droped items inside getDrops ++ protected static ThreadLocal captureDrops = ThreadLocal.withInitial(() -> false); ++ protected static ThreadLocal> capturedDrops = ThreadLocal.withInitial(NonNullList::create); ++ protected NonNullList captureDrops(boolean start) { ++ if (start) { ++ captureDrops.set(true); ++ capturedDrops.get().clear(); ++ return NonNullList.create(); ++ } else { ++ captureDrops.set(false); ++ return capturedDrops.get(); ++ } ++ } ++ ++ /** ++ * Sensitive version of getSoundType ++ * @param state The state ++ * @param world The world ++ * @param pos The position. Note that the world may not necessarily have {@code state} here! ++ * @param entity The entity that is breaking/stepping on/placing/hitting/falling on this block, or null if no entity is in this context ++ * @return A SoundType to use ++ */ ++ public SoundType getSoundType(IBlockState state, World world, BlockPos pos, @Nullable Entity entity) { ++ return getSoundType(); ++ } ++ ++ /** ++ * @param state The state ++ * @param world The world ++ * @param pos The position of this state ++ * @param beaconPos The position of the beacon ++ * @return A float RGB [0.0, 1.0] array to be averaged with a beacon's existing beam color, or null to do nothing to the beam ++ */ ++ @Nullable ++ public float[] getBeaconColorMultiplier(IBlockState state, World world, BlockPos pos, BlockPos beaconPos) { ++ return null; ++ } ++ ++ /** ++ * Use this to change the fog color used when the entity is "inside" a material. ++ * Vec3d is used here as "r/g/b" 0 - 1 values. ++ * ++ * @param world The world. ++ * @param pos The position at the entity viewport. ++ * @param state The state at the entity viewport. ++ * @param entity the entity ++ * @param originalColor The current fog color, You are not expected to use this, Return as the default if applicable. ++ * @return The new fog color. ++ */ ++ @SideOnly (Side.CLIENT) ++ public Vec3d getFogColor(World world, BlockPos pos, IBlockState state, Entity entity, Vec3d originalColor, float partialTicks) { ++ if (state.getMaterial() == Material.WATER) { ++ float f12 = 0.0F; ++ ++ if (entity instanceof net.minecraft.entity.EntityLivingBase) { ++ net.minecraft.entity.EntityLivingBase ent = (net.minecraft.entity.EntityLivingBase)entity; ++ f12 = (float)net.minecraft.enchantment.EnchantmentHelper.getRespirationModifier(ent) * 0.2F; ++ ++ if (ent.isPotionActive(net.minecraft.init.MobEffects.WATER_BREATHING)) { ++ f12 = f12 * 0.3F + 0.6F; ++ } ++ } ++ return new Vec3d(0.02F + f12, 0.02F + f12, 0.2F + f12); ++ } else if (state.getMaterial() == Material.LAVA) { ++ return new Vec3d(0.6F, 0.1F, 0.0F); ++ } ++ return originalColor; ++ } ++ ++ /** ++ * Used to determine the state 'viewed' by an entity (see ++ * {@link net.minecraft.client.renderer.ActiveRenderInfo#getBlockStateAtEntityViewpoint(World, Entity, float)}). ++ * Can be used by fluid blocks to determine if the viewpoint is within the fluid or not. ++ * ++ * @param state the state ++ * @param world the world ++ * @param pos the position ++ * @param viewpoint the viewpoint ++ * @return the block state that should be 'seen' ++ */ ++ public IBlockState getStateAtViewpoint(IBlockState state, IBlockAccess world, BlockPos pos, Vec3d viewpoint) { ++ return state; ++ } ++ ++ /** ++ * Gets the {@link IBlockState} to place ++ * @param world The world the block is being placed in ++ * @param pos The position the block is being placed at ++ * @param facing The side the block is being placed on ++ * @param hitX The X coordinate of the hit vector ++ * @param hitY The Y coordinate of the hit vector ++ * @param hitZ The Z coordinate of the hit vector ++ * @param meta The metadata of {@link ItemStack} as processed by {@link Item#getMetadata(int)} ++ * @param placer The entity placing the block ++ * @param hand The player hand used to place this block ++ * @return The state to be placed in the world ++ */ ++ public IBlockState getStateForPlacement(World world, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer, EnumHand hand) { ++ return getStateForPlacement(world, pos, facing, hitX, hitY, hitZ, meta, placer); ++ } ++ ++ /** ++ * Determines if another block can connect to this block ++ * ++ * @param world The current world ++ * @param pos The position of this block ++ * @param facing The side the connecting block is on ++ * @return True to allow another block to connect to this block ++ */ ++ public boolean canBeConnectedTo(IBlockAccess world, BlockPos pos, EnumFacing facing) { ++ return false; ++ } ++ ++ /** @deprecated use {@link #getAiPathNodeType(IBlockState, IBlockAccess, BlockPos, net.minecraft.entity.EntityLiving)} */ ++ @Nullable ++ @Deprecated // TODO: remove ++ public net.minecraft.pathfinding.PathNodeType getAiPathNodeType(IBlockState state, IBlockAccess world, BlockPos pos) { ++ return isBurning(world, pos) ? net.minecraft.pathfinding.PathNodeType.DAMAGE_FIRE : null; ++ } ++ ++ /** ++ * Get the {@code PathNodeType} for this block. Return {@code null} for vanilla behavior. ++ * ++ * @return the PathNodeType ++ */ ++ @Nullable ++ public net.minecraft.pathfinding.PathNodeType getAiPathNodeType(IBlockState state, IBlockAccess world, BlockPos pos, @Nullable net.minecraft.entity.EntityLiving entity) { ++ return getAiPathNodeType(state, world, pos); ++ } ++ ++ /** ++ * @param blockState The state for this block ++ * @param world The world this block is in ++ * @param pos The position of this block ++ * @param side The side of this block that the chest lid is trying to open into ++ * @return true if the chest should be prevented from opening by this block ++ */ ++ public boolean doesSideBlockChestOpening(IBlockState blockState, IBlockAccess world, BlockPos pos, EnumFacing side) { ++ ResourceLocation registryName = this.getRegistryName(); ++ if (registryName != null && "minecraft".equals(registryName.getNamespace())) { ++ // maintain the vanilla behavior of https://bugs.mojang.com/browse/MC-378 ++ return isNormalCube(blockState, world, pos); ++ } ++ return isSideSolid(blockState, world, pos, side); ++ } ++ ++ /** ++ * @param state The state ++ * @return true if the block is sticky block which used for pull or push adjacent blocks (use by piston) ++ */ ++ public boolean isStickyBlock(IBlockState state) { ++ return state.getBlock() == Blocks.SLIME_BLOCK; ++ } ++ ++ /* ========================================= FORGE END ======================================*/ ++ + public static void registerBlocks() { + registerBlock(0, AIR_ID, new BlockAir().setTranslationKey("air")); + registerBlock(1, "stone", new BlockStone().setHardness(1.5F).setResistance(10.0F).setSoundType(SoundType.STONE).setTranslationKey("stone")); +@@ -1520,7 +2787,7 @@ + "quartz_stairs", + new BlockStairs(block11.getDefaultState().withProperty(BlockQuartz.VARIANT, BlockQuartz.EnumType.DEFAULT)).setTranslationKey("stairsQuartz") + ); +- registerBlock(157, "activator_rail", new BlockRailPowered().setHardness(0.7F).setSoundType(SoundType.METAL).setTranslationKey("activatorRail")); ++ registerBlock(157, "activator_rail", new BlockRailPowered(true).setHardness(0.7F).setSoundType(SoundType.METAL).setTranslationKey("activatorRail")); + registerBlock(158, "dropper", new BlockDropper().setHardness(3.5F).setSoundType(SoundType.STONE).setTranslationKey("dropper")); + registerBlock( + 159, +@@ -1944,22 +3211,6 @@ + block15.useNeighborBrightness = flag; + } + } +- +- Set set = Sets.newHashSet(REGISTRY.getObject(new ResourceLocation("tripwire"))); +- +- for (Block block16 : REGISTRY) { +- if (set.contains(block16)) { +- for (int i = 0; i < 15; i++) { +- int j = REGISTRY.getIDForObject(block16) << 4 | i; +- BLOCK_STATE_IDS.put(block16.getStateFromMeta(i), j); +- } +- } else { +- for (IBlockState iblockstate : block16.getBlockState().getValidStates()) { +- int k = REGISTRY.getIDForObject(block16) << 4 | block16.getMetaFromState(iblockstate); +- BLOCK_STATE_IDS.put(iblockstate, k); +- } +- } +- } + } + + private static void registerBlock(int id, ResourceLocation textualID, Block block_) { diff --git a/module/minecraft/patches/net/minecraft/block/BlockBanner.java.patch b/module/minecraft/patches/net/minecraft/block/BlockBanner.java.patch new file mode 100644 index 000000000..2dd6cb3e5 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockBanner.java.patch @@ -0,0 +1,43 @@ +--- original/net/minecraft/block/BlockBanner.java ++++ modified/net/minecraft/block/BlockBanner.java +@@ -3,6 +3,7 @@ + import java.util.Random; + import javax.annotation.Nullable; + import net.minecraft.block.material.Material; ++import net.minecraft.block.properties.IProperty; + import net.minecraft.block.properties.PropertyDirection; + import net.minecraft.block.properties.PropertyInteger; + import net.minecraft.block.state.BlockFaceShape; +@@ -98,11 +99,8 @@ + /** Spawns this Block's drops into the World as EntityItems. */ + @Override + public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, IBlockState state, float chance, int fortune) { +- ItemStack itemstack = this.getTileDataItemStack(worldIn, pos); +- if (itemstack.isEmpty()) { ++ { + super.dropBlockAsItemWithChance(worldIn, pos, state, chance, fortune); +- } else { +- spawnAsEntity(worldIn, pos, itemstack); + } + } + +@@ -139,6 +137,19 @@ + return BlockFaceShape.UNDEFINED; + } + ++ @Override ++ public void getDrops(net.minecraft.util.NonNullList drops, IBlockAccess world, BlockPos pos, IBlockState state, int fortune) { ++ TileEntity te = world.getTileEntity(pos); ++ ++ if (te instanceof TileEntityBanner) { ++ TileEntityBanner tileentitybanner = (TileEntityBanner)te; ++ ItemStack itemstack = tileentitybanner.getItem(); ++ drops.add(itemstack); ++ } else { ++ drops.add(new ItemStack(Items.BANNER, 1, 0)); ++ } ++ } ++ + public static class BlockBannerHanging extends BlockBanner { + protected static final AxisAlignedBB NORTH_AABB = new AxisAlignedBB(0.0, 0.0, 0.875, 1.0, 0.78125, 1.0); + protected static final AxisAlignedBB SOUTH_AABB = new AxisAlignedBB(0.0, 0.0, 0.0, 1.0, 0.78125, 0.125); diff --git a/module/minecraft/patches/net/minecraft/block/BlockBed.java.patch b/module/minecraft/patches/net/minecraft/block/BlockBed.java.patch new file mode 100644 index 000000000..c7ec41e19 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockBed.java.patch @@ -0,0 +1,13 @@ +--- original/net/minecraft/block/BlockBed.java ++++ modified/net/minecraft/block/BlockBed.java +@@ -88,7 +88,9 @@ + } + } + +- if (worldIn.provider.canRespawnHere() && worldIn.getBiome(pos) != Biomes.HELL) { ++ net.minecraft.world.WorldProvider.WorldSleepResult sleepResult = worldIn.provider.canSleepAt(playerIn, pos); ++ if (sleepResult != net.minecraft.world.WorldProvider.WorldSleepResult.BED_EXPLODES) { ++ if (sleepResult == net.minecraft.world.WorldProvider.WorldSleepResult.DENY) return true; + if (state.getValue(OCCUPIED)) { + EntityPlayer entityplayer = this.getPlayerInBed(worldIn, pos); + if (entityplayer != null) { diff --git a/module/minecraft/patches/net/minecraft/block/BlockBush.java.patch b/module/minecraft/patches/net/minecraft/block/BlockBush.java.patch new file mode 100644 index 000000000..3deea870d --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockBush.java.patch @@ -0,0 +1,68 @@ +--- original/net/minecraft/block/BlockBush.java ++++ modified/net/minecraft/block/BlockBush.java +@@ -17,7 +17,7 @@ + import net.minecraftforge.fml.relauncher.Side; + import net.minecraftforge.fml.relauncher.SideOnly; + +-public class BlockBush extends Block { ++public class BlockBush extends Block implements net.minecraftforge.common.IPlantable { + protected static final AxisAlignedBB BUSH_AABB = new AxisAlignedBB(0.3F, 0.0, 0.3F, 0.7F, 0.6F, 0.7F); + + protected BlockBush() { +@@ -37,7 +37,8 @@ + /** Checks if this block can be placed exactly at the given position. */ + @Override + public boolean canPlaceBlockAt(World worldIn, BlockPos pos) { +- return super.canPlaceBlockAt(worldIn, pos) && this.canSustainBush(worldIn.getBlockState(pos.down())); ++ IBlockState soil = worldIn.getBlockState(pos.down()); ++ return super.canPlaceBlockAt(worldIn, pos) && soil.getBlock().canSustainPlant(soil, worldIn, pos.down(), net.minecraft.util.EnumFacing.UP, this); + } + + /** Return true if the block can sustain a Bush */ +@@ -67,6 +68,10 @@ + } + + public boolean canBlockStay(World worldIn, BlockPos pos, IBlockState state) { ++ if (state.getBlock() == this) { //Forge: This function is called during world gen and placement, before this block is set, so if we are not 'here' then assume it's the pre-check. ++ IBlockState soil = worldIn.getBlockState(pos.down()); ++ return soil.getBlock().canSustainPlant(soil, worldIn, pos.down(), net.minecraft.util.EnumFacing.UP, this); ++ } + return this.canSustainBush(worldIn.getBlockState(pos.down())); + } + +@@ -98,7 +103,34 @@ + return false; + } + +- /** Gets the render layer this block will render on. SOLID for solid blocks, CUTOUT or CUTOUT_MIPPED for on-off transparency (glass, reeds), TRANSLUCENT for fully blended transparency (stained glass) */ ++ @Override ++ public net.minecraftforge.common.EnumPlantType getPlantType(net.minecraft.world.IBlockAccess world, BlockPos pos) { ++ if (this == Blocks.WHEAT) return net.minecraftforge.common.EnumPlantType.Crop; ++ if (this == Blocks.CARROTS) return net.minecraftforge.common.EnumPlantType.Crop; ++ if (this == Blocks.POTATOES) return net.minecraftforge.common.EnumPlantType.Crop; ++ if (this == Blocks.BEETROOTS) return net.minecraftforge.common.EnumPlantType.Crop; ++ if (this == Blocks.MELON_STEM) return net.minecraftforge.common.EnumPlantType.Crop; ++ if (this == Blocks.PUMPKIN_STEM) return net.minecraftforge.common.EnumPlantType.Crop; ++ if (this == Blocks.DEADBUSH) return net.minecraftforge.common.EnumPlantType.Desert; ++ if (this == Blocks.WATERLILY) return net.minecraftforge.common.EnumPlantType.Water; ++ if (this == Blocks.RED_MUSHROOM) return net.minecraftforge.common.EnumPlantType.Cave; ++ if (this == Blocks.BROWN_MUSHROOM) return net.minecraftforge.common.EnumPlantType.Cave; ++ if (this == Blocks.NETHER_WART) return net.minecraftforge.common.EnumPlantType.Nether; ++ if (this == Blocks.SAPLING) return net.minecraftforge.common.EnumPlantType.Plains; ++ if (this == Blocks.TALLGRASS) return net.minecraftforge.common.EnumPlantType.Plains; ++ if (this == Blocks.DOUBLE_PLANT) return net.minecraftforge.common.EnumPlantType.Plains; ++ if (this == Blocks.RED_FLOWER) return net.minecraftforge.common.EnumPlantType.Plains; ++ if (this == Blocks.YELLOW_FLOWER) return net.minecraftforge.common.EnumPlantType.Plains; ++ return net.minecraftforge.common.EnumPlantType.Plains; ++ } ++ ++ @Override ++ public IBlockState getPlant(net.minecraft.world.IBlockAccess world, BlockPos pos) { ++ IBlockState state = world.getBlockState(pos); ++ if (state.getBlock() != this) return getDefaultState(); ++ return state; ++ } ++ + @SideOnly(Side.CLIENT) + @Override + public BlockRenderLayer getRenderLayer() { diff --git a/module/minecraft/patches/net/minecraft/block/BlockButton.java.patch b/module/minecraft/patches/net/minecraft/block/BlockButton.java.patch new file mode 100644 index 000000000..0efe17623 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockButton.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/block/BlockButton.java ++++ modified/net/minecraft/block/BlockButton.java +@@ -99,7 +99,7 @@ + IBlockState iblockstate = worldIn.getBlockState(blockpos); + boolean flag = iblockstate.getBlockFaceShape(worldIn, blockpos, direction) == BlockFaceShape.SOLID; + Block block = iblockstate.getBlock(); +- return direction == EnumFacing.UP ? block == Blocks.HOPPER || !isExceptionBlockForAttaching(block) && flag : !isExceptBlockForAttachWithPiston(block) && flag; ++ return direction == EnumFacing.UP ? iblockstate.isTopSolid() || !isExceptionBlockForAttaching(block) && flag : !isExceptBlockForAttachWithPiston(block) && flag; + } + + /** Called by ItemBlocks just before a block is actually set in the world, to allow for adjustments to the IBlockstate */ diff --git a/module/minecraft/patches/net/minecraft/block/BlockCactus.java.patch b/module/minecraft/patches/net/minecraft/block/BlockCactus.java.patch new file mode 100644 index 000000000..20964fc4b --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockCactus.java.patch @@ -0,0 +1,66 @@ +--- original/net/minecraft/block/BlockCactus.java ++++ modified/net/minecraft/block/BlockCactus.java +@@ -19,7 +19,7 @@ + import net.minecraftforge.fml.relauncher.Side; + import net.minecraftforge.fml.relauncher.SideOnly; + +-public class BlockCactus extends Block { ++public class BlockCactus extends Block implements net.minecraftforge.common.IPlantable { + public static final PropertyInteger AGE = PropertyInteger.create("age", 0, 15); + protected static final AxisAlignedBB CACTUS_COLLISION_AABB = new AxisAlignedBB(0.0625, 0.0, 0.0625, 0.9375, 0.9375, 0.9375); + protected static final AxisAlignedBB CACTUS_AABB = new AxisAlignedBB(0.0625, 0.0, 0.0625, 0.9375, 1.0, 0.9375); +@@ -33,6 +33,7 @@ + + @Override + public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand) { ++ if (!worldIn.isAreaLoaded(pos, 1)) return; // Forge: prevent growing cactus from loading unloaded chunks with block update + BlockPos blockpos = pos.up(); + if (worldIn.isAirBlock(blockpos)) { + int i = 1; +@@ -43,6 +44,8 @@ + + if (i < 3) { + int j = state.getValue(AGE); ++ ++ if(net.minecraftforge.common.ForgeHooks.onCropsGrowPre(worldIn, blockpos, state, true)) { + if (j == 15) { + worldIn.setBlockState(blockpos, this.getDefaultState()); + IBlockState iblockstate = state.withProperty(AGE, 0); +@@ -51,6 +54,8 @@ + } else { + worldIn.setBlockState(pos, state.withProperty(AGE, j + 1), 4); + } ++ net.minecraftforge.common.ForgeHooks.onCropsGrowPost(worldIn, pos, state, worldIn.getBlockState(pos)); ++ } + } + } + } +@@ -108,9 +113,8 @@ + } + } + +- Block block = worldIn.getBlockState(pos.down()).getBlock(); +- return block == Blocks.CACTUS +- || block == Blocks.SAND && !worldIn.getBlockState(pos.up()).getMaterial().isLiquid(); ++ IBlockState state = worldIn.getBlockState(pos.down()); ++ return state.getBlock().canSustainPlant(state, worldIn, pos.down(), EnumFacing.UP, this) && !worldIn.getBlockState(pos.up()).getMaterial().isLiquid(); + } + + /** Called When an Entity Collided with the Block */ +@@ -139,6 +143,16 @@ + } + + @Override ++ public net.minecraftforge.common.EnumPlantType getPlantType(net.minecraft.world.IBlockAccess world, BlockPos pos) { ++ return net.minecraftforge.common.EnumPlantType.Desert; ++ } ++ ++ @Override ++ public IBlockState getPlant(net.minecraft.world.IBlockAccess world, BlockPos pos) { ++ return getDefaultState(); ++ } ++ ++ @Override + protected BlockStateContainer createBlockState() { + return new BlockStateContainer(this, AGE); + } diff --git a/module/minecraft/patches/net/minecraft/block/BlockChest.java.patch b/module/minecraft/patches/net/minecraft/block/BlockChest.java.patch new file mode 100644 index 000000000..0eddc328e --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockChest.java.patch @@ -0,0 +1,30 @@ +--- original/net/minecraft/block/BlockChest.java ++++ modified/net/minecraft/block/BlockChest.java +@@ -416,7 +416,7 @@ + BlockPos blockpos = pos.offset(enumfacing); + Block block = worldIn.getBlockState(blockpos).getBlock(); + if (block == this) { +- if (this.isBlocked(worldIn, blockpos)) { ++ if (!allowBlocking && this.isBlocked(worldIn, blockpos)) { // Forge: fix MC-99321 + return null; + } + +@@ -476,7 +476,7 @@ + } + + private boolean isBelowSolidBlock(World worldIn, BlockPos pos) { +- return worldIn.getBlockState(pos.up()).isNormalCube(); ++ return worldIn.getBlockState(pos.up()).doesSideBlockChestOpening(worldIn, pos.up(), EnumFacing.DOWN); + } + + private boolean isOcelotSittingOnChest(World worldIn, BlockPos pos) { +@@ -569,4 +569,9 @@ + BASIC, + TRAP; + } ++ ++ /* ======================================== FORGE START =====================================*/ ++ public boolean rotateBlock(World world, BlockPos pos, EnumFacing axis) { ++ return !isDoubleChest(world, pos) && super.rotateBlock(world, pos, axis); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/block/BlockChorusFlower.java.patch b/module/minecraft/patches/net/minecraft/block/BlockChorusFlower.java.patch new file mode 100644 index 000000000..a1dcecac0 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockChorusFlower.java.patch @@ -0,0 +1,28 @@ +--- original/net/minecraft/block/BlockChorusFlower.java ++++ modified/net/minecraft/block/BlockChorusFlower.java +@@ -4,6 +4,7 @@ + import javax.annotation.Nullable; + import net.minecraft.block.material.MapColor; + import net.minecraft.block.material.Material; ++import net.minecraft.block.properties.IProperty; + import net.minecraft.block.properties.PropertyInteger; + import net.minecraft.block.state.BlockFaceShape; + import net.minecraft.block.state.BlockStateContainer; +@@ -47,7 +48,8 @@ + BlockPos blockpos = pos.up(); + if (worldIn.isAirBlock(blockpos) && blockpos.getY() < 256) { + int i = state.getValue(AGE); +- if (i < 5 && rand.nextInt(1) == 0) { ++ ++ if (i < 5 && net.minecraftforge.common.ForgeHooks.onCropsGrowPre(worldIn, blockpos, state, rand.nextInt(1) == 0)) { + boolean flag = false; + boolean flag1 = false; + IBlockState iblockstate = worldIn.getBlockState(pos.down()); +@@ -110,6 +112,7 @@ + } else if (i == 4) { + this.placeDeadFlower(worldIn, pos); + } ++ net.minecraftforge.common.ForgeHooks.onCropsGrowPost(worldIn, pos, state, worldIn.getBlockState(pos)); + } + } + } diff --git a/module/minecraft/patches/net/minecraft/block/BlockCocoa.java.patch b/module/minecraft/patches/net/minecraft/block/BlockCocoa.java.patch new file mode 100644 index 000000000..4337c84b6 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockCocoa.java.patch @@ -0,0 +1,40 @@ +--- original/net/minecraft/block/BlockCocoa.java ++++ modified/net/minecraft/block/BlockCocoa.java +@@ -55,10 +55,12 @@ + public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand) { + if (!this.canBlockStay(worldIn, pos, state)) { + this.dropBlock(worldIn, pos, state); +- } else if (worldIn.rand.nextInt(5) == 0) { ++ } else { + int i = state.getValue(AGE); +- if (i < 2) { ++ ++ if (i < 2 && net.minecraftforge.common.ForgeHooks.onCropsGrowPre(worldIn, pos, state, rand.nextInt(5) == 0)) { + worldIn.setBlockState(pos, state.withProperty(AGE, i + 1), 2); ++ net.minecraftforge.common.ForgeHooks.onCropsGrowPost(worldIn, pos, state, worldIn.getBlockState(pos)); + } + } + } +@@ -161,14 +163,20 @@ + /** Spawns this Block's drops into the World as EntityItems. */ + @Override + public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, IBlockState state, float chance, int fortune) { +- int i = state.getValue(AGE); ++ super.dropBlockAsItemWithChance(worldIn, pos, state, chance, fortune); ++ } ++ ++ @Override ++ public void getDrops(net.minecraft.util.NonNullList drops, IBlockAccess world, BlockPos pos, IBlockState state, int fortune) { ++ super.getDrops(drops, world, pos, state, fortune); ++ int i = ((Integer)state.getValue(AGE)).intValue(); + int j = 1; + if (i >= 2) { + j = 3; + } + + for (int k = 0; k < j; k++) { +- spawnAsEntity(worldIn, pos, new ItemStack(Items.DYE, 1, EnumDyeColor.BROWN.getDyeDamage())); ++ drops.add(new ItemStack(Items.DYE, 1, EnumDyeColor.BROWN.getDyeDamage())); + } + } + diff --git a/module/minecraft/patches/net/minecraft/block/BlockCrops.java.patch b/module/minecraft/patches/net/minecraft/block/BlockCrops.java.patch new file mode 100644 index 000000000..d3e50a009 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockCrops.java.patch @@ -0,0 +1,74 @@ +--- original/net/minecraft/block/BlockCrops.java ++++ modified/net/minecraft/block/BlockCrops.java +@@ -71,12 +71,16 @@ + @Override + public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand) { + super.updateTick(worldIn, pos, state, rand); ++ ++ if (!worldIn.isAreaLoaded(pos, 1)) return; // Forge: prevent loading unloaded chunks when checking neighbor's light + if (worldIn.getLightFromNeighbors(pos.up()) >= 9) { + int i = this.getAge(state); + if (i < this.getMaxAge()) { + float f = getGrowthChance(this, worldIn, pos); +- if (rand.nextInt((int)(25.0F / f) + 1) == 0) { ++ ++ if(net.minecraftforge.common.ForgeHooks.onCropsGrowPre(worldIn, pos, state, rand.nextInt((int)(25.0F / f) + 1) == 0)) { + worldIn.setBlockState(pos, this.withAge(i + 1), 2); ++ net.minecraftforge.common.ForgeHooks.onCropsGrowPost(worldIn, pos, state, worldIn.getBlockState(pos)); + } + } + } +@@ -104,9 +108,11 @@ + for (int j = -1; j <= 1; j++) { + float f1 = 0.0F; + IBlockState iblockstate = worldIn.getBlockState(blockpos.add(i, 0, j)); +- if (iblockstate.getBlock() == Blocks.FARMLAND) { ++ ++ if (iblockstate.getBlock().canSustainPlant(iblockstate, worldIn, blockpos.add(i, 0, j), net.minecraft.util.EnumFacing.UP, (net.minecraftforge.common.IPlantable)blockIn)) { + f1 = 1.0F; +- if (iblockstate.getValue(BlockFarmland.MOISTURE) > 0) { ++ ++ if (iblockstate.getBlock().isFertile(worldIn, blockpos.add(i, 0, j))) { + f1 = 3.0F; + } + } +@@ -144,8 +150,8 @@ + + @Override + public boolean canBlockStay(World worldIn, BlockPos pos, IBlockState state) { +- return (worldIn.getLight(pos) >= 8 || worldIn.canSeeSky(pos)) +- && this.canSustainBush(worldIn.getBlockState(pos.down())); ++ IBlockState soil = worldIn.getBlockState(pos.down()); ++ return (worldIn.getLight(pos) >= 8 || worldIn.canSeeSky(pos)) && soil.getBlock().canSustainPlant(soil, worldIn, pos.down(), net.minecraft.util.EnumFacing.UP, this); + } + + protected Item getSeed() { +@@ -158,9 +164,26 @@ + + /** Spawns this Block's drops into the World as EntityItems. */ + @Override ++ public void getDrops(net.minecraft.util.NonNullList drops, net.minecraft.world.IBlockAccess world, BlockPos pos, IBlockState state, int fortune) { ++ super.getDrops(drops, world, pos, state, 0); ++ int age = getAge(state); ++ Random rand = world instanceof World ? ((World)world).rand : new Random(); ++ ++ if (age >= getMaxAge()) { ++ int k = 3 + fortune; ++ ++ for (int i = 0; i < 3 + fortune; ++i) { ++ if (rand.nextInt(2 * getMaxAge()) <= age) { ++ drops.add(new ItemStack(this.getSeed(), 1, 0)); ++ } ++ } ++ } ++ } ++ + public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, IBlockState state, float chance, int fortune) { +- super.dropBlockAsItemWithChance(worldIn, pos, state, chance, 0); +- if (!worldIn.isRemote) { ++ super.dropBlockAsItemWithChance(worldIn, pos, state, chance, fortune); ++ ++ if (false && !worldIn.isRemote) { // Forge: NOP all this. + int i = this.getAge(state); + if (i >= this.getMaxAge()) { + int j = 3 + fortune; diff --git a/module/minecraft/patches/net/minecraft/block/BlockDeadBush.java.patch b/module/minecraft/patches/net/minecraft/block/BlockDeadBush.java.patch new file mode 100644 index 000000000..c28a2cbb3 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockDeadBush.java.patch @@ -0,0 +1,26 @@ +--- original/net/minecraft/block/BlockDeadBush.java ++++ modified/net/minecraft/block/BlockDeadBush.java +@@ -17,7 +17,7 @@ + import net.minecraft.world.IBlockAccess; + import net.minecraft.world.World; + +-public class BlockDeadBush extends BlockBush { ++public class BlockDeadBush extends BlockBush implements net.minecraftforge.common.IShearable { + protected static final AxisAlignedBB DEAD_BUSH_AABB = new AxisAlignedBB(0.099999994F, 0.0, 0.099999994F, 0.9F, 0.8F, 0.9F); + + protected BlockDeadBush() { +@@ -78,4 +78,14 @@ + super.harvestBlock(worldIn, player, pos, state, te, stack); + } + } ++ ++ @Override ++ public boolean isShearable(ItemStack item, net.minecraft.world.IBlockAccess world, BlockPos pos) { ++ return true; ++ } ++ ++ @Override ++ public java.util.List onSheared(ItemStack item, net.minecraft.world.IBlockAccess world, BlockPos pos, int fortune) { ++ return java.util.List.of(new ItemStack(Blocks.DEADBUSH)); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/block/BlockDoor.java.patch b/module/minecraft/patches/net/minecraft/block/BlockDoor.java.patch new file mode 100644 index 000000000..4208556c3 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockDoor.java.patch @@ -0,0 +1,29 @@ +--- original/net/minecraft/block/BlockDoor.java ++++ modified/net/minecraft/block/BlockDoor.java +@@ -196,7 +196,7 @@ + flag1 = true; + } + +- if (!worldIn.getBlockState(pos.down()).isTopSolid()) { ++ if (!worldIn.getBlockState(pos.down()).isSideSolid(worldIn, pos.down(), EnumFacing.UP)) { + worldIn.setBlockToAir(pos); + flag1 = true; + if (iblockstate1.getBlock() == this) { +@@ -231,11 +231,12 @@ + /** Checks if this block can be placed exactly at the given position. */ + @Override + public boolean canPlaceBlockAt(World worldIn, BlockPos pos) { +- return pos.getY() >= 255 +- ? false +- : worldIn.getBlockState(pos.down()).isTopSolid() +- && super.canPlaceBlockAt(worldIn, pos) +- && super.canPlaceBlockAt(worldIn, pos.up()); ++ if (pos.getY() >= worldIn.getHeight() - 1) { ++ return false; ++ } else { ++ IBlockState state = worldIn.getBlockState(pos.down()); ++ return (state.isTopSolid() || state.getBlockFaceShape(worldIn, pos.down(), EnumFacing.UP) == BlockFaceShape.SOLID) && super.canPlaceBlockAt(worldIn, pos) && super.canPlaceBlockAt(worldIn, pos.up()); ++ } + } + + /** @deprecated call via {@link IBlockState#getMobilityFlag()} whenever possible. Implementing/overriding is fine. */ diff --git a/module/minecraft/patches/net/minecraft/block/BlockDoublePlant.java.patch b/module/minecraft/patches/net/minecraft/block/BlockDoublePlant.java.patch new file mode 100644 index 000000000..04fcec1d5 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockDoublePlant.java.patch @@ -0,0 +1,82 @@ +--- original/net/minecraft/block/BlockDoublePlant.java ++++ modified/net/minecraft/block/BlockDoublePlant.java +@@ -23,7 +23,7 @@ + import net.minecraft.world.IBlockAccess; + import net.minecraft.world.World; + +-public class BlockDoublePlant extends BlockBush implements IGrowable { ++public class BlockDoublePlant extends BlockBush implements IGrowable, net.minecraftforge.common.IShearable { + public static final PropertyEnum VARIANT = PropertyEnum.create( + "variant", BlockDoublePlant.EnumPlantType.class + ); +@@ -85,21 +85,22 @@ + BlockPos blockpos1 = flag ? pos.down() : pos; + Block block = flag ? this : worldIn.getBlockState(blockpos).getBlock(); + Block block1 = flag ? worldIn.getBlockState(blockpos1).getBlock() : this; ++ ++ if (!flag) this.dropBlockAsItem(worldIn, pos, state, 0); //Forge move above the setting to air. ++ + if (block == this) { + worldIn.setBlockState(blockpos, Blocks.AIR.getDefaultState(), 2); + } + + if (block1 == this) { + worldIn.setBlockState(blockpos1, Blocks.AIR.getDefaultState(), 3); +- if (!flag) { +- this.dropBlockAsItem(worldIn, blockpos1, state, 0); +- } + } + } + } + + @Override + public boolean canBlockStay(World worldIn, BlockPos pos, IBlockState state) { ++ if (state.getBlock() != this) return super.canBlockStay(worldIn, pos, state); //Forge: This function is called during world gen and placement, before this block is set, so if we are not 'here' then assume it's the pre-check. + if (state.getValue(HALF) == BlockDoublePlant.EnumBlockHalf.UPPER) { + return worldIn.getBlockState(pos.down()).getBlock() == this; + } +@@ -156,10 +157,7 @@ + public void harvestBlock( + World worldIn, EntityPlayer player, BlockPos pos, IBlockState state, @Nullable TileEntity te, ItemStack stack + ) { +- if (worldIn.isRemote +- || stack.getItem() != Items.SHEARS +- || state.getValue(HALF) != BlockDoublePlant.EnumBlockHalf.LOWER +- || !this.onHarvest(worldIn, pos, state, player)) { ++ { + super.harvestBlock(worldIn, player, pos, state, te, stack); + } + } +@@ -201,9 +199,6 @@ + } + + player.addStat(StatList.getBlockStats(this)); +- int i = (blockdoubleplant$enumplanttype == BlockDoublePlant.EnumPlantType.GRASS ? BlockTallGrass.EnumType.GRASS : BlockTallGrass.EnumType.FERN) +- .getMeta(); +- spawnAsEntity(worldIn, pos, new ItemStack(Blocks.TALLGRASS, 2, i)); + return true; + } + +@@ -279,6 +274,22 @@ + return Block.EnumOffsetType.XZ; + } + ++ @Override ++ public boolean isShearable(ItemStack item, IBlockAccess world, BlockPos pos) { ++ IBlockState state = world.getBlockState(pos); ++ EnumPlantType type = state.getValue(VARIANT); ++ return state.getValue(HALF) == EnumBlockHalf.LOWER && (type == EnumPlantType.FERN || type == EnumPlantType.GRASS); ++ } ++ ++ @Override ++ public java.util.List onSheared(ItemStack item, net.minecraft.world.IBlockAccess world, BlockPos pos, int fortune) { ++ java.util.List ret = new java.util.ArrayList(); ++ EnumPlantType type = world.getBlockState(pos).getValue(VARIANT); ++ if (type == EnumPlantType.FERN) ret.add(new ItemStack(Blocks.TALLGRASS, 2, BlockTallGrass.EnumType.FERN.getMeta())); ++ if (type == EnumPlantType.GRASS) ret.add(new ItemStack(Blocks.TALLGRASS, 2, BlockTallGrass.EnumType.GRASS.getMeta())); ++ return ret; ++ } ++ + public enum EnumBlockHalf implements IStringSerializable { + UPPER, + LOWER; diff --git a/module/minecraft/patches/net/minecraft/block/BlockDragonEgg.java.patch b/module/minecraft/patches/net/minecraft/block/BlockDragonEgg.java.patch new file mode 100644 index 000000000..d86fe989a --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockDragonEgg.java.patch @@ -0,0 +1,38 @@ +--- original/net/minecraft/block/BlockDragonEgg.java ++++ modified/net/minecraft/block/BlockDragonEgg.java +@@ -48,7 +48,7 @@ + } + + private void checkFall(World worldIn, BlockPos pos) { +- if (BlockFalling.canFallThrough(worldIn.getBlockState(pos.down())) && pos.getY() >= 0) { ++ if (worldIn.isAirBlock(pos.down()) && BlockFalling.canFallThrough(worldIn.getBlockState(pos.down())) && pos.getY() >= 0) { + int i = 32; + if (!BlockFalling.fallInstantly && worldIn.isAreaLoaded(pos.add(-32, -32, -32), pos.add(32, 32, 32))) { + worldIn.spawnEntity( +@@ -60,7 +60,7 @@ + worldIn.setBlockToAir(pos); + BlockPos blockpos = pos; + +- while (BlockFalling.canFallThrough(worldIn.getBlockState(blockpos)) && blockpos.getY() > 0) { ++ while (worldIn.isAirBlock(blockpos) && BlockFalling.canFallThrough(worldIn.getBlockState(blockpos)) && blockpos.getY() > 0) { + blockpos = blockpos.down(); + } + +@@ -98,11 +98,12 @@ + if (iblockstate.getBlock() == this) { + for (int i = 0; i < 1000; i++) { + BlockPos blockpos = pos.add( +- worldIn.rand.nextInt(16) - worldIn.rand.nextInt(16), +- worldIn.rand.nextInt(8) - worldIn.rand.nextInt(8), +- worldIn.rand.nextInt(16) - worldIn.rand.nextInt(16) +- ); +- if (worldIn.getBlockState(blockpos).getBlock().material == Material.AIR) { ++ worldIn.rand.nextInt(16) - worldIn.rand.nextInt(16), ++ worldIn.rand.nextInt(8) - worldIn.rand.nextInt(8), ++ worldIn.rand.nextInt(16) - worldIn.rand.nextInt(16) ++ ); ++ ++ if (worldIn.isAirBlock(blockpos)) { + if (worldIn.isRemote) { + for (int j = 0; j < 128; j++) { + double d0 = worldIn.rand.nextDouble(); diff --git a/module/minecraft/patches/net/minecraft/block/BlockDropper.java.patch b/module/minecraft/patches/net/minecraft/block/BlockDropper.java.patch new file mode 100644 index 000000000..9f1e2a237 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockDropper.java.patch @@ -0,0 +1,12 @@ +--- original/net/minecraft/block/BlockDropper.java ++++ modified/net/minecraft/block/BlockDropper.java +@@ -36,7 +36,8 @@ + worldIn.playEvent(1001, pos, 0); + } else { + ItemStack itemstack = tileentitydispenser.getStackInSlot(i); +- if (!itemstack.isEmpty()) { ++ ++ if (!itemstack.isEmpty() && net.minecraftforge.items.VanillaInventoryCodeHooks.dropperInsertHook(worldIn, pos, tileentitydispenser, i, itemstack)) { + EnumFacing enumfacing = worldIn.getBlockState(pos).getValue(FACING); + BlockPos blockpos = pos.offset(enumfacing); + IInventory iinventory = TileEntityHopper.getInventoryAtPosition( diff --git a/module/minecraft/patches/net/minecraft/block/BlockDynamicLiquid.java.patch b/module/minecraft/patches/net/minecraft/block/BlockDynamicLiquid.java.patch new file mode 100644 index 000000000..779de0b0a --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockDynamicLiquid.java.patch @@ -0,0 +1,67 @@ +--- original/net/minecraft/block/BlockDynamicLiquid.java ++++ modified/net/minecraft/block/BlockDynamicLiquid.java +@@ -25,6 +25,7 @@ + + @Override + public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand) { ++ if (!worldIn.isAreaLoaded(pos, this.getSlopeFindDistance(worldIn))) return; // Forge: avoid loading unloaded chunks + int i = state.getValue(LEVEL); + int j = 1; + if (this.material == Material.LAVA && !worldIn.provider.doesWaterVaporize()) { +@@ -54,7 +55,7 @@ + } + } + +- if (this.adjacentSourceBlocks >= 2 && this.material == Material.WATER) { ++ if (this.adjacentSourceBlocks >= 2 && net.minecraftforge.event.ForgeEventFactory.canCreateFluidSource(worldIn, pos, state, this.material == Material.WATER)) { + IBlockState iblockstate = worldIn.getBlockState(pos.down()); + if (iblockstate.getMaterial().isSolid()) { + i1 = 0; +@@ -87,8 +88,8 @@ + IBlockState iblockstate1 = worldIn.getBlockState(pos.down()); + if (this.canFlowInto(worldIn, pos.down(), iblockstate1)) { + if (this.material == Material.LAVA +- && worldIn.getBlockState(pos.down()).getMaterial() == Material.WATER) { +- worldIn.setBlockState(pos.down(), Blocks.STONE.getDefaultState()); ++ && worldIn.getBlockState(pos.down()).getMaterial() == Material.WATER) { ++ worldIn.setBlockState(pos.down(), net.minecraftforge.event.ForgeEventFactory.fireFluidPlaceBlockEvent(worldIn, pos.down(), pos, Blocks.STONE.getDefaultState())); + this.triggerMixEffects(worldIn, pos.down()); + return; + } +@@ -121,6 +122,7 @@ + if (this.material == Material.LAVA) { + this.triggerMixEffects(worldIn, pos); + } else { ++ if (state.getBlock() != Blocks.SNOW_LAYER) //Forge: Vanilla has a 'bug' where snowballs don't drop like every other block. So special case because ewww... + state.getBlock().dropBlockAsItem(worldIn, pos, state, 0); + } + } +@@ -137,8 +139,8 @@ + BlockPos blockpos = pos.offset(enumfacing); + IBlockState iblockstate = worldIn.getBlockState(blockpos); + if (!this.isBlocked(worldIn, blockpos, iblockstate) +- && (iblockstate.getMaterial() != this.material || iblockstate.getValue(LEVEL) > 0)) { +- if (!this.isBlocked(worldIn, blockpos.down(), iblockstate)) { ++ && (iblockstate.getMaterial() != this.material || iblockstate.getValue(LEVEL) > 0)) { ++ if (!this.isBlocked(worldIn, blockpos.down(), worldIn.getBlockState(blockpos.down()))) { + return distance; + } + +@@ -191,13 +193,13 @@ + } + + private boolean isBlocked(World worldIn, BlockPos pos, IBlockState state) { +- Block block = worldIn.getBlockState(pos).getBlock(); ++ Block block = state.getBlock(); //Forge: state must be valid for position ++ Material mat = state.getMaterial(); ++ + if (block instanceof BlockDoor || block == Blocks.STANDING_SIGN || block == Blocks.LADDER || block == Blocks.REEDS) { + return true; + } else { +- return block.material != Material.PORTAL && block.material != Material.STRUCTURE_VOID +- ? block.material.blocksMovement() +- : true; ++ return mat != Material.PORTAL && mat != Material.STRUCTURE_VOID ? mat.blocksMovement() : true; + } + } + diff --git a/module/minecraft/patches/net/minecraft/block/BlockEnchantmentTable.java.patch b/module/minecraft/patches/net/minecraft/block/BlockEnchantmentTable.java.patch new file mode 100644 index 000000000..3014cdebc --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockEnchantmentTable.java.patch @@ -0,0 +1,12 @@ +--- original/net/minecraft/block/BlockEnchantmentTable.java ++++ modified/net/minecraft/block/BlockEnchantmentTable.java +@@ -59,7 +59,8 @@ + if (rand.nextInt(16) == 0) { + for (int k = 0; k <= 1; k++) { + BlockPos blockpos = pos.add(i, k, j); +- if (worldIn.getBlockState(blockpos).getBlock() == Blocks.BOOKSHELF) { ++ ++ if (net.minecraftforge.common.ForgeHooks.getEnchantPower(worldIn, blockpos) > 0) { + if (!worldIn.isAirBlock(pos.add(i / 2, 0, j / 2))) { + break; + } diff --git a/module/minecraft/patches/net/minecraft/block/BlockEnderChest.java.patch b/module/minecraft/patches/net/minecraft/block/BlockEnderChest.java.patch new file mode 100644 index 000000000..95f379516 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockEnderChest.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/block/BlockEnderChest.java ++++ modified/net/minecraft/block/BlockEnderChest.java +@@ -133,7 +133,7 @@ + return true; + } + +- if (worldIn.getBlockState(pos.up()).isNormalCube()) { ++ if (worldIn.getBlockState(pos.up()).doesSideBlockChestOpening(worldIn, pos.up(), EnumFacing.DOWN)) { + return true; + } + diff --git a/module/minecraft/patches/net/minecraft/block/BlockFalling.java.patch b/module/minecraft/patches/net/minecraft/block/BlockFalling.java.patch new file mode 100644 index 000000000..6d9767daf --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockFalling.java.patch @@ -0,0 +1,25 @@ +--- original/net/minecraft/block/BlockFalling.java ++++ modified/net/minecraft/block/BlockFalling.java +@@ -44,18 +44,19 @@ + } + + private void checkFallable(World worldIn, BlockPos pos) { +- if (canFallThrough(worldIn.getBlockState(pos.down())) && pos.getY() >= 0) { ++ if ((worldIn.isAirBlock(pos.down()) || canFallThrough(worldIn.getBlockState(pos.down()))) && pos.getY() >= 0) { + int i = 32; + if (fallInstantly || !worldIn.isAreaLoaded(pos.add(-32, -32, -32), pos.add(32, 32, 32))) { ++ IBlockState state = worldIn.getBlockState(pos); + worldIn.setBlockToAir(pos); + BlockPos blockpos = pos.down(); + +- while (canFallThrough(worldIn.getBlockState(blockpos)) && blockpos.getY() > 0) { ++ while ((worldIn.isAirBlock(blockpos) || canFallThrough(worldIn.getBlockState(blockpos))) && blockpos.getY() > 0) { + blockpos = blockpos.down(); + } + + if (blockpos.getY() > 0) { +- worldIn.setBlockState(blockpos.up(), this.getDefaultState()); ++ worldIn.setBlockState(blockpos.up(), state); //Forge: Fix loss of state information during world gen. + } + } else if (!worldIn.isRemote) { + EntityFallingBlock entityfallingblock = new EntityFallingBlock( diff --git a/module/minecraft/patches/net/minecraft/block/BlockFarmland.java.patch b/module/minecraft/patches/net/minecraft/block/BlockFarmland.java.patch new file mode 100644 index 000000000..1008e773d --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockFarmland.java.patch @@ -0,0 +1,33 @@ +--- original/net/minecraft/block/BlockFarmland.java ++++ modified/net/minecraft/block/BlockFarmland.java +@@ -69,11 +69,7 @@ + /** Block's chance to react to a living entity falling on it. */ + @Override + public void onFallenUpon(World worldIn, BlockPos pos, Entity entityIn, float fallDistance) { +- if (!worldIn.isRemote +- && worldIn.rand.nextFloat() < fallDistance - 0.5F +- && entityIn instanceof EntityLivingBase +- && (entityIn instanceof EntityPlayer || worldIn.getGameRules().getBoolean("mobGriefing")) +- && entityIn.width * entityIn.width * entityIn.height > 0.512F) { ++ if (net.minecraftforge.common.ForgeHooks.onFarmlandTrample(worldIn, pos, Blocks.DIRT.getDefaultState(), fallDistance, entityIn)) { // Forge: Move logic to Entity#canTrample + turnToDirt(worldIn, pos); + } + +@@ -92,7 +88,7 @@ + + private boolean hasCrops(World worldIn, BlockPos pos) { + Block block = worldIn.getBlockState(pos.up()).getBlock(); +- return block instanceof BlockCrops || block instanceof BlockStem; ++ return block instanceof net.minecraftforge.common.IPlantable && canSustainPlant(worldIn.getBlockState(pos), worldIn, pos, net.minecraft.util.EnumFacing.UP, (net.minecraftforge.common.IPlantable)block); + } + + private boolean hasWater(World worldIn, BlockPos pos) { +@@ -104,7 +100,7 @@ + } + } + +- return false; ++ return net.minecraftforge.common.FarmlandWaterManager.hasBlockWaterTicket(worldIn, pos); + } + + /** Called when a neighboring block was changed and marks that this state should perform any checks during a neighbor change. Cases may include when redstone power is updated, cactus blocks popping off due to a neighboring solid block, etc. */ diff --git a/module/minecraft/patches/net/minecraft/block/BlockFence.java.patch b/module/minecraft/patches/net/minecraft/block/BlockFence.java.patch new file mode 100644 index 000000000..e7ee1e56f --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockFence.java.patch @@ -0,0 +1,48 @@ +--- original/net/minecraft/block/BlockFence.java ++++ modified/net/minecraft/block/BlockFence.java +@@ -207,10 +207,10 @@ + /** Get the actual Block state of this Block at the given position. This applies properties not visible in the metadata, such as fence connections. */ + @Override + public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos) { +- return state.withProperty(NORTH, this.canConnectTo(worldIn, pos.north(), EnumFacing.SOUTH)) +- .withProperty(EAST, this.canConnectTo(worldIn, pos.east(), EnumFacing.WEST)) +- .withProperty(SOUTH, this.canConnectTo(worldIn, pos.south(), EnumFacing.NORTH)) +- .withProperty(WEST, this.canConnectTo(worldIn, pos.west(), EnumFacing.EAST)); ++ return state.withProperty(NORTH, canFenceConnectTo(worldIn, pos, EnumFacing.NORTH)) ++ .withProperty(EAST, canFenceConnectTo(worldIn, pos, EnumFacing.EAST)) ++ .withProperty(SOUTH, canFenceConnectTo(worldIn, pos, EnumFacing.SOUTH)) ++ .withProperty(WEST, canFenceConnectTo(worldIn, pos, EnumFacing.WEST)); + } + + /** +@@ -263,15 +263,22 @@ + return new BlockStateContainer(this, NORTH, EAST, WEST, SOUTH); + } + +- /** +- * Get the geometry of the queried face at the given position and state. This is used to decide whether things like buttons are allowed to be placed on the face, or how glass panes connect to the face, among other things. +- *

+- * Common values are {@code SOLID}, which is the default, and {@code UNDEFINED}, which represents something that does not fit the other descriptions and will generally cause other things not to connect to the face. +- * +- * @return an approximation of the form of the given face +- * @deprecated call via {@link IBlockState#getBlockFaceShape(IBlockAccess,BlockPos,EnumFacing)} whenever possible. Implementing/overriding is fine. +- */ ++ /* ======================================== FORGE START ======================================== */ ++ + @Override ++ public boolean canBeConnectedTo(IBlockAccess world, BlockPos pos, EnumFacing facing) { ++ return canConnectTo(world, pos.offset(facing), facing.getOpposite()); ++ } ++ ++ private boolean canFenceConnectTo(IBlockAccess world, BlockPos pos, EnumFacing facing) { ++ BlockPos other = pos.offset(facing); ++ Block block = world.getBlockState(other).getBlock(); ++ return block.canBeConnectedTo(world, other, facing.getOpposite()) || canConnectTo(world, other, facing.getOpposite()); ++ } ++ ++ /* ======================================== FORGE END ======================================== */ ++ ++ @Override + public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face) { + return face != EnumFacing.UP && face != EnumFacing.DOWN ? BlockFaceShape.MIDDLE_POLE : BlockFaceShape.CENTER; + } diff --git a/module/minecraft/patches/net/minecraft/block/BlockFenceGate.java.patch b/module/minecraft/patches/net/minecraft/block/BlockFenceGate.java.patch new file mode 100644 index 000000000..d153eb79b --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockFenceGate.java.patch @@ -0,0 +1,51 @@ +--- original/net/minecraft/block/BlockFenceGate.java ++++ modified/net/minecraft/block/BlockFenceGate.java +@@ -57,13 +57,13 @@ + EnumFacing.Axis enumfacing$axis = state.getValue(FACING).getAxis(); + if (enumfacing$axis == EnumFacing.Axis.Z + && ( +- worldIn.getBlockState(pos.west()).getBlock() == Blocks.COBBLESTONE_WALL +- || worldIn.getBlockState(pos.east()).getBlock() == Blocks.COBBLESTONE_WALL ++ worldIn.getBlockState(pos.west()).getBlock() instanceof BlockWall ++ || worldIn.getBlockState(pos.east()).getBlock() instanceof BlockWall + ) + || enumfacing$axis == EnumFacing.Axis.X + && ( +- worldIn.getBlockState(pos.north()).getBlock() == Blocks.COBBLESTONE_WALL +- || worldIn.getBlockState(pos.south()).getBlock() == Blocks.COBBLESTONE_WALL ++ worldIn.getBlockState(pos.north()).getBlock() instanceof BlockWall ++ || worldIn.getBlockState(pos.south()).getBlock() instanceof BlockWall + )) { + state = state.withProperty(IN_WALL, true); + } +@@ -228,15 +228,22 @@ + return new BlockStateContainer(this, FACING, OPEN, POWERED, IN_WALL); + } + +- /** +- * Get the geometry of the queried face at the given position and state. This is used to decide whether things like buttons are allowed to be placed on the face, or how glass panes connect to the face, among other things. +- *

+- * Common values are {@code SOLID}, which is the default, and {@code UNDEFINED}, which represents something that does not fit the other descriptions and will generally cause other things not to connect to the face. +- * +- * @return an approximation of the form of the given face +- * @deprecated call via {@link IBlockState#getBlockFaceShape(IBlockAccess,BlockPos,EnumFacing)} whenever possible. Implementing/overriding is fine. +- */ ++ /* ======================================== FORGE START ======================================== */ ++ + @Override ++ public boolean canBeConnectedTo(IBlockAccess world, BlockPos pos, EnumFacing facing) { ++ IBlockState state = world.getBlockState(pos); ++ if (state.getBlock() instanceof BlockFenceGate && ++ state.getBlockFaceShape(world, pos, facing) == BlockFaceShape.MIDDLE_POLE) { ++ Block connector = world.getBlockState(pos.offset(facing)).getBlock(); ++ return connector instanceof BlockFence || connector instanceof BlockWall; ++ } ++ return false; ++ } ++ ++ /* ======================================== FORGE END ======================================== */ ++ ++ @Override + public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face) { + if (face != EnumFacing.UP && face != EnumFacing.DOWN) { + return state.getValue(FACING).getAxis() == face.rotateY().getAxis() diff --git a/module/minecraft/patches/net/minecraft/block/BlockFire.java.patch b/module/minecraft/patches/net/minecraft/block/BlockFire.java.patch new file mode 100644 index 000000000..1442b180a --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockFire.java.patch @@ -0,0 +1,221 @@ +--- original/net/minecraft/block/BlockFire.java ++++ modified/net/minecraft/block/BlockFire.java +@@ -38,14 +38,14 @@ + /** Get the actual Block state of this Block at the given position. This applies properties not visible in the metadata, such as fence connections. */ + @Override + public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos) { +- return !worldIn.getBlockState(pos.down()).isTopSolid() +- && !Blocks.FIRE.canCatchFire(worldIn, pos.down()) +- ? state.withProperty(NORTH, this.canCatchFire(worldIn, pos.north())) +- .withProperty(EAST, this.canCatchFire(worldIn, pos.east())) +- .withProperty(SOUTH, this.canCatchFire(worldIn, pos.south())) +- .withProperty(WEST, this.canCatchFire(worldIn, pos.west())) +- .withProperty(UPPER, this.canCatchFire(worldIn, pos.up())) +- : this.getDefaultState(); ++ return !worldIn.getBlockState(pos.down()).isSideSolid(worldIn, pos.down(), EnumFacing.UP) ++ && !Blocks.FIRE.canCatchFire(worldIn, pos.down(), EnumFacing.UP) ++ ? state.withProperty(NORTH, this.canCatchFire(worldIn, pos.north(), EnumFacing.SOUTH)) ++ .withProperty(EAST, this.canCatchFire(worldIn, pos.east(), EnumFacing.WEST)) ++ .withProperty(SOUTH, this.canCatchFire(worldIn, pos.south(), EnumFacing.NORTH)) ++ .withProperty(WEST, this.canCatchFire(worldIn, pos.west(), EnumFacing.EAST)) ++ .withProperty(UPPER, this.canCatchFire(worldIn, pos.up(), EnumFacing.DOWN)) ++ : this.getDefaultState(); + } + + protected BlockFire() { +@@ -104,6 +104,7 @@ + } + + public void setFireInfo(Block blockIn, int encouragement, int flammability) { ++ if (blockIn == Blocks.AIR) throw new IllegalArgumentException("Tried to set air on fire... This is bad."); + this.encouragements.put(blockIn, encouragement); + this.flammabilities.put(blockIn, flammability); + } +@@ -145,15 +146,13 @@ + @Override + public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand) { + if (worldIn.getGameRules().getBoolean("doFireTick")) { ++ if (!worldIn.isAreaLoaded(pos, 2)) return; // Forge: prevent loading unloaded chunks when spreading fire + if (!this.canPlaceBlockAt(worldIn, pos)) { + worldIn.setBlockToAir(pos); + } + + Block block = worldIn.getBlockState(pos.down()).getBlock(); +- boolean flag = block == Blocks.NETHERRACK || block == Blocks.MAGMA; +- if (worldIn.provider instanceof WorldProviderEnd && block == Blocks.BEDROCK) { +- flag = true; +- } ++ boolean flag = block.isFireSource(worldIn, pos.down(), EnumFacing.UP); + + int i = state.getValue(AGE); + if (!flag && worldIn.isRaining() && this.canDie(worldIn, pos) && rand.nextFloat() < 0.2F + i * 0.03F) { +@@ -167,14 +166,14 @@ + worldIn.scheduleUpdate(pos, this, this.tickRate(worldIn) + rand.nextInt(10)); + if (!flag) { + if (!this.canNeighborCatchFire(worldIn, pos)) { +- if (!worldIn.getBlockState(pos.down()).isTopSolid() || i > 3) { ++ if (!worldIn.getBlockState(pos.down()).isSideSolid(worldIn, pos.down(), EnumFacing.UP) || i > 3) { + worldIn.setBlockToAir(pos); + } + + return; + } + +- if (!this.canCatchFire(worldIn, pos.down()) && i == 15 && rand.nextInt(4) == 0) { ++ if (!this.canCatchFire(worldIn, pos.down(), EnumFacing.UP) && i == 15 && rand.nextInt(4) == 0) { + worldIn.setBlockToAir(pos); + return; + } +@@ -186,12 +185,12 @@ + j = -50; + } + +- this.catchOnFire(worldIn, pos.east(), 300 + j, rand, i); +- this.catchOnFire(worldIn, pos.west(), 300 + j, rand, i); +- this.catchOnFire(worldIn, pos.down(), 250 + j, rand, i); +- this.catchOnFire(worldIn, pos.up(), 250 + j, rand, i); +- this.catchOnFire(worldIn, pos.north(), 300 + j, rand, i); +- this.catchOnFire(worldIn, pos.south(), 300 + j, rand, i); ++ this.tryCatchFire(worldIn, pos.east(), 300 + j, rand, i, EnumFacing.WEST); ++ this.tryCatchFire(worldIn, pos.west(), 300 + j, rand, i, EnumFacing.EAST); ++ this.tryCatchFire(worldIn, pos.down(), 250 + j, rand, i, EnumFacing.UP); ++ this.tryCatchFire(worldIn, pos.up(), 250 + j, rand, i, EnumFacing.DOWN); ++ this.tryCatchFire(worldIn, pos.north(), 300 + j, rand, i, EnumFacing.SOUTH); ++ this.tryCatchFire(worldIn, pos.south(), 300 + j, rand, i, EnumFacing.NORTH); + + for (int k = -1; k <= 1; k++) { + for (int l = -1; l <= 1; l++) { +@@ -240,18 +239,26 @@ + return false; + } + ++ @Deprecated // Use Block.getFlammability + public int getFlammability(Block blockIn) { + Integer integer = this.flammabilities.get(blockIn); + return integer == null ? 0 : integer; + } + ++ @Deprecated // Use Block.getFireSpreadSpeed + public int getEncouragement(Block blockIn) { + Integer integer = this.encouragements.get(blockIn); + return integer == null ? 0 : integer; + } + ++ @Deprecated // Use tryCatchFire with face below + private void catchOnFire(World worldIn, BlockPos pos, int chance, Random random, int age) { +- int i = this.getFlammability(worldIn.getBlockState(pos).getBlock()); ++ this.tryCatchFire(worldIn, pos, chance, random, age, EnumFacing.UP); ++ } ++ ++ private void tryCatchFire(World worldIn, BlockPos pos, int chance, Random random, int age, EnumFacing face) { ++ int i = worldIn.getBlockState(pos).getBlock().getFlammability(worldIn, pos, face); ++ + if (random.nextInt(chance) < i) { + IBlockState iblockstate = worldIn.getBlockState(pos); + if (random.nextInt(age + 10) < 5 && !worldIn.isRainingAt(pos)) { +@@ -273,7 +280,7 @@ + + private boolean canNeighborCatchFire(World worldIn, BlockPos pos) { + for (EnumFacing enumfacing : EnumFacing.values()) { +- if (this.canCatchFire(worldIn, pos.offset(enumfacing))) { ++ if (this.canCatchFire(worldIn, pos.offset(enumfacing), enumfacing.getOpposite())) { + return true; + } + } +@@ -289,7 +296,7 @@ + int i = 0; + + for (EnumFacing enumfacing : EnumFacing.values()) { +- i = Math.max(this.getEncouragement(worldIn.getBlockState(pos.offset(enumfacing)).getBlock()), i); ++ i = Math.max(worldIn.getBlockState(pos.offset(enumfacing)).getBlock().getFireSpreadSpeed(worldIn, pos.offset(enumfacing), enumfacing.getOpposite()), i); + } + + return i; +@@ -301,9 +308,9 @@ + return false; + } + +- /** Checks if the block can be caught on fire */ ++ @Deprecated // Use canCatchFire with face sensitive version below + public boolean canCatchFire(IBlockAccess worldIn, BlockPos pos) { +- return this.getEncouragement(worldIn.getBlockState(pos).getBlock()) > 0; ++ return canCatchFire(worldIn, pos, EnumFacing.UP); + } + + /** Checks if this block can be placed exactly at the given position. */ +@@ -349,9 +356,9 @@ + ); + } + +- if (!worldIn.getBlockState(pos.down()).isTopSolid() +- && !Blocks.FIRE.canCatchFire(worldIn, pos.down())) { +- if (Blocks.FIRE.canCatchFire(worldIn, pos.west())) { ++ if (!worldIn.getBlockState(pos.down()).isSideSolid(worldIn, pos.down(), EnumFacing.UP) ++ && !Blocks.FIRE.canCatchFire(worldIn, pos.down(), EnumFacing.UP)) { ++ if (Blocks.FIRE.canCatchFire(worldIn, pos.west(), EnumFacing.EAST)) { + for (int j = 0; j < 2; j++) { + double d3 = pos.getX() + rand.nextDouble() * 0.1F; + double d8 = pos.getY() + rand.nextDouble(); +@@ -360,7 +367,7 @@ + } + } + +- if (Blocks.FIRE.canCatchFire(worldIn, pos.east())) { ++ if (Blocks.FIRE.canCatchFire(worldIn, pos.east(), EnumFacing.WEST)) { + for (int k = 0; k < 2; k++) { + double d4 = pos.getX() + 1 - rand.nextDouble() * 0.1F; + double d9 = pos.getY() + rand.nextDouble(); +@@ -369,7 +376,7 @@ + } + } + +- if (Blocks.FIRE.canCatchFire(worldIn, pos.north())) { ++ if (Blocks.FIRE.canCatchFire(worldIn, pos.north(), EnumFacing.SOUTH)) { + for (int l = 0; l < 2; l++) { + double d5 = pos.getX() + rand.nextDouble(); + double d10 = pos.getY() + rand.nextDouble(); +@@ -378,7 +385,7 @@ + } + } + +- if (Blocks.FIRE.canCatchFire(worldIn, pos.south())) { ++ if (Blocks.FIRE.canCatchFire(worldIn, pos.south(), EnumFacing.NORTH)) { + for (int i1 = 0; i1 < 2; i1++) { + double d6 = pos.getX() + rand.nextDouble(); + double d11 = pos.getY() + rand.nextDouble(); +@@ -387,7 +394,7 @@ + } + } + +- if (Blocks.FIRE.canCatchFire(worldIn, pos.up())) { ++ if (Blocks.FIRE.canCatchFire(worldIn, pos.up(), EnumFacing.DOWN)) { + for (int j1 = 0; j1 < 2; j1++) { + double d7 = pos.getX() + rand.nextDouble(); + double d12 = pos.getY() + 1 - rand.nextDouble() * 0.1F; +@@ -438,14 +445,20 @@ + return new BlockStateContainer(this, AGE, NORTH, EAST, SOUTH, WEST, UPPER); + } + ++ /*================================= Forge Start ======================================*/ + /** +- * Get the geometry of the queried face at the given position and state. This is used to decide whether things like buttons are allowed to be placed on the face, or how glass panes connect to the face, among other things. +- *

+- * Common values are {@code SOLID}, which is the default, and {@code UNDEFINED}, which represents something that does not fit the other descriptions and will generally cause other things not to connect to the face. +- * +- * @return an approximation of the form of the given face +- * @deprecated call via {@link IBlockState#getBlockFaceShape(IBlockAccess,BlockPos,EnumFacing)} whenever possible. Implementing/overriding is fine. ++ * Side sensitive version that calls the block function. ++ * ++ * @param world The current world ++ * @param pos Block position ++ * @param face The side the fire is coming from ++ * @return True if the face can catch fire. + */ ++ public boolean canCatchFire(IBlockAccess world, BlockPos pos, EnumFacing face) { ++ return world.getBlockState(pos).getBlock().isFlammable(world, pos, face); ++ } ++ /*================================= Forge Start ======================================*/ ++ + @Override + public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face) { + return BlockFaceShape.UNDEFINED; diff --git a/module/minecraft/patches/net/minecraft/block/BlockFlowerPot.java.patch b/module/minecraft/patches/net/minecraft/block/BlockFlowerPot.java.patch new file mode 100644 index 000000000..ec7b01d24 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockFlowerPot.java.patch @@ -0,0 +1,61 @@ +--- original/net/minecraft/block/BlockFlowerPot.java ++++ modified/net/minecraft/block/BlockFlowerPot.java +@@ -157,13 +157,15 @@ + /** Checks if this block can be placed exactly at the given position. */ + @Override + public boolean canPlaceBlockAt(World worldIn, BlockPos pos) { +- return super.canPlaceBlockAt(worldIn, pos) && worldIn.getBlockState(pos.down()).isTopSolid(); ++ IBlockState downState = worldIn.getBlockState(pos.down()); ++ return super.canPlaceBlockAt(worldIn, pos) && (downState.isTopSolid() || downState.getBlockFaceShape(worldIn, pos.down(), EnumFacing.UP) == BlockFaceShape.SOLID); + } + + /** Called when a neighboring block was changed and marks that this state should perform any checks during a neighbor change. Cases may include when redstone power is updated, cactus blocks popping off due to a neighboring solid block, etc. */ + @Override + public void neighborChanged(IBlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos) { +- if (!worldIn.getBlockState(pos.down()).isTopSolid()) { ++ IBlockState downState = worldIn.getBlockState(pos.down()); ++ if (!downState.isTopSolid() && downState.getBlockFaceShape(worldIn, pos.down(), EnumFacing.UP) != BlockFaceShape.SOLID) { + this.dropBlockAsItem(worldIn, pos, state, 0); + worldIn.setBlockToAir(pos); + } +@@ -172,11 +174,6 @@ + /** Called serverside after this block is replaced with another in Chunk, but before the Tile Entity is updated */ + @Override + public void breakBlock(World worldIn, BlockPos pos, IBlockState state) { +- TileEntityFlowerPot tileentityflowerpot = this.getTileEntity(worldIn, pos); +- if (tileentityflowerpot != null && tileentityflowerpot.getFlowerPotItem() != null) { +- spawnAsEntity(worldIn, pos, new ItemStack(tileentityflowerpot.getFlowerPotItem(), 1, tileentityflowerpot.getFlowerPotData())); +- } +- + super.breakBlock(worldIn, pos, state); + } + +@@ -388,6 +385,28 @@ + return BlockFaceShape.UNDEFINED; + } + ++ /*============================FORGE START=====================================*/ ++ @Override ++ public void getDrops(net.minecraft.util.NonNullList drops, IBlockAccess world, BlockPos pos, IBlockState state, int fortune) { ++ super.getDrops(drops, world, pos, state, fortune); ++ TileEntityFlowerPot te = world.getTileEntity(pos) instanceof TileEntityFlowerPot ? (TileEntityFlowerPot)world.getTileEntity(pos) : null; ++ if (te != null && te.getFlowerPotItem() != null) ++ drops.add(new ItemStack(te.getFlowerPotItem(), 1, te.getFlowerPotData())); ++ } ++ ++ @Override ++ public boolean removedByPlayer(IBlockState state, World world, BlockPos pos, EntityPlayer player, boolean willHarvest) { ++ if (willHarvest) return true; //If it will harvest, delay deletion of the block until after getDrops ++ return super.removedByPlayer(state, world, pos, player, willHarvest); ++ } ++ ++ @Override ++ public void harvestBlock(World world, EntityPlayer player, BlockPos pos, IBlockState state, @Nullable TileEntity te, ItemStack tool) { ++ super.harvestBlock(world, player, pos, state, te, tool); ++ world.setBlockToAir(pos); ++ } ++ /*===========================FORGE END==========================================*/ ++ + public enum EnumFlowerType implements IStringSerializable { + EMPTY("empty"), + POPPY("rose"), diff --git a/module/minecraft/patches/net/minecraft/block/BlockGrass.java.patch b/module/minecraft/patches/net/minecraft/block/BlockGrass.java.patch new file mode 100644 index 000000000..4d6f5a231 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockGrass.java.patch @@ -0,0 +1,42 @@ +--- original/net/minecraft/block/BlockGrass.java ++++ modified/net/minecraft/block/BlockGrass.java +@@ -35,7 +35,8 @@ + @Override + public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand) { + if (!worldIn.isRemote) { +- if (worldIn.getLightFromNeighbors(pos.up()) < 4 && worldIn.getBlockState(pos.up()).getLightOpacity() > 2) { ++ if (!worldIn.isAreaLoaded(pos, 3)) return; // Forge: prevent loading unloaded chunks when checking neighbor's light and spreading ++ if (worldIn.getLightFromNeighbors(pos.up()) < 4 && worldIn.getBlockState(pos.up()).getLightOpacity(worldIn, pos.up()) > 2) { + worldIn.setBlockState(pos, Blocks.DIRT.getDefaultState()); + } else { + if (worldIn.getLightFromNeighbors(pos.up()) >= 9) { +@@ -48,9 +49,9 @@ + IBlockState iblockstate = worldIn.getBlockState(blockpos.up()); + IBlockState iblockstate1 = worldIn.getBlockState(blockpos); + if (iblockstate1.getBlock() == Blocks.DIRT +- && iblockstate1.getValue(BlockDirt.VARIANT) == BlockDirt.DirtType.DIRT +- && worldIn.getLightFromNeighbors(blockpos.up()) >= 4 +- && iblockstate.getLightOpacity() <= 2) { ++ && iblockstate1.getValue(BlockDirt.VARIANT) == BlockDirt.DirtType.DIRT ++ && worldIn.getLightFromNeighbors(blockpos.up()) >= 4 ++ && iblockstate.getLightOpacity(worldIn, pos.up()) <= 2) { + worldIn.setBlockState(blockpos, Blocks.GRASS.getDefaultState()); + } + } +@@ -95,14 +96,9 @@ + } + } + +- if (worldIn.getBlockState(blockpos1).getBlock().material == Material.AIR) { ++ if (worldIn.isAirBlock(blockpos1)) { + if (rand.nextInt(8) == 0) { +- BlockFlower.EnumFlowerType blockflower$enumflowertype = worldIn.getBiome(blockpos1).pickRandomFlower(rand, blockpos1); +- BlockFlower blockflower = blockflower$enumflowertype.getBlockType().getBlock(); +- IBlockState iblockstate = blockflower.getDefaultState().withProperty(blockflower.getTypeProperty(), blockflower$enumflowertype); +- if (blockflower.canBlockStay(worldIn, blockpos1, iblockstate)) { +- worldIn.setBlockState(blockpos1, iblockstate, 3); +- } ++ worldIn.getBiome(blockpos1).plantFlower(worldIn, rand, blockpos1); + } else { + IBlockState iblockstate1 = Blocks.TALLGRASS + .getDefaultState() diff --git a/module/minecraft/patches/net/minecraft/block/BlockHugeMushroom.java.patch b/module/minecraft/patches/net/minecraft/block/BlockHugeMushroom.java.patch new file mode 100644 index 000000000..91b984e54 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockHugeMushroom.java.patch @@ -0,0 +1,30 @@ +--- original/net/minecraft/block/BlockHugeMushroom.java ++++ modified/net/minecraft/block/BlockHugeMushroom.java +@@ -3,6 +3,7 @@ + import java.util.Random; + import net.minecraft.block.material.MapColor; + import net.minecraft.block.material.Material; ++import net.minecraft.block.properties.IProperty; + import net.minecraft.block.properties.PropertyEnum; + import net.minecraft.block.state.BlockStateContainer; + import net.minecraft.block.state.IBlockState; +@@ -225,6 +226,19 @@ + protected BlockStateContainer createBlockState() { + return new BlockStateContainer(this, VARIANT); + } ++ public boolean rotateBlock(World world, BlockPos pos, EnumFacing axis) ++ { ++ IBlockState state = world.getBlockState(pos); ++ for (IProperty prop : (java.util.Set>)state.getProperties().keySet()) ++ { ++ if (prop.getName().equals("variant")) ++ { ++ world.setBlockState(pos, state.cycleProperty(prop)); ++ return true; ++ } ++ } ++ return false; ++ } + + public enum EnumType implements IStringSerializable { + NORTH_WEST(1, "north_west"), diff --git a/module/minecraft/patches/net/minecraft/block/BlockIce.java.patch b/module/minecraft/patches/net/minecraft/block/BlockIce.java.patch new file mode 100644 index 000000000..b7f7ab186 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockIce.java.patch @@ -0,0 +1,29 @@ +--- original/net/minecraft/block/BlockIce.java ++++ modified/net/minecraft/block/BlockIce.java +@@ -42,8 +42,14 @@ + ) { + player.addStat(StatList.getBlockStats(this)); + player.addExhaustion(0.005F); +- if (this.canSilkHarvest() && EnchantmentHelper.getEnchantmentLevel(Enchantments.SILK_TOUCH, stack) > 0) { +- spawnAsEntity(worldIn, pos, this.getSilkTouchDrop(state)); ++ ++ if (this.canSilkHarvest(worldIn, pos, state, player) && EnchantmentHelper.getEnchantmentLevel(Enchantments.SILK_TOUCH, stack) > 0) { ++ java.util.List items = new java.util.ArrayList(); ++ items.add(this.getSilkTouchDrop(state)); ++ ++ net.minecraftforge.event.ForgeEventFactory.fireBlockHarvesting(items, worldIn, pos, state, 0, 1.0f, true, player); ++ for (ItemStack is : items) ++ spawnAsEntity(worldIn, pos, is); + } else { + if (worldIn.provider.doesWaterVaporize()) { + worldIn.setBlockToAir(pos); +@@ -51,7 +57,9 @@ + } + + int i = EnchantmentHelper.getEnchantmentLevel(Enchantments.FORTUNE, stack); ++ harvesters.set(player); + this.dropBlockAsItem(worldIn, pos, state, i); ++ harvesters.set(null); + Material material = worldIn.getBlockState(pos.down()).getMaterial(); + if (material.blocksMovement() || material.isLiquid()) { + worldIn.setBlockState(pos, Blocks.FLOWING_WATER.getDefaultState()); diff --git a/module/minecraft/patches/net/minecraft/block/BlockLadder.java.patch b/module/minecraft/patches/net/minecraft/block/BlockLadder.java.patch new file mode 100644 index 000000000..3f6eae5c7 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockLadder.java.patch @@ -0,0 +1,14 @@ +--- original/net/minecraft/block/BlockLadder.java ++++ modified/net/minecraft/block/BlockLadder.java +@@ -177,6 +177,11 @@ + * @deprecated call via {@link IBlockState#getBlockFaceShape(IBlockAccess,BlockPos,EnumFacing)} whenever possible. Implementing/overriding is fine. + */ + @Override ++ public boolean isLadder(IBlockState state, IBlockAccess world, BlockPos pos, EntityLivingBase entity) { ++ return true; ++ } ++ ++ @Override + public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face) { + return BlockFaceShape.UNDEFINED; + } diff --git a/module/minecraft/patches/net/minecraft/block/BlockLeaves.java.patch b/module/minecraft/patches/net/minecraft/block/BlockLeaves.java.patch new file mode 100644 index 000000000..1061077b9 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockLeaves.java.patch @@ -0,0 +1,131 @@ +--- original/net/minecraft/block/BlockLeaves.java ++++ modified/net/minecraft/block/BlockLeaves.java +@@ -17,7 +17,7 @@ + import net.minecraftforge.fml.relauncher.Side; + import net.minecraftforge.fml.relauncher.SideOnly; + +-public abstract class BlockLeaves extends Block { ++public abstract class BlockLeaves extends Block implements net.minecraftforge.common.IShearable { + public static final PropertyBool DECAYABLE = PropertyBool.create("decayable"); + public static final PropertyBool CHECK_DECAY = PropertyBool.create("check_decay"); + protected boolean leavesFancy; +@@ -46,8 +46,9 @@ + for (int l1 = -1; l1 <= 1; l1++) { + BlockPos blockpos = pos.add(j1, k1, l1); + IBlockState iblockstate = worldIn.getBlockState(blockpos); +- if (iblockstate.getMaterial() == Material.LEAVES && !iblockstate.getValue(CHECK_DECAY)) { +- worldIn.setBlockState(blockpos, iblockstate.withProperty(CHECK_DECAY, true), 4); ++ ++ if (iblockstate.getBlock().isLeaves(iblockstate, worldIn, blockpos)) { ++ iblockstate.getBlock().beginLeavesDecay(iblockstate, worldIn, blockpos); + } + } + } +@@ -71,7 +72,8 @@ + this.surroundings = new int[32768]; + } + +- if (worldIn.isAreaLoaded(new BlockPos(k - 5, l - 5, i1 - 5), new BlockPos(k + 5, l + 5, i1 + 5))) { ++ if (!worldIn.isAreaLoaded(pos, 1)) return; // Forge: prevent decaying leaves from updating neighbors and loading unloaded chunks ++ if (worldIn.isAreaLoaded(pos, 6)) { // Forge: extend range from 5 to 6 to account for neighbor checks in world.markAndNotifyBlock -> world.updateObservingBlocksAt + BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos(); + + for (int i2 = -4; i2 <= 4; i2++) { +@@ -79,8 +81,9 @@ + for (int k2 = -4; k2 <= 4; k2++) { + IBlockState iblockstate = worldIn.getBlockState(blockpos$mutableblockpos.setPos(k + i2, l + j2, i1 + k2)); + Block block = iblockstate.getBlock(); +- if (block != Blocks.LOG && block != Blocks.LOG2) { +- if (iblockstate.getMaterial() == Material.LEAVES) { ++ ++ if (!block.canSustainLeaves(iblockstate, worldIn, blockpos$mutableblockpos.setPos(k + i2, l + j2, i1 + k2))) { ++ if (block.isLeaves(iblockstate, worldIn, blockpos$mutableblockpos.setPos(k + i2, l + j2, i1 + k2))) { + this.surroundings[(i2 + 16) * 1024 + (j2 + 16) * 32 + k2 + 16] = -2; + } else { + this.surroundings[(i2 + 16) * 1024 + (j2 + 16) * 32 + k2 + 16] = -1; +@@ -171,30 +174,7 @@ + /** Spawns this Block's drops into the World as EntityItems. */ + @Override + public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, IBlockState state, float chance, int fortune) { +- if (!worldIn.isRemote) { +- int i = this.getSaplingDropChance(state); +- if (fortune > 0) { +- i -= 2 << fortune; +- if (i < 10) { +- i = 10; +- } +- } +- +- if (worldIn.rand.nextInt(i) == 0) { +- Item item = this.getItemDropped(state, worldIn.rand, fortune); +- spawnAsEntity(worldIn, pos, new ItemStack(item, 1, this.damageDropped(state))); +- } +- +- i = 200; +- if (fortune > 0) { +- i -= 10 << fortune; +- if (i < 40) { +- i = 40; +- } +- } +- +- this.dropApple(worldIn, pos, state, i); +- } ++ super.dropBlockAsItemWithChance(worldIn, pos, state, chance, fortune); + } + + protected void dropApple(World worldIn, BlockPos pos, IBlockState state, int chance) { +@@ -234,7 +214,52 @@ + + public abstract BlockPlanks.EnumType getWoodType(int var1); + +- /** @deprecated call via {@link IBlockState#shouldSideBeRendered(IBlockAccess,BlockPos,EnumFacing)} whenever possible. Implementing/overriding is fine. */ ++ @Override ++ public boolean isShearable(ItemStack item, IBlockAccess world, BlockPos pos) { ++ return true; ++ } ++ ++ @Override ++ public boolean isLeaves(IBlockState state, IBlockAccess world, BlockPos pos) { ++ return true; ++ } ++ ++ @Override ++ public void beginLeavesDecay(IBlockState state, World world, BlockPos pos) { ++ if (!(Boolean)state.getValue(CHECK_DECAY)) { ++ world.setBlockState(pos, state.withProperty(CHECK_DECAY, true), 4); ++ } ++ } ++ ++ @Override ++ public void getDrops(net.minecraft.util.NonNullList drops, IBlockAccess world, BlockPos pos, IBlockState state, int fortune) { ++ Random rand = world instanceof World ? ((World)world).rand : new Random(); ++ int chance = this.getSaplingDropChance(state); ++ ++ if (fortune > 0) { ++ chance -= 2 << fortune; ++ if (chance < 10) chance = 10; ++ } ++ ++ if (rand.nextInt(chance) == 0) { ++ ItemStack drop = new ItemStack(getItemDropped(state, rand, fortune), 1, damageDropped(state)); ++ if (!drop.isEmpty()) ++ drops.add(drop); ++ } ++ ++ chance = 200; ++ if (fortune > 0) { ++ chance -= 10 << fortune; ++ if (chance < 40) chance = 40; ++ } ++ ++ this.captureDrops(true); ++ if (world instanceof World) ++ this.dropApple((World)world, pos, state, chance); // Dammet mojang ++ drops.addAll(this.captureDrops(false)); ++ } ++ ++ + @SideOnly(Side.CLIENT) + @Override + public boolean shouldSideBeRendered(IBlockState blockState, IBlockAccess blockAccess, BlockPos pos, EnumFacing side) { diff --git a/module/minecraft/patches/net/minecraft/block/BlockLiquid.java.patch b/module/minecraft/patches/net/minecraft/block/BlockLiquid.java.patch new file mode 100644 index 000000000..aaeb235d7 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockLiquid.java.patch @@ -0,0 +1,52 @@ +--- original/net/minecraft/block/BlockLiquid.java ++++ modified/net/minecraft/block/BlockLiquid.java +@@ -353,13 +353,13 @@ + if (flag) { + Integer integer = state.getValue(LEVEL); + if (integer == 0) { +- worldIn.setBlockState(pos, Blocks.OBSIDIAN.getDefaultState()); ++ worldIn.setBlockState(pos, net.minecraftforge.event.ForgeEventFactory.fireFluidPlaceBlockEvent(worldIn, pos, pos, Blocks.OBSIDIAN.getDefaultState())); + this.triggerMixEffects(worldIn, pos); + return true; + } + + if (integer <= 4) { +- worldIn.setBlockState(pos, Blocks.COBBLESTONE.getDefaultState()); ++ worldIn.setBlockState(pos, net.minecraftforge.event.ForgeEventFactory.fireFluidPlaceBlockEvent(worldIn, pos, pos, Blocks.COBBLESTONE.getDefaultState())); + this.triggerMixEffects(worldIn, pos); + return true; + } +@@ -444,7 +444,33 @@ + * @deprecated call via {@link IBlockState#getBlockFaceShape(IBlockAccess,BlockPos,EnumFacing)} whenever possible. Implementing/overriding is fine. + */ + @Override ++ public float getBlockLiquidHeight(World world, BlockPos pos, IBlockState state, Material material) { ++ return BlockLiquid.getBlockLiquidHeight(state, world, pos); ++ } ++ ++ @Override + public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face) { + return BlockFaceShape.UNDEFINED; + } ++ ++ @Override ++ @SideOnly (Side.CLIENT) ++ public Vec3d getFogColor(World world, BlockPos pos, IBlockState state, Entity entity, Vec3d originalColor, float partialTicks) { ++ Vec3d viewport = net.minecraft.client.renderer.ActiveRenderInfo.projectViewFromEntity(entity, partialTicks); ++ ++ if (state.getMaterial().isLiquid()) { ++ float height = 0.0F; ++ if (state.getBlock() instanceof BlockLiquid) { ++ height = getLiquidHeightPercent(state.getValue(LEVEL)) - 0.11111111F; ++ } ++ float f1 = (float) (pos.getY() + 1) - height; ++ if (viewport.y > (double)f1) { ++ BlockPos upPos = pos.up(); ++ IBlockState upState = world.getBlockState(upPos); ++ return upState.getBlock().getFogColor(world, upPos, upState, entity, originalColor, partialTicks); ++ } ++ } ++ ++ return super.getFogColor(world, pos, state, entity, originalColor, partialTicks); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/block/BlockLog.java.patch b/module/minecraft/patches/net/minecraft/block/BlockLog.java.patch new file mode 100644 index 000000000..274b720aa --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockLog.java.patch @@ -0,0 +1,31 @@ +--- original/net/minecraft/block/BlockLog.java ++++ modified/net/minecraft/block/BlockLog.java +@@ -29,8 +29,9 @@ + if (worldIn.isAreaLoaded(pos.add(-5, -5, -5), pos.add(5, 5, 5))) { + for (BlockPos blockpos : BlockPos.getAllInBox(pos.add(-4, -4, -4), pos.add(4, 4, 4))) { + IBlockState iblockstate = worldIn.getBlockState(blockpos); +- if (iblockstate.getMaterial() == Material.LEAVES && !iblockstate.getValue(BlockLeaves.CHECK_DECAY)) { +- worldIn.setBlockState(blockpos, iblockstate.withProperty(BlockLeaves.CHECK_DECAY, true), 4); ++ ++ if (iblockstate.getBlock().isLeaves(iblockstate, worldIn, blockpos)) { ++ iblockstate.getBlock().beginLeavesDecay(iblockstate, worldIn, blockpos); + } + } + } +@@ -73,6 +74,16 @@ + } + } + ++ @Override ++ public boolean canSustainLeaves(IBlockState state, net.minecraft.world.IBlockAccess world, BlockPos pos) { ++ return true; ++ } ++ ++ @Override ++ public boolean isWood(net.minecraft.world.IBlockAccess world, BlockPos pos) { ++ return true; ++ } ++ + public enum EnumAxis implements IStringSerializable { + X("x"), + Y("y"), diff --git a/module/minecraft/patches/net/minecraft/block/BlockMobSpawner.java.patch b/module/minecraft/patches/net/minecraft/block/BlockMobSpawner.java.patch new file mode 100644 index 000000000..a8170d177 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockMobSpawner.java.patch @@ -0,0 +1,18 @@ +--- original/net/minecraft/block/BlockMobSpawner.java ++++ modified/net/minecraft/block/BlockMobSpawner.java +@@ -42,10 +42,13 @@ + @Override + public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, IBlockState state, float chance, int fortune) { + super.dropBlockAsItemWithChance(worldIn, pos, state, chance, fortune); +- int i = 15 + worldIn.rand.nextInt(15) + worldIn.rand.nextInt(15); +- this.dropXpOnBlockBreak(worldIn, pos, i); + } + ++ @Override ++ public int getExpDrop(IBlockState state, net.minecraft.world.IBlockAccess world, BlockPos pos, int fortune) { ++ return 15 + RANDOM.nextInt(15) + RANDOM.nextInt(15); ++ } ++ + /** + * Used to determine ambient occlusion and culling when rebuilding chunks for render + * @deprecated call via {@link IBlockState#isOpaqueCube()} whenever possible. Implementing/overriding is fine. diff --git a/module/minecraft/patches/net/minecraft/block/BlockMushroom.java.patch b/module/minecraft/patches/net/minecraft/block/BlockMushroom.java.patch new file mode 100644 index 000000000..75ea65809 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockMushroom.java.patch @@ -0,0 +1,13 @@ +--- original/net/minecraft/block/BlockMushroom.java ++++ modified/net/minecraft/block/BlockMushroom.java +@@ -73,8 +73,8 @@ + return true; + } else { + return iblockstate.getBlock() == Blocks.DIRT && iblockstate.getValue(BlockDirt.VARIANT) == BlockDirt.DirtType.PODZOL +- ? true +- : worldIn.getLight(pos) < 13 && this.canSustainBush(iblockstate); ++ ? true ++ : worldIn.getLight(pos) < 13 && iblockstate.getBlock().canSustainPlant(iblockstate, worldIn, pos.down(), net.minecraft.util.EnumFacing.UP, this); + } + } else { + return false; diff --git a/module/minecraft/patches/net/minecraft/block/BlockMycelium.java.patch b/module/minecraft/patches/net/minecraft/block/BlockMycelium.java.patch new file mode 100644 index 000000000..6bdf777e5 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockMycelium.java.patch @@ -0,0 +1,25 @@ +--- original/net/minecraft/block/BlockMycelium.java ++++ modified/net/minecraft/block/BlockMycelium.java +@@ -36,7 +36,8 @@ + @Override + public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand) { + if (!worldIn.isRemote) { +- if (worldIn.getLightFromNeighbors(pos.up()) < 4 && worldIn.getBlockState(pos.up()).getLightOpacity() > 2) { ++ if (!worldIn.isAreaLoaded(pos, 2)) return; // Forge: prevent loading unloaded chunks when checking neighbor's light and spreading ++ if (worldIn.getLightFromNeighbors(pos.up()) < 4 && worldIn.getBlockState(pos.up()).getLightOpacity(worldIn, pos.up()) > 2) { + worldIn.setBlockState(pos, Blocks.DIRT.getDefaultState().withProperty(BlockDirt.VARIANT, BlockDirt.DirtType.DIRT)); + } else { + if (worldIn.getLightFromNeighbors(pos.up()) >= 9) { +@@ -45,9 +46,9 @@ + IBlockState iblockstate = worldIn.getBlockState(blockpos); + IBlockState iblockstate1 = worldIn.getBlockState(blockpos.up()); + if (iblockstate.getBlock() == Blocks.DIRT +- && iblockstate.getValue(BlockDirt.VARIANT) == BlockDirt.DirtType.DIRT +- && worldIn.getLightFromNeighbors(blockpos.up()) >= 4 +- && iblockstate1.getLightOpacity() <= 2) { ++ && iblockstate.getValue(BlockDirt.VARIANT) == BlockDirt.DirtType.DIRT ++ && worldIn.getLightFromNeighbors(blockpos.up()) >= 4 ++ && iblockstate1.getLightOpacity(worldIn, blockpos.up()) <= 2) { + worldIn.setBlockState(blockpos, this.getDefaultState()); + } + } diff --git a/module/minecraft/patches/net/minecraft/block/BlockNetherWart.java.patch b/module/minecraft/patches/net/minecraft/block/BlockNetherWart.java.patch new file mode 100644 index 000000000..88754dceb --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockNetherWart.java.patch @@ -0,0 +1,57 @@ +--- original/net/minecraft/block/BlockNetherWart.java ++++ modified/net/minecraft/block/BlockNetherWart.java +@@ -45,24 +45,27 @@ + + @Override + public boolean canBlockStay(World worldIn, BlockPos pos, IBlockState state) { +- return this.canSustainBush(worldIn.getBlockState(pos.down())); ++ return super.canBlockStay(worldIn, pos, state); + } + + @Override + public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand) { + int i = state.getValue(AGE); +- if (i < 3 && rand.nextInt(10) == 0) { +- state = state.withProperty(AGE, i + 1); +- worldIn.setBlockState(pos, state, 2); ++ ++ if (i < 3 && net.minecraftforge.common.ForgeHooks.onCropsGrowPre(worldIn, pos, state, rand.nextInt(10) == 0)) { ++ IBlockState newState = state.withProperty(AGE, i + 1); ++ worldIn.setBlockState(pos, newState, 2); ++ net.minecraftforge.common.ForgeHooks.onCropsGrowPost(worldIn, pos, state, newState); + } + + super.updateTick(worldIn, pos, state, rand); + } + +- /** Spawns this Block's drops into the World as EntityItems. */ ++ @SuppressWarnings("unused") + @Override + public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, IBlockState state, float chance, int fortune) { +- if (!worldIn.isRemote) { ++ super.dropBlockAsItemWithChance(worldIn, pos, state, chance, fortune); ++ if (false && !worldIn.isRemote) { + int i = 1; + if (state.getValue(AGE) >= 3) { + i = 2 + worldIn.rand.nextInt(3); +@@ -107,6 +110,20 @@ + } + + @Override ++ public void getDrops(net.minecraft.util.NonNullList drops, net.minecraft.world.IBlockAccess world, BlockPos pos, IBlockState state, int fortune) { ++ Random rand = world instanceof World ? ((World)world).rand : new Random(); ++ int count = 1; ++ ++ if (state.getValue(AGE) >= 3) { ++ count = 2 + rand.nextInt(3) + (fortune > 0 ? rand.nextInt(fortune + 1) : 0); ++ } ++ ++ for (int i = 0; i < count; i++) { ++ drops.add(new ItemStack(Items.NETHER_WART)); ++ } ++ } ++ ++ @Override + protected BlockStateContainer createBlockState() { + return new BlockStateContainer(this, AGE); + } diff --git a/module/minecraft/patches/net/minecraft/block/BlockNewLeaf.java.patch b/module/minecraft/patches/net/minecraft/block/BlockNewLeaf.java.patch new file mode 100644 index 000000000..b97977a67 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockNewLeaf.java.patch @@ -0,0 +1,12 @@ +--- original/net/minecraft/block/BlockNewLeaf.java ++++ modified/net/minecraft/block/BlockNewLeaf.java +@@ -112,4 +112,9 @@ + super.harvestBlock(worldIn, player, pos, state, te, stack); + } + } ++ ++ @Override ++ public NonNullList onSheared(ItemStack item, net.minecraft.world.IBlockAccess world, BlockPos pos, int fortune) { ++ return NonNullList.withSize(1, new ItemStack(this, 1, world.getBlockState(pos).getValue(VARIANT).getMetadata() - 4)); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/block/BlockNote.java.patch b/module/minecraft/patches/net/minecraft/block/BlockNote.java.patch new file mode 100644 index 000000000..de3d45a7e --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockNote.java.patch @@ -0,0 +1,23 @@ +--- original/net/minecraft/block/BlockNote.java ++++ modified/net/minecraft/block/BlockNote.java +@@ -75,7 +75,9 @@ + TileEntity tileentity = worldIn.getTileEntity(pos); + if (tileentity instanceof TileEntityNote) { + TileEntityNote tileentitynote = (TileEntityNote)tileentity; ++ int old = tileentitynote.note; + tileentitynote.changePitch(); ++ if (old == tileentitynote.note) return false; + tileentitynote.triggerNote(worldIn, pos); + playerIn.addStat(StatList.NOTEBLOCK_TUNED); + } +@@ -114,6 +116,10 @@ + */ + @Override + public boolean eventReceived(IBlockState state, World worldIn, BlockPos pos, int id, int param) { ++ net.minecraftforge.event.world.NoteBlockEvent.Play e = new net.minecraftforge.event.world.NoteBlockEvent.Play(worldIn, pos, state, param, id); ++ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(e)) return false; ++ id = e.getInstrument().ordinal(); ++ param = e.getVanillaNoteId(); + float f = (float)Math.pow(2.0, (param - 12) / 12.0); + worldIn.playSound(null, pos, this.getInstrument(id), SoundCategory.RECORDS, 3.0F, f); + worldIn.spawnParticle( diff --git a/module/minecraft/patches/net/minecraft/block/BlockObserver.java.patch b/module/minecraft/patches/net/minecraft/block/BlockObserver.java.patch new file mode 100644 index 000000000..303b384f0 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockObserver.java.patch @@ -0,0 +1,14 @@ +--- original/net/minecraft/block/BlockObserver.java ++++ modified/net/minecraft/block/BlockObserver.java +@@ -157,4 +157,11 @@ + public IBlockState getStateFromMeta(int meta) { + return this.getDefaultState().withProperty(FACING, EnumFacing.byIndex(meta & 7)); + } ++ ++ /* ======================================== FORGE START =====================================*/ ++ @Override ++ public void observedNeighborChange(IBlockState observerState, World world, BlockPos observerPos, Block changedBlock, BlockPos changedBlockPos) { ++ observedNeighborChanged(observerState, world, observerPos, changedBlock, changedBlockPos); ++ } ++ /* ========================================= FORGE END ======================================*/ + } diff --git a/module/minecraft/patches/net/minecraft/block/BlockOldLeaf.java.patch b/module/minecraft/patches/net/minecraft/block/BlockOldLeaf.java.patch new file mode 100644 index 000000000..ff9207c45 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockOldLeaf.java.patch @@ -0,0 +1,17 @@ +--- original/net/minecraft/block/BlockOldLeaf.java ++++ modified/net/minecraft/block/BlockOldLeaf.java +@@ -109,9 +109,13 @@ + ) { + if (!worldIn.isRemote && stack.getItem() == Items.SHEARS) { + player.addStat(StatList.getBlockStats(this)); +- spawnAsEntity(worldIn, pos, new ItemStack(Item.getItemFromBlock(this), 1, state.getValue(VARIANT).getMetadata())); + } else { + super.harvestBlock(worldIn, player, pos, state, te, stack); + } + } ++ ++ @Override ++ public NonNullList onSheared(ItemStack item, net.minecraft.world.IBlockAccess world, BlockPos pos, int fortune) { ++ return NonNullList.withSize(1, new ItemStack(this, 1, world.getBlockState(pos).getValue(VARIANT).getMetadata())); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/block/BlockOre.java.patch b/module/minecraft/patches/net/minecraft/block/BlockOre.java.patch new file mode 100644 index 000000000..cedcb7e12 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockOre.java.patch @@ -0,0 +1,37 @@ +--- original/net/minecraft/block/BlockOre.java ++++ modified/net/minecraft/block/BlockOre.java +@@ -67,22 +67,27 @@ + @Override + public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, IBlockState state, float chance, int fortune) { + super.dropBlockAsItemWithChance(worldIn, pos, state, chance, fortune); +- if (this.getItemDropped(state, worldIn.rand, fortune) != Item.getItemFromBlock(this)) { ++ } ++ @Override ++ public int getExpDrop(IBlockState state, net.minecraft.world.IBlockAccess world, BlockPos pos, int fortune) { ++ Random rand = world instanceof World ? ((World)world).rand : new Random(); ++ if (this.getItemDropped(state, rand, fortune) != Item.getItemFromBlock(this)) { + int i = 0; + if (this == Blocks.COAL_ORE) { +- i = MathHelper.getInt(worldIn.rand, 0, 2); ++ i = MathHelper.getInt(rand, 0, 2); + } else if (this == Blocks.DIAMOND_ORE) { +- i = MathHelper.getInt(worldIn.rand, 3, 7); ++ i = MathHelper.getInt(rand, 3, 7); + } else if (this == Blocks.EMERALD_ORE) { +- i = MathHelper.getInt(worldIn.rand, 3, 7); ++ i = MathHelper.getInt(rand, 3, 7); + } else if (this == Blocks.LAPIS_ORE) { +- i = MathHelper.getInt(worldIn.rand, 2, 5); ++ i = MathHelper.getInt(rand, 2, 5); + } else if (this == Blocks.QUARTZ_ORE) { +- i = MathHelper.getInt(worldIn.rand, 2, 5); ++ i = MathHelper.getInt(rand, 2, 5); + } + +- this.dropXpOnBlockBreak(worldIn, pos, i); ++ return i; + } ++ return 0; + } + + @Override diff --git a/module/minecraft/patches/net/minecraft/block/BlockPane.java.patch b/module/minecraft/patches/net/minecraft/block/BlockPane.java.patch new file mode 100644 index 000000000..1c38acc10 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockPane.java.patch @@ -0,0 +1,61 @@ +--- original/net/minecraft/block/BlockPane.java ++++ modified/net/minecraft/block/BlockPane.java +@@ -130,22 +130,10 @@ + /** Get the actual Block state of this Block at the given position. This applies properties not visible in the metadata, such as fence connections. */ + @Override + public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos) { +- return state.withProperty( +- NORTH, +- this.attachesTo(worldIn, worldIn.getBlockState(pos.north()), pos.north(), EnumFacing.SOUTH) +- ) +- .withProperty( +- SOUTH, +- this.attachesTo(worldIn, worldIn.getBlockState(pos.south()), pos.south(), EnumFacing.NORTH) +- ) +- .withProperty( +- WEST, +- this.attachesTo(worldIn, worldIn.getBlockState(pos.west()), pos.west(), EnumFacing.EAST) +- ) +- .withProperty( +- EAST, +- this.attachesTo(worldIn, worldIn.getBlockState(pos.east()), pos.east(), EnumFacing.WEST) +- ); ++ return state.withProperty(NORTH, canPaneConnectTo(worldIn, pos, EnumFacing.NORTH)) ++ .withProperty(SOUTH, canPaneConnectTo(worldIn, pos, EnumFacing.SOUTH)) ++ .withProperty(WEST, canPaneConnectTo(worldIn, pos, EnumFacing.WEST)) ++ .withProperty(EAST, canPaneConnectTo(worldIn, pos, EnumFacing.EAST)); + } + + /** Get the Item that this Block should drop when harvested. */ +@@ -269,15 +257,23 @@ + return new BlockStateContainer(this, NORTH, EAST, WEST, SOUTH); + } + +- /** +- * Get the geometry of the queried face at the given position and state. This is used to decide whether things like buttons are allowed to be placed on the face, or how glass panes connect to the face, among other things. +- *

+- * Common values are {@code SOLID}, which is the default, and {@code UNDEFINED}, which represents something that does not fit the other descriptions and will generally cause other things not to connect to the face. +- * +- * @return an approximation of the form of the given face +- * @deprecated call via {@link IBlockState#getBlockFaceShape(IBlockAccess,BlockPos,EnumFacing)} whenever possible. Implementing/overriding is fine. +- */ ++ /* ======================================== FORGE START ======================================== */ ++ + @Override ++ public boolean canBeConnectedTo(IBlockAccess world, BlockPos pos, EnumFacing facing) { ++ BlockPos offset = pos.offset(facing); ++ return attachesTo(world, world.getBlockState(offset), offset, facing.getOpposite()); ++ } ++ ++ public boolean canPaneConnectTo(IBlockAccess world, BlockPos pos, EnumFacing dir) { ++ BlockPos other = pos.offset(dir); ++ IBlockState state = world.getBlockState(other); ++ return state.getBlock().canBeConnectedTo(world, other, dir.getOpposite()) || attachesTo(world, state, other, dir.getOpposite()); ++ } ++ ++ /* ======================================== FORGE END ======================================== */ ++ ++ @Override + public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face) { + return face != EnumFacing.UP && face != EnumFacing.DOWN ? BlockFaceShape.MIDDLE_POLE_THIN : BlockFaceShape.CENTER_SMALL; + } diff --git a/module/minecraft/patches/net/minecraft/block/BlockPistonBase.java.patch b/module/minecraft/patches/net/minecraft/block/BlockPistonBase.java.patch new file mode 100644 index 000000000..203622bf0 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockPistonBase.java.patch @@ -0,0 +1,45 @@ +--- original/net/minecraft/block/BlockPistonBase.java ++++ modified/net/minecraft/block/BlockPistonBase.java +@@ -245,7 +245,7 @@ + } + + if (!flag1 +- && iblockstate.getMaterial() != Material.AIR ++ && !iblockstate.getBlock().isAir(iblockstate, worldIn, blockpos) + && canPush(iblockstate, worldIn, blockpos, enumfacing.getOpposite(), false, enumfacing) + && (iblockstate.getPushReaction() == EnumPushReaction.NORMAL || block == Blocks.PISTON || block == Blocks.STICKY_PISTON)) { + this.doMove(worldIn, pos, enumfacing, false); +@@ -307,7 +307,7 @@ + return false; + } + +- return !block.hasTileEntity(); ++ return !block.hasTileEntity(blockStateIn); + } else { + return false; + } +@@ -342,7 +342,9 @@ + for (int j = list2.size() - 1; j >= 0; j--) { + BlockPos blockpos1 = list2.get(j); + IBlockState iblockstate = worldIn.getBlockState(blockpos1); +- iblockstate.getBlock().dropBlockAsItem(worldIn, blockpos1, iblockstate, 0); ++ // Forge: With our change to how snowballs are dropped this needs to disallow to mimic vanilla behavior. ++ float chance = iblockstate.getBlock() instanceof BlockSnow ? -1.0f : 1.0f; ++ iblockstate.getBlock().dropBlockAsItemWithChance(worldIn, blockpos1, iblockstate, chance, 0); + worldIn.setBlockState(blockpos1, Blocks.AIR.getDefaultState(), 4); + aiblockstate[--k] = iblockstate; + } +@@ -441,6 +443,13 @@ + * @return an approximation of the form of the given face + * @deprecated call via {@link IBlockState#getBlockFaceShape(IBlockAccess,BlockPos,EnumFacing)} whenever possible. Implementing/overriding is fine. + */ ++ /* ======================================== FORGE START =====================================*/ ++ public boolean rotateBlock(World world, BlockPos pos, EnumFacing axis) ++ { ++ IBlockState state = world.getBlockState(pos); ++ return !state.getValue(EXTENDED) && super.rotateBlock(world, pos, axis); ++ } ++ /* ======================================== FORGE END =======================================*/ + @Override + public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face) { + state = this.getActualState(state, worldIn, pos); diff --git a/module/minecraft/patches/net/minecraft/block/BlockPistonMoving.java.patch b/module/minecraft/patches/net/minecraft/block/BlockPistonMoving.java.patch new file mode 100644 index 000000000..9908a444f --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockPistonMoving.java.patch @@ -0,0 +1,34 @@ +--- original/net/minecraft/block/BlockPistonMoving.java ++++ modified/net/minecraft/block/BlockPistonMoving.java +@@ -131,13 +131,14 @@ + /** Spawns this Block's drops into the World as EntityItems. */ + @Override + public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, IBlockState state, float chance, int fortune) { +- if (!worldIn.isRemote) { ++ if (false && !worldIn.isRemote) { // Forge: Noop this out + TileEntityPiston tileentitypiston = this.getTilePistonAt(worldIn, pos); + if (tileentitypiston != null) { + IBlockState iblockstate = tileentitypiston.getPistonState(); + iblockstate.getBlock().dropBlockAsItem(worldIn, pos, iblockstate, 0); + } + } ++ super.dropBlockAsItemWithChance(worldIn, pos, state, 1, fortune); // mimic vanilla behavior from above and ignore chance + } + + /** +@@ -253,6 +254,15 @@ + * @deprecated call via {@link IBlockState#getBlockFaceShape(IBlockAccess,BlockPos,EnumFacing)} whenever possible. Implementing/overriding is fine. + */ + @Override ++ public void getDrops(net.minecraft.util.NonNullList drops, IBlockAccess world, BlockPos pos, IBlockState state, int fortune) { ++ TileEntityPiston tileentitypiston = this.getTilePistonAt(world, pos); ++ if (tileentitypiston != null) { ++ IBlockState pushed = tileentitypiston.getPistonState(); ++ drops.addAll(pushed.getBlock().getDrops(world, pos, pushed, fortune)); // use the old method until it gets removed, for backward compatibility ++ } ++ } ++ ++ @Override + public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face) { + return BlockFaceShape.UNDEFINED; + } diff --git a/module/minecraft/patches/net/minecraft/block/BlockPortal.java.patch b/module/minecraft/patches/net/minecraft/block/BlockPortal.java.patch new file mode 100644 index 000000000..be6015208 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockPortal.java.patch @@ -0,0 +1,19 @@ +--- original/net/minecraft/block/BlockPortal.java ++++ modified/net/minecraft/block/BlockPortal.java +@@ -108,12 +108,14 @@ + + public boolean trySpawnPortal(World worldIn, BlockPos pos) { + BlockPortal.Size blockportal$size = new BlockPortal.Size(worldIn, pos, EnumFacing.Axis.X); +- if (blockportal$size.isValid() && blockportal$size.portalBlockCount == 0) { ++ ++ if (blockportal$size.isValid() && blockportal$size.portalBlockCount == 0 && !net.minecraftforge.event.ForgeEventFactory.onTrySpawnPortal(worldIn, pos, blockportal$size)) { + blockportal$size.placePortalBlocks(); + return true; + } else { + BlockPortal.Size blockportal$size1 = new BlockPortal.Size(worldIn, pos, EnumFacing.Axis.Z); +- if (blockportal$size1.isValid() && blockportal$size1.portalBlockCount == 0) { ++ ++ if (blockportal$size1.isValid() && blockportal$size1.portalBlockCount == 0 && !net.minecraftforge.event.ForgeEventFactory.onTrySpawnPortal(worldIn, pos, blockportal$size1)) { + blockportal$size1.placePortalBlocks(); + return true; + } else { diff --git a/module/minecraft/patches/net/minecraft/block/BlockPotato.java.patch b/module/minecraft/patches/net/minecraft/block/BlockPotato.java.patch new file mode 100644 index 000000000..05ee061ee --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockPotato.java.patch @@ -0,0 +1,24 @@ +--- original/net/minecraft/block/BlockPotato.java ++++ modified/net/minecraft/block/BlockPotato.java +@@ -35,7 +35,8 @@ + @Override + public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, IBlockState state, float chance, int fortune) { + super.dropBlockAsItemWithChance(worldIn, pos, state, chance, fortune); +- if (!worldIn.isRemote) { ++ ++ if (false && !worldIn.isRemote) { //Forge: Moved to getDrops + if (this.isMaxAge(state) && worldIn.rand.nextInt(50) == 0) { + spawnAsEntity(worldIn, pos, new ItemStack(Items.POISONOUS_POTATO)); + } +@@ -47,4 +48,11 @@ + public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos) { + return POTATO_AABB[state.getValue(this.getAgeProperty())]; + } ++ ++ @Override ++ public void getDrops(net.minecraft.util.NonNullList drops, net.minecraft.world.IBlockAccess world, BlockPos pos, IBlockState state, int fortune) { ++ super.getDrops(drops, world, pos, state, fortune); ++ if (this.isMaxAge(state) && RANDOM.nextInt(50) == 0) ++ drops.add(new ItemStack(Items.POISONOUS_POTATO)); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/block/BlockPumpkin.java.patch b/module/minecraft/patches/net/minecraft/block/BlockPumpkin.java.patch new file mode 100644 index 000000000..c3e540c70 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockPumpkin.java.patch @@ -0,0 +1,13 @@ +--- original/net/minecraft/block/BlockPumpkin.java ++++ modified/net/minecraft/block/BlockPumpkin.java +@@ -131,8 +131,8 @@ + /** Checks if this block can be placed exactly at the given position. */ + @Override + public boolean canPlaceBlockAt(World worldIn, BlockPos pos) { +- return worldIn.getBlockState(pos).getBlock().material.isReplaceable() +- && worldIn.getBlockState(pos.down()).isTopSolid(); ++ return worldIn.getBlockState(pos).getBlock().isReplaceable(worldIn, pos) ++ && worldIn.isSideSolid(pos.down(), EnumFacing.UP); + } + + /** diff --git a/module/minecraft/patches/net/minecraft/block/BlockQuartz.java.patch b/module/minecraft/patches/net/minecraft/block/BlockQuartz.java.patch new file mode 100644 index 000000000..c2ce60f1a --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockQuartz.java.patch @@ -0,0 +1,37 @@ +--- original/net/minecraft/block/BlockQuartz.java ++++ modified/net/minecraft/block/BlockQuartz.java +@@ -2,6 +2,7 @@ + + import net.minecraft.block.material.MapColor; + import net.minecraft.block.material.Material; ++import net.minecraft.block.properties.IProperty; + import net.minecraft.block.properties.PropertyEnum; + import net.minecraft.block.state.BlockStateContainer; + import net.minecraft.block.state.IBlockState; +@@ -126,6 +127,26 @@ + protected BlockStateContainer createBlockState() { + return new BlockStateContainer(this, VARIANT); + } ++ @Override ++ public boolean rotateBlock(World world, BlockPos pos, EnumFacing axis) ++ { ++ IBlockState state = world.getBlockState(pos); ++ for (IProperty prop : state.getProperties().keySet()) ++ { ++ if (prop.getName().equals("variant") && prop.getValueClass() == EnumType.class) ++ { ++ EnumType current = (EnumType)state.getValue(prop); ++ EnumType next = current == EnumType.LINES_X ? EnumType.LINES_Y : ++ current == EnumType.LINES_Y ? EnumType.LINES_Z : ++ current == EnumType.LINES_Z ? EnumType.LINES_X : current; ++ if (next == current) ++ return false; ++ world.setBlockState(pos, state.withProperty(prop, next)); ++ return true; ++ } ++ } ++ return false; ++ } + + public enum EnumType implements IStringSerializable { + DEFAULT(0, "default", "default"), diff --git a/module/minecraft/patches/net/minecraft/block/BlockRailBase.java.patch b/module/minecraft/patches/net/minecraft/block/BlockRailBase.java.patch new file mode 100644 index 000000000..a58b05653 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockRailBase.java.patch @@ -0,0 +1,228 @@ +--- original/net/minecraft/block/BlockRailBase.java ++++ modified/net/minecraft/block/BlockRailBase.java +@@ -31,7 +31,7 @@ + + public static boolean isRailBlock(IBlockState state) { + Block block = state.getBlock(); +- return block == Blocks.RAIL || block == Blocks.GOLDEN_RAIL || block == Blocks.DETECTOR_RAIL || block == Blocks.ACTIVATOR_RAIL; ++ return block instanceof BlockRailBase; + } + + protected BlockRailBase(boolean isPowered) { +@@ -60,8 +60,8 @@ + @Override + public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos) { + BlockRailBase.EnumRailDirection blockrailbase$enumraildirection = state.getBlock() == this +- ? state.getValue(this.getShapeProperty()) +- : null; ++ ? getRailDirection(source, pos, state, null) ++ : null; + return blockrailbase$enumraildirection != null && blockrailbase$enumraildirection.isAscending() ? ASCENDING_AABB : FLAT_AABB; + } + +@@ -87,7 +87,7 @@ + /** Checks if this block can be placed exactly at the given position. */ + @Override + public boolean canPlaceBlockAt(World worldIn, BlockPos pos) { +- return worldIn.getBlockState(pos.down()).isTopSolid(); ++ return worldIn.getBlockState(pos.down()).isSideSolid(worldIn, pos.down(), EnumFacing.UP); + } + + /** Called after the block is set in the Chunk data, but before the Tile Entity is set */ +@@ -105,27 +105,25 @@ + @Override + public void neighborChanged(IBlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos) { + if (!worldIn.isRemote) { +- BlockRailBase.EnumRailDirection blockrailbase$enumraildirection = state.getValue(this.getShapeProperty()); ++ final IBlockState currentState = worldIn.getBlockState(pos); ++ BlockRailBase.EnumRailDirection blockrailbase$enumraildirection = getRailDirection(worldIn, pos, currentState.getBlock() == this ? currentState : state, null); + boolean flag = false; +- if (!worldIn.getBlockState(pos.down()).isTopSolid()) { ++ ++ if (!worldIn.getBlockState(pos.down()).isSideSolid(worldIn, pos.down(), EnumFacing.UP)) { + flag = true; + } + +- if (blockrailbase$enumraildirection == BlockRailBase.EnumRailDirection.ASCENDING_EAST +- && !worldIn.getBlockState(pos.east()).isTopSolid()) { ++ if (blockrailbase$enumraildirection == BlockRailBase.EnumRailDirection.ASCENDING_EAST && !worldIn.getBlockState(pos.east()).isSideSolid(worldIn, pos.east(), EnumFacing.UP)) { + flag = true; +- } else if (blockrailbase$enumraildirection == BlockRailBase.EnumRailDirection.ASCENDING_WEST +- && !worldIn.getBlockState(pos.west()).isTopSolid()) { ++ } else if (blockrailbase$enumraildirection == BlockRailBase.EnumRailDirection.ASCENDING_WEST && !worldIn.getBlockState(pos.west()).isSideSolid(worldIn, pos.west(), EnumFacing.UP)) { + flag = true; +- } else if (blockrailbase$enumraildirection == BlockRailBase.EnumRailDirection.ASCENDING_NORTH +- && !worldIn.getBlockState(pos.north()).isTopSolid()) { ++ } else if (blockrailbase$enumraildirection == BlockRailBase.EnumRailDirection.ASCENDING_NORTH && !worldIn.getBlockState(pos.north()).isSideSolid(worldIn, pos.north(), EnumFacing.UP)) { + flag = true; +- } else if (blockrailbase$enumraildirection == BlockRailBase.EnumRailDirection.ASCENDING_SOUTH +- && !worldIn.getBlockState(pos.south()).isTopSolid()) { ++ } else if (blockrailbase$enumraildirection == BlockRailBase.EnumRailDirection.ASCENDING_SOUTH && !worldIn.getBlockState(pos.south()).isSideSolid(worldIn, pos.south(), EnumFacing.UP)) { + flag = true; + } + +- if (flag && !worldIn.isAirBlock(pos)) { ++ if (flag && !currentState.getBlock().isAir(currentState, worldIn, pos)) { + this.dropBlockAsItem(worldIn, pos, state, 0); + worldIn.setBlockToAir(pos); + } else { +@@ -160,7 +158,8 @@ + @Override + public void breakBlock(World worldIn, BlockPos pos, IBlockState state) { + super.breakBlock(worldIn, pos, state); +- if (state.getValue(this.getShapeProperty()).isAscending()) { ++ ++ if (getRailDirection(worldIn, pos, state, null).isAscending()) { + worldIn.notifyNeighborsOfStateChange(pos.up(), this, false); + } + +@@ -170,8 +169,94 @@ + } + } + ++ //Forge: Use getRailDirection(IBlockAccess, BlockPos, IBlockState, EntityMinecart) for enhanced ability + public abstract IProperty getShapeProperty(); + ++ /* ======================================== FORGE START =====================================*/ ++ /** ++ * Return true if the rail can make corners. ++ * Used by placement logic. ++ * @param world The world. ++ * @param pos Block's position in world ++ * @return True if the rail can make corners. ++ */ ++ public boolean isFlexibleRail(IBlockAccess world, BlockPos pos) { ++ return !this.isPowered; ++ } ++ ++ /** ++ * Returns true if the rail can make up and down slopes. ++ * Used by placement logic. ++ * @param world The world. ++ * @param pos Block's position in world ++ * @return True if the rail can make slopes. ++ */ ++ public boolean canMakeSlopes(IBlockAccess world, BlockPos pos) { ++ return true; ++ } ++ ++ /** ++ * Return the rail's direction. ++ * Can be used to make the cart think the rail is a different shape, ++ * for example when making diamond junctions or switches. ++ * The cart parameter will often be null unless it it called from EntityMinecart. ++ * ++ * @param world The world. ++ * @param pos Block's position in world ++ * @param state The BlockState ++ * @param cart The cart asking for the metadata, null if it is not called by EntityMinecart. ++ * @return The direction. ++ */ ++ public EnumRailDirection getRailDirection(IBlockAccess world, BlockPos pos, IBlockState state, @javax.annotation.Nullable net.minecraft.entity.item.EntityMinecart cart) { ++ return state.getValue(getShapeProperty()); ++ } ++ ++ /** ++ * Returns the max speed of the rail at the specified position. ++ * @param world The world. ++ * @param cart The cart on the rail, may be null. ++ * @param pos Block's position in world ++ * @return The max speed of the current rail. ++ */ ++ public float getRailMaxSpeed(World world, net.minecraft.entity.item.EntityMinecart cart, BlockPos pos) { ++ return 0.4f; ++ } ++ ++ /** ++ * This function is called by any minecart that passes over this rail. ++ * It is called once per update tick that the minecart is on the rail. ++ * @param world The world. ++ * @param cart The cart on the rail. ++ * @param pos Block's position in world ++ */ ++ public void onMinecartPass(World world, net.minecraft.entity.item.EntityMinecart cart, BlockPos pos) { ++ } ++ ++ /** ++ * Rotate the block. For vanilla blocks this rotates around the axis passed in (generally, it should be the "face" that was hit). ++ * Note: for mod blocks, this is up to the block and modder to decide. It is not mandated that it be a rotation around the ++ * face, but could be a rotation to orient *to* that face, or a visiting of possible rotations. ++ * The method should return true if the rotation was successful though. ++ * ++ * @param world The world ++ * @param pos Block position in world ++ * @param axis The axis to rotate around ++ * @return True if the rotation was successful, False if the rotation failed, or is not possible ++ */ ++ @Override ++ public boolean rotateBlock(World world, BlockPos pos, EnumFacing axis) { ++ IBlockState state = world.getBlockState(pos); ++ for (IProperty prop : state.getProperties().keySet()) { ++ if (prop.getName().equals("shape")) { ++ world.setBlockState(pos, state.cycleProperty(prop)); ++ return true; ++ } ++ } ++ return false; ++ } ++ ++ /* ======================================== FORGE END =====================================*/ ++ + public enum EnumRailDirection implements IStringSerializable { + NORTH_SOUTH(0, "north_south"), + EAST_WEST(1, "east_west"), +@@ -233,14 +318,16 @@ + private IBlockState state; + private final boolean isPowered; + private final List connectedRails = Lists.newArrayList(); ++ private final boolean canMakeSlopes; + + public Rail(World worldIn, BlockPos pos, IBlockState state) { + this.world = worldIn; + this.pos = pos; + this.state = state; + this.block = (BlockRailBase)state.getBlock(); +- BlockRailBase.EnumRailDirection blockrailbase$enumraildirection = state.getValue(this.block.getShapeProperty()); +- this.isPowered = this.block.isPowered; ++ BlockRailBase.EnumRailDirection blockrailbase$enumraildirection = block.getRailDirection(worldIn, pos, state, null); ++ this.isPowered = !this.block.isFlexibleRail(worldIn, pos); ++ this.canMakeSlopes = this.block.canMakeSlopes(worldIn, pos); + this.updateConnectedRails(blockrailbase$enumraildirection); + } + +@@ -398,7 +485,7 @@ + } + } + +- if (blockrailbase$enumraildirection == BlockRailBase.EnumRailDirection.NORTH_SOUTH) { ++ if (blockrailbase$enumraildirection == BlockRailBase.EnumRailDirection.NORTH_SOUTH && canMakeSlopes) { + if (BlockRailBase.isRailBlock(this.world, blockpos.up())) { + blockrailbase$enumraildirection = BlockRailBase.EnumRailDirection.ASCENDING_NORTH; + } +@@ -408,7 +495,7 @@ + } + } + +- if (blockrailbase$enumraildirection == BlockRailBase.EnumRailDirection.EAST_WEST) { ++ if (blockrailbase$enumraildirection == BlockRailBase.EnumRailDirection.EAST_WEST && canMakeSlopes) { + if (BlockRailBase.isRailBlock(this.world, blockpos3.up())) { + blockrailbase$enumraildirection = BlockRailBase.EnumRailDirection.ASCENDING_EAST; + } +@@ -518,7 +605,7 @@ + } + } + +- if (blockrailbase$enumraildirection == BlockRailBase.EnumRailDirection.NORTH_SOUTH) { ++ if (blockrailbase$enumraildirection == BlockRailBase.EnumRailDirection.NORTH_SOUTH && canMakeSlopes) { + if (BlockRailBase.isRailBlock(this.world, blockpos.up())) { + blockrailbase$enumraildirection = BlockRailBase.EnumRailDirection.ASCENDING_NORTH; + } +@@ -528,7 +615,7 @@ + } + } + +- if (blockrailbase$enumraildirection == BlockRailBase.EnumRailDirection.EAST_WEST) { ++ if (blockrailbase$enumraildirection == BlockRailBase.EnumRailDirection.EAST_WEST && canMakeSlopes) { + if (BlockRailBase.isRailBlock(this.world, blockpos3.up())) { + blockrailbase$enumraildirection = BlockRailBase.EnumRailDirection.ASCENDING_EAST; + } diff --git a/module/minecraft/patches/net/minecraft/block/BlockRailDetector.java.patch b/module/minecraft/patches/net/minecraft/block/BlockRailDetector.java.patch new file mode 100644 index 000000000..0db73c4f5 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockRailDetector.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/block/BlockRailDetector.java ++++ modified/net/minecraft/block/BlockRailDetector.java +@@ -163,6 +163,8 @@ + @Override + public int getComparatorInputOverride(IBlockState blockState, World worldIn, BlockPos pos) { + if (blockState.getValue(POWERED)) { ++ List carts = this.findMinecarts(worldIn, pos, EntityMinecart.class); ++ if (!carts.isEmpty() && carts.getFirst().getComparatorLevel() > -1) return carts.getFirst().getComparatorLevel(); + List list = this.findMinecarts(worldIn, pos, EntityMinecartCommandBlock.class); + if (!list.isEmpty()) { + return list.get(0).getCommandBlockLogic().getSuccessCount(); diff --git a/module/minecraft/patches/net/minecraft/block/BlockRailPowered.java.patch b/module/minecraft/patches/net/minecraft/block/BlockRailPowered.java.patch new file mode 100644 index 000000000..3880d3831 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockRailPowered.java.patch @@ -0,0 +1,28 @@ +--- original/net/minecraft/block/BlockRailPowered.java ++++ modified/net/minecraft/block/BlockRailPowered.java +@@ -27,8 +27,15 @@ + ); + public static final PropertyBool POWERED = PropertyBool.create("powered"); + ++ private final boolean isActivator; ++ + protected BlockRailPowered() { ++ this(false); ++ } ++ ++ protected BlockRailPowered(boolean isActivator) { + super(true); ++ this.isActivator = isActivator; + this.setDefaultState( + this.blockState.getBaseState().withProperty(SHAPE, BlockRailBase.EnumRailDirection.NORTH_SOUTH).withProperty(POWERED, false) + ); +@@ -111,7 +118,8 @@ + + protected boolean isSameRailWithPower(World worldIn, BlockPos pos, boolean p_176567_3_, int distance, BlockRailBase.EnumRailDirection p_176567_5_) { + IBlockState iblockstate = worldIn.getBlockState(pos); +- if (iblockstate.getBlock() != this) { ++ ++ if (!(iblockstate.getBlock() instanceof BlockRailPowered) || isActivator != ((BlockRailPowered)iblockstate.getBlock()).isActivator) { + return false; + } + diff --git a/module/minecraft/patches/net/minecraft/block/BlockRedstoneComparator.java.patch b/module/minecraft/patches/net/minecraft/block/BlockRedstoneComparator.java.patch new file mode 100644 index 000000000..d3338ffcc --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockRedstoneComparator.java.patch @@ -0,0 +1,24 @@ +--- original/net/minecraft/block/BlockRedstoneComparator.java ++++ modified/net/minecraft/block/BlockRedstoneComparator.java +@@ -341,7 +341,21 @@ + .withProperty(POWERED, false) + .withProperty(MODE, BlockRedstoneComparator.Mode.COMPARE); + } ++ @Override ++ public void onNeighborChange(IBlockAccess world, BlockPos pos, BlockPos neighbor) ++ { ++ if (pos.getY() == neighbor.getY() && world instanceof World && !((World) world).isRemote) ++ { ++ neighborChanged(world.getBlockState(pos), (World)world, pos, world.getBlockState(neighbor).getBlock(), neighbor); ++ } ++ } + ++ @Override ++ public boolean getWeakChanges(IBlockAccess world, BlockPos pos) ++ { ++ return true; ++ } ++ + public enum Mode implements IStringSerializable { + COMPARE("compare"), + SUBTRACT("subtract"); diff --git a/module/minecraft/patches/net/minecraft/block/BlockRedstoneDiode.java.patch b/module/minecraft/patches/net/minecraft/block/BlockRedstoneDiode.java.patch new file mode 100644 index 000000000..f0f7b616f --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockRedstoneDiode.java.patch @@ -0,0 +1,59 @@ +--- original/net/minecraft/block/BlockRedstoneDiode.java ++++ modified/net/minecraft/block/BlockRedstoneDiode.java +@@ -41,11 +41,13 @@ + /** Checks if this block can be placed exactly at the given position. */ + @Override + public boolean canPlaceBlockAt(World worldIn, BlockPos pos) { +- return worldIn.getBlockState(pos.down()).isTopSolid() ? super.canPlaceBlockAt(worldIn, pos) : false; ++ IBlockState downState = worldIn.getBlockState(pos.down()); ++ return (downState.isTopSolid() || downState.getBlockFaceShape(worldIn, pos.down(), EnumFacing.UP) == BlockFaceShape.SOLID) && super.canPlaceBlockAt(worldIn, pos); + } + + public boolean canBlockStay(World worldIn, BlockPos pos) { +- return worldIn.getBlockState(pos.down()).isTopSolid(); ++ IBlockState downState = worldIn.getBlockState(pos.down()); ++ return downState.isTopSolid() || downState.getBlockFaceShape(worldIn, pos.down(), EnumFacing.UP) == BlockFaceShape.SOLID; + } + + /** Called randomly when setTickRandomly is set to true (used by e.g. crops to grow, etc.) */ +@@ -213,6 +215,8 @@ + protected void notifyNeighbors(World worldIn, BlockPos pos, IBlockState state) { + EnumFacing enumfacing = state.getValue(FACING); + BlockPos blockpos = pos.offset(enumfacing.getOpposite()); ++ if(net.minecraftforge.event.ForgeEventFactory.onNeighborNotify(worldIn, pos, worldIn.getBlockState(pos), java.util.EnumSet.of(enumfacing.getOpposite()), false).isCanceled()) ++ return; + worldIn.neighborChanged(blockpos, this, pos); + worldIn.notifyNeighborsOfStateExcept(blockpos, this, enumfacing); + } +@@ -283,15 +287,23 @@ + return BlockRenderLayer.CUTOUT; + } + +- /** +- * Get the geometry of the queried face at the given position and state. This is used to decide whether things like buttons are allowed to be placed on the face, or how glass panes connect to the face, among other things. +- *

+- * Common values are {@code SOLID}, which is the default, and {@code UNDEFINED}, which represents something that does not fit the other descriptions and will generally cause other things not to connect to the face. +- * +- * @return an approximation of the form of the given face +- * @deprecated call via {@link IBlockState#getBlockFaceShape(IBlockAccess,BlockPos,EnumFacing)} whenever possible. Implementing/overriding is fine. +- */ ++ /* ======================================== FORGE START =====================================*/ + @Override ++ public boolean rotateBlock(World world, BlockPos pos, EnumFacing axis) { ++ if (super.rotateBlock(world, pos, axis)) { ++ IBlockState state = world.getBlockState(pos); ++ state = getUnpoweredState(state); ++ world.setBlockState(pos, state); ++ ++ if (shouldBePowered(world, pos, state)) { ++ world.scheduleUpdate(pos, this, 1); ++ } ++ return true; ++ } ++ return false; ++ } ++ ++ @Override + public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face) { + return face == EnumFacing.DOWN ? BlockFaceShape.SOLID : BlockFaceShape.UNDEFINED; + } diff --git a/module/minecraft/patches/net/minecraft/block/BlockRedstoneOre.java.patch b/module/minecraft/patches/net/minecraft/block/BlockRedstoneOre.java.patch new file mode 100644 index 000000000..cf20a8904 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockRedstoneOre.java.patch @@ -0,0 +1,20 @@ +--- original/net/minecraft/block/BlockRedstoneOre.java ++++ modified/net/minecraft/block/BlockRedstoneOre.java +@@ -101,10 +101,14 @@ + @Override + public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, IBlockState state, float chance, int fortune) { + super.dropBlockAsItemWithChance(worldIn, pos, state, chance, fortune); +- if (this.getItemDropped(state, worldIn.rand, fortune) != Item.getItemFromBlock(this)) { +- int i = 1 + worldIn.rand.nextInt(5); +- this.dropXpOnBlockBreak(worldIn, pos, i); ++ } ++ ++ @Override ++ public int getExpDrop(IBlockState state, net.minecraft.world.IBlockAccess world, BlockPos pos, int fortune) { ++ if (this.getItemDropped(state, RANDOM, fortune) != Item.getItemFromBlock(this)) { ++ return 1 + RANDOM.nextInt(5); + } ++ return 0; + } + + /** Called periodically clientside on blocks near the player to show effects (like furnace fire particles). Note that this method is unrelated to {@link randomTick} and {@link #needsRandomTick}, and will always be called regardless of whether the block can receive random update ticks */ diff --git a/module/minecraft/patches/net/minecraft/block/BlockRedstoneTorch.java.patch b/module/minecraft/patches/net/minecraft/block/BlockRedstoneTorch.java.patch new file mode 100644 index 000000000..e7aa73f2e --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockRedstoneTorch.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/block/BlockRedstoneTorch.java ++++ modified/net/minecraft/block/BlockRedstoneTorch.java +@@ -20,7 +20,7 @@ + import net.minecraftforge.fml.relauncher.SideOnly; + + public class BlockRedstoneTorch extends BlockTorch { +- private static final Map> toggles = Maps.newHashMap(); ++ private static final Map> toggles = new java.util.WeakHashMap>(); // FORGE - fix vanilla MC-101233 + private final boolean isOn; + + private boolean isBurnedOut(World worldIn, BlockPos pos, boolean turnOff) { diff --git a/module/minecraft/patches/net/minecraft/block/BlockRedstoneWire.java.patch b/module/minecraft/patches/net/minecraft/block/BlockRedstoneWire.java.patch new file mode 100644 index 000000000..ecc6e3deb --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockRedstoneWire.java.patch @@ -0,0 +1,71 @@ +--- original/net/minecraft/block/BlockRedstoneWire.java ++++ modified/net/minecraft/block/BlockRedstoneWire.java +@@ -123,13 +123,14 @@ + private BlockRedstoneWire.EnumAttachPosition getAttachPosition(IBlockAccess worldIn, BlockPos pos, EnumFacing direction) { + BlockPos blockpos = pos.offset(direction); + IBlockState iblockstate = worldIn.getBlockState(pos.offset(direction)); +- if (!canConnectTo(worldIn.getBlockState(blockpos), direction) +- && (iblockstate.isNormalCube() || !canConnectUpwardsTo(worldIn.getBlockState(blockpos.down())))) { ++ ++ if (!canConnectTo(worldIn.getBlockState(blockpos), direction, worldIn, blockpos) ++ && (iblockstate.isNormalCube() || !canConnectUpwardsTo(worldIn, blockpos.down()))) { + IBlockState iblockstate1 = worldIn.getBlockState(pos.up()); + if (!iblockstate1.isNormalCube()) { +- boolean flag = worldIn.getBlockState(blockpos).isTopSolid() ++ boolean flag = worldIn.getBlockState(blockpos).isSideSolid(worldIn, blockpos, EnumFacing.UP) + || worldIn.getBlockState(blockpos).getBlock() == Blocks.GLOWSTONE; +- if (flag && canConnectUpwardsTo(worldIn.getBlockState(blockpos.up()))) { ++ if (flag && canConnectUpwardsTo(worldIn, blockpos.up())) { + if (iblockstate.isBlockNormalCube()) { + return BlockRedstoneWire.EnumAttachPosition.UP; + } +@@ -169,8 +170,10 @@ + /** Checks if this block can be placed exactly at the given position. */ + @Override + public boolean canPlaceBlockAt(World worldIn, BlockPos pos) { +- return worldIn.getBlockState(pos.down()).isTopSolid() +- || worldIn.getBlockState(pos.down()).getBlock() == Blocks.GLOWSTONE; ++ IBlockState downState = worldIn.getBlockState(pos.down()); ++ return downState.isTopSolid() ++ || downState.getBlockFaceShape(worldIn, pos.down(), EnumFacing.UP) == BlockFaceShape.SOLID ++ || worldIn.getBlockState(pos.down()).getBlock() == Blocks.GLOWSTONE; + } + + private IBlockState updateSurroundingRedstone(World worldIn, BlockPos pos, IBlockState state) { +@@ -377,7 +380,7 @@ + boolean flag1 = worldIn.getBlockState(pos.up()).isNormalCube(); + if (!flag1 && flag && canConnectUpwardsTo(worldIn, blockpos.up())) { + return true; +- } else if (canConnectTo(iblockstate, side)) { ++ } else if (canConnectTo(iblockstate, side, worldIn, pos)) { + return true; + } else { + return iblockstate.getBlock() == Blocks.POWERED_REPEATER && iblockstate.getValue(BlockRedstoneDiode.FACING) == side +@@ -387,14 +390,10 @@ + } + + protected static boolean canConnectUpwardsTo(IBlockAccess worldIn, BlockPos pos) { +- return canConnectUpwardsTo(worldIn.getBlockState(pos)); ++ return canConnectTo(worldIn.getBlockState(pos), null, worldIn, pos); + } + +- protected static boolean canConnectUpwardsTo(IBlockState state) { +- return canConnectTo(state, null); +- } +- +- protected static boolean canConnectTo(IBlockState blockState, @Nullable EnumFacing side) { ++ protected static boolean canConnectTo(IBlockState blockState, @Nullable EnumFacing side, IBlockAccess world, BlockPos pos) { + Block block = blockState.getBlock(); + if (block == Blocks.REDSTONE_WIRE) { + return true; +@@ -403,8 +402,8 @@ + return enumfacing == side || enumfacing.getOpposite() == side; + } else { + return Blocks.OBSERVER == blockState.getBlock() +- ? side == blockState.getValue(BlockObserver.FACING) +- : blockState.canProvidePower() && side != null; ++ ? side == blockState.getValue(BlockObserver.FACING) ++ : blockState.getBlock().canConnectRedstone(blockState, world, pos, side); + } + } + diff --git a/module/minecraft/patches/net/minecraft/block/BlockReed.java.patch b/module/minecraft/patches/net/minecraft/block/BlockReed.java.patch new file mode 100644 index 000000000..9cc028bed --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockReed.java.patch @@ -0,0 +1,56 @@ +--- original/net/minecraft/block/BlockReed.java ++++ modified/net/minecraft/block/BlockReed.java +@@ -20,7 +20,7 @@ + import net.minecraftforge.fml.relauncher.Side; + import net.minecraftforge.fml.relauncher.SideOnly; + +-public class BlockReed extends Block { ++public class BlockReed extends Block implements net.minecraftforge.common.IPlantable { + public static final PropertyInteger AGE = PropertyInteger.create("age", 0, 15); + protected static final AxisAlignedBB REED_AABB = new AxisAlignedBB(0.125, 0.0, 0.125, 0.875, 1.0, 0.875); + +@@ -49,12 +49,16 @@ + + if (i < 3) { + int j = state.getValue(AGE); ++ ++ if(net.minecraftforge.common.ForgeHooks.onCropsGrowPre(worldIn, pos, state, true)) { + if (j == 15) { + worldIn.setBlockState(pos.up(), this.getDefaultState()); + worldIn.setBlockState(pos, state.withProperty(AGE, 0), 4); + } else { + worldIn.setBlockState(pos, state.withProperty(AGE, j + 1), 4); + } ++ net.minecraftforge.common.ForgeHooks.onCropsGrowPost(worldIn, pos, state, worldIn.getBlockState(pos)); ++ } + } + } + } +@@ -63,7 +67,10 @@ + /** Checks if this block can be placed exactly at the given position. */ + @Override + public boolean canPlaceBlockAt(World worldIn, BlockPos pos) { +- Block block = worldIn.getBlockState(pos.down()).getBlock(); ++ IBlockState state = worldIn.getBlockState(pos.down()); ++ Block block = state.getBlock(); ++ if (block.canSustainPlant(state, worldIn, pos.down(), EnumFacing.UP, this)) return true; ++ + if (block == this) { + return true; + } +@@ -157,6 +164,15 @@ + } + + @Override ++ public net.minecraftforge.common.EnumPlantType getPlantType(IBlockAccess world, BlockPos pos) { ++ return net.minecraftforge.common.EnumPlantType.Beach; ++ } ++ @Override ++ public IBlockState getPlant(IBlockAccess world, BlockPos pos) { ++ return this.getDefaultState(); ++ } ++ ++ @Override + protected BlockStateContainer createBlockState() { + return new BlockStateContainer(this, AGE); + } diff --git a/module/minecraft/patches/net/minecraft/block/BlockRotatedPillar.java.patch b/module/minecraft/patches/net/minecraft/block/BlockRotatedPillar.java.patch new file mode 100644 index 000000000..9d47586fc --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockRotatedPillar.java.patch @@ -0,0 +1,21 @@ +--- original/net/minecraft/block/BlockRotatedPillar.java ++++ modified/net/minecraft/block/BlockRotatedPillar.java +@@ -29,6 +29,18 @@ + * @deprecated call via {@link IBlockState#withRotation(Rotation)} whenever possible. Implementing/overriding is fine. + */ + @Override ++ public boolean rotateBlock(net.minecraft.world.World world, BlockPos pos, EnumFacing axis) { ++ net.minecraft.block.state.IBlockState state = world.getBlockState(pos); ++ for (net.minecraft.block.properties.IProperty prop : state.getProperties().keySet()) { ++ if (prop.getName().equals("axis")) { ++ world.setBlockState(pos, state.cycleProperty(prop)); ++ return true; ++ } ++ } ++ return false; ++ } ++ ++ @Override + public IBlockState withRotation(IBlockState state, Rotation rot) { + switch (rot) { + case COUNTERCLOCKWISE_90: diff --git a/module/minecraft/patches/net/minecraft/block/BlockSapling.java.patch b/module/minecraft/patches/net/minecraft/block/BlockSapling.java.patch new file mode 100644 index 000000000..ee0d782fd --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockSapling.java.patch @@ -0,0 +1,19 @@ +--- original/net/minecraft/block/BlockSapling.java ++++ modified/net/minecraft/block/BlockSapling.java +@@ -50,6 +50,8 @@ + public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand) { + if (!worldIn.isRemote) { + super.updateTick(worldIn, pos, state, rand); ++ ++ if (!worldIn.isAreaLoaded(pos, 1)) return; // Forge: prevent loading unloaded chunks when checking neighbor's light + if (worldIn.getLightFromNeighbors(pos.up()) >= 9 && rand.nextInt(7) == 0) { + this.grow(worldIn, pos, state, rand); + } +@@ -65,6 +67,7 @@ + } + + public void generateTree(World worldIn, BlockPos pos, IBlockState state, Random rand) { ++ if (!net.minecraftforge.event.terraingen.TerrainGen.saplingGrowTree(worldIn, rand, pos)) return; + WorldGenerator worldgenerator = rand.nextInt(10) == 0 ? new WorldGenBigTree(true) : new WorldGenTrees(true); + int i = 0; + int j = 0; diff --git a/module/minecraft/patches/net/minecraft/block/BlockSkull.java.patch b/module/minecraft/patches/net/minecraft/block/BlockSkull.java.patch new file mode 100644 index 000000000..620a33cea --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockSkull.java.patch @@ -0,0 +1,54 @@ +--- original/net/minecraft/block/BlockSkull.java ++++ modified/net/minecraft/block/BlockSkull.java +@@ -144,16 +144,12 @@ + + /** Spawns this Block's drops into the World as EntityItems. */ + @Override +- public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, IBlockState state, float chance, int fortune) { +- } +- +- /** Called before the Block is set to air in the world. Called regardless of if the player's tool can actually collect this block */ +- @Override + public void onBlockHarvested(World worldIn, BlockPos pos, IBlockState state, EntityPlayer player) { + if (player.capabilities.isCreativeMode) { + state = state.withProperty(NODROP, true); + worldIn.setBlockState(pos, state, 4); + } ++ this.dropBlockAsItem(worldIn, pos, state, 0); + + super.onBlockHarvested(worldIn, pos, state, player); + } +@@ -161,12 +157,18 @@ + /** Called serverside after this block is replaced with another in Chunk, but before the Tile Entity is updated */ + @Override + public void breakBlock(World worldIn, BlockPos pos, IBlockState state) { +- if (!worldIn.isRemote) { ++ super.breakBlock(worldIn, pos, state); ++ } ++ ++ @Override ++ public void getDrops(net.minecraft.util.NonNullList drops, IBlockAccess worldIn, BlockPos pos, IBlockState state, int fortune) { ++ { + if (!state.getValue(NODROP)) { + TileEntity tileentity = worldIn.getTileEntity(pos); + if (tileentity instanceof TileEntitySkull) { + TileEntitySkull tileentityskull = (TileEntitySkull)tileentity; +- ItemStack itemstack = this.getItem(worldIn, pos, state); ++ ItemStack itemstack = new ItemStack(Items.SKULL, 1, tileentityskull.getSkullType()); ++ + if (tileentityskull.getSkullType() == 3 && tileentityskull.getPlayerProfile() != null) { + itemstack.setTagCompound(new NBTTagCompound()); + NBTTagCompound nbttagcompound = new NBTTagCompound(); +@@ -174,11 +176,9 @@ + itemstack.getTagCompound().setTag("SkullOwner", nbttagcompound); + } + +- spawnAsEntity(worldIn, pos, itemstack); ++ drops.add(itemstack); + } + } +- +- super.breakBlock(worldIn, pos, state); + } + } + diff --git a/module/minecraft/patches/net/minecraft/block/BlockSlab.java.patch b/module/minecraft/patches/net/minecraft/block/BlockSlab.java.patch new file mode 100644 index 000000000..fe01748ee --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockSlab.java.patch @@ -0,0 +1,65 @@ +--- original/net/minecraft/block/BlockSlab.java ++++ modified/net/minecraft/block/BlockSlab.java +@@ -90,6 +90,18 @@ + + /** Called by ItemBlocks just before a block is actually set in the world, to allow for adjustments to the IBlockstate */ + @Override ++ public boolean doesSideBlockRendering(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing face) { ++ if (net.minecraftforge.common.ForgeModContainer.disableStairSlabCulling) ++ return super.doesSideBlockRendering(state, world, pos, face); ++ ++ if ( state.isOpaqueCube() ) ++ return true; ++ ++ EnumBlockHalf side = state.getValue(HALF); ++ return (side == EnumBlockHalf.TOP && face == EnumFacing.UP) || (side == EnumBlockHalf.BOTTOM && face == EnumFacing.DOWN); ++ } ++ ++ @Override + public IBlockState getStateForPlacement( + World worldIn, + BlockPos pos, +@@ -133,26 +145,28 @@ + + if (side != EnumFacing.UP && side != EnumFacing.DOWN && !super.shouldSideBeRendered(blockState, blockAccess, pos, side)) { + return false; +- } +- +- IBlockState iblockstate = blockAccess.getBlockState(pos.offset(side)); +- boolean flag = isHalfSlab(iblockstate) && iblockstate.getValue(HALF) == BlockSlab.EnumBlockHalf.TOP; +- boolean flag1 = isHalfSlab(blockState) && blockState.getValue(HALF) == BlockSlab.EnumBlockHalf.TOP; +- if (flag1) { +- if (side == EnumFacing.DOWN) { ++ } else if (false) { // Forge: Additional logic breaks doesSideBlockRendering and is no longer useful. ++ IBlockState iblockstate = blockAccess.getBlockState(pos.offset(side)); ++ boolean flag = isHalfSlab(iblockstate) && iblockstate.getValue(HALF) == BlockSlab.EnumBlockHalf.TOP; ++ boolean flag1 = isHalfSlab(blockState) && blockState.getValue(HALF) == BlockSlab.EnumBlockHalf.TOP; ++ if (flag1) { ++ if (side == EnumFacing.DOWN) { ++ return true; ++ } else { ++ return side == EnumFacing.UP && super.shouldSideBeRendered(blockState, blockAccess, pos, side) ++ ? true ++ : !isHalfSlab(iblockstate) || !flag; ++ } ++ } else if (side == EnumFacing.UP) { + return true; + } else { +- return side == EnumFacing.UP && super.shouldSideBeRendered(blockState, blockAccess, pos, side) ++ return side == EnumFacing.DOWN && super.shouldSideBeRendered(blockState, blockAccess, pos, side) + ? true +- : !isHalfSlab(iblockstate) || !flag; ++ : !isHalfSlab(iblockstate) || flag; + } +- } else if (side == EnumFacing.UP) { +- return true; +- } else { +- return side == EnumFacing.DOWN && super.shouldSideBeRendered(blockState, blockAccess, pos, side) +- ? true +- : !isHalfSlab(iblockstate) || flag; + } ++ ++ return super.shouldSideBeRendered(blockState, blockAccess, pos, side); + } + + @SideOnly(Side.CLIENT) diff --git a/module/minecraft/patches/net/minecraft/block/BlockSnow.java.patch b/module/minecraft/patches/net/minecraft/block/BlockSnow.java.patch new file mode 100644 index 000000000..d005643ad --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockSnow.java.patch @@ -0,0 +1,59 @@ +--- original/net/minecraft/block/BlockSnow.java ++++ modified/net/minecraft/block/BlockSnow.java +@@ -119,8 +119,8 @@ + if (block != Blocks.ICE && block != Blocks.PACKED_ICE && block != Blocks.BARRIER) { + BlockFaceShape blockfaceshape = iblockstate.getBlockFaceShape(worldIn, pos.down(), EnumFacing.UP); + return blockfaceshape == BlockFaceShape.SOLID +- || iblockstate.getMaterial() == Material.LEAVES +- || block == this && iblockstate.getValue(LAYERS) == 8; ++ || iblockstate.getBlock().isLeaves(iblockstate, worldIn, pos.down()) ++ || block == this && iblockstate.getValue(LAYERS) == 8; + } else { + return false; + } +@@ -134,7 +134,6 @@ + + private boolean checkAndDropBlock(World worldIn, BlockPos pos, IBlockState state) { + if (!this.canPlaceBlockAt(worldIn, pos)) { +- this.dropBlockAsItem(worldIn, pos, state, 0); + worldIn.setBlockToAir(pos); + return false; + } else { +@@ -147,9 +146,8 @@ + public void harvestBlock( + World worldIn, EntityPlayer player, BlockPos pos, IBlockState state, @Nullable TileEntity te, ItemStack stack + ) { +- spawnAsEntity(worldIn, pos, new ItemStack(Items.SNOWBALL, state.getValue(LAYERS) + 1, 0)); ++ super.harvestBlock(worldIn, player, pos, state, te, stack); + worldIn.setBlockToAir(pos); +- player.addStat(StatList.getBlockStats(this)); + } + + /** Get the Item that this Block should drop when harvested. */ +@@ -161,13 +159,12 @@ + /** Returns the quantity of items to drop on block destruction. */ + @Override + public int quantityDropped(Random random) { +- return 0; ++ return 1; + } + + @Override + public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand) { + if (worldIn.getLightFor(EnumSkyBlock.BLOCK, pos) > 11) { +- this.dropBlockAsItem(worldIn, pos, worldIn.getBlockState(pos), 0); + worldIn.setBlockToAir(pos); + } + } +@@ -205,6 +202,11 @@ + } + + @Override ++ public int quantityDropped(IBlockState state, int fortune, Random random) { ++ return state.getValue(LAYERS) + 1; ++ } ++ ++ @Override + protected BlockStateContainer createBlockState() { + return new BlockStateContainer(this, LAYERS); + } diff --git a/module/minecraft/patches/net/minecraft/block/BlockStairs.java.patch b/module/minecraft/patches/net/minecraft/block/BlockStairs.java.patch new file mode 100644 index 000000000..a2be2ec53 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockStairs.java.patch @@ -0,0 +1,32 @@ +--- original/net/minecraft/block/BlockStairs.java ++++ modified/net/minecraft/block/BlockStairs.java +@@ -601,7 +601,29 @@ + protected BlockStateContainer createBlockState() { + return new BlockStateContainer(this, FACING, HALF, SHAPE); + } ++ @Override ++ public boolean doesSideBlockRendering(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing face) ++ { ++ if (net.minecraftforge.common.ForgeModContainer.disableStairSlabCulling) ++ return super.doesSideBlockRendering(state, world, pos, face); + ++ if ( state.isOpaqueCube() ) ++ return true; ++ ++ state = this.getActualState(state, world, pos); ++ ++ EnumHalf half = state.getValue(HALF); ++ EnumFacing side = state.getValue(FACING); ++ EnumShape shape = state.getValue(SHAPE); ++ if (face == EnumFacing.UP) return half == EnumHalf.TOP; ++ if (face == EnumFacing.DOWN) return half == EnumHalf.BOTTOM; ++ if (shape == EnumShape.OUTER_LEFT || shape == EnumShape.OUTER_RIGHT) return false; ++ if (face == side) return true; ++ if (shape == EnumShape.INNER_LEFT && face.rotateY() == side) return true; ++ if (shape == EnumShape.INNER_RIGHT && face.rotateYCCW() == side) return true; ++ return false; ++ } ++ + public enum EnumHalf implements IStringSerializable { + TOP("top"), + BOTTOM("bottom"); diff --git a/module/minecraft/patches/net/minecraft/block/BlockStaticLiquid.java.patch b/module/minecraft/patches/net/minecraft/block/BlockStaticLiquid.java.patch new file mode 100644 index 000000000..7ffcf1f14 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockStaticLiquid.java.patch @@ -0,0 +1,36 @@ +--- original/net/minecraft/block/BlockStaticLiquid.java ++++ modified/net/minecraft/block/BlockStaticLiquid.java +@@ -41,17 +41,19 @@ + + for (int j = 0; j < i; j++) { + blockpos = blockpos.add(rand.nextInt(3) - 1, 1, rand.nextInt(3) - 1); +- if (blockpos.getY() >= 0 && blockpos.getY() < 256 && !worldIn.isBlockLoaded(blockpos)) { ++ ++ if (blockpos.getY() >= 0 && blockpos.getY() < worldIn.getHeight() && !worldIn.isBlockLoaded(blockpos)) { + return; + } + +- Block block = worldIn.getBlockState(blockpos).getBlock(); +- if (block.material == Material.AIR) { ++ IBlockState block = worldIn.getBlockState(blockpos); ++ ++ if (block.getBlock().isAir(block, worldIn, blockpos)) { + if (this.isSurroundingBlockFlammable(worldIn, blockpos)) { +- worldIn.setBlockState(blockpos, Blocks.FIRE.getDefaultState()); ++ worldIn.setBlockState(blockpos, net.minecraftforge.event.ForgeEventFactory.fireFluidPlaceBlockEvent(worldIn, blockpos, pos, Blocks.FIRE.getDefaultState())); + return; + } +- } else if (block.material.blocksMovement()) { ++ } else if (block.getMaterial().blocksMovement()) { + return; + } + } +@@ -63,7 +65,7 @@ + } + + if (worldIn.isAirBlock(blockpos1.up()) && this.getCanBlockBurn(worldIn, blockpos1)) { +- worldIn.setBlockState(blockpos1.up(), Blocks.FIRE.getDefaultState()); ++ worldIn.setBlockState(blockpos1.up(), net.minecraftforge.event.ForgeEventFactory.fireFluidPlaceBlockEvent(worldIn, blockpos1.up(), pos, Blocks.FIRE.getDefaultState())); + } + } + } diff --git a/module/minecraft/patches/net/minecraft/block/BlockStem.java.patch b/module/minecraft/patches/net/minecraft/block/BlockStem.java.patch new file mode 100644 index 000000000..51eb101c6 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockStem.java.patch @@ -0,0 +1,65 @@ +--- original/net/minecraft/block/BlockStem.java ++++ modified/net/minecraft/block/BlockStem.java +@@ -71,13 +71,16 @@ + @Override + public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand) { + super.updateTick(worldIn, pos, state, rand); ++ ++ if (!worldIn.isAreaLoaded(pos, 1)) return; // Forge: prevent loading unloaded chunks when checking neighbor's light + if (worldIn.getLightFromNeighbors(pos.up()) >= 9) { + float f = BlockCrops.getGrowthChance(this, worldIn, pos); +- if (rand.nextInt((int)(25.0F / f) + 1) == 0) { ++ ++ if(net.minecraftforge.common.ForgeHooks.onCropsGrowPre(worldIn, pos, state, rand.nextInt((int)(25.0F / f) + 1) == 0)) { + int i = state.getValue(AGE); + if (i < 7) { +- state = state.withProperty(AGE, i + 1); +- worldIn.setBlockState(pos, state, 2); ++ IBlockState newState = state.withProperty(AGE, i + 1); ++ worldIn.setBlockState(pos, newState, 2); + } else { + for (EnumFacing enumfacing : EnumFacing.Plane.HORIZONTAL) { + if (worldIn.getBlockState(pos.offset(enumfacing)).getBlock() == this.crop) { +@@ -86,12 +89,17 @@ + } + + pos = pos.offset(EnumFacing.Plane.HORIZONTAL.random(rand)); +- Block block = worldIn.getBlockState(pos.down()).getBlock(); +- if (worldIn.getBlockState(pos).getBlock().material == Material.AIR +- && (block == Blocks.FARMLAND || block == Blocks.DIRT || block == Blocks.GRASS)) { ++ IBlockState soil = worldIn.getBlockState(pos.down()); ++ Block block = soil.getBlock(); ++ ++ if (worldIn.isAirBlock(pos) ++ && (block.canSustainPlant(soil, worldIn, pos.down(), EnumFacing.UP, this) ++ || block == Blocks.DIRT ++ || block == Blocks.GRASS)) { + worldIn.setBlockState(pos, this.crop.getDefaultState()); + } + } ++ net.minecraftforge.common.ForgeHooks.onCropsGrowPost(worldIn, pos, state, worldIn.getBlockState(pos)); + } + } + } +@@ -105,14 +113,18 @@ + @Override + public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, IBlockState state, float chance, int fortune) { + super.dropBlockAsItemWithChance(worldIn, pos, state, chance, fortune); +- if (!worldIn.isRemote) { ++ } ++ ++ @Override ++ public void getDrops(net.minecraft.util.NonNullList drops, IBlockAccess world, BlockPos pos, IBlockState state, int fortune) { ++ { + Item item = this.getSeedItem(); + if (item != null) { + int i = state.getValue(AGE); + + for (int j = 0; j < 3; j++) { +- if (worldIn.rand.nextInt(15) <= i) { +- spawnAsEntity(worldIn, pos, new ItemStack(item)); ++ if (RANDOM.nextInt(15) <= i) { ++ drops.add(new ItemStack(item)); + } + } + } diff --git a/module/minecraft/patches/net/minecraft/block/BlockTallGrass.java.patch b/module/minecraft/patches/net/minecraft/block/BlockTallGrass.java.patch new file mode 100644 index 000000000..f636179c1 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockTallGrass.java.patch @@ -0,0 +1,51 @@ +--- original/net/minecraft/block/BlockTallGrass.java ++++ modified/net/minecraft/block/BlockTallGrass.java +@@ -21,7 +21,7 @@ + import net.minecraft.world.IBlockAccess; + import net.minecraft.world.World; + +-public class BlockTallGrass extends BlockBush implements IGrowable { ++public class BlockTallGrass extends BlockBush implements IGrowable, net.minecraftforge.common.IShearable { + public static final PropertyEnum TYPE = PropertyEnum.create("type", BlockTallGrass.EnumType.class); + protected static final AxisAlignedBB TALL_GRASS_AABB = new AxisAlignedBB(0.099999994F, 0.0, 0.099999994F, 0.9F, 0.8F, 0.9F); + +@@ -38,7 +38,7 @@ + + @Override + public boolean canBlockStay(World worldIn, BlockPos pos, IBlockState state) { +- return this.canSustainBush(worldIn.getBlockState(pos.down())); ++ return super.canBlockStay(worldIn, pos, state); + } + + /** Whether this Block can be replaced directly by other blocks (true for e.g. tall grass) */ +@@ -50,7 +50,7 @@ + /** Get the Item that this Block should drop when harvested. */ + @Override + public Item getItemDropped(IBlockState state, Random rand, int fortune) { +- return rand.nextInt(8) == 0 ? Items.WHEAT_SEEDS : Items.AIR; ++ return null; + } + + /** Get the quantity dropped based on the given fortune level */ +@@ -173,4 +173,21 @@ + } + } + } ++ ++ @Override public boolean isShearable(ItemStack item, IBlockAccess world, BlockPos pos) { ++ return true; ++ } ++ ++ @Override ++ public NonNullList onSheared(ItemStack item, IBlockAccess world, BlockPos pos, int fortune) { ++ return NonNullList.withSize(1, new ItemStack(Blocks.TALLGRASS, 1, world.getBlockState(pos).getValue(TYPE).getMeta())); ++ } ++ ++ @Override ++ public void getDrops(NonNullList drops, IBlockAccess world, BlockPos pos, IBlockState state, int fortune) { ++ if (RANDOM.nextInt(8) != 0) return; ++ ItemStack seed = net.minecraftforge.common.ForgeHooks.getGrassSeed(RANDOM, fortune); ++ if (!seed.isEmpty()) ++ drops.add(seed); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/block/BlockTorch.java.patch b/module/minecraft/patches/net/minecraft/block/BlockTorch.java.patch new file mode 100644 index 000000000..1fb859998 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockTorch.java.patch @@ -0,0 +1,19 @@ +--- original/net/minecraft/block/BlockTorch.java ++++ modified/net/minecraft/block/BlockTorch.java +@@ -82,14 +82,8 @@ + } + + private boolean canPlaceOn(World worldIn, BlockPos pos) { +- Block block = worldIn.getBlockState(pos).getBlock(); +- boolean flag = block == Blocks.END_GATEWAY || block == Blocks.LIT_PUMPKIN; +- if (worldIn.getBlockState(pos).isTopSolid()) { +- return !flag; +- } +- +- boolean flag1 = block instanceof BlockFence || block == Blocks.GLASS || block == Blocks.COBBLESTONE_WALL || block == Blocks.STAINED_GLASS; +- return flag1 && !flag; ++ IBlockState state = worldIn.getBlockState(pos); ++ return state.getBlock().canPlaceTorchOnTop(state, worldIn, pos); + } + + /** Checks if this block can be placed exactly at the given position. */ diff --git a/module/minecraft/patches/net/minecraft/block/BlockTrapDoor.java.patch b/module/minecraft/patches/net/minecraft/block/BlockTrapDoor.java.patch new file mode 100644 index 000000000..918e8cb41 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockTrapDoor.java.patch @@ -0,0 +1,20 @@ +--- original/net/minecraft/block/BlockTrapDoor.java ++++ modified/net/minecraft/block/BlockTrapDoor.java +@@ -279,6 +279,17 @@ + ? BlockFaceShape.SOLID + : BlockFaceShape.UNDEFINED; + } ++ @Override ++ public boolean isLadder(IBlockState state, IBlockAccess world, BlockPos pos, EntityLivingBase entity) ++ { ++ if (state.getValue(OPEN)) ++ { ++ IBlockState down = world.getBlockState(pos.down()); ++ if (down.getBlock() == net.minecraft.init.Blocks.LADDER) ++ return down.getValue(BlockLadder.FACING) == state.getValue(FACING); ++ } ++ return false; ++ } + + public enum DoorHalf implements IStringSerializable { + TOP("top"), diff --git a/module/minecraft/patches/net/minecraft/block/BlockVine.java.patch b/module/minecraft/patches/net/minecraft/block/BlockVine.java.patch new file mode 100644 index 000000000..a7131cc46 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockVine.java.patch @@ -0,0 +1,55 @@ +--- original/net/minecraft/block/BlockVine.java ++++ modified/net/minecraft/block/BlockVine.java +@@ -27,7 +27,7 @@ + import net.minecraftforge.fml.relauncher.Side; + import net.minecraftforge.fml.relauncher.SideOnly; + +-public class BlockVine extends Block { ++public class BlockVine extends Block implements net.minecraftforge.common.IShearable { + public static final PropertyBool UP = PropertyBool.create("up"); + public static final PropertyBool NORTH = PropertyBool.create("north"); + public static final PropertyBool EAST = PropertyBool.create("east"); +@@ -195,7 +195,7 @@ + @Override + public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand) { + if (!worldIn.isRemote) { +- if (worldIn.rand.nextInt(4) == 0) { ++ if (worldIn.rand.nextInt(4) == 0 && worldIn.isAreaLoaded(pos, 4)) { // Forge: check area to prevent loading unloaded chunks + int i = 4; + int j = 5; + boolean flag = false; +@@ -273,7 +273,8 @@ + BlockPos blockpos3 = pos.offset(enumfacing2); + IBlockState iblockstate = worldIn.getBlockState(blockpos3); + Block block = iblockstate.getBlock(); +- if (block.material == Material.AIR) { ++ ++ if (block.isAir(iblockstate, worldIn, blockpos3)) { + EnumFacing enumfacing = enumfacing2.rotateY(); + EnumFacing enumfacing1 = enumfacing2.rotateYCCW(); + boolean flag1 = state.getValue(getPropertyFor(enumfacing)); +@@ -462,15 +463,16 @@ + return i; + } + +- /** +- * Get the geometry of the queried face at the given position and state. This is used to decide whether things like buttons are allowed to be placed on the face, or how glass panes connect to the face, among other things. +- *

+- * Common values are {@code SOLID}, which is the default, and {@code UNDEFINED}, which represents something that does not fit the other descriptions and will generally cause other things not to connect to the face. +- * +- * @return an approximation of the form of the given face +- * @deprecated call via {@link IBlockState#getBlockFaceShape(IBlockAccess,BlockPos,EnumFacing)} whenever possible. Implementing/overriding is fine. +- */ ++ /*************************FORGE START***********************************/ ++ @Override public boolean isLadder(IBlockState state, IBlockAccess world, BlockPos pos, EntityLivingBase entity){ return true; } ++ @Override public boolean isShearable(ItemStack item, IBlockAccess world, BlockPos pos){ return true; } + @Override ++ public java.util.List onSheared(ItemStack item, IBlockAccess world, BlockPos pos, int fortune) { ++ return java.util.Arrays.asList(new ItemStack(this, 1)); ++ } ++ /*************************FORGE END***********************************/ ++ ++ @Override + public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face) { + return BlockFaceShape.UNDEFINED; + } diff --git a/module/minecraft/patches/net/minecraft/block/BlockWall.java.patch b/module/minecraft/patches/net/minecraft/block/BlockWall.java.patch new file mode 100644 index 000000000..239627cf3 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockWall.java.patch @@ -0,0 +1,41 @@ +--- original/net/minecraft/block/BlockWall.java ++++ modified/net/minecraft/block/BlockWall.java +@@ -216,10 +216,10 @@ + /** Get the actual Block state of this Block at the given position. This applies properties not visible in the metadata, such as fence connections. */ + @Override + public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos) { +- boolean flag = this.canConnectTo(worldIn, pos.north(), EnumFacing.SOUTH); +- boolean flag1 = this.canConnectTo(worldIn, pos.east(), EnumFacing.WEST); +- boolean flag2 = this.canConnectTo(worldIn, pos.south(), EnumFacing.NORTH); +- boolean flag3 = this.canConnectTo(worldIn, pos.west(), EnumFacing.EAST); ++ boolean flag = canWallConnectTo(worldIn, pos, EnumFacing.NORTH); ++ boolean flag1 = canWallConnectTo(worldIn, pos, EnumFacing.EAST); ++ boolean flag2 = canWallConnectTo(worldIn, pos, EnumFacing.SOUTH); ++ boolean flag3 = canWallConnectTo(worldIn, pos, EnumFacing.WEST); + boolean flag4 = flag && !flag1 && flag2 && !flag3 || !flag && flag1 && !flag2 && flag3; + return state.withProperty(UP, !flag4 || !worldIn.isAirBlock(pos.up())) + .withProperty(NORTH, flag) +@@ -245,7 +245,23 @@ + public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face) { + return face != EnumFacing.UP && face != EnumFacing.DOWN ? BlockFaceShape.MIDDLE_POLE_THICK : BlockFaceShape.CENTER_BIG; + } ++ /* ======================================== FORGE START ======================================== */ + ++ @Override ++ public boolean canBeConnectedTo(IBlockAccess world, BlockPos pos, EnumFacing facing) ++ { ++ return canConnectTo(world, pos.offset(facing), facing.getOpposite()); ++ } ++ ++ private boolean canWallConnectTo(IBlockAccess world, BlockPos pos, EnumFacing facing) ++ { ++ BlockPos other = pos.offset(facing); ++ Block block = world.getBlockState(other).getBlock(); ++ return block.canBeConnectedTo(world, other, facing.getOpposite()) || canConnectTo(world, other, facing.getOpposite()); ++ } ++ ++ /* ======================================== FORGE END ======================================== */ ++ + public enum EnumType implements IStringSerializable { + NORMAL(0, "cobblestone", "normal"), + MOSSY(1, "mossy_cobblestone", "mossy"); diff --git a/module/minecraft/patches/net/minecraft/block/BlockWeb.java.patch b/module/minecraft/patches/net/minecraft/block/BlockWeb.java.patch new file mode 100644 index 000000000..9e420f0b7 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/BlockWeb.java.patch @@ -0,0 +1,28 @@ +--- original/net/minecraft/block/BlockWeb.java ++++ modified/net/minecraft/block/BlockWeb.java +@@ -22,7 +22,7 @@ + import net.minecraftforge.fml.relauncher.Side; + import net.minecraftforge.fml.relauncher.SideOnly; + +-public class BlockWeb extends Block { ++public class BlockWeb extends Block implements net.minecraftforge.common.IShearable { + public BlockWeb() { + super(Material.WEB); + this.setCreativeTab(CreativeTabs.DECORATIONS); +@@ -96,6 +96,16 @@ + * @deprecated call via {@link IBlockState#getBlockFaceShape(IBlockAccess,BlockPos,EnumFacing)} whenever possible. Implementing/overriding is fine. + */ + @Override ++ public boolean isShearable(ItemStack item, IBlockAccess world, BlockPos pos) { ++ return true; ++ } ++ ++ @Override ++ public java.util.List onSheared(ItemStack item, IBlockAccess world, BlockPos pos, int fortune) { ++ return com.google.common.collect.Lists.newArrayList(new ItemStack(Item.getItemFromBlock(this))); ++ } ++ ++ @Override + public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face) { + return BlockFaceShape.UNDEFINED; + } diff --git a/module/minecraft/patches/net/minecraft/block/SoundType.java.patch b/module/minecraft/patches/net/minecraft/block/SoundType.java.patch new file mode 100644 index 000000000..f7df3d459 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/SoundType.java.patch @@ -0,0 +1,18 @@ +--- original/net/minecraft/block/SoundType.java ++++ modified/net/minecraft/block/SoundType.java +@@ -147,7 +147,6 @@ + return this.pitch; + } + +- @SideOnly(Side.CLIENT) + public SoundEvent getBreakSound() { + return this.breakSound; + } +@@ -160,7 +159,6 @@ + return this.placeSound; + } + +- @SideOnly(Side.CLIENT) + public SoundEvent getHitSound() { + return this.hitSound; + } diff --git a/module/minecraft/patches/net/minecraft/block/state/BlockPistonStructureHelper.java.patch b/module/minecraft/patches/net/minecraft/block/state/BlockPistonStructureHelper.java.patch new file mode 100644 index 000000000..92d0d5f94 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/state/BlockPistonStructureHelper.java.patch @@ -0,0 +1,49 @@ +--- original/net/minecraft/block/state/BlockPistonStructureHelper.java ++++ modified/net/minecraft/block/state/BlockPistonStructureHelper.java +@@ -51,7 +51,8 @@ + + for (int i = 0; i < this.toMove.size(); i++) { + BlockPos blockpos = this.toMove.get(i); +- if (this.world.getBlockState(blockpos).getBlock() == Blocks.SLIME_BLOCK && !this.addBranchingBlocks(blockpos)) { ++ ++ if (this.world.getBlockState(blockpos).getBlock().isStickyBlock(this.world.getBlockState(blockpos)) && !this.addBranchingBlocks(blockpos)) { + return false; + } + } +@@ -63,7 +64,8 @@ + private boolean addBlockLine(BlockPos origin, EnumFacing p_177251_2_) { + IBlockState iblockstate = this.world.getBlockState(origin); + Block block = iblockstate.getBlock(); +- if (iblockstate.getMaterial() == Material.AIR) { ++ ++ if (iblockstate.getBlock().isAir(iblockstate, this.world, origin)) { + return true; + } + +@@ -84,7 +86,7 @@ + return false; + } + +- while (block == Blocks.SLIME_BLOCK) { ++ while (block.isStickyBlock(iblockstate)) { + BlockPos blockpos = origin.offset(this.moveDirection.getOpposite(), i); + iblockstate = this.world.getBlockState(blockpos); + block = iblockstate.getBlock(); +@@ -116,7 +118,7 @@ + + for (int l = 0; l <= k + i1; l++) { + BlockPos blockpos2 = this.toMove.get(l); +- if (this.world.getBlockState(blockpos2).getBlock() == Blocks.SLIME_BLOCK && !this.addBranchingBlocks(blockpos2)) { ++ if (this.world.getBlockState(blockpos2).getBlock().isStickyBlock(this.world.getBlockState(blockpos2)) && !this.addBranchingBlocks(blockpos2)) { + return false; + } + } +@@ -125,7 +127,7 @@ + } + + iblockstate = this.world.getBlockState(blockpos1); +- if (iblockstate.getMaterial() == Material.AIR) { ++ if (iblockstate.getBlock().isAir(iblockstate, this.world, blockpos1)) { + return true; + } + diff --git a/module/minecraft/patches/net/minecraft/block/state/BlockStateBase.java.patch b/module/minecraft/patches/net/minecraft/block/state/BlockStateBase.java.patch new file mode 100644 index 000000000..d5f0eefe4 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/state/BlockStateBase.java.patch @@ -0,0 +1,12 @@ +--- original/net/minecraft/block/state/BlockStateBase.java ++++ modified/net/minecraft/block/state/BlockStateBase.java +@@ -63,4 +63,9 @@ + + return stringbuilder.toString(); + } ++ ++ @Nullable ++ public com.google.common.collect.ImmutableTable, Comparable, IBlockState> getPropertyValueTable() { ++ return null; ++ } + } diff --git a/module/minecraft/patches/net/minecraft/block/state/BlockStateContainer.java.patch b/module/minecraft/patches/net/minecraft/block/state/BlockStateContainer.java.patch new file mode 100644 index 000000000..f50d5eb60 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/state/BlockStateContainer.java.patch @@ -0,0 +1,137 @@ +--- original/net/minecraft/block/state/BlockStateContainer.java ++++ modified/net/minecraft/block/state/BlockStateContainer.java +@@ -54,6 +54,16 @@ + private final ImmutableList validStates; + + public BlockStateContainer(Block blockIn, IProperty... properties) { ++ this(blockIn, properties, null); ++ } ++ ++ protected StateImplementation createState(Block block, ImmutableMap, Comparable> properties, @Nullable ImmutableMap, java.util.Optional> unlistedProperties) ++ { ++ return new StateImplementation(block, properties); ++ } ++ ++ protected BlockStateContainer(Block blockIn, IProperty[] properties, ImmutableMap, java.util.Optional> unlistedProperties) ++ { + this.block = blockIn; + Map> map = Maps.newHashMap(); + +@@ -68,9 +78,7 @@ + + for (List> list : Cartesian.cartesianProduct(this.getAllowedValues())) { + Map, Comparable> map1 = MapPopulator.createMap(this.properties.values(), list); +- BlockStateContainer.StateImplementation blockstatecontainer$stateimplementation = new BlockStateContainer.StateImplementation( +- blockIn, ImmutableMap.copyOf(map1) +- ); ++ BlockStateContainer.StateImplementation blockstatecontainer$stateimplementation = createState(blockIn, ImmutableMap.copyOf(map1), unlistedProperties); + map2.put(map1, blockstatecontainer$stateimplementation); + list1.add(blockstatecontainer$stateimplementation); + } +@@ -148,6 +156,13 @@ + this.block = blockIn; + this.properties = propertiesIn; + } ++ ++ protected StateImplementation(Block blockIn, ImmutableMap, Comparable> propertiesIn, ImmutableTable, Comparable, IBlockState> propertyValueTable) ++ { ++ this.block = blockIn; ++ this.properties = propertiesIn; ++ this.propertyValueTable = propertyValueTable; ++ } + + /** Get the names of all properties defined for this BlockState */ + @Override +@@ -458,5 +473,92 @@ + public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, BlockPos pos, EnumFacing facing) { + return this.block.getBlockFaceShape(worldIn, this, pos, facing); + } ++ //Forge Start ++ @Override ++ public ImmutableTable, Comparable, IBlockState> getPropertyValueTable() ++ { ++ return propertyValueTable; ++ } ++ ++ @Override ++ public int getLightOpacity(IBlockAccess world, BlockPos pos) ++ { ++ return this.block.getLightOpacity(this, world, pos); ++ } ++ ++ @Override ++ public int getLightValue(IBlockAccess world, BlockPos pos) ++ { ++ return this.block.getLightValue(this, world, pos); ++ } ++ ++ @Override ++ public boolean isSideSolid(IBlockAccess world, BlockPos pos, EnumFacing side) ++ { ++ return this.block.isSideSolid(this, world, pos, side); ++ } ++ ++ @Override ++ public boolean doesSideBlockChestOpening(IBlockAccess world, BlockPos pos, EnumFacing side) ++ { ++ return this.block.doesSideBlockChestOpening(this, world, pos, side); ++ } ++ ++ @Override ++ public boolean doesSideBlockRendering(IBlockAccess world, BlockPos pos, EnumFacing side) ++ { ++ return this.block.doesSideBlockRendering(this, world, pos, side); + } + } ++ /** ++ * Forge added class to make building things easier. ++ * Will return an instance of BlockStateContainer appropriate for ++ * the list of properties passed in. ++ * ++ * Example usage: ++ * ++ * protected BlockStateContainer createBlockState() ++ * { ++ * return (new BlockStateContainer.Builder(this)).add(FACING).add(SOME_UNLISTED).build(); ++ * } ++ * ++ */ ++ public static class Builder ++ { ++ private final Block block; ++ private final List> listed = Lists.newArrayList(); ++ private final List> unlisted = Lists.newArrayList(); ++ ++ public Builder(Block block) ++ { ++ this.block = block; ++ } ++ ++ public Builder add(IProperty... props) ++ { ++ for (IProperty prop : props) ++ this.listed.add(prop); ++ return this; ++ } ++ ++ public Builder add(net.minecraftforge.common.property.IUnlistedProperty... props) ++ { ++ for (net.minecraftforge.common.property.IUnlistedProperty prop : props) ++ this.unlisted.add(prop); ++ return this; ++ } ++ ++ public BlockStateContainer build() ++ { ++ IProperty[] listed = new IProperty[this.listed.size()]; ++ listed = this.listed.toArray(listed); ++ if (this.unlisted.size() == 0) ++ return new BlockStateContainer(this.block, listed); ++ ++ net.minecraftforge.common.property.IUnlistedProperty[] unlisted = new net.minecraftforge.common.property.IUnlistedProperty[this.unlisted.size()]; ++ unlisted = this.unlisted.toArray(unlisted); ++ ++ return new net.minecraftforge.common.property.ExtendedBlockState(this.block, listed, unlisted); ++ } ++ } ++} diff --git a/module/minecraft/patches/net/minecraft/block/state/IBlockProperties.java.patch b/module/minecraft/patches/net/minecraft/block/state/IBlockProperties.java.patch new file mode 100644 index 000000000..b099267fa --- /dev/null +++ b/module/minecraft/patches/net/minecraft/block/state/IBlockProperties.java.patch @@ -0,0 +1,31 @@ +--- original/net/minecraft/block/state/IBlockProperties.java ++++ modified/net/minecraft/block/state/IBlockProperties.java +@@ -27,10 +27,15 @@ + + boolean canEntitySpawn(Entity var1); + ++ @Deprecated //Forge location aware version below + int getLightOpacity(); + ++ int getLightOpacity(IBlockAccess world, BlockPos pos); ++ ++ @Deprecated //Forge location aware version below + int getLightValue(); + ++ int getLightValue(IBlockAccess world, BlockPos pos); + @SideOnly(Side.CLIENT) + boolean isTranslucent(); + +@@ -97,7 +102,12 @@ + RayTraceResult collisionRayTrace(World var1, BlockPos var2, Vec3d var3, Vec3d var4); + + /** Determines if the block is solid enough on the top side to support other blocks, like redstone components. */ ++ @Deprecated // Forge: Use isSideSolid(IBlockAccess, BlockPos, EnumFacing.UP) instead + boolean isTopSolid(); ++ //Forge added functions ++ boolean doesSideBlockRendering(IBlockAccess world, BlockPos pos, EnumFacing side); ++ boolean isSideSolid(IBlockAccess world, BlockPos pos, EnumFacing side); ++ boolean doesSideBlockChestOpening(IBlockAccess world, BlockPos pos, EnumFacing side); + + Vec3d getOffset(IBlockAccess var1, BlockPos var2); + diff --git a/module/minecraft/patches/net/minecraft/client/ClientBrandRetriever.java.patch b/module/minecraft/patches/net/minecraft/client/ClientBrandRetriever.java.patch new file mode 100644 index 000000000..e3c096fe8 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/ClientBrandRetriever.java.patch @@ -0,0 +1,10 @@ +--- original/net/minecraft/client/ClientBrandRetriever.java ++++ modified/net/minecraft/client/ClientBrandRetriever.java +@@ -6,6 +6,6 @@ + @SideOnly(Side.CLIENT) + public class ClientBrandRetriever { + public static String getClientModName() { +- return "vanilla"; ++ return net.minecraftforge.fml.common.FMLCommonHandler.instance().getModName(); + } + } diff --git a/module/minecraft/patches/net/minecraft/client/LoadingScreenRenderer.java.patch b/module/minecraft/patches/net/minecraft/client/LoadingScreenRenderer.java.patch new file mode 100644 index 000000000..96d519a4f --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/LoadingScreenRenderer.java.patch @@ -0,0 +1,26 @@ +--- original/net/minecraft/client/LoadingScreenRenderer.java ++++ modified/net/minecraft/client/LoadingScreenRenderer.java +@@ -119,6 +119,8 @@ + GlStateManager.clear(16640); + } + ++ try { ++ if (!net.minecraftforge.fml.client.FMLClientHandler.instance().handleLoadingScreen(scaledresolution)) { //FML Don't render while FML's pre-screen is rendering + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder bufferbuilder = tessellator.getBuffer(); + this.mc.getTextureManager().bindTexture(Gui.OPTIONS_BACKGROUND); +@@ -159,8 +161,12 @@ + .fontRenderer + .drawStringWithShadow(this.currentlyDisplayedText, (k - this.mc.fontRenderer.getStringWidth(this.currentlyDisplayedText)) / 2, l / 2 - 4 - 16, 16777215); + this.mc +- .fontRenderer +- .drawStringWithShadow(this.message, (k - this.mc.fontRenderer.getStringWidth(this.message)) / 2, l / 2 - 4 + 8, 16777215); ++ .fontRenderer ++ .drawStringWithShadow(this.message, (k - this.mc.fontRenderer.getStringWidth(this.message)) / 2, l / 2 - 4 + 8, 16777215); ++ } ++ } catch (java.io.IOException e) { ++ throw new RuntimeException(e); ++ } //FML End + this.framebuffer.unbindFramebuffer(); + if (OpenGlHelper.isFramebufferEnabled()) { + this.framebuffer.framebufferRender(k * j, l * j); diff --git a/module/minecraft/patches/net/minecraft/client/Minecraft.java.patch b/module/minecraft/patches/net/minecraft/client/Minecraft.java.patch new file mode 100644 index 000000000..1d2b83cd6 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/Minecraft.java.patch @@ -0,0 +1,625 @@ +--- original/net/minecraft/client/Minecraft.java ++++ modified/net/minecraft/client/Minecraft.java +@@ -363,6 +363,7 @@ + + public Minecraft(GameConfiguration gameConfig) { + instance = this; ++ net.minecraftforge.client.ForgeHooksClient.invalidateLog4jThreadCache(); + this.gameDir = gameConfig.folderInfo.gameDir; + this.fileAssets = gameConfig.folderInfo.assetsDir; + this.fileResourcepacks = gameConfig.folderInfo.resourcePacksDir; +@@ -375,7 +376,6 @@ + this.sessionService = new YggdrasilAuthenticationService(this.proxy, UUID.randomUUID().toString()).createMinecraftSessionService(); + this.session = gameConfig.userInfo.session; + LOGGER.info("Setting user: {}", this.session.getUsername()); +- LOGGER.debug("(Session ID is {})", this.session.getSessionID()); + this.isDemo = gameConfig.gameInfo.isDemo; + this.displayWidth = gameConfig.displayInfo.width > 0 ? gameConfig.displayInfo.width : 1; + this.displayHeight = gameConfig.displayInfo.height > 0 ? gameConfig.displayInfo.height : 1; +@@ -470,10 +470,10 @@ + this.resourceManager = new SimpleReloadableResourceManager(this.metadataSerializer); + this.languageManager = new LanguageManager(this.metadataSerializer, this.gameSettings.language); + this.resourceManager.registerReloadListener(this.languageManager); +- this.refreshResources(); ++ net.minecraftforge.fml.client.FMLClientHandler.instance().beginMinecraftLoading(this, this.defaultResourcePacks, this.resourceManager, this.metadataSerializer); + this.renderEngine = new TextureManager(this.resourceManager); + this.resourceManager.registerReloadListener(this.renderEngine); +- this.drawSplashScreen(this.renderEngine); ++ net.minecraftforge.fml.client.SplashProgress.drawVanillaScreen(this.renderEngine); + this.skinManager = new SkinManager(this.renderEngine, new File(this.fileAssets, "skins"), this.sessionService); + this.saveLoader = new AnvilSaveConverter(new File(this.gameDir, "saves"), this.dataFixer); + this.soundHandler = new SoundHandler(this.resourceManager, this.gameSettings); +@@ -491,6 +491,8 @@ + this.resourceManager.registerReloadListener(new GrassColorReloadListener()); + this.resourceManager.registerReloadListener(new FoliageColorReloadListener()); + this.mouseHelper = new MouseHelper(); ++ net.minecraftforge.fml.common.ProgressManager.ProgressBar bar= net.minecraftforge.fml.common.ProgressManager.push("Rendering Setup", 5, true); ++ bar.step("GL Setup"); + this.checkGLError("Pre startup"); + GlStateManager.enableTexture2D(); + GlStateManager.shadeModel(7425); +@@ -504,19 +506,24 @@ + GlStateManager.loadIdentity(); + GlStateManager.matrixMode(5888); + this.checkGLError("Startup"); ++ bar.step("Loading Texture Map"); + this.textureMapBlocks = new TextureMap("textures"); + this.textureMapBlocks.setMipmapLevels(this.gameSettings.mipmapLevels); + this.renderEngine.loadTickableTexture(TextureMap.LOCATION_BLOCKS_TEXTURE, this.textureMapBlocks); + this.renderEngine.bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); + this.textureMapBlocks.setBlurMipmapDirect(false, this.gameSettings.mipmapLevels > 0); ++ bar.step("Loading Model Manager"); + this.modelManager = new ModelManager(this.textureMapBlocks); + this.resourceManager.registerReloadListener(this.modelManager); + this.blockColors = BlockColors.init(); + this.itemColors = ItemColors.init(this.blockColors); ++ bar.step("Loading Item Renderer"); + this.renderItem = new RenderItem(this.renderEngine, this.modelManager, this.itemColors); + this.renderManager = new RenderManager(this.renderEngine, this.renderItem); + this.itemRenderer = new ItemRenderer(this); + this.resourceManager.registerReloadListener(this.renderItem); ++ bar.step("Loading Entity Renderer"); ++ net.minecraftforge.fml.client.SplashProgress.pause(); + this.entityRenderer = new EntityRenderer(this, this.resourceManager); + this.resourceManager.registerReloadListener(this.entityRenderer); + this.blockRenderDispatcher = new BlockRendererDispatcher(this.modelManager.getBlockModelShapes(), this.blockColors); +@@ -527,18 +534,25 @@ + this.resourceManager.registerReloadListener(this.searchTreeManager); + GlStateManager.viewport(0, 0, this.displayWidth, this.displayHeight); + this.effectRenderer = new ParticleManager(this.world, this.renderEngine); ++ net.minecraftforge.fml.client.SplashProgress.resume(); ++ net.minecraftforge.fml.common.ProgressManager.pop(bar); ++ net.minecraftforge.fml.client.FMLClientHandler.instance().finishMinecraftLoading(); ++ net.minecraftforge.client.ForgeHooksClient.clearTaskbarProgress(); + this.checkGLError("Post startup"); +- this.ingameGUI = new GuiIngame(this); ++ this.ingameGUI = new net.minecraftforge.client.GuiIngameForge(this); ++ + if (this.serverName != null) { +- this.displayGuiScreen(new GuiConnecting(new GuiMainMenu(), this, this.serverName, this.serverPort)); ++ net.minecraftforge.fml.client.FMLClientHandler.instance().connectToServerAtStartup(this.serverName, this.serverPort); + } else { + this.displayGuiScreen(new GuiMainMenu()); + } + +- this.renderEngine.deleteTexture(this.mojangLogo); ++ net.minecraftforge.fml.client.SplashProgress.clearVanillaResources(renderEngine, mojangLogo); + this.mojangLogo = null; + this.loadingScreen = new LoadingScreenRenderer(this); + this.debugRenderer = new DebugRenderer(this); ++ ++ net.minecraftforge.fml.client.FMLClientHandler.instance().onInitializationComplete(); + if (this.gameSettings.fullScreen && !this.fullscreen) { + this.toggleFullscreen(); + } +@@ -597,26 +611,14 @@ + this.metadataSerializer.registerMetadataSectionType(new LanguageMetadataSectionSerializer(), LanguageMetadataSection.class); + } + +- private void createDisplay() throws LWJGLException { ++ private void createDisplay() { + Display.setResizable(true); +- Display.setTitle("Minecraft 1.12.2"); ++ Display.setTitle("Cleanroom"); + +- try { +- Display.create(new PixelFormat().withDepthBits(24)); +- } catch (LWJGLException lwjglexception) { +- LOGGER.error("Couldn't set pixel format", lwjglexception); +- +- try { +- Thread.sleep(1000L); +- } catch (InterruptedException interruptedexception) { +- } +- +- if (this.fullscreen) { +- this.updateDisplayMode(); +- } +- +- Display.create(); +- } ++ Display.create((new PixelFormat()).withDepthBits(24)); ++ net.minecraftforge.client.ForgeHooksClient.initializeWindowsInformation(); ++ net.minecraftforge.client.ForgeHooksClient.setWindowStyle(fullscreen); ++ net.minecraftforge.client.ForgeHooksClient.initializeTaskbarAPI(); + } + + private void setInitialDisplayMode() throws LWJGLException { +@@ -679,6 +681,7 @@ + } + + private void startTimerHackThread() { ++ if (!org.apache.commons.lang3.SystemUtils.IS_OS_WINDOWS) return; + Thread thread = new Thread("Timer hack thread") { + @Override + public void run() { +@@ -691,6 +694,7 @@ + } + }; + thread.setDaemon(true); ++ thread.setPriority(Thread.MIN_PRIORITY); + thread.start(); + } + +@@ -704,22 +708,26 @@ + File file1 = new File(getMinecraft().gameDir, "crash-reports"); + File file2 = new File(file1, "crash-" + new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss").format(new Date()) + "-client.txt"); + Bootstrap.printToSYSOUT(crashReportIn.getCompleteReport()); ++ ++ int retVal; + if (crashReportIn.getFile() != null) { + Bootstrap.printToSYSOUT("#@!@# Game crashed! Crash report saved to: #@!@# " + crashReportIn.getFile()); +- System.exit(-1); ++ retVal = -1; + } else if (crashReportIn.saveToFile(file2)) { + Bootstrap.printToSYSOUT("#@!@# Game crashed! Crash report saved to: #@!@# " + file2.getAbsolutePath()); +- System.exit(-1); ++ retVal = -1; + } else { + Bootstrap.printToSYSOUT("#@?@# Game crashed! Crash report could not be saved. #@?@#"); +- System.exit(-2); ++ retVal = -2; + } ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().handleExit(retVal); + } + + public boolean isUnicode() { + return this.languageManager.isCurrentLocaleUnicode() || this.gameSettings.forceUnicodeFont; + } + ++ @Deprecated // Forge: Use selective refreshResources method in FMLClientHandler + public void refreshResources() { + List list = Lists.newArrayList(this.defaultResourcePacks); + if (this.integratedServer != null) { +@@ -902,16 +910,22 @@ + * @param guiScreenIn The {@link GuiScreen} to display. If it is {@code null}, any open GUI will be closed. + */ + public void displayGuiScreen(@Nullable GuiScreen guiScreenIn) { +- if (this.currentScreen != null) { +- this.currentScreen.onGuiClosed(); +- } +- + if (guiScreenIn == null && this.world == null) { + guiScreenIn = new GuiMainMenu(); + } else if (guiScreenIn == null && this.player.getHealth() <= 0.0F) { + guiScreenIn = new GuiGameOver(null); + } + ++ GuiScreen old = this.currentScreen; ++ net.minecraftforge.client.event.GuiOpenEvent event = new net.minecraftforge.client.event.GuiOpenEvent(guiScreenIn); ++ ++ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event)) return; ++ ++ guiScreenIn = event.getGui(); ++ if (old != null && guiScreenIn != old) { ++ old.onGuiClosed(); ++ } ++ + if (guiScreenIn instanceof GuiMainMenu || guiScreenIn instanceof GuiMultiplayer) { + this.gameSettings.showDebugInfo = false; + this.ingameGUI.getChatGUI().clearChatMessages(true); +@@ -999,7 +1013,7 @@ + long i1 = System.nanoTime() - l; + this.checkGLError("Pre render"); + this.profiler.endStartSection("sound"); +- this.soundHandler.setListener(this.player, this.timer.renderPartialTicks); ++ this.soundHandler.setListener(this.getRenderViewEntity(), this.timer.renderPartialTicks); //Forge: MC-46445 Spectator mode particles and sounds computed from where you have been before + this.profiler.endSection(); + this.profiler.startSection("render"); + GlStateManager.pushMatrix(); +@@ -1009,11 +1023,13 @@ + GlStateManager.enableTexture2D(); + this.profiler.endSection(); + if (!this.skipRenderWorld) { ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().onRenderTickStart(this.timer.renderPartialTicks); + this.profiler.endStartSection("gameRenderer"); + this.entityRenderer.updateCameraAndRender(this.isGamePaused ? this.renderPartialTicksPaused : this.timer.renderPartialTicks, i); + this.profiler.endStartSection("toasts"); + this.toastGui.drawToast(new ScaledResolution(this)); + this.profiler.endSection(); ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().onRenderTickEnd(this.timer.renderPartialTicks); + } + + this.profiler.endSection(); +@@ -1308,9 +1324,9 @@ + if (this.leftClickCounter <= 0 && !this.player.isHandActive()) { + if (leftClick && this.objectMouseOver != null && this.objectMouseOver.typeOfHit == RayTraceResult.Type.BLOCK) { + BlockPos blockpos = this.objectMouseOver.getBlockPos(); +- if (this.world.getBlockState(blockpos).getMaterial() != Material.AIR +- && this.playerController.onPlayerDamageBlock(blockpos, this.objectMouseOver.sideHit)) { +- this.effectRenderer.addBlockHitEffects(blockpos, this.objectMouseOver.sideHit); ++ ++ if (!this.world.isAirBlock(blockpos) && this.playerController.onPlayerDamageBlock(blockpos, this.objectMouseOver.sideHit)) { ++ this.effectRenderer.addBlockHitEffects(blockpos, this.objectMouseOver); + this.player.swingArm(EnumHand.MAIN_HAND); + } + } else { +@@ -1333,7 +1349,8 @@ + break; + case BLOCK: + BlockPos blockpos = this.objectMouseOver.getBlockPos(); +- if (this.world.getBlockState(blockpos).getMaterial() != Material.AIR) { ++ ++ if (!this.world.isAirBlock(blockpos)) { + this.playerController.clickBlock(blockpos, this.objectMouseOver.sideHit); + break; + } +@@ -1343,6 +1360,7 @@ + } + + this.player.resetCooldown(); ++ net.minecraftforge.common.ForgeHooks.onEmptyLeftClick(this.player); + } + + this.player.swingArm(EnumHand.MAIN_HAND); +@@ -1399,6 +1417,7 @@ + } + } + ++ if (itemstack.isEmpty() && (this.objectMouseOver == null || this.objectMouseOver.typeOfHit == RayTraceResult.Type.MISS)) net.minecraftforge.common.ForgeHooks.onEmptyClick(this.player, enumhand); + if (!itemstack.isEmpty() + && this.playerController.processRightClick(this.player, this.world, enumhand) == EnumActionResult.SUCCESS) { + this.entityRenderer.itemRenderer.resetEquippedProgress(enumhand); +@@ -1411,6 +1430,10 @@ + + /** Toggles fullscreen mode. */ + public void toggleFullscreen() { ++ if (net.minecraftforge.common.ForgeEarlyConfig.WINDOW_BORDERLESS_REPLACES_FULLSCREEN) { ++ Display.toggleBorderless(); ++ return; ++ } + try { + this.fullscreen = !this.fullscreen; + this.gameSettings.fullScreen = this.fullscreen; +@@ -1445,6 +1468,10 @@ + } + + Display.setFullscreen(this.fullscreen); ++ if (!this.fullscreen && (Util.getOSType() == Util.EnumOS.WINDOWS)) { //Forge: Fix MC-68754, Screen is not resizeable after exiting fullscreen due to LWJGL bug https://github.com/LWJGL/lwjgl/issues/142 which is fixed, but not in the version MC ships ++ Display.setResizable(false); ++ Display.setResizable(true); ++ } + Display.setVSyncEnabled(this.gameSettings.enableVsync); + this.updateDisplay(); + } catch (Exception exception) { +@@ -1483,6 +1510,8 @@ + this.rightClickDelayTimer--; + } + ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().onPreClientTick(); ++ + this.profiler.startSection("gui"); + if (!this.isGamePaused) { + this.ingameGUI.updateTick(); +@@ -1632,6 +1661,7 @@ + } + + this.profiler.endSection(); ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().onPostClientTick(); + this.systemTime = getSystemTime(); + } + +@@ -1705,6 +1735,7 @@ + } + } + } ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().fireKeyInput(); + } + + this.processKeyBinds(); +@@ -1896,6 +1927,8 @@ + + private void runTickMouse() throws IOException { + while (Mouse.next()) { ++ if (net.minecraftforge.client.ForgeHooksClient.postMouseEvent()) continue; ++ + int i = Mouse.getEventButton(); + KeyBinding.setKeyBindState(i - 100, Mouse.getEventButtonState()); + if (Mouse.getEventButtonState()) { +@@ -1931,6 +1964,7 @@ + this.currentScreen.handleMouseInput(); + } + } ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().fireMouseInput(); + } + } + +@@ -1949,6 +1983,7 @@ + + /** Arguments: World foldername, World ingame name, WorldSettings */ + public void launchIntegratedServer(String folderName, String worldName, @Nullable WorldSettings worldSettingsIn) { ++ net.minecraftforge.fml.client.FMLClientHandler.instance().startIntegratedServer(folderName, worldName, worldSettingsIn); + this.loadWorld(null); + System.gc(); + ISaveHandler isavehandler = this.saveLoader.getSaveLoader(folderName, false); +@@ -1990,6 +2025,11 @@ + this.loadingScreen.displaySavingString(I18n.format("menu.loadingLevel")); + + while (!this.integratedServer.serverIsInRunLoop()) { ++ if (!net.minecraftforge.fml.common.StartupQuery.check() || this.integratedServer.isServerStopped()) { ++ loadWorld(null); ++ displayGuiScreen(null); ++ return; ++ } + String s = this.integratedServer.getUserMessage(); + if (s != null) { + this.loadingScreen.displayLoadingString(I18n.format(s)); +@@ -2007,8 +2047,13 @@ + SocketAddress socketaddress = this.integratedServer.getNetworkSystem().addLocalEndpoint(); + NetworkManager networkmanager = NetworkManager.provideLocalClient(socketaddress); + networkmanager.setNetHandler(new NetHandlerLoginClient(networkmanager, this, null)); +- networkmanager.sendPacket(new C00Handshake(socketaddress.toString(), 0, EnumConnectionState.LOGIN)); +- networkmanager.sendPacket(new CPacketLoginStart(this.getSession().getProfile())); ++ networkmanager.sendPacket(new C00Handshake(socketaddress.toString(), 0, EnumConnectionState.LOGIN, true)); ++ com.mojang.authlib.GameProfile gameProfile = this.getSession().getProfile(); ++ if (!this.getSession().hasCachedProperties()) { ++ gameProfile = sessionService.fillProfileProperties(gameProfile, true); //Forge: Fill profile properties upon game load. Fixes MC-52974. ++ this.getSession().setProperties(gameProfile.getProperties()); ++ } ++ networkmanager.sendPacket(new CPacketLoginStart(gameProfile)); + this.networkManager = networkmanager; + } + +@@ -2019,6 +2064,8 @@ + + /** par2Str is displayed on the loading screen to the user unloads the current world first */ + public void loadWorld(@Nullable WorldClient worldClientIn, String loadingMessage) { ++ if (world != null) net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.WorldEvent.Unload(world)); ++ + if (worldClientIn == null) { + NetHandlerPlayClient nethandlerplayclient = this.getConnection(); + if (nethandlerplayclient != null) { +@@ -2027,6 +2074,14 @@ + + if (this.integratedServer != null && this.integratedServer.isAnvilFileSet()) { + this.integratedServer.initiateShutdown(); ++ if (loadingScreen != null && this.running) { ++ this.loadingScreen.displayLoadingString(I18n.format("forge.client.shutdown.internal")); ++ } ++ while (!integratedServer.isServerStopped()) { ++ try { ++ Thread.sleep(10); ++ } catch (InterruptedException ie) {} ++ } + } + + this.integratedServer = null; +@@ -2047,6 +2102,7 @@ + this.ingameGUI.resetPlayersOverlayFooterHeader(); + this.setServerData(null); + this.integratedServerIsRunning = false; ++ net.minecraftforge.fml.client.FMLClientHandler.instance().handleClientWorldClosing(this.world); + } + + this.soundHandler.stopSounds(); +@@ -2060,6 +2116,8 @@ + } + + TileEntityRendererDispatcher.instance.setWorld(worldClientIn); ++ net.minecraftforge.client.MinecraftForgeClient.clearRenderCache(); ++ + if (worldClientIn != null) { + if (!this.integratedServerIsRunning) { + AuthenticationService authenticationservice = new YggdrasilAuthenticationService(this.proxy, UUID.randomUUID().toString()); +@@ -2112,6 +2170,7 @@ + this.player == null ? new RecipeBook() : this.player.getRecipeBook() + ); + this.player.getDataManager().setEntryValues(entityplayersp.getDataManager().getAll()); ++ this.player.updateSyncFields(entityplayersp); // Forge: fix MC-10657 + this.player.dimension = dimension; + this.renderViewEntity = this.player; + this.player.preparePlayerToSpawn(); +@@ -2153,110 +2212,8 @@ + /** Called when user clicked he's mouse middle button (pick block) */ + private void middleClickMouse() { + if (this.objectMouseOver != null && this.objectMouseOver.typeOfHit != RayTraceResult.Type.MISS) { +- boolean flag = this.player.capabilities.isCreativeMode; +- TileEntity tileentity = null; +- ItemStack itemstack; +- if (this.objectMouseOver.typeOfHit == RayTraceResult.Type.BLOCK) { +- BlockPos blockpos = this.objectMouseOver.getBlockPos(); +- IBlockState iblockstate = this.world.getBlockState(blockpos); +- Block block = iblockstate.getBlock(); +- if (iblockstate.getMaterial() == Material.AIR) { +- return; +- } +- +- itemstack = block.getItem(this.world, blockpos, iblockstate); +- if (itemstack.isEmpty()) { +- return; +- } +- +- if (flag && GuiScreen.isCtrlKeyDown() && block.hasTileEntity()) { +- tileentity = this.world.getTileEntity(blockpos); +- } +- } else { +- if (this.objectMouseOver.typeOfHit != RayTraceResult.Type.ENTITY || this.objectMouseOver.entityHit == null || !flag) { +- return; +- } +- +- if (this.objectMouseOver.entityHit instanceof EntityPainting) { +- itemstack = new ItemStack(Items.PAINTING); +- } else if (this.objectMouseOver.entityHit instanceof EntityLeashKnot) { +- itemstack = new ItemStack(Items.LEAD); +- } else if (this.objectMouseOver.entityHit instanceof EntityItemFrame) { +- EntityItemFrame entityitemframe = (EntityItemFrame)this.objectMouseOver.entityHit; +- ItemStack itemstack1 = entityitemframe.getDisplayedItem(); +- if (itemstack1.isEmpty()) { +- itemstack = new ItemStack(Items.ITEM_FRAME); +- } else { +- itemstack = itemstack1.copy(); +- } +- } else if (this.objectMouseOver.entityHit instanceof EntityMinecart) { +- EntityMinecart entityminecart = (EntityMinecart)this.objectMouseOver.entityHit; +- Item item; +- switch (entityminecart.getType()) { +- case FURNACE: +- item = Items.FURNACE_MINECART; +- break; +- case CHEST: +- item = Items.CHEST_MINECART; +- break; +- case TNT: +- item = Items.TNT_MINECART; +- break; +- case HOPPER: +- item = Items.HOPPER_MINECART; +- break; +- case COMMAND_BLOCK: +- item = Items.COMMAND_BLOCK_MINECART; +- break; +- default: +- item = Items.MINECART; +- } +- +- itemstack = new ItemStack(item); +- } else if (this.objectMouseOver.entityHit instanceof EntityBoat) { +- itemstack = new ItemStack(((EntityBoat)this.objectMouseOver.entityHit).getItemBoat()); +- } else if (this.objectMouseOver.entityHit instanceof EntityArmorStand) { +- itemstack = new ItemStack(Items.ARMOR_STAND); +- } else if (this.objectMouseOver.entityHit instanceof EntityEnderCrystal) { +- itemstack = new ItemStack(Items.END_CRYSTAL); +- } else { +- ResourceLocation resourcelocation = EntityList.getKey(this.objectMouseOver.entityHit); +- if (resourcelocation == null || !EntityList.ENTITY_EGGS.containsKey(resourcelocation)) { +- return; +- } +- +- itemstack = new ItemStack(Items.SPAWN_EGG); +- ItemMonsterPlacer.applyEntityIdToItemStack(itemstack, resourcelocation); +- } +- } +- +- if (itemstack.isEmpty()) { +- String s = ""; +- if (this.objectMouseOver.typeOfHit == RayTraceResult.Type.BLOCK) { +- s = Block.REGISTRY.getNameForObject(this.world.getBlockState(this.objectMouseOver.getBlockPos()).getBlock()).toString(); +- } else if (this.objectMouseOver.typeOfHit == RayTraceResult.Type.ENTITY) { +- s = EntityList.getKey(this.objectMouseOver.entityHit).toString(); +- } +- +- LOGGER.warn("Picking on: [{}] {} gave null item", this.objectMouseOver.typeOfHit, s); +- } else { +- InventoryPlayer inventoryplayer = this.player.inventory; +- if (tileentity != null) { +- this.storeTEInStack(itemstack, tileentity); +- } +- +- int i = inventoryplayer.getSlotFor(itemstack); +- if (flag) { +- inventoryplayer.setPickedItemStack(itemstack); +- this.playerController.sendSlotPacket(this.player.getHeldItem(EnumHand.MAIN_HAND), 36 + inventoryplayer.currentItem); +- } else if (i != -1) { +- if (InventoryPlayer.isHotbar(i)) { +- inventoryplayer.currentItem = i; +- } else { +- this.playerController.pickItem(i); +- } +- } +- } ++ net.minecraftforge.common.ForgeHooks.onPickBlock(this.objectMouseOver, this.player, this.world); ++ // We delete this code wholly instead of commenting it out, to make sure we detect changes in it between MC versions + } + } + +@@ -2293,7 +2250,11 @@ + }); + theCrash.getCategory().addDetail("OpenGL", new ICrashReportDetail() { + public String call() { +- return GlStateManager.glGetString(7937) + " GL version " + GlStateManager.glGetString(7938) + ", " + GlStateManager.glGetString(7936); ++ if (Minecraft.getMinecraft().isCallingFromMinecraftThread() && Display.isCreated()) { ++ return GlStateManager.glGetString(7937) + " GL version " + GlStateManager.glGetString(7938) + ", " + GlStateManager.glGetString(7936); ++ } else { ++ return "No OpenGL context found in the current thread"; ++ } + } + }); + theCrash.getCategory().addDetail("GL Caps", new ICrashReportDetail() { +@@ -2372,6 +2333,7 @@ + return instance; + } + ++ @Deprecated // Forge: Use selective scheduleResourceRefresh method in FMLClientHandler + public ListenableFuture scheduleResourcesRefresh() { + return this.addScheduledTask(new Runnable() { + @Override +@@ -2536,15 +2498,8 @@ + + /** Used in the usage snooper. */ + public static int getGLMaximumTextureSize() { +- for (int i = 16384; i > 0; i >>= 1) { +- GlStateManager.glTexImage2D(32868, 0, 6408, i, i, 0, 6408, 5121, null); +- int j = GlStateManager.glGetTexLevelParameteri(32868, 0, 4096); +- if (j != 0) { +- return i; +- } +- } +- +- return -1; ++ //Forge we redirect this to our code which caches the value before any splash screen stuff is done. ++ return net.minecraftforge.fml.client.SplashProgress.getMaxTextureSize(); + } + + /** Returns whether snooping is enabled or not. */ +@@ -2658,6 +2613,9 @@ + } + + if (this.player != null) { ++ MusicTicker.MusicType type = this.world.provider.getMusicType(); ++ if (type != null) return type; ++ + if (this.player.world.provider instanceof WorldProviderHell) { + return MusicTicker.MusicType.NETHER; + } else if (this.player.world.provider instanceof WorldProviderEnd) { +@@ -2677,9 +2635,9 @@ + if (i != 0 && !Keyboard.isRepeatEvent()) { + if (!(this.currentScreen instanceof GuiControls) || ((GuiControls)this.currentScreen).time <= getSystemTime() - 20L) { + if (Keyboard.getEventKeyState()) { +- if (i == this.gameSettings.keyBindFullscreen.getKeyCode()) { ++ if (this.gameSettings.keyBindFullscreen.isActiveAndMatches(i)) { + this.toggleFullscreen(); +- } else if (i == this.gameSettings.keyBindScreenshot.getKeyCode()) { ++ } else if (this.gameSettings.keyBindScreenshot.isActiveAndMatches(i)) { + this.ingameGUI + .getChatGUI() + .printChatMessage(ScreenShotHelper.saveScreenshot(this.gameDir, this.displayWidth, this.displayHeight, this.framebuffer)); +@@ -2691,7 +2649,7 @@ + ((ScreenChatOptions)this.currentScreen).updateNarratorButton(); + } + } +- } ++ } else if (this.currentScreen instanceof GuiControls) ((GuiControls)this.currentScreen).buttonId = null; + } + } + } +@@ -2720,7 +2678,7 @@ + try { + return Futures.immediateFuture(callableToSchedule.call()); + } catch (Exception exception) { +- return Futures.immediateFailedCheckedFuture(exception); ++ return Futures.immediateFailedFuture(exception); + } + } else { + ListenableFutureTask listenablefuturetask = ListenableFutureTask.create(callableToSchedule); +@@ -2802,7 +2760,11 @@ + return this.blockColors; + } + +- /** Whether to use reduced debug info */ ++ // FORGE ++ public ItemColors getItemColors() { ++ return this.itemColors; ++ } ++ + public boolean isReducedDebug() { + return this.player != null && this.player.hasReducedDebug() || this.gameSettings.reducedDebugInfo; + } +@@ -2814,4 +2776,8 @@ + public Tutorial getTutorial() { + return this.tutorial; + } ++ ++ public SearchTreeManager getSearchTreeManager() { ++ return this.searchTreeManager; ++ } + } diff --git a/module/minecraft/patches/net/minecraft/client/audio/SoundHandler.java.patch b/module/minecraft/patches/net/minecraft/client/audio/SoundHandler.java.patch new file mode 100644 index 000000000..4c411844a --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/audio/SoundHandler.java.patch @@ -0,0 +1,47 @@ +--- original/net/minecraft/client/audio/SoundHandler.java ++++ modified/net/minecraft/client/audio/SoundHandler.java +@@ -68,6 +68,7 @@ + public void onResourceManagerReload(IResourceManager resourceManager) { + this.soundRegistry.clearMap(); + ++ java.util.List> resources = new java.util.LinkedList<>(); + for (String s : resourceManager.getResourceDomains()) { + try { + for (IResource iresource : resourceManager.getAllResources(new ResourceLocation(s, "sounds.json"))) { +@@ -75,7 +76,7 @@ + Map map = this.getSoundMap(iresource.getInputStream()); + + for (Entry entry : map.entrySet()) { +- this.loadSoundResource(new ResourceLocation(s, entry.getKey()), entry.getValue()); ++ resources.add(new net.minecraft.util.Tuple<>(new ResourceLocation(s, entry.getKey()), entry.getValue())); + } + } catch (RuntimeException runtimeexception) { + LOGGER.warn("Invalid sounds.json", runtimeexception); +@@ -85,6 +86,16 @@ + } + } + ++ net.minecraftforge.fml.common.ProgressManager.ProgressBar resourcesBar = net.minecraftforge.fml.common.ProgressManager.push("Loading sounds", resources.size()); ++ resources.forEach(entry -> { ++ resourcesBar.step(entry.getFirst().toString()); ++ try { ++ this.loadSoundResource(entry.getFirst(), entry.getSecond()); ++ } catch (RuntimeException e) { ++ LOGGER.warn("Invalid sounds.json", e); ++ } ++ }); ++ net.minecraftforge.fml.common.ProgressManager.pop(resourcesBar); + for (ResourceLocation resourcelocation : this.soundRegistry.getKeys()) { + SoundEventAccessor soundeventaccessor = this.soundRegistry.getObject(resourcelocation); + if (soundeventaccessor.getSubtitle() instanceof TextComponentTranslation) { +@@ -209,6 +220,10 @@ + this.sndManager.setListener(player, p_147691_2_); + } + ++ public void setListener(net.minecraft.entity.Entity entity, float partialTicks) { ++ this.sndManager.setListener(entity, partialTicks); ++ } ++ + public void pauseSounds() { + this.sndManager.pauseAllSounds(); + } diff --git a/module/minecraft/patches/net/minecraft/client/audio/SoundManager.java.patch b/module/minecraft/patches/net/minecraft/client/audio/SoundManager.java.patch new file mode 100644 index 000000000..8b51992f2 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/audio/SoundManager.java.patch @@ -0,0 +1,106 @@ +--- original/net/minecraft/client/audio/SoundManager.java ++++ modified/net/minecraft/client/audio/SoundManager.java +@@ -77,6 +77,7 @@ + try { + SoundSystemConfig.addLibrary(LibraryLWJGLOpenAL.class); + SoundSystemConfig.setCodec("ogg", CodecJOrbis.class); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.sound.SoundSetupEvent(this)); + } catch (SoundSystemException soundsystemexception) { + LOGGER.error(LOG_MARKER, "Error linking with the LibraryJavaSound plug-in", soundsystemexception); + } +@@ -95,6 +96,7 @@ + + this.unloadSoundSystem(); + this.loadSoundSystem(); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.sound.SoundLoadEvent(this)); + } + + /** Tries to add the paulscode library and the relevant codecs. If it fails, the master volume will be set to zero. */ +@@ -179,6 +181,7 @@ + this.sndSystem.stop(s); + } + ++ this.pausedChannels.clear(); //Forge: MC-35856 Fixed paused sounds repeating when switching worlds + this.playingSounds.clear(); + this.delayedSounds.clear(); + this.tickableSounds.clear(); +@@ -278,6 +281,9 @@ + + public void playSound(ISound p_sound) { + if (this.loaded) { ++ p_sound = net.minecraftforge.client.ForgeHooksClient.playSound(this, p_sound); ++ if (p_sound == null) return; ++ + SoundEventAccessor soundeventaccessor = p_sound.createAccessor(this.sndHandler); + ResourceLocation resourcelocation = p_sound.getSoundLocation(); + if (soundeventaccessor == null) { +@@ -317,32 +323,34 @@ + ResourceLocation resourcelocation1 = sound.getSoundAsOggLocation(); + if (sound.isStreaming()) { + this.sndSystem +- .newStreamingSource( +- false, +- s, +- getURLForSoundResource(resourcelocation1), +- resourcelocation1.toString(), +- flag, +- p_sound.getXPosF(), +- p_sound.getYPosF(), +- p_sound.getZPosF(), +- p_sound.getAttenuationType().getTypeInt(), +- f +- ); ++ .newStreamingSource( ++ false, ++ s, ++ getURLForSoundResource(resourcelocation1), ++ resourcelocation1.toString(), ++ flag, ++ p_sound.getXPosF(), ++ p_sound.getYPosF(), ++ p_sound.getZPosF(), ++ p_sound.getAttenuationType().getTypeInt(), ++ f ++ ); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.sound.PlayStreamingSourceEvent(this, p_sound, s)); + } else { + this.sndSystem +- .newSource( +- false, +- s, +- getURLForSoundResource(resourcelocation1), +- resourcelocation1.toString(), +- flag, +- p_sound.getXPosF(), +- p_sound.getYPosF(), +- p_sound.getZPosF(), +- p_sound.getAttenuationType().getTypeInt(), +- f +- ); ++ .newSource( ++ false, ++ s, ++ getURLForSoundResource(resourcelocation1), ++ resourcelocation1.toString(), ++ flag, ++ p_sound.getXPosF(), ++ p_sound.getYPosF(), ++ p_sound.getZPosF(), ++ p_sound.getAttenuationType().getTypeInt(), ++ f ++ ); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.sound.PlaySoundSourceEvent(this, p_sound, s)); + } + + LOGGER.debug(LOG_MARKER, "Playing sound {} for event {} as channel {}", sound.getSoundLocation(), resourcelocation, s); +@@ -425,6 +433,10 @@ + + /** Sets the listener of sounds */ + public void setListener(EntityPlayer player, float p_148615_2_) { ++ setListener((net.minecraft.entity.Entity) player, p_148615_2_); ++ } ++ ++ public void setListener(net.minecraft.entity.Entity player, float p_148615_2_) { + if (this.loaded && player != null) { + float f = player.prevRotationPitch + (player.rotationPitch - player.prevRotationPitch) * p_148615_2_; + float f1 = player.prevRotationYaw + (player.rotationYaw - player.prevRotationYaw) * p_148615_2_; diff --git a/module/minecraft/patches/net/minecraft/client/entity/AbstractClientPlayer.java.patch b/module/minecraft/patches/net/minecraft/client/entity/AbstractClientPlayer.java.patch new file mode 100644 index 000000000..85088ab3c --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/entity/AbstractClientPlayer.java.patch @@ -0,0 +1,19 @@ +--- original/net/minecraft/client/entity/AbstractClientPlayer.java ++++ modified/net/minecraft/client/entity/AbstractClientPlayer.java +@@ -125,7 +125,7 @@ + f = 1.0F; + } + +- if (this.isHandActive() && this.getActiveItemStack().getItem() == Items.BOW) { ++ if (this.isHandActive() && this.getActiveItemStack().getItem() instanceof net.minecraft.item.ItemBow) { + int i = this.getItemInUseMaxCount(); + float f1 = i / 20.0F; + if (f1 > 1.0F) { +@@ -137,6 +137,6 @@ + f *= 1.0F - f1 * 0.15F; + } + +- return f; ++ return net.minecraftforge.client.ForgeHooksClient.getOffsetFOV(this, f); + } + } diff --git a/module/minecraft/patches/net/minecraft/client/entity/EntityOtherPlayerMP.java.patch b/module/minecraft/patches/net/minecraft/client/entity/EntityOtherPlayerMP.java.patch new file mode 100644 index 000000000..04e68c4a4 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/entity/EntityOtherPlayerMP.java.patch @@ -0,0 +1,10 @@ +--- original/net/minecraft/client/entity/EntityOtherPlayerMP.java ++++ modified/net/minecraft/client/entity/EntityOtherPlayerMP.java +@@ -41,6 +41,7 @@ + /** Called when the entity is attacked. */ + @Override + public boolean attackEntityFrom(DamageSource source, float amount) { ++ net.minecraftforge.common.ForgeHooks.onPlayerAttack(this, source, amount); + return true; + } + diff --git a/module/minecraft/patches/net/minecraft/client/entity/EntityPlayerSP.java.patch b/module/minecraft/patches/net/minecraft/client/entity/EntityPlayerSP.java.patch new file mode 100644 index 000000000..a7706a7c6 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/entity/EntityPlayerSP.java.patch @@ -0,0 +1,123 @@ +--- original/net/minecraft/client/entity/EntityPlayerSP.java ++++ modified/net/minecraft/client/entity/EntityPlayerSP.java +@@ -141,6 +141,7 @@ + /** Called when the entity is attacked. */ + @Override + public boolean attackEntityFrom(DamageSource source, float amount) { ++ net.minecraftforge.common.ForgeHooks.onPlayerAttack(this, source, amount); + return false; + } + +@@ -426,6 +427,13 @@ + } + } + ++ private boolean isHeadspaceFree(BlockPos pos, int height) { ++ for (int y = 0; y < height; y++) { ++ if (!isOpenBlockSpace(pos.add(0, y, 0))) return false; ++ } ++ return true; ++ } ++ + @Override + protected boolean pushOutOfBlocks(double x, double y, double z) { + if (this.noClip) { +@@ -435,25 +443,28 @@ + BlockPos blockpos = new BlockPos(x, y, z); + double d0 = x - blockpos.getX(); + double d1 = z - blockpos.getZ(); +- if (!this.isOpenBlockSpace(blockpos)) { ++ ++ int entHeight = Math.max((int)Math.ceil(this.height), 1); ++ boolean inTranslucentBlock = !this.isHeadspaceFree(blockpos, entHeight); ++ if (inTranslucentBlock) { + int i = -1; + double d2 = 9999.0; +- if (this.isOpenBlockSpace(blockpos.west()) && d0 < d2) { ++ if (this.isHeadspaceFree(blockpos.west(), entHeight) && d0 < d2) { + d2 = d0; + i = 0; + } + +- if (this.isOpenBlockSpace(blockpos.east()) && 1.0 - d0 < d2) { ++ if (this.isHeadspaceFree(blockpos.east(), entHeight) && 1.0D - d0 < d2) { + d2 = 1.0 - d0; + i = 1; + } + +- if (this.isOpenBlockSpace(blockpos.north()) && d1 < d2) { ++ if (this.isHeadspaceFree(blockpos.north(), entHeight) && d1 < d2) { + d2 = d1; + i = 4; + } + +- if (this.isOpenBlockSpace(blockpos.south()) && 1.0 - d1 < d2) { ++ if (this.isHeadspaceFree(blockpos.south(), entHeight) && 1.0D - d1 < d2) { + d2 = 1.0 - d1; + i = 5; + } +@@ -481,7 +492,8 @@ + + /** Returns true if the block at the given BlockPos and the block above it are NOT full cubes. */ + private boolean isOpenBlockSpace(BlockPos pos) { +- return !this.world.getBlockState(pos).isNormalCube() && !this.world.getBlockState(pos.up()).isNormalCube(); ++ IBlockState iblockstate = world.getBlockState(pos); ++ return !iblockstate.getBlock().isNormalCube(iblockstate, world, pos); + } + + /** Set sprinting switch for Entity. */ +@@ -528,8 +540,13 @@ + + @Override + public void playSound(SoundEvent soundIn, float volume, float pitch) { +- this.world +- .playSound(this.posX, this.posY, this.posZ, soundIn, this.getSoundCategory(), volume, pitch, false); ++ net.minecraftforge.event.entity.PlaySoundAtEntityEvent event = net.minecraftforge.event.ForgeEventFactory.onPlaySoundAtEntity(this, soundIn, this.getSoundCategory(), volume, pitch); ++ if (event.isCanceled() || event.getSound() == null) return; ++ soundIn = event.getSound(); ++ volume = event.getVolume(); ++ pitch = event.getPitch(); ++ ++ this.world.playSound(this.posX, this.posY, this.posZ, soundIn, event.getCategory(), volume, pitch, false); + } + + /** Returns whether the entity is in a server world */ +@@ -754,6 +771,7 @@ + float f = 0.8F; + boolean flag2 = this.movementInput.moveForward >= 0.8F; + this.movementInput.updatePlayerMoveState(); ++ net.minecraftforge.client.ForgeHooksClient.onInputUpdate(this, this.movementInput); + this.mc.getTutorial().handleMovement(this.movementInput); + if (this.isHandActive() && !this.isRiding()) { + this.movementInput.moveStrafe *= 0.2F; +@@ -769,10 +787,13 @@ + } + + AxisAlignedBB axisalignedbb = this.getEntityBoundingBox(); ++ net.minecraftforge.client.event.PlayerSPPushOutOfBlocksEvent event = new net.minecraftforge.client.event.PlayerSPPushOutOfBlocksEvent(this, axisalignedbb); ++ if(!net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event)) { axisalignedbb = event.getEntityBoundingBox(); + this.pushOutOfBlocks(this.posX - this.width * 0.35, axisalignedbb.minY + 0.5, this.posZ + this.width * 0.35); + this.pushOutOfBlocks(this.posX - this.width * 0.35, axisalignedbb.minY + 0.5, this.posZ - this.width * 0.35); + this.pushOutOfBlocks(this.posX + this.width * 0.35, axisalignedbb.minY + 0.5, this.posZ - this.width * 0.35); + this.pushOutOfBlocks(this.posX + this.width * 0.35, axisalignedbb.minY + 0.5, this.posZ + this.width * 0.35); ++ } + boolean flag4 = this.getFoodStats().getFoodLevel() > 6.0F || this.capabilities.allowFlying; + if (this.onGround + && !flag1 +@@ -1029,4 +1050,16 @@ + } + } + } ++ ++ public void updateSyncFields(EntityPlayerSP old) { ++ this.lastReportedPosX = old.lastReportedPosX; ++ this.lastReportedPosY = old.lastReportedPosY; ++ this.lastReportedPosZ = old.lastReportedPosZ; ++ this.lastReportedYaw = old.lastReportedYaw; ++ this.lastReportedPitch = old.lastReportedPitch; ++ this.prevOnGround = old.prevOnGround; ++ this.serverSneakState = old.serverSneakState; ++ this.serverSprintState = old.serverSprintState; ++ this.positionUpdateTicks = old.positionUpdateTicks; ++ } + } diff --git a/module/minecraft/patches/net/minecraft/client/gui/FontRenderer.java.patch b/module/minecraft/patches/net/minecraft/client/gui/FontRenderer.java.patch new file mode 100644 index 000000000..c5ce469ba --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/FontRenderer.java.patch @@ -0,0 +1,254 @@ +--- original/net/minecraft/client/gui/FontRenderer.java ++++ modified/net/minecraft/client/gui/FontRenderer.java +@@ -73,7 +73,7 @@ + this.locationFontTexture = location; + this.renderEngine = textureManagerIn; + this.unicodeFlag = unicode; +- textureManagerIn.bindTexture(this.locationFontTexture); ++ bindTexture(this.locationFontTexture); + + for (int i = 0; i < 32; i++) { + int j = (i >> 3 & 1) * 85; +@@ -116,7 +116,7 @@ + + BufferedImage bufferedimage; + try { +- iresource = Minecraft.getMinecraft().getResourceManager().getResource(this.locationFontTexture); ++ iresource = getResource(this.locationFontTexture); + bufferedimage = TextureUtil.readBufferedImage(iresource.getInputStream()); + } catch (IOException ioexception) { + throw new RuntimeException(ioexception); +@@ -165,7 +165,7 @@ + IResource iresource = null; + + try { +- iresource = Minecraft.getMinecraft().getResourceManager().getResource(new ResourceLocation("font/glyph_sizes.bin")); ++ iresource = getResource(new ResourceLocation("font/glyph_sizes.bin")); + iresource.getInputStream().read(this.glyphWidth); + } catch (IOException ioexception) { + throw new RuntimeException(ioexception); +@@ -176,6 +176,7 @@ + + /** Render the given char */ + private float renderChar(char ch, boolean italic) { ++ if (ch == 160) return 4.0F; // forge: display nbsp as space. MC-2595 + if (ch == ' ') { + return 4.0F; + } +@@ -190,7 +191,7 @@ + int i = ch % 16 * 8; + int j = ch / 16 * 8; + int k = italic ? 1 : 0; +- this.renderEngine.bindTexture(this.locationFontTexture); ++ bindTexture(this.locationFontTexture); + int l = this.charWidth[ch]; + float f = l - 0.01F; + GlStateManager.glBegin(5); +@@ -216,7 +217,7 @@ + + /** Load one of the /font/glyph_XX.png into a new GL texture and store the texture ID in glyphTextureName array. */ + private void loadGlyphTexture(int page) { +- this.renderEngine.bindTexture(this.getUnicodePageLocation(page)); ++ bindTexture(this.getUnicodePageLocation(page)); + } + + /** Render a single Unicode character at current (posX,posY) location using one of the /font/glyph_XX.png files... */ +@@ -261,7 +262,7 @@ + + /** Draws the specified string. */ + public int drawString(String text, float x, float y, int color, boolean dropShadow) { +- GlStateManager.enableAlpha(); ++ enableAlpha(); + this.resetStyles(); + int i; + if (dropShadow) { +@@ -316,7 +317,7 @@ + + int j1 = this.colorCode[i1]; + this.textColor = j1; +- GlStateManager.color((j1 >> 16) / 255.0F, (j1 >> 8 & 0xFF) / 255.0F, (j1 & 0xFF) / 255.0F, this.alpha); ++ setColor((j1 >> 16) / 255.0F, (j1 >> 8 & 255) / 255.0F, (j1 & 255) / 255.0F, this.alpha); + } else if (i1 == 16) { + this.randomStyle = true; + } else if (i1 == 17) { +@@ -333,7 +334,7 @@ + this.strikethroughStyle = false; + this.underlineStyle = false; + this.italicStyle = false; +- GlStateManager.color(this.red, this.blue, this.green, this.alpha); ++ setColor(this.red, this.blue, this.green, this.alpha); + } + + i++; +@@ -357,7 +358,7 @@ + c0 = c1; + } + +- float f1 = this.unicodeFlag ? 0.5F : 1.0F; ++ float f1 = j == -1 || this.unicodeFlag ? 0.5f : 1f; + boolean flag = (c0 == 0 || j == -1 || this.unicodeFlag) && shadow; + if (flag) { + this.posX -= f1; +@@ -386,7 +387,15 @@ + + f++; + } ++ doDraw(f); ++ } ++ } ++ } + ++ protected void doDraw(float f) { ++ { ++ { ++ + if (this.strikethroughStyle) { + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder bufferbuilder = tessellator.getBuffer(); +@@ -451,7 +460,7 @@ + this.blue = (color >> 8 & 0xFF) / 255.0F; + this.green = (color & 0xFF) / 255.0F; + this.alpha = (color >> 24 & 0xFF) / 255.0F; +- GlStateManager.color(this.red, this.blue, this.green, this.alpha); ++ setColor(this.red, this.blue, this.green, this.alpha); + this.posX = x; + this.posY = y; + this.renderStringAtPos(text, dropShadow); +@@ -492,6 +501,7 @@ + + /** Returns the width of this character as rendered. */ + public int getCharWidth(char character) { ++ if (character == 160) return 4; // forge: display nbsp as space. MC-2595 + if (character == 167) { + return -1; + } else if (character == ' ') { +@@ -580,7 +590,7 @@ + + /** Remove all newline characters from the end of the string */ + private String trimStringNewline(String text) { +- while (text != null && text.endsWith("\n")) { ++ while (text.endsWith("\n")) { + text = text.substring(0, text.length() - 1); + } + +@@ -625,10 +635,86 @@ + + /** Breaks a string into a list of pieces where the width of each line is always less than or equal to the provided width. Formatting codes will be preserved between lines. */ + public List listFormattedStringToWidth(String str, int wrapWidth) { +- return Arrays.asList(this.wrapFormattedStringToWidth(str, wrapWidth).split("\n")); ++ if (str.isEmpty()) { ++ return java.util.Collections.singletonList(""); ++ } ++ com.ibm.icu.segmenter.Segments segments = com.cleanroommc.client.ICU4JInstances.SEGMENTER.segment(str); ++ List list = new java.util.ArrayList<>(); ++ StringBuilder line = new StringBuilder(); ++ StringBuilder current = new StringBuilder(); ++ StringBuilder format = new StringBuilder(); ++ StringBuilder segFormat = new StringBuilder(); ++ boolean bold = false; ++ int lineWidth = 0; ++ int segmentWidth; ++ out: ++ for (java.util.Iterator it = segments.segments().iterator(); it.hasNext(); ) { ++ com.ibm.icu.segmenter.Segment segment = it.next(); ++ segmentWidth = 0; ++ int size = segment.limit - segment.start; ++ CharSequence sequence = segment.getSubSequence(); ++ segFormat.setLength(0); ++ segFormat.append(format); ++ for (int i = 0; i < size; i++) { ++ char c = sequence.charAt(i); ++ switch (c) { ++ case '\n': ++ line.append(current); ++ current.setLength(0); ++ list.add(line.toString()); ++ line.setLength(0); ++ line.append(format); ++ lineWidth = 0; ++ continue out; ++ case '§': ++ if (++i < size) { ++ char next = sequence.charAt(i); ++ if (next == 'l' || next == 'L') { ++ bold = true; ++ } else if (next == 'r' || next == 'R') { ++ bold = false; ++ format.setLength(0); ++ } else if (isFormatColor(next)) { ++ bold = false; ++ } ++ format.append('§').append(next); ++ current.append('§').append(next); ++ continue; ++ } ++ default: ++ int cWidth = getCharWidth(c); ++ if (bold) cWidth++; ++ if (lineWidth + cWidth > wrapWidth) { ++ if (i >= current.length()) { ++ lineWidth = 0; ++ segmentWidth = 0; ++ line.append(current); ++ format.setLength(0); ++ format.append(segFormat); ++ current.setLength(0); ++ } else { ++ lineWidth = segmentWidth; ++ line.append(current, 0, current.length() - i); ++ current.delete(0, current.length() - i); ++ } ++ list.add(line.toString()); ++ line.setLength(0); ++ line.append(format); ++ } ++ current.append(c); ++ lineWidth += cWidth; ++ segmentWidth += cWidth; ++ } ++ } ++ } ++ line.append(current); ++ if (!line.isEmpty()) { ++ list.add(line.toString()); ++ } ++ return list; + } + +- /** Inserts newline and formatting into a string to wrap it within the specified width. */ ++ @Deprecated + String wrapFormattedStringToWidth(String str, int wrapWidth) { + int i = this.sizeStringToWidth(str, wrapWidth); + if (str.length() <= i) { +@@ -642,7 +728,7 @@ + return s + "\n" + this.wrapFormattedStringToWidth(s1, wrapWidth); + } + +- /** Determines how many characters from the string will fit into the specified width. */ ++ @Deprecated + private int sizeStringToWidth(String str, int wrapWidth) { + int i = str.length(); + int j = 0; +@@ -725,6 +811,22 @@ + return this.bidiFlag; + } + ++ protected void setColor(float r, float g, float b, float a) { ++ GlStateManager.color(r,g,b,a); ++ } ++ ++ protected void enableAlpha() { ++ GlStateManager.enableAlpha(); ++ } ++ ++ protected void bindTexture(ResourceLocation location) { ++ renderEngine.bindTexture(location); ++ } ++ ++ protected IResource getResource(ResourceLocation location) throws IOException { ++ return Minecraft.getMinecraft().getResourceManager().getResource(location); ++ } ++ + public int getColorCode(char character) { + int i = "0123456789abcdef".indexOf(character); + return i >= 0 && i < this.colorCode.length ? this.colorCode[i] : -1; diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiBossOverlay.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiBossOverlay.java.patch new file mode 100644 index 000000000..4e2dc9e85 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiBossOverlay.java.patch @@ -0,0 +1,22 @@ +--- original/net/minecraft/client/gui/GuiBossOverlay.java ++++ modified/net/minecraft/client/gui/GuiBossOverlay.java +@@ -30,12 +30,18 @@ + for (BossInfoClient bossinfoclient : this.mapBossInfos.values()) { + int k = i / 2 - 91; + int l = j; ++ net.minecraftforge.client.event.RenderGameOverlayEvent.BossInfo event = ++ net.minecraftforge.client.ForgeHooksClient.bossBarRenderPre(scaledresolution, bossinfoclient, k, j, 10 + this.client.fontRenderer.FONT_HEIGHT); ++ if (!event.isCanceled()) { + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + this.client.getTextureManager().bindTexture(GUI_BARS_TEXTURES); + this.render(k, l, bossinfoclient); + String s = bossinfoclient.getName().getFormattedText(); + this.client.fontRenderer.drawStringWithShadow(s, i / 2 - this.client.fontRenderer.getStringWidth(s) / 2, l - 9, 16777215); +- j += 10 + this.client.fontRenderer.FONT_HEIGHT; ++ } ++ j += event.getIncrement(); ++ ++ net.minecraftforge.client.ForgeHooksClient.bossBarRenderPost(scaledresolution); + if (j >= scaledresolution.getScaledHeight() / 3) { + break; + } diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiButton.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiButton.java.patch new file mode 100644 index 000000000..8ef2845cd --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiButton.java.patch @@ -0,0 +1,21 @@ +--- original/net/minecraft/client/gui/GuiButton.java ++++ modified/net/minecraft/client/gui/GuiButton.java +@@ -28,6 +28,7 @@ + /** Hides the button completely if false. */ + public boolean visible = true; + protected boolean hovered; ++ public int packedFGColour; //FML + + public GuiButton(int buttonId, int x, int y, String buttonText) { + this(buttonId, x, y, 200, 20, buttonText); +@@ -84,6 +85,10 @@ + ); + this.mouseDragged(mc, mouseX, mouseY); + int j = 14737632; ++ ++ if (packedFGColour != 0) { ++ j = packedFGColour; ++ } else + if (!this.enabled) { + j = 10526880; + } else if (this.hovered) { diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiControls.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiControls.java.patch new file mode 100644 index 000000000..38ad34956 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiControls.java.patch @@ -0,0 +1,46 @@ +--- original/net/minecraft/client/gui/GuiControls.java ++++ modified/net/minecraft/client/gui/GuiControls.java +@@ -79,7 +79,7 @@ + this.mc.displayGuiScreen(this.parentScreen); + } else if (button.id == 201) { + for (KeyBinding keybinding : this.mc.gameSettings.keyBindings) { +- keybinding.setKeyCode(keybinding.getKeyCodeDefault()); ++ keybinding.setToDefault(); + } + + KeyBinding.resetKeyBindingArrayAndHash(); +@@ -93,6 +93,7 @@ + @Override + protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { + if (this.buttonId != null) { ++ this.buttonId.setKeyModifierAndCode(net.minecraftforge.client.settings.KeyModifier.getActiveModifier(), -100 + mouseButton); + this.options.setOptionKeyBinding(this.buttonId, -100 + mouseButton); + this.buttonId = null; + KeyBinding.resetKeyBindingArrayAndHash(); +@@ -114,13 +115,17 @@ + protected void keyTyped(char typedChar, int keyCode) throws IOException { + if (this.buttonId != null) { + if (keyCode == 1) { ++ this.buttonId.setKeyModifierAndCode(net.minecraftforge.client.settings.KeyModifier.NONE, 0); + this.options.setOptionKeyBinding(this.buttonId, 0); + } else if (keyCode != 0) { ++ this.buttonId.setKeyModifierAndCode(net.minecraftforge.client.settings.KeyModifier.getActiveModifier(), keyCode); + this.options.setOptionKeyBinding(this.buttonId, keyCode); + } else if (typedChar > 0) { ++ this.buttonId.setKeyModifierAndCode(net.minecraftforge.client.settings.KeyModifier.getActiveModifier(), typedChar + 256); + this.options.setOptionKeyBinding(this.buttonId, typedChar + 256); + } + ++ if (!net.minecraftforge.client.settings.KeyModifier.isKeyCodeModifier(keyCode)) + this.buttonId = null; + this.time = Minecraft.getSystemTime(); + KeyBinding.resetKeyBindingArrayAndHash(); +@@ -138,7 +143,7 @@ + boolean flag = false; + + for (KeyBinding keybinding : this.options.keyBindings) { +- if (keybinding.getKeyCode() != keybinding.getKeyCodeDefault()) { ++ if (!keybinding.isSetToDefaultValue()) { + flag = true; + break; + } diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiCreateWorld.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiCreateWorld.java.patch new file mode 100644 index 000000000..d082d8bd7 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiCreateWorld.java.patch @@ -0,0 +1,61 @@ +--- original/net/minecraft/client/gui/GuiCreateWorld.java ++++ modified/net/minecraft/client/gui/GuiCreateWorld.java +@@ -220,6 +220,8 @@ + } + } + ++ WorldType.WORLD_TYPES[this.selectedIndex].onGUICreateWorldPress(); ++ + WorldSettings worldsettings = new WorldSettings( + i, GameType.getByName(this.gameMode), this.generateStructuresEnabled, this.hardCoreMode, WorldType.WORLD_TYPES[this.selectedIndex] + ); +@@ -298,11 +300,7 @@ + this.allowCheats = !this.allowCheats; + this.updateDisplayState(); + } else if (button.id == 8) { +- if (WorldType.WORLD_TYPES[this.selectedIndex] == WorldType.FLAT) { +- this.mc.displayGuiScreen(new GuiCreateFlatWorld(this, this.chunkProviderSettingsJson)); +- } else { +- this.mc.displayGuiScreen(new GuiCustomizeWorldScreen(this, this.chunkProviderSettingsJson)); +- } ++ WorldType.WORLD_TYPES[this.selectedIndex].onCustomizeButton(mc, this); + } + } + } +@@ -356,11 +354,7 @@ + this.btnBonusItems.visible = this.inMoreWorldOptionsDisplay; + this.btnMapType.visible = this.inMoreWorldOptionsDisplay; + this.btnAllowCommands.visible = this.inMoreWorldOptionsDisplay; +- this.btnCustomizeType.visible = this.inMoreWorldOptionsDisplay +- && ( +- WorldType.WORLD_TYPES[this.selectedIndex] == WorldType.FLAT +- || WorldType.WORLD_TYPES[this.selectedIndex] == WorldType.CUSTOMIZED +- ); ++ this.btnCustomizeType.visible = this.inMoreWorldOptionsDisplay && WorldType.WORLD_TYPES[this.selectedIndex].isCustomizable(); + } + + this.updateDisplayState(); +@@ -393,6 +387,23 @@ + /** Called when the mouse is clicked. Args : mouseX, mouseY, clickedButton */ + @Override + protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { ++ if (this.btnMapType.mousePressed(this.mc, mouseX, mouseY)) { ++ if (mouseButton == 1) { ++ ++ do { ++ this.selectedIndex--; ++ ++ if (this.selectedIndex < 0) { ++ this.selectedIndex = WorldType.WORLD_TYPES.length - 1; ++ } ++ } while (!this.canSelectCurWorldType()); ++ ++ this.chunkProviderSettingsJson = ""; ++ this.updateDisplayState(); ++ this.showMoreWorldOptions(this.inMoreWorldOptionsDisplay); ++ } ++ } ++ + super.mouseClicked(mouseX, mouseY, mouseButton); + if (this.inMoreWorldOptionsDisplay) { + this.worldSeedField.mouseClicked(mouseX, mouseY, mouseButton); diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiEnchantment.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiEnchantment.java.patch new file mode 100644 index 000000000..35aa05799 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiEnchantment.java.patch @@ -0,0 +1,27 @@ +--- original/net/minecraft/client/gui/GuiEnchantment.java ++++ modified/net/minecraft/client/gui/GuiEnchantment.java +@@ -169,7 +169,8 @@ + String s1 = EnchantmentNameParts.getInstance().generateNewRandomName(this.fontRenderer, l1); + FontRenderer fontrenderer = this.mc.standardGalacticFontRenderer; + int i2 = 6839882; +- if ((k < l + 1 || this.mc.player.experienceLevel < k1) && !this.mc.player.capabilities.isCreativeMode) { ++ ++ if (((k < l + 1 || this.mc.player.experienceLevel < k1) && !this.mc.player.capabilities.isCreativeMode) || this.container.enchantClue[l] == -1) { // Forge: render buttons as disabled when enchantable but enchantability not met on lower levels + this.drawTexturedModalRect(i1, j + 14 + 19 * l, 0, 185, 108, 19); + this.drawTexturedModalRect(i1 + 1, j + 15 + 19 * l, 16 * l, 239, 16, 16); + fontrenderer.drawSplitString(s1, j1, j + 16 + 19 * l, l1, (i2 & 16711422) >> 1); +@@ -210,9 +211,12 @@ + Enchantment enchantment = Enchantment.getEnchantmentByID(this.container.enchantClue[j]); + int l = this.container.worldClue[j]; + int i1 = j + 1; +- if (this.isPointInRegion(60, 14 + 19 * j, 108, 17, mouseX, mouseY) && k > 0 && l >= 0 && enchantment != null) { ++ ++ if (this.isPointInRegion(60, 14 + 19 * j, 108, 17, mouseX, mouseY) && k > 0) { + List list = Lists.newArrayList(); +- list.add("" + TextFormatting.WHITE + TextFormatting.ITALIC + I18n.format("container.enchant.clue", enchantment.getTranslatedName(l))); ++ list.add("" + TextFormatting.WHITE + TextFormatting.ITALIC + I18n.format("container.enchant.clue", enchantment == null ? "" : enchantment.getTranslatedName(l))); ++ ++ if(enchantment == null) java.util.Collections.addAll(list, "", TextFormatting.RED + I18n.format("forge.container.enchant.limitedEnchantability")); else + if (!flag) { + list.add(""); + if (this.mc.player.experienceLevel < k) { diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiGameOver.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiGameOver.java.patch new file mode 100644 index 000000000..aba3fd651 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiGameOver.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/client/gui/GuiGameOver.java ++++ modified/net/minecraft/client/gui/GuiGameOver.java +@@ -64,7 +64,7 @@ + break; + case 1: + if (this.mc.world.getWorldInfo().isHardcoreModeEnabled()) { +- this.mc.displayGuiScreen(new GuiMainMenu()); ++ confirmClicked(true, 0); // Forge : Fix MC-30646 + } else { + GuiYesNo guiyesno = new GuiYesNo( + this, diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiIngame.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiIngame.java.patch new file mode 100644 index 000000000..7114d0231 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiIngame.java.patch @@ -0,0 +1,38 @@ +--- original/net/minecraft/client/gui/GuiIngame.java ++++ modified/net/minecraft/client/gui/GuiIngame.java +@@ -359,8 +359,9 @@ + } + + BlockPos blockpos = raytraceresult.getBlockPos(); +- if (!this.mc.world.getBlockState(blockpos).getBlock().hasTileEntity() +- || !(this.mc.world.getTileEntity(blockpos) instanceof IInventory)) { ++ ++ net.minecraft.block.state.IBlockState state = this.mc.world.getBlockState(blockpos); ++ if (!state.getBlock().hasTileEntity(state) || !(this.mc.world.getTileEntity(blockpos) instanceof IInventory)) { + return; + } + } +@@ -419,7 +420,11 @@ + + for (PotionEffect potioneffect : Ordering.natural().reverse().sortedCopy(collection)) { + Potion potion = potioneffect.getPotion(); +- if (potion.hasStatusIcon() && potioneffect.doesShowParticles()) { ++ ++ if (!potion.shouldRenderHUD(potioneffect)) continue; ++ // Rebind in case previous renderHUDEffect changed texture ++ this.mc.getTextureManager().bindTexture(GuiContainer.INVENTORY_BACKGROUND); ++ if (potioneffect.doesShowParticles()) { + int k = resolution.getScaledWidth(); + int l = 1; + if (this.mc.isDemo()) { +@@ -451,7 +456,10 @@ + } + + GlStateManager.color(1.0F, 1.0F, 1.0F, f); ++ // FORGE - Move status icon check down from above so renderHUDEffect will still be called without a status icon ++ if (potion.hasStatusIcon()) + this.drawTexturedModalRect(k + 3, l + 3, i1 % 8 * 18, 198 + i1 / 8 * 18, 18, 18); ++ potion.renderHUDEffect(potioneffect, this, k, l, this.zLevel, f); + } + } + } diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiIngameMenu.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiIngameMenu.java.patch new file mode 100644 index 000000000..395bda3ac --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiIngameMenu.java.patch @@ -0,0 +1,57 @@ +--- original/net/minecraft/client/gui/GuiIngameMenu.java ++++ modified/net/minecraft/client/gui/GuiIngameMenu.java +@@ -12,6 +12,7 @@ + public class GuiIngameMenu extends GuiScreen { + private int saveStep; + private int visibleTime; ++ private net.minecraftforge.client.gui.NotificationModUpdateScreen modUpdateNotification; + + /** Adds the buttons (and other controls) to the screen in question. Called when the GUI is displayed and when the window resizes, the buttonList is cleared beforehand. */ + @Override +@@ -28,13 +29,16 @@ + this.buttonList.add(new GuiButton(4, this.width / 2 - 100, this.height / 4 + 24 + -16, I18n.format("menu.returnToGame"))); + this.buttonList + .add(new GuiButton(0, this.width / 2 - 100, this.height / 4 + 96 + -16, 98, 20, I18n.format("menu.options"))); +- GuiButton guibutton = this.addButton( +- new GuiButton(7, this.width / 2 + 2, this.height / 4 + 96 + -16, 98, 20, I18n.format("menu.shareToLan")) +- ); ++ GuiButton modButton = this.addButton(new GuiButton(12, this.width / 2 + 2, this.height / 4 + 96 + i, 98, 20, I18n.format("fml.menu.mods"))); ++ GuiButton guibutton = this.addButton(new GuiButton(7, this.width / 2 - 100, this.height / 4 + 72 + -16, 200, 20, I18n.format("menu.shareToLan", new Object[0]))); + guibutton.enabled = this.mc.isSingleplayer() && !this.mc.getIntegratedServer().getPublic(); + this.buttonList + .add(new GuiButton(5, this.width / 2 - 100, this.height / 4 + 48 + -16, 98, 20, I18n.format("gui.advancements"))); + this.buttonList.add(new GuiButton(6, this.width / 2 + 2, this.height / 4 + 48 + -16, 98, 20, I18n.format("gui.stats"))); ++ ++ this.modUpdateNotification = new net.minecraftforge.client.gui.NotificationModUpdateScreen(modButton); ++ this.modUpdateNotification.setGuiSize(this.width, this.height); ++ this.modUpdateNotification.initGui(); + } + + /** Called by the controls from the buttonList when activated. (Mouse pressed for buttons) */ +@@ -67,13 +71,19 @@ + this.mc.setIngameFocus(); + break; + case 5: ++ if (this.mc.player != null) + this.mc.displayGuiScreen(new GuiScreenAdvancements(this.mc.player.connection.getAdvancementManager())); + break; + case 6: ++ if (this.mc.player != null) + this.mc.displayGuiScreen(new GuiStats(this, this.mc.player.getStatFileWriter())); + break; + case 7: + this.mc.displayGuiScreen(new GuiShareToLan(this)); ++ break; ++ case 12: ++ net.minecraftforge.fml.client.FMLClientHandler.instance().showInGameModOptions(this); ++ break; + } + } + +@@ -90,5 +100,6 @@ + this.drawDefaultBackground(); + this.drawCenteredString(this.fontRenderer, I18n.format("menu.game"), this.width / 2, 40, 16777215); + super.drawScreen(mouseX, mouseY, partialTicks); ++ this.modUpdateNotification.drawScreen(mouseX, mouseY, partialTicks); + } + } diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiKeyBindingList.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiKeyBindingList.java.patch new file mode 100644 index 000000000..2c5b0c3cb --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiKeyBindingList.java.patch @@ -0,0 +1,78 @@ +--- original/net/minecraft/client/gui/GuiKeyBindingList.java ++++ modified/net/minecraft/client/gui/GuiKeyBindingList.java +@@ -56,7 +56,7 @@ + + @Override + protected int getScrollBarX() { +- return super.getScrollBarX() + 15; ++ return super.getScrollBarX() + 35; + } + + /** Gets the width of the list */ +@@ -125,7 +125,7 @@ + private KeyEntry(KeyBinding name) { + this.keybinding = name; + this.keyDesc = I18n.format(name.getKeyDescription()); +- this.btnChangeKeyBinding = new GuiButton(0, 0, 0, 75, 20, I18n.format(name.getKeyDescription())); ++ this.btnChangeKeyBinding = new GuiButton(0, 0, 0, 95, 20, I18n.format(name.getKeyDescription())); + this.btnReset = new GuiButton(0, 0, 0, 50, 20, I18n.format("controls.reset")); + } + +@@ -143,26 +143,28 @@ + ) { + boolean flag = GuiKeyBindingList.this.controlsScreen.buttonId == this.keybinding; + GuiKeyBindingList.this.mc +- .fontRenderer +- .drawString( +- this.keyDesc, +- x + 90 - GuiKeyBindingList.this.maxListLabelWidth, +- y + slotHeight / 2 - GuiKeyBindingList.this.mc.fontRenderer.FONT_HEIGHT / 2, +- 16777215 +- ); +- this.btnReset.x = x + 190; ++ .fontRenderer ++ .drawString( ++ this.keyDesc, ++ x + 90 - GuiKeyBindingList.this.maxListLabelWidth, ++ y + slotHeight / 2 - GuiKeyBindingList.this.mc.fontRenderer.FONT_HEIGHT / 2, ++ 16777215 ++ ); ++ this.btnReset.x = x + 210; + this.btnReset.y = y; +- this.btnReset.enabled = this.keybinding.getKeyCode() != this.keybinding.getKeyCodeDefault(); ++ this.btnReset.enabled = !this.keybinding.isSetToDefaultValue(); + this.btnReset.drawButton(GuiKeyBindingList.this.mc, mouseX, mouseY, partialTicks); + this.btnChangeKeyBinding.x = x + 105; + this.btnChangeKeyBinding.y = y; +- this.btnChangeKeyBinding.displayString = GameSettings.getKeyDisplayString(this.keybinding.getKeyCode()); ++ this.btnChangeKeyBinding.displayString = this.keybinding.getDisplayName(); + boolean flag1 = false; ++ boolean keyCodeModifierConflict = true; // less severe form of conflict, like SHIFT conflicting with SHIFT+G ++ + if (this.keybinding.getKeyCode() != 0) { + for (KeyBinding keybinding : GuiKeyBindingList.this.mc.gameSettings.keyBindings) { +- if (keybinding != this.keybinding && keybinding.getKeyCode() == this.keybinding.getKeyCode()) { ++ if (keybinding != this.keybinding && keybinding.conflicts(this.keybinding)) { + flag1 = true; +- break; ++ keyCodeModifierConflict &= keybinding.hasKeyCodeModifierConflict(this.keybinding); + } + } + } +@@ -175,7 +177,7 @@ + + TextFormatting.WHITE + + " <"; + } else if (flag1) { +- this.btnChangeKeyBinding.displayString = TextFormatting.RED + this.btnChangeKeyBinding.displayString; ++ this.btnChangeKeyBinding.displayString = (keyCodeModifierConflict ? TextFormatting.GOLD : TextFormatting.RED) + this.btnChangeKeyBinding.displayString; + } + + this.btnChangeKeyBinding.drawButton(GuiKeyBindingList.this.mc, mouseX, mouseY, partialTicks); +@@ -188,6 +190,7 @@ + GuiKeyBindingList.this.controlsScreen.buttonId = this.keybinding; + return true; + } else if (this.btnReset.mousePressed(GuiKeyBindingList.this.mc, mouseX, mouseY)) { ++ this.keybinding.setToDefault(); + GuiKeyBindingList.this.mc.gameSettings.setOptionKeyBinding(this.keybinding, this.keybinding.getKeyCodeDefault()); + KeyBinding.resetKeyBindingArrayAndHash(); + return true; diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiLanguage.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiLanguage.java.patch new file mode 100644 index 000000000..6c1ae9ea1 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiLanguage.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/client/gui/GuiLanguage.java ++++ modified/net/minecraft/client/gui/GuiLanguage.java +@@ -123,7 +123,7 @@ + Language language = this.languageMap.get(this.langCodeList.get(slotIndex)); + GuiLanguage.this.languageManager.setCurrentLanguage(language); + GuiLanguage.this.game_settings_3.language = language.getLanguageCode(); +- this.mc.refreshResources(); ++ net.minecraftforge.fml.client.FMLClientHandler.instance().refreshResources(net.minecraftforge.client.resource.VanillaResourceType.LANGUAGES); + GuiLanguage.this.fontRenderer.setUnicodeFlag(GuiLanguage.this.languageManager.isCurrentLocaleUnicode() || GuiLanguage.this.game_settings_3.forceUnicodeFont); + GuiLanguage.this.fontRenderer.setBidiFlag(GuiLanguage.this.languageManager.isCurrentLanguageBidirectional()); + GuiLanguage.this.confirmSettingsBtn.displayString = I18n.format("gui.done"); diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiListWorldSelectionEntry.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiListWorldSelectionEntry.java.patch new file mode 100644 index 000000000..560409853 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiListWorldSelectionEntry.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/client/gui/GuiListWorldSelectionEntry.java ++++ modified/net/minecraft/client/gui/GuiListWorldSelectionEntry.java +@@ -240,7 +240,7 @@ + private void loadWorld() { + this.client.getSoundHandler().playSound(PositionedSoundRecord.getMasterRecord(SoundEvents.UI_BUTTON_CLICK, 1.0F)); + if (this.client.getSaveLoader().canLoadWorld(this.worldSummary.getFileName())) { +- this.client.launchIntegratedServer(this.worldSummary.getFileName(), this.worldSummary.getDisplayName(), null); ++ net.minecraftforge.fml.client.FMLClientHandler.instance().tryLoadExistingWorld(worldSelScreen, this.worldSummary); + } + } + diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiMainMenu.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiMainMenu.java.patch new file mode 100644 index 000000000..49318db89 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiMainMenu.java.patch @@ -0,0 +1,149 @@ +--- original/net/minecraft/client/gui/GuiMainMenu.java ++++ modified/net/minecraft/client/gui/GuiMainMenu.java +@@ -93,6 +93,8 @@ + private GuiScreen realmsNotification; + private int widthCopyright; + private int widthCopyrightRest; ++ private GuiButton modButton; ++ private net.minecraftforge.client.gui.NotificationModUpdateScreen modUpdateNotification; + + public GuiMainMenu() { + this.splashText = "missingno"; +@@ -132,19 +134,9 @@ + + /** Is there currently a realms notification screen, and are realms notifications enabled? */ + private boolean areRealmsNotificationsEnabled() { +- return Minecraft.getMinecraft().gameSettings.getOptionOrdinalValue(GameSettings.Options.REALMS_NOTIFICATIONS) && this.realmsNotification != null; ++ return false; + } + +- /** Called from the main game loop to update the screen. */ +- @Override +- public void updateScreen() { +- if (this.areRealmsNotificationsEnabled()) { +- this.realmsNotification.updateScreen(); +- } +- } +- +- /** Returns true if this GUI should pause the game when it is displayed in single-player */ +- @Override + public boolean doesGuiPauseGame() { + return false; + } +@@ -193,25 +185,15 @@ + } + + this.mc.setConnectedToRealms(false); +- if (Minecraft.getMinecraft().gameSettings.getOptionOrdinalValue(GameSettings.Options.REALMS_NOTIFICATIONS) && !this.hasCheckedForRealmsNotification) { +- RealmsBridge realmsbridge = new RealmsBridge(); +- this.realmsNotification = realmsbridge.getNotificationScreen(this); +- this.hasCheckedForRealmsNotification = true; +- } + +- if (this.areRealmsNotificationsEnabled()) { +- this.realmsNotification.setGuiSize(this.width, this.height); +- this.realmsNotification.initGui(); +- } ++ this.modUpdateNotification = net.minecraftforge.client.gui.NotificationModUpdateScreen.init(this, this.modButton); + } + + /** Adds Singleplayer and Multiplayer buttons on Main Menu for players who have bought the game. */ + private void addSingleplayerMultiplayerButtons(int p_73969_1_, int p_73969_2_) { + this.buttonList.add(new GuiButton(1, this.width / 2 - 100, p_73969_1_, I18n.format("menu.singleplayer"))); + this.buttonList.add(new GuiButton(2, this.width / 2 - 100, p_73969_1_ + p_73969_2_ * 1, I18n.format("menu.multiplayer"))); +- this.realmsButton = this.addButton( +- new GuiButton(14, this.width / 2 - 100, p_73969_1_ + p_73969_2_ * 2, I18n.format("menu.online")) +- ); ++ this.buttonList.add(this.modButton = new GuiButton(6, this.width / 2 - 100, p_73969_1_ + p_73969_2_ * 2, I18n.format("fml.menu.mods"))); + } + + /** Adds Demo buttons on Main Menu for players who are playing Demo. */ +@@ -246,14 +228,14 @@ + this.mc.displayGuiScreen(new GuiMultiplayer(this)); + } + +- if (button.id == 14 && this.realmsButton.visible) { +- this.switchToRealms(); +- } +- + if (button.id == 4) { + this.mc.shutdown(); + } + ++ if (button.id == 6) { ++ this.mc.displayGuiScreen(new net.minecraftforge.fml.client.GuiModList(this)); ++ } ++ + if (button.id == 11) { + this.mc.launchIntegratedServer("Demo_World", "Demo_World", WorldServerDemo.DEMO_WORLD_SETTINGS); + } +@@ -278,8 +260,6 @@ + } + + private void switchToRealms() { +- RealmsBridge realmsbridge = new RealmsBridge(); +- realmsbridge.switchToRealms(this); + } + + @Override +@@ -482,6 +462,9 @@ + + this.mc.getTextureManager().bindTexture(field_194400_H); + drawModalRectWithCustomSizedTexture(j + 88, 67, 0.0F, 0.0F, 98, 14, 128.0F, 16.0F); ++ ++ this.splashText = net.minecraftforge.client.ForgeHooksClient.renderMainMenu(this, this.fontRenderer, this.width, this.height, this.splashText); ++ + GlStateManager.pushMatrix(); + GlStateManager.translate(this.width / 2 + 90, 70.0F, 0.0F); + GlStateManager.rotate(-20.0F, 0.0F, 0.0F, 1.0F); +@@ -497,7 +480,14 @@ + s = s + ("release".equalsIgnoreCase(this.mc.getVersionType()) ? "" : "/" + this.mc.getVersionType()); + } + +- this.drawString(this.fontRenderer, s, 2, this.height - 10, -1); ++ java.util.List brandings = com.google.common.collect.Lists.reverse(net.minecraftforge.fml.common.FMLCommonHandler.instance().getBrandings(true)); ++ for (int brdline = 0; brdline < brandings.size(); brdline++) { ++ String brd = brandings.get(brdline); ++ if (!com.google.common.base.Strings.isNullOrEmpty(brd)) { ++ this.drawString(this.fontRenderer, brd, 2, this.height - ( 10 + brdline * (this.fontRenderer.FONT_HEIGHT + 1)), 16777215); ++ } ++ } ++ + this.drawString(this.fontRenderer, "Copyright Mojang AB. Do not distribute!", this.widthCopyrightRest, this.height - 10, -1); + if (mouseX > this.widthCopyrightRest + && mouseX < this.widthCopyrightRest + this.widthCopyright +@@ -516,9 +506,8 @@ + } + + super.drawScreen(mouseX, mouseY, partialTicks); +- if (this.areRealmsNotificationsEnabled()) { +- this.realmsNotification.drawScreen(mouseX, mouseY, partialTicks); +- } ++ ++ modUpdateNotification.drawScreen(mouseX, mouseY, partialTicks); + } + + /** Called when the mouse is clicked. Args : mouseX, mouseY, clickedButton */ +@@ -538,10 +527,6 @@ + } + } + +- if (this.areRealmsNotificationsEnabled()) { +- this.realmsNotification.mouseClicked(mouseX, mouseY, mouseButton); +- } +- + if (mouseX > this.widthCopyrightRest + && mouseX < this.widthCopyrightRest + this.widthCopyright + && mouseY > this.height - 10 +@@ -550,11 +535,4 @@ + } + } + +- /** Called when the screen is unloaded. Used to disable keyboard repeat events */ +- @Override +- public void onGuiClosed() { +- if (this.realmsNotification != null) { +- this.realmsNotification.onGuiClosed(); +- } +- } + } diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiMultiplayer.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiMultiplayer.java.patch new file mode 100644 index 000000000..5b08c5ed6 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiMultiplayer.java.patch @@ -0,0 +1,19 @@ +--- original/net/minecraft/client/gui/GuiMultiplayer.java ++++ modified/net/minecraft/client/gui/GuiMultiplayer.java +@@ -40,6 +40,7 @@ + + public GuiMultiplayer(GuiScreen parentScreen) { + this.parentScreen = parentScreen; ++ net.minecraftforge.fml.client.FMLClientHandler.instance().setupServerList(); + } + + /** Adds the buttons (and other controls) to the screen in question. Called when the GUI is displayed and when the window resizes, the buttonList is cleared beforehand. */ +@@ -301,7 +302,7 @@ + } + + private void connectToServer(ServerData server) { +- this.mc.displayGuiScreen(new GuiConnecting(this, this.mc, server)); ++ net.minecraftforge.fml.client.FMLClientHandler.instance().connectToServer(this, server); + } + + public void selectServer(int index) { diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiOptions.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiOptions.java.patch new file mode 100644 index 000000000..50f68466b --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiOptions.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/client/gui/GuiOptions.java ++++ modified/net/minecraft/client/gui/GuiOptions.java +@@ -74,7 +74,7 @@ + } else { + this.difficultyButton.enabled = false; + } +- } else { ++ } else if (false) { // removed realms button + this.buttonList + .add( + new GuiOptionButton( diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiOverlayDebug.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiOverlayDebug.java.patch new file mode 100644 index 000000000..a335f5858 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiOverlayDebug.java.patch @@ -0,0 +1,50 @@ +--- original/net/minecraft/client/gui/GuiOverlayDebug.java ++++ modified/net/minecraft/client/gui/GuiOverlayDebug.java +@@ -2,6 +2,7 @@ + + import com.google.common.base.Strings; + import com.google.common.collect.Lists; ++import com.google.common.collect.UnmodifiableIterator; + import java.util.List; + import java.util.Map.Entry; + import net.minecraft.block.Block; +@@ -25,6 +26,7 @@ + import net.minecraft.world.chunk.Chunk; + import net.minecraftforge.fml.relauncher.Side; + import net.minecraftforge.fml.relauncher.SideOnly; ++import org.lwjgl.Sys; + import org.lwjgl.opengl.Display; + + @SideOnly(Side.CLIENT) +@@ -218,16 +220,21 @@ + long k = Runtime.getRuntime().freeMemory(); + long l = j - k; + List list = Lists.newArrayList( +- String.format("Java: %s %dbit", System.getProperty("java.version"), this.mc.isJava64bit() ? 64 : 32), +- String.format("Mem: % 2d%% %03d/%03dMB", l * 100L / i, bytesToMb(l), bytesToMb(i)), +- String.format("Allocated: % 2d%% %03dMB", j * 100L / i, bytesToMb(j)), +- "", +- String.format("CPU: %s", OpenGlHelper.getCpu()), +- "", +- String.format("Display: %dx%d (%s)", Display.getWidth(), Display.getHeight(), GlStateManager.glGetString(7936)), +- GlStateManager.glGetString(7937), +- GlStateManager.glGetString(7938) +- ); ++ String.format("Java: %s %dbit", System.getProperty("java.version"), this.mc.isJava64bit() ? 64 : 32), ++ "LWJGL: " + Sys.getVersion(), ++ String.format("Mem: % 2d%% %03d/%03dMB", l * 100L / i, bytesToMb(l), bytesToMb(i)), ++ String.format("Allocated: % 2d%% %03dMB", j * 100L / i, bytesToMb(j)), ++ "", ++ String.format("CPU: %s", OpenGlHelper.getCpu()), ++ "", ++ String.format("Display: %dx%d (%s)", Display.getWidth(), Display.getHeight(), GlStateManager.glGetString(7936)), ++ GlStateManager.glGetString(7937), ++ GlStateManager.glGetString(7938) ++ ); ++ ++ list.add(""); ++ list.addAll(net.minecraftforge.fml.common.FMLCommonHandler.instance().getBrandings(false)); ++ + if (this.mc.isReducedDebug()) { + return list; + } diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiScreen.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiScreen.java.patch new file mode 100644 index 000000000..e4c7c1757 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiScreen.java.patch @@ -0,0 +1,114 @@ +--- original/net/minecraft/client/gui/GuiScreen.java ++++ modified/net/minecraft/client/gui/GuiScreen.java +@@ -68,6 +68,7 @@ + private int touchValue; + private URI clickedLinkURI; + private boolean focused; ++ protected boolean keyHandled, mouseHandled; // Forge: allow canceling key and mouse Post events from handleMouseInput and handleKeyboardInput + + /** Draws the screen and all the components in it. */ + public void drawScreen(int mouseX, int mouseY, float partialTicks) { +@@ -127,7 +128,10 @@ + } + + protected void renderToolTip(ItemStack stack, int x, int y) { +- this.drawHoveringText(this.getItemToolTip(stack), x, y); ++ FontRenderer font = stack.getItem().getFontRenderer(stack); ++ net.minecraftforge.fml.client.config.GuiUtils.preItemToolTip(stack); ++ this.drawHoveringText(this.getItemToolTip(stack), x, y, (font == null ? fontRenderer : font)); ++ net.minecraftforge.fml.client.config.GuiUtils.postItemToolTip(); + } + + public List getItemToolTip(ItemStack p_191927_1_) { +@@ -138,7 +142,7 @@ + + for (int i = 0; i < list.size(); i++) { + if (i == 0) { +- list.set(i, p_191927_1_.getRarity().color + list.get(i)); ++ list.set(i, p_191927_1_.getItem().getForgeRarity(p_191927_1_).getColor() + (String)list.get(i)); + } else { + list.set(i, TextFormatting.GRAY + list.get(i)); + } +@@ -162,7 +166,12 @@ + + /** Draws a List of strings as a tooltip. Every entry is drawn on a seperate line. */ + public void drawHoveringText(List textLines, int x, int y) { +- if (!textLines.isEmpty()) { ++ drawHoveringText(textLines, x, y, fontRenderer); ++ } ++ ++ protected void drawHoveringText(List textLines, int x, int y, FontRenderer font) { ++ net.minecraftforge.fml.client.config.GuiUtils.drawHoveringText(textLines, x, y, width, height, -1, font); ++ if (false && !textLines.isEmpty()) { + GlStateManager.disableRescaleNormal(); + RenderHelper.disableStandardItemLighting(); + GlStateManager.disableLighting(); +@@ -339,9 +348,12 @@ + } + + public void sendChatMessage(String msg, boolean addToChat) { ++ msg = net.minecraftforge.event.ForgeEventFactory.onClientSendMessage(msg); ++ if (msg.isEmpty()) return; + if (addToChat) { + this.mc.ingameGUI.getChatGUI().addToSentMessages(msg); + } ++ if (net.minecraftforge.client.ClientCommandHandler.instance.executeCommand(mc.player, msg) != 0) return; + + this.mc.player.sendChatMessage(msg); + } +@@ -352,9 +364,15 @@ + for (int i = 0; i < this.buttonList.size(); i++) { + GuiButton guibutton = this.buttonList.get(i); + if (guibutton.mousePressed(this.mc, mouseX, mouseY)) { ++ net.minecraftforge.client.event.GuiScreenEvent.ActionPerformedEvent.Pre event = new net.minecraftforge.client.event.GuiScreenEvent.ActionPerformedEvent.Pre(this, guibutton, this.buttonList); ++ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event)) ++ break; ++ guibutton = event.getButton(); + this.selectedButton = guibutton; + guibutton.playPressSound(this.mc.getSoundHandler()); + this.actionPerformed(guibutton); ++ if (this.equals(this.mc.currentScreen)) ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.GuiScreenEvent.ActionPerformedEvent.Post(this, event.getButton(), this.buttonList)); + } + } + } +@@ -383,8 +401,11 @@ + this.fontRenderer = mc.fontRenderer; + this.width = width; + this.height = height; ++ if (!net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.GuiScreenEvent.InitGuiEvent.Pre(this, this.buttonList))) { + this.buttonList.clear(); + this.initGui(); ++ } ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.GuiScreenEvent.InitGuiEvent.Post(this, this.buttonList)); + } + + /** Set the gui to the specified width and height */ +@@ -401,13 +422,19 @@ + public void handleInput() throws IOException { + if (Mouse.isCreated()) { + while (Mouse.next()) { ++ this.mouseHandled = false; ++ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.GuiScreenEvent.MouseInputEvent.Pre(this))) continue; + this.handleMouseInput(); ++ if (this.equals(this.mc.currentScreen) && !this.mouseHandled) net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.GuiScreenEvent.MouseInputEvent.Post(this)); + } + } + + if (Keyboard.isCreated()) { + while (Keyboard.next()) { ++ this.keyHandled = false; ++ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.GuiScreenEvent.KeyboardInputEvent.Pre(this))) continue; + this.handleKeyboardInput(); ++ if (this.equals(this.mc.currentScreen) && !this.keyHandled) net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.GuiScreenEvent.KeyboardInputEvent.Post(this)); + } + } + } +@@ -465,6 +492,7 @@ + */ + public void drawDefaultBackground() { + this.drawWorldBackground(0); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.GuiScreenEvent.BackgroundDrawnEvent(this)); + } + + /** diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiScreenBook.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiScreenBook.java.patch new file mode 100644 index 000000000..8ea78235b --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiScreenBook.java.patch @@ -0,0 +1,10 @@ +--- original/net/minecraft/client/gui/GuiScreenBook.java ++++ modified/net/minecraft/client/gui/GuiScreenBook.java +@@ -69,6 +69,7 @@ + this.bookPages = nbttagcompound.getTagList("pages", 8).copy(); + this.bookTotalPages = this.bookPages.tagCount(); + if (this.bookTotalPages < 1) { ++ this.bookPages.appendTag(new NBTTagString("")); // Forge: fix MC-1685 + this.bookTotalPages = 1; + } + } diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiScreenDemo.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiScreenDemo.java.patch new file mode 100644 index 000000000..f67cb531b --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiScreenDemo.java.patch @@ -0,0 +1,40 @@ +--- original/net/minecraft/client/gui/GuiScreenDemo.java ++++ modified/net/minecraft/client/gui/GuiScreenDemo.java +@@ -75,23 +75,23 @@ + j += 12; + GameSettings gamesettings = this.mc.gameSettings; + this.fontRenderer +- .drawString( +- I18n.format( +- "demo.help.movementShort", +- GameSettings.getKeyDisplayString(gamesettings.keyBindForward.getKeyCode()), +- GameSettings.getKeyDisplayString(gamesettings.keyBindLeft.getKeyCode()), +- GameSettings.getKeyDisplayString(gamesettings.keyBindBack.getKeyCode()), +- GameSettings.getKeyDisplayString(gamesettings.keyBindRight.getKeyCode()) +- ), +- i, +- j, +- 5197647 +- ); ++ .drawString( ++ I18n.format( ++ "demo.help.movementShort", ++ gamesettings.keyBindForward.getDisplayName(), ++ gamesettings.keyBindLeft.getDisplayName(), ++ gamesettings.keyBindBack.getDisplayName(), ++ gamesettings.keyBindRight.getDisplayName() ++ ), ++ i, ++ j, ++ 5197647 ++ ); + this.fontRenderer.drawString(I18n.format("demo.help.movementMouse"), i, j + 12, 5197647); + this.fontRenderer +- .drawString(I18n.format("demo.help.jump", GameSettings.getKeyDisplayString(gamesettings.keyBindJump.getKeyCode())), i, j + 24, 5197647); ++ .drawString(I18n.format("demo.help.jump", gamesettings.keyBindJump.getDisplayName()), i, j + 24, 5197647); + this.fontRenderer +- .drawString(I18n.format("demo.help.inventory", GameSettings.getKeyDisplayString(gamesettings.keyBindInventory.getKeyCode())), i, j + 36, 5197647); ++ .drawString(I18n.format("demo.help.inventory", gamesettings.keyBindInventory.getDisplayName()), i, j + 36, 5197647); + this.fontRenderer.drawSplitString(I18n.format("demo.help.fullWrapped"), i, j + 68, 218, 2039583); + super.drawScreen(mouseX, mouseY, partialTicks); + } diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiSleepMP.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiSleepMP.java.patch new file mode 100644 index 000000000..7f7c5a4fd --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiSleepMP.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/client/gui/GuiSleepMP.java ++++ modified/net/minecraft/client/gui/GuiSleepMP.java +@@ -26,7 +26,7 @@ + } else { + String s = this.inputField.getText().trim(); + if (!s.isEmpty()) { +- this.mc.player.sendChatMessage(s); ++ this.sendChatMessage(s); // Forge: fix vanilla not adding messages to the sent list while sleeping + } + + this.inputField.setText(""); diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiSlot.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiSlot.java.patch new file mode 100644 index 000000000..26f07f387 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiSlot.java.patch @@ -0,0 +1,62 @@ +--- original/net/minecraft/client/gui/GuiSlot.java ++++ modified/net/minecraft/client/gui/GuiSlot.java +@@ -178,27 +178,8 @@ + GlStateManager.disableFog(); + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder bufferbuilder = tessellator.getBuffer(); +- this.mc.getTextureManager().bindTexture(Gui.OPTIONS_BACKGROUND); +- GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); +- float f = 32.0F; +- bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR); +- bufferbuilder.pos(this.left, this.bottom, 0.0) +- .tex(this.left / 32.0F, (this.bottom + (int)this.amountScrolled) / 32.0F) +- .color(32, 32, 32, 255) +- .endVertex(); +- bufferbuilder.pos(this.right, this.bottom, 0.0) +- .tex(this.right / 32.0F, (this.bottom + (int)this.amountScrolled) / 32.0F) +- .color(32, 32, 32, 255) +- .endVertex(); +- bufferbuilder.pos(this.right, this.top, 0.0) +- .tex(this.right / 32.0F, (this.top + (int)this.amountScrolled) / 32.0F) +- .color(32, 32, 32, 255) +- .endVertex(); +- bufferbuilder.pos(this.left, this.top, 0.0) +- .tex(this.left / 32.0F, (this.top + (int)this.amountScrolled) / 32.0F) +- .color(32, 32, 32, 255) +- .endVertex(); +- tessellator.draw(); ++ // Forge: background rendering moved into separate method. ++ this.drawContainerBackground(tessellator); + int k = this.left + this.width / 2 - this.getListWidth() / 2 + 2; + int l = this.top + 4 - (int)this.amountScrolled; + if (this.hasListHeader) { +@@ -438,4 +419,29 @@ + public int getSlotHeight() { + return this.slotHeight; + } ++ ++ protected void drawContainerBackground(Tessellator tessellator) { ++ BufferBuilder buffer = tessellator.getBuffer(); ++ this.mc.getTextureManager().bindTexture(Gui.OPTIONS_BACKGROUND); ++ GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); ++ float f = 32.0F; ++ buffer.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR); ++ buffer.pos(this.left, this.bottom, 0.0) ++ .tex((float)this.left / f, (float)(this.bottom + (int)this.amountScrolled) / f) ++ .color(32, 32, 32, 255) ++ .endVertex(); ++ buffer.pos(this.right, this.bottom, 0.0) ++ .tex((float)this.right / f, (float)(this.bottom + (int)this.amountScrolled) / f) ++ .color(32, 32, 32, 255) ++ .endVertex(); ++ buffer.pos(this.right, this.top, 0.0) ++ .tex((float)this.right / f, (float)(this.top + (int)this.amountScrolled) / f) ++ .color(32, 32, 32, 255) ++ .endVertex(); ++ buffer.pos(this.left, this.top, 0.0) ++ .tex((float)this.left / f, (float)(this.top + (int)this.amountScrolled) / f) ++ .color(32, 32, 32, 255) ++ .endVertex(); ++ tessellator.draw(); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiSpectator.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiSpectator.java.patch new file mode 100644 index 000000000..3b0d73e20 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiSpectator.java.patch @@ -0,0 +1,12 @@ +--- original/net/minecraft/client/gui/GuiSpectator.java ++++ modified/net/minecraft/client/gui/GuiSpectator.java +@@ -93,7 +93,8 @@ + GlStateManager.color(f, f, f, p_175266_4_); + p_175266_5_.renderIcon(f, i); + GlStateManager.popMatrix(); +- String s = String.valueOf(GameSettings.getKeyDisplayString(this.mc.gameSettings.keyBindsHotbar[p_175266_1_].getKeyCode())); ++ String s = String.valueOf(this.mc.gameSettings.keyBindsHotbar[p_175266_1_].getDisplayName()); ++ + if (i > 3 && p_175266_5_.isEnabled()) { + this.mc + .fontRenderer diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiTextField.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiTextField.java.patch new file mode 100644 index 000000000..2e421e518 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiTextField.java.patch @@ -0,0 +1,18 @@ +--- original/net/minecraft/client/gui/GuiTextField.java ++++ modified/net/minecraft/client/gui/GuiTextField.java +@@ -1,5 +1,6 @@ + package net.minecraft.client.gui; + ++import com.cleanroommc.client.IMEHandler; + import com.google.common.base.Predicate; + import com.google.common.base.Predicates; + import net.minecraft.client.Minecraft; +@@ -519,6 +520,8 @@ + } + + this.isFocused = isFocusedIn; ++ IMEHandler.setIME(this.isFocused); ++ + if (Minecraft.getMinecraft().currentScreen != null) { + Minecraft.getMinecraft().currentScreen.setFocused(isFocusedIn); + } diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiUtilRenderComponents.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiUtilRenderComponents.java.patch new file mode 100644 index 000000000..6eeb56073 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiUtilRenderComponents.java.patch @@ -0,0 +1,27 @@ +--- original/net/minecraft/client/gui/GuiUtilRenderComponents.java ++++ modified/net/minecraft/client/gui/GuiUtilRenderComponents.java +@@ -46,10 +46,13 @@ + String s2 = fontRendererIn.trimStringToWidth(s4, maxTextLenght - i, false); + String s3 = s2.length() < s4.length() ? s4.substring(s2.length()) : null; + if (s3 != null && !s3.isEmpty()) { +- int l = s2.lastIndexOf(32); ++ com.cleanroommc.client.ICU4JInstances.BREAK_ITERATOR.setText(s4); ++ int l = com.cleanroommc.client.ICU4JInstances.BREAK_ITERATOR.preceding(s2.length()); ++ + if (l >= 0 && fontRendererIn.getStringWidth(s4.substring(0, l)) > 0) { + s2 = s4.substring(0, l); +- if (p_178908_3_) { ++ ++ if (p_178908_3_ && s4.charAt(l) == ' ') { + l++; + } + +@@ -59,6 +62,8 @@ + s3 = s4; + } + ++ s3 = FontRenderer.getFormatFromString(s2) + s3; //Forge: Fix chat formatting not surviving line wrapping. ++ + TextComponentString textcomponentstring1 = new TextComponentString(s3); + textcomponentstring1.setStyle(itextcomponent1.getStyle().createShallowCopy()); + list1.add(j + 1, textcomponentstring1); diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiVideoSettings.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiVideoSettings.java.patch new file mode 100644 index 000000000..c9933adbe --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiVideoSettings.java.patch @@ -0,0 +1,14 @@ +--- original/net/minecraft/client/gui/GuiVideoSettings.java ++++ modified/net/minecraft/client/gui/GuiVideoSettings.java +@@ -131,4 +131,11 @@ + this.drawCenteredString(this.fontRenderer, this.screenTitle, this.width / 2, 5, 16777215); + super.drawScreen(mouseX, mouseY, partialTicks); + } ++ ++ // FORGE: fix for MC-64581 very laggy mipmap slider ++ @Override ++ public void onGuiClosed() { ++ super.onGuiClosed(); ++ this.mc.gameSettings.onGuiClosed(); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/client/gui/MapItemRenderer.java.patch b/module/minecraft/patches/net/minecraft/client/gui/MapItemRenderer.java.patch new file mode 100644 index 000000000..bf41ed189 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/MapItemRenderer.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/client/gui/MapItemRenderer.java ++++ modified/net/minecraft/client/gui/MapItemRenderer.java +@@ -123,6 +123,8 @@ + + for (MapDecoration mapdecoration : this.mapData.mapDecorations.values()) { + if (!noOverlayRendering || mapdecoration.renderOnFrame()) { ++ if (mapdecoration.render(k)) { k++; continue; } ++ MapItemRenderer.this.textureManager.bindTexture(MapItemRenderer.TEXTURE_MAP_ICONS); // Rebind in case custom render changes it + GlStateManager.pushMatrix(); + GlStateManager.translate( + 0.0F + mapdecoration.getX() / 2.0F + 64.0F, 0.0F + mapdecoration.getY() / 2.0F + 64.0F, -0.02F diff --git a/module/minecraft/patches/net/minecraft/client/gui/ScaledResolution.java.patch b/module/minecraft/patches/net/minecraft/client/gui/ScaledResolution.java.patch new file mode 100644 index 000000000..542244816 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/ScaledResolution.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/client/gui/ScaledResolution.java ++++ modified/net/minecraft/client/gui/ScaledResolution.java +@@ -28,7 +28,7 @@ + } + + if (flag && this.scaleFactor % 2 != 0 && this.scaleFactor != 1) { +- this.scaleFactor--; ++ this.scaleFactor++; + } + + this.scaledWidthD = (double)this.scaledWidth / this.scaleFactor; diff --git a/module/minecraft/patches/net/minecraft/client/gui/ServerListEntryNormal.java.patch b/module/minecraft/patches/net/minecraft/client/gui/ServerListEntryNormal.java.patch new file mode 100644 index 000000000..d5651e475 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/ServerListEntryNormal.java.patch @@ -0,0 +1,23 @@ +--- original/net/minecraft/client/gui/ServerListEntryNormal.java ++++ modified/net/minecraft/client/gui/ServerListEntryNormal.java +@@ -90,7 +90,7 @@ + boolean flag1 = this.server.version < 340; + boolean flag2 = flag || flag1; + this.mc.fontRenderer.drawString(this.server.serverName, x + 32 + 3, y + 1, 16777215); +- List list = this.mc.fontRenderer.listFormattedStringToWidth(this.server.serverMOTD, listWidth - 32 - 2); ++ List list = this.mc.fontRenderer.listFormattedStringToWidth(net.minecraftforge.fml.client.FMLClientHandler.instance().fixDescription(this.server.serverMOTD), listWidth - 32 - 2); + + for (int i = 0; i < Math.min(list.size(), 2); i++) { + this.mc +@@ -157,6 +157,11 @@ + + int i1 = mouseX - x; + int j1 = mouseY - y; ++ ++ String tooltip = net.minecraftforge.fml.client.FMLClientHandler.instance().enhanceServerListEntry(this, this.server, x, listWidth, y, i1, j1); ++ if (tooltip != null) { ++ this.owner.setHoveringText(tooltip); ++ } else + if (i1 >= listWidth - 15 && i1 <= listWidth - 5 && j1 >= 0 && j1 <= 8) { + this.owner.setHoveringText(s1); + } else if (i1 >= listWidth - j - 15 - 2 && i1 <= listWidth - 15 - 2 && j1 >= 0 && j1 <= 8) { diff --git a/module/minecraft/patches/net/minecraft/client/gui/advancements/GuiAdvancementTab.java.patch b/module/minecraft/patches/net/minecraft/client/gui/advancements/GuiAdvancementTab.java.patch new file mode 100644 index 000000000..5bb2e2430 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/advancements/GuiAdvancementTab.java.patch @@ -0,0 +1,37 @@ +--- original/net/minecraft/client/gui/advancements/GuiAdvancementTab.java ++++ modified/net/minecraft/client/gui/advancements/GuiAdvancementTab.java +@@ -36,6 +36,7 @@ + private int maxY = Integer.MIN_VALUE; + private float fade; + private boolean centered; ++ private int page; + + public GuiAdvancementTab( + Minecraft p_i47589_1_, +@@ -139,8 +140,8 @@ + } + + for (AdvancementTabType advancementtabtype : AdvancementTabType.values()) { +- if (p_193936_2_ < advancementtabtype.getMax()) { +- return new GuiAdvancementTab(p_193936_0_, p_193936_1_, advancementtabtype, p_193936_2_, p_193936_3_, p_193936_3_.getDisplay()); ++ if ((p_193936_2_ % AdvancementTabType.MAX_TABS) < advancementtabtype.getMax()) { ++ return new GuiAdvancementTab(p_193936_0_, p_193936_1_, advancementtabtype, p_193936_2_ % AdvancementTabType.MAX_TABS, p_193936_2_ / AdvancementTabType.MAX_TABS, p_193936_3_, p_193936_3_.getDisplay()); + } + + p_193936_2_ -= advancementtabtype.getMax(); +@@ -190,4 +191,15 @@ + public GuiScreenAdvancements getScreen() { + return this.screen; + } ++ ++ /* ======================================== FORGE START =====================================*/ ++ public int getPage() { ++ return this.page; ++ } ++ ++ public GuiAdvancementTab(Minecraft p_i47589_1_, GuiScreenAdvancements p_i47589_2_, AdvancementTabType p_i47589_3_, int p_i47589_4_, int page, Advancement p_i47589_5_, DisplayInfo p_i47589_6_) { ++ this(p_i47589_1_, p_i47589_2_, p_i47589_3_, p_i47589_4_, p_i47589_5_, p_i47589_6_); ++ this.page = page; ++ } ++ /* ======================================== FORGE END =====================================*/ + } diff --git a/module/minecraft/patches/net/minecraft/client/gui/advancements/GuiScreenAdvancements.java.patch b/module/minecraft/patches/net/minecraft/client/gui/advancements/GuiScreenAdvancements.java.patch new file mode 100644 index 000000000..0adeeae86 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/advancements/GuiScreenAdvancements.java.patch @@ -0,0 +1,85 @@ +--- original/net/minecraft/client/gui/advancements/GuiScreenAdvancements.java ++++ modified/net/minecraft/client/gui/advancements/GuiScreenAdvancements.java +@@ -28,6 +28,7 @@ + private int scrollMouseX; + private int scrollMouseY; + private boolean isScrolling; ++ private static int tabPage, maxPages; + + public GuiScreenAdvancements(ClientAdvancementManager p_i47383_1_) { + this.clientAdvancementManager = p_i47383_1_; +@@ -44,6 +45,13 @@ + } else { + this.clientAdvancementManager.setSelectedTab(this.selectedTab == null ? null : this.selectedTab.getAdvancement(), true); + } ++ if (this.tabs.size() > AdvancementTabType.MAX_TABS) { ++ int guiLeft = (this.width - 252) / 2; ++ int guiTop = (this.height - 140) / 2; ++ this.buttonList.add(new net.minecraft.client.gui.GuiButton(101, guiLeft, guiTop - 50, 20, 20, "<")); ++ this.buttonList.add(new net.minecraft.client.gui.GuiButton(102, guiLeft + 252 - 20, guiTop - 50, 20, 20, ">")); ++ maxPages = this.tabs.size() / AdvancementTabType.MAX_TABS; ++ } + } + + /** Called when the screen is unloaded. Used to disable keyboard repeat events */ +@@ -64,7 +72,7 @@ + int j = (this.height - 140) / 2; + + for (GuiAdvancementTab guiadvancementtab : this.tabs.values()) { +- if (guiadvancementtab.isMouseOver(i, j, mouseX, mouseY)) { ++ if (guiadvancementtab.getPage() == tabPage && guiadvancementtab.isMouseOver(i, j, mouseX, mouseY)) { + this.clientAdvancementManager.setSelectedTab(guiadvancementtab.getAdvancement(), true); + break; + } +@@ -106,6 +114,13 @@ + this.drawDefaultBackground(); + this.renderInside(mouseX, mouseY, i, j); + this.renderWindow(i, j); ++ super.drawScreen(mouseX, mouseY, partialTicks); ++ if (maxPages != 0) { ++ String page = String.format("%d / %d", tabPage + 1, maxPages + 1); ++ int width = this.fontRenderer.getStringWidth(page); ++ GlStateManager.disableLighting(); ++ this.fontRenderer.drawStringWithShadow(page, i + (252 / 2) - (width / 2), j - 44, -1); ++ } + this.renderToolTips(mouseX, mouseY, i, j); + } + +@@ -141,6 +156,7 @@ + this.mc.getTextureManager().bindTexture(TABS); + + for (GuiAdvancementTab guiadvancementtab : this.tabs.values()) { ++ if(guiadvancementtab.getPage() == tabPage) + guiadvancementtab.drawTab(p_191934_1_, p_191934_2_, guiadvancementtab == this.selectedTab); + } + +@@ -154,6 +170,7 @@ + RenderHelper.enableGUIStandardItemLighting(); + + for (GuiAdvancementTab guiadvancementtab1 : this.tabs.values()) { ++ if(guiadvancementtab1.getPage() == tabPage) + guiadvancementtab1.drawIcon(p_191934_1_, p_191934_2_, this.itemRender); + } + +@@ -176,7 +193,7 @@ + + if (this.tabs.size() > 1) { + for (GuiAdvancementTab guiadvancementtab : this.tabs.values()) { +- if (guiadvancementtab.isMouseOver(p_191937_3_, p_191937_4_, p_191937_1_, p_191937_2_)) { ++ if (guiadvancementtab.getPage() == tabPage && guiadvancementtab.isMouseOver(p_191937_3_, p_191937_4_, p_191937_1_, p_191937_2_)) { + this.drawHoveringText(guiadvancementtab.getTitle(), p_191937_1_, p_191937_2_); + } + } +@@ -240,4 +257,12 @@ + + return this.tabs.get(p_191935_1_); + } ++ ++ @Override ++ protected void actionPerformed(net.minecraft.client.gui.GuiButton button) throws IOException { ++ if(button.id == 101) ++ tabPage = Math.max(tabPage - 1, 0); ++ else if(button.id == 102) ++ tabPage = Math.min(tabPage + 1, maxPages); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/client/gui/inventory/GuiContainer.java.patch b/module/minecraft/patches/net/minecraft/client/gui/inventory/GuiContainer.java.patch new file mode 100644 index 000000000..8379cc162 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/inventory/GuiContainer.java.patch @@ -0,0 +1,158 @@ +--- original/net/minecraft/client/gui/inventory/GuiContainer.java ++++ modified/net/minecraft/client/gui/inventory/GuiContainer.java +@@ -123,6 +123,7 @@ + RenderHelper.disableStandardItemLighting(); + this.drawGuiContainerForegroundLayer(mouseX, mouseY); + RenderHelper.enableGUIStandardItemLighting(); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.GuiContainerEvent.DrawForeground(this, mouseX, mouseY)); + InventoryPlayer inventoryplayer = this.mc.player.inventory; + ItemStack itemstack = this.draggedStack.isEmpty() ? inventoryplayer.getItemStack() : this.draggedStack; + if (!itemstack.isEmpty()) { +@@ -180,9 +181,11 @@ + GlStateManager.translate(0.0F, 0.0F, 32.0F); + this.zLevel = 200.0F; + this.itemRender.zLevel = 200.0F; ++ net.minecraft.client.gui.FontRenderer font = stack.getItem().getFontRenderer(stack); ++ if (font == null) font = fontRenderer; + this.itemRender.renderItemAndEffectIntoGUI(stack, x, y); + this.itemRender +- .renderItemOverlayIntoGUI(this.fontRenderer, stack, x, y - (this.draggedStack.isEmpty() ? 0 : 8), altText); ++ .renderItemOverlayIntoGUI(font, stack, x, y - (this.draggedStack.isEmpty() ? 0 : 8), altText); + this.zLevel = 0.0F; + this.itemRender.zLevel = 0.0F; + } +@@ -234,11 +237,11 @@ + this.zLevel = 100.0F; + this.itemRender.zLevel = 100.0F; + if (itemstack.isEmpty() && slotIn.isEnabled()) { +- String s1 = slotIn.getSlotTexture(); +- if (s1 != null) { +- TextureAtlasSprite textureatlassprite = this.mc.getTextureMapBlocks().getAtlasSprite(s1); ++ TextureAtlasSprite textureatlassprite = slotIn.getBackgroundSprite(); ++ ++ if (textureatlassprite != null) { + GlStateManager.disableLighting(); +- this.mc.getTextureManager().bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); ++ this.mc.getTextureManager().bindTexture(slotIn.getBackgroundLocation()); + this.drawTexturedModalRect(i, j, textureatlassprite, 16, 16); + GlStateManager.enableLighting(); + flag1 = true; +@@ -299,7 +302,7 @@ + @Override + protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { + super.mouseClicked(mouseX, mouseY, mouseButton); +- boolean flag = mouseButton == this.mc.gameSettings.keyBindPickBlock.getKeyCode() + 100; ++ boolean flag = this.mc.gameSettings.keyBindPickBlock.isActiveAndMatches(mouseButton - 100); + Slot slot = this.getSlotAtPosition(mouseX, mouseY); + long i = Minecraft.getSystemTime(); + this.doubleClick = this.lastClickSlot == slot && i - this.lastClickTime < 250L && this.lastClickButton == mouseButton; +@@ -308,6 +311,7 @@ + int j = this.guiLeft; + int k = this.guiTop; + boolean flag1 = this.hasClickedOutside(mouseX, mouseY, j, k); ++ if (slot != null) flag1 = false; // Forge, prevent dropping of items through slots outside of GUI boundaries + int l = -1; + if (slot != null) { + l = slot.slotNumber; +@@ -333,7 +337,7 @@ + } + } else if (!this.dragSplitting) { + if (this.mc.player.inventory.getItemStack().isEmpty()) { +- if (mouseButton == this.mc.gameSettings.keyBindPickBlock.getKeyCode() + 100) { ++ if (this.mc.gameSettings.keyBindPickBlock.isActiveAndMatches(mouseButton - 100)) { + this.handleMouseClick(slot, l, mouseButton, ClickType.CLONE); + } else { + boolean flag2 = l != -999 && (Keyboard.isKeyDown(42) || Keyboard.isKeyDown(54)); +@@ -357,7 +361,7 @@ + this.dragSplittingLimit = 0; + } else if (mouseButton == 1) { + this.dragSplittingLimit = 1; +- } else if (mouseButton == this.mc.gameSettings.keyBindPickBlock.getKeyCode() + 100) { ++ } else if (this.mc.gameSettings.keyBindPickBlock.isActiveAndMatches(mouseButton - 100)) { + this.dragSplittingLimit = 2; + } + } +@@ -419,10 +423,12 @@ + /** Called when a mouse button is released. */ + @Override + protected void mouseReleased(int mouseX, int mouseY, int state) { ++ super.mouseReleased(mouseX, mouseY, state); //Forge, Call parent to release buttons + Slot slot = this.getSlotAtPosition(mouseX, mouseY); + int i = this.guiLeft; + int j = this.guiTop; + boolean flag = this.hasClickedOutside(mouseX, mouseY, i, j); ++ if (slot != null) flag = false; // Forge, prevent dropping of items through slots outside of GUI boundaries + int k = -1; + if (slot != null) { + k = slot.slotNumber; +@@ -437,10 +443,10 @@ + if (!this.shiftClickedSlot.isEmpty()) { + for (Slot slot2 : this.inventorySlots.inventorySlots) { + if (slot2 != null +- && slot2.canTakeStack(this.mc.player) +- && slot2.getHasStack() +- && slot2.inventory == slot.inventory +- && Container.canAddItemToSlot(slot2, this.shiftClickedSlot, true)) { ++ && slot2.canTakeStack(this.mc.player) ++ && slot2.getHasStack() ++ && slot2.isSameInventory(slot) ++ && Container.canAddItemToSlot(slot2, this.shiftClickedSlot, true)) { + this.handleMouseClick(slot2, slot2.slotNumber, state, ClickType.QUICK_MOVE); + } + } +@@ -504,7 +510,7 @@ + + this.handleMouseClick(null, -999, Container.getQuickcraftMask(2, this.dragSplittingLimit), ClickType.QUICK_CRAFT); + } else if (!this.mc.player.inventory.getItemStack().isEmpty()) { +- if (state == this.mc.gameSettings.keyBindPickBlock.getKeyCode() + 100) { ++ if (this.mc.gameSettings.keyBindPickBlock.isActiveAndMatches(state - 100)) { + this.handleMouseClick(slot, k, state, ClickType.CLONE); + } else { + boolean flag1 = k != -999 && (Keyboard.isKeyDown(42) || Keyboard.isKeyDown(54)); +@@ -555,15 +561,15 @@ + /** Fired when a key is typed (except F11 which toggles full screen). This is the equivalent of KeyListener.keyTyped(KeyEvent e). Args : character (character on the key), keyCode (lwjgl Keyboard key code) */ + @Override + protected void keyTyped(char typedChar, int keyCode) throws IOException { +- if (keyCode == 1 || keyCode == this.mc.gameSettings.keyBindInventory.getKeyCode()) { ++ if (keyCode == 1 || this.mc.gameSettings.keyBindInventory.isActiveAndMatches(keyCode)) { + this.mc.player.closeScreen(); + } + + this.checkHotbarKeys(keyCode); + if (this.hoveredSlot != null && this.hoveredSlot.getHasStack()) { +- if (keyCode == this.mc.gameSettings.keyBindPickBlock.getKeyCode()) { ++ if (this.mc.gameSettings.keyBindPickBlock.isActiveAndMatches(keyCode)) { + this.handleMouseClick(this.hoveredSlot, this.hoveredSlot.slotNumber, 0, ClickType.CLONE); +- } else if (keyCode == this.mc.gameSettings.keyBindDrop.getKeyCode()) { ++ } else if (this.mc.gameSettings.keyBindDrop.isActiveAndMatches(keyCode)) { + this.handleMouseClick(this.hoveredSlot, this.hoveredSlot.slotNumber, isCtrlKeyDown() ? 1 : 0, ClickType.THROW); + } + } +@@ -576,7 +582,7 @@ + protected boolean checkHotbarKeys(int keyCode) { + if (this.mc.player.inventory.getItemStack().isEmpty() && this.hoveredSlot != null) { + for (int i = 0; i < 9; i++) { +- if (keyCode == this.mc.gameSettings.keyBindsHotbar[i].getKeyCode()) { ++ if (this.mc.gameSettings.keyBindsHotbar[i].isActiveAndMatches(keyCode)) { + this.handleMouseClick(this.hoveredSlot, this.hoveredSlot.slotNumber, i, ClickType.SWAP); + return true; + } +@@ -608,4 +614,18 @@ + this.mc.player.closeScreen(); + } + } ++ ++ /* ======================================== FORGE START =====================================*/ ++ ++ /** ++ * Returns the slot that is currently displayed under the mouse. ++ */ ++ @javax.annotation.Nullable ++ public Slot getSlotUnderMouse() { return this.hoveredSlot; } ++ public int getGuiLeft() { return guiLeft; } ++ public int getGuiTop() { return guiTop; } ++ public int getXSize() { return xSize; } ++ public int getYSize() { return ySize; } ++ ++ /* ======================================== FORGE END =====================================*/ + } diff --git a/module/minecraft/patches/net/minecraft/client/gui/inventory/GuiContainerCreative.java.patch b/module/minecraft/patches/net/minecraft/client/gui/inventory/GuiContainerCreative.java.patch new file mode 100644 index 000000000..053406300 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/inventory/GuiContainerCreative.java.patch @@ -0,0 +1,296 @@ +--- original/net/minecraft/client/gui/inventory/GuiContainerCreative.java ++++ modified/net/minecraft/client/gui/inventory/GuiContainerCreative.java +@@ -61,6 +61,8 @@ + private Slot destroyItemSlot; + private boolean clearSearch; + private CreativeCrafting listener; ++ private static int tabPage = 0; ++ private int maxPages = 0; + + public GuiContainerCreative(EntityPlayer player) { + super(new GuiContainerCreative.ContainerCreative(player)); +@@ -250,6 +252,12 @@ + this.setCurrentCreativeTab(CreativeTabs.CREATIVE_TAB_ARRAY[i]); + this.listener = new CreativeCrafting(this.mc); + this.mc.player.inventoryContainer.addListener(this.listener); ++ int tabCount = CreativeTabs.CREATIVE_TAB_ARRAY.length; ++ if (tabCount > 12) { ++ buttonList.add(new GuiButton(101, guiLeft, guiTop - 50, 20, 20, "<")); ++ buttonList.add(new GuiButton(102, guiLeft + xSize - 20, guiTop - 50, 20, 20, ">")); ++ maxPages = (int) Math.ceil((tabCount - 12) / 10D); ++ } + } else { + this.mc.displayGuiScreen(new GuiInventory(this.mc.player)); + } +@@ -269,7 +277,7 @@ + /** Fired when a key is typed (except F11 which toggles full screen). This is the equivalent of KeyListener.keyTyped(KeyEvent e). Args : character (character on the key), keyCode (lwjgl Keyboard key code) */ + @Override + protected void keyTyped(char typedChar, int keyCode) throws IOException { +- if (selectedTabIndex != CreativeTabs.SEARCH.getIndex()) { ++ if (!CreativeTabs.CREATIVE_TAB_ARRAY[selectedTabIndex].hasSearchBar()) { + if (GameSettings.isKeyDown(this.mc.gameSettings.keyBindChat)) { + this.setCurrentCreativeTab(CreativeTabs.SEARCH); + } else { +@@ -294,6 +302,32 @@ + private void updateCreativeSearch() { + GuiContainerCreative.ContainerCreative guicontainercreative$containercreative = (GuiContainerCreative.ContainerCreative)this.inventorySlots; + guicontainercreative$containercreative.itemList.clear(); ++ ++ CreativeTabs tab = CreativeTabs.CREATIVE_TAB_ARRAY[selectedTabIndex]; ++ if (tab.hasSearchBar() && tab != CreativeTabs.SEARCH) { ++ tab.displayAllRelevantItems(guicontainercreative$containercreative.itemList); ++ if (!this.searchField.getText().isEmpty()) { ++ //TODO: Make this a SearchTree not a manual search ++ String search = this.searchField.getText().toLowerCase(Locale.ROOT); ++ java.util.Iterator itr = guicontainercreative$containercreative.itemList.iterator(); ++ while (itr.hasNext()) { ++ ItemStack stack = itr.next(); ++ boolean matches = false; ++ for (String line : stack.getTooltip(this.mc.player, this.mc.gameSettings.advancedItemTooltips ? ITooltipFlag.TooltipFlags.ADVANCED : ITooltipFlag.TooltipFlags.NORMAL)) { ++ if (TextFormatting.getTextWithoutFormattingCodes(line).toLowerCase(Locale.ROOT).contains(search)) { ++ matches = true; ++ break; ++ } ++ } ++ if (!matches) ++ itr.remove(); ++ } ++ } ++ this.currentScroll = 0.0F; ++ guicontainercreative$containercreative.scrollTo(0.0F); ++ return; ++ } ++ + if (this.searchField.getText().isEmpty()) { + for (Item item : Item.REGISTRY) { + item.getSubItems(CreativeTabs.SEARCH, guicontainercreative$containercreative.itemList); +@@ -315,9 +349,10 @@ + @Override + protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { + CreativeTabs creativetabs = CreativeTabs.CREATIVE_TAB_ARRAY[selectedTabIndex]; +- if (creativetabs.drawInForegroundOfTab()) { ++ ++ if (creativetabs != null && creativetabs.drawInForegroundOfTab()) { + GlStateManager.disableBlend(); +- this.fontRenderer.drawString(I18n.format(creativetabs.getTranslationKey()), 8, 6, 4210752); ++ this.fontRenderer.drawString(I18n.format(creativetabs.getTranslationKey()), 8, 6, creativetabs.getLabelColor()); + } + } + +@@ -346,7 +381,7 @@ + int j = mouseY - this.guiTop; + + for (CreativeTabs creativetabs : CreativeTabs.CREATIVE_TAB_ARRAY) { +- if (this.isMouseOverTab(creativetabs, i, j)) { ++ if (creativetabs != null && this.isMouseOverTab(creativetabs, i, j)) { + this.setCurrentCreativeTab(creativetabs); + return; + } +@@ -358,6 +393,7 @@ + + /** returns (if you are not on the inventoryTab) and (the flag isn't set) and (you have more than 1 page of items) */ + private boolean needsScrollBars() { ++ if (CreativeTabs.CREATIVE_TAB_ARRAY[selectedTabIndex] == null) return false; + return selectedTabIndex != CreativeTabs.INVENTORY.getIndex() + && CreativeTabs.CREATIVE_TAB_ARRAY[selectedTabIndex].hasScrollbar() + && ((GuiContainerCreative.ContainerCreative)this.inventorySlots).canScroll(); +@@ -365,6 +401,7 @@ + + /** Sets the current creative tab, restructuring the GUI as needed. */ + private void setCurrentCreativeTab(CreativeTabs tab) { ++ if (tab == null) return; + int i = selectedTabIndex; + selectedTabIndex = tab.getIndex(); + GuiContainerCreative.ContainerCreative guicontainercreative$containercreative = (GuiContainerCreative.ContainerCreative)this.inventorySlots; +@@ -438,11 +475,13 @@ + } + + if (this.searchField != null) { +- if (tab == CreativeTabs.SEARCH) { ++ if (tab.hasSearchBar()) { + this.searchField.setVisible(true); + this.searchField.setCanLoseFocus(false); + this.searchField.setFocused(true); + this.searchField.setText(""); ++ this.searchField.width = tab.getSearchbarWidth(); ++ this.searchField.x = this.guiLeft + (82 /*default left*/ + 89 /*default width*/) - this.searchField.width; + this.updateCreativeSearch(); + } else { + this.searchField.setVisible(false); +@@ -504,18 +543,40 @@ + + super.drawScreen(mouseX, mouseY, partialTicks); + +- for (CreativeTabs creativetabs : CreativeTabs.CREATIVE_TAB_ARRAY) { ++ int start = tabPage * 10; ++ int end = Math.min(CreativeTabs.CREATIVE_TAB_ARRAY.length, ((tabPage + 1) * 10) + 2); ++ if (tabPage != 0) start += 2; ++ boolean rendered = false; ++ ++ for (CreativeTabs creativetabs : java.util.Arrays.copyOfRange(CreativeTabs.CREATIVE_TAB_ARRAY,start,end)) { ++ if (creativetabs == null) continue; + if (this.renderCreativeInventoryHoveringText(creativetabs, mouseX, mouseY)) { ++ rendered = true; + break; + } + } + ++ if (!rendered && !renderCreativeInventoryHoveringText(CreativeTabs.SEARCH, mouseX, mouseY)) { ++ renderCreativeInventoryHoveringText(CreativeTabs.INVENTORY, mouseX, mouseY); ++ } ++ + if (this.destroyItemSlot != null + && selectedTabIndex == CreativeTabs.INVENTORY.getIndex() + && this.isPointInRegion(this.destroyItemSlot.xPos, this.destroyItemSlot.yPos, 16, 16, mouseX, mouseY)) { + this.drawHoveringText(I18n.format("inventory.binSlot"), mouseX, mouseY); + } + ++ if (maxPages != 0) { ++ String page = String.format("%d / %d", tabPage + 1, maxPages + 1); ++ int width = fontRenderer.getStringWidth(page); ++ GlStateManager.disableLighting(); ++ this.zLevel = 300.0F; ++ itemRender.zLevel = 300.0F; ++ fontRenderer.drawString(page, guiLeft + (xSize / 2) - (width / 2), guiTop - 44, -1); ++ this.zLevel = 0.0F; ++ itemRender.zLevel = 0.0F; ++ } ++ + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + GlStateManager.disableLighting(); + this.renderHoveredToolTip(mouseX, mouseY); +@@ -549,13 +610,16 @@ + + for (int i = 0; i < list.size(); i++) { + if (i == 0) { +- list.set(i, stack.getRarity().color + list.get(i)); ++ list.set(i, stack.getItem().getForgeRarity(stack).getColor() + list.get(i)); + } else { + list.set(i, TextFormatting.GRAY + list.get(i)); + } + } + +- this.drawHoveringText(list, x, y); ++ net.minecraft.client.gui.FontRenderer font = stack.getItem().getFontRenderer(stack); ++ net.minecraftforge.fml.client.config.GuiUtils.preItemToolTip(stack); ++ this.drawHoveringText(list, x, y, (font == null ? fontRenderer : font)); ++ net.minecraftforge.fml.client.config.GuiUtils.postItemToolTip(); + } else { + super.renderToolTip(stack, x, y); + } +@@ -568,14 +632,31 @@ + RenderHelper.enableGUIStandardItemLighting(); + CreativeTabs creativetabs = CreativeTabs.CREATIVE_TAB_ARRAY[selectedTabIndex]; + +- for (CreativeTabs creativetabs1 : CreativeTabs.CREATIVE_TAB_ARRAY) { ++ int start = tabPage * 10; ++ int end = Math.min(CreativeTabs.CREATIVE_TAB_ARRAY.length, ((tabPage + 1) * 10 + 2)); ++ if (tabPage != 0) start += 2; ++ ++ for (CreativeTabs creativetabs1 : java.util.Arrays.copyOfRange(CreativeTabs.CREATIVE_TAB_ARRAY,start,end)) { + this.mc.getTextureManager().bindTexture(CREATIVE_INVENTORY_TABS); ++ ++ if (creativetabs1 == null) continue; + if (creativetabs1.getIndex() != selectedTabIndex) { + this.drawTab(creativetabs1); + } + } + +- this.mc.getTextureManager().bindTexture(new ResourceLocation("textures/gui/container/creative_inventory/tab_" + creativetabs.getBackgroundImageName())); ++ if (tabPage != 0) { ++ if (creativetabs != CreativeTabs.SEARCH) { ++ this.mc.getTextureManager().bindTexture(CREATIVE_INVENTORY_TABS); ++ drawTab(CreativeTabs.SEARCH); ++ } ++ if (creativetabs != CreativeTabs.INVENTORY) { ++ this.mc.getTextureManager().bindTexture(CREATIVE_INVENTORY_TABS); ++ drawTab(CreativeTabs.INVENTORY); ++ } ++ } ++ ++ this.mc.getTextureManager().bindTexture(creativetabs.getBackgroundImage()); + this.drawTexturedModalRect(this.guiLeft, this.guiTop, 0, 0, this.xSize, this.ySize); + this.searchField.drawTextBox(); + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); +@@ -587,6 +668,12 @@ + this.drawTexturedModalRect(i, j + (int)((k - j - 17) * this.currentScroll), 232 + (this.needsScrollBars() ? 0 : 12), 0, 12, 15); + } + ++ if (creativetabs == null || creativetabs.getTabPage() != tabPage) { ++ if (creativetabs != CreativeTabs.SEARCH && creativetabs != CreativeTabs.INVENTORY) { ++ return; ++ } ++ } ++ + this.drawTab(creativetabs); + if (creativetabs == CreativeTabs.INVENTORY) { + GuiInventory.drawEntityOnScreen( +@@ -602,6 +689,12 @@ + + /** Checks if the mouse is over the given tab. Returns true if so. */ + protected boolean isMouseOverTab(CreativeTabs tab, int mouseX, int mouseY) { ++ if (tab.getTabPage() != tabPage) { ++ if (tab != CreativeTabs.SEARCH && tab != CreativeTabs.INVENTORY) { ++ return false; ++ } ++ } ++ + int i = tab.getColumn(); + int j = 28 * i; + int k = 0; +@@ -673,6 +766,8 @@ + } + + GlStateManager.disableLighting(); ++ GlStateManager.color(1F, 1F, 1F); //Forge: Reset color in case Items change it. ++ GlStateManager.enableBlend(); //Forge: Make sure blend is enabled else tabs show a white border. + this.drawTexturedModalRect(l, i1, j, k, 28, 32); + this.zLevel = 100.0F; + this.itemRender.zLevel = 100.0F; +@@ -694,6 +789,12 @@ + if (button.id == 1) { + this.mc.displayGuiScreen(new GuiStats(this, this.mc.player.getStatFileWriter())); + } ++ ++ if (button.id == 101) { ++ tabPage = Math.max(tabPage - 1, 0); ++ } else if (button.id == 102) { ++ tabPage = Math.min(tabPage + 1, maxPages); ++ } + } + + /** Returns the index of the currently selected tab. */ +@@ -887,6 +988,33 @@ + public boolean canTakeStack(EntityPlayer playerIn) { + return this.slot.canTakeStack(playerIn); + } ++ ++ /*========================================= FORGE START =====================================*/ ++ public net.minecraft.util.ResourceLocation getBackgroundLocation() { ++ return this.slot.getBackgroundLocation(); ++ } ++ ++ public void setBackgroundLocation(net.minecraft.util.ResourceLocation texture) { ++ this.slot.setBackgroundLocation(texture); ++ } ++ ++ public void setBackgroundName(@Nullable String name) { ++ this.slot.setBackgroundName(name); ++ } ++ ++ @Nullable ++ public net.minecraft.client.renderer.texture.TextureAtlasSprite getBackgroundSprite() { ++ return this.slot.getBackgroundSprite(); ++ } ++ ++ public int getSlotIndex() { ++ return this.slot.getSlotIndex(); ++ } ++ ++ public boolean isSameInventory(Slot other) { ++ return this.slot.isSameInventory(other); ++ } ++ /*========================================= FORGE END =====================================*/ + } + + @SideOnly(Side.CLIENT) diff --git a/module/minecraft/patches/net/minecraft/client/gui/recipebook/GuiRecipeBook.java.patch b/module/minecraft/patches/net/minecraft/client/gui/recipebook/GuiRecipeBook.java.patch new file mode 100644 index 000000000..9bdd4d309 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/recipebook/GuiRecipeBook.java.patch @@ -0,0 +1,30 @@ +--- original/net/minecraft/client/gui/recipebook/GuiRecipeBook.java ++++ modified/net/minecraft/client/gui/recipebook/GuiRecipeBook.java +@@ -380,7 +380,7 @@ + + languagemanager.setCurrentLanguage(language); + this.mc.gameSettings.language = language.getLanguageCode(); +- this.mc.refreshResources(); ++ net.minecraftforge.fml.client.FMLClientHandler.instance().refreshResources(net.minecraftforge.client.resource.VanillaResourceType.LANGUAGES); + this.mc + .fontRenderer + .setUnicodeFlag(this.mc.getLanguageManager().isCurrentLocaleUnicode() || this.mc.gameSettings.forceUnicodeFont); +@@ -413,7 +413,7 @@ + this.ghostRecipe.addIngredient(Ingredient.fromStacks(itemstack), p_193951_2_.get(0).xPos, p_193951_2_.get(0).yPos); + int i = this.craftingSlots.getWidth(); + int j = this.craftingSlots.getHeight(); +- int k = p_193951_1_ instanceof ShapedRecipes ? ((ShapedRecipes)p_193951_1_).getWidth() : i; ++ int k = p_193951_1_ instanceof net.minecraftforge.common.crafting.IShapedRecipe ? ((net.minecraftforge.common.crafting.IShapedRecipe)p_193951_1_).getRecipeWidth() : i; + int l = 1; + Iterator iterator = p_193951_1_.getIngredients().iterator(); + +@@ -424,7 +424,8 @@ + } + + Ingredient ingredient = iterator.next(); +- if (ingredient != Ingredient.EMPTY) { ++ ++ if (ingredient.getMatchingStacks().length > 0) { + Slot slot = p_193951_2_.get(l); + this.ghostRecipe.addIngredient(ingredient, slot.xPos, slot.yPos); + } diff --git a/module/minecraft/patches/net/minecraft/client/gui/recipebook/GuiRecipeOverlay.java.patch b/module/minecraft/patches/net/minecraft/client/gui/recipebook/GuiRecipeOverlay.java.patch new file mode 100644 index 000000000..1d896a1af --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/recipebook/GuiRecipeOverlay.java.patch @@ -0,0 +1,18 @@ +--- original/net/minecraft/client/gui/recipebook/GuiRecipeOverlay.java ++++ modified/net/minecraft/client/gui/recipebook/GuiRecipeOverlay.java +@@ -313,10 +313,11 @@ + this.drawTexturedModalRect(this.x, this.y, i, j, this.width, this.height); + int k = 3; + int l = 3; +- if (this.recipe instanceof ShapedRecipes) { +- ShapedRecipes shapedrecipes = (ShapedRecipes)this.recipe; +- k = shapedrecipes.getWidth(); +- l = shapedrecipes.getHeight(); ++ ++ if (this.recipe instanceof net.minecraftforge.common.crafting.IShapedRecipe) { ++ net.minecraftforge.common.crafting.IShapedRecipe shapedrecipes = (net.minecraftforge.common.crafting.IShapedRecipe)this.recipe; ++ k = shapedrecipes.getRecipeWidth(); ++ l = shapedrecipes.getRecipeHeight(); + } + + Iterator iterator = this.recipe.getIngredients().iterator(); diff --git a/module/minecraft/patches/net/minecraft/client/gui/toasts/RecipeToast.java.patch b/module/minecraft/patches/net/minecraft/client/gui/toasts/RecipeToast.java.patch new file mode 100644 index 000000000..ffb193ddc --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/toasts/RecipeToast.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/client/gui/toasts/RecipeToast.java ++++ modified/net/minecraft/client/gui/toasts/RecipeToast.java +@@ -39,7 +39,7 @@ + RenderHelper.enableGUIStandardItemLighting(); + toastGui.getMinecraft() + .getRenderItem() +- .renderItemAndEffectIntoGUI(null, this.recipesOutputs.get((int)(delta / (5000L / this.recipesOutputs.size()) % this.recipesOutputs.size())), 8, 8); ++ .renderItemAndEffectIntoGUI(null, this.recipesOutputs.get((int)(delta * this.recipesOutputs.size() / 5000L % this.recipesOutputs.size())), 8, 8); //Forge: fix math so that it doesn't divide by 0 when there are more than 5000 recipes + return delta - this.firstDrawTime >= 5000L ? IToast.Visibility.HIDE : IToast.Visibility.SHOW; + } + diff --git a/module/minecraft/patches/net/minecraft/client/model/ModelBase.java.patch b/module/minecraft/patches/net/minecraft/client/model/ModelBase.java.patch new file mode 100644 index 000000000..27bdf435a --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/model/ModelBase.java.patch @@ -0,0 +1,10 @@ +--- original/net/minecraft/client/model/ModelBase.java ++++ modified/net/minecraft/client/model/ModelBase.java +@@ -10,7 +10,6 @@ + import net.minecraftforge.fml.relauncher.Side; + import net.minecraftforge.fml.relauncher.SideOnly; + +-@SideOnly(Side.CLIENT) + public abstract class ModelBase { + public float swingProgress; + public boolean isRiding; diff --git a/module/minecraft/patches/net/minecraft/client/model/ModelBox.java.patch b/module/minecraft/patches/net/minecraft/client/model/ModelBox.java.patch new file mode 100644 index 000000000..d907d2c21 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/model/ModelBox.java.patch @@ -0,0 +1,18 @@ +--- original/net/minecraft/client/model/ModelBox.java ++++ modified/net/minecraft/client/model/ModelBox.java +@@ -4,7 +4,6 @@ + import net.minecraftforge.fml.relauncher.Side; + import net.minecraftforge.fml.relauncher.SideOnly; + +-@SideOnly(Side.CLIENT) + public class ModelBox { + /** The (x,y,z) vertex positions and (u,v) texture coordinates for each of the 8 points on a cube */ + private final PositionTextureVertex[] vertexPositions; +@@ -164,6 +163,7 @@ + } + } + ++ @SideOnly(Side.CLIENT) + public void render(BufferBuilder renderer, float scale) { + for (TexturedQuad texturedquad : this.quadList) { + texturedquad.draw(renderer, scale); diff --git a/module/minecraft/patches/net/minecraft/client/model/ModelRenderer.java.patch b/module/minecraft/patches/net/minecraft/client/model/ModelRenderer.java.patch new file mode 100644 index 000000000..666e7c01e --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/model/ModelRenderer.java.patch @@ -0,0 +1,44 @@ +--- original/net/minecraft/client/model/ModelRenderer.java ++++ modified/net/minecraft/client/model/ModelRenderer.java +@@ -9,7 +9,6 @@ + import net.minecraftforge.fml.relauncher.Side; + import net.minecraftforge.fml.relauncher.SideOnly; + +-@SideOnly(Side.CLIENT) + public class ModelRenderer { + /** The size of the texture file's width in pixels. */ + public float textureWidth = 64.0F; +@@ -123,6 +122,7 @@ + this.rotationPointZ = rotationPointZIn; + } + ++ @SideOnly(Side.CLIENT) + public void render(float scale) { + if (!this.isHidden) { + if (this.showModel) { +@@ -178,6 +178,7 @@ + } + } + ++ @SideOnly(Side.CLIENT) + public void renderWithRotation(float scale) { + if (!this.isHidden) { + if (this.showModel) { +@@ -205,7 +206,7 @@ + } + } + +- /** Allows the changing of Angles after a box has been rendered */ ++ @SideOnly(Side.CLIENT) + public void postRender(float scale) { + if (!this.isHidden) { + if (this.showModel) { +@@ -233,7 +234,7 @@ + } + } + +- /** Compiles a GL display list for this model */ ++ @SideOnly(Side.CLIENT) + private void compileDisplayList(float scale) { + this.displayList = GLAllocation.generateDisplayLists(1); + GlStateManager.glNewList(this.displayList, 4864); diff --git a/module/minecraft/patches/net/minecraft/client/model/ModelSkeleton.java.patch b/module/minecraft/patches/net/minecraft/client/model/ModelSkeleton.java.patch new file mode 100644 index 000000000..905dab4c5 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/model/ModelSkeleton.java.patch @@ -0,0 +1,22 @@ +--- original/net/minecraft/client/model/ModelSkeleton.java ++++ modified/net/minecraft/client/model/ModelSkeleton.java +@@ -43,7 +43,8 @@ + this.rightArmPose = ModelBiped.ArmPose.EMPTY; + this.leftArmPose = ModelBiped.ArmPose.EMPTY; + ItemStack itemstack = entitylivingbaseIn.getHeldItem(EnumHand.MAIN_HAND); +- if (itemstack.getItem() == Items.BOW && ((AbstractSkeleton)entitylivingbaseIn).isSwingingArms()) { ++ ++ if (itemstack.getItem() instanceof net.minecraft.item.ItemBow && ((AbstractSkeleton)entitylivingbaseIn).isSwingingArms()) { + if (entitylivingbaseIn.getPrimaryHand() == EnumHandSide.RIGHT) { + this.rightArmPose = ModelBiped.ArmPose.BOW_AND_ARROW; + } else { +@@ -60,7 +61,8 @@ + super.setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scaleFactor, entityIn); + ItemStack itemstack = ((EntityLivingBase)entityIn).getHeldItemMainhand(); + AbstractSkeleton abstractskeleton = (AbstractSkeleton)entityIn; +- if (abstractskeleton.isSwingingArms() && (itemstack.isEmpty() || itemstack.getItem() != Items.BOW)) { ++ ++ if (abstractskeleton.isSwingingArms() && (itemstack.isEmpty() || !(itemstack.getItem() instanceof net.minecraft.item.ItemBow))) { + float f = MathHelper.sin(this.swingProgress * (float) Math.PI); + float f1 = MathHelper.sin((1.0F - (1.0F - this.swingProgress) * (1.0F - this.swingProgress)) * (float) Math.PI); + this.bipedRightArm.rotateAngleZ = 0.0F; diff --git a/module/minecraft/patches/net/minecraft/client/model/PositionTextureVertex.java.patch b/module/minecraft/patches/net/minecraft/client/model/PositionTextureVertex.java.patch new file mode 100644 index 000000000..f478b97d0 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/model/PositionTextureVertex.java.patch @@ -0,0 +1,13 @@ +--- original/net/minecraft/client/model/PositionTextureVertex.java ++++ modified/net/minecraft/client/model/PositionTextureVertex.java +@@ -1,10 +1,7 @@ + package net.minecraft.client.model; + + import net.minecraft.util.math.Vec3d; +-import net.minecraftforge.fml.relauncher.Side; +-import net.minecraftforge.fml.relauncher.SideOnly; + +-@SideOnly(Side.CLIENT) + public class PositionTextureVertex { + public Vec3d vector3D; + public float texturePositionX; diff --git a/module/minecraft/patches/net/minecraft/client/model/TexturedQuad.java.patch b/module/minecraft/patches/net/minecraft/client/model/TexturedQuad.java.patch new file mode 100644 index 000000000..52ba370d3 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/model/TexturedQuad.java.patch @@ -0,0 +1,19 @@ +--- original/net/minecraft/client/model/TexturedQuad.java ++++ modified/net/minecraft/client/model/TexturedQuad.java +@@ -7,7 +7,6 @@ + import net.minecraftforge.fml.relauncher.Side; + import net.minecraftforge.fml.relauncher.SideOnly; + +-@SideOnly(Side.CLIENT) + public class TexturedQuad { + public PositionTextureVertex[] vertexPositions; + public int nVertices; +@@ -38,7 +37,7 @@ + this.vertexPositions = apositiontexturevertex; + } + +- /** Draw this primitve. This is typically called only once as the generated drawing instructions are saved by the renderer and reused later. */ ++ @SideOnly(Side.CLIENT) + public void draw(BufferBuilder renderer, float scale) { + Vec3d vec3d = this.vertexPositions[1].vector3D.subtractReverse(this.vertexPositions[0].vector3D); + Vec3d vec3d1 = this.vertexPositions[1].vector3D.subtractReverse(this.vertexPositions[2].vector3D); diff --git a/module/minecraft/patches/net/minecraft/client/multiplayer/ChunkProviderClient.java.patch b/module/minecraft/patches/net/minecraft/client/multiplayer/ChunkProviderClient.java.patch new file mode 100644 index 000000000..6ac64961c --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/multiplayer/ChunkProviderClient.java.patch @@ -0,0 +1,34 @@ +--- original/net/minecraft/client/multiplayer/ChunkProviderClient.java ++++ modified/net/minecraft/client/multiplayer/ChunkProviderClient.java +@@ -31,6 +31,9 @@ + /** Reference to the World object. */ + private final World world; + ++ private java.util.function.BiConsumer loadChunkCallback = null; ++ private java.util.function.BiConsumer unloadChunkCallback = null; ++ + public ChunkProviderClient(World worldIn) { + this.blankChunk = new EmptyChunk(worldIn, 0, 0); + this.world = worldIn; +@@ -44,6 +47,9 @@ + } + + this.loadedChunks.remove(ChunkPos.asLong(x, z)); ++ if (unloadChunkCallback != null) { ++ unloadChunkCallback.accept(x, z); ++ } + } + + @Nullable +@@ -56,7 +62,11 @@ + public Chunk loadChunk(int chunkX, int chunkZ) { + Chunk chunk = new Chunk(this.world, chunkX, chunkZ); + this.loadedChunks.put(ChunkPos.asLong(chunkX, chunkZ), chunk); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.ChunkEvent.Load(chunk)); + chunk.markLoaded(true); ++ if (loadChunkCallback != null) { ++ loadChunkCallback.accept(chunkX, chunkZ); ++ } + return chunk; + } + diff --git a/module/minecraft/patches/net/minecraft/client/multiplayer/GuiConnecting.java.patch b/module/minecraft/patches/net/minecraft/client/multiplayer/GuiConnecting.java.patch new file mode 100644 index 000000000..a0b541c7a --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/multiplayer/GuiConnecting.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/client/multiplayer/GuiConnecting.java ++++ modified/net/minecraft/client/multiplayer/GuiConnecting.java +@@ -67,7 +67,7 @@ + GuiConnecting.this.networkManager, GuiConnecting.this.mc, GuiConnecting.this.previousGuiScreen + ) + ); +- GuiConnecting.this.networkManager.sendPacket(new C00Handshake(ip, port, EnumConnectionState.LOGIN)); ++ GuiConnecting.this.networkManager.sendPacket(new C00Handshake(ip, port, EnumConnectionState.LOGIN, true)); + GuiConnecting.this.networkManager + .sendPacket(new CPacketLoginStart(GuiConnecting.this.mc.getSession().getProfile())); + } catch (UnknownHostException unknownhostexception) { diff --git a/module/minecraft/patches/net/minecraft/client/multiplayer/PlayerControllerMP.java.patch b/module/minecraft/patches/net/minecraft/client/multiplayer/PlayerControllerMP.java.patch new file mode 100644 index 000000000..16ff02b23 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/multiplayer/PlayerControllerMP.java.patch @@ -0,0 +1,332 @@ +--- original/net/minecraft/client/multiplayer/PlayerControllerMP.java ++++ modified/net/minecraft/client/multiplayer/PlayerControllerMP.java +@@ -112,6 +112,7 @@ + + if (!this.mc.player.isAllowEdit()) { + ItemStack itemstack = this.mc.player.getHeldItemMainhand(); ++ + if (itemstack.isEmpty()) { + return false; + } +@@ -122,42 +123,49 @@ + } + } + +- if (this.currentGameType.isCreative() +- && !this.mc.player.getHeldItemMainhand().isEmpty() +- && this.mc.player.getHeldItemMainhand().getItem() instanceof ItemSword) { ++ ItemStack stack = mc.player.getHeldItemMainhand(); ++ if (!stack.isEmpty() && stack.getItem().onBlockStartBreak(stack, pos, mc.player)) { + return false; + } + +- World world = this.mc.world; +- IBlockState iblockstate = world.getBlockState(pos); +- Block block = iblockstate.getBlock(); +- if ((block instanceof BlockCommandBlock || block instanceof BlockStructure) && !this.mc.player.canUseCommandBlock()) { ++ if (this.currentGameType.isCreative() && !stack.isEmpty() && !stack.getItem().canDestroyBlockInCreative(mc.world, pos, stack, mc.player)) { + return false; +- } ++ } else { ++ World world = this.mc.world; ++ IBlockState iblockstate = world.getBlockState(pos); ++ Block block = iblockstate.getBlock(); + +- if (iblockstate.getMaterial() == Material.AIR) { +- return false; +- } ++ if ((block instanceof BlockCommandBlock || block instanceof BlockStructure) && !this.mc.player.canUseCommandBlock()) { ++ return false; ++ } else if (iblockstate.getMaterial() == Material.AIR) { ++ return false; ++ } else { ++ world.playEvent(2001, pos, Block.getStateId(iblockstate)); + +- world.playEvent(2001, pos, Block.getStateId(iblockstate)); +- block.onBlockHarvested(world, pos, iblockstate, this.mc.player); +- boolean flag = world.setBlockState(pos, Blocks.AIR.getDefaultState(), 11); +- if (flag) { +- block.onPlayerDestroy(world, pos, iblockstate); +- } ++ this.currentBlock = new BlockPos(this.currentBlock.getX(), -1, this.currentBlock.getZ()); + +- this.currentBlock = new BlockPos(this.currentBlock.getX(), -1, this.currentBlock.getZ()); +- if (!this.currentGameType.isCreative()) { +- ItemStack itemstack1 = this.mc.player.getHeldItemMainhand(); +- if (!itemstack1.isEmpty()) { +- itemstack1.onBlockDestroyed(world, iblockstate, pos, this.mc.player); +- if (itemstack1.isEmpty()) { +- this.mc.player.setHeldItem(EnumHand.MAIN_HAND, ItemStack.EMPTY); ++ if (!this.currentGameType.isCreative()) { ++ ItemStack itemstack1 = this.mc.player.getHeldItemMainhand(); ++ ItemStack copyBeforeUse = itemstack1.copy(); ++ ++ if (!itemstack1.isEmpty()) { ++ itemstack1.onBlockDestroyed(world, iblockstate, pos, this.mc.player); ++ ++ if (itemstack1.isEmpty()) { ++ net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(this.mc.player, copyBeforeUse, EnumHand.MAIN_HAND); ++ this.mc.player.setHeldItem(EnumHand.MAIN_HAND, ItemStack.EMPTY); ++ } ++ } + } ++ ++ boolean flag = block.removedByPlayer(iblockstate, world, pos, mc.player, false); ++ ++ if (flag) { ++ block.onPlayerDestroy(world, pos, iblockstate); ++ } ++ return flag; + } + } +- +- return flag; + } + + /** Called when the player is hitting a block with an item. */ +@@ -188,30 +196,34 @@ + .getTutorial() + .onHitBlock(this.mc.world, loc, this.mc.world.getBlockState(loc), 1.0F); + this.connection.sendPacket(new CPacketPlayerDigging(CPacketPlayerDigging.Action.START_DESTROY_BLOCK, loc, face)); ++ if (!net.minecraftforge.common.ForgeHooks.onLeftClickBlock(this.mc.player, loc, face, net.minecraftforge.common.ForgeHooks.rayTraceEyeHitVec(this.mc.player, getBlockReachDistance() + 1)).isCanceled()) + clickBlockCreative(this.mc, this, loc, face); + this.blockHitDelay = 5; + } else if (!this.isHittingBlock || !this.isHittingPosition(loc)) { + if (this.isHittingBlock) { + this.connection.sendPacket(new CPacketPlayerDigging(CPacketPlayerDigging.Action.ABORT_DESTROY_BLOCK, this.currentBlock, face)); + } ++ net.minecraftforge.event.entity.player.PlayerInteractEvent.LeftClickBlock event = net.minecraftforge.common.ForgeHooks.onLeftClickBlock(this.mc.player, loc, face, net.minecraftforge.common.ForgeHooks.rayTraceEyeHitVec(this.mc.player, getBlockReachDistance() + 1)); + + IBlockState iblockstate = this.mc.world.getBlockState(loc); + this.mc.getTutorial().onHitBlock(this.mc.world, loc, iblockstate, 0.0F); + this.connection.sendPacket(new CPacketPlayerDigging(CPacketPlayerDigging.Action.START_DESTROY_BLOCK, loc, face)); + boolean flag = iblockstate.getMaterial() != Material.AIR; + if (flag && this.curBlockDamageMP == 0.0F) { ++ if (event.getUseBlock() != net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) + iblockstate.getBlock().onBlockClicked(this.mc.world, loc, this.mc.player); + } + +- if (flag && iblockstate.getPlayerRelativeBlockHardness(this.mc.player, this.mc.player.world, loc) >= 1.0F) { +- this.onPlayerDestroyBlock(loc); +- } else { +- this.isHittingBlock = true; +- this.currentBlock = loc; +- this.currentItemHittingBlock = this.mc.player.getHeldItemMainhand(); +- this.curBlockDamageMP = 0.0F; +- this.stepSoundTickCounter = 0.0F; +- this.mc ++ if (event.getUseItem() == net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) return true; ++ if (flag && iblockstate.getPlayerRelativeBlockHardness(this.mc.player, this.mc.player.world, loc) >= 1.0F) { ++ this.onPlayerDestroyBlock(loc); ++ } else { ++ this.isHittingBlock = true; ++ this.currentBlock = loc; ++ this.currentItemHittingBlock = this.mc.player.getHeldItemMainhand(); ++ this.curBlockDamageMP = 0.0F; ++ this.stepSoundTickCounter = 0.0F; ++ this.mc + .world + .sendBlockBreakProgress(this.mc.player.getEntityId(), this.currentBlock, (int)(this.curBlockDamageMP * 10.0F) - 1); + } +@@ -264,7 +276,7 @@ + this.curBlockDamageMP = this.curBlockDamageMP + + iblockstate.getPlayerRelativeBlockHardness(this.mc.player, this.mc.player.world, posBlock); + if (this.stepSoundTickCounter % 4.0F == 0.0F) { +- SoundType soundtype = block.getSoundType(); ++ SoundType soundtype = block.getSoundType(iblockstate, mc.world, posBlock, mc.player); + this.mc + .getSoundHandler() + .playSound( +@@ -302,7 +314,8 @@ + + /** player reach distance = 4F */ + public float getBlockReachDistance() { +- return this.currentGameType.isCreative() ? 5.0F : 4.5F; ++ float attrib = (float) mc.player.getEntityAttribute(EntityPlayer.REACH_DISTANCE).getAttributeValue(); ++ return this.currentGameType.isCreative() ? attrib : attrib - 0.5F; + } + + public void updateController() { +@@ -318,9 +331,7 @@ + ItemStack itemstack = this.mc.player.getHeldItemMainhand(); + boolean flag = this.currentItemHittingBlock.isEmpty() && itemstack.isEmpty(); + if (!this.currentItemHittingBlock.isEmpty() && !itemstack.isEmpty()) { +- flag = itemstack.getItem() == this.currentItemHittingBlock.getItem() +- && ItemStack.areItemStackTagsEqual(itemstack, this.currentItemHittingBlock) +- && (itemstack.isItemStackDamageable() || itemstack.getMetadata() == this.currentItemHittingBlock.getMetadata()); ++ flag = !net.minecraftforge.client.ForgeHooksClient.shouldCauseBlockBreakReset(this.currentItemHittingBlock, itemstack); + } + + return pos.equals(this.currentBlock) && flag; +@@ -344,77 +355,110 @@ + float f1 = (float)(vec.y - pos.getY()); + float f2 = (float)(vec.z - pos.getZ()); + boolean flag = false; ++ + if (!this.mc.world.getWorldBorder().contains(pos)) { + return EnumActionResult.FAIL; +- } +- +- if (this.currentGameType != GameType.SPECTATOR) { +- IBlockState iblockstate = worldIn.getBlockState(pos); +- if ((!player.isSneaking() || player.getHeldItemMainhand().isEmpty() && player.getHeldItemOffhand().isEmpty()) +- && iblockstate.getBlock().onBlockActivated(worldIn, pos, iblockstate, player, hand, direction, f, f1, f2)) { +- flag = true; ++ } else { ++ net.minecraftforge.event.entity.player.PlayerInteractEvent.RightClickBlock event = net.minecraftforge.common.ForgeHooks ++ .onRightClickBlock(player, hand, pos, direction, net.minecraftforge.common.ForgeHooks.rayTraceEyeHitVec(player, getBlockReachDistance() + 1)); ++ if (event.isCanceled()) { ++ // Give the server a chance to fire event as well. That way server event is not dependant on client event. ++ this.connection.sendPacket(new CPacketPlayerTryUseItemOnBlock(pos, direction, hand, f, f1, f2)); ++ return event.getCancellationResult(); + } ++ EnumActionResult result = EnumActionResult.PASS; + +- if (!flag && itemstack.getItem() instanceof ItemBlock) { +- ItemBlock itemblock = (ItemBlock)itemstack.getItem(); +- if (!itemblock.canPlaceBlockOnSide(worldIn, pos, direction, player, itemstack)) { +- return EnumActionResult.FAIL; ++ if (this.currentGameType != GameType.SPECTATOR) { ++ EnumActionResult ret = itemstack.onItemUseFirst(player, worldIn, pos, hand, direction, f, f1, f2); ++ if (ret != EnumActionResult.PASS) { ++ // The server needs to process the item use as well. Otherwise onItemUseFirst won't ever be called on the server without causing weird bugs ++ this.connection.sendPacket(new CPacketPlayerTryUseItemOnBlock(pos, direction, hand, f, f1, f2)); ++ return ret; + } ++ ++ IBlockState iblockstate = worldIn.getBlockState(pos); ++ boolean bypass = player.getHeldItemMainhand().doesSneakBypassUse(worldIn, pos, player) && player.getHeldItemOffhand().doesSneakBypassUse(worldIn, pos, player); ++ ++ if ((!player.isSneaking() || bypass || event.getUseBlock() == net.minecraftforge.fml.common.eventhandler.Event.Result.ALLOW)) { ++ if (event.getUseBlock() != net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) ++ flag = iblockstate.getBlock().onBlockActivated(worldIn, pos, iblockstate, player, hand, direction, f, f1, f2); ++ if (flag) result = EnumActionResult.SUCCESS; ++ } ++ ++ if (!flag && itemstack.getItem() instanceof ItemBlock) { ++ ItemBlock itemblock = (ItemBlock)itemstack.getItem(); ++ ++ if (!itemblock.canPlaceBlockOnSide(worldIn, pos, direction, player, itemstack)) { ++ return EnumActionResult.FAIL; ++ } ++ } + } +- } + +- this.connection.sendPacket(new CPacketPlayerTryUseItemOnBlock(pos, direction, hand, f, f1, f2)); +- if (flag || this.currentGameType == GameType.SPECTATOR) { +- return EnumActionResult.SUCCESS; +- } ++ this.connection.sendPacket(new CPacketPlayerTryUseItemOnBlock(pos, direction, hand, f, f1, f2)); + +- if (itemstack.isEmpty()) { +- return EnumActionResult.PASS; +- } ++ if ((flag || this.currentGameType == GameType.SPECTATOR) && event.getUseItem() != net.minecraftforge.fml.common.eventhandler.Event.Result.ALLOW) { ++ return EnumActionResult.SUCCESS; ++ } else if (itemstack.isEmpty()) { ++ return EnumActionResult.PASS; ++ } else if (player.getCooldownTracker().hasCooldown(itemstack.getItem())) { ++ return EnumActionResult.PASS; ++ } else { ++ if (itemstack.getItem() instanceof ItemBlock && !player.canUseCommandBlock()) { ++ Block block = ((ItemBlock)itemstack.getItem()).getBlock(); + +- if (player.getCooldownTracker().hasCooldown(itemstack.getItem())) { +- return EnumActionResult.PASS; +- } ++ if (block instanceof BlockCommandBlock || block instanceof BlockStructure) { ++ return EnumActionResult.FAIL; ++ } ++ } + +- if (itemstack.getItem() instanceof ItemBlock && !player.canUseCommandBlock()) { +- Block block = ((ItemBlock)itemstack.getItem()).getBlock(); +- if (block instanceof BlockCommandBlock || block instanceof BlockStructure) { +- return EnumActionResult.FAIL; ++ if (this.currentGameType.isCreative()) { ++ int i = itemstack.getMetadata(); ++ int j = itemstack.getCount(); ++ if (event.getUseItem() != net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) { ++ EnumActionResult enumactionresult = itemstack.onItemUse(player, worldIn, pos, hand, direction, f, f1, f2); ++ itemstack.setItemDamage(i); ++ itemstack.setCount(j); ++ return enumactionresult; ++ } else return result; ++ } else { ++ ItemStack copyForUse = itemstack.copy(); ++ if (event.getUseItem() != net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) ++ result = itemstack.onItemUse(player, worldIn, pos, hand, direction, f, f1, f2); ++ if (itemstack.isEmpty()) ++ net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(player, copyForUse, hand); ++ return result; ++ } + } + } +- +- if (this.currentGameType.isCreative()) { +- int i = itemstack.getMetadata(); +- int j = itemstack.getCount(); +- EnumActionResult enumactionresult = itemstack.onItemUse(player, worldIn, pos, hand, direction, f, f1, f2); +- itemstack.setItemDamage(i); +- itemstack.setCount(j); +- return enumactionresult; +- } else { +- return itemstack.onItemUse(player, worldIn, pos, hand, direction, f, f1, f2); +- } + } + + public EnumActionResult processRightClick(EntityPlayer player, World worldIn, EnumHand hand) { + if (this.currentGameType == GameType.SPECTATOR) { + return EnumActionResult.PASS; +- } ++ } else { ++ this.syncCurrentPlayItem(); ++ this.connection.sendPacket(new CPacketPlayerTryUseItem(hand)); ++ ItemStack itemstack = player.getHeldItem(hand); + +- this.syncCurrentPlayItem(); +- this.connection.sendPacket(new CPacketPlayerTryUseItem(hand)); +- ItemStack itemstack = player.getHeldItem(hand); +- if (player.getCooldownTracker().hasCooldown(itemstack.getItem())) { +- return EnumActionResult.PASS; +- } ++ if (player.getCooldownTracker().hasCooldown(itemstack.getItem())) { ++ return EnumActionResult.PASS; ++ } else { ++ EnumActionResult cancelResult = net.minecraftforge.common.ForgeHooks.onItemRightClick(player, hand); ++ if (cancelResult != null) return cancelResult; ++ int i = itemstack.getCount(); ++ ActionResult actionresult = itemstack.useItemRightClick(worldIn, player, hand); ++ ItemStack itemstack1 = actionresult.getResult(); + +- int i = itemstack.getCount(); +- ActionResult actionresult = itemstack.useItemRightClick(worldIn, player, hand); +- ItemStack itemstack1 = actionresult.getResult(); +- if (itemstack1 != itemstack || itemstack1.getCount() != i) { +- player.setHeldItem(hand, itemstack1); +- } ++ if (itemstack1 != itemstack || itemstack1.getCount() != i) { ++ player.setHeldItem(hand, itemstack1); ++ if (itemstack1.isEmpty()) { ++ net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(player, itemstack, hand); ++ } ++ } + +- return actionresult.getType(); ++ return actionresult.getType(); ++ } ++ } + } + + public EntityPlayerSP createPlayer(World p_192830_1_, StatisticsManager p_192830_2_, RecipeBook p_192830_3_) { +@@ -447,6 +491,9 @@ + ray.hitVec.z - target.posZ + ); + this.connection.sendPacket(new CPacketUseEntity(target, hand, vec3d)); ++ if (this.currentGameType == GameType.SPECTATOR) return EnumActionResult.PASS; // don't fire for spectators to match non-specific EntityInteract ++ EnumActionResult cancelResult = net.minecraftforge.common.ForgeHooks.onInteractEntityAt(player, target, ray, hand); ++ if(cancelResult != null) return cancelResult; + return this.currentGameType == GameType.SPECTATOR ? EnumActionResult.PASS : target.applyPlayerInteraction(player, vec3d, hand); + } + diff --git a/module/minecraft/patches/net/minecraft/client/multiplayer/WorldClient.java.patch b/module/minecraft/patches/net/minecraft/client/multiplayer/WorldClient.java.patch new file mode 100644 index 000000000..75c7a5ba6 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/multiplayer/WorldClient.java.patch @@ -0,0 +1,22 @@ +--- original/net/minecraft/client/multiplayer/WorldClient.java ++++ modified/net/minecraft/client/multiplayer/WorldClient.java +@@ -62,15 +62,17 @@ + protected Set visibleChunks = Sets.newHashSet(); + + public WorldClient(NetHandlerPlayClient netHandler, WorldSettings settings, int dimension, EnumDifficulty difficulty, Profiler profilerIn) { +- super(new SaveHandlerMP(), new WorldInfo(settings, "MpServer"), DimensionType.getById(dimension).createDimension(), profilerIn, true); ++ super(new SaveHandlerMP(), new WorldInfo(settings, "MpServer"), net.minecraftforge.common.DimensionManager.createProviderFor(dimension), profilerIn, true); + this.connection = netHandler; + this.getWorldInfo().setDifficulty(difficulty); +- this.setSpawnPoint(new BlockPos(8, 64, 8)); + this.provider.setWorld(this); ++ this.setSpawnPoint(new BlockPos(8, 64, 8)); //Forge: Moved below registerWorld to prevent NPE in our redirect. + this.chunkProvider = this.createChunkProvider(); + this.mapStorage = new SaveDataMemoryStorage(); + this.calculateInitialSkylight(); + this.calculateInitialWeather(); ++ this.initCapabilities(); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.WorldEvent.Load(this)); + } + + /** Runs a single tick for the world */ diff --git a/module/minecraft/patches/net/minecraft/client/network/NetHandlerHandshakeMemory.java.patch b/module/minecraft/patches/net/minecraft/client/network/NetHandlerHandshakeMemory.java.patch new file mode 100644 index 000000000..dfbdc90e1 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/network/NetHandlerHandshakeMemory.java.patch @@ -0,0 +1,10 @@ +--- original/net/minecraft/client/network/NetHandlerHandshakeMemory.java ++++ modified/net/minecraft/client/network/NetHandlerHandshakeMemory.java +@@ -22,6 +22,7 @@ + /** There are two recognized intentions for initiating a handshake: logging in and acquiring server status. The NetworkManager's protocol will be reconfigured according to the specified intention, although a login-intention must pass a versioncheck or receive a disconnect otherwise */ + @Override + public void processHandshake(C00Handshake packetIn) { ++ if (!net.minecraftforge.fml.common.FMLCommonHandler.instance().handleServerHandshake(packetIn, this.networkManager)) return; + this.networkManager.setConnectionState(packetIn.getRequestedState()); + this.networkManager.setNetHandler(new NetHandlerLoginServer(this.server, this.networkManager)); + } diff --git a/module/minecraft/patches/net/minecraft/client/network/NetHandlerLoginClient.java.patch b/module/minecraft/patches/net/minecraft/client/network/NetHandlerLoginClient.java.patch new file mode 100644 index 000000000..5f08bdcb3 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/network/NetHandlerLoginClient.java.patch @@ -0,0 +1,14 @@ +--- original/net/minecraft/client/network/NetHandlerLoginClient.java ++++ modified/net/minecraft/client/network/NetHandlerLoginClient.java +@@ -101,7 +101,10 @@ + public void handleLoginSuccess(SPacketLoginSuccess packetIn) { + this.gameProfile = packetIn.getProfile(); + this.networkManager.setConnectionState(EnumConnectionState.PLAY); +- this.networkManager.setNetHandler(new NetHandlerPlayClient(this.mc, this.previousGuiScreen, this.networkManager, this.gameProfile)); ++ NetHandlerPlayClient nhpc = new NetHandlerPlayClient(this.mc, this.previousGuiScreen, this.networkManager, this.gameProfile); ++ this.networkManager.setNetHandler(nhpc); ++ net.minecraftforge.fml.client.FMLClientHandler.instance().setPlayClient(nhpc); ++ net.minecraftforge.fml.common.network.internal.FMLNetworkHandler.fmlClientHandshake(this.networkManager); + } + + /** Invoked when disconnecting, the parameter is a ChatComponent describing the reason for termination */ diff --git a/module/minecraft/patches/net/minecraft/client/network/NetHandlerPlayClient.java.patch b/module/minecraft/patches/net/minecraft/client/network/NetHandlerPlayClient.java.patch new file mode 100644 index 000000000..09db982e2 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/network/NetHandlerPlayClient.java.patch @@ -0,0 +1,184 @@ +--- original/net/minecraft/client/network/NetHandlerPlayClient.java ++++ modified/net/minecraft/client/network/NetHandlerPlayClient.java +@@ -302,7 +302,7 @@ + this.world = new WorldClient( + this, + new WorldSettings(0L, packetIn.getGameType(), false, packetIn.isHardcoreMode(), packetIn.getWorldType()), +- packetIn.getDimension(), ++ net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.get(getNetworkManager()).getOverrideDimension(packetIn), + packetIn.getDifficulty(), + this.client.profiler + ); +@@ -735,15 +735,16 @@ + Chunk chunk = this.world.getChunk(packetIn.getChunkX(), packetIn.getChunkZ()); + chunk.read(packetIn.getReadBuffer(), packetIn.getExtractedSize(), packetIn.isFullChunk()); + this.world +- .markBlockRangeForRenderUpdate( +- packetIn.getChunkX() << 4, +- 0, +- packetIn.getChunkZ() << 4, +- (packetIn.getChunkX() << 4) + 15, +- 256, +- (packetIn.getChunkZ() << 4) + 15 +- ); +- if (!packetIn.isFullChunk() || !(this.world.provider instanceof WorldProviderSurface)) { ++ .markBlockRangeForRenderUpdate( ++ packetIn.getChunkX() << 4, ++ 0, ++ packetIn.getChunkZ() << 4, ++ (packetIn.getChunkX() << 4) + 15, ++ 256, ++ (packetIn.getChunkZ() << 4) + 15 ++ ); ++ ++ if (!packetIn.isFullChunk() || this.world.provider.shouldClientCheckLighting()) { + chunk.resetRelightChecks(); + } + +@@ -751,7 +752,7 @@ + BlockPos blockpos = new BlockPos(nbttagcompound.getInteger("x"), nbttagcompound.getInteger("y"), nbttagcompound.getInteger("z")); + TileEntity tileentity = this.world.getTileEntity(blockpos); + if (tileentity != null) { +- tileentity.readFromNBT(nbttagcompound); ++ tileentity.handleUpdateTag(nbttagcompound); + } + } + } +@@ -846,7 +847,9 @@ + @Override + public void handleChat(SPacketChat packetIn) { + PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client); +- this.client.ingameGUI.addChatMessage(packetIn.getType(), packetIn.getChatComponent()); ++ net.minecraft.util.text.ITextComponent message = net.minecraftforge.event.ForgeEventFactory.onClientChat(packetIn.getType(), packetIn.getChatComponent()); ++ if (message == null) return; ++ this.client.ingameGUI.addChatMessage(packetIn.getType(), message); + } + + /** Renders a specified animation: Waking up a player, a living entity swinging its currently held item, being hurt or receiving a critical hit by normal or magical means */ +@@ -951,10 +954,7 @@ + if (entity1 == this.client.player && !flag) { + this.client + .ingameGUI +- .setOverlayMessage( +- I18n.format("mount.onboard", GameSettings.getKeyDisplayString(this.client.gameSettings.keyBindSneak.getKeyCode())), +- false +- ); ++ .setOverlayMessage(I18n.format("mount.onboard", this.client.gameSettings.keyBindSneak.getDisplayName()), false); + } + } + } +@@ -1188,6 +1188,12 @@ + || i == 10 && tileentity instanceof TileEntityShulkerBox + || i == 11 && tileentity instanceof TileEntityBed) { + tileentity.readFromNBT(packetIn.getNbtCompound()); ++ } else { ++ if(tileentity == null) { ++ LOGGER.error("Received invalid update packet for null tile entity at {} with data: {}", packetIn.getPos(), packetIn.getNbtCompound()); ++ return; ++ } ++ tileentity.onDataPacket(netManager, packetIn); + } + + if (flag && this.client.currentScreen instanceof GuiCommandBlock) { +@@ -1279,27 +1285,27 @@ + this.client.displayGuiScreen(new GuiScreenDemo()); + } else if (f == 101.0F) { + this.client +- .ingameGUI +- .getChatGUI() +- .printChatMessage( +- new TextComponentTranslation( +- "demo.help.movement", +- GameSettings.getKeyDisplayString(gamesettings.keyBindForward.getKeyCode()), +- GameSettings.getKeyDisplayString(gamesettings.keyBindLeft.getKeyCode()), +- GameSettings.getKeyDisplayString(gamesettings.keyBindBack.getKeyCode()), +- GameSettings.getKeyDisplayString(gamesettings.keyBindRight.getKeyCode()) +- ) +- ); ++ .ingameGUI ++ .getChatGUI() ++ .printChatMessage( ++ new TextComponentTranslation( ++ "demo.help.movement", ++ gamesettings.keyBindForward.getDisplayName(), ++ gamesettings.keyBindLeft.getDisplayName(), ++ gamesettings.keyBindBack.getDisplayName(), ++ gamesettings.keyBindRight.getDisplayName() ++ ) ++ ); + } else if (f == 102.0F) { + this.client +- .ingameGUI +- .getChatGUI() +- .printChatMessage(new TextComponentTranslation("demo.help.jump", GameSettings.getKeyDisplayString(gamesettings.keyBindJump.getKeyCode()))); ++ .ingameGUI ++ .getChatGUI() ++ .printChatMessage(new TextComponentTranslation("demo.help.jump", gamesettings.keyBindJump.getDisplayName())); + } else if (f == 103.0F) { + this.client +- .ingameGUI +- .getChatGUI() +- .printChatMessage(new TextComponentTranslation("demo.help.inventory", GameSettings.getKeyDisplayString(gamesettings.keyBindInventory.getKeyCode()))); ++ .ingameGUI ++ .getChatGUI() ++ .printChatMessage(new TextComponentTranslation("demo.help.inventory", gamesettings.keyBindInventory.getDisplayName())); + } + } else if (i == 6) { + this.world +@@ -1440,7 +1446,8 @@ + PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client); + Entity entity = this.world.getEntityByID(packetIn.getEntityId()); + if (entity instanceof EntityLivingBase) { +- Potion potion = Potion.getPotionById(packetIn.getEffectId()); ++ Potion potion = Potion.getPotionById(packetIn.getEffectId() & 0xFF); ++ + if (potion != null) { + PotionEffect potioneffect = new PotionEffect( + potion, packetIn.getDuration(), packetIn.getAmplifier(), packetIn.getIsAmbient(), packetIn.doesShowParticles() +@@ -1643,7 +1650,7 @@ + File file2 = new File(file1, s2); + if (file2.isFile()) { + this.netManager.sendPacket(new CPacketResourcePackStatus(CPacketResourcePackStatus.Action.ACCEPTED)); +- Futures.addCallback(this.client.getResourcePackRepository().setServerResourcePack(file2), this.createDownloadCallback()); ++ Futures.addCallback(this.client.getResourcePackRepository().setServerResourcePack(file2), this.createDownloadCallback(), Runnable::run); + return; + } + } catch (UnsupportedEncodingException unsupportedencodingexception) { +@@ -1654,7 +1661,7 @@ + ServerData serverdata = this.client.getCurrentServerData(); + if (serverdata != null && serverdata.getResourceMode() == ServerData.ServerResourceMode.ENABLED) { + this.netManager.sendPacket(new CPacketResourcePackStatus(CPacketResourcePackStatus.Action.ACCEPTED)); +- Futures.addCallback(this.client.getResourcePackRepository().downloadResourcePack(s, s1), this.createDownloadCallback()); ++ Futures.addCallback(this.client.getResourcePackRepository().downloadResourcePack(s, s1), this.createDownloadCallback(), Runnable::run); + } else if (serverdata != null && serverdata.getResourceMode() != ServerData.ServerResourceMode.PROMPT) { + this.netManager.sendPacket(new CPacketResourcePackStatus(CPacketResourcePackStatus.Action.DECLINED)); + } else { +@@ -1680,7 +1687,8 @@ + .sendPacket(new CPacketResourcePackStatus(CPacketResourcePackStatus.Action.ACCEPTED)); + Futures.addCallback( + NetHandlerPlayClient.this.client.getResourcePackRepository().downloadResourcePack(s, s1), +- NetHandlerPlayClient.this.createDownloadCallback() ++ NetHandlerPlayClient.this.createDownloadCallback(), ++ Runnable::run + ); + } else { + if (serverdata1 != null) { +@@ -1786,6 +1794,7 @@ + } catch (IOException ioexception) { + LOGGER.error("Couldn't load trade info", ioexception); + } finally { ++ if (false) // Forge: let packet handle releasing buffer + packetbuffer.release(); + } + } else if ("MC|Brand".equals(packetIn.getChannelName())) { +@@ -1985,8 +1994,8 @@ + IAttributeInstance iattributeinstance = abstractattributemap.getAttributeInstanceByName(spacketentityproperties$snapshot.getName()); + if (iattributeinstance == null) { + iattributeinstance = abstractattributemap.registerAttribute( +- new RangedAttribute(null, spacketentityproperties$snapshot.getName(), 0.0, Double.MIN_NORMAL, Double.MAX_VALUE) +- ); ++ new RangedAttribute(null, spacketentityproperties$snapshot.getName(), 0.0, -Double.MAX_VALUE, Double.MAX_VALUE) ++ ); // Forge: fix invalid value range (MC-150405) + } + + iattributeinstance.setBaseValue(spacketentityproperties$snapshot.getBaseValue()); diff --git a/module/minecraft/patches/net/minecraft/client/network/ServerPinger.java.patch b/module/minecraft/patches/net/minecraft/client/network/ServerPinger.java.patch new file mode 100644 index 000000000..930de625e --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/network/ServerPinger.java.patch @@ -0,0 +1,19 @@ +--- original/net/minecraft/client/network/ServerPinger.java ++++ modified/net/minecraft/client/network/ServerPinger.java +@@ -138,6 +138,7 @@ + server.setBase64EncodedIconData(null); + } + ++ net.minecraftforge.fml.client.FMLClientHandler.instance().bindServerListData(server, serverstatusresponse); + this.pingSentAt = Minecraft.getSystemTime(); + networkmanager.sendPacket(new CPacketPing(this.pingSentAt)); + this.successful = true; +@@ -166,7 +167,7 @@ + ); + + try { +- networkmanager.sendPacket(new C00Handshake(serveraddress.getIP(), serveraddress.getPort(), EnumConnectionState.STATUS)); ++ networkmanager.sendPacket(new C00Handshake(serveraddress.getIP(), serveraddress.getPort(), EnumConnectionState.STATUS, true)); + networkmanager.sendPacket(new CPacketServerQuery()); + } catch (Throwable throwable) { + LOGGER.error(throwable); diff --git a/module/minecraft/patches/net/minecraft/client/particle/Particle.java.patch b/module/minecraft/patches/net/minecraft/client/particle/Particle.java.patch new file mode 100644 index 000000000..ed7b946a8 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/particle/Particle.java.patch @@ -0,0 +1,22 @@ +--- original/net/minecraft/client/particle/Particle.java ++++ modified/net/minecraft/client/particle/Particle.java +@@ -286,17 +286,8 @@ + if (particleWidth != this.width || particleHeight != this.height) { + this.width = particleWidth; + this.height = particleHeight; +- AxisAlignedBB axisalignedbb = this.getBoundingBox(); +- this.setBoundingBox( +- new AxisAlignedBB( +- axisalignedbb.minX, +- axisalignedbb.minY, +- axisalignedbb.minZ, +- axisalignedbb.minX + this.width, +- axisalignedbb.minY + this.height, +- axisalignedbb.minZ + this.width +- ) +- ); ++ // FORGE: Fix MC-12269 - Glitchy movement when setSize is called without setPosition ++ setPosition(posX, posY, posZ); + } + } + diff --git a/module/minecraft/patches/net/minecraft/client/particle/ParticleItemPickup.java.patch b/module/minecraft/patches/net/minecraft/client/particle/ParticleItemPickup.java.patch new file mode 100644 index 000000000..ccc260c44 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/particle/ParticleItemPickup.java.patch @@ -0,0 +1,12 @@ +--- original/net/minecraft/client/particle/ParticleItemPickup.java ++++ modified/net/minecraft/client/particle/ParticleItemPickup.java +@@ -69,7 +69,9 @@ + d7 -= interpPosY; + d8 -= interpPosZ; + GlStateManager.enableLighting(); ++ GlStateManager.enableCull(); + this.renderManager.renderEntity(this.item, d6, d7, d8, this.item.rotationYaw, partialTicks, false); ++ GlStateManager.disableCull(); + } + + @Override diff --git a/module/minecraft/patches/net/minecraft/client/particle/ParticleManager.java.patch b/module/minecraft/patches/net/minecraft/client/particle/ParticleManager.java.patch new file mode 100644 index 000000000..40d351a62 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/particle/ParticleManager.java.patch @@ -0,0 +1,31 @@ +--- original/net/minecraft/client/particle/ParticleManager.java ++++ modified/net/minecraft/client/particle/ParticleManager.java +@@ -153,6 +153,7 @@ + } + + public void addEffect(Particle effect) { ++ if (effect == null) return; //Forge: Prevent modders from being bad and adding nulls causing untraceable NPEs. + this.queue.add(effect); + } + +@@ -351,7 +352,7 @@ + } + + public void addBlockDestroyEffects(BlockPos pos, IBlockState state) { +- if (state.getMaterial() != Material.AIR) { ++ if (!state.getBlock().isAir(state, this.world, pos) && !state.getBlock().addDestroyEffects(world, pos, this)) { + state = state.getActualState(this.world, pos); + int i = 4; + +@@ -445,4 +446,11 @@ + + return "" + i; + } ++ ++ public void addBlockHitEffects(BlockPos pos, net.minecraft.util.math.RayTraceResult target) { ++ IBlockState state = world.getBlockState(pos); ++ if (state != null && !state.getBlock().addHitEffects(state, world, target, this)) { ++ addBlockHitEffects(pos, target.sideHit); ++ } ++ } + } diff --git a/module/minecraft/patches/net/minecraft/client/renderer/ActiveRenderInfo.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/ActiveRenderInfo.java.patch new file mode 100644 index 000000000..b258e0334 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/ActiveRenderInfo.java.patch @@ -0,0 +1,36 @@ +--- original/net/minecraft/client/renderer/ActiveRenderInfo.java ++++ modified/net/minecraft/client/renderer/ActiveRenderInfo.java +@@ -38,6 +38,10 @@ + + /** Updates the current render info and camera location based on entity look angles and 1st/3rd person view mode */ + public static void updateRenderInfo(EntityPlayer entityplayerIn, boolean p_74583_1_) { ++ updateRenderInfo((Entity) entityplayerIn, p_74583_1_); ++ } ++ ++ public static void updateRenderInfo(Entity entityplayerIn, boolean p_74583_1_) { + GlStateManager.getFloat(2982, MODELVIEW); + GlStateManager.getFloat(2983, PROJECTION); + GlStateManager.glGetInteger(2978, VIEWPORT); +@@ -81,7 +85,7 @@ + } + } + +- return iblockstate; ++ return iblockstate.getBlock().getStateAtViewpoint(iblockstate, worldIn, blockpos, vec3d); + } + + public static float getRotationX() { +@@ -103,4 +107,13 @@ + public static float getRotationXY() { + return rotationXY; + } ++ ++ /* ======================================== FORGE START =====================================*/ ++ ++ /** ++ * Vector from render view entity position (corrected for partialTickTime) to the middle of screen ++ */ ++ public static Vec3d getCameraPosition() { ++ return position; ++ } + } diff --git a/module/minecraft/patches/net/minecraft/client/renderer/BlockFluidRenderer.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/BlockFluidRenderer.java.patch new file mode 100644 index 000000000..67fac808d --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/BlockFluidRenderer.java.patch @@ -0,0 +1,13 @@ +--- original/net/minecraft/client/renderer/BlockFluidRenderer.java ++++ modified/net/minecraft/client/renderer/BlockFluidRenderer.java +@@ -201,8 +201,8 @@ + BlockPos blockpos = blockPosIn.add(j1, 0, k1); + TextureAtlasSprite textureatlassprite1 = atextureatlassprite[1]; + if (!flag) { +- Block block = blockAccess.getBlockState(blockpos).getBlock(); +- if (block == Blocks.GLASS || block == Blocks.STAINED_GLASS) { ++ IBlockState state = blockAccess.getBlockState(blockpos); ++ if (state.getBlockFaceShape(blockAccess, blockpos, EnumFacing.VALUES[i1 + 2].getOpposite()) == net.minecraft.block.state.BlockFaceShape.SOLID) { + textureatlassprite1 = this.atlasSpriteWaterOverlay; + } + } diff --git a/module/minecraft/patches/net/minecraft/client/renderer/BlockModelRenderer.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/BlockModelRenderer.java.patch new file mode 100644 index 000000000..a0029cc71 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/BlockModelRenderer.java.patch @@ -0,0 +1,49 @@ +--- original/net/minecraft/client/renderer/BlockModelRenderer.java ++++ modified/net/minecraft/client/renderer/BlockModelRenderer.java +@@ -46,7 +46,7 @@ + boolean checkSides, + long rand + ) { +- boolean flag = Minecraft.isAmbientOcclusionEnabled() && stateIn.getLightValue() == 0 && modelIn.isAmbientOcclusion(); ++ boolean flag = Minecraft.isAmbientOcclusionEnabled() && stateIn.getLightValue(worldIn, posIn) == 0 && modelIn.isAmbientOcclusion(stateIn); + + try { + return flag +@@ -146,6 +146,14 @@ + buffer.putBrightness4( + aoFace.vertexBrightness[0], aoFace.vertexBrightness[1], aoFace.vertexBrightness[2], aoFace.vertexBrightness[3] + ); ++ ++ if(bakedquad.shouldApplyDiffuseLighting()) { ++ float diffuse = net.minecraftforge.client.model.pipeline.LightUtil.diffuseLight(bakedquad.getFace()); ++ aoFace.vertexColorMultiplier[0] *= diffuse; ++ aoFace.vertexColorMultiplier[1] *= diffuse; ++ aoFace.vertexColorMultiplier[2] *= diffuse; ++ aoFace.vertexColorMultiplier[3] *= diffuse; ++ } + if (bakedquad.hasTintIndex()) { + int k = this.blockColors.colorMultiplier(stateIn, blockAccessIn, posIn, bakedquad.getTintIndex()); + if (EntityRenderer.anaglyphEnable) { +@@ -270,10 +278,22 @@ + float f = (k >> 16 & 0xFF) / 255.0F; + float f1 = (k >> 8 & 0xFF) / 255.0F; + float f2 = (k & 0xFF) / 255.0F; ++ if(bakedquad.shouldApplyDiffuseLighting()) { ++ float diffuse = net.minecraftforge.client.model.pipeline.LightUtil.diffuseLight(bakedquad.getFace()); ++ f *= diffuse; ++ f1 *= diffuse; ++ f2 *= diffuse; ++ } + buffer.putColorMultiplier(f, f1, f2, 4); + buffer.putColorMultiplier(f, f1, f2, 3); + buffer.putColorMultiplier(f, f1, f2, 2); + buffer.putColorMultiplier(f, f1, f2, 1); ++ } else if(bakedquad.shouldApplyDiffuseLighting()) { ++ float diffuse = net.minecraftforge.client.model.pipeline.LightUtil.diffuseLight(bakedquad.getFace()); ++ buffer.putColorMultiplier(diffuse, diffuse, diffuse, 4); ++ buffer.putColorMultiplier(diffuse, diffuse, diffuse, 3); ++ buffer.putColorMultiplier(diffuse, diffuse, diffuse, 2); ++ buffer.putColorMultiplier(diffuse, diffuse, diffuse, 1); + } + + buffer.putPosition(d0, d1, d2); diff --git a/module/minecraft/patches/net/minecraft/client/renderer/BlockModelShapes.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/BlockModelShapes.java.patch new file mode 100644 index 000000000..b555db070 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/BlockModelShapes.java.patch @@ -0,0 +1,9 @@ +--- original/net/minecraft/client/renderer/BlockModelShapes.java ++++ modified/net/minecraft/client/renderer/BlockModelShapes.java +@@ -412,5 +412,6 @@ + return new ModelResourceLocation(s + "_double_slab", s1); + } + }); ++ net.minecraftforge.client.model.ModelLoader.onRegisterAllBlocks(this); + } + } diff --git a/module/minecraft/patches/net/minecraft/client/renderer/BlockRendererDispatcher.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/BlockRendererDispatcher.java.patch new file mode 100644 index 000000000..20ab306bd --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/BlockRendererDispatcher.java.patch @@ -0,0 +1,31 @@ +--- original/net/minecraft/client/renderer/BlockRendererDispatcher.java ++++ modified/net/minecraft/client/renderer/BlockRendererDispatcher.java +@@ -26,7 +26,7 @@ + + public BlockRendererDispatcher(BlockModelShapes p_i46577_1_, BlockColors p_i46577_2_) { + this.blockModelShapes = p_i46577_1_; +- this.blockModelRenderer = new BlockModelRenderer(p_i46577_2_); ++ this.blockModelRenderer = new net.minecraftforge.client.model.pipeline.ForgeBlockModelRenderer(p_i46577_2_); + this.fluidRenderer = new BlockFluidRenderer(p_i46577_2_); + } + +@@ -38,7 +38,7 @@ + if (state.getRenderType() == EnumBlockRenderType.MODEL) { + state = state.getActualState(blockAccess, pos); + IBakedModel ibakedmodel = this.blockModelShapes.getModelForState(state); +- IBakedModel ibakedmodel1 = new SimpleBakedModel.Builder(state, ibakedmodel, texture, pos).makeBakedModel(); ++ IBakedModel ibakedmodel1 = net.minecraftforge.client.ForgeHooksClient.getDamageModel(ibakedmodel, texture, state, blockAccess, pos); + this.blockModelRenderer.renderModel(blockAccess, ibakedmodel1, state, pos, Tessellator.getInstance().getBuffer(), true); + } + } +@@ -59,7 +59,9 @@ + + switch (enumblockrendertype) { + case MODEL: +- return this.blockModelRenderer.renderModel(blockAccess, this.getModelForState(state), state, pos, bufferBuilderIn, true); ++ IBakedModel model = this.getModelForState(state); ++ state = state.getBlock().getExtendedState(state, blockAccess, pos); ++ return this.blockModelRenderer.renderModel(blockAccess, model, state, pos, bufferBuilderIn, true); + case ENTITYBLOCK_ANIMATED: + return false; + case LIQUID: diff --git a/module/minecraft/patches/net/minecraft/client/renderer/BufferBuilder.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/BufferBuilder.java.patch new file mode 100644 index 000000000..8e8daba69 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/BufferBuilder.java.patch @@ -0,0 +1,69 @@ +--- original/net/minecraft/client/renderer/BufferBuilder.java ++++ modified/net/minecraft/client/renderer/BufferBuilder.java +@@ -120,6 +120,8 @@ + + bitset.set(i1); + } ++ this.rawIntBuffer.limit(this.rawIntBuffer.capacity()); ++ this.rawIntBuffer.position(this.getBufferSize()); + } + + public BufferBuilder.State getVertexState() { +@@ -374,8 +376,8 @@ + } + + public void addVertexData(int[] vertexData) { +- this.growBuffer(vertexData.length * 4); +- ((Buffer)this.rawIntBuffer).position(this.getBufferSize()); ++ this.growBuffer(vertexData.length * 4 + this.vertexFormat.getSize());//Forge, fix MC-122110 ++ this.rawIntBuffer.position(this.getBufferSize()); + this.rawIntBuffer.put(vertexData); + this.vertexCount = this.vertexCount + vertexData.length / this.vertexFormat.getIntegerSize(); + } +@@ -454,15 +456,15 @@ + break; + case USHORT: + case SHORT: +- this.byteBuffer.putShort(i, (short)((int)x * 32767 & 65535)); +- this.byteBuffer.putShort(i + 2, (short)((int)y * 32767 & 65535)); +- this.byteBuffer.putShort(i + 4, (short)((int)z * 32767 & 65535)); ++ this.byteBuffer.putShort(i, (short)((int)(x * 32767) & 65535)); ++ this.byteBuffer.putShort(i + 2, (short)((int)(y * 32767) & 65535)); ++ this.byteBuffer.putShort(i + 4, (short)((int)(z * 32767) & 65535)); + break; + case UBYTE: + case BYTE: +- this.byteBuffer.put(i, (byte)((int)x * 127 & 0xFF)); +- this.byteBuffer.put(i + 1, (byte)((int)y * 127 & 0xFF)); +- this.byteBuffer.put(i + 2, (byte)((int)z * 127 & 0xFF)); ++ this.byteBuffer.put(i, (byte)((int)(x * 127) & 0xFF)); ++ this.byteBuffer.put(i + 1, (byte)((int)(y * 127) & 0xFF)); ++ this.byteBuffer.put(i + 2, (byte)((int)(z * 127) & 0xFF)); + } + + this.nextVertexFormatIndex(); +@@ -535,4 +537,24 @@ + return this.stateVertexFormat; + } + } ++ ++ ++ //For some unknown reason Mojang changed the vanilla function to hardcode alpha as 255.... So lets re-add the parameter -.- ++ public void putColorRGBA(int index, int red, int green, int blue, int alpha) { ++ if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) ++ this.rawIntBuffer.put(index, alpha << 24 | blue << 16 | green << 8 | red); ++ else ++ this.rawIntBuffer.put(index, red << 24 | green << 16 | blue << 8 | alpha); ++ } ++ ++ public boolean isColorDisabled() { ++ return this.noColor; ++ } ++ ++ public void putBulkData(ByteBuffer buffer) { ++ growBuffer(buffer.limit() + this.vertexFormat.getSize()); ++ this.byteBuffer.position(this.vertexCount * this.vertexFormat.getSize()); ++ this.byteBuffer.put(buffer); ++ this.vertexCount += buffer.limit() / this.vertexFormat.getSize(); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/client/renderer/ChestRenderer.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/ChestRenderer.java.patch new file mode 100644 index 000000000..c513795d8 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/ChestRenderer.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/client/renderer/ChestRenderer.java ++++ modified/net/minecraft/client/renderer/ChestRenderer.java +@@ -11,6 +11,7 @@ + public void renderChestBrightness(Block blockIn, float color) { + GlStateManager.color(color, color, color, 1.0F); + GlStateManager.rotate(90.0F, 0.0F, 1.0F, 0.0F); +- TileEntityItemStackRenderer.instance.renderByItem(new ItemStack(blockIn)); ++ ItemStack stack = new ItemStack(blockIn); ++ stack.getItem().getTileEntityItemStackRenderer().renderByItem(stack); + } + } diff --git a/module/minecraft/patches/net/minecraft/client/renderer/EntityRenderer.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/EntityRenderer.java.patch new file mode 100644 index 000000000..0ad3220d9 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/EntityRenderer.java.patch @@ -0,0 +1,351 @@ +--- original/net/minecraft/client/renderer/EntityRenderer.java ++++ modified/net/minecraft/client/renderer/EntityRenderer.java +@@ -240,7 +240,7 @@ + this.loadShader(new ResourceLocation("shaders/post/spider.json")); + } else if (entityIn instanceof EntityEnderman) { + this.loadShader(new ResourceLocation("shaders/post/invert.json")); +- } ++ } else net.minecraftforge.client.ForgeHooksClient.loadEntityShader(entityIn, this); + } + } + +@@ -303,7 +303,7 @@ + this.mc.setRenderViewEntity(this.mc.player); + } + +- float f3 = this.mc.world.getLightBrightness(new BlockPos(this.mc.getRenderViewEntity())); ++ float f3 = this.mc.world.getLightBrightness(new BlockPos(this.mc.getRenderViewEntity().getPositionEyes(1.0F))); // Forge: fix MC-51150 + float f4 = this.mc.gameSettings.renderDistanceChunks / 32.0F; + float f2 = f3 * (1.0F - f4) + f4; + this.fogColor1 = this.fogColor1 + (f2 - this.fogColor1) * 0.1F; +@@ -403,7 +403,7 @@ + } else if (raytraceresult != null) { + double d3 = vec3d.distanceTo(raytraceresult.hitVec); + if (d3 < d2 || d2 == 0.0) { +- if (entity1.getLowestRidingEntity() == entity.getLowestRidingEntity()) { ++ if (entity1.getLowestRidingEntity() == entity.getLowestRidingEntity() && !entity1.canRiderInteract()) { + if (d2 == 0.0) { + this.pointedEntity = entity1; + vec3d3 = raytraceresult.hitVec; +@@ -476,7 +476,7 @@ + f = f * 60.0F / 70.0F; + } + +- return f; ++ return net.minecraftforge.client.ForgeHooksClient.getFOVModifier(this, entity, iblockstate, partialTicks, f); + } + + private void hurtCameraEffect(float partialTicks) { +@@ -531,11 +531,7 @@ + if (!this.mc.gameSettings.debugCamEnable) { + BlockPos blockpos = new BlockPos(entity); + IBlockState iblockstate = this.mc.world.getBlockState(blockpos); +- Block block = iblockstate.getBlock(); +- if (block == Blocks.BED) { +- int j = iblockstate.getValue(BlockBed.FACING).getHorizontalIndex(); +- GlStateManager.rotate(j * 90, 0.0F, 1.0F, 0.0F); +- } ++ net.minecraftforge.client.ForgeHooksClient.orientBedCamera(this.mc.world, blockpos, iblockstate, entity); + + GlStateManager.rotate(entity.prevRotationYaw + (entity.rotationYaw - entity.prevRotationYaw) * partialTicks + 180.0F, 0.0F, -1.0F, 0.0F); + GlStateManager.rotate(entity.prevRotationPitch + (entity.rotationPitch - entity.prevRotationPitch) * partialTicks, -1.0F, 0.0F, 0.0F); +@@ -588,15 +584,19 @@ + } + + if (!this.mc.gameSettings.debugCamEnable) { +- GlStateManager.rotate(entity.prevRotationPitch + (entity.rotationPitch - entity.prevRotationPitch) * partialTicks, 1.0F, 0.0F, 0.0F); ++ float yaw = entity.prevRotationYaw + (entity.rotationYaw - entity.prevRotationYaw) * partialTicks + 180.0F; ++ float pitch = entity.prevRotationPitch + (entity.rotationPitch - entity.prevRotationPitch) * partialTicks; ++ float roll = 0.0F; + if (entity instanceof EntityAnimal) { + EntityAnimal entityanimal = (EntityAnimal)entity; +- GlStateManager.rotate( +- entityanimal.prevRotationYawHead + (entityanimal.rotationYawHead - entityanimal.prevRotationYawHead) * partialTicks + 180.0F, 0.0F, 1.0F, 0.0F +- ); +- } else { +- GlStateManager.rotate(entity.prevRotationYaw + (entity.rotationYaw - entity.prevRotationYaw) * partialTicks + 180.0F, 0.0F, 1.0F, 0.0F); ++ yaw = entityanimal.prevRotationYawHead + (entityanimal.rotationYawHead - entityanimal.prevRotationYawHead) * partialTicks + 180.0F; + } ++ IBlockState state = ActiveRenderInfo.getBlockStateAtEntityViewpoint(this.mc.world, entity, partialTicks); ++ net.minecraftforge.client.event.EntityViewRenderEvent.CameraSetup event = new net.minecraftforge.client.event.EntityViewRenderEvent.CameraSetup(this, entity, state, partialTicks, yaw, pitch, roll); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event); ++ GlStateManager.rotate(event.getRoll(), 0.0F, 0.0F, 1.0F); ++ GlStateManager.rotate(event.getPitch(), 1.0F, 0.0F, 0.0F); ++ GlStateManager.rotate(event.getYaw(), 0.0F, 1.0F, 0.0F); + } + + GlStateManager.translate(0.0F, -f, 0.0F); +@@ -703,7 +703,9 @@ + } + + boolean flag = this.mc.getRenderViewEntity() instanceof EntityLivingBase +- && ((EntityLivingBase)this.mc.getRenderViewEntity()).isPlayerSleeping(); ++ && ((EntityLivingBase)this.mc.getRenderViewEntity()).isPlayerSleeping(); ++ ++ if (!net.minecraftforge.client.ForgeHooksClient.renderFirstPersonHand(mc.renderGlobal, partialTicks, pass)) + if (this.mc.gameSettings.thirdPersonView == 0 + && !flag + && !this.mc.gameSettings.hideGUI +@@ -797,6 +799,15 @@ + f12 = 0.25F + f9 * 0.75F; + } + ++ float[] colors = {f8, f9, f10}; ++ world.provider.getLightmapColors(partialTicks, f, f2, f3, colors); ++ f8 = colors[0]; f9 = colors[1]; f10 = colors[2]; ++ ++ // Forge: fix MC-58177 ++ f8 = MathHelper.clamp(f8, 0f, 1f); ++ f9 = MathHelper.clamp(f9, 0f, 1f); ++ f10 = MathHelper.clamp(f10, 0f, 1f); ++ + if (this.mc.player.isPotionActive(MobEffects.NIGHT_VISION)) { + float f17 = this.getNightVisionBrightness(this.mc.player, partialTicks); + float f14 = 1.0F / f10; +@@ -940,7 +951,15 @@ + j = Math.max(j, 60); + long k = System.nanoTime() - nanoTime; + long l = Math.max(1000000000 / j / 4 - k, 0L); +- this.renderWorld(partialTicks, System.nanoTime() + l); ++ ++ if (com.cleanroommc.kirino.KirinoCommonCore.KIRINO_CONFIG_HUB.isEnable() ++ && com.cleanroommc.kirino.KirinoCommonCore.KIRINO_CONFIG_HUB.isEnableRenderDelegate() ++ && !com.cleanroommc.kirino.KirinoClientCore.isRenderUnsupported()) { ++ com.cleanroommc.kirino.KirinoClientCore.EntityRenderer$renderWorld(System.nanoTime() + l); ++ } else { ++ this.renderWorld(partialTicks, System.nanoTime() + l); ++ } ++ + if (this.mc.isSingleplayer() && this.timeWorldIcon < Minecraft.getSystemTime() - 1000L) { + this.timeWorldIcon = Minecraft.getSystemTime(); + if (!this.mc.getIntegratedServer().isWorldIconSet()) { +@@ -979,13 +998,17 @@ + GlStateManager.loadIdentity(); + this.setupOverlayRendering(); + this.renderEndNanoTime = System.nanoTime(); ++ // Forge: Fix MC-112292 ++ net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher.instance.renderEngine = this.mc.getTextureManager(); ++ // Forge: also fix rendering text before entering world (not part of MC-112292, but the same reason) ++ net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher.instance.fontRenderer = this.mc.fontRenderer; + } + + if (this.mc.currentScreen != null) { + GlStateManager.clear(256); + + try { +- this.mc.currentScreen.drawScreen(k1, l1, this.mc.getTickLength()); ++ net.minecraftforge.client.ForgeHooksClient.drawScreen(this.mc.currentScreen, k1, l1, this.mc.getTickLength()); + } catch (Throwable throwable) { + CrashReport crashreport = CrashReport.makeCrashReport(throwable, "Rendering screen"); + CrashReportCategory crashreportcategory = crashreport.makeCategory("Screen render details"); +@@ -1067,7 +1090,7 @@ + BlockPos blockpos = this.mc.objectMouseOver.getBlockPos(); + Block block = this.mc.world.getBlockState(blockpos).getBlock(); + if (this.mc.playerController.getCurrentGameType() == GameType.SPECTATOR) { +- flag = block.hasTileEntity() && this.mc.world.getTileEntity(blockpos) instanceof IInventory; ++ flag = block.hasTileEntity(this.mc.world.getBlockState(blockpos)) && this.mc.world.getTileEntity(blockpos) instanceof IInventory; + } else { + flag = !itemstack.isEmpty() && (itemstack.canDestroy(block) || itemstack.canPlaceOn(block)); + } +@@ -1104,6 +1127,15 @@ + } + + private void renderWorldPass(int pass, float partialTicks, long finishTimeNano) { ++ if (com.cleanroommc.kirino.KirinoCommonCore.KIRINO_CONFIG_HUB.isEnable() ++ && (!com.cleanroommc.kirino.KirinoCommonCore.KIRINO_CONFIG_HUB.isEnableRenderDelegate() ++ || com.cleanroommc.kirino.KirinoClientCore.isRenderUnsupported())) { ++ if (com.cleanroommc.kirino.KirinoCommonCore.KIRINO_ENGINE.isAfterFirstPrepare()) { ++ com.cleanroommc.kirino.KirinoClientCore.runHeadlessly(com.cleanroommc.kirino.engine.FramePhase.PREPARE); ++ } ++ com.cleanroommc.kirino.KirinoClientCore.runHeadlessly(com.cleanroommc.kirino.engine.FramePhase.PRE_UPDATE); ++ } ++ + RenderGlobal renderglobal = this.mc.renderGlobal; + ParticleManager particlemanager = this.mc.effectRenderer; + boolean flag = this.isDrawBlockOutline(); +@@ -1114,7 +1146,7 @@ + GlStateManager.clear(16640); + this.mc.profiler.endStartSection("camera"); + this.setupCameraTransform(partialTicks, pass); +- ActiveRenderInfo.updateRenderInfo(this.mc.player, this.mc.gameSettings.thirdPersonView == 2); ++ ActiveRenderInfo.updateRenderInfo(this.mc.getRenderViewEntity(), this.mc.gameSettings.thirdPersonView == 2); //Forge: MC-46445 Spectator mode particles and sounds computed from where you have been before + this.mc.profiler.endStartSection("frustum"); + ClippingHelperImpl.getInstance(); + this.mc.profiler.endStartSection("culling"); +@@ -1154,6 +1186,13 @@ + this.renderCloudsCheck(renderglobal, partialTicks, pass, d0, d1, d2); + } + ++ if (com.cleanroommc.kirino.KirinoCommonCore.KIRINO_CONFIG_HUB.isEnable() ++ && (!com.cleanroommc.kirino.KirinoCommonCore.KIRINO_CONFIG_HUB.isEnableRenderDelegate() ++ || com.cleanroommc.kirino.KirinoClientCore.isRenderUnsupported())) { ++ com.cleanroommc.kirino.KirinoClientCore.runHeadlessly(com.cleanroommc.kirino.engine.FramePhase.UPDATE); ++ com.cleanroommc.kirino.KirinoClientCore.runHeadlessly(com.cleanroommc.kirino.engine.FramePhase.RENDER_OPAQUE); ++ } ++ + this.mc.profiler.endStartSection("prepareterrain"); + this.setupFog(0, partialTicks); + this.mc.getTextureManager().bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); +@@ -1171,7 +1210,9 @@ + GlStateManager.disableAlpha(); + renderglobal.renderBlockLayer(BlockRenderLayer.SOLID, partialTicks, pass, entity); + GlStateManager.enableAlpha(); ++ this.mc.getTextureManager().getTexture(TextureMap.LOCATION_BLOCKS_TEXTURE).setBlurMipmap(false, this.mc.gameSettings.mipmapLevels > 0); // FORGE: fix flickering leaves when mods mess up the blurMipmap settings + renderglobal.renderBlockLayer(BlockRenderLayer.CUTOUT_MIPPED, partialTicks, pass, entity); ++ this.mc.getTextureManager().getTexture(TextureMap.LOCATION_BLOCKS_TEXTURE).restoreLastBlurMipmap(); + this.mc.getTextureManager().getTexture(TextureMap.LOCATION_BLOCKS_TEXTURE).setBlurMipmap(false, false); + renderglobal.renderBlockLayer(BlockRenderLayer.CUTOUT, partialTicks, pass, entity); + this.mc.getTextureManager().getTexture(TextureMap.LOCATION_BLOCKS_TEXTURE).restoreLastBlurMipmap(); +@@ -1183,7 +1224,9 @@ + GlStateManager.pushMatrix(); + RenderHelper.enableStandardItemLighting(); + this.mc.profiler.endStartSection("entities"); ++ net.minecraftforge.client.ForgeHooksClient.setRenderPass(0); + renderglobal.renderEntities(entity, icamera, partialTicks); ++ net.minecraftforge.client.ForgeHooksClient.setRenderPass(0); + RenderHelper.disableStandardItemLighting(); + this.disableLightmap(); + } +@@ -1194,6 +1237,7 @@ + EntityPlayer entityplayer = (EntityPlayer)entity; + GlStateManager.disableAlpha(); + this.mc.profiler.endStartSection("outline"); ++ if (!net.minecraftforge.client.ForgeHooksClient.onDrawBlockHighlight(renderglobal, entityplayer, mc.objectMouseOver, 0, partialTicks)) + renderglobal.drawSelectionBox(entityplayer, this.mc.objectMouseOver, 0, partialTicks); + GlStateManager.enableAlpha(); + } +@@ -1242,8 +1286,25 @@ + GlStateManager.depthMask(false); + this.mc.getTextureManager().bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); + GlStateManager.shadeModel(7425); ++ ++ if (com.cleanroommc.kirino.KirinoCommonCore.KIRINO_CONFIG_HUB.isEnable() ++ && (!com.cleanroommc.kirino.KirinoCommonCore.KIRINO_CONFIG_HUB.isEnableRenderDelegate() ++ || com.cleanroommc.kirino.KirinoClientCore.isRenderUnsupported())) { ++ com.cleanroommc.kirino.KirinoClientCore.runHeadlessly(com.cleanroommc.kirino.engine.FramePhase.RENDER_TRANSPARENT); ++ } ++ + this.mc.profiler.endStartSection("translucent"); + renderglobal.renderBlockLayer(BlockRenderLayer.TRANSLUCENT, partialTicks, pass, entity); ++ if (!this.debugView) { //Only render if render pass 0 happens as well. ++ RenderHelper.enableStandardItemLighting(); ++ this.mc.profiler.endStartSection("entities"); ++ net.minecraftforge.client.ForgeHooksClient.setRenderPass(1); ++ renderglobal.renderEntities(entity, icamera, partialTicks); ++ // restore blending function changed by RenderGlobal.preRenderDamagedBlocks ++ GlStateManager.tryBlendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO); ++ net.minecraftforge.client.ForgeHooksClient.setRenderPass(-1); ++ RenderHelper.disableStandardItemLighting(); ++ } + GlStateManager.shadeModel(7424); + GlStateManager.depthMask(true); + GlStateManager.enableCull(); +@@ -1254,11 +1315,21 @@ + this.renderCloudsCheck(renderglobal, partialTicks, pass, d0, d1, d2); + } + ++ this.mc.profiler.endStartSection("forge_render_last"); ++ net.minecraftforge.client.ForgeHooksClient.dispatchRenderLast(renderglobal, partialTicks); ++ + this.mc.profiler.endStartSection("hand"); + if (this.renderHand) { + GlStateManager.clear(256); + this.renderHand(partialTicks, pass); + } ++ ++ if (com.cleanroommc.kirino.KirinoCommonCore.KIRINO_CONFIG_HUB.isEnable() ++ && (!com.cleanroommc.kirino.KirinoCommonCore.KIRINO_CONFIG_HUB.isEnableRenderDelegate() ++ || com.cleanroommc.kirino.KirinoClientCore.isRenderUnsupported())) { ++ com.cleanroommc.kirino.KirinoClientCore.runHeadlessly(com.cleanroommc.kirino.engine.FramePhase.POST_UPDATE); ++ com.cleanroommc.kirino.KirinoClientCore.runHeadlessly(com.cleanroommc.kirino.engine.FramePhase.RENDER_OVERLAY); ++ } + } + + private void renderCloudsCheck(RenderGlobal renderGlobalIn, float partialTicks, int pass, double x, double y, double z) { +@@ -1376,6 +1447,12 @@ + + /** Render rain and snow */ + protected void renderRainSnow(float partialTicks) { ++ net.minecraftforge.client.IRenderHandler renderer = this.mc.world.provider.getWeatherRenderer(); ++ if (renderer != null) { ++ renderer.render(partialTicks, this.mc.world, mc); ++ return; ++ } ++ + float f = this.mc.world.getRainStrength(partialTicks); + if (!(f <= 0.0F)) { + this.enableLightmap(); +@@ -1612,22 +1689,15 @@ + this.fogColorRed = (float)vec3d3.x; + this.fogColorGreen = (float)vec3d3.y; + this.fogColorBlue = (float)vec3d3.z; +- } else if (iblockstate.getMaterial() == Material.WATER) { +- float f12 = 0.0F; +- if (entity instanceof EntityLivingBase) { +- f12 = EnchantmentHelper.getRespirationModifier((EntityLivingBase)entity) * 0.2F; +- if (((EntityLivingBase)entity).isPotionActive(MobEffects.WATER_BREATHING)) { +- f12 = f12 * 0.3F + 0.6F; +- } +- } +- +- this.fogColorRed = 0.02F + f12; +- this.fogColorGreen = 0.02F + f12; +- this.fogColorBlue = 0.2F + f12; +- } else if (iblockstate.getMaterial() == Material.LAVA) { +- this.fogColorRed = 0.6F; +- this.fogColorGreen = 0.1F; +- this.fogColorBlue = 0.0F; ++ } else { ++ //Forge Moved to Block. ++ Vec3d viewport = ActiveRenderInfo.projectViewFromEntity(entity, partialTicks); ++ BlockPos viewportPos = new BlockPos(viewport); ++ IBlockState viewportState = this.mc.world.getBlockState(viewportPos); ++ Vec3d inMaterialColor = viewportState.getBlock().getFogColor(this.mc.world, viewportPos, viewportState, entity, new Vec3d(fogColorRed, fogColorGreen, fogColorBlue), partialTicks); ++ this.fogColorRed = (float)inMaterialColor.x; ++ this.fogColorGreen = (float)inMaterialColor.y; ++ this.fogColorBlue = (float)inMaterialColor.z; + } + + float f13 = this.fogColor2 + (this.fogColor1 - this.fogColor2) * partialTicks; +@@ -1673,6 +1743,9 @@ + f6 = 1.0F / this.fogColorBlue; + } + ++ // Forge: fix MC-4647 and MC-10480 ++ if (Float.isInfinite(f6)) f6 = Math.nextAfter(f6, 0.0); ++ + this.fogColorRed = this.fogColorRed * (1.0F - f15) + this.fogColorRed * f6 * f15; + this.fogColorGreen = this.fogColorGreen * (1.0F - f15) + this.fogColorGreen * f6 * f15; + this.fogColorBlue = this.fogColorBlue * (1.0F - f15) + this.fogColorBlue * f6 * f15; +@@ -1687,6 +1760,13 @@ + this.fogColorBlue = f7; + } + ++ net.minecraftforge.client.event.EntityViewRenderEvent.FogColors event = new net.minecraftforge.client.event.EntityViewRenderEvent.FogColors(this, entity, iblockstate, partialTicks, this.fogColorRed, this.fogColorGreen, this.fogColorBlue); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event); ++ ++ this.fogColorRed = event.getRed(); ++ this.fogColorGreen = event.getGreen(); ++ this.fogColorBlue = event.getBlue(); ++ + GlStateManager.clearColor(this.fogColorRed, this.fogColorGreen, this.fogColorBlue, 0.0F); + } + +@@ -1697,6 +1777,9 @@ + GlStateManager.glNormal3f(0.0F, -1.0F, 0.0F); + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + IBlockState iblockstate = ActiveRenderInfo.getBlockStateAtEntityViewpoint(this.mc.world, entity, partialTicks); ++ float hook = net.minecraftforge.client.ForgeHooksClient.getFogDensity(this, entity, iblockstate, partialTicks, 0.1F); ++ if (hook >= 0) GlStateManager.setFogDensity(hook); ++ else + if (entity instanceof EntityLivingBase && ((EntityLivingBase)entity).isPotionActive(MobEffects.BLINDNESS)) { + float f1 = 5.0F; + int i = ((EntityLivingBase)entity).getActivePotionEffect(MobEffects.BLINDNESS).getDuration(); +@@ -1753,6 +1836,7 @@ + GlStateManager.setFogStart(f * 0.05F); + GlStateManager.setFogEnd(Math.min(f, 192.0F) * 0.5F); + } ++ net.minecraftforge.client.ForgeHooksClient.onFogRender(this, entity, iblockstate, partialTicks, startCoords, f); + } + + GlStateManager.enableColorMaterial(); diff --git a/module/minecraft/patches/net/minecraft/client/renderer/InventoryEffectRenderer.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/InventoryEffectRenderer.java.patch new file mode 100644 index 000000000..4669f874c --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/InventoryEffectRenderer.java.patch @@ -0,0 +1,37 @@ +--- original/net/minecraft/client/renderer/InventoryEffectRenderer.java ++++ modified/net/minecraft/client/renderer/InventoryEffectRenderer.java +@@ -27,10 +27,16 @@ + } + + protected void updateActivePotionEffects() { +- if (this.mc.player.getActivePotionEffects().isEmpty()) { ++ boolean hasVisibleEffect = false; ++ for(PotionEffect potioneffect : this.mc.player.getActivePotionEffects()) { ++ Potion potion = potioneffect.getPotion(); ++ if(potion.shouldRender(potioneffect)) { hasVisibleEffect = true; break; } ++ } ++ if (this.mc.player.getActivePotionEffects().isEmpty() || !hasVisibleEffect) { + this.guiLeft = (this.width - this.xSize) / 2; + this.hasActivePotionEffects = false; + } else { ++ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.GuiScreenEvent.PotionShiftEvent(this))) this.guiLeft = (this.width - this.xSize) / 2; else + this.guiLeft = 160 + (this.width - this.xSize - 200) / 2; + this.hasActivePotionEffects = true; + } +@@ -61,6 +67,7 @@ + + for (PotionEffect potioneffect : Ordering.natural().sortedCopy(collection)) { + Potion potion = potioneffect.getPotion(); ++ if(!potion.shouldRender(potioneffect)) continue; + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + this.mc.getTextureManager().bindTexture(INVENTORY_BACKGROUND); + this.drawTexturedModalRect(i, j, 0, 166, 140, 32); +@@ -69,6 +76,8 @@ + this.drawTexturedModalRect(i + 6, j + 7, 0 + i1 % 8 * 18, 198 + i1 / 8 * 18, 18, 18); + } + ++ potion.renderInventoryEffect(potioneffect, this, i, j, this.zLevel); ++ if (!potion.shouldRenderInvText(potioneffect)) { j += l; continue; } + String s1 = I18n.format(potion.getName()); + if (potioneffect.getAmplifier() == 1) { + s1 = s1 + " " + I18n.format("enchantment.level.2"); diff --git a/module/minecraft/patches/net/minecraft/client/renderer/ItemModelMesher.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/ItemModelMesher.java.patch new file mode 100644 index 000000000..110b22158 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/ItemModelMesher.java.patch @@ -0,0 +1,13 @@ +--- original/net/minecraft/client/renderer/ItemModelMesher.java ++++ modified/net/minecraft/client/renderer/ItemModelMesher.java +@@ -29,7 +29,9 @@ + } + + public TextureAtlasSprite getParticleIcon(Item item, int meta) { +- return this.getItemModel(new ItemStack(item, 1, meta)).getParticleTexture(); ++ ItemStack stack = new ItemStack(item, 1, meta); ++ IBakedModel model = this.getItemModel(stack); ++ return model.getOverrides().handleItemState(model, stack, null, null).getParticleTexture(); + } + + public IBakedModel getItemModel(ItemStack stack) { diff --git a/module/minecraft/patches/net/minecraft/client/renderer/ItemRenderer.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/ItemRenderer.java.patch new file mode 100644 index 000000000..e0d7da77a --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/ItemRenderer.java.patch @@ -0,0 +1,101 @@ +--- original/net/minecraft/client/renderer/ItemRenderer.java ++++ modified/net/minecraft/client/renderer/ItemRenderer.java +@@ -202,7 +202,8 @@ + bufferbuilder.pos(135.0, -7.0, 0.0).tex(1.0, 0.0).endVertex(); + bufferbuilder.pos(-7.0, -7.0, 0.0).tex(0.0, 0.0).endVertex(); + tessellator.draw(); +- MapData mapdata = Items.FILLED_MAP.getMapData(stack, this.mc.world); ++ MapData mapdata = ((net.minecraft.item.ItemMap) stack.getItem()).getMapData(stack, this.mc.world); ++ + if (mapdata != null) { + this.mc.entityRenderer.getMapItemRenderer().renderMap(mapdata, false); + } +@@ -283,7 +284,8 @@ + boolean flag1 = true; + if (abstractclientplayer.isHandActive()) { + ItemStack itemstack = abstractclientplayer.getActiveItemStack(); +- if (itemstack.getItem() == Items.BOW) { ++ ++ if (itemstack.getItem() instanceof net.minecraft.item.ItemBow) { + EnumHand enumhand1 = abstractclientplayer.getActiveHand(); + flag = enumhand1 == EnumHand.MAIN_HAND; + flag1 = !flag; +@@ -297,12 +299,14 @@ + if (flag) { + float f3 = enumhand == EnumHand.MAIN_HAND ? f : 0.0F; + float f5 = 1.0F - (this.prevEquippedProgressMainHand + (this.equippedProgressMainHand - this.prevEquippedProgressMainHand) * partialTicks); ++ if(!net.minecraftforge.client.ForgeHooksClient.renderSpecificFirstPersonHand(EnumHand.MAIN_HAND, partialTicks, f1, f3, f5, this.itemStackMainHand)) + this.renderItemInFirstPerson(abstractclientplayer, partialTicks, f1, EnumHand.MAIN_HAND, f3, this.itemStackMainHand, f5); + } + + if (flag1) { + float f4 = enumhand == EnumHand.OFF_HAND ? f : 0.0F; + float f6 = 1.0F - (this.prevEquippedProgressOffHand + (this.equippedProgressOffHand - this.prevEquippedProgressOffHand) * partialTicks); ++ if(!net.minecraftforge.client.ForgeHooksClient.renderSpecificFirstPersonHand(EnumHand.OFF_HAND, partialTicks, f1, f4, f6, this.itemStackOffHand)) + this.renderItemInFirstPerson(abstractclientplayer, partialTicks, f1, EnumHand.OFF_HAND, f4, this.itemStackOffHand, f6); + } + +@@ -326,7 +330,7 @@ + if (flag && !player.isInvisible()) { + this.renderArmFirstPerson(p_187457_7_, p_187457_5_, enumhandside); + } +- } else if (stack.getItem() == Items.FILLED_MAP) { ++ } else if (stack.getItem() instanceof net.minecraft.item.ItemMap) { + if (flag && this.itemStackOffHand.isEmpty()) { + this.renderMapFirstPerson(p_187457_3_, p_187457_7_, p_187457_5_); + } else { +@@ -398,6 +402,7 @@ + GlStateManager.disableAlpha(); + if (this.mc.player.isEntityInsideOpaqueBlock()) { + IBlockState iblockstate = this.mc.world.getBlockState(new BlockPos(this.mc.player)); ++ BlockPos overlayPos = new BlockPos(this.mc.player); + EntityPlayer entityplayer = this.mc.player; + + for (int i = 0; i < 8; i++) { +@@ -408,20 +413,24 @@ + IBlockState iblockstate1 = this.mc.world.getBlockState(blockpos); + if (iblockstate1.causesSuffocation()) { + iblockstate = iblockstate1; ++ overlayPos = blockpos; + } + } + + if (iblockstate.getRenderType() != EnumBlockRenderType.INVISIBLE) { ++ if (!net.minecraftforge.event.ForgeEventFactory.renderBlockOverlay(mc.player, partialTicks, net.minecraftforge.client.event.RenderBlockOverlayEvent.OverlayType.BLOCK, iblockstate, overlayPos)) + this.renderSuffocationOverlay(this.mc.getBlockRendererDispatcher().getBlockModelShapes().getTexture(iblockstate)); + } + } + + if (!this.mc.player.isSpectator()) { + if (this.mc.player.isInsideOfMaterial(Material.WATER)) { ++ if (!net.minecraftforge.event.ForgeEventFactory.renderWaterOverlay(mc.player, partialTicks)) + this.renderWaterOverlayTexture(partialTicks); + } + + if (this.mc.player.isBurning()) { ++ if (!net.minecraftforge.event.ForgeEventFactory.renderFireOverlay(mc.player, partialTicks)) + this.renderFireInFirstPerson(); + } + } +@@ -547,10 +556,17 @@ + this.equippedProgressOffHand = MathHelper.clamp(this.equippedProgressOffHand - 0.4F, 0.0F, 1.0F); + } else { + float f = entityplayersp.getCooledAttackStrength(1.0F); +- this.equippedProgressMainHand = this.equippedProgressMainHand +- + MathHelper.clamp((Objects.equals(this.itemStackMainHand, itemstack) ? f * f * f : 0.0F) - this.equippedProgressMainHand, -0.4F, 0.4F); +- this.equippedProgressOffHand = this.equippedProgressOffHand +- + MathHelper.clamp((Objects.equals(this.itemStackOffHand, itemstack1) ? 1 : 0) - this.equippedProgressOffHand, -0.4F, 0.4F); ++ ++ boolean requipM = net.minecraftforge.client.ForgeHooksClient.shouldCauseReequipAnimation(this.itemStackMainHand, itemstack, entityplayersp.inventory.currentItem); ++ boolean requipO = net.minecraftforge.client.ForgeHooksClient.shouldCauseReequipAnimation(this.itemStackOffHand, itemstack1, -1); ++ ++ if (!requipM && !Objects.equals(this.itemStackMainHand, itemstack)) ++ this.itemStackMainHand = itemstack; ++ if (!requipM && !Objects.equals(this.itemStackOffHand, itemstack1)) ++ this.itemStackOffHand = itemstack1; ++ ++ this.equippedProgressMainHand += MathHelper.clamp((!requipM ? f * f * f : 0.0F) - this.equippedProgressMainHand, -0.4F, 0.4F); ++ this.equippedProgressOffHand += MathHelper.clamp((!requipO ? 1 : 0) - this.equippedProgressOffHand, -0.4F, 0.4F); + } + + if (this.equippedProgressMainHand < 0.1F) { diff --git a/module/minecraft/patches/net/minecraft/client/renderer/OpenGlHelper.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/OpenGlHelper.java.patch new file mode 100644 index 000000000..c84a2b199 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/OpenGlHelper.java.patch @@ -0,0 +1,48 @@ +--- original/net/minecraft/client/renderer/OpenGlHelper.java ++++ modified/net/minecraft/client/renderer/OpenGlHelper.java +@@ -31,8 +31,8 @@ + import org.lwjgl.opengl.GL20; + import org.lwjgl.opengl.GL30; + import org.lwjgl.opengl.GLContext; +-import oshi.SystemInfo; +-import oshi.hardware.Processor; ++import oshi.ffm.SystemInfo; ++import oshi.hardware.CentralProcessor; + + @SideOnly(Side.CLIENT) + public class OpenGlHelper { +@@ -95,7 +95,10 @@ + public static int GL_ARRAY_BUFFER; + public static int GL_STATIC_DRAW; + +- /** Initializes the texture constants to be used when rendering lightmap values */ ++ /* Stores the last values sent into setLightmapTextureCoords */ ++ public static float lastBrightnessX = 0.0f; ++ public static float lastBrightnessY = 0.0f; ++ + public static void initializeTextures() { + ContextCapabilities contextcapabilities = GLContext.getCapabilities(); + arbMultitexture = contextcapabilities.GL_ARB_multitexture && !contextcapabilities.OpenGL13; +@@ -263,8 +266,8 @@ + } + + try { +- Processor[] aprocessor = new SystemInfo().getHardware().getProcessors(); +- cpu = String.format("%dx %s", aprocessor.length, aprocessor[0]).replaceAll("\\s+", " "); ++ CentralProcessor aprocessor = (new SystemInfo()).getHardware().getProcessor(); ++ cpu = String.format("%dx %s", aprocessor.getLogicalProcessorCount(), aprocessor.getProcessorIdentifier().getName()).replaceAll("\\s+", " "); + } catch (Throwable throwable) { + } + } +@@ -676,6 +679,11 @@ + } else { + GL13.glMultiTexCoord2f(target, x, y); + } ++ ++ if (target == lightmapTexUnit) { ++ lastBrightnessX = x; ++ lastBrightnessY = y; ++ } + } + + public static void glBlendFunc(int sFactorRGB, int dFactorRGB, int sfactorAlpha, int dfactorAlpha) { diff --git a/module/minecraft/patches/net/minecraft/client/renderer/RenderGlobal.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/RenderGlobal.java.patch new file mode 100644 index 000000000..2b7d8daa9 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/RenderGlobal.java.patch @@ -0,0 +1,183 @@ +--- original/net/minecraft/client/renderer/RenderGlobal.java ++++ modified/net/minecraft/client/renderer/RenderGlobal.java +@@ -498,7 +498,9 @@ + } + + public void renderEntities(Entity renderViewEntity, ICamera camera, float partialTicks) { ++ int pass = net.minecraftforge.client.MinecraftForgeClient.getRenderPass(); + if (this.renderEntitiesStartupCounter > 0) { ++ if (pass > 0) return; + this.renderEntitiesStartupCounter--; + } else { + double d0 = renderViewEntity.prevPosX + (renderViewEntity.posX - renderViewEntity.prevPosX) * partialTicks; +@@ -515,17 +517,19 @@ + partialTicks + ); + this.renderManager +- .cacheActiveRenderInfo( +- this.world, +- this.mc.fontRenderer, +- this.mc.getRenderViewEntity(), +- this.mc.pointedEntity, +- this.mc.gameSettings, +- partialTicks +- ); ++ .cacheActiveRenderInfo( ++ this.world, ++ this.mc.fontRenderer, ++ this.mc.getRenderViewEntity(), ++ this.mc.pointedEntity, ++ this.mc.gameSettings, ++ partialTicks ++ ); ++ if(pass == 0) { + this.countEntitiesTotal = 0; + this.countEntitiesRendered = 0; + this.countEntitiesHidden = 0; ++ } + Entity entity = this.mc.getRenderViewEntity(); + double d3 = entity.lastTickPosX + (entity.posX - entity.lastTickPosX) * partialTicks; + double d4 = entity.lastTickPosY + (entity.posY - entity.lastTickPosY) * partialTicks; +@@ -537,10 +541,13 @@ + this.mc.entityRenderer.enableLightmap(); + this.world.profiler.endStartSection("global"); + List list = this.world.getLoadedEntityList(); ++ if (pass == 0) { + this.countEntitiesTotal = list.size(); ++ } + + for (int i = 0; i < this.world.weatherEffects.size(); i++) { + Entity entity1 = this.world.weatherEffects.get(i); ++ if (!entity1.shouldRenderInPass(pass)) continue; + this.countEntitiesRendered++; + if (entity1.isInRangeToRender3d(d0, d1, d2)) { + this.renderManager.renderEntityStatic(entity1, partialTicks, false); +@@ -560,6 +567,7 @@ + / 16]; + if (!classinheritancemultimap.isEmpty()) { + for (Entity entity2 : classinheritancemultimap) { ++ if(!entity2.shouldRenderInPass(pass)) continue; + boolean flag = this.renderManager.shouldRender(entity2, camera, d0, d1, d2) + || entity2.isRidingOrBeingRiddenBy(this.mc.player); + if (flag) { +@@ -594,6 +602,7 @@ + } + } + ++ if(pass == 0) + if (this.isRenderEntityOutlines() && (!list1.isEmpty() || this.entityOutlinesRendered)) { + this.world.profiler.endStartSection("entityOutlines"); + this.entityOutlineFramebuffer.framebufferClear(); +@@ -629,10 +638,12 @@ + this.world.profiler.endStartSection("blockentities"); + RenderHelper.enableStandardItemLighting(); + ++ TileEntityRendererDispatcher.instance.preDrawBatch(); + for (RenderGlobal.ContainerLocalRenderInformation renderglobal$containerlocalrenderinformation1 : this.renderInfos) { + List list3 = renderglobal$containerlocalrenderinformation1.renderChunk.getCompiledChunk().getTileEntities(); + if (!list3.isEmpty()) { + for (TileEntity tileentity2 : list3) { ++ if (!tileentity2.shouldRenderInPass(pass) || !camera.isBoundingBoxInFrustum(tileentity2.getRenderBoundingBox())) continue; + TileEntityRendererDispatcher.instance.render(tileentity2, partialTicks, -1); + } + } +@@ -640,9 +651,11 @@ + + synchronized (this.setTileEntities) { + for (TileEntity tileentity : this.setTileEntities) { ++ if (!tileentity.shouldRenderInPass(pass) || !camera.isBoundingBoxInFrustum(tileentity.getRenderBoundingBox())) continue; + TileEntityRendererDispatcher.instance.render(tileentity, partialTicks, -1); + } + } ++ TileEntityRendererDispatcher.instance.drawBatch(pass); + + this.preRenderDamagedBlocks(); + +@@ -817,7 +830,8 @@ + for (int j = -this.renderDistanceChunks; j <= this.renderDistanceChunks; j++) { + for (int k = -this.renderDistanceChunks; k <= this.renderDistanceChunks; k++) { + RenderChunk renderchunk1 = this.viewFrustum.getRenderChunk(new BlockPos((j << 4) + 8, i, (k << 4) + 8)); +- if (renderchunk1 != null && camera.isBoundingBoxInFrustum(renderchunk1.boundingBox)) { ++ ++ if (renderchunk1 != null && camera.isBoundingBoxInFrustum(renderchunk1.boundingBox.expand(0.0, blockpos1.getY() > 0 ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY, 0.0))) { // Forge: fix MC-73139 + renderchunk1.setFrameIndex(frameCount); + queue.add(new RenderGlobal.ContainerLocalRenderInformation(renderchunk1, null, 0)); + } +@@ -868,7 +882,8 @@ + this.displayListEntitiesDirty = true; + BlockPos blockpos2 = renderchunk4.getPosition().add(8, 8, 8); + boolean flag3 = blockpos2.distanceSq(blockpos1) < 768.0; +- if (!renderchunk4.needsImmediateUpdate() && !flag3) { ++ ++ if (net.minecraftforge.common.ForgeModContainer.alwaysSetupTerrainOffThread || (!renderchunk4.needsImmediateUpdate() && !flag3)) { + this.chunksToUpdate.add(renderchunk4); + } else { + this.mc.profiler.startSection("build near"); +@@ -1120,6 +1135,12 @@ + } + + public void renderSky(float partialTicks, int pass) { ++ net.minecraftforge.client.IRenderHandler renderer = this.world.provider.getSkyRenderer(); ++ if (renderer != null) { ++ renderer.render(partialTicks, world, mc); ++ return; ++ } ++ + if (this.mc.world.provider.getDimensionType().getId() == 1) { + this.renderSkyEnd(); + } else if (this.mc.world.provider.isSurfaceWorld()) { +@@ -1317,6 +1338,7 @@ + } + + public void renderClouds(float partialTicks, int pass, double x, double y, double z) { ++ if (net.minecraftforge.fml.client.FMLClientHandler.instance().renderClouds(this.cloudTickCounter, partialTicks)) return; + if (this.mc.world.provider.isSurfaceWorld()) { + if (this.mc.gameSettings.shouldRenderClouds() == 2) { + this.renderCloudsFancy(partialTicks, pass, x, y, z); +@@ -1771,7 +1793,7 @@ + ); + GlStateManager.enableBlend(); + GlStateManager.color(1.0F, 1.0F, 1.0F, 0.5F); +- GlStateManager.doPolygonOffset(-3.0F, -3.0F); ++ GlStateManager.doPolygonOffset(-1.0F, -10.0F); // FORGE: Fix MC-234 + GlStateManager.enablePolygonOffset(); + GlStateManager.alphaFunc(516, 0.1F); + GlStateManager.enableAlpha(); +@@ -1806,7 +1828,13 @@ + double d4 = blockpos.getY() - d1; + double d5 = blockpos.getZ() - d2; + Block block = this.world.getBlockState(blockpos).getBlock(); +- if (!(block instanceof BlockChest) && !(block instanceof BlockEnderChest) && !(block instanceof BlockSign) && !(block instanceof BlockSkull)) { ++ TileEntity te = this.world.getTileEntity(blockpos); ++ boolean hasBreak = block instanceof BlockChest || block instanceof BlockEnderChest || block instanceof BlockSign || block instanceof BlockSkull; ++ if (!hasBreak) { ++ hasBreak = te != null && te.canRenderBreaking(); ++ } ++ ++ if (!hasBreak) { + if (d3 * d3 + d4 * d4 + d5 * d5 > 1024.0) { + iterator.remove(); + } else { +@@ -2035,11 +2063,13 @@ + int j = pos.getY(); + int k = pos.getZ(); + this.markBlocksForUpdate(i - 1, j - 1, k - 1, i + 1, j + 1, k + 1, (flags & 8) != 0); ++ com.cleanroommc.kirino.KirinoClientCore.RenderGlobal$notifyBlockUpdate(i, j, k, oldState, newState); + } + + @Override + public void notifyLightSet(BlockPos pos) { + this.setLightUpdates.add(pos.toImmutable()); ++ com.cleanroommc.kirino.KirinoClientCore.RenderGlobal$notifyLightUpdate(pos.getX(), pos.getY(), pos.getZ()); + } + + /** On the client, re-renders all blocks in this range, inclusive. On the server, does nothing. */ +@@ -2496,7 +2526,7 @@ + case 2001: + Block block = Block.getBlockById(data & 4095); + if (block.getDefaultState().getMaterial() != Material.AIR) { +- SoundType soundtype = block.getSoundType(); ++ SoundType soundtype = block.getSoundType(Block.getStateById(data), this.world, blockPosIn, null); + this.world + .playSound( + blockPosIn, diff --git a/module/minecraft/patches/net/minecraft/client/renderer/RenderItem.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/RenderItem.java.patch new file mode 100644 index 000000000..abedd8752 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/RenderItem.java.patch @@ -0,0 +1,126 @@ +--- original/net/minecraft/client/renderer/RenderItem.java ++++ modified/net/minecraft/client/renderer/RenderItem.java +@@ -70,7 +70,7 @@ + + public RenderItem(TextureManager p_i46552_1_, ModelManager p_i46552_2_, ItemColors p_i46552_3_) { + this.textureManager = p_i46552_1_; +- this.itemModelMesher = new ItemModelMesher(p_i46552_2_); ++ this.itemModelMesher = new net.minecraftforge.client.ItemModelMesherForge(p_i46552_2_); + this.registerItems(); + this.itemColors = p_i46552_3_; + } +@@ -104,6 +104,10 @@ + } + + private void renderModel(IBakedModel model, int color, ItemStack stack) { ++ if (net.minecraftforge.common.ForgeModContainer.allowEmissiveItems) { ++ net.minecraftforge.client.ForgeHooksClient.renderLitItem(this, model, color, stack); ++ return; ++ } + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder bufferbuilder = tessellator.getBuffer(); + bufferbuilder.begin(7, DefaultVertexFormats.ITEM); +@@ -123,7 +127,7 @@ + if (model.isBuiltInRenderer()) { + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + GlStateManager.enableRescaleNormal(); +- TileEntityItemStackRenderer.instance.renderByItem(stack); ++ stack.getItem().getTileEntityItemStackRenderer().renderByItem(stack); + } else { + this.renderModel(model, stack); + if (stack.hasEffect()) { +@@ -191,7 +195,7 @@ + k |= -16777216; + } + +- this.renderQuad(renderer, bakedquad, k); ++ net.minecraftforge.client.model.pipeline.LightUtil.renderQuadColor(renderer, bakedquad, k); + } + } + +@@ -209,15 +213,7 @@ + + public IBakedModel getItemModelWithOverrides(ItemStack stack, @Nullable World worldIn, @Nullable EntityLivingBase entitylivingbaseIn) { + IBakedModel ibakedmodel = this.itemModelMesher.getItemModel(stack); +- Item item = stack.getItem(); +- if (item != null && item.hasCustomProperties()) { +- ResourceLocation resourcelocation = ibakedmodel.getOverrides().applyOverride(stack, worldIn, entitylivingbaseIn); +- return resourcelocation == null +- ? ibakedmodel +- : this.itemModelMesher.getModelManager().getModel(new ModelResourceLocation(resourcelocation, "inventory")); +- } else { +- return ibakedmodel; +- } ++ return ibakedmodel.getOverrides().handleItemState(ibakedmodel, stack, worldIn, entitylivingbaseIn); + } + + public void renderItem(ItemStack stack, EntityLivingBase entitylivingbaseIn, ItemCameraTransforms.TransformType transform, boolean leftHanded) { +@@ -242,11 +238,8 @@ + GlStateManager.DestFactor.ZERO + ); + GlStateManager.pushMatrix(); +- ItemCameraTransforms itemcameratransforms = bakedmodel.getItemCameraTransforms(); +- ItemCameraTransforms.applyTransformSide(itemcameratransforms.getTransform(transform), leftHanded); +- if (this.isThereOneNegativeScale(itemcameratransforms.getTransform(transform))) { +- GlStateManager.cullFace(GlStateManager.CullFace.FRONT); +- } ++ // TODO: check if negative scale is a thing ++ bakedmodel = net.minecraftforge.client.ForgeHooksClient.handleCameraTransforms(bakedmodel, transform, leftHanded); + + this.renderItem(stack, bakedmodel); + GlStateManager.cullFace(GlStateManager.CullFace.BACK); +@@ -278,7 +271,7 @@ + GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + this.setupGuiTransform(x, y, bakedmodel.isGui3d()); +- bakedmodel.getItemCameraTransforms().applyTransform(ItemCameraTransforms.TransformType.GUI); ++ bakedmodel = net.minecraftforge.client.ForgeHooksClient.handleCameraTransforms(bakedmodel, ItemCameraTransforms.TransformType.GUI, false); + this.renderItem(stack, bakedmodel); + GlStateManager.disableAlpha(); + GlStateManager.disableRescaleNormal(); +@@ -318,6 +311,7 @@ + return String.valueOf(p_184391_2_.getItem()); + } + }); ++ crashreportcategory.addDetail("Registry Name", () -> String.valueOf(p_184391_2_.getItem().getRegistryName())); + crashreportcategory.addDetail("Item Aux", new ICrashReportDetail() { + public String call() throws Exception { + return String.valueOf(p_184391_2_.getMetadata()); +@@ -355,9 +349,12 @@ + fr.drawStringWithShadow(s, xPosition + 19 - 2 - fr.getStringWidth(s), yPosition + 6 + 3, 16777215); + GlStateManager.enableLighting(); + GlStateManager.enableDepth(); ++ // Fixes opaque cooldown overlay a bit lower ++ // TODO: check if enabled blending still screws things up down the line. ++ GlStateManager.enableBlend(); + } + +- if (stack.isItemDamaged()) { ++ if (stack.getItem().showDurabilityBar(stack)) { + GlStateManager.disableLighting(); + GlStateManager.disableDepth(); + GlStateManager.disableTexture2D(); +@@ -365,11 +362,10 @@ + GlStateManager.disableBlend(); + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder bufferbuilder = tessellator.getBuffer(); +- float f = stack.getItemDamage(); +- float f1 = stack.getMaxDamage(); +- float f2 = Math.max(0.0F, (f1 - f) / f1); +- int i = Math.round(13.0F - f * 13.0F / f1); +- int j = MathHelper.hsvToRGB(f2 / 3.0F, 1.0F, 1.0F); ++ double health = stack.getItem().getDurabilityForDisplay(stack); ++ int rgbfordisplay = stack.getItem().getRGBDurabilityForDisplay(stack); ++ int i = Math.round(13.0F - (float)health * 13.0F); ++ int j = rgbfordisplay; + this.draw(bufferbuilder, xPosition + 2, yPosition + 13, 13, 2, 0, 0, 0, 255); + this.draw(bufferbuilder, xPosition + 2, yPosition + 13, i, 1, j >> 16 & 0xFF, j >> 8 & 0xFF, j & 0xFF, 255); + GlStateManager.enableBlend(); +@@ -1058,6 +1054,7 @@ + this.registerBlock(Blocks.STRUCTURE_BLOCK, TileEntityStructure.Mode.LOAD.getModeId(), "structure_block"); + this.registerBlock(Blocks.STRUCTURE_BLOCK, TileEntityStructure.Mode.CORNER.getModeId(), "structure_block"); + this.registerBlock(Blocks.STRUCTURE_BLOCK, TileEntityStructure.Mode.DATA.getModeId(), "structure_block"); ++ net.minecraftforge.client.model.ModelLoader.onRegisterItems(this.itemModelMesher); + } + + @Override diff --git a/module/minecraft/patches/net/minecraft/client/renderer/WorldVertexBufferUploader.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/WorldVertexBufferUploader.java.patch new file mode 100644 index 000000000..ee62a7428 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/WorldVertexBufferUploader.java.patch @@ -0,0 +1,57 @@ +--- original/net/minecraft/client/renderer/WorldVertexBufferUploader.java ++++ modified/net/minecraft/client/renderer/WorldVertexBufferUploader.java +@@ -23,25 +23,9 @@ + int k = vertexformatelement.getType().getGlConstant(); + int l = vertexformatelement.getIndex(); + ((Buffer)bytebuffer).position(vertexformat.getOffset(j)); +- switch (vertexformatelement$enumusage) { +- case POSITION: +- GlStateManager.glVertexPointer(vertexformatelement.getElementCount(), k, i, bytebuffer); +- GlStateManager.glEnableClientState(32884); +- break; +- case UV: +- OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit + l); +- GlStateManager.glTexCoordPointer(vertexformatelement.getElementCount(), k, i, bytebuffer); +- GlStateManager.glEnableClientState(32888); +- OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit); +- break; +- case COLOR: +- GlStateManager.glColorPointer(vertexformatelement.getElementCount(), k, i, bytebuffer); +- GlStateManager.glEnableClientState(32886); +- break; +- case NORMAL: +- GlStateManager.glNormalPointer(k, i, bytebuffer); +- GlStateManager.glEnableClientState(32885); +- } ++ ++ // moved to VertexFormatElement.preDraw ++ vertexformatelement.getUsage().preDraw(vertexformat, j, i, bytebuffer); + } + + GlStateManager.glDrawArrays(bufferBuilderIn.getDrawMode(), 0, bufferBuilderIn.getVertexCount()); +@@ -51,22 +35,9 @@ + VertexFormatElement vertexformatelement1 = list.get(i1); + VertexFormatElement.EnumUsage vertexformatelement$enumusage1 = vertexformatelement1.getUsage(); + int k1 = vertexformatelement1.getIndex(); +- switch (vertexformatelement$enumusage1) { +- case POSITION: +- GlStateManager.glDisableClientState(32884); +- break; +- case UV: +- OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit + k1); +- GlStateManager.glDisableClientState(32888); +- OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit); +- break; +- case COLOR: +- GlStateManager.glDisableClientState(32886); +- GlStateManager.resetColor(); +- break; +- case NORMAL: +- GlStateManager.glDisableClientState(32885); +- } ++ ++ // moved to VertexFormatElement.postDraw ++ vertexformatelement1.getUsage().postDraw(vertexformat, i1, i, bytebuffer); + } + } + diff --git a/module/minecraft/patches/net/minecraft/client/renderer/block/model/BakedQuad.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/block/model/BakedQuad.java.patch new file mode 100644 index 000000000..904e19dc4 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/block/model/BakedQuad.java.patch @@ -0,0 +1,49 @@ +--- original/net/minecraft/client/renderer/block/model/BakedQuad.java ++++ modified/net/minecraft/client/renderer/block/model/BakedQuad.java +@@ -6,14 +6,23 @@ + import net.minecraftforge.fml.relauncher.SideOnly; + + @SideOnly(Side.CLIENT) +-public class BakedQuad { +- /** Joined 4 vertex records, each stores packed data according to the VertexFormat of the quad. Vanilla minecraft uses DefaultVertexFormats.BLOCK, Forge uses (usually) ITEM, use BakedQuad.getFormat() to get the correct format. */ ++public class BakedQuad implements net.minecraftforge.client.model.pipeline.IVertexProducer { + protected final int[] vertexData; + protected final int tintIndex; + protected final EnumFacing face; + protected final TextureAtlasSprite sprite; + ++ /** ++ * @deprecated Use constructor with the format argument. ++ */ ++ @Deprecated + public BakedQuad(int[] vertexDataIn, int tintIndexIn, EnumFacing faceIn, TextureAtlasSprite spriteIn) { ++ this(vertexDataIn, tintIndexIn, faceIn, spriteIn, true, net.minecraft.client.renderer.vertex.DefaultVertexFormats.ITEM); ++ } ++ ++ public BakedQuad(int[] vertexDataIn, int tintIndexIn, EnumFacing faceIn, TextureAtlasSprite spriteIn, boolean applyDiffuseLighting, net.minecraft.client.renderer.vertex.VertexFormat format) { ++ this.format = format; ++ this.applyDiffuseLighting = applyDiffuseLighting; + this.vertexData = vertexDataIn; + this.tintIndex = tintIndexIn; + this.face = faceIn; +@@ -39,4 +48,20 @@ + public EnumFacing getFace() { + return this.face; + } ++ ++ protected final net.minecraft.client.renderer.vertex.VertexFormat format; ++ protected final boolean applyDiffuseLighting; ++ ++ @Override ++ public void pipe(net.minecraftforge.client.model.pipeline.IVertexConsumer consumer) { ++ net.minecraftforge.client.model.pipeline.LightUtil.putBakedQuad(consumer, this); ++ } ++ ++ public net.minecraft.client.renderer.vertex.VertexFormat getFormat() { ++ return format; ++ } ++ ++ public boolean shouldApplyDiffuseLighting() { ++ return applyDiffuseLighting; ++ } + } diff --git a/module/minecraft/patches/net/minecraft/client/renderer/block/model/BakedQuadRetextured.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/block/model/BakedQuadRetextured.java.patch new file mode 100644 index 000000000..b21043674 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/block/model/BakedQuadRetextured.java.patch @@ -0,0 +1,40 @@ +--- original/net/minecraft/client/renderer/block/model/BakedQuadRetextured.java ++++ modified/net/minecraft/client/renderer/block/model/BakedQuadRetextured.java +@@ -14,7 +14,9 @@ + Arrays.copyOf(quad.getVertexData(), quad.getVertexData().length), + quad.tintIndex, + FaceBakery.getFacingFromVertexData(quad.getVertexData()), +- quad.getSprite() ++ quad.getSprite(), ++ quad.applyDiffuseLighting, ++ quad.format + ); + this.texture = textureIn; + this.remapQuad(); +@@ -22,13 +24,19 @@ + + private void remapQuad() { + for (int i = 0; i < 4; i++) { +- int j = 7 * i; +- this.vertexData[j + 4] = Float.floatToRawIntBits( +- this.texture.getInterpolatedU(this.sprite.getUnInterpolatedU(Float.intBitsToFloat(this.vertexData[j + 4]))) +- ); +- this.vertexData[j + 4 + 1] = Float.floatToRawIntBits( +- this.texture.getInterpolatedV(this.sprite.getUnInterpolatedV(Float.intBitsToFloat(this.vertexData[j + 4 + 1]))) +- ); ++ int j = format.getIntegerSize() * i; ++ int uvIndex = format.getUvOffsetById(0) / 4; ++ this.vertexData[j + uvIndex] = Float.floatToRawIntBits( ++ this.texture.getInterpolatedU(this.sprite.getUnInterpolatedU(Float.intBitsToFloat(this.vertexData[j + uvIndex]))) ++ ); ++ this.vertexData[j + uvIndex + 1] = Float.floatToRawIntBits( ++ this.texture.getInterpolatedV(this.sprite.getUnInterpolatedV(Float.intBitsToFloat(this.vertexData[j + uvIndex + 1]))) ++ ); + } + } ++ ++ @Override ++ public TextureAtlasSprite getSprite() { ++ return texture; ++ } + } diff --git a/module/minecraft/patches/net/minecraft/client/renderer/block/model/FaceBakery.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/block/model/FaceBakery.java.patch new file mode 100644 index 000000000..7551b2609 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/block/model/FaceBakery.java.patch @@ -0,0 +1,142 @@ +--- original/net/minecraft/client/renderer/block/model/FaceBakery.java ++++ modified/net/minecraft/client/renderer/block/model/FaceBakery.java +@@ -53,20 +53,45 @@ + boolean uvLocked, + boolean shade + ) { ++ return makeBakedQuad( ++ posFrom, ++ posTo, ++ face, ++ sprite, ++ facing, ++ (net.minecraftforge.common.model.ITransformation)modelRotationIn, ++ partRotation, ++ uvLocked, ++ shade ++ ); ++ } ++ ++ public BakedQuad makeBakedQuad( ++ Vector3f posFrom, ++ Vector3f posTo, ++ BlockPartFace face, ++ TextureAtlasSprite sprite, ++ EnumFacing facing, ++ net.minecraftforge.common.model.ITransformation modelRotationIn, ++ BlockPartRotation partRotation, ++ boolean uvLocked, ++ boolean shade ++ ) { + BlockFaceUV blockfaceuv = face.blockFaceUV; + if (uvLocked) { +- blockfaceuv = this.applyUVLock(face.blockFaceUV, facing, modelRotationIn); ++ blockfaceuv = net.minecraftforge.client.ForgeHooksClient.applyUVLock(face.blockFaceUV, facing, modelRotationIn); + } + + int[] aint = this.makeQuadVertexData( +- blockfaceuv, sprite, facing, this.getPositionsDiv16(posFrom, posTo), modelRotationIn, partRotation, shade +- ); ++ blockfaceuv, sprite, facing, this.getPositionsDiv16(posFrom, posTo), modelRotationIn, partRotation, false ++ ); + EnumFacing enumfacing = getFacingFromVertexData(aint); + if (partRotation == null) { + this.applyFacing(aint, enumfacing); + } + +- return new BakedQuad(aint, face.tintIndex, enumfacing, sprite); ++ net.minecraftforge.client.ForgeHooksClient.fillNormal(aint, enumfacing); ++ return new BakedQuad(aint, face.tintIndex, enumfacing, sprite, shade, net.minecraft.client.renderer.vertex.DefaultVertexFormats.ITEM); + } + + private BlockFaceUV applyUVLock(BlockFaceUV p_188010_1_, EnumFacing p_188010_2_, ModelRotation p_188010_3_) { +@@ -82,6 +107,26 @@ + @Nullable BlockPartRotation partRotation, + boolean shade + ) { ++ return makeQuadVertexData( ++ uvs, ++ sprite, ++ orientation, ++ p_188012_4_, ++ (net.minecraftforge.common.model.ITransformation)rotationIn, ++ partRotation, ++ shade ++ ); ++ } ++ ++ private int[] makeQuadVertexData( ++ BlockFaceUV uvs, ++ TextureAtlasSprite sprite, ++ EnumFacing orientation, ++ float[] p_188012_4_, ++ net.minecraftforge.common.model.ITransformation rotationIn, ++ BlockPartRotation partRotation, ++ boolean shade ++ ) { + int[] aint = new int[28]; + + for (int i = 0; i < 4; i++) { +@@ -136,7 +181,31 @@ + @Nullable BlockPartRotation p_188015_8_, + boolean p_188015_9_ + ) { +- EnumFacing enumfacing = p_188015_7_.rotateFace(p_188015_3_); ++ fillVertexData( ++ p_188015_1_, ++ p_188015_2_, ++ p_188015_3_, ++ p_188015_4_, ++ p_188015_5_, ++ p_188015_6_, ++ (net.minecraftforge.common.model.ITransformation)p_188015_7_, ++ p_188015_8_, ++ p_188015_9_ ++ ); ++ } ++ ++ private void fillVertexData( ++ int[] p_188015_1_, ++ int p_188015_2_, ++ EnumFacing p_188015_3_, ++ BlockFaceUV p_188015_4_, ++ float[] p_188015_5_, ++ TextureAtlasSprite p_188015_6_, ++ net.minecraftforge.common.model.ITransformation p_188015_7_, ++ BlockPartRotation p_188015_8_, ++ boolean p_188015_9_ ++ ) { ++ EnumFacing enumfacing = p_188015_7_.rotate(p_188015_3_); + int i = p_188015_9_ ? this.getFaceShadeColor(enumfacing) : -1; + EnumFaceDirection.VertexInformation enumfacedirection$vertexinformation = EnumFaceDirection.getFacing(p_188015_3_).getVertexInformation(p_188015_2_); + Vector3f vector3f = new Vector3f( +@@ -157,8 +226,8 @@ + faceData[i + 1] = Float.floatToRawIntBits(position.y); + faceData[i + 2] = Float.floatToRawIntBits(position.z); + faceData[i + 3] = shadeColor; +- faceData[i + 4] = Float.floatToRawIntBits(sprite.getInterpolatedU(faceUV.getVertexU(vertexIndex))); +- faceData[i + 4 + 1] = Float.floatToRawIntBits(sprite.getInterpolatedV(faceUV.getVertexV(vertexIndex))); ++ faceData[i + 4] = Float.floatToRawIntBits(sprite.getInterpolatedU(faceUV.getVertexU(vertexIndex) * .999 + faceUV.getVertexU((vertexIndex + 2) % 4) * .001)); ++ faceData[i + 4 + 1] = Float.floatToRawIntBits(sprite.getInterpolatedV(faceUV.getVertexV(vertexIndex) * .999 + faceUV.getVertexV((vertexIndex + 2) % 4) * .001)); + } + + private void rotatePart(Vector3f p_178407_1_, @Nullable BlockPartRotation partRotation) { +@@ -196,12 +265,16 @@ + } + + public int rotateVertex(Vector3f p_188011_1_, EnumFacing p_188011_2_, int p_188011_3_, ModelRotation p_188011_4_) { ++ return rotateVertex(p_188011_1_, p_188011_2_, p_188011_3_, (net.minecraftforge.common.model.ITransformation)p_188011_4_); ++ } ++ ++ public int rotateVertex(Vector3f p_188011_1_, EnumFacing p_188011_2_, int p_188011_3_, net.minecraftforge.common.model.ITransformation p_188011_4_) { + if (p_188011_4_ == ModelRotation.X0_Y0) { + return p_188011_3_; + } + +- this.rotateScale(p_188011_1_, new Vector3f(0.5F, 0.5F, 0.5F), p_188011_4_.matrix(), new Vector3f(1.0F, 1.0F, 1.0F)); +- return p_188011_4_.rotateVertex(p_188011_2_, p_188011_3_); ++ net.minecraftforge.client.ForgeHooksClient.transform(p_188011_1_, p_188011_4_.getMatrix()); ++ return p_188011_4_.rotate(p_188011_2_, p_188011_3_); + } + + private void rotateScale(Vector3f position, Vector3f rotationOrigin, Matrix4f rotationMatrix, Vector3f scale) { diff --git a/module/minecraft/patches/net/minecraft/client/renderer/block/model/IBakedModel.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/block/model/IBakedModel.java.patch new file mode 100644 index 000000000..0f9c849a6 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/block/model/IBakedModel.java.patch @@ -0,0 +1,22 @@ +--- original/net/minecraft/client/renderer/block/model/IBakedModel.java ++++ modified/net/minecraft/client/renderer/block/model/IBakedModel.java +@@ -20,7 +20,18 @@ + + TextureAtlasSprite getParticleTexture(); + +- ItemCameraTransforms getItemCameraTransforms(); ++ @Deprecated ++ default ItemCameraTransforms getItemCameraTransforms() { return ItemCameraTransforms.DEFAULT; } + + ItemOverrideList getOverrides(); ++ ++ default boolean isAmbientOcclusion(IBlockState state) { return isAmbientOcclusion(); } ++ ++ /* ++ * Returns the pair of the model for the given perspective, and the matrix ++ * that should be applied to the GL state before rendering it (matrix may be null). ++ */ ++ default org.apache.commons.lang3.tuple.Pair handlePerspective(ItemCameraTransforms.TransformType cameraTransformType) { ++ return net.minecraftforge.client.ForgeHooksClient.handlePerspective(this, cameraTransformType); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/client/renderer/block/model/ItemCameraTransforms.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/block/model/ItemCameraTransforms.java.patch new file mode 100644 index 000000000..31866703e --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/block/model/ItemCameraTransforms.java.patch @@ -0,0 +1,45 @@ +--- original/net/minecraft/client/renderer/block/model/ItemCameraTransforms.java ++++ modified/net/minecraft/client/renderer/block/model/ItemCameraTransforms.java +@@ -12,6 +12,9 @@ + import net.minecraftforge.fml.relauncher.SideOnly; + import org.lwjgl.util.vector.Quaternion; + ++/* ++ * @deprecated use {@link net.minecraftforge.client.model.IPerspectiveAwareModel} instead ++ */ + @SideOnly(Side.CLIENT) + public class ItemCameraTransforms { + public static final ItemCameraTransforms DEFAULT = new ItemCameraTransforms(); +@@ -46,6 +49,7 @@ + ); + } + ++ @Deprecated + public ItemCameraTransforms(ItemCameraTransforms transforms) { + this.thirdperson_left = transforms.thirdperson_left; + this.thirdperson_right = transforms.thirdperson_right; +@@ -57,6 +61,7 @@ + this.fixed = transforms.fixed; + } + ++ @Deprecated + public ItemCameraTransforms( + ItemTransformVec3f thirdperson_leftIn, + ItemTransformVec3f thirdperson_rightIn, +@@ -117,6 +122,7 @@ + return new Quaternion(f3 * f6 * f8 + f4 * f5 * f7, f4 * f5 * f8 - f3 * f6 * f7, f3 * f5 * f8 + f4 * f6 * f7, f4 * f6 * f8 - f3 * f5 * f7); + } + ++ @Deprecated + public ItemTransformVec3f getTransform(ItemCameraTransforms.TransformType type) { + switch (type) { + case THIRD_PERSON_LEFT_HAND: +@@ -184,7 +190,7 @@ + } + + @SideOnly(Side.CLIENT) +- public enum TransformType { ++ public enum TransformType implements net.minecraftforge.common.model.IModelPart { + NONE, + THIRD_PERSON_LEFT_HAND, + THIRD_PERSON_RIGHT_HAND, diff --git a/module/minecraft/patches/net/minecraft/client/renderer/block/model/ItemOverrideList.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/block/model/ItemOverrideList.java.patch new file mode 100644 index 000000000..ba08b43df --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/block/model/ItemOverrideList.java.patch @@ -0,0 +1,29 @@ +--- original/net/minecraft/client/renderer/block/model/ItemOverrideList.java ++++ modified/net/minecraft/client/renderer/block/model/ItemOverrideList.java +@@ -25,6 +25,7 @@ + } + + @Nullable ++ @Deprecated + public ResourceLocation applyOverride(ItemStack stack, @Nullable World worldIn, @Nullable EntityLivingBase entityIn) { + if (!this.overrides.isEmpty()) { + for (ItemOverride itemoverride : this.overrides) { +@@ -36,4 +37,18 @@ + + return null; + } ++ ++ public IBakedModel handleItemState(IBakedModel originalModel, ItemStack stack, @Nullable World world, @Nullable EntityLivingBase entity) { ++ if (!stack.isEmpty() && stack.getItem().hasCustomProperties()) { ++ ResourceLocation location = applyOverride(stack, world, entity); ++ if (location != null) { ++ return net.minecraft.client.Minecraft.getMinecraft().getRenderItem().getItemModelMesher().getModelManager().getModel(net.minecraftforge.client.model.ModelLoader.getInventoryVariant(location.toString())); ++ } ++ } ++ return originalModel; ++ } ++ ++ public com.google.common.collect.ImmutableList getOverrides() { ++ return com.google.common.collect.ImmutableList.copyOf(overrides); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/client/renderer/block/model/ItemTransformVec3f.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/block/model/ItemTransformVec3f.java.patch new file mode 100644 index 000000000..f69244ca2 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/block/model/ItemTransformVec3f.java.patch @@ -0,0 +1,17 @@ +--- original/net/minecraft/client/renderer/block/model/ItemTransformVec3f.java ++++ modified/net/minecraft/client/renderer/block/model/ItemTransformVec3f.java +@@ -13,8 +13,13 @@ + import net.minecraftforge.fml.relauncher.SideOnly; + import org.lwjgl.util.vector.Vector3f; + ++/* ++ * @deprecated use {@link net.minecraftforge.client.model.IModelState} and {@link net.minecraftforge.client.model.TRSRTransformation} ++ */ + @SideOnly(Side.CLIENT) +-public class ItemTransformVec3f { ++@Deprecated ++public class ItemTransformVec3f implements net.minecraftforge.common.model.IModelState { ++ public java.util.Optional apply(java.util.Optional part) { return net.minecraftforge.client.ForgeHooksClient.applyTransform(this, part); } + public static final ItemTransformVec3f DEFAULT = new ItemTransformVec3f(new Vector3f(), new Vector3f(), new Vector3f(1.0F, 1.0F, 1.0F)); + public final Vector3f rotation; + public final Vector3f translation; diff --git a/module/minecraft/patches/net/minecraft/client/renderer/block/model/ModelBakery.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/block/model/ModelBakery.java.patch new file mode 100644 index 000000000..0c47cf73f --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/block/model/ModelBakery.java.patch @@ -0,0 +1,173 @@ +--- original/net/minecraft/client/renderer/block/model/ModelBakery.java ++++ modified/net/minecraft/client/renderer/block/model/ModelBakery.java +@@ -134,6 +134,18 @@ + for (Block block : Block.REGISTRY) { + for (final ResourceLocation resourcelocation : blockstatemapper.getBlockstateLocations(block)) { + try { ++ loadBlock(blockstatemapper, block, resourcelocation); ++ } catch (Exception exception) { ++ LOGGER.warn((String)("Unable to load definition " + resourcelocation), (Throwable)exception); ++ } ++ } ++ } ++ } ++ ++ protected void loadBlock(BlockStateMapper blockstatemapper, Block block, final ResourceLocation resourcelocation) { ++ { ++ { ++ { + ModelBlockDefinition modelblockdefinition = this.getModelBlockDefinition(resourcelocation); + Map map = blockstatemapper.getVariants(block); + if (modelblockdefinition.hasMultipartData()) { +@@ -142,7 +154,6 @@ + Collection collection1 = this.multipartVariantMap.get(modelblockdefinition); + if (collection1 == null) { + collection1 = Lists.newArrayList(); +- this.multipartVariantMap.put(modelblockdefinition, collection1); + } + + collection1.addAll(Lists.newArrayList(Iterables.filter(collection, new Predicate() { +@@ -150,22 +161,21 @@ + return resourcelocation.equals(p_apply_1_); + } + }))); ++ registerMultipartVariant(modelblockdefinition, collection1); + } + + for (Entry entry : map.entrySet()) { + ModelResourceLocation modelresourcelocation = entry.getValue(); + if (resourcelocation.equals(modelresourcelocation)) { + try { +- this.variants.put(modelresourcelocation, modelblockdefinition.getVariant(modelresourcelocation.getVariant())); ++ registerVariant(modelblockdefinition, modelresourcelocation); + } catch (RuntimeException runtimeexception) { + if (!modelblockdefinition.hasMultipartData()) { +- LOGGER.warn("Unable to load variant: {} from {}", modelresourcelocation.getVariant(), modelresourcelocation); ++ LOGGER.warn("Unable to load variant: " + modelresourcelocation.getVariant() + " from " + modelresourcelocation, runtimeexception); + } + } + } + } +- } catch (Exception exception) { +- LOGGER.warn("Unable to load definition {}", resourcelocation, exception); + } + } + } +@@ -230,7 +240,7 @@ + + try { + inputstream = resource.getInputStream(); +- return ModelBlockDefinition.parseFromReader(new InputStreamReader(inputstream, StandardCharsets.UTF_8)); ++ return ModelBlockDefinition.parseFromReader(new InputStreamReader(inputstream, StandardCharsets.UTF_8), location); + } catch (Exception exception) { + throw new RuntimeException( + "Encountered an exception when loading model definition of '" +@@ -353,6 +363,7 @@ + } + + protected void registerVariantNames() { ++ this.variantNames.clear(); // FML clear this to prevent double ups. + this.variantNames + .put( + Item.getItemFromBlock(Blocks.STONE), +@@ -609,6 +620,9 @@ + this.variantNames.put(Items.OAK_DOOR, Lists.newArrayList("oak_door")); + this.variantNames.put(Items.BOAT, Lists.newArrayList("oak_boat")); + this.variantNames.put(Items.TOTEM_OF_UNDYING, Lists.newArrayList("totem")); ++ for (Entry, Set> e : customVariantNames.entrySet()) { ++ this.variantNames.put(e.getKey().get(), Lists.newArrayList(e.getValue().iterator())); ++ } + } + + protected List getVariantNames(Item stack) { +@@ -621,7 +635,7 @@ + } + + protected ResourceLocation getItemLocation(String location) { +- ResourceLocation resourcelocation = new ResourceLocation(location); ++ ResourceLocation resourcelocation = new ResourceLocation(location.replaceAll("#.*", "")); + return new ResourceLocation(resourcelocation.getNamespace(), "item/" + resourcelocation.getPath()); + } + +@@ -695,7 +709,7 @@ + private void bakeItemModels() { + for (Entry entry : this.itemLocations.entrySet()) { + ResourceLocation resourcelocation = entry.getValue(); +- ModelResourceLocation modelresourcelocation = new ModelResourceLocation(entry.getKey(), "inventory"); ++ ModelResourceLocation modelresourcelocation = net.minecraftforge.client.model.ModelLoader.getInventoryVariant(entry.getKey()); + ModelBlock modelblock = this.models.get(resourcelocation); + if (modelblock == null || !modelblock.isResolved()) { + LOGGER.warn("Missing model for: {}", resourcelocation); +@@ -755,6 +769,10 @@ + + @Nullable + private IBakedModel bakeModel(ModelBlock modelBlockIn, ModelRotation modelRotationIn, boolean uvLocked) { ++ return bakeModel(modelBlockIn, (net.minecraftforge.common.model.ITransformation)modelRotationIn, uvLocked); ++ } ++ ++ protected IBakedModel bakeModel(ModelBlock modelBlockIn, net.minecraftforge.common.model.ITransformation modelRotationIn, boolean uvLocked) { + TextureAtlasSprite textureatlassprite = this.sprites.get(new ResourceLocation(modelBlockIn.resolveTextureName("particle"))); + SimpleBakedModel.Builder simplebakedmodel$builder = new SimpleBakedModel.Builder(modelBlockIn, modelBlockIn.createOverrides()) + .setTexture(textureatlassprite); +@@ -766,13 +784,13 @@ + for (EnumFacing enumfacing : blockpart.mapFaces.keySet()) { + BlockPartFace blockpartface = blockpart.mapFaces.get(enumfacing); + TextureAtlasSprite textureatlassprite1 = this.sprites.get(new ResourceLocation(modelBlockIn.resolveTextureName(blockpartface.texture))); +- if (blockpartface.cullFace == null) { ++ if (blockpartface.cullFace == null || !net.minecraftforge.common.model.TRSRTransformation.isInteger(modelRotationIn.getMatrix())) { + simplebakedmodel$builder.addGeneralQuad( + this.makeBakedQuad(blockpart, blockpartface, textureatlassprite1, enumfacing, modelRotationIn, uvLocked) + ); + } else { + simplebakedmodel$builder.addFaceQuad( +- modelRotationIn.rotateFace(blockpartface.cullFace), ++ modelRotationIn.rotate(blockpartface.cullFace), + this.makeBakedQuad(blockpart, blockpartface, textureatlassprite1, enumfacing, modelRotationIn, uvLocked) + ); + } +@@ -790,20 +808,13 @@ + ModelRotation transform, + boolean uvLocked + ) { +- return this.faceBakery +- .makeBakedQuad( +- blockPartt.positionFrom, +- blockPartt.positionTo, +- blockPartFaceIn, +- sprite, +- face, +- transform, +- blockPartt.partRotation, +- uvLocked, +- blockPartt.shade +- ); ++ return makeBakedQuad(blockPartt, blockPartFaceIn, sprite, face, (net.minecraftforge.common.model.ITransformation)transform, uvLocked); + } + ++ protected BakedQuad makeBakedQuad(BlockPart blockPartt, BlockPartFace blockPartFaceIn, TextureAtlasSprite sprite, EnumFacing face, net.minecraftforge.common.model.ITransformation transform, boolean uvLocked) { ++ return this.faceBakery.makeBakedQuad(blockPartt.positionFrom, blockPartt.positionTo, blockPartFaceIn, sprite, face, transform, blockPartt.partRotation, uvLocked, blockPartt.shade); ++ } ++ + private void loadModelsCheck() { + this.loadModels(); + +@@ -974,4 +985,19 @@ + MODEL_GENERATED.name = "generation marker"; + MODEL_ENTITY.name = "block entity marker"; + } ++ ++ protected void registerMultipartVariant(ModelBlockDefinition definition, Collection locations) { ++ this.multipartVariantMap.put(definition, locations); ++ } ++ ++ private static Map, Set> customVariantNames = Maps.newHashMap(); ++ ++ public static void registerItemVariants(Item item, ResourceLocation... names) { ++ if (!customVariantNames.containsKey(item.delegate)) { ++ customVariantNames.put(item.delegate, Sets.newHashSet()); ++ } ++ for(ResourceLocation name : names) { ++ customVariantNames.get(item.delegate).add(name.toString()); ++ } ++ } + } diff --git a/module/minecraft/patches/net/minecraft/client/renderer/block/model/ModelBlockDefinition.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/block/model/ModelBlockDefinition.java.patch new file mode 100644 index 000000000..b1090685d --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/block/model/ModelBlockDefinition.java.patch @@ -0,0 +1,17 @@ +--- original/net/minecraft/client/renderer/block/model/ModelBlockDefinition.java ++++ modified/net/minecraft/client/renderer/block/model/ModelBlockDefinition.java +@@ -38,9 +38,13 @@ + private Multipart multipart; + + public static ModelBlockDefinition parseFromReader(Reader reader) { +- return JsonUtils.fromJson(GSON, reader, ModelBlockDefinition.class); ++ return parseFromReader(reader, null); + } + ++ public static ModelBlockDefinition parseFromReader(Reader reader, net.minecraft.util.ResourceLocation location) { ++ return net.minecraftforge.client.model.BlockStateLoader.load(reader, location, GSON); ++ } ++ + public ModelBlockDefinition(Map variants, Multipart multipartIn) { + this.multipart = multipartIn; + this.mapVariants.putAll(variants); diff --git a/module/minecraft/patches/net/minecraft/client/renderer/block/model/ModelManager.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/block/model/ModelManager.java.patch new file mode 100644 index 000000000..157a18480 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/block/model/ModelManager.java.patch @@ -0,0 +1,14 @@ +--- original/net/minecraft/client/renderer/block/model/ModelManager.java ++++ modified/net/minecraft/client/renderer/block/model/ModelManager.java +@@ -22,9 +22,10 @@ + + @Override + public void onResourceManagerReload(IResourceManager resourceManager) { +- ModelBakery modelbakery = new ModelBakery(resourceManager, this.texMap, this.modelProvider); ++ net.minecraftforge.client.model.ModelLoader modelbakery = new net.minecraftforge.client.model.ModelLoader(resourceManager, this.texMap, this.modelProvider); + this.modelRegistry = modelbakery.setupModelRegistry(); + this.defaultModel = this.modelRegistry.getObject(ModelBakery.MODEL_MISSING); ++ net.minecraftforge.client.ForgeHooksClient.onModelBake(this, this.modelRegistry, modelbakery); + this.modelProvider.reloadModels(); + } + diff --git a/module/minecraft/patches/net/minecraft/client/renderer/block/model/ModelResourceLocation.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/block/model/ModelResourceLocation.java.patch new file mode 100644 index 000000000..85b738e85 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/block/model/ModelResourceLocation.java.patch @@ -0,0 +1,14 @@ +--- original/net/minecraft/client/renderer/block/model/ModelResourceLocation.java ++++ modified/net/minecraft/client/renderer/block/model/ModelResourceLocation.java +@@ -2,11 +2,8 @@ + + import java.util.Locale; + import net.minecraft.util.ResourceLocation; +-import net.minecraftforge.fml.relauncher.Side; +-import net.minecraftforge.fml.relauncher.SideOnly; + import org.apache.commons.lang3.StringUtils; + +-@SideOnly(Side.CLIENT) + public class ModelResourceLocation extends ResourceLocation { + private final String variant; + diff --git a/module/minecraft/patches/net/minecraft/client/renderer/block/model/ModelRotation.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/block/model/ModelRotation.java.patch new file mode 100644 index 000000000..bca1a03d9 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/block/model/ModelRotation.java.patch @@ -0,0 +1,21 @@ +--- original/net/minecraft/client/renderer/block/model/ModelRotation.java ++++ modified/net/minecraft/client/renderer/block/model/ModelRotation.java +@@ -10,7 +10,7 @@ + import org.lwjgl.util.vector.Vector3f; + + @SideOnly(Side.CLIENT) +-public enum ModelRotation { ++public enum ModelRotation implements net.minecraftforge.common.model.IModelState, net.minecraftforge.common.model.ITransformation { + X0_Y0(0, 0), + X0_Y90(0, 90), + X0_Y180(0, 180), +@@ -100,4 +100,9 @@ + MAP_ROTATIONS.put(modelrotation.combinedXY, modelrotation); + } + } ++ ++ public java.util.Optional apply(java.util.Optional part) { return net.minecraftforge.client.ForgeHooksClient.applyTransform(this, part); } ++ public javax.vecmath.Matrix4f getMatrix() { return net.minecraftforge.common.model.TRSRTransformation.from(this).getMatrix(); } ++ public EnumFacing rotate(EnumFacing facing) { return rotateFace(facing); } ++ public int rotate(EnumFacing facing, int vertexIndex) { return rotateVertex(facing, vertexIndex); } + } diff --git a/module/minecraft/patches/net/minecraft/client/renderer/block/model/SimpleBakedModel.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/block/model/SimpleBakedModel.java.patch new file mode 100644 index 000000000..7bd378467 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/block/model/SimpleBakedModel.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/client/renderer/block/model/SimpleBakedModel.java ++++ modified/net/minecraft/client/renderer/block/model/SimpleBakedModel.java +@@ -91,7 +91,7 @@ + } + + public Builder(IBlockState state, IBakedModel model, TextureAtlasSprite texture, BlockPos pos) { +- this(model.isAmbientOcclusion(), model.isGui3d(), model.getItemCameraTransforms(), model.getOverrides()); ++ this(model.isAmbientOcclusion(state), model.isGui3d(), model.getItemCameraTransforms(), model.getOverrides()); + this.builderTexture = model.getParticleTexture(); + long i = MathHelper.getPositionRandom(pos); + diff --git a/module/minecraft/patches/net/minecraft/client/renderer/block/model/Variant.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/block/model/Variant.java.patch new file mode 100644 index 000000000..d02370048 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/block/model/Variant.java.patch @@ -0,0 +1,36 @@ +--- original/net/minecraft/client/renderer/block/model/Variant.java ++++ modified/net/minecraft/client/renderer/block/model/Variant.java +@@ -12,7 +12,7 @@ + import net.minecraftforge.fml.relauncher.SideOnly; + + @SideOnly(Side.CLIENT) +-public class Variant { ++public class Variant implements net.minecraftforge.client.model.ISmartVariant { + private final ResourceLocation modelLocation; + private final ModelRotation rotation; + private final boolean uvLock; +@@ -29,10 +29,15 @@ + return this.modelLocation; + } + ++ @Deprecated + public ModelRotation getRotation() { + return this.rotation; + } + ++ public net.minecraftforge.common.model.IModelState getState() { ++ return this.rotation; ++ } ++ + public boolean isUvLock() { + return this.uvLock; + } +@@ -123,4 +128,8 @@ + } + } + } ++ ++ public net.minecraftforge.client.model.IModel process(net.minecraftforge.client.model.IModel base) { ++ return base.uvlock(isUvLock()); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/client/renderer/block/model/WeightedBakedModel.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/block/model/WeightedBakedModel.java.patch new file mode 100644 index 000000000..9be865888 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/block/model/WeightedBakedModel.java.patch @@ -0,0 +1,14 @@ +--- original/net/minecraft/client/renderer/block/model/WeightedBakedModel.java ++++ modified/net/minecraft/client/renderer/block/model/WeightedBakedModel.java +@@ -39,6 +39,11 @@ + } + + @Override ++ public boolean isAmbientOcclusion(IBlockState state) { ++ return this.baseModel.isAmbientOcclusion(state); ++ } ++ ++ @Override + public boolean isGui3d() { + return this.baseModel.isGui3d(); + } diff --git a/module/minecraft/patches/net/minecraft/client/renderer/block/statemap/StateMap.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/block/statemap/StateMap.java.patch new file mode 100644 index 000000000..cd3f2e924 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/block/statemap/StateMap.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/client/renderer/block/statemap/StateMap.java ++++ modified/net/minecraft/client/renderer/block/statemap/StateMap.java +@@ -32,7 +32,7 @@ + if (this.name == null) { + s = Block.REGISTRY.getNameForObject(state.getBlock()).toString(); + } else { +- s = this.removeName(this.name, map); ++ s = String.format("%s:%s", Block.REGISTRY.getNameForObject(state.getBlock()).getNamespace(), this.removeName(this.name, map)); + } + + if (this.suffix != null) { diff --git a/module/minecraft/patches/net/minecraft/client/renderer/chunk/ChunkRenderDispatcher.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/chunk/ChunkRenderDispatcher.java.patch new file mode 100644 index 000000000..22eff3fbc --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/chunk/ChunkRenderDispatcher.java.patch @@ -0,0 +1,19 @@ +--- original/net/minecraft/client/renderer/chunk/ChunkRenderDispatcher.java ++++ modified/net/minecraft/client/renderer/chunk/ChunkRenderDispatcher.java +@@ -42,9 +42,15 @@ + private final ChunkRenderWorker renderWorker; + + public ChunkRenderDispatcher() { ++ this(-1); ++ } ++ ++ public ChunkRenderDispatcher(int countRenderBuilders) { + int i = Math.max(1, (int)(Runtime.getRuntime().maxMemory() * 0.3) / 10485760); + int j = Math.max(1, MathHelper.clamp(Runtime.getRuntime().availableProcessors(), 1, i / 5)); +- this.countRenderBuilders = MathHelper.clamp(j * 10, 1, i); ++ if(countRenderBuilders < 0) countRenderBuilders = MathHelper.clamp(j * 10, 1, i); ++ this.countRenderBuilders = countRenderBuilders; ++ + if (j > 1) { + for (int k = 0; k < j; k++) { + ChunkRenderWorker chunkrenderworker = new ChunkRenderWorker(this); diff --git a/module/minecraft/patches/net/minecraft/client/renderer/chunk/ChunkRenderWorker.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/chunk/ChunkRenderWorker.java.patch new file mode 100644 index 000000000..2f1cd1a4b --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/chunk/ChunkRenderWorker.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/client/renderer/chunk/ChunkRenderWorker.java ++++ modified/net/minecraft/client/renderer/chunk/ChunkRenderWorker.java +@@ -189,7 +189,7 @@ + Minecraft.getMinecraft().crashed(CrashReport.makeCrashReport(p_onFailure_1_, "Rendering chunk")); + } + } +- } ++ }, Runnable::run + ); + } + } diff --git a/module/minecraft/patches/net/minecraft/client/renderer/chunk/RenderChunk.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/chunk/RenderChunk.java.patch new file mode 100644 index 000000000..9b6303a00 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/chunk/RenderChunk.java.patch @@ -0,0 +1,77 @@ +--- original/net/minecraft/client/renderer/chunk/RenderChunk.java ++++ modified/net/minecraft/client/renderer/chunk/RenderChunk.java +@@ -144,20 +144,22 @@ + visgraph.setOpaqueCube(blockpos$mutableblockpos); + } + +- if (block.hasTileEntity()) { ++ if (block.hasTileEntity(iblockstate)) { + TileEntity tileentity = this.worldView.getTileEntity(blockpos$mutableblockpos, Chunk.EnumCreateEntityType.CHECK); + if (tileentity != null) { + TileEntitySpecialRenderer tileentityspecialrenderer = TileEntityRendererDispatcher.instance.getRenderer(tileentity); + if (tileentityspecialrenderer != null) { +- compiledchunk.addTileEntity(tileentity); ++ + if (tileentityspecialrenderer.isGlobalRenderer(tileentity)) { + set.add(tileentity); +- } ++ } else compiledchunk.addTileEntity(tileentity); // FORGE: Fix MC-112730 + } + } + } + +- BlockRenderLayer blockrenderlayer1 = block.getRenderLayer(); ++ for(BlockRenderLayer blockrenderlayer1 : BlockRenderLayer.values()) { ++ if(!block.canRenderInLayer(iblockstate, blockrenderlayer1)) continue; ++ net.minecraftforge.client.ForgeHooksClient.setRenderLayer(blockrenderlayer1); + int j = blockrenderlayer1.ordinal(); + if (block.getDefaultState().getRenderType() != EnumBlockRenderType.INVISIBLE) { + BufferBuilder bufferbuilder = generator.getRegionRenderCacheBuilder().getWorldRendererByLayerId(j); +@@ -168,6 +170,8 @@ + + aboolean[j] |= blockrendererdispatcher.renderBlock(iblockstate, blockpos$mutableblockpos, this.worldView, bufferbuilder); + } ++ } ++ net.minecraftforge.client.ForgeHooksClient.setRenderLayer(null); + } + + for (BlockRenderLayer blockrenderlayer : BlockRenderLayer.values()) { +@@ -231,9 +235,9 @@ + + private void rebuildWorldView() { + int i = 1; +- this.worldView = new ChunkCache( +- this.world, this.position.add(-1, -1, -1), this.position.add(16, 16, 16), 1 +- ); ++ ChunkCache cache = createRegionRenderCache(this.world, this.position.add(-1, -1, -1), this.position.add(16, 16, 16), 1); ++ net.minecraftforge.client.MinecraftForgeClient.onRebuildChunk(this.world, this.position, cache); ++ this.worldView = cache; + } + + @Nullable +@@ -353,6 +357,25 @@ + return this.needsUpdate && this.needsImmediateUpdate; + } + ++ /* ======================================== FORGE START =====================================*/ ++ /** ++ * Creates a new RegionRenderCache instance.
++ * Extending classes can change the behavior of the cache, allowing to visually change ++ * blocks (schematics etc). ++ * ++ * @see RegionRenderCache ++ * @param world The world to cache. ++ * @param from The starting position of the chunk minus one on each axis. ++ * @param to The ending position of the chunk plus one on each axis. ++ * @param subtract Padding used internally by the RegionRenderCache constructor to make ++ * the cache a 20x20x20 cube, for a total of 8000 states in the cache. ++ * @return new RegionRenderCache instance ++ */ ++ protected ChunkCache createRegionRenderCache(World world, BlockPos from, BlockPos to, int subtract) { ++ return new ChunkCache(world, from, to, subtract); ++ } ++ /* ========================================= FORGE END ======================================*/ ++ + public BlockPos getBlockPosOffset16(EnumFacing facing) { + return this.mapEnumFacing[facing.ordinal()]; + } diff --git a/module/minecraft/patches/net/minecraft/client/renderer/color/BlockColors.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/color/BlockColors.java.patch new file mode 100644 index 000000000..d01d01758 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/color/BlockColors.java.patch @@ -0,0 +1,45 @@ +--- original/net/minecraft/client/renderer/color/BlockColors.java ++++ modified/net/minecraft/client/renderer/color/BlockColors.java +@@ -26,7 +26,8 @@ + + @SideOnly(Side.CLIENT) + public class BlockColors { +- private final ObjectIntIdentityMap mapBlockColors = new ObjectIntIdentityMap<>(32); ++ // FORGE: Use RegistryDelegates as non-Vanilla block ids are not constant ++ private final java.util.Map, IBlockColor> blockColorMap = com.google.common.collect.Maps.newHashMap(); + + public static BlockColors init() { + final BlockColors blockcolors = new BlockColors(); +@@ -159,11 +160,13 @@ + return worldIn != null && pos != null ? 2129968 : 7455580; + } + }, Blocks.WATERLILY); ++ net.minecraftforge.client.ForgeHooksClient.onBlockColorsInit(blockcolors); + return blockcolors; + } + + public int getColor(IBlockState state, World p_189991_2_, BlockPos p_189991_3_) { +- IBlockColor iblockcolor = this.mapBlockColors.getByValue(Block.getIdFromBlock(state.getBlock())); ++ IBlockColor iblockcolor = this.blockColorMap.get(state.getBlock().delegate); ++ + if (iblockcolor != null) { + return iblockcolor.colorMultiplier(state, null, null, 0); + } +@@ -173,13 +176,15 @@ + } + + public int colorMultiplier(IBlockState state, @Nullable IBlockAccess blockAccess, @Nullable BlockPos pos, int tintIndex) { +- IBlockColor iblockcolor = this.mapBlockColors.getByValue(Block.getIdFromBlock(state.getBlock())); ++ IBlockColor iblockcolor = this.blockColorMap.get(state.getBlock().delegate); + return iblockcolor == null ? -1 : iblockcolor.colorMultiplier(state, blockAccess, pos, tintIndex); + } + + public void registerBlockColorHandler(IBlockColor blockColor, Block... blocksIn) { + for (Block block : blocksIn) { +- this.mapBlockColors.put(blockColor, Block.getIdFromBlock(block)); ++ if (block == null) throw new IllegalArgumentException("Block registered to block color handler cannot be null!"); ++ if (block.getRegistryName() == null) throw new IllegalArgumentException("Block must be registered before assigning color handler."); ++ this.blockColorMap.put(block.delegate, blockColor); + } + } + } diff --git a/module/minecraft/patches/net/minecraft/client/renderer/color/ItemColors.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/color/ItemColors.java.patch new file mode 100644 index 000000000..9bfeea1fe --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/color/ItemColors.java.patch @@ -0,0 +1,44 @@ +--- original/net/minecraft/client/renderer/color/ItemColors.java ++++ modified/net/minecraft/client/renderer/color/ItemColors.java +@@ -23,7 +23,8 @@ + + @SideOnly(Side.CLIENT) + public class ItemColors { +- private final ObjectIntIdentityMap mapItemColors = new ObjectIntIdentityMap<>(32); ++ // FORGE: Use RegistryDelegates as non-Vanilla item ids are not constant ++ private final java.util.Map, IItemColor> itemColorMap = com.google.common.collect.Maps.newHashMap(); + + public static ItemColors init(final BlockColors colors) { + ItemColors itemcolors = new ItemColors(); +@@ -115,23 +116,28 @@ + return tintIndex == 0 ? -1 : ItemMap.getColor(stack); + } + }, Items.FILLED_MAP); ++ net.minecraftforge.client.ForgeHooksClient.onItemColorsInit(itemcolors, colors); + return itemcolors; + } + + public int colorMultiplier(ItemStack stack, int tintIndex) { +- IItemColor iitemcolor = this.mapItemColors.getByValue(Item.REGISTRY.getIDForObject(stack.getItem())); ++ IItemColor iitemcolor = this.itemColorMap.get(stack.getItem().delegate); + return iitemcolor == null ? -1 : iitemcolor.colorMultiplier(stack, tintIndex); + } + + public void registerItemColorHandler(IItemColor itemColor, Block... blocksIn) { + for (Block block : blocksIn) { +- this.mapItemColors.put(itemColor, Item.getIdFromItem(Item.getItemFromBlock(block))); ++ if (block == null) throw new IllegalArgumentException("Block registered to item color handler cannot be null!"); ++ if (block.getRegistryName() == null) throw new IllegalArgumentException("Block must be registered before assigning color handler."); ++ this.itemColorMap.put(Item.getItemFromBlock(block).delegate, itemColor); + } + } + + public void registerItemColorHandler(IItemColor itemColor, Item... itemsIn) { + for (Item item : itemsIn) { +- this.mapItemColors.put(itemColor, Item.getIdFromItem(item)); ++ if (item == null) throw new IllegalArgumentException("Item registered to item color handler cannot be null!"); ++ if (item.getRegistryName() == null) throw new IllegalArgumentException("Item must be registered before assigning color handler."); ++ this.itemColorMap.put(item.delegate, itemColor); + } + } + } diff --git a/module/minecraft/patches/net/minecraft/client/renderer/entity/RenderEntityItem.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/entity/RenderEntityItem.java.patch new file mode 100644 index 000000000..7539dc077 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/entity/RenderEntityItem.java.patch @@ -0,0 +1,82 @@ +--- original/net/minecraft/client/renderer/entity/RenderEntityItem.java ++++ modified/net/minecraft/client/renderer/entity/RenderEntityItem.java +@@ -37,7 +37,7 @@ + boolean flag = p_177077_9_.isGui3d(); + int i = this.getModelCount(itemstack); + float f = 0.25F; +- float f1 = MathHelper.sin((itemIn.getAge() + p_177077_8_) / 10.0F + itemIn.hoverStart) * 0.1F + 0.1F; ++ float f1 = shouldBob() ? MathHelper.sin((itemIn.getAge() + p_177077_8_) / 10.0F + itemIn.hoverStart) * 0.1F + 0.1F : 0; + float f2 = p_177077_9_.getItemCameraTransforms().getTransform(ItemCameraTransforms.TransformType.GROUND).scale.y; + GlStateManager.translate((float)p_177077_2_, (float)p_177077_4_ + f1 + 0.25F * f2, (float)p_177077_6_); + if (flag || this.renderManager.options != null) { +@@ -88,14 +88,11 @@ + GlStateManager.pushMatrix(); + IBakedModel ibakedmodel = this.itemRenderer.getItemModelWithOverrides(itemstack, entity.world, null); + int j = this.transformModelCount(entity, x, y, z, partialTicks, ibakedmodel); +- float f = ibakedmodel.getItemCameraTransforms().ground.scale.x; +- float f1 = ibakedmodel.getItemCameraTransforms().ground.scale.y; +- float f2 = ibakedmodel.getItemCameraTransforms().ground.scale.z; + boolean flag1 = ibakedmodel.isGui3d(); + if (!flag1) { +- float f3 = -0.0F * (j - 1) * 0.5F * f; +- float f4 = -0.0F * (j - 1) * 0.5F * f1; +- float f5 = -0.09375F * (j - 1) * 0.5F * f2; ++ float f3 = -0.0F * (j - 1) * 0.5F; ++ float f4 = -0.0F * (j - 1) * 0.5F; ++ float f5 = -0.09375F * (j - 1) * 0.5F; + GlStateManager.translate(f3, f4, f5); + } + +@@ -111,11 +108,11 @@ + float f7 = (this.random.nextFloat() * 2.0F - 1.0F) * 0.15F; + float f9 = (this.random.nextFloat() * 2.0F - 1.0F) * 0.15F; + float f6 = (this.random.nextFloat() * 2.0F - 1.0F) * 0.15F; +- GlStateManager.translate(f7, f9, f6); ++ GlStateManager.translate(shouldSpreadItems() ? f7 : 0, shouldSpreadItems() ? f9 : 0, f6); + } + +- ibakedmodel.getItemCameraTransforms().applyTransform(ItemCameraTransforms.TransformType.GROUND); +- this.itemRenderer.renderItem(itemstack, ibakedmodel); ++ IBakedModel transformedModel = net.minecraftforge.client.ForgeHooksClient.handleCameraTransforms(ibakedmodel, ItemCameraTransforms.TransformType.GROUND, false); ++ this.itemRenderer.renderItem(itemstack, transformedModel); + GlStateManager.popMatrix(); + } else { + GlStateManager.pushMatrix(); +@@ -125,10 +122,10 @@ + GlStateManager.translate(f8, f10, 0.0F); + } + +- ibakedmodel.getItemCameraTransforms().applyTransform(ItemCameraTransforms.TransformType.GROUND); +- this.itemRenderer.renderItem(itemstack, ibakedmodel); ++ IBakedModel transformedModel = net.minecraftforge.client.ForgeHooksClient.handleCameraTransforms(ibakedmodel, ItemCameraTransforms.TransformType.GROUND, false); ++ this.itemRenderer.renderItem(itemstack, transformedModel); + GlStateManager.popMatrix(); +- GlStateManager.translate(0.0F * f, 0.0F * f1, 0.09375F * f2); ++ GlStateManager.translate(0.0F, 0.0F, 0.09375F); + } + } + +@@ -152,4 +149,23 @@ + protected ResourceLocation getEntityTexture(EntityItem entity) { + return TextureMap.LOCATION_BLOCKS_TEXTURE; + } ++ /*==================================== FORGE START ===========================================*/ ++ ++ /** ++ * Items should spread out when rendered in 3d? ++ * @return ++ */ ++ public boolean shouldSpreadItems() ++ { ++ return true; + } ++ /** ++ * Items should have a bob effect ++ * @return ++ */ ++ public boolean shouldBob() ++ { ++ return true; ++ } ++ /*==================================== FORGE END =============================================*/ ++} diff --git a/module/minecraft/patches/net/minecraft/client/renderer/entity/RenderFish.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/entity/RenderFish.java.patch new file mode 100644 index 000000000..cfa3a1d60 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/entity/RenderFish.java.patch @@ -0,0 +1,12 @@ +--- original/net/minecraft/client/renderer/entity/RenderFish.java ++++ modified/net/minecraft/client/renderer/entity/RenderFish.java +@@ -66,7 +66,8 @@ + GlStateManager.popMatrix(); + int k = entityplayer.getPrimaryHand() == EnumHandSide.RIGHT ? 1 : -1; + ItemStack itemstack = entityplayer.getHeldItemMainhand(); +- if (itemstack.getItem() != Items.FISHING_ROD) { ++ ++ if (!(itemstack.getItem() instanceof net.minecraft.item.ItemFishingRod)) { + k = -k; + } + diff --git a/module/minecraft/patches/net/minecraft/client/renderer/entity/RenderItemFrame.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/entity/RenderItemFrame.java.patch new file mode 100644 index 000000000..1ff9ba9f3 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/entity/RenderItemFrame.java.patch @@ -0,0 +1,42 @@ +--- original/net/minecraft/client/renderer/entity/RenderItemFrame.java ++++ modified/net/minecraft/client/renderer/entity/RenderItemFrame.java +@@ -46,7 +46,8 @@ + BlockRendererDispatcher blockrendererdispatcher = this.mc.getBlockRendererDispatcher(); + ModelManager modelmanager = blockrendererdispatcher.getBlockModelShapes().getModelManager(); + IBakedModel ibakedmodel; +- if (entity.getDisplayedItem().getItem() == Items.FILLED_MAP) { ++ ++ if (entity.getDisplayedItem().getItem() instanceof net.minecraft.item.ItemMap) { + ibakedmodel = modelmanager.getModel(this.mapModel); + } else { + ibakedmodel = modelmanager.getModel(this.itemFrameModel); +@@ -88,16 +89,19 @@ + if (!itemstack.isEmpty()) { + GlStateManager.pushMatrix(); + GlStateManager.disableLighting(); +- boolean flag = itemstack.getItem() == Items.FILLED_MAP; ++ boolean flag = itemstack.getItem() instanceof net.minecraft.item.ItemMap; + int i = flag ? itemFrame.getRotation() % 4 * 2 : itemFrame.getRotation(); + GlStateManager.rotate(i * 360.0F / 8.0F, 0.0F, 0.0F, 1.0F); ++ ++ net.minecraftforge.client.event.RenderItemInFrameEvent event = new net.minecraftforge.client.event.RenderItemInFrameEvent(itemFrame, this); ++ if (!net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event)) { + if (flag) { + this.renderManager.renderEngine.bindTexture(MAP_BACKGROUND_TEXTURES); + GlStateManager.rotate(180.0F, 0.0F, 0.0F, 1.0F); + float f = 0.0078125F; + GlStateManager.scale(0.0078125F, 0.0078125F, 0.0078125F); + GlStateManager.translate(-64.0F, -64.0F, 0.0F); +- MapData mapdata = Items.FILLED_MAP.getMapData(itemstack, itemFrame.world); ++ MapData mapdata = ((net.minecraft.item.ItemMap) itemstack.getItem()).getMapData(itemstack, itemFrame.world); + GlStateManager.translate(0.0F, 0.0F, -1.0F); + if (mapdata != null) { + this.mc.entityRenderer.getMapItemRenderer().renderMap(mapdata, true); +@@ -110,6 +114,7 @@ + RenderHelper.disableStandardItemLighting(); + GlStateManager.popAttrib(); + } ++ } + + GlStateManager.enableLighting(); + GlStateManager.popMatrix(); diff --git a/module/minecraft/patches/net/minecraft/client/renderer/entity/RenderLivingBase.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/entity/RenderLivingBase.java.patch new file mode 100644 index 000000000..2a02d4d28 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/entity/RenderLivingBase.java.patch @@ -0,0 +1,71 @@ +--- original/net/minecraft/client/renderer/entity/RenderLivingBase.java ++++ modified/net/minecraft/client/renderer/entity/RenderLivingBase.java +@@ -32,6 +32,9 @@ + protected List> layerRenderers = Lists.newArrayList(); + protected boolean renderMarker; + ++ public static float NAME_TAG_RANGE = 64.0f; ++ public static float NAME_TAG_RANGE_SNEAK = 32.0f; ++ + public RenderLivingBase(RenderManager renderManagerIn, ModelBase modelBaseIn, float shadowSizeIn) { + super(renderManagerIn); + this.mainModel = modelBaseIn; +@@ -66,17 +69,20 @@ + + /** Renders the desired {@code T} type Entity. */ + public void doRender(T entity, double x, double y, double z, float entityYaw, float partialTicks) { ++ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.RenderLivingEvent.Pre(entity, this, partialTicks, x, y, z))) return; + GlStateManager.pushMatrix(); + GlStateManager.disableCull(); + this.mainModel.swingProgress = this.getSwingProgress(entity, partialTicks); +- this.mainModel.isRiding = entity.isRiding(); ++ boolean shouldSit = entity.isRiding() && (entity.getRidingEntity() != null && entity.getRidingEntity().shouldRiderSit()); ++ this.mainModel.isRiding = shouldSit; + this.mainModel.isChild = entity.isChild(); + + try { + float f = this.interpolateRotation(entity.prevRenderYawOffset, entity.renderYawOffset, partialTicks); + float f1 = this.interpolateRotation(entity.prevRotationYawHead, entity.rotationYawHead, partialTicks); + float f2 = f1 - f; +- if (entity.isRiding() && entity.getRidingEntity() instanceof EntityLivingBase) { ++ ++ if (shouldSit && entity.getRidingEntity() instanceof EntityLivingBase) { + EntityLivingBase entitylivingbase = (EntityLivingBase)entity.getRidingEntity(); + f = this.interpolateRotation(entitylivingbase.prevRenderYawOffset, entitylivingbase.renderYawOffset, partialTicks); + f2 = f1 - f; +@@ -114,6 +120,7 @@ + if (f5 > 1.0F) { + f5 = 1.0F; + } ++ f2 = f1 - f; // Forge: Fix MC-1207 + } + + GlStateManager.enableAlpha(); +@@ -160,6 +167,7 @@ + GlStateManager.enableCull(); + GlStateManager.popMatrix(); + super.doRender(entity, x, y, z, entityYaw, partialTicks); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.RenderLivingEvent.Post(entity, this, partialTicks, x, y, z)); + } + + public float prepareScale(T entitylivingbaseIn, float partialTicks) { +@@ -388,15 +396,18 @@ + } + + public void renderName(T entity, double x, double y, double z) { ++ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.RenderLivingEvent.Specials.Pre(entity, this, x, y, z))) return; + if (this.canRenderName(entity)) { + double d0 = entity.getDistanceSq(this.renderManager.renderViewEntity); +- float f = entity.isSneaking() ? 32.0F : 64.0F; ++ float f = entity.isSneaking() ? NAME_TAG_RANGE_SNEAK : NAME_TAG_RANGE; ++ + if (!(d0 >= f * f)) { + String s = entity.getDisplayName().getFormattedText(); + GlStateManager.alphaFunc(516, 0.1F); + this.renderEntityName(entity, x, y, z, s, d0); + } + } ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.RenderLivingEvent.Specials.Post(entity, this, x, y, z)); + } + + protected boolean canRenderName(T entity) { diff --git a/module/minecraft/patches/net/minecraft/client/renderer/entity/RenderManager.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/entity/RenderManager.java.patch new file mode 100644 index 000000000..64b5bbe95 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/entity/RenderManager.java.patch @@ -0,0 +1,28 @@ +--- original/net/minecraft/client/renderer/entity/RenderManager.java ++++ modified/net/minecraft/client/renderer/entity/RenderManager.java +@@ -231,8 +231,13 @@ + this.playerRenderer = new RenderPlayer(this); + this.skinMap.put("default", this.playerRenderer); + this.skinMap.put("slim", new RenderPlayer(this, true)); ++ net.minecraftforge.fml.client.registry.RenderingRegistry.loadEntityRenderers(this, this.entityRenderMap); + } + ++ public Map getSkinMap() { ++ return (Map) java.util.Collections.unmodifiableMap(skinMap); ++ } ++ + public void setRenderPosition(double renderPosXIn, double renderPosYIn, double renderPosZIn) { + this.renderPosX = renderPosXIn; + this.renderPosY = renderPosYIn; +@@ -269,8 +274,9 @@ + if (livingPlayerIn instanceof EntityLivingBase && ((EntityLivingBase)livingPlayerIn).isPlayerSleeping()) { + IBlockState iblockstate = worldIn.getBlockState(new BlockPos(livingPlayerIn)); + Block block = iblockstate.getBlock(); +- if (block == Blocks.BED) { +- int i = iblockstate.getValue(BlockBed.FACING).getHorizontalIndex(); ++ ++ if (block.isBed(iblockstate, worldIn, new BlockPos(livingPlayerIn), (EntityLivingBase)livingPlayerIn)) { ++ int i = block.getBedDirection(iblockstate, worldIn, new BlockPos(livingPlayerIn)).getHorizontalIndex(); + this.playerViewY = i * 90 + 180; + this.playerViewX = 0.0F; + } diff --git a/module/minecraft/patches/net/minecraft/client/renderer/entity/RenderPlayer.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/entity/RenderPlayer.java.patch new file mode 100644 index 000000000..e8acc75f1 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/entity/RenderPlayer.java.patch @@ -0,0 +1,45 @@ +--- original/net/minecraft/client/renderer/entity/RenderPlayer.java ++++ modified/net/minecraft/client/renderer/entity/RenderPlayer.java +@@ -53,6 +53,7 @@ + + /** Renders the desired {@code T} type Entity. */ + public void doRender(AbstractClientPlayer entity, double x, double y, double z, float entityYaw, float partialTicks) { ++ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.RenderPlayerEvent.Pre(entity, this, partialTicks, x, y, z))) return; + if (!entity.isUser() || this.renderManager.renderViewEntity == entity) { + double d0 = y; + if (entity.isSneaking()) { +@@ -64,6 +65,7 @@ + super.doRender(entity, x, d0, z, entityYaw, partialTicks); + GlStateManager.disableBlendProfile(GlStateManager.Profile.PLAYER_SKIN); + } ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.RenderPlayerEvent.Post(entity, this, partialTicks, x, y, z)); + } + + private void setModelVisibilities(AbstractClientPlayer clientPlayer) { +@@ -104,6 +106,10 @@ + if (enumaction1 == EnumAction.BLOCK) { + modelbiped$armpose1 = ModelBiped.ArmPose.BLOCK; + } ++ // FORGE: fix MC-88356 allow offhand to use bow and arrow animation ++ else if (enumaction1 == EnumAction.BOW) { ++ modelbiped$armpose1 = ModelBiped.ArmPose.BOW_AND_ARROW; ++ } + } + } + +@@ -150,6 +156,7 @@ + } + + public void renderRightArm(AbstractClientPlayer clientPlayer) { ++ if (net.minecraftforge.client.ForgeHooksClient.renderSpecificFirstPersonArm(this, clientPlayer, EnumHandSide.RIGHT)) return; + float f = 1.0F; + GlStateManager.color(1.0F, 1.0F, 1.0F); + float f1 = 0.0625F; +@@ -167,6 +174,7 @@ + } + + public void renderLeftArm(AbstractClientPlayer clientPlayer) { ++ if (net.minecraftforge.client.ForgeHooksClient.renderSpecificFirstPersonArm(this, clientPlayer, EnumHandSide.LEFT)) return; + float f = 1.0F; + GlStateManager.color(1.0F, 1.0F, 1.0F); + float f1 = 0.0625F; diff --git a/module/minecraft/patches/net/minecraft/client/renderer/entity/RenderVillager.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/entity/RenderVillager.java.patch new file mode 100644 index 000000000..c5bfaab32 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/entity/RenderVillager.java.patch @@ -0,0 +1,25 @@ +--- original/net/minecraft/client/renderer/entity/RenderVillager.java ++++ modified/net/minecraft/client/renderer/entity/RenderVillager.java +@@ -28,21 +28,7 @@ + + /** Returns the location of an entity's texture. Doesn't seem to be called unless you call Render.bindEntityTexture. */ + protected ResourceLocation getEntityTexture(EntityVillager entity) { +- switch (entity.getProfession()) { +- case 0: +- return FARMER_VILLAGER_TEXTURES; +- case 1: +- return LIBRARIAN_VILLAGER_TEXTURES; +- case 2: +- return PRIEST_VILLAGER_TEXTURES; +- case 3: +- return SMITH_VILLAGER_TEXTURES; +- case 4: +- return BUTCHER_VILLAGER_TEXTURES; +- case 5: +- default: +- return VILLAGER_TEXTURES; +- } ++ return entity.getProfessionForge().getSkin(); + } + + /** Allows the render to do state modifications necessary before the model is rendered. */ diff --git a/module/minecraft/patches/net/minecraft/client/renderer/entity/RenderZombieVillager.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/entity/RenderZombieVillager.java.patch new file mode 100644 index 000000000..388c09081 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/entity/RenderZombieVillager.java.patch @@ -0,0 +1,10 @@ +--- original/net/minecraft/client/renderer/entity/RenderZombieVillager.java ++++ modified/net/minecraft/client/renderer/entity/RenderZombieVillager.java +@@ -23,6 +23,7 @@ + + /** Returns the location of an entity's texture. Doesn't seem to be called unless you call Render.bindEntityTexture. */ + protected ResourceLocation getEntityTexture(EntityZombieVillager entity) { ++ if (true) return entity.getForgeProfession().getZombieSkin(); + switch (entity.getProfession()) { + case 0: + return ZOMBIE_VILLAGER_FARMER_LOCATION; diff --git a/module/minecraft/patches/net/minecraft/client/renderer/entity/layers/LayerArmorBase.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/entity/layers/LayerArmorBase.java.patch new file mode 100644 index 000000000..fd8e94744 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/entity/layers/LayerArmorBase.java.patch @@ -0,0 +1,85 @@ +--- original/net/minecraft/client/renderer/entity/layers/LayerArmorBase.java ++++ modified/net/minecraft/client/renderer/entity/layers/LayerArmorBase.java +@@ -70,28 +70,26 @@ + ItemArmor itemarmor = (ItemArmor)itemstack.getItem(); + if (itemarmor.getEquipmentSlot() == slotIn) { + T t = this.getModelFromSlot(slotIn); ++ t = getArmorModelHook(entityLivingBaseIn, itemstack, slotIn, t); + t.setModelAttributes(this.renderer.getMainModel()); + t.setLivingAnimations(entityLivingBaseIn, limbSwing, limbSwingAmount, partialTicks); + this.setModelSlotVisible(t, slotIn); + boolean flag = this.isLegSlot(slotIn); +- this.renderer.bindTexture(this.getArmorResource(itemarmor, flag)); +- switch (itemarmor.getArmorMaterial()) { +- case LEATHER: ++ this.renderer.bindTexture(this.getArmorResource(entityLivingBaseIn, itemstack, slotIn, null)); { ++ if (itemarmor.hasOverlay(itemstack)) { // Allow this for anything, not only cloth + int i = itemarmor.getColor(itemstack); + float f = (i >> 16 & 0xFF) / 255.0F; + float f1 = (i >> 8 & 0xFF) / 255.0F; + float f2 = (i & 0xFF) / 255.0F; + GlStateManager.color(this.colorR * f, this.colorG * f1, this.colorB * f2, this.alpha); + t.render(entityLivingBaseIn, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); +- this.renderer.bindTexture(this.getArmorResource(itemarmor, flag, "overlay")); +- case CHAIN: +- case IRON: +- case GOLD: +- case DIAMOND: ++ this.renderer.bindTexture(this.getArmorResource(entityLivingBaseIn, itemstack, slotIn, "overlay")); ++ } ++ { // Non-colored + GlStateManager.color(this.colorR, this.colorG, this.colorB, this.alpha); + t.render(entityLivingBaseIn, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); +- default: +- if (!this.skipRenderGlint && itemstack.isItemEnchanted()) { ++ } // Default ++ if (!this.skipRenderGlint && itemstack.hasEffect()) { + renderEnchantedGlint( + this.renderer, entityLivingBaseIn, t, limbSwing, limbSwingAmount, partialTicks, ageInTicks, netHeadYaw, headPitch, scale + ); +@@ -179,4 +177,45 @@ + protected abstract void initArmor(); + + protected abstract void setModelSlotVisible(T var1, EntityEquipmentSlot var2); ++ ++ /*=================================== FORGE START =========================================*/ ++ ++ /** ++ * Hook to allow item-sensitive armor model. for LayerBipedArmor. ++ */ ++ protected T getArmorModelHook(EntityLivingBase entity, ItemStack itemStack, EntityEquipmentSlot slot, T model) { ++ return model; ++ } ++ ++ /** ++ * More generic ForgeHook version of the above function, it allows for Items to have more control over what texture they provide. ++ * ++ * @param entity Entity wearing the armor ++ * @param stack ItemStack for the armor ++ * @param slot Slot ID that the item is in ++ * @param type Subtype, can be null or "overlay" ++ * @return ResourceLocation pointing at the armor's texture ++ */ ++ public ResourceLocation getArmorResource(net.minecraft.entity.Entity entity, ItemStack stack, EntityEquipmentSlot slot, String type) { ++ ItemArmor item = (ItemArmor)stack.getItem(); ++ String texture = item.getArmorMaterial().getName(); ++ String domain = "minecraft"; ++ int idx = texture.indexOf(':'); ++ if (idx != -1) { ++ domain = texture.substring(0, idx); ++ texture = texture.substring(idx + 1); ++ } ++ String s1 = String.format("%s:textures/models/armor/%s_layer_%d%s.png", domain, texture, (isLegSlot(slot) ? 2 : 1), type == null ? "" : String.format("_%s", type)); ++ ++ s1 = net.minecraftforge.client.ForgeHooksClient.getArmorTexture(entity, stack, s1, slot, type); ++ ResourceLocation resourcelocation = (ResourceLocation)ARMOR_TEXTURE_RES_MAP.get(s1); ++ ++ if (resourcelocation == null) { ++ resourcelocation = new ResourceLocation(s1); ++ ARMOR_TEXTURE_RES_MAP.put(s1, resourcelocation); ++ } ++ ++ return resourcelocation; ++ } ++ /*=================================== FORGE END ===========================================*/ + } diff --git a/module/minecraft/patches/net/minecraft/client/renderer/entity/layers/LayerBipedArmor.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/entity/layers/LayerBipedArmor.java.patch new file mode 100644 index 000000000..6ac3dfad8 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/entity/layers/LayerBipedArmor.java.patch @@ -0,0 +1,20 @@ +--- original/net/minecraft/client/renderer/entity/layers/LayerBipedArmor.java ++++ modified/net/minecraft/client/renderer/entity/layers/LayerBipedArmor.java +@@ -18,6 +18,7 @@ + this.modelArmor = new ModelBiped(1.0F); + } + ++ @SuppressWarnings("incomplete-switch") + protected void setModelSlotVisible(ModelBiped p_188359_1_, EntityEquipmentSlot slotIn) { + this.setModelVisible(p_188359_1_); + switch (slotIn) { +@@ -44,4 +45,9 @@ + protected void setModelVisible(ModelBiped model) { + model.setVisible(false); + } ++ ++ @Override ++ protected ModelBiped getArmorModelHook(net.minecraft.entity.EntityLivingBase entity, net.minecraft.item.ItemStack itemStack, EntityEquipmentSlot slot, ModelBiped model) { ++ return net.minecraftforge.client.ForgeHooksClient.getArmorModel(entity, itemStack, slot, model); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/client/renderer/entity/layers/LayerHeldItem.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/entity/layers/LayerHeldItem.java.patch new file mode 100644 index 000000000..6049f4e41 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/entity/layers/LayerHeldItem.java.patch @@ -0,0 +1,17 @@ +--- original/net/minecraft/client/renderer/entity/layers/LayerHeldItem.java ++++ modified/net/minecraft/client/renderer/entity/layers/LayerHeldItem.java +@@ -50,11 +50,12 @@ + private void renderHeldItem(EntityLivingBase p_188358_1_, ItemStack p_188358_2_, ItemCameraTransforms.TransformType p_188358_3_, EnumHandSide handSide) { + if (!p_188358_2_.isEmpty()) { + GlStateManager.pushMatrix(); +- this.translateToHand(handSide); ++ + if (p_188358_1_.isSneaking()) { + GlStateManager.translate(0.0F, 0.2F, 0.0F); + } +- ++ // Forge: moved this call down, fixes incorrect offset while sneaking. ++ this.translateToHand(handSide); + GlStateManager.rotate(-90.0F, 1.0F, 0.0F, 0.0F); + GlStateManager.rotate(180.0F, 0.0F, 1.0F, 0.0F); + boolean flag = handSide == EnumHandSide.LEFT; diff --git a/module/minecraft/patches/net/minecraft/client/renderer/entity/layers/LayerHeldItemWitch.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/entity/layers/LayerHeldItemWitch.java.patch new file mode 100644 index 000000000..f84f6a82c --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/entity/layers/LayerHeldItemWitch.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/client/renderer/entity/layers/LayerHeldItemWitch.java ++++ modified/net/minecraft/client/renderer/entity/layers/LayerHeldItemWitch.java +@@ -52,7 +52,7 @@ + GlStateManager.rotate(-5.0F, 0.0F, 1.0F, 0.0F); + float f1 = 0.375F; + GlStateManager.scale(0.375F, -0.375F, 0.375F); +- } else if (item == Items.BOW) { ++ } else if (item instanceof net.minecraft.item.ItemBow) { + GlStateManager.translate(0.0F, 0.125F, -0.125F); + GlStateManager.rotate(-45.0F, 0.0F, 1.0F, 0.0F); + float f2 = 0.625F; diff --git a/module/minecraft/patches/net/minecraft/client/renderer/texture/LayeredColorMaskTexture.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/texture/LayeredColorMaskTexture.java.patch new file mode 100644 index 000000000..eb7d1bfdc --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/texture/LayeredColorMaskTexture.java.patch @@ -0,0 +1,12 @@ +--- original/net/minecraft/client/renderer/texture/LayeredColorMaskTexture.java ++++ modified/net/minecraft/client/renderer/texture/LayeredColorMaskTexture.java +@@ -61,8 +61,7 @@ + String s = this.listTextures.get(j); + int k = this.listDyeColors.get(j).getColorValue(); + if (s != null) { +- iresource1 = resourceManager.getResource(new ResourceLocation(s)); +- BufferedImage bufferedimage2 = TextureUtil.readBufferedImage(iresource1.getInputStream()); ++ BufferedImage bufferedimage2 = net.minecraftforge.client.MinecraftForgeClient.getImageLayer(new ResourceLocation(s), resourceManager); + if (bufferedimage2.getWidth() == bufferedimage.getWidth() + && bufferedimage2.getHeight() == bufferedimage.getHeight() + && bufferedimage2.getType() == 6) { diff --git a/module/minecraft/patches/net/minecraft/client/renderer/texture/Stitcher.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/texture/Stitcher.java.patch new file mode 100644 index 000000000..e09a08484 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/texture/Stitcher.java.patch @@ -0,0 +1,53 @@ +--- original/net/minecraft/client/renderer/texture/Stitcher.java ++++ modified/net/minecraft/client/renderer/texture/Stitcher.java +@@ -49,21 +49,27 @@ + public void doStitch() { + Stitcher.Holder[] astitcher$holder = this.setStitchHolders.toArray(new Stitcher.Holder[this.setStitchHolders.size()]); + Arrays.sort(astitcher$holder); ++ net.minecraftforge.fml.common.ProgressManager.ProgressBar bar = net.minecraftforge.fml.common.ProgressManager.push("Texture stitching", astitcher$holder.length); + + for (Stitcher.Holder stitcher$holder : astitcher$holder) { ++ bar.step(stitcher$holder.getAtlasSprite().getIconName()); + if (!this.allocateSlot(stitcher$holder)) { + String s = String.format( +- "Unable to fit: %s - size: %dx%d - Maybe try a lowerresolution resourcepack?", +- stitcher$holder.getAtlasSprite().getIconName(), +- stitcher$holder.getAtlasSprite().getIconWidth(), +- stitcher$holder.getAtlasSprite().getIconHeight() +- ); ++ "Unable to fit: %s - size: %dx%d - Maybe try a lowerresolution resourcepack?", ++ stitcher$holder.getAtlasSprite().getIconName(), ++ stitcher$holder.getAtlasSprite().getIconWidth(), ++ stitcher$holder.getAtlasSprite().getIconHeight() ++ ); ++ net.minecraftforge.fml.common.FMLLog.log.info(s); ++ for (Stitcher.Holder h : astitcher$holder) ++ net.minecraftforge.fml.common.FMLLog.log.info(" {}", h); + throw new StitcherException(stitcher$holder, s); + } + } + + this.currentWidth = MathHelper.smallestEncompassingPowerOfTwo(this.currentWidth); + this.currentHeight = MathHelper.smallestEncompassingPowerOfTwo(this.currentHeight); ++ net.minecraftforge.fml.common.ProgressManager.pop(bar); + } + + public List getStichSlots() { +@@ -132,7 +138,7 @@ + boolean flag4 = flag2 && l != j1; + boolean flag; + if (flag3 ^ flag4) { +- flag = flag3; ++ flag = !flag3 && flag1; //Forge: Fix stitcher not expanding entire height before growing width, and {potentially} growing larger then the max size. + } else { + flag = flag1 && k <= l; + } +@@ -206,7 +212,7 @@ + + @Override + public String toString() { +- return "Holder{width=" + this.width + ", height=" + this.height + '}'; ++ return "Holder{width=" + this.width + ", height=" + this.height + ", name=" + this.sprite.getIconName() + '}'; + } + + public int compareTo(Stitcher.Holder p_compareTo_1_) { diff --git a/module/minecraft/patches/net/minecraft/client/renderer/texture/TextureAtlasSprite.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/texture/TextureAtlasSprite.java.patch new file mode 100644 index 000000000..78b62849c --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/texture/TextureAtlasSprite.java.patch @@ -0,0 +1,57 @@ +--- original/net/minecraft/client/renderer/texture/TextureAtlasSprite.java ++++ modified/net/minecraft/client/renderer/texture/TextureAtlasSprite.java +@@ -45,12 +45,10 @@ + this.originX = originInX; + this.originY = originInY; + this.rotated = rotatedIn; +- float f = (float)(0.01F / inX); +- float f1 = (float)(0.01F / inY); +- this.minU = originInX / (float)inX + f; +- this.maxU = (originInX + this.width) / (float)inX - f; +- this.minV = (float)originInY / inY + f1; +- this.maxV = (float)(originInY + this.height) / inY - f1; ++ this.minU = (float)originInX / (float)(inX); ++ this.maxU = (float)(originInX + this.width) / (float)(inX); ++ this.minV = (float)originInY / (float)inY; ++ this.maxV = (float)(originInY + this.height) / (float)inY; + } + + public void copyFrom(TextureAtlasSprite atlasSpirit) { +@@ -354,4 +352,37 @@ + + this.maxV + + '}'; + } ++ ++ /*===================================== FORGE START =====================================*/ ++ /** ++ * The result of this function determines is the below 'load' function is called, and the ++ * default vanilla loading code is bypassed completely. ++ * @param manager Main resource manager ++ * @param location File resource location ++ * @return True to use your own custom load code and bypass vanilla loading. ++ */ ++ public boolean hasCustomLoader(net.minecraft.client.resources.IResourceManager manager, net.minecraft.util.ResourceLocation location) { ++ return false; ++ } ++ ++ /** ++ * Load the specified resource as this sprite's data. ++ * Returning false from this function will prevent this icon from being stitched onto the master texture. ++ * @param manager Main resource manager ++ * @param location File resource location ++ * @param textureGetter accessor for dependencies. All of them will be loaded before this one ++ * @return False to prevent this Icon from being stitched ++ */ ++ public boolean load(net.minecraft.client.resources.IResourceManager manager, net.minecraft.util.ResourceLocation location, java.util.function.Function textureGetter) { ++ return true; ++ } ++ ++ /** ++ * @return all textures that should be loaded before this texture. ++ */ ++ public java.util.Collection getDependencies() { ++ return com.google.common.collect.ImmutableList.of(); ++ } ++ ++ /*===================================== FORGE END ======================================*/ + } diff --git a/module/minecraft/patches/net/minecraft/client/renderer/texture/TextureManager.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/texture/TextureManager.java.patch new file mode 100644 index 000000000..e55a53860 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/texture/TextureManager.java.patch @@ -0,0 +1,29 @@ +--- original/net/minecraft/client/renderer/texture/TextureManager.java ++++ modified/net/minecraft/client/renderer/texture/TextureManager.java +@@ -109,16 +109,19 @@ + public void deleteTexture(ResourceLocation textureLocation) { + ITextureObject itextureobject = this.getTexture(textureLocation); + if (itextureobject != null) { ++ this.mapTextureObjects.remove(textureLocation); // Forge: fix MC-98707 + TextureUtil.deleteTexture(itextureobject.getGlTextureId()); + } + } + + @Override + public void onResourceManagerReload(IResourceManager resourceManager) { ++ net.minecraftforge.fml.common.ProgressManager.ProgressBar bar = net.minecraftforge.fml.common.ProgressManager.push("Reloading Texture Manager", this.mapTextureObjects.keySet().size(), true); + Iterator> iterator = this.mapTextureObjects.entrySet().iterator(); + + while (iterator.hasNext()) { + Entry entry = iterator.next(); ++ bar.step(entry.getKey().toString()); + ITextureObject itextureobject = entry.getValue(); + if (itextureobject == TextureUtil.MISSING_TEXTURE) { + iterator.remove(); +@@ -126,5 +129,6 @@ + this.loadTexture(entry.getKey(), itextureobject); + } + } ++ net.minecraftforge.fml.common.ProgressManager.pop(bar); + } + } diff --git a/module/minecraft/patches/net/minecraft/client/renderer/texture/TextureMap.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/texture/TextureMap.java.patch new file mode 100644 index 000000000..d59bb49d4 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/texture/TextureMap.java.patch @@ -0,0 +1,251 @@ +--- original/net/minecraft/client/renderer/texture/TextureMap.java ++++ modified/net/minecraft/client/renderer/texture/TextureMap.java +@@ -41,6 +41,14 @@ + } + + public TextureMap(String basePathIn, @Nullable ITextureMapPopulator iconCreatorIn) { ++ this(basePathIn, iconCreatorIn, false); ++ } ++ ++ public TextureMap(String basePathIn, boolean skipFirst) { ++ this(basePathIn, null, skipFirst); ++ } ++ ++ public TextureMap(String basePathIn, @Nullable ITextureMapPopulator iconCreatorIn, boolean skipFirst) { + this.basePath = basePathIn; + this.iconCreator = iconCreatorIn; + } +@@ -63,6 +71,7 @@ + + public void loadSprites(IResourceManager resourceManager, ITextureMapPopulator iconCreatorIn) { + this.mapRegisteredSprites.clear(); ++ net.minecraftforge.client.ForgeHooksClient.onTextureStitchedPre(this); + iconCreatorIn.registerSprites(this); + this.initMissingImage(); + this.deleteGlTexture(); +@@ -76,23 +85,58 @@ + this.listAnimatedSprites.clear(); + int j = Integer.MAX_VALUE; + int k = 1 << this.mipmapLevels; ++ net.minecraftforge.fml.common.FMLLog.log.info("Max texture size: {}", i); ++ net.minecraftforge.fml.common.ProgressManager.ProgressBar bar = net.minecraftforge.fml.common.ProgressManager.push("Texture stitching", this.mapRegisteredSprites.size()); ++ loadedSprites.clear(); + +- for (Entry entry : this.mapRegisteredSprites.entrySet()) { +- TextureAtlasSprite textureatlassprite = entry.getValue(); +- ResourceLocation resourcelocation = this.getResourceLocation(textureatlassprite); +- IResource iresource = null; ++ for (Entry entry : Maps.newHashMap(this.mapRegisteredSprites).entrySet()) { ++ final ResourceLocation location = new ResourceLocation(entry.getKey()); ++ bar.step(location.toString()); ++ j = loadTexture(stitcher, resourceManager, location, entry.getValue(), bar, j, k); ++ } ++ finishLoading(stitcher, bar, j, k); ++ } + ++ private int loadTexture(Stitcher stitcher, IResourceManager resourceManager, ResourceLocation location, TextureAtlasSprite textureatlassprite, net.minecraftforge.fml.common.ProgressManager.ProgressBar bar, int j, int k) { ++ if (loadedSprites.contains(location)) { ++ return j; ++ } ++ ResourceLocation resourcelocation = this.getResourceLocation(textureatlassprite); ++ IResource iresource = null; ++ ++ for(ResourceLocation loading : loadingSprites) { ++ if(location.equals(loading)) { ++ final String error = "circular texture dependencies, stack: [" + com.google.common.base.Joiner.on(", ").join(loadingSprites) + "]"; ++ net.minecraftforge.fml.client.FMLClientHandler.instance().trackBrokenTexture(resourcelocation, error); ++ return j; ++ } ++ } ++ loadingSprites.addLast(location); ++ try { ++ for (ResourceLocation dependency : textureatlassprite.getDependencies()) { ++ if (!mapRegisteredSprites.containsKey(dependency.toString())) { ++ registerSprite(dependency); ++ } ++ TextureAtlasSprite depSprite = mapRegisteredSprites.get(dependency.toString()); ++ j = loadTexture(stitcher, resourceManager, dependency, depSprite, bar, j, k); ++ } + try { ++ if (textureatlassprite.hasCustomLoader(resourceManager, resourcelocation)) { ++ if (textureatlassprite.load(resourceManager, resourcelocation, l -> mapRegisteredSprites.get(l.toString()))) { ++ return j; ++ } ++ } else { + PngSizeInfo pngsizeinfo = PngSizeInfo.makeFromResource(resourceManager.getResource(resourcelocation)); + iresource = resourceManager.getResource(resourcelocation); + boolean flag = iresource.getMetadata("animation") != null; + textureatlassprite.loadSprite(pngsizeinfo, flag); ++ } + } catch (RuntimeException runtimeexception) { +- LOGGER.error("Unable to parse metadata from {}", resourcelocation, runtimeexception); +- continue; ++ net.minecraftforge.fml.client.FMLClientHandler.instance().trackBrokenTexture(resourcelocation, runtimeexception.getMessage()); ++ return j; + } catch (IOException ioexception) { +- LOGGER.error("Using missing texture, unable to load {}", resourcelocation, ioexception); +- continue; ++ net.minecraftforge.fml.client.FMLClientHandler.instance().trackMissingTexture(resourcelocation); ++ return j; + } finally { + IOUtils.closeQuietly(iresource); + } +@@ -100,22 +144,33 @@ + j = Math.min(j, Math.min(textureatlassprite.getIconWidth(), textureatlassprite.getIconHeight())); + int j1 = Math.min(Integer.lowestOneBit(textureatlassprite.getIconWidth()), Integer.lowestOneBit(textureatlassprite.getIconHeight())); + if (j1 < k) { ++ // FORGE: do not lower the mipmap level, just log the problematic textures + LOGGER.warn( +- "Texture {} with size {}x{} limits mip level from {} to {}", ++ "Texture {} with size {}x{} will have visual artifacts at mip level {}, it can only support level {}. Please report to the mod author that the texture should be some multiple of 16x16.", + resourcelocation, + textureatlassprite.getIconWidth(), + textureatlassprite.getIconHeight(), + MathHelper.log2(k), + MathHelper.log2(j1) + ); +- k = j1; ++ + } + ++ if (generateMipmaps(resourceManager, textureatlassprite)) + stitcher.addSprite(textureatlassprite); ++ return j; ++ } finally { ++ loadingSprites.removeLast(); ++ loadedSprites.add(location); + } ++ } + ++ private void finishLoading(Stitcher stitcher, net.minecraftforge.fml.common.ProgressManager.ProgressBar bar, int j, int k) { ++ net.minecraftforge.fml.common.ProgressManager.pop(bar); + int l = Math.min(j, k); + int i1 = MathHelper.log2(l); ++ ++ if (false) // FORGE: do not lower the mipmap level + if (i1 < this.mipmapLevels) { + LOGGER.warn("{}: dropping miplevel from {} to {}, because of minimum power of two: {}", this.basePath, this.mipmapLevels, i1, l); + this.mipmapLevels = i1; +@@ -123,19 +178,25 @@ + + this.missingImage.generateMipmaps(this.mipmapLevels); + stitcher.addSprite(this.missingImage); ++ bar = net.minecraftforge.fml.common.ProgressManager.push("Texture creation", 2); + + try { ++ bar.step("Stitching"); + stitcher.doStitch(); + } catch (StitcherException stitcherexception) { + throw stitcherexception; + } + + LOGGER.info("Created: {}x{} {}-atlas", stitcher.getCurrentWidth(), stitcher.getCurrentHeight(), this.basePath); ++ bar.step("Allocating GL texture"); + TextureUtil.allocateTextureImpl(this.getGlTextureId(), this.mipmapLevels, stitcher.getCurrentWidth(), stitcher.getCurrentHeight()); + Map map = Maps.newHashMap(this.mapRegisteredSprites); + ++ net.minecraftforge.fml.common.ProgressManager.pop(bar); ++ bar = net.minecraftforge.fml.common.ProgressManager.push("Texture mipmap and upload", stitcher.getStichSlots().size()); ++ + for (TextureAtlasSprite textureatlassprite1 : stitcher.getStichSlots()) { +- if (textureatlassprite1 == this.missingImage || this.generateMipmaps(resourceManager, textureatlassprite1)) { ++ bar.step(textureatlassprite1.getIconName()); { + String s = textureatlassprite1.getIconName(); + map.remove(s); + this.mapUploadedSprites.put(s, textureatlassprite1); +@@ -167,23 +228,27 @@ + for (TextureAtlasSprite textureatlassprite2 : map.values()) { + textureatlassprite2.copyFrom(this.missingImage); + } ++ net.minecraftforge.client.ForgeHooksClient.onTextureStitchedPost(this); ++ net.minecraftforge.fml.common.ProgressManager.pop(bar); + } + + private boolean generateMipmaps(IResourceManager resourceManager, final TextureAtlasSprite texture) { + ResourceLocation resourcelocation = this.getResourceLocation(texture); + IResource iresource = null; + +- try { +- iresource = resourceManager.getResource(resourcelocation); +- texture.loadSpriteFrames(iresource, this.mipmapLevels + 1); +- } catch (RuntimeException runtimeexception) { +- LOGGER.error("Unable to parse metadata from {}", resourcelocation, runtimeexception); +- return false; +- } catch (IOException ioexception) { +- LOGGER.error("Using missing texture, unable to load {}", resourcelocation, ioexception); +- return false; +- } finally { +- IOUtils.closeQuietly(iresource); ++ if (!texture.hasCustomLoader(resourceManager, resourcelocation)) { ++ try { ++ iresource = resourceManager.getResource(resourcelocation); ++ texture.loadSpriteFrames(iresource, this.mipmapLevels + 1); ++ } catch (RuntimeException runtimeexception) { ++ LOGGER.error("Unable to parse metadata from {}", resourcelocation, runtimeexception); ++ return false; ++ } catch (IOException ioexception) { ++ LOGGER.error("Using missing texture, unable to load {}", resourcelocation, ioexception); ++ return false; ++ } finally { ++ IOUtils.closeQuietly(iresource); ++ } + } + + try { +@@ -239,7 +304,7 @@ + throw new IllegalArgumentException("Location cannot be null!"); + } + +- TextureAtlasSprite textureatlassprite = this.mapRegisteredSprites.get(location); ++ TextureAtlasSprite textureatlassprite = this.mapRegisteredSprites.get(location.toString()); + if (textureatlassprite == null) { + textureatlassprite = TextureAtlasSprite.makeAtlasSprite(location); + this.mapRegisteredSprites.put(location.toString(), textureatlassprite); +@@ -260,4 +325,47 @@ + public TextureAtlasSprite getMissingSprite() { + return this.missingImage; + } ++ ++ //=================================================================================================== ++ // Forge Start ++ //=================================================================================================== ++ ++ private final java.util.Deque loadingSprites = new java.util.ArrayDeque<>(); ++ private final java.util.Set loadedSprites = new java.util.HashSet<>(); ++ ++ /** ++ * Grabs the registered entry for the specified name, returning null if there was not a entry. ++ * Opposed to registerIcon, this will not instantiate the entry, useful to test if a mapping exists. ++ * ++ * @param name The name of the entry to find ++ * @return The registered entry, null if nothing was registered. ++ */ ++ @Nullable ++ public TextureAtlasSprite getTextureExtry(String name) { ++ return mapRegisteredSprites.get(name); ++ } ++ ++ /** ++ * Adds a texture registry entry to this map for the specified name if one does not already exist. ++ * Returns false if the map already contains a entry for the specified name. ++ * ++ * @param entry Entry instance ++ * @return True if the entry was added to the map, false otherwise. ++ */ ++ public boolean setTextureEntry(TextureAtlasSprite entry) { ++ String name = entry.getIconName(); ++ if (!mapRegisteredSprites.containsKey(name)) { ++ mapRegisteredSprites.put(name, entry); ++ return true; ++ } ++ return false; ++ } ++ ++ public String getBasePath() { ++ return basePath; ++ } ++ ++ public int getMipmapLevels() { ++ return mipmapLevels; ++ } + } diff --git a/module/minecraft/patches/net/minecraft/client/renderer/texture/TextureUtil.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/texture/TextureUtil.java.patch new file mode 100644 index 000000000..bfb898f7b --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/texture/TextureUtil.java.patch @@ -0,0 +1,46 @@ +--- original/net/minecraft/client/renderer/texture/TextureUtil.java ++++ modified/net/minecraft/client/renderer/texture/TextureUtil.java +@@ -54,7 +54,7 @@ + if (p_147949_0_ > 0) { + boolean flag = false; + +- for (int i = 0; i < p_147949_2_.length; i++) { ++ for (int i = 0; i < p_147949_2_[0].length; i++) { + if (p_147949_2_[0][i] >> 24 == 0) { + flag = true; + break; +@@ -68,6 +68,7 @@ + int[] aint1 = aint[l1 - 1]; + int[] aint2 = new int[aint1.length >> 2]; + int j = p_147949_1_ >> l1; ++ if (j > 0) { // FORGE: forcing higher mipmap levels on odd textures needs this check + int k = aint2.length / j; + int l = j << 1; + +@@ -77,6 +78,7 @@ + aint2[i1 + j1 * j] = blendColors(aint1[k1 + 0], aint1[k1 + 1], aint1[k1 + 0 + l], aint1[k1 + 1 + l], flag); + } + } ++ } // end if (j > 0) + + aint[l1] = aint2; + } +@@ -142,6 +144,7 @@ + ) { + for (int i = 0; i < p_147955_0_.length; i++) { + int[] aint = p_147955_0_[i]; ++ if ((p_147955_1_ >> i <= 0) || (p_147955_2_ >> i <= 0)) break; + uploadTextureSub(i, aint, p_147955_1_ >> i, p_147955_2_ >> i, p_147955_3_ >> i, p_147955_4_ >> i, p_147955_5_, p_147955_6_, p_147955_0_.length > 1); + } + } +@@ -182,8 +185,10 @@ + } + + public static void allocateTextureImpl(int glTextureId, int mipmapLevels, int width, int height) { ++ synchronized (net.minecraftforge.fml.client.SplashProgress.class) { + deleteTexture(glTextureId); + bindTexture(glTextureId); ++ } + if (mipmapLevels >= 0) { + GlStateManager.glTexParameteri(3553, 33085, mipmapLevels); + GlStateManager.glTexParameteri(3553, 33082, 0); diff --git a/module/minecraft/patches/net/minecraft/client/renderer/tileentity/TileEntityItemStackRenderer.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/tileentity/TileEntityItemStackRenderer.java.patch new file mode 100644 index 000000000..f6f03c431 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/tileentity/TileEntityItemStackRenderer.java.patch @@ -0,0 +1,14 @@ +--- original/net/minecraft/client/renderer/tileentity/TileEntityItemStackRenderer.java ++++ modified/net/minecraft/client/renderer/tileentity/TileEntityItemStackRenderer.java +@@ -95,8 +95,9 @@ + TileEntityRendererDispatcher.instance.render(this.chestTrap, 0.0, 0.0, 0.0, 0.0F, partialTicks); + } else if (Block.getBlockFromItem(item) instanceof BlockShulkerBox) { + TileEntityRendererDispatcher.instance +- .render(SHULKER_BOXES[BlockShulkerBox.getColorFromItem(item).getMetadata()], 0.0, 0.0, 0.0, 0.0F, partialTicks); +- } else { ++ .render(SHULKER_BOXES[BlockShulkerBox.getColorFromItem(item).getMetadata()], 0.0, 0.0, 0.0, 0.0F, partialTicks); ++ } else if (Block.getBlockFromItem(item) != Blocks.CHEST) net.minecraftforge.client.ForgeHooksClient.renderTileItem(itemStackIn.getItem(), itemStackIn.getMetadata()); ++ else { + TileEntityRendererDispatcher.instance.render(this.chestBasic, 0.0, 0.0, 0.0, 0.0F, partialTicks); + } + } diff --git a/module/minecraft/patches/net/minecraft/client/renderer/tileentity/TileEntityPistonRenderer.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/tileentity/TileEntityPistonRenderer.java.patch new file mode 100644 index 000000000..0e1aa45b1 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/tileentity/TileEntityPistonRenderer.java.patch @@ -0,0 +1,16 @@ +--- original/net/minecraft/client/renderer/tileentity/TileEntityPistonRenderer.java ++++ modified/net/minecraft/client/renderer/tileentity/TileEntityPistonRenderer.java +@@ -22,11 +22,12 @@ + + @SideOnly(Side.CLIENT) + public class TileEntityPistonRenderer extends TileEntitySpecialRenderer { +- private final BlockRendererDispatcher blockRenderer = Minecraft.getMinecraft().getBlockRendererDispatcher(); ++ private BlockRendererDispatcher blockRenderer; + + public void render( + TileEntityPiston te, double x, double y, double z, float partialTicks, int destroyStage, float alpha + ) { ++ if (blockRenderer == null) blockRenderer = Minecraft.getMinecraft().getBlockRendererDispatcher(); //Forge: Delay this from constructor to allow us to change it later + BlockPos blockpos = te.getPos(); + IBlockState iblockstate = te.getPistonState(); + Block block = iblockstate.getBlock(); diff --git a/module/minecraft/patches/net/minecraft/client/renderer/tileentity/TileEntityRendererDispatcher.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/tileentity/TileEntityRendererDispatcher.java.patch new file mode 100644 index 000000000..13422d64b --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/tileentity/TileEntityRendererDispatcher.java.patch @@ -0,0 +1,86 @@ +--- original/net/minecraft/client/renderer/tileentity/TileEntityRendererDispatcher.java ++++ modified/net/minecraft/client/renderer/tileentity/TileEntityRendererDispatcher.java +@@ -88,7 +88,7 @@ + + @Nullable + public TileEntitySpecialRenderer getRenderer(@Nullable TileEntity tileEntityIn) { +- return tileEntityIn == null ? null : this.getRenderer((Class)tileEntityIn.getClass()); ++ return tileEntityIn == null || tileEntityIn.isInvalid() ? null : this.getRenderer(tileEntityIn.getClass()); // Forge: fix MC-123363 + } + + public void prepare( +@@ -111,13 +111,16 @@ + + public void render(TileEntity tileentityIn, float partialTicks, int destroyStage) { + if (tileentityIn.getDistanceSq(this.entityX, this.entityY, this.entityZ) < tileentityIn.getMaxRenderDistanceSquared()) { ++ if(!drawingBatch || !tileentityIn.hasFastRenderer()) { + RenderHelper.enableStandardItemLighting(); + int i = this.world.getCombinedLight(tileentityIn.getPos(), 0); + int j = i % 65536; + int k = i / 65536; + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, j, k); + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); ++ } + BlockPos blockpos = tileentityIn.getPos(); ++ if (this.world.isBlockLoaded(blockpos, false)) // Forge: fix MC-123363 + this.render( + tileentityIn, + blockpos.getX() - staticPlayerX, +@@ -145,6 +148,9 @@ + TileEntitySpecialRenderer tileentityspecialrenderer = this.getRenderer(tileEntityIn); + if (tileentityspecialrenderer != null) { + try { ++ if(drawingBatch && tileEntityIn.hasFastRenderer()) ++ tileentityspecialrenderer.renderTileEntityFast(tileEntityIn, x, y, z, partialTicks, destroyStage, p_192854_10_, batchBuffer.getBuffer()); ++ else + tileentityspecialrenderer.render(tileEntityIn, x, y, z, partialTicks, destroyStage, p_192854_10_); + } catch (Throwable throwable) { + CrashReport crashreport = CrashReport.makeCrashReport(throwable, "Rendering Block Entity"); +@@ -165,4 +171,47 @@ + public FontRenderer getFontRenderer() { + return this.fontRenderer; + } ++ ++ /* ======================================== FORGE START =====================================*/ ++ /** ++ * Buffer used for batched TESRs ++ */ ++ private net.minecraft.client.renderer.Tessellator batchBuffer = new net.minecraft.client.renderer.Tessellator(0x200000); ++ private boolean drawingBatch = false; ++ ++ /** ++ * Prepare for a batched TESR rendering. ++ * You probably shouldn't call this manually. ++ */ ++ public void preDrawBatch() { ++ batchBuffer.getBuffer().begin(org.lwjgl.opengl.GL11.GL_QUADS, net.minecraft.client.renderer.vertex.DefaultVertexFormats.BLOCK); ++ drawingBatch = true; ++ } ++ ++ /** ++ * Render all TESRs batched so far. ++ * You probably shouldn't call this manually. ++ */ ++ public void drawBatch(int pass) { ++ renderEngine.bindTexture(net.minecraft.client.renderer.texture.TextureMap.LOCATION_BLOCKS_TEXTURE); ++ net.minecraft.client.renderer.RenderHelper.disableStandardItemLighting(); ++ GlStateManager.blendFunc(org.lwjgl.opengl.GL11.GL_SRC_ALPHA, org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA); ++ GlStateManager.enableBlend(); ++ GlStateManager.disableCull(); ++ ++ if (net.minecraft.client.Minecraft.isAmbientOcclusionEnabled()) { ++ GlStateManager.shadeModel(org.lwjgl.opengl.GL11.GL_SMOOTH); ++ } else { ++ GlStateManager.shadeModel(org.lwjgl.opengl.GL11.GL_FLAT); ++ } ++ ++ if(pass > 0) { ++ net.minecraft.util.math.Vec3d cameraPos = net.minecraft.client.renderer.ActiveRenderInfo.getCameraPosition(); ++ batchBuffer.getBuffer().sortVertexData((float)cameraPos.x, (float)cameraPos.y, (float)cameraPos.z); ++ } ++ batchBuffer.draw(); ++ ++ net.minecraft.client.renderer.RenderHelper.enableStandardItemLighting(); ++ drawingBatch = false; ++ } + } diff --git a/module/minecraft/patches/net/minecraft/client/renderer/tileentity/TileEntitySpecialRenderer.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/tileentity/TileEntitySpecialRenderer.java.patch new file mode 100644 index 000000000..157dfa8c1 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/tileentity/TileEntitySpecialRenderer.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/client/renderer/tileentity/TileEntitySpecialRenderer.java ++++ modified/net/minecraft/client/renderer/tileentity/TileEntitySpecialRenderer.java +@@ -75,6 +75,8 @@ + return false; + } + ++ public void renderTileEntityFast(T te, double x, double y, double z, float partialTicks, int destroyStage, float partial, net.minecraft.client.renderer.BufferBuilder buffer) {} ++ + protected void drawNameplate(T te, String str, double x, double y, double z, int maxDistance) { + Entity entity = this.rendererDispatcher.entity; + double d0 = te.getDistanceSq(entity.posX, entity.posY, entity.posZ); diff --git a/module/minecraft/patches/net/minecraft/client/renderer/vertex/VertexFormat.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/vertex/VertexFormat.java.patch new file mode 100644 index 000000000..cac3b0b33 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/vertex/VertexFormat.java.patch @@ -0,0 +1,39 @@ +--- original/net/minecraft/client/renderer/vertex/VertexFormat.java ++++ modified/net/minecraft/client/renderer/vertex/VertexFormat.java +@@ -17,6 +17,7 @@ + private int colorElementOffset = -1; + private final List uvOffsetsById = Lists.newArrayList(); + private int normalElementOffset = -1; ++ private int hashCode; + + public VertexFormat(VertexFormat vertexFormatIn) { + this(); +@@ -38,6 +39,7 @@ + this.uvOffsetsById.clear(); + this.normalElementOffset = -1; + this.vertexSize = 0; ++ this.hashCode = 0; + } + + public VertexFormat addElement(VertexFormatElement element) { +@@ -60,6 +62,7 @@ + } + + this.vertexSize = this.vertexSize + element.getSize(); ++ this.hashCode = 0; + return this; + } + +@@ -158,8 +161,11 @@ + + @Override + public int hashCode() { ++ if (this.hashCode != 0) return this.hashCode; + int i = this.elements.hashCode(); + i = 31 * i + this.offsets.hashCode(); +- return 31 * i + this.vertexSize; ++ i = 31 * i + this.vertexSize; ++ this.hashCode = i; ++ return i; + } + } diff --git a/module/minecraft/patches/net/minecraft/client/renderer/vertex/VertexFormatElement.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/vertex/VertexFormatElement.java.patch new file mode 100644 index 000000000..c7c0cb7f5 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/vertex/VertexFormatElement.java.patch @@ -0,0 +1,21 @@ +--- original/net/minecraft/client/renderer/vertex/VertexFormatElement.java ++++ modified/net/minecraft/client/renderer/vertex/VertexFormatElement.java +@@ -126,10 +126,17 @@ + NORMAL("Normal"), + COLOR("Vertex Color"), + UV("UV"), ++ // As of 1.8.8 - unused in vanilla; use GENERIC for now ++ @Deprecated + MATRIX("Bone Matrix"), ++ @Deprecated + BLEND_WEIGHT("Blend Weight"), +- PADDING("Padding"); ++ PADDING("Padding"), ++ GENERIC("Generic"); + ++ public void preDraw(VertexFormat format, int element, int stride, java.nio.ByteBuffer buffer) { net.minecraftforge.client.ForgeHooksClient.preDraw(this, format, element, stride, buffer); } ++ public void postDraw(VertexFormat format, int element, int stride, java.nio.ByteBuffer buffer) { net.minecraftforge.client.ForgeHooksClient.postDraw(this, format, element, stride, buffer); } ++ + private final String displayName; + + EnumUsage(String displayNameIn) { diff --git a/module/minecraft/patches/net/minecraft/client/resources/AbstractResourcePack.java.patch b/module/minecraft/patches/net/minecraft/client/resources/AbstractResourcePack.java.patch new file mode 100644 index 000000000..588ac65ce --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/resources/AbstractResourcePack.java.patch @@ -0,0 +1,20 @@ +--- original/net/minecraft/client/resources/AbstractResourcePack.java ++++ modified/net/minecraft/client/resources/AbstractResourcePack.java +@@ -66,7 +66,7 @@ + + try { + bufferedreader = new BufferedReader(new InputStreamReader(p_110596_1_, StandardCharsets.UTF_8)); +- jsonobject = new JsonParser().parse(bufferedreader).getAsJsonObject(); ++ jsonobject = JsonParser.parseReader(bufferedreader).getAsJsonObject(); + } catch (RuntimeException runtimeexception) { + throw new JsonParseException(runtimeexception); + } finally { +@@ -85,4 +85,8 @@ + public String getPackName() { + return this.resourcePackFile.getName(); + } ++ ++ public File getResourcePackFile() { ++ return resourcePackFile; ++ } + } diff --git a/module/minecraft/patches/net/minecraft/client/resources/FallbackResourceManager.java.patch b/module/minecraft/patches/net/minecraft/client/resources/FallbackResourceManager.java.patch new file mode 100644 index 000000000..d77f1031c --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/resources/FallbackResourceManager.java.patch @@ -0,0 +1,10 @@ +--- original/net/minecraft/client/resources/FallbackResourceManager.java ++++ modified/net/minecraft/client/resources/FallbackResourceManager.java +@@ -124,6 +124,7 @@ + this.isClosed = true; + } + ++ @SuppressWarnings("removal") + @Override + protected void finalize() throws Throwable { + if (!this.isClosed) { diff --git a/module/minecraft/patches/net/minecraft/client/resources/IResourceManagerReloadListener.java.patch b/module/minecraft/patches/net/minecraft/client/resources/IResourceManagerReloadListener.java.patch new file mode 100644 index 000000000..7968ba3cf --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/resources/IResourceManagerReloadListener.java.patch @@ -0,0 +1,14 @@ +--- original/net/minecraft/client/resources/IResourceManagerReloadListener.java ++++ modified/net/minecraft/client/resources/IResourceManagerReloadListener.java +@@ -3,6 +3,11 @@ + import net.minecraftforge.fml.relauncher.Side; + import net.minecraftforge.fml.relauncher.SideOnly; + ++/** ++ * @deprecated Forge: {@link net.minecraftforge.client.resource.ISelectiveResourceReloadListener}, which selectively allows ++ * individual resource types being reloaded should rather be used where possible. ++ */ ++@Deprecated + @SideOnly(Side.CLIENT) + public interface IResourceManagerReloadListener { + void onResourceManagerReload(IResourceManager var1); diff --git a/module/minecraft/patches/net/minecraft/client/resources/Language.java.patch b/module/minecraft/patches/net/minecraft/client/resources/Language.java.patch new file mode 100644 index 000000000..7c081d991 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/resources/Language.java.patch @@ -0,0 +1,24 @@ +--- original/net/minecraft/client/resources/Language.java ++++ modified/net/minecraft/client/resources/Language.java +@@ -15,6 +15,12 @@ + this.region = regionIn; + this.name = nameIn; + this.bidirectional = bidirectionalIn; ++ String[] splitLangCode = languageCode.split("_", 2); ++ if (splitLangCode.length == 1) { // Vanilla has some languages without underscores ++ this.javaLocale = new java.util.Locale(languageCode); ++ } else { ++ this.javaLocale = new java.util.Locale(splitLangCode[0], splitLangCode[1]); ++ } + } + + public String getLanguageCode() { +@@ -47,4 +53,8 @@ + public int compareTo(Language p_compareTo_1_) { + return this.languageCode.compareTo(p_compareTo_1_.languageCode); + } ++ ++ // Forge: add access to Locale so modders can create correct string and number formatters ++ private final java.util.Locale javaLocale; ++ public java.util.Locale getJavaLocale() { return javaLocale; } + } diff --git a/module/minecraft/patches/net/minecraft/client/resources/LegacyV2Adapter.java.patch b/module/minecraft/patches/net/minecraft/client/resources/LegacyV2Adapter.java.patch new file mode 100644 index 000000000..5f2f82d4a --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/resources/LegacyV2Adapter.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/client/resources/LegacyV2Adapter.java ++++ modified/net/minecraft/client/resources/LegacyV2Adapter.java +@@ -67,4 +67,8 @@ + public String getPackName() { + return this.pack.getPackName(); + } ++ ++ public IResourcePack getUnadaptedPack() { ++ return pack; ++ } + } diff --git a/module/minecraft/patches/net/minecraft/client/resources/Locale.java.patch b/module/minecraft/patches/net/minecraft/client/resources/Locale.java.patch new file mode 100644 index 000000000..1693e45c2 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/resources/Locale.java.patch @@ -0,0 +1,35 @@ +--- original/net/minecraft/client/resources/Locale.java ++++ modified/net/minecraft/client/resources/Locale.java +@@ -46,23 +46,6 @@ + } + + private void checkUnicode() { +- this.unicode = false; +- int i = 0; +- int j = 0; +- +- for (String s : this.properties.values()) { +- int k = s.length(); +- j += k; +- +- for (int l = 0; l < k; l++) { +- if (s.charAt(l) >= 256) { +- i++; +- } +- } +- } +- +- float f = (float)i / j; +- this.unicode = f > 0.1; + } + + /** Loads the locale data for the list of resources. */ +@@ -79,6 +62,8 @@ + } + + private void loadLocaleData(InputStream inputStreamIn) throws IOException { ++ inputStreamIn = net.minecraftforge.fml.common.FMLCommonHandler.instance().loadLanguage(properties, inputStreamIn); ++ if (inputStreamIn == null) return; + for (String s : IOUtils.readLines(inputStreamIn, StandardCharsets.UTF_8)) { + if (!s.isEmpty() && s.charAt(0) != '#') { + String[] astring = Iterables.toArray(SPLITTER.split(s), String.class); diff --git a/module/minecraft/patches/net/minecraft/client/resources/ResourceIndex.java.patch b/module/minecraft/patches/net/minecraft/client/resources/ResourceIndex.java.patch new file mode 100644 index 000000000..38bb061be --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/resources/ResourceIndex.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/client/resources/ResourceIndex.java ++++ modified/net/minecraft/client/resources/ResourceIndex.java +@@ -36,7 +36,7 @@ + + try { + bufferedreader = Files.newReader(file2, StandardCharsets.UTF_8); +- JsonObject jsonobject = new JsonParser().parse(bufferedreader).getAsJsonObject(); ++ JsonObject jsonobject = JsonParser.parseReader(bufferedreader).getAsJsonObject(); + JsonObject jsonobject1 = JsonUtils.getJsonObject(jsonobject, "objects", null); + if (jsonobject1 != null) { + for (Entry entry : jsonobject1.entrySet()) { diff --git a/module/minecraft/patches/net/minecraft/client/resources/ResourcePackRepository.java.patch b/module/minecraft/patches/net/minecraft/client/resources/ResourcePackRepository.java.patch new file mode 100644 index 000000000..855127eb4 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/resources/ResourcePackRepository.java.patch @@ -0,0 +1,32 @@ +--- original/net/minecraft/client/resources/ResourcePackRepository.java ++++ modified/net/minecraft/client/resources/ResourcePackRepository.java +@@ -240,7 +240,7 @@ + FileUtils.deleteQuietly(file1); + settablefuture.setException(p_onFailure_1_); + } +- }); ++ }, Runnable::run); + return this.downloadingPacks; + } finally { + this.lock.unlock(); +@@ -248,8 +248,10 @@ + } + + private boolean checkHash(String p_190113_1_, File p_190113_2_) { ++ java.io.InputStream is = null; + try { +- String s = DigestUtils.sha1Hex(new FileInputStream(p_190113_2_)); ++ String s = DigestUtils.sha1Hex(is = new FileInputStream(p_190113_2_)); ++ + if (p_190113_1_.isEmpty()) { + LOGGER.info("Found file {} without verification hash", p_190113_2_); + return true; +@@ -263,7 +265,7 @@ + LOGGER.warn("File {} had wrong hash (expected {}, found {}).", p_190113_2_, p_190113_1_, s); + } catch (IOException ioexception) { + LOGGER.warn("File {} couldn't be hashed.", p_190113_2_, ioexception); +- } ++ } finally { IOUtils.closeQuietly(is); } // Forge: close stream after use + + return false; + } diff --git a/module/minecraft/patches/net/minecraft/client/resources/SimpleReloadableResourceManager.java.patch b/module/minecraft/patches/net/minecraft/client/resources/SimpleReloadableResourceManager.java.patch new file mode 100644 index 000000000..6c98a25ee --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/resources/SimpleReloadableResourceManager.java.patch @@ -0,0 +1,43 @@ +--- original/net/minecraft/client/resources/SimpleReloadableResourceManager.java ++++ modified/net/minecraft/client/resources/SimpleReloadableResourceManager.java +@@ -79,6 +79,7 @@ + /** Releases all current resource packs, loads the given list, then triggers all listeners */ + @Override + public void reloadResources(List resourcesPacksList) { ++ net.minecraftforge.fml.common.ProgressManager.ProgressBar resReload = net.minecraftforge.fml.common.ProgressManager.push("Loading Resources", resourcesPacksList.size()+1, true); + this.clearResources(); + LOGGER.info("Reloading ResourceManager: {}", JOINER_RESOURCE_PACKS.join(Iterables.transform(resourcesPacksList, new Function() { + public String apply(@Nullable IResourcePack p_apply_1_) { +@@ -87,22 +88,32 @@ + }))); + + for (IResourcePack iresourcepack : resourcesPacksList) { ++ resReload.step(iresourcepack.getPackName()); + this.reloadResourcePack(iresourcepack); + } + ++ resReload.step("Reloading listeners"); + this.notifyReloadListeners(); ++ net.minecraftforge.fml.common.ProgressManager.pop(resReload); + } + + /** Registers a listener to be invoked every time the resource manager reloads. NOTE: The listener is immediately invoked once when it is registered. */ + @Override + public void registerReloadListener(IResourceManagerReloadListener reloadListener) { ++ net.minecraftforge.fml.common.ProgressManager.ProgressBar resReload = net.minecraftforge.fml.common.ProgressManager.push("Loading Resource", 1); ++ resReload.step(reloadListener.getClass()); + this.reloadListeners.add(reloadListener); + reloadListener.onResourceManagerReload(this); ++ net.minecraftforge.fml.common.ProgressManager.pop(resReload); + } + + private void notifyReloadListeners() { ++ net.minecraftforge.fml.common.ProgressManager.ProgressBar resReload = net.minecraftforge.fml.common.ProgressManager.push("Reloading", this.reloadListeners.size()); + for (IResourceManagerReloadListener iresourcemanagerreloadlistener : this.reloadListeners) { ++ resReload.step(iresourcemanagerreloadlistener.getClass()); ++ if (!net.minecraftforge.client.ForgeHooksClient.shouldUseVanillaReloadableListener(iresourcemanagerreloadlistener)) continue; // Forge: Selective reloading for vanilla listeners + iresourcemanagerreloadlistener.onResourceManagerReload(this); + } ++ net.minecraftforge.fml.common.ProgressManager.pop(resReload); + } + } diff --git a/module/minecraft/patches/net/minecraft/client/resources/SimpleResource.java.patch b/module/minecraft/patches/net/minecraft/client/resources/SimpleResource.java.patch new file mode 100644 index 000000000..7b4a59b54 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/resources/SimpleResource.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/client/resources/SimpleResource.java ++++ modified/net/minecraft/client/resources/SimpleResource.java +@@ -64,7 +64,7 @@ + + try { + bufferedreader = new BufferedReader(new InputStreamReader(this.mcmetaInputStream, StandardCharsets.UTF_8)); +- this.mcmetaJson = new JsonParser().parse(bufferedreader).getAsJsonObject(); ++ this.mcmetaJson = JsonParser.parseReader(bufferedreader).getAsJsonObject(); + } finally { + IOUtils.closeQuietly(bufferedreader); + } diff --git a/module/minecraft/patches/net/minecraft/client/settings/GameSettings.java.patch b/module/minecraft/patches/net/minecraft/client/settings/GameSettings.java.patch new file mode 100644 index 000000000..0786a4277 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/settings/GameSettings.java.patch @@ -0,0 +1,156 @@ +--- original/net/minecraft/client/settings/GameSettings.java ++++ modified/net/minecraft/client/settings/GameSettings.java +@@ -65,6 +65,7 @@ + } + }; + public static final Splitter COLON_SPLITTER = Splitter.on(':'); ++ @Deprecated + /** GUI scale values */ + private static final String[] GUISCALES = new String[]{ + "options.guiScale.auto", "options.guiScale.small", "options.guiScale.normal", "options.guiScale.large" +@@ -216,6 +217,7 @@ + public boolean forceUnicodeFont; + + public GameSettings(Minecraft mcIn, File mcDataDir) { ++ setForgeKeybindProperties(); + this.mc = mcIn; + this.optionsFile = new File(mcDataDir, "options.txt"); + if (mcIn.isJava64bit() && Runtime.getRuntime().maxMemory() >= 1000000000L) { +@@ -229,6 +231,7 @@ + } + + public GameSettings() { ++ setForgeKeybindProperties(); + } + + /** Gets the display name for a key. */ +@@ -315,7 +318,7 @@ + this.mc.getTextureMapBlocks().setMipmapLevels(this.mipmapLevels); + this.mc.getTextureManager().bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); + this.mc.getTextureMapBlocks().setBlurMipmapDirect(false, this.mipmapLevels > 0); +- this.mc.scheduleResourcesRefresh(); ++ this.needsBlockModelRefresh = true; // FORGE: fix for MC-64581 very laggy mipmap slider + } + } + +@@ -340,7 +343,11 @@ + } + + if (settingsOption == GameSettings.Options.GUI_SCALE) { +- this.guiScale = this.guiScale + value & 3; ++ int maxScale = 1; ++ while (this.mc.displayWidth / (maxScale + 1) >= 320 && this.mc.displayHeight / (maxScale + 1) >= 240) { ++ maxScale++; ++ } ++ this.guiScale = (this.guiScale + value) % (maxScale + 1); + } + + if (settingsOption == GameSettings.Options.PARTICLES) { +@@ -366,7 +373,7 @@ + + if (settingsOption == GameSettings.Options.ANAGLYPH) { + this.anaglyph = !this.anaglyph; +- this.mc.refreshResources(); ++ net.minecraftforge.fml.client.FMLClientHandler.instance().refreshResources(net.minecraftforge.client.resource.VanillaResourceType.TEXTURES); + } + + if (settingsOption == GameSettings.Options.GRAPHICS) { +@@ -603,7 +610,7 @@ + } + + if (settingOption == GameSettings.Options.GUI_SCALE) { +- return s + getTranslation(GUISCALES, this.guiScale); ++ return s + (this.guiScale == 0 ? I18n.format("options.guiScale.auto") : this.guiScale); + } + + if (settingOption == GameSettings.Options.CHAT_VISIBILITY) { +@@ -643,13 +650,14 @@ + + /** Loads the options from the options file. It appears that this has replaced the previous 'loadOptions' */ + public void loadOptions() { ++ FileInputStream fileInputStream = null; // Forge: fix MC-151173 + try { + if (!this.optionsFile.exists()) { + return; + } + + this.soundLevels.clear(); +- List list = IOUtils.readLines(new FileInputStream(this.optionsFile)); ++ List list = IOUtils.readLines(fileInputStream = new FileInputStream(this.optionsFile), StandardCharsets.UTF_8); // Forge: fix MC-117449, MC-151173 + NBTTagCompound nbttagcompound = new NBTTagCompound(); + + for (String s : list) { +@@ -905,7 +913,11 @@ + + for (KeyBinding keybinding : this.keyBindings) { + if (s1.equals("key_" + keybinding.getKeyDescription())) { +- keybinding.setKeyCode(Integer.parseInt(s2)); ++ if (s2.indexOf(':') != -1) { ++ String[] t = s2.split(":"); ++ keybinding.setKeyModifierAndCode(net.minecraftforge.client.settings.KeyModifier.valueFromString(t[1]), Integer.parseInt(t[0])); ++ } else ++ keybinding.setKeyModifierAndCode(net.minecraftforge.client.settings.KeyModifier.NONE, Integer.parseInt(s2)); + } + } + +@@ -928,7 +940,7 @@ + KeyBinding.resetKeyBindingArrayAndHash(); + } catch (Exception exception2) { + LOGGER.error("Failed to load options", exception2); +- } ++ } finally { IOUtils.closeQuietly(fileInputStream); } // Forge: fix MC-151173 + } + + private NBTTagCompound dataFix(NBTTagCompound p_189988_1_) { +@@ -953,6 +965,7 @@ + + /** Saves the options to the options file. */ + public void saveOptions() { ++ if (net.minecraftforge.fml.client.FMLClientHandler.instance().isLoading()) return; + PrintWriter printwriter = null; + + try { +@@ -1023,7 +1036,8 @@ + printwriter.println("tutorialStep:" + this.tutorialStep.getName()); + + for (KeyBinding keybinding : this.keyBindings) { +- printwriter.println("key_" + keybinding.getKeyDescription() + ":" + keybinding.getKeyCode()); ++ String keyString = "key_" + keybinding.getKeyDescription() + ":" + keybinding.getKeyCode(); ++ printwriter.println(keybinding.getKeyModifier() != net.minecraftforge.client.settings.KeyModifier.NONE ? keyString + ":" + keybinding.getKeyModifier() : keyString); + } + + for (SoundCategory soundcategory : SoundCategory.values()) { +@@ -1226,4 +1240,33 @@ + return value; + } + } ++ ++ /******* Forge Start ***********/ ++ private void setForgeKeybindProperties() { ++ net.minecraftforge.client.settings.KeyConflictContext inGame = net.minecraftforge.client.settings.KeyConflictContext.IN_GAME; ++ keyBindForward.setKeyConflictContext(inGame); ++ keyBindLeft.setKeyConflictContext(inGame); ++ keyBindBack.setKeyConflictContext(inGame); ++ keyBindRight.setKeyConflictContext(inGame); ++ keyBindJump.setKeyConflictContext(inGame); ++ keyBindSneak.setKeyConflictContext(inGame); ++ keyBindSprint.setKeyConflictContext(inGame); ++ keyBindAttack.setKeyConflictContext(inGame); ++ keyBindChat.setKeyConflictContext(inGame); ++ keyBindPlayerList.setKeyConflictContext(inGame); ++ keyBindCommand.setKeyConflictContext(inGame); ++ keyBindTogglePerspective.setKeyConflictContext(inGame); ++ keyBindSmoothCamera.setKeyConflictContext(inGame); ++ keyBindSwapHands.setKeyConflictContext(inGame); ++ } ++ ++ // FORGE: fix for MC-64581 very laggy mipmap slider ++ private boolean needsBlockModelRefresh = false; ++ public void onGuiClosed() { ++ if (needsBlockModelRefresh) { ++ net.minecraftforge.fml.client.FMLClientHandler.instance().scheduleResourcesRefresh(net.minecraftforge.client.resource.VanillaResourceType.MODELS); ++ this.needsBlockModelRefresh = false; ++ } ++ } ++ /******* Forge End ***********/ + } diff --git a/module/minecraft/patches/net/minecraft/client/settings/KeyBinding.java.patch b/module/minecraft/patches/net/minecraft/client/settings/KeyBinding.java.patch new file mode 100644 index 000000000..700bd67a3 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/settings/KeyBinding.java.patch @@ -0,0 +1,182 @@ +--- original/net/minecraft/client/settings/KeyBinding.java ++++ modified/net/minecraft/client/settings/KeyBinding.java +@@ -14,7 +14,7 @@ + @SideOnly(Side.CLIENT) + public class KeyBinding implements Comparable { + private static final Map KEYBIND_ARRAY = Maps.newHashMap(); +- private static final IntHashMap HASH = new IntHashMap<>(); ++ private static final net.minecraftforge.client.settings.KeyBindingMap HASH = new net.minecraftforge.client.settings.KeyBindingMap(); + private static final Set KEYBIND_SET = Sets.newHashSet(); + /** A map that assigns priorities to all categories, for ordering purposes. */ + private static final Map CATEGORY_ORDER = Maps.newHashMap(); +@@ -28,16 +28,14 @@ + + public static void onTick(int keyCode) { + if (keyCode != 0) { +- KeyBinding keybinding = HASH.lookup(keyCode); +- if (keybinding != null) { +- keybinding.pressTime++; +- } ++ HASH.lookupActives(keyCode).forEach($ -> ++$.pressTime); + } + } + + public static void setKeyBindState(int keyCode, boolean pressed) { + if (keyCode != 0) { +- KeyBinding keybinding = HASH.lookup(keyCode); ++ for (KeyBinding keybinding : HASH.lookupAll(keyCode)) ++ + if (keybinding != null) { + keybinding.pressed = pressed; + } +@@ -84,7 +82,7 @@ + + /** Returns true if the key is pressed (used for continuous querying). Should be used in tickers. */ + public boolean isKeyDown() { +- return this.pressed; ++ return this.pressed && getKeyConflictContext().isActive() && getKeyModifier().isActive(getKeyConflictContext()); + } + + public String getKeyCategory() { +@@ -123,19 +121,137 @@ + } + + public int compareTo(KeyBinding p_compareTo_1_) { +- return this.keyCategory.equals(p_compareTo_1_.keyCategory) +- ? I18n.format(this.keyDescription).compareTo(I18n.format(p_compareTo_1_.keyDescription)) +- : CATEGORY_ORDER.get(this.keyCategory).compareTo(CATEGORY_ORDER.get(p_compareTo_1_.keyCategory)); ++ if (this.keyCategory.equals(p_compareTo_1_.keyCategory)) return I18n.format(this.keyDescription).compareTo(I18n.format(p_compareTo_1_.keyDescription)); ++ Integer tCat = CATEGORY_ORDER.get(this.keyCategory); ++ Integer oCat = CATEGORY_ORDER.get(p_compareTo_1_.keyCategory); ++ if (tCat == null && oCat != null) return 1; ++ if (tCat != null && oCat == null) return -1; ++ if (tCat == null && oCat == null) return I18n.format(this.keyCategory).compareTo(I18n.format(p_compareTo_1_.keyCategory)); ++ return tCat.compareTo(oCat); + } + ++ /****************** Forge Start *****************************/ ++ private net.minecraftforge.client.settings.KeyModifier keyModifierDefault = net.minecraftforge.client.settings.KeyModifier.NONE; ++ private net.minecraftforge.client.settings.KeyModifier keyModifier = net.minecraftforge.client.settings.KeyModifier.NONE; ++ private net.minecraftforge.client.settings.IKeyConflictContext keyConflictContext = net.minecraftforge.client.settings.KeyConflictContext.UNIVERSAL; ++ + /** ++ * Convenience constructor for creating KeyBindings with keyConflictContext set. ++ */ ++ public KeyBinding(String description, net.minecraftforge.client.settings.IKeyConflictContext keyConflictContext, int keyCode, String category) { ++ this(description, keyConflictContext, net.minecraftforge.client.settings.KeyModifier.NONE, keyCode, category); ++ } ++ ++ /** ++ * Convenience constructor for creating KeyBindings with keyConflictContext and keyModifier set. ++ */ ++ public KeyBinding(String description, net.minecraftforge.client.settings.IKeyConflictContext keyConflictContext, net.minecraftforge.client.settings.KeyModifier keyModifier, int keyCode, String category) { ++ this.keyDescription = description; ++ this.keyCode = keyCode; ++ this.keyCodeDefault = keyCode; ++ this.keyCategory = category; ++ this.keyConflictContext = keyConflictContext; ++ this.keyModifier = keyModifier; ++ this.keyModifierDefault = keyModifier; ++ if (this.keyModifier.matches(keyCode)) { ++ this.keyModifier = net.minecraftforge.client.settings.KeyModifier.NONE; ++ } ++ KEYBIND_ARRAY.put(description, this); ++ HASH.addKey(keyCode, this); ++ KEYBIND_SET.add(category); ++ } ++ ++ /** ++ * Checks that the key conflict context and modifier are active, and that the keyCode matches this binding. ++ */ ++ public boolean isActiveAndMatches(int keyCode) { ++ return keyCode != 0 && keyCode == this.getKeyCode() && getKeyConflictContext().isActive() && getKeyModifier().isActive(getKeyConflictContext()); ++ } ++ ++ public void setKeyConflictContext(net.minecraftforge.client.settings.IKeyConflictContext keyConflictContext) { ++ this.keyConflictContext = keyConflictContext; ++ } ++ ++ public net.minecraftforge.client.settings.IKeyConflictContext getKeyConflictContext() { ++ return keyConflictContext; ++ } ++ ++ public net.minecraftforge.client.settings.KeyModifier getKeyModifierDefault() { ++ return keyModifierDefault; ++ } ++ ++ public net.minecraftforge.client.settings.KeyModifier getKeyModifier() { ++ return keyModifier; ++ } ++ ++ public void setKeyModifierAndCode(net.minecraftforge.client.settings.KeyModifier keyModifier, int keyCode) { ++ this.keyCode = keyCode; ++ if (keyModifier.matches(keyCode)) { ++ keyModifier = net.minecraftforge.client.settings.KeyModifier.NONE; ++ } ++ HASH.removeKey(this); ++ this.keyModifier = keyModifier; ++ HASH.addKey(keyCode, this); ++ } ++ ++ public void setToDefault() { ++ setKeyModifierAndCode(getKeyModifierDefault(), getKeyCodeDefault()); ++ } ++ ++ public boolean isSetToDefaultValue() { ++ return getKeyCode() == getKeyCodeDefault() && getKeyModifier() == getKeyModifierDefault(); ++ } ++ ++ /** ++ * Returns true when the other keyBinding conflicts with this one ++ */ ++ public boolean conflicts(KeyBinding other) { ++ if (getKeyConflictContext().conflicts(other.getKeyConflictContext()) || other.getKeyConflictContext().conflicts(getKeyConflictContext())) { ++ net.minecraftforge.client.settings.KeyModifier keyModifier = getKeyModifier(); ++ net.minecraftforge.client.settings.KeyModifier otherKeyModifier = other.getKeyModifier(); ++ if (keyModifier.matches(other.getKeyCode()) || otherKeyModifier.matches(getKeyCode())) { ++ return true; ++ } else if (getKeyCode() == other.getKeyCode()) { ++ return keyModifier == otherKeyModifier || ++ // IN_GAME key contexts have a conflict when at least one modifier is NONE. ++ // For example: If you hold shift to crouch, you can still press E to open your inventory. This means that a Shift+E hotkey is in conflict with E. ++ // GUI and other key contexts do not have this limitation. ++ (getKeyConflictContext().conflicts(net.minecraftforge.client.settings.KeyConflictContext.IN_GAME) && ++ (keyModifier == net.minecraftforge.client.settings.KeyModifier.NONE || otherKeyModifier == net.minecraftforge.client.settings.KeyModifier.NONE)); ++ } ++ } ++ return false; ++ } ++ ++ /** ++ * Returns true when one of the bindings' key codes conflicts with the other's modifier. ++ */ ++ public boolean hasKeyCodeModifierConflict(KeyBinding other) { ++ if (getKeyConflictContext().conflicts(other.getKeyConflictContext()) || other.getKeyConflictContext().conflicts(getKeyConflictContext())) { ++ if (getKeyModifier().matches(other.getKeyCode()) || other.getKeyModifier().matches(getKeyCode())) { ++ return true; ++ } ++ } ++ return false; ++ } ++ ++ public String getDisplayName() { ++ return getKeyModifier().getLocalizedComboName(getKeyCode()); ++ } ++ /****************** Forge End *****************************/ ++ ++ /** + * Returns a supplier which gets a keybind's current binding (eg, key.forward returns W by default), or the keybind's name if no such keybind exists (eg, key.invalid returns key.invalid) + * + * @param key The description of the key (eg, key.forward). + */ + public static Supplier getDisplayString(String key) { + KeyBinding keybinding = KEYBIND_ARRAY.get(key); +- return keybinding == null ? () -> key : () -> GameSettings.getKeyDisplayString(keybinding.getKeyCode()); ++ return keybinding == null ? () -> { ++ return key; ++ } : () -> { ++ return keybinding.getDisplayName(); ++ }; + } + + static { diff --git a/module/minecraft/patches/net/minecraft/client/shader/Framebuffer.java.patch b/module/minecraft/patches/net/minecraft/client/shader/Framebuffer.java.patch new file mode 100644 index 000000000..a3ea0731a --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/shader/Framebuffer.java.patch @@ -0,0 +1,52 @@ +--- original/net/minecraft/client/shader/Framebuffer.java ++++ modified/net/minecraft/client/shader/Framebuffer.java +@@ -94,8 +94,14 @@ + OpenGlHelper.glFramebufferTexture2D(OpenGlHelper.GL_FRAMEBUFFER, OpenGlHelper.GL_COLOR_ATTACHMENT0, 3553, this.framebufferTexture, 0); + if (this.useDepth) { + OpenGlHelper.glBindRenderbuffer(OpenGlHelper.GL_RENDERBUFFER, this.depthBuffer); ++ if (!this.stencilEnabled) { + OpenGlHelper.glRenderbufferStorage(OpenGlHelper.GL_RENDERBUFFER, 33190, this.framebufferTextureWidth, this.framebufferTextureHeight); + OpenGlHelper.glFramebufferRenderbuffer(OpenGlHelper.GL_FRAMEBUFFER, OpenGlHelper.GL_DEPTH_ATTACHMENT, OpenGlHelper.GL_RENDERBUFFER, this.depthBuffer); ++ } else { ++ OpenGlHelper.glRenderbufferStorage(OpenGlHelper.GL_RENDERBUFFER, org.lwjgl.opengl.EXTPackedDepthStencil.GL_DEPTH24_STENCIL8_EXT, this.framebufferTextureWidth, this.framebufferTextureHeight); ++ OpenGlHelper.glFramebufferRenderbuffer(OpenGlHelper.GL_FRAMEBUFFER, org.lwjgl.opengl.EXTFramebufferObject.GL_DEPTH_ATTACHMENT_EXT, OpenGlHelper.GL_RENDERBUFFER, this.depthBuffer); ++ OpenGlHelper.glFramebufferRenderbuffer(OpenGlHelper.GL_FRAMEBUFFER, org.lwjgl.opengl.EXTFramebufferObject.GL_STENCIL_ATTACHMENT_EXT, OpenGlHelper.GL_RENDERBUFFER, this.depthBuffer); ++ } + } + + this.framebufferClear(); +@@ -222,4 +228,34 @@ + GlStateManager.clear(i); + this.unbindFramebuffer(); + } ++ ++ /*================================ FORGE START ================================================*/ ++ private boolean stencilEnabled = false; ++ /** ++ * Attempts to enabled 8 bits of stencil buffer on this FrameBuffer. ++ * Modders must call this directly to set things up. ++ * This is to prevent the default cause where graphics cards do not support stencil bits. ++ * Modders should check the below 'isStencilEnabled' to check if another modder has already enabled them. ++ * ++ * Note: ++ * As of now the only thing that is checked is if FBOs are supported entirely, in the future ++ * we may expand to check for errors. ++ * ++ * @return True if the FBO was re-initialized with stencil bits. ++ */ ++ public boolean enableStencil() { ++ if (!OpenGlHelper.isFramebufferEnabled()) return false; ++ stencilEnabled = true; ++ this.createBindFramebuffer(framebufferWidth, framebufferHeight); ++ return true; //TODO: Find a way to detect if this failed? ++ } ++ ++ /** ++ * Returns wither or not this FBO has been successfully initialized with stencil bits. ++ * If not, and a modder wishes it to be, they must call enableStencil. ++ */ ++ public boolean isStencilEnabled() { ++ return this.stencilEnabled; ++ } ++ /*================================ FORGE END ================================================*/ + } diff --git a/module/minecraft/patches/net/minecraft/client/shader/ShaderGroup.java.patch b/module/minecraft/patches/net/minecraft/client/shader/ShaderGroup.java.patch new file mode 100644 index 000000000..754b21e57 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/shader/ShaderGroup.java.patch @@ -0,0 +1,26 @@ +--- original/net/minecraft/client/shader/ShaderGroup.java ++++ modified/net/minecraft/client/shader/ShaderGroup.java +@@ -52,12 +52,11 @@ + } + + public void parseGroup(TextureManager p_152765_1_, ResourceLocation p_152765_2_) throws JsonSyntaxException, IOException, JsonException { +- JsonParser jsonparser = new JsonParser(); + IResource iresource = null; + + try { + iresource = this.resourceManager.getResource(p_152765_2_); +- JsonObject jsonobject = jsonparser.parse(IOUtils.toString(iresource.getInputStream(), StandardCharsets.UTF_8)).getAsJsonObject(); ++ JsonObject jsonobject = JsonParser.parseString(IOUtils.toString(iresource.getInputStream(), StandardCharsets.UTF_8)).getAsJsonObject(); + if (JsonUtils.isJsonArray(jsonobject, "targets")) { + JsonArray jsonarray = jsonobject.getAsJsonArray("targets"); + int i = 0; +@@ -143,7 +142,8 @@ + String s3 = JsonUtils.getString(jsonobject1, "id"); + Framebuffer framebuffer2 = this.getFramebuffer(s3); + if (framebuffer2 == null) { +- ResourceLocation resourcelocation = new ResourceLocation("textures/effect/" + s3 + ".png"); ++ String[] rl = ResourceLocation.splitObjectName(s3); ++ ResourceLocation resourcelocation = new ResourceLocation(rl[0], "textures/effect/" + rl[1] + ".png"); + IResource iresource = null; + + try { diff --git a/module/minecraft/patches/net/minecraft/client/shader/ShaderLoader.java.patch b/module/minecraft/patches/net/minecraft/client/shader/ShaderLoader.java.patch new file mode 100644 index 000000000..e9a8f5889 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/shader/ShaderLoader.java.patch @@ -0,0 +1,12 @@ +--- original/net/minecraft/client/shader/ShaderLoader.java ++++ modified/net/minecraft/client/shader/ShaderLoader.java +@@ -50,7 +50,8 @@ + public static ShaderLoader loadShader(IResourceManager resourceManager, ShaderLoader.ShaderType type, String filename) throws IOException { + ShaderLoader shaderloader = type.getLoadedShaders().get(filename); + if (shaderloader == null) { +- ResourceLocation resourcelocation = new ResourceLocation("shaders/program/" + filename + type.getShaderExtension()); ++ String[] rl = ResourceLocation.splitObjectName(filename); ++ ResourceLocation resourcelocation = new ResourceLocation(rl[0], "shaders/program/" + rl[1] + type.getShaderExtension()); + IResource iresource = resourceManager.getResource(resourcelocation); + + try { diff --git a/module/minecraft/patches/net/minecraft/client/shader/ShaderManager.java.patch b/module/minecraft/patches/net/minecraft/client/shader/ShaderManager.java.patch new file mode 100644 index 000000000..7d82a5d1e --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/shader/ShaderManager.java.patch @@ -0,0 +1,20 @@ +--- original/net/minecraft/client/shader/ShaderManager.java ++++ modified/net/minecraft/client/shader/ShaderManager.java +@@ -51,14 +51,14 @@ + private final ShaderLoader fragmentShaderLoader; + + public ShaderManager(IResourceManager resourceManager, String programName) throws IOException, JsonException { +- JsonParser jsonparser = new JsonParser(); +- ResourceLocation resourcelocation = new ResourceLocation("shaders/program/" + programName + ".json"); ++ String[] rl = ResourceLocation.splitObjectName(programName); ++ ResourceLocation resourcelocation = new ResourceLocation(rl[0], "shaders/program/" + rl[1] + ".json"); + this.programFilename = programName; + IResource iresource = null; + + try { + iresource = resourceManager.getResource(resourcelocation); +- JsonObject jsonobject = jsonparser.parse(IOUtils.toString(iresource.getInputStream(), StandardCharsets.UTF_8)).getAsJsonObject(); ++ JsonObject jsonobject = JsonParser.parseString(IOUtils.toString(iresource.getInputStream(), StandardCharsets.UTF_8)).getAsJsonObject(); + String s = JsonUtils.getString(jsonobject, "vertex"); + String s1 = JsonUtils.getString(jsonobject, "fragment"); + JsonArray jsonarray = JsonUtils.getJsonArray(jsonobject, "samplers", null); diff --git a/module/minecraft/patches/net/minecraft/client/util/RecipeBookClient.java.patch b/module/minecraft/patches/net/minecraft/client/util/RecipeBookClient.java.patch new file mode 100644 index 000000000..8bc2f78f0 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/util/RecipeBookClient.java.patch @@ -0,0 +1,19 @@ +--- original/net/minecraft/client/util/RecipeBookClient.java ++++ modified/net/minecraft/client/util/RecipeBookClient.java +@@ -39,8 +39,15 @@ + } + + static { +- Table table = HashBasedTable.create(); ++ rebuildTable(); ++ } + ++ public static void rebuildTable() { ++ RECIPES_BY_TAB.clear(); ++ ALL_RECIPES.clear(); ++ ++ Table table = HashBasedTable.create(); ++ + for (IRecipe irecipe : CraftingManager.REGISTRY) { + if (!irecipe.isDynamic()) { + CreativeTabs creativetabs = getItemStackTab(irecipe.getRecipeOutput()); diff --git a/module/minecraft/patches/net/minecraft/client/util/RecipeItemHelper.java.patch b/module/minecraft/patches/net/minecraft/client/util/RecipeItemHelper.java.patch new file mode 100644 index 000000000..d82629a50 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/util/RecipeItemHelper.java.patch @@ -0,0 +1,17 @@ +--- original/net/minecraft/client/util/RecipeItemHelper.java ++++ modified/net/minecraft/client/util/RecipeItemHelper.java +@@ -21,9 +21,13 @@ + public final Int2IntMap itemToCount = new Int2IntOpenHashMap(); + + public void accountStack(ItemStack stack) { ++ this.accountStack(stack, -1); ++ } ++ ++ public void accountStack(ItemStack stack, int forceCount) { + if (!stack.isEmpty() && !stack.isItemDamaged() && !stack.isItemEnchanted() && !stack.hasDisplayName()) { + int i = pack(stack); +- int j = stack.getCount(); ++ int j = forceCount == -1 ? stack.getCount() : forceCount; + this.increment(i, j); + } + } diff --git a/module/minecraft/patches/net/minecraft/command/CommandBase.java.patch b/module/minecraft/patches/net/minecraft/command/CommandBase.java.patch new file mode 100644 index 000000000..cad1cd7d3 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/command/CommandBase.java.patch @@ -0,0 +1,12 @@ +--- original/net/minecraft/command/CommandBase.java ++++ modified/net/minecraft/command/CommandBase.java +@@ -294,7 +294,8 @@ + itextcomponent.appendText(" "); + } + +- ITextComponent itextcomponent1 = new TextComponentString(args[i]); ++ ITextComponent itextcomponent1 = net.minecraftforge.common.ForgeHooks.newChatWithLinks(args[i]); // Forge: links for messages ++ + if (p_147176_3_) { + ITextComponent itextcomponent2 = EntitySelector.matchEntitiesToTextComponent(sender, args[i]); + if (itextcomponent2 == null) { diff --git a/module/minecraft/patches/net/minecraft/command/CommandFill.java.patch b/module/minecraft/patches/net/minecraft/command/CommandFill.java.patch new file mode 100644 index 000000000..aebfdaf33 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/command/CommandFill.java.patch @@ -0,0 +1,28 @@ +--- original/net/minecraft/command/CommandFill.java ++++ modified/net/minecraft/command/CommandFill.java +@@ -81,11 +81,12 @@ + } + } + +- NBTTagCompound nbttagcompound = new NBTTagCompound(); +- boolean flag = false; +- if (args.length >= 10 && block.hasTileEntity()) { +- String s = buildString(args, 9); ++ NBTTagCompound nbttagcompound = new NBTTagCompound(); ++ boolean flag = false; + ++ if (args.length >= 10 && block.hasTileEntity(iblockstate)) { ++ String s = buildString(args, 9); ++ + try { + nbttagcompound = JsonToNBT.getTagFromJson(s); + flag = true; +@@ -109,7 +110,7 @@ + if (!world.isAirBlock(blockpos4)) { + continue; + } +- } else if ("replace".equals(args[8]) && !block.hasTileEntity() && args.length > 9) { ++ } else if ("replace".equals(args[8]) && !block.hasTileEntity(iblockstate) && args.length > 9) { + Block block1 = CommandBase.getBlockByText(sender, args[9]); + if (world.getBlockState(blockpos4).getBlock() != block1 + || args.length > 10 diff --git a/module/minecraft/patches/net/minecraft/command/CommandGameRule.java.patch b/module/minecraft/patches/net/minecraft/command/CommandGameRule.java.patch new file mode 100644 index 000000000..14702541e --- /dev/null +++ b/module/minecraft/patches/net/minecraft/command/CommandGameRule.java.patch @@ -0,0 +1,10 @@ +--- original/net/minecraft/command/CommandGameRule.java ++++ modified/net/minecraft/command/CommandGameRule.java +@@ -67,6 +67,7 @@ + entityplayermp.connection.sendPacket(new SPacketEntityStatus(entityplayermp, b0)); + } + } ++ net.minecraftforge.event.ForgeEventFactory.onGameRuleChange(rules, p_184898_1_, server); + } + + /** Get a list of options for when the user presses the TAB key */ diff --git a/module/minecraft/patches/net/minecraft/command/CommandHandler.java.patch b/module/minecraft/patches/net/minecraft/command/CommandHandler.java.patch new file mode 100644 index 000000000..940dd41ce --- /dev/null +++ b/module/minecraft/patches/net/minecraft/command/CommandHandler.java.patch @@ -0,0 +1,18 @@ +--- original/net/minecraft/command/CommandHandler.java ++++ modified/net/minecraft/command/CommandHandler.java +@@ -45,6 +45,15 @@ + textcomponenttranslation1.getStyle().setColor(TextFormatting.RED); + sender.sendMessage(textcomponenttranslation1); + } else if (icommand.checkPermission(this.getServer(), sender)) { ++ net.minecraftforge.event.CommandEvent event = new net.minecraftforge.event.CommandEvent(icommand, sender, astring); ++ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event)) { ++ if (event.getException() != null) { ++ com.google.common.base.Throwables.throwIfUnchecked(event.getException()); ++ } ++ return 1; ++ } ++ if (event.getParameters() != null) astring = event.getParameters(); ++ + if (j > -1) { + List list = EntitySelector.matchEntities(sender, astring[j], Entity.class); + String s1 = astring[j]; diff --git a/module/minecraft/patches/net/minecraft/command/EntitySelector.java.patch b/module/minecraft/patches/net/minecraft/command/EntitySelector.java.patch new file mode 100644 index 000000000..6bc88ed34 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/command/EntitySelector.java.patch @@ -0,0 +1,43 @@ +--- original/net/minecraft/command/EntitySelector.java ++++ modified/net/minecraft/command/EntitySelector.java +@@ -115,6 +115,10 @@ + + /** Returns all entities of the given class that matches the given at-token in a list. */ + public static List matchEntities(ICommandSender sender, String token, Class targetClass) throws CommandException { ++ return net.minecraftforge.common.command.SelectorHandlerManager.matchEntities(sender, token, targetClass); ++ } ++ ++ public static List matchEntitiesDefault(ICommandSender sender, String token, Class targetClass) throws CommandException { + Matcher matcher = TOKEN_PATTERN.matcher(token); + if (matcher.matches() && sender.canUseCommand(1, "@")) { + Map map = getArgumentMap(matcher.group(2)); +@@ -140,6 +144,7 @@ + list2.addAll(getTagPredicates(map)); + list2.addAll(getRadiusPredicates(map, vec3d)); + list2.addAll(getRotationsPredicates(map)); ++ list2.addAll(net.minecraftforge.fml.common.registry.GameRegistry.createEntitySelectors(map, s, sender, vec3d)); + if ("s".equalsIgnoreCase(s)) { + Entity entity = sender.getCommandSenderEntity(); + if (entity != null && targetClass.isAssignableFrom(entity.getClass())) { +@@ -622,6 +627,10 @@ + + /** Returns whether the given pattern can match more than one player. */ + public static boolean matchesMultiplePlayers(String selectorStr) throws CommandException { ++ return net.minecraftforge.common.command.SelectorHandlerManager.matchesMultiplePlayers(selectorStr); ++ } ++ ++ public static boolean matchesMultiplePlayersDefault(String selectorStr) throws CommandException { + Matcher matcher = TOKEN_PATTERN.matcher(selectorStr); + if (!matcher.matches()) { + return false; +@@ -635,6 +644,10 @@ + + /** Returns whether the given string represents a selector. */ + public static boolean isSelector(String selectorStr) { ++ return net.minecraftforge.common.command.SelectorHandlerManager.isSelector(selectorStr); ++ } ++ ++ public static boolean isSelectorDefault(String selectorStr) { + return TOKEN_PATTERN.matcher(selectorStr).matches(); + } + diff --git a/module/minecraft/patches/net/minecraft/command/server/CommandSetBlock.java.patch b/module/minecraft/patches/net/minecraft/command/server/CommandSetBlock.java.patch new file mode 100644 index 000000000..6a2260f3d --- /dev/null +++ b/module/minecraft/patches/net/minecraft/command/server/CommandSetBlock.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/command/server/CommandSetBlock.java ++++ modified/net/minecraft/command/server/CommandSetBlock.java +@@ -63,7 +63,7 @@ + + NBTTagCompound nbttagcompound = new NBTTagCompound(); + boolean flag = false; +- if (args.length >= 7 && block.hasTileEntity()) { ++ if (args.length >= 7 && block.hasTileEntity(iblockstate)) { + String s = buildString(args, 6); + + try { diff --git a/module/minecraft/patches/net/minecraft/crash/CrashReport.java.patch b/module/minecraft/patches/net/minecraft/crash/CrashReport.java.patch new file mode 100644 index 000000000..0c230a0b8 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/crash/CrashReport.java.patch @@ -0,0 +1,26 @@ +--- original/net/minecraft/crash/CrashReport.java ++++ modified/net/minecraft/crash/CrashReport.java +@@ -103,6 +103,7 @@ + return IntCache.getCacheSizes(); + } + }); ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().enhanceCrashReport(this, this.systemDetailsCategory); + } + + /** Returns the description of the Crash Report. */ +@@ -171,13 +172,14 @@ + IOUtils.closeQuietly(printwriter); + } + +- return s; ++ return s + com.cleanroommc.cleanmix.CleanMixHooks.addMixinMetadataToCrashReport(throwable); + } + + /** Gets the complete report with headers, stack trace, and different sections as a string. */ + public String getCompleteReport() { + StringBuilder stringbuilder = new StringBuilder(); + stringbuilder.append("---- Minecraft Crash Report ----\n"); ++ net.minecraftforge.fml.relauncher.CoreModManager.onCrash(stringbuilder); + stringbuilder.append("// "); + stringbuilder.append(getWittyComment()); + stringbuilder.append("\n\n"); diff --git a/module/minecraft/patches/net/minecraft/crash/CrashReportCategory.java.patch b/module/minecraft/patches/net/minecraft/crash/CrashReportCategory.java.patch new file mode 100644 index 000000000..5f7335c96 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/crash/CrashReportCategory.java.patch @@ -0,0 +1,25 @@ +--- original/net/minecraft/crash/CrashReportCategory.java ++++ modified/net/minecraft/crash/CrashReportCategory.java +@@ -107,8 +107,11 @@ + return 0; + } + +- this.stackTrace = new StackTraceElement[astacktraceelement.length - 3 - size]; +- System.arraycopy(astacktraceelement, 3 + size, this.stackTrace, 0, this.stackTrace.length); ++ int len = astacktraceelement.length - 3 - size; ++ // Really Mojang, Still, god damn... ++ if (len <= 0) len = astacktraceelement.length; ++ this.stackTrace = new StackTraceElement[len]; ++ System.arraycopy(astacktraceelement, astacktraceelement.length - len, this.stackTrace, 0, this.stackTrace.length); + return this.stackTrace.length; + } + +@@ -175,7 +178,7 @@ + category.addDetail("Block type", new ICrashReportDetail() { + public String call() throws Exception { + try { +- return String.format("ID #%d (%s // %s)", i, blockIn.getTranslationKey(), blockIn.getClass().getCanonicalName()); ++ return String.format("ID #%d (%s // %s // %s)", i, blockIn.getTranslationKey(), blockIn.getClass().getName(), blockIn.getRegistryName()); + } catch (Throwable throwable) { + return "ID #" + i; + } diff --git a/module/minecraft/patches/net/minecraft/creativetab/CreativeTabs.java.patch b/module/minecraft/patches/net/minecraft/creativetab/CreativeTabs.java.patch new file mode 100644 index 000000000..73476f43b --- /dev/null +++ b/module/minecraft/patches/net/minecraft/creativetab/CreativeTabs.java.patch @@ -0,0 +1,84 @@ +--- original/net/minecraft/creativetab/CreativeTabs.java ++++ modified/net/minecraft/creativetab/CreativeTabs.java +@@ -135,7 +135,18 @@ + private EnumEnchantmentType[] enchantmentTypes = new EnumEnchantmentType[0]; + private ItemStack icon; + ++ public CreativeTabs(String label) { ++ this(getNextID(), label); ++ } ++ + public CreativeTabs(int index, String label) { ++ if (index >= CREATIVE_TAB_ARRAY.length) { ++ CreativeTabs[] tmp = new CreativeTabs[index + 1]; ++ for (int x = 0; x < CREATIVE_TAB_ARRAY.length; x++) { ++ tmp[x] = CREATIVE_TAB_ARRAY[x]; ++ } ++ CREATIVE_TAB_ARRAY = tmp; ++ } + this.index = index; + this.tabLabel = label; + this.icon = ItemStack.EMPTY; +@@ -203,12 +214,18 @@ + /** returns index % 6 */ + @SideOnly(Side.CLIENT) + public int getColumn() { ++ if (index > 11) { ++ return ((index - 12) % 10) % 5; ++ } + return this.index % 6; + } + + /** returns tabIndex < 6 */ + @SideOnly(Side.CLIENT) + public boolean isOnTopRow() { ++ if (index > 11) { ++ return ((index - 12) % 10) < 5; ++ } + return this.index < 6; + } + +@@ -247,4 +264,43 @@ + item.getSubItems(this, p_78018_1_); + } + } ++ ++ public int getTabPage() { ++ if (index > 11) { ++ return ((index - 12) / 10) + 1; ++ } ++ return 0; ++ } ++ ++ public static int getNextID() { ++ return CREATIVE_TAB_ARRAY.length; ++ } ++ ++ /** ++ * Determines if the search bar should be shown for this tab. ++ * ++ * @return True to show the bar ++ */ ++ public boolean hasSearchBar() { ++ return index == CreativeTabs.SEARCH.index; ++ } ++ ++ /** ++ * Gets the width of the search bar of the creative tab, use this if your ++ * creative tab name overflows together with a custom texture. ++ * ++ * @return The width of the search bar, 89 by default ++ */ ++ public int getSearchbarWidth() { ++ return 89; ++ } ++ ++ @SideOnly(Side.CLIENT) ++ public net.minecraft.util.ResourceLocation getBackgroundImage() { ++ return new net.minecraft.util.ResourceLocation("textures/gui/container/creative_inventory/tab_" + this.getBackgroundImageName()); ++ } ++ ++ public int getLabelColor() { ++ return 4210752; ++ } + } diff --git a/module/minecraft/patches/net/minecraft/enchantment/Enchantment.java.patch b/module/minecraft/patches/net/minecraft/enchantment/Enchantment.java.patch new file mode 100644 index 000000000..c8d08876a --- /dev/null +++ b/module/minecraft/patches/net/minecraft/enchantment/Enchantment.java.patch @@ -0,0 +1,49 @@ +--- original/net/minecraft/enchantment/Enchantment.java ++++ modified/net/minecraft/enchantment/Enchantment.java +@@ -14,9 +14,8 @@ + import net.minecraft.util.text.TextFormatting; + import net.minecraft.util.text.translation.I18n; + +-public abstract class Enchantment { +- public static final RegistryNamespaced REGISTRY = new RegistryNamespaced<>(); +- /** Where this enchantment has an effect, e.g. offhand, pants */ ++public abstract class Enchantment extends net.minecraftforge.registries.IForgeRegistryEntry.Impl { ++ public static final RegistryNamespaced REGISTRY = net.minecraftforge.registries.GameData.getWrapper(Enchantment.class); + private final EntityEquipmentSlot[] applicableEquipmentTypes; + private final Enchantment.Rarity rarity; + /** The EnumEnchantmentType given to this Enchantment. */ +@@ -129,7 +128,7 @@ + + /** Determines if this enchantment can be applied to a specific ItemStack. */ + public boolean canApply(ItemStack stack) { +- return this.type.canEnchantItem(stack.getItem()); ++ return canApplyAtEnchantingTable(stack); + } + + /** Called whenever a mob is damaged with an item that has this enchantment on it. */ +@@ -148,7 +147,24 @@ + return false; + } + +- /** Registers all of the vanilla enchantments. */ ++ /** ++ * This applies specifically to applying at the enchanting table. The other method {@link #canApply(ItemStack)} ++ * applies for all possible enchantments. ++ * @param stack ++ * @return ++ */ ++ public boolean canApplyAtEnchantingTable(ItemStack stack) { ++ return stack.getItem().canApplyAtEnchantingTable(stack, this); ++ } ++ ++ /** ++ * Is this enchantment allowed to be enchanted on books via Enchantment Table ++ * @return false to disable the vanilla feature ++ */ ++ public boolean isAllowedOnBooks() { ++ return true; ++ } ++ + public static void registerEnchantments() { + EntityEquipmentSlot[] aentityequipmentslot = new EntityEquipmentSlot[]{ + EntityEquipmentSlot.HEAD, EntityEquipmentSlot.CHEST, EntityEquipmentSlot.LEGS, EntityEquipmentSlot.FEET diff --git a/module/minecraft/patches/net/minecraft/enchantment/EnchantmentFrostWalker.java.patch b/module/minecraft/patches/net/minecraft/enchantment/EnchantmentFrostWalker.java.patch new file mode 100644 index 000000000..0062660f3 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/enchantment/EnchantmentFrostWalker.java.patch @@ -0,0 +1,14 @@ +--- original/net/minecraft/enchantment/EnchantmentFrostWalker.java ++++ modified/net/minecraft/enchantment/EnchantmentFrostWalker.java +@@ -57,8 +57,9 @@ + if (iblockstate.getMaterial() == Material.AIR) { + IBlockState iblockstate1 = worldIn.getBlockState(blockpos$mutableblockpos1); + if (iblockstate1.getMaterial() == Material.WATER +- && iblockstate1.getValue(BlockLiquid.LEVEL) == 0 +- && worldIn.mayPlace(Blocks.FROSTED_ICE, blockpos$mutableblockpos1, false, EnumFacing.DOWN, null)) { ++ && (iblockstate1.getBlock() == net.minecraft.init.Blocks.WATER || iblockstate1.getBlock() == net.minecraft.init.Blocks.FLOWING_WATER) ++ && iblockstate1.getValue(BlockLiquid.LEVEL) == 0 ++ && worldIn.mayPlace(Blocks.FROSTED_ICE, blockpos$mutableblockpos1, false, EnumFacing.DOWN, null)) { + worldIn.setBlockState(blockpos$mutableblockpos1, Blocks.FROSTED_ICE.getDefaultState()); + worldIn.scheduleUpdate( + blockpos$mutableblockpos1.toImmutable(), diff --git a/module/minecraft/patches/net/minecraft/enchantment/EnchantmentHelper.java.patch b/module/minecraft/patches/net/minecraft/enchantment/EnchantmentHelper.java.patch new file mode 100644 index 000000000..2b8cd4122 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/enchantment/EnchantmentHelper.java.patch @@ -0,0 +1,67 @@ +--- original/net/minecraft/enchantment/EnchantmentHelper.java ++++ modified/net/minecraft/enchantment/EnchantmentHelper.java +@@ -120,6 +120,7 @@ + ENCHANTMENT_MODIFIER_DAMAGE.damageModifier = 0; + ENCHANTMENT_MODIFIER_DAMAGE.source = source; + applyEnchantmentModifierArray(ENCHANTMENT_MODIFIER_DAMAGE, stacks); ++ ENCHANTMENT_MODIFIER_DAMAGE.source = null; //Forge Fix memory leaks: https://bugs.mojang.com/browse/MC-128547 + return ENCHANTMENT_MODIFIER_DAMAGE.damageModifier; + } + +@@ -145,6 +146,9 @@ + if (p_151384_1_ instanceof EntityPlayer) { + applyEnchantmentModifier(ENCHANTMENT_ITERATOR_HURT, p_151384_0_.getHeldItemMainhand()); + } ++ ++ ENCHANTMENT_ITERATOR_HURT.attacker = null; //Forge Fix memory leaks: https://bugs.mojang.com/browse/MC-128547 ++ ENCHANTMENT_ITERATOR_HURT.user = null; + } + + public static void applyArthropodEnchantments(EntityLivingBase p_151385_0_, Entity p_151385_1_) { +@@ -157,6 +161,9 @@ + if (p_151385_0_ instanceof EntityPlayer) { + applyEnchantmentModifier(ENCHANTMENT_ITERATOR_DAMAGE, p_151385_0_.getHeldItemMainhand()); + } ++ ++ ENCHANTMENT_ITERATOR_DAMAGE.user = null; //Forge Fix memory leaks: https://bugs.mojang.com/browse/MC-128547 ++ ENCHANTMENT_ITERATOR_DAMAGE.target = null; + } + + public static int getMaxEnchantmentLevel(Enchantment p_185284_0_, EntityLivingBase p_185284_1_) { +@@ -251,7 +258,8 @@ + /** Returns the enchantability of itemstack, using a separate calculation for each enchantNum (0, 1 or 2), cutting to the max enchantability power of the table, which is locked to a max of 15. */ + public static int calcItemStackEnchantability(Random rand, int enchantNum, int power, ItemStack stack) { + Item item = stack.getItem(); +- int i = item.getItemEnchantability(); ++ int i = item.getItemEnchantability(stack); ++ + if (i <= 0) { + return 0; + } +@@ -291,7 +299,8 @@ + public static List buildEnchantmentList(Random randomIn, ItemStack itemStackIn, int level, boolean allowTreasure) { + List list = Lists.newArrayList(); + Item item = itemStackIn.getItem(); +- int i = item.getItemEnchantability(); ++ int i = item.getItemEnchantability(itemStackIn); ++ + if (i <= 0) { + return list; + } +@@ -328,13 +337,13 @@ + } + + public static List getEnchantmentDatas(int p_185291_0_, ItemStack p_185291_1_, boolean allowTreasure) { +- List list = Lists.newArrayList(); ++ List list = Lists.newArrayList(); + Item item = p_185291_1_.getItem(); + boolean flag = p_185291_1_.getItem() == Items.BOOK; + + for (Enchantment enchantment : Enchantment.REGISTRY) { +- if ((!enchantment.isTreasureEnchantment() || allowTreasure) && (enchantment.type.canEnchantItem(item) || flag)) { +- for (int i = enchantment.getMaxLevel(); i > enchantment.getMinLevel() - 1; i--) { ++ if ((!enchantment.isTreasureEnchantment() || allowTreasure) && (enchantment.canApplyAtEnchantingTable(p_185291_1_) || (flag && enchantment.isAllowedOnBooks()))) { ++ for (int i = enchantment.getMaxLevel(); i > enchantment.getMinLevel() - 1; --i) { + if (p_185291_0_ >= enchantment.getMinEnchantability(i) && p_185291_0_ <= enchantment.getMaxEnchantability(i)) { + list.add(new EnchantmentData(enchantment, i)); + break; diff --git a/module/minecraft/patches/net/minecraft/enchantment/EnchantmentThorns.java.patch b/module/minecraft/patches/net/minecraft/enchantment/EnchantmentThorns.java.patch new file mode 100644 index 000000000..ebb0f042a --- /dev/null +++ b/module/minecraft/patches/net/minecraft/enchantment/EnchantmentThorns.java.patch @@ -0,0 +1,38 @@ +--- original/net/minecraft/enchantment/EnchantmentThorns.java ++++ modified/net/minecraft/enchantment/EnchantmentThorns.java +@@ -50,10 +50,10 @@ + } + + if (!itemstack.isEmpty()) { +- itemstack.damageItem(3, user); ++ damageArmor(itemstack, 3, user); + } + } else if (!itemstack.isEmpty()) { +- itemstack.damageItem(1, user); ++ damageArmor(itemstack, 1, user); + } + } + +@@ -64,4 +64,22 @@ + public static int getDamage(int level, Random rnd) { + return level > 10 ? level - 10 : 1 + rnd.nextInt(4); + } ++ ++ private void damageArmor(ItemStack stack, int amount, EntityLivingBase entity) { ++ int slot = -1; ++ int x = 0; ++ for (ItemStack i : entity.getArmorInventoryList()) { ++ if (i == stack){ ++ slot = x; ++ break; ++ } ++ x++; ++ } ++ if (slot == -1 || !(stack.getItem() instanceof net.minecraftforge.common.ISpecialArmor)) { ++ stack.damageItem(1, entity); ++ return; ++ } ++ net.minecraftforge.common.ISpecialArmor armor = (net.minecraftforge.common.ISpecialArmor)stack.getItem(); ++ armor.damageArmor(entity, stack, DamageSource.causeThornsDamage(entity), amount, slot); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/enchantment/EnumEnchantmentType.java.patch b/module/minecraft/patches/net/minecraft/enchantment/EnumEnchantmentType.java.patch new file mode 100644 index 000000000..339b8618e --- /dev/null +++ b/module/minecraft/patches/net/minecraft/enchantment/EnumEnchantmentType.java.patch @@ -0,0 +1,18 @@ +--- original/net/minecraft/enchantment/EnumEnchantmentType.java ++++ modified/net/minecraft/enchantment/EnumEnchantmentType.java +@@ -108,6 +108,14 @@ + EnumEnchantmentType() { + } + ++ private com.google.common.base.Predicate delegate = null; ++ ++ private EnumEnchantmentType(com.google.common.base.Predicate delegate) { ++ this.delegate = delegate; ++ } ++ + /** Return true if the item passed can be enchanted by a enchantment of this type. */ +- public abstract boolean canEnchantItem(Item var1); ++ public boolean canEnchantItem(Item itemIn) { ++ return this.delegate == null ? false : this.delegate.apply(itemIn); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/entity/Entity.java.patch b/module/minecraft/patches/net/minecraft/entity/Entity.java.patch new file mode 100644 index 000000000..f2b05a347 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/Entity.java.patch @@ -0,0 +1,445 @@ +--- original/net/minecraft/entity/Entity.java ++++ modified/net/minecraft/entity/Entity.java +@@ -85,7 +85,7 @@ + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + +-public abstract class Entity implements ICommandSender { ++public abstract class Entity implements ICommandSender, net.minecraftforge.common.capabilities.ICapabilitySerializable { + private static final Logger LOGGER = LogManager.getLogger(); + private static final List EMPTY_EQUIPMENT = Collections.emptyList(); + private static final AxisAlignedBB ZERO_AABB = new AxisAlignedBB(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); +@@ -216,6 +216,10 @@ + private boolean isPositionDirty; + private final double[] pistonDeltas; + private long pistonDeltasGameTime; ++ /** ++ * Setting this to true will prevent the world from calling {@link #onUpdate()} for this entity. ++ */ ++ public boolean updateBlocked; + + public Entity(World worldIn) { + this.entityId = nextEntityID++; +@@ -236,7 +240,7 @@ + this.world = worldIn; + this.setPosition(0.0, 0.0, 0.0); + if (worldIn != null) { +- this.dimension = worldIn.provider.getDimensionType().getId(); ++ this.dimension = worldIn.provider.getDimension(); + } + + this.dataManager = new EntityDataManager(this); +@@ -247,8 +251,16 @@ + this.dataManager.register(SILENT, false); + this.dataManager.register(NO_GRAVITY, false); + this.entityInit(); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.EntityEvent.EntityConstructing(this)); ++ capabilities = net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(this); + } + ++ /** Forge: Used to store custom data for each entity. */ ++ private NBTTagCompound customEntityData; ++ public boolean captureDrops = false; ++ public java.util.ArrayList capturedDrops = new java.util.ArrayList(); ++ private net.minecraftforge.common.capabilities.CapabilityDispatcher capabilities; ++ + public int getEntityId() { + return this.entityId; + } +@@ -373,6 +385,7 @@ + this.posX = x; + this.posY = y; + this.posZ = z; ++ if (this.isAddedToWorld() && !this.world.isRemote) this.world.updateEntityWithOptionalForce(this, false); // Forge - Process chunk registration after moving. + float f = this.width / 2.0F; + float f1 = this.height; + this.setEntityBoundingBox(new AxisAlignedBB(x - f, y, z - f, x + f, y + f1, z + f)); +@@ -901,6 +914,7 @@ + this.posX = (axisalignedbb.minX + axisalignedbb.maxX) / 2.0; + this.posY = axisalignedbb.minY; + this.posZ = (axisalignedbb.minZ + axisalignedbb.maxZ) / 2.0; ++ if (this.isAddedToWorld() && !this.world.isRemote) this.world.updateEntityWithOptionalForce(this, false); // Forge - Process chunk registration after moving. + } + + protected SoundEvent getSwimSound() { +@@ -950,7 +964,8 @@ + } + + protected void playStepSound(BlockPos pos, Block blockIn) { +- SoundType soundtype = blockIn.getSoundType(); ++ SoundType soundtype = blockIn.getSoundType(world.getBlockState(pos), world, pos, this); ++ + if (this.world.getBlockState(pos.up()).getBlock() == Blocks.SNOW_LAYER) { + soundtype = Blocks.SNOW_LAYER.getSoundType(); + this.playSound(soundtype.getStepSound(), soundtype.getVolume() * 0.15F, soundtype.getPitch()); +@@ -1151,6 +1166,8 @@ + int k = MathHelper.floor(this.posZ); + BlockPos blockpos = new BlockPos(i, j, k); + IBlockState iblockstate = this.world.getBlockState(blockpos); ++ ++ if(!iblockstate.getBlock().addRunningEffects(iblockstate, world, blockpos, this)) + if (iblockstate.getRenderType() != EnumBlockRenderType.INVISIBLE) { + this.world + .spawnParticle( +@@ -1174,11 +1191,12 @@ + double d0 = this.posY + this.getEyeHeight(); + BlockPos blockpos = new BlockPos(this.posX, d0, this.posZ); + IBlockState iblockstate = this.world.getBlockState(blockpos); ++ ++ Boolean result = iblockstate.getBlock().isEntityInsideMaterial(this.world, blockpos, iblockstate, this, d0, materialIn, true); ++ if (result != null) return result; ++ + if (iblockstate.getMaterial() == materialIn) { +- float f = BlockLiquid.getLiquidHeightPercent(iblockstate.getBlock().getMetaFromState(iblockstate)) - 0.11111111F; +- float f1 = blockpos.getY() + 1 - f; +- boolean flag = d0 < f1; +- return !flag && this instanceof EntityPlayer ? false : flag; ++ return net.minecraftforge.common.ForgeHooks.isInsideOfMaterial(materialIn, this, blockpos); + } else { + return false; + } +@@ -1262,6 +1280,7 @@ + this.prevRotationYaw -= 360.0F; + } + ++ if (!this.world.isRemote) this.world.getChunk((int) Math.floor(this.posX) >> 4, (int) Math.floor(this.posZ) >> 4); // Forge - ensure target chunk is loaded. + this.setPosition(this.posX, this.posY, this.posZ); + this.setRotation(yaw, pitch); + } +@@ -1542,6 +1561,7 @@ + if (this.glowing) { + compound.setBoolean("Glowing", this.glowing); + } ++ compound.setBoolean("UpdateBlocked", updateBlocked); + + if (!this.tags.isEmpty()) { + NBTTagList nbttaglist = new NBTTagList(); +@@ -1553,6 +1573,9 @@ + compound.setTag("Tags", nbttaglist); + } + ++ if (customEntityData != null) compound.setTag("ForgeData", customEntityData); ++ if (this.capabilities != null) compound.setTag("ForgeCaps", this.capabilities.serializeNBT()); ++ + this.writeEntityToNBT(compound); + if (this.isBeingRidden()) { + NBTTagList nbttaglist1 = new NBTTagList(); +@@ -1640,6 +1663,11 @@ + this.setSilent(compound.getBoolean("Silent")); + this.setNoGravity(compound.getBoolean("NoGravity")); + this.setGlowing(compound.getBoolean("Glowing")); ++ updateBlocked = compound.getBoolean("UpdateBlocked"); ++ ++ if (compound.hasKey("ForgeData")) customEntityData = compound.getCompoundTag("ForgeData"); ++ if (this.capabilities != null && compound.hasKey("ForgeCaps")) this.capabilities.deserializeNBT(compound.getCompoundTag("ForgeCaps")); ++ + if (compound.hasKey("Tags", 9)) { + this.tags.clear(); + NBTTagList nbttaglist1 = compound.getTagList("Tags", 8); +@@ -1720,7 +1748,11 @@ + + EntityItem entityitem = new EntityItem(this.world, this.posX, this.posY + offsetY, this.posZ, stack); + entityitem.setDefaultPickupDelay(); +- this.world.spawnEntity(entityitem); ++ if (captureDrops) { ++ this.capturedDrops.add(entityitem); ++ } else { ++ this.world.spawnEntity(entityitem); ++ } + return entityitem; + } + +@@ -1775,6 +1807,7 @@ + this.motionX = 0.0; + this.motionY = 0.0; + this.motionZ = 0.0; ++ if(!updateBlocked) + this.onUpdate(); + if (this.isRiding()) { + entity.updatePassenger(this); +@@ -1814,6 +1847,7 @@ + } + } + ++ if (!net.minecraftforge.event.ForgeEventFactory.canMountEntity(this, entityIn, true)) return false; + if (force || this.canBeRidden(entityIn) && entityIn.canFitPassenger(this)) { + if (this.isRiding()) { + this.dismountRidingEntity(); +@@ -1842,6 +1876,7 @@ + public void dismountRidingEntity() { + if (this.ridingEntity != null) { + Entity entity = this.ridingEntity; ++ if (!net.minecraftforge.event.ForgeEventFactory.canMountEntity(this, entity, false)) return; + this.ridingEntity = null; + entity.removePassenger(this); + } +@@ -2260,14 +2295,22 @@ + + @Nullable + public Entity changeDimension(int dimensionIn) { ++ if (this.world.isRemote || this.isDead) return null; ++ return changeDimension(dimensionIn, this.getServer().getWorld(dimensionIn).getDefaultTeleporter()); ++ } ++ ++ @Nullable // Forge: Entities that require custom handling should override this method, not the other ++ public Entity changeDimension(int dimensionIn, net.minecraftforge.common.util.ITeleporter teleporter) { + if (!this.world.isRemote && !this.isDead) { ++ if (!net.minecraftforge.common.ForgeHooks.onTravelToDimension(this, dimensionIn)) return null; + this.world.profiler.startSection("changeDimension"); + MinecraftServer minecraftserver = this.getServer(); + int i = this.dimension; + WorldServer worldserver = minecraftserver.getWorld(i); + WorldServer worldserver1 = minecraftserver.getWorld(dimensionIn); + this.dimension = dimensionIn; +- if (i == 1 && dimensionIn == 1) { ++ ++ if (i == 1 && dimensionIn == 1 && teleporter.isVanilla()) { + worldserver1 = minecraftserver.getWorld(0); + this.dimension = 0; + } +@@ -2276,20 +2319,23 @@ + this.isDead = false; + this.world.profiler.startSection("reposition"); + BlockPos blockpos; +- if (dimensionIn == 1) { ++ ++ if (dimensionIn == 1 && teleporter.isVanilla()) { + blockpos = worldserver1.getSpawnCoordinate(); + } else { +- double d0 = this.posX; +- double d1 = this.posZ; ++ double moveFactor = worldserver.provider.getMovementFactor() / worldserver1.provider.getMovementFactor(); ++ double d0 = MathHelper.clamp(this.posX * moveFactor, worldserver1.getWorldBorder().minX() + 16.0, worldserver1.getWorldBorder().maxX() - 16.0); ++ double d1 = MathHelper.clamp(this.posZ * moveFactor, worldserver1.getWorldBorder().minZ() + 16.0, worldserver1.getWorldBorder().maxZ() - 16.0); + double d2 = 8.0; +- if (dimensionIn == -1) { ++ ++ if (false && dimensionIn == -1) { + d0 = MathHelper.clamp( + d0 / 8.0, worldserver1.getWorldBorder().minX() + 16.0, worldserver1.getWorldBorder().maxX() - 16.0 + ); + d1 = MathHelper.clamp( +- d1 / 8.0, worldserver1.getWorldBorder().minZ() + 16.0, worldserver1.getWorldBorder().maxZ() - 16.0 +- ); +- } else if (dimensionIn == 0) { ++ d1 / 8.0, worldserver1.getWorldBorder().minZ() + 16.0, worldserver1.getWorldBorder().maxZ() - 16.0 ++ ); ++ } else if (false && dimensionIn == 0) { + d0 = MathHelper.clamp( + d0 * 8.0, worldserver1.getWorldBorder().minX() + 16.0, worldserver1.getWorldBorder().maxX() - 16.0 + ); +@@ -2302,8 +2348,7 @@ + d1 = MathHelper.clamp((int)d1, -29999872, 29999872); + float f = this.rotationYaw; + this.setLocationAndAngles(d0, this.posY, d1, 90.0F, 0.0F); +- Teleporter teleporter = worldserver1.getDefaultTeleporter(); +- teleporter.placeInExistingPortal(this, f); ++ teleporter.placeEntity(worldserver1, this, f); + blockpos = new BlockPos(this); + } + +@@ -2312,7 +2357,8 @@ + Entity entity = EntityList.newEntity((Class)this.getClass(), worldserver1); + if (entity != null) { + entity.copyDataFromOld(this); +- if (i == 1 && dimensionIn == 1) { ++ ++ if (i == 1 && dimensionIn == 1 && teleporter.isVanilla()) { + BlockPos blockpos1 = worldserver1.getTopSolidOrLiquidBlock(worldserver1.getSpawnPoint()); + entity.moveToBlockPosAndAngles(blockpos1, entity.rotationYaw, entity.rotationPitch); + } else { +@@ -2344,7 +2390,7 @@ + + /** Explosion resistance of a block relative to this entity */ + public float getExplosionResistance(Explosion explosionIn, World worldIn, BlockPos pos, IBlockState blockStateIn) { +- return blockStateIn.getBlock().getExplosionResistance(this); ++ return blockStateIn.getBlock().getExplosionResistance(worldIn, pos, this, explosionIn); + } + + public boolean canExplosionDestroyBlock(Explosion explosionIn, World worldIn, BlockPos pos, IBlockState blockStateIn, float p_174816_5_) { +@@ -2639,7 +2685,184 @@ + EnchantmentHelper.applyArthropodEnchantments(entityLivingBaseIn, entityIn); + } + +- /** Add the given player to the list of players tracking this entity. For instance, a player may track a boss in order to view its associated boss bar. */ ++ /* ================================== Forge Start =====================================*/ ++ /** ++ * Internal use for keeping track of entities that are tracked by a world, to ++ * allow guarantees that entity position changes will force a chunk load, avoiding ++ * potential issues with entity desyncing and bad chunk data. ++ */ ++ private boolean isAddedToWorld; ++ ++ /** ++ * Gets whether this entity has been added to a world (for tracking). Specifically ++ * between the times when an entity is added to a world and the entity being removed ++ * from the world's tracked lists. See {@link World#onEntityAdded(Entity)} and ++ * {@link World#onEntityRemoved(Entity)}. ++ * ++ * @return True if this entity is being tracked by a world ++ */ ++ public final boolean isAddedToWorld() { return this.isAddedToWorld; } ++ ++ /** ++ * Called after the entity has been added to the world's ++ * ticking list. Can be overriden, but needs to call super ++ * to prevent MC-136995. ++ */ ++ public void onAddedToWorld() { ++ this.isAddedToWorld = true; ++ } ++ ++ /** ++ * Called after the entity has been removed to the world's ++ * ticking list. Can be overriden, but needs to call super ++ * to prevent MC-136995. ++ */ ++ public void onRemovedFromWorld() { ++ this.isAddedToWorld = false; ++ } ++ ++ /** ++ * Returns a NBTTagCompound that can be used to store custom data for this entity. ++ * It will be written, and read from disc, so it persists over world saves. ++ * @return A NBTTagCompound ++ */ ++ public NBTTagCompound getEntityData() { ++ if (customEntityData == null) { ++ customEntityData = new NBTTagCompound(); ++ } ++ return customEntityData; ++ } ++ ++ /** ++ * Used in model rendering to determine if the entity riding this entity should be in the 'sitting' position. ++ * @return false to prevent an entity that is mounted to this entity from displaying the 'sitting' animation. ++ */ ++ public boolean shouldRiderSit() { ++ return true; ++ } ++ ++ /** ++ * Called when a user uses the creative pick block button on this entity. ++ * ++ * @param target The full target the player is looking at ++ * @return A ItemStack to add to the player's inventory, empty ItemStack if nothing should be added. ++ */ ++ public ItemStack getPickedResult(RayTraceResult target) { ++ if (this instanceof net.minecraft.entity.item.EntityPainting) { ++ return new ItemStack(net.minecraft.init.Items.PAINTING); ++ } else if (this instanceof EntityLeashKnot) { ++ return new ItemStack(net.minecraft.init.Items.LEAD); ++ } else if (this instanceof net.minecraft.entity.item.EntityItemFrame) { ++ ItemStack held = ((net.minecraft.entity.item.EntityItemFrame)this).getDisplayedItem(); ++ if (held.isEmpty()) { ++ return new ItemStack(net.minecraft.init.Items.ITEM_FRAME); ++ } else { ++ return held.copy(); ++ } ++ } else if (this instanceof net.minecraft.entity.item.EntityMinecart) { ++ return ((net.minecraft.entity.item.EntityMinecart)this).getCartItem(); ++ } else if (this instanceof net.minecraft.entity.item.EntityBoat) { ++ return new ItemStack(((EntityBoat)this).getItemBoat()); ++ } else if (this instanceof net.minecraft.entity.item.EntityArmorStand) { ++ return new ItemStack(net.minecraft.init.Items.ARMOR_STAND); ++ } else if (this instanceof net.minecraft.entity.item.EntityEnderCrystal) { ++ return new ItemStack(net.minecraft.init.Items.END_CRYSTAL); ++ } else { ++ ResourceLocation name = EntityList.getKey(this); ++ if (name != null && EntityList.ENTITY_EGGS.containsKey(name)) { ++ ItemStack stack = new ItemStack(net.minecraft.init.Items.SPAWN_EGG); ++ net.minecraft.item.ItemMonsterPlacer.applyEntityIdToItemStack(stack, name); ++ return stack; ++ } ++ } ++ return ItemStack.EMPTY; ++ } ++ ++ public UUID getPersistentID() { ++ return entityUniqueID; ++ } ++ ++ /** ++ * Reset the entity ID to a new value. Not to be used from Mod code ++ */ ++ @Deprecated // TODO: remove (1.13?) ++ public final void resetEntityId() { ++ this.entityId = nextEntityID++; ++ } ++ ++ public boolean shouldRenderInPass(int pass) { ++ return pass == 0; ++ } ++ ++ /** ++ * Returns true if the entity is of the @link{EnumCreatureType} provided ++ * @param type The EnumCreatureType type this entity is evaluating ++ * @param forSpawnCount If this is being invoked to check spawn count caps. ++ * @return If the creature is of the type provided ++ */ ++ public boolean isCreatureType(EnumCreatureType type, boolean forSpawnCount) { ++ if (forSpawnCount && (this instanceof EntityLiving) && ((EntityLiving)this).isNoDespawnRequired()) return false; ++ return type.getCreatureClass().isAssignableFrom(this.getClass()); ++ } ++ ++ /** ++ * If a rider of this entity can interact with this entity. Should return true on the ++ * ridden entity if so. ++ * ++ * @return if the entity can be interacted with from a rider ++ */ ++ public boolean canRiderInteract() { ++ return false; ++ } ++ ++ /** ++ * If the rider should be dismounted from the entity when the entity goes under water ++ * ++ * @param rider The entity that is riding ++ * @return if the entity should be dismounted when under water ++ */ ++ public boolean shouldDismountInWater(Entity rider) { ++ return this instanceof EntityLivingBase; ++ } ++ ++ @Override ++ public boolean hasCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable net.minecraft.util.EnumFacing facing) { ++ return capabilities != null && capabilities.hasCapability(capability, facing); ++ } ++ ++ @Override ++ @Nullable ++ public T getCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable net.minecraft.util.EnumFacing facing) { ++ return capabilities == null ? null : capabilities.getCapability(capability, facing); ++ } ++ ++ public void deserializeNBT(NBTTagCompound nbt) { ++ this.readFromNBT(nbt); ++ } ++ ++ public NBTTagCompound serializeNBT() { ++ NBTTagCompound ret = new NBTTagCompound(); ++ ret.setString("id", this.getEntityString()); ++ return this.writeToNBT(ret); ++ } ++ ++ /** ++ * Checks if this {@link Entity} can trample a {@link Block}. ++ * ++ * @param world The world in which the block will be trampled ++ * @param block The block being tested ++ * @param pos The block pos ++ * @param fallDistance The fall distance ++ * @return {@code true} if this entity can trample, {@code false} otherwise ++ */ ++ public boolean canTrample(World world, Block block, BlockPos pos, float fallDistance) { ++ return world.rand.nextFloat() < fallDistance - 0.5F ++ && this instanceof EntityLivingBase ++ && (this instanceof EntityPlayer || net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(world, this)) ++ && this.width * this.width * this.height > 0.512F; ++ } ++ /* ================================== Forge End =====================================*/ ++ + public void addTrackingPlayer(EntityPlayerMP player) { + } + diff --git a/module/minecraft/patches/net/minecraft/entity/EntityAgeable.java.patch b/module/minecraft/patches/net/minecraft/entity/EntityAgeable.java.patch new file mode 100644 index 000000000..d7e7506ae --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/EntityAgeable.java.patch @@ -0,0 +1,20 @@ +--- original/net/minecraft/entity/EntityAgeable.java ++++ modified/net/minecraft/entity/EntityAgeable.java +@@ -33,7 +33,7 @@ + ItemStack itemstack = player.getHeldItem(hand); + if (itemstack.getItem() == Items.SPAWN_EGG) { + if (!this.world.isRemote) { +- Class oclass = EntityList.REGISTRY.getObject(ItemMonsterPlacer.getNamedIdFrom(itemstack)); ++ Class oclass = EntityList.getClass(ItemMonsterPlacer.getNamedIdFrom(itemstack)); + if (oclass != null && this.getClass() == oclass) { + EntityAgeable entityageable = this.createChild(this); + if (entityageable != null) { +@@ -63,7 +63,7 @@ + return false; + } + +- Class oclass = EntityList.REGISTRY.getObject(ItemMonsterPlacer.getNamedIdFrom(stack)); ++ Class oclass = EntityList.getClass(ItemMonsterPlacer.getNamedIdFrom(stack)); + return oclass != null && entityClass == oclass; + } + diff --git a/module/minecraft/patches/net/minecraft/entity/EntityFlying.java.patch b/module/minecraft/patches/net/minecraft/entity/EntityFlying.java.patch new file mode 100644 index 000000000..13c7bff46 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/EntityFlying.java.patch @@ -0,0 +1,53 @@ +--- original/net/minecraft/entity/EntityFlying.java ++++ modified/net/minecraft/entity/EntityFlying.java +@@ -35,34 +35,28 @@ + } else { + float f = 0.91F; + if (this.onGround) { +- f = this.world +- .getBlockState( +- new BlockPos( +- MathHelper.floor(this.posX), +- MathHelper.floor(this.getEntityBoundingBox().minY) - 1, +- MathHelper.floor(this.posZ) +- ) +- ) +- .getBlock() +- .slipperiness +- * 0.91F; ++ BlockPos underPos = ++ new BlockPos( ++ MathHelper.floor(this.posX), ++ MathHelper.floor(this.getEntityBoundingBox().minY) - 1, ++ MathHelper.floor(this.posZ) ++ ); ++ IBlockState underState = this.world.getBlockState(underPos); ++ f = underState.getBlock().getSlipperiness(underState, this.world, underPos, this) * 0.91F; + } + + float f1 = 0.16277136F / (f * f * f); + this.moveRelative(strafe, vertical, forward, this.onGround ? 0.1F * f1 : 0.02F); + f = 0.91F; + if (this.onGround) { +- f = this.world +- .getBlockState( +- new BlockPos( +- MathHelper.floor(this.posX), +- MathHelper.floor(this.getEntityBoundingBox().minY) - 1, +- MathHelper.floor(this.posZ) +- ) +- ) +- .getBlock() +- .slipperiness +- * 0.91F; ++ BlockPos underPos = ++ new BlockPos( ++ MathHelper.floor(this.posX), ++ MathHelper.floor(this.getEntityBoundingBox().minY) - 1, ++ MathHelper.floor(this.posZ) ++ ); ++ IBlockState underState = this.world.getBlockState(underPos); ++ f = underState.getBlock().getSlipperiness(underState, this.world, underPos, this) * 0.91F; + } + + this.move(MoverType.SELF, this.motionX, this.motionY, this.motionZ); diff --git a/module/minecraft/patches/net/minecraft/entity/EntityHanging.java.patch b/module/minecraft/patches/net/minecraft/entity/EntityHanging.java.patch new file mode 100644 index 000000000..d568b8f59 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/EntityHanging.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/entity/EntityHanging.java ++++ modified/net/minecraft/entity/EntityHanging.java +@@ -126,6 +126,8 @@ + int j1 = (j - 1) / -2; + blockpos$mutableblockpos.setPos(blockpos).move(enumfacing, k + i1).move(EnumFacing.UP, l + j1); + IBlockState iblockstate = this.world.getBlockState(blockpos$mutableblockpos); ++ if (iblockstate.isSideSolid(this.world, blockpos$mutableblockpos, this.facingDirection)) ++ continue; + if (!iblockstate.getMaterial().isSolid() && !BlockRedstoneDiode.isDiode(iblockstate)) { + return false; + } diff --git a/module/minecraft/patches/net/minecraft/entity/EntityLeashKnot.java.patch b/module/minecraft/patches/net/minecraft/entity/EntityLeashKnot.java.patch new file mode 100644 index 000000000..e4fc052e9 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/EntityLeashKnot.java.patch @@ -0,0 +1,10 @@ +--- original/net/minecraft/entity/EntityLeashKnot.java ++++ modified/net/minecraft/entity/EntityLeashKnot.java +@@ -51,6 +51,7 @@ + this.posX = this.hangingPosition.getX() + 0.5; + this.posY = this.hangingPosition.getY() + 0.5; + this.posZ = this.hangingPosition.getZ() + 0.5; ++ if (this.isAddedToWorld() && !this.world.isRemote) this.world.updateEntityWithOptionalForce(this, false); // Forge - Process chunk registration after moving. + } + + /** Updates facing and bounding box based on it */ diff --git a/module/minecraft/patches/net/minecraft/entity/EntityList.java.patch b/module/minecraft/patches/net/minecraft/entity/EntityList.java.patch new file mode 100644 index 000000000..8c3593224 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/EntityList.java.patch @@ -0,0 +1,177 @@ +--- original/net/minecraft/entity/EntityList.java ++++ modified/net/minecraft/entity/EntityList.java +@@ -112,20 +112,8 @@ + * @deprecated DO NOT USE. This field does not exist under forge, and mods using it will break if forge is installed. Directly use the equivalent methods in this class instead. + */ + public static final RegistryNamespaced> REGISTRY = new RegistryNamespaced<>(); +- /** This is a HashMap of the Creative Entity Eggs/Spawners. */ + public static final Map ENTITY_EGGS = Maps.newLinkedHashMap(); +- /** +- * A list of all known entity types. +- * +- * @deprecated DO NOT USE. This field does not exist under forge, and mods using it will break if forge is installed. Use {@link #getEntityNameList()} instead. +- */ +- public static final Set KNOWN_TYPES = Sets.newHashSet(); +- /** +- * A list of "old" entity names (used as IDs in versions prior to 1.11) and still used for translations. +- * +- * @deprecated DO NOT USE. This field does not exist under forge, and mods using it will break if forge is installed. Unfortunately, there is no direct replacement for the list, but {@link #getEntityString()} and {@link #getTranslationName()} can be used for individual entities. +- */ +- private static final List OLD_NAMES = Lists.newArrayList(); ++ private static final Set EXTRA_NAMES = Sets.newHashSet(); + + /** Gets the {@link ResourceLocation} that identifies the given entity's type. */ + @Nullable +@@ -140,7 +128,8 @@ + */ + @Nullable + public static ResourceLocation getKey(Class entityIn) { +- return REGISTRY.getNameForObject(entityIn); ++ net.minecraftforge.fml.common.registry.EntityEntry entry = net.minecraftforge.fml.common.registry.EntityRegistry.getEntry(entityIn); ++ return entry == null ? null : entry.getRegistryName(); + } + + /** +@@ -150,8 +139,8 @@ + */ + @Nullable + public static String getEntityString(Entity entityIn) { +- int i = REGISTRY.getIDForObject((Class)entityIn.getClass()); +- return i == -1 ? null : OLD_NAMES.get(i); ++ net.minecraftforge.fml.common.registry.EntityEntry entry = net.minecraftforge.fml.common.registry.EntityRegistry.getEntry(entityIn.getClass()); ++ return entry == null ? null : entry.getName(); + } + + /** +@@ -163,8 +152,8 @@ + */ + @Nullable + public static String getTranslationName(@Nullable ResourceLocation entityType) { +- int i = REGISTRY.getIDForObject(REGISTRY.getObject(entityType)); +- return i == -1 ? null : OLD_NAMES.get(i); ++ net.minecraftforge.fml.common.registry.EntityEntry entry = net.minecraftforge.fml.common.registry.ForgeRegistries.ENTITIES.getValue(entityType); ++ return entry == null ? null : entry.getName(); + } + + /** +@@ -177,14 +166,25 @@ + @Nullable + @SideOnly(Side.CLIENT) + public static Class getClassFromID(int entityID) { +- return REGISTRY.getObjectById(entityID); ++ net.minecraftforge.fml.common.registry.EntityEntry entry = net.minecraftforge.registries.GameData.getEntityRegistry().getValue(entityID); ++ return entry == null ? null : entry.getEntityClass(); + } + + @Nullable + @SideOnly(Side.CLIENT) + public static Class getClassFromName(String p_192839_0_) { +- return REGISTRY.getObject(new ResourceLocation(p_192839_0_)); ++ net.minecraftforge.fml.common.registry.EntityEntry entry = net.minecraftforge.fml.common.registry.ForgeRegistries.ENTITIES.getValue(new ResourceLocation(p_192839_0_)); ++ return entry == null ? null : entry.getEntityClass(); + } ++ public static int getID(Class cls) { ++ net.minecraftforge.fml.common.registry.EntityEntry entry = net.minecraftforge.fml.common.registry.EntityRegistry.getEntry(cls); ++ return entry == null ? -1 : net.minecraftforge.registries.GameData.getEntityRegistry().getID(entry); ++ } ++ @Nullable ++ public static Class getClass(ResourceLocation key) { ++ net.minecraftforge.fml.common.registry.EntityEntry entry = net.minecraftforge.fml.common.registry.ForgeRegistries.ENTITIES.getValue(key); ++ return entry == null ? null : entry.getEntityClass(); ++ } + + /** + * Creates a new entity of the given type in the given world. +@@ -213,7 +213,8 @@ + @Nullable + @SideOnly(Side.CLIENT) + public static Entity createEntityByID(int entityID, World worldIn) { +- return newEntity(getClassFromID(entityID), worldIn); ++ net.minecraftforge.fml.common.registry.EntityEntry entry = net.minecraftforge.registries.GameData.getEntityRegistry().getValue(entityID); ++ return entry == null ? null : entry.newInstance(worldIn); + } + + /** +@@ -223,7 +224,8 @@ + */ + @Nullable + public static Entity createEntityByIDFromName(ResourceLocation name, World worldIn) { +- return newEntity(REGISTRY.getObject(name), worldIn); ++ net.minecraftforge.fml.common.registry.EntityEntry entry = net.minecraftforge.fml.common.registry.ForgeRegistries.ENTITIES.getValue(name); ++ return entry == null ? null : entry.newInstance(worldIn); + } + + /** +@@ -240,7 +242,13 @@ + if (entity == null) { + LOGGER.warn("Skipping Entity with id {}", resourcelocation); + } else { ++ try { + entity.readFromNBT(nbt); ++ } catch (Exception e) { ++ net.minecraftforge.fml.common.FMLLog.log.error("An Entity {}({}) has thrown an exception during loading, its state cannot be restored. Report this to the mod author", ++ nbt.getString("id"), entity.getName(), e); ++ entity = null; ++ } + } + + return entity; +@@ -252,7 +260,7 @@ + * @return A collection of all known entity types. Do not modify this collection. + */ + public static Set getEntityNameList() { +- return KNOWN_TYPES; ++ return Sets.union(net.minecraftforge.fml.common.registry.ForgeRegistries.ENTITIES.getKeys(), EXTRA_NAMES); + } + + /** +@@ -418,7 +426,7 @@ + addSpawnInfo("zombie_horse", 3232308, 9945732); + addSpawnInfo("zombie_pigman", 15373203, 5009705); + addSpawnInfo("zombie_villager", 5651507, 7969893); +- KNOWN_TYPES.add(LIGHTNING_BOLT); ++ EXTRA_NAMES.add(LIGHTNING_BOLT); + } + + private static void register(int id, String name, Class clazz, String oldName) { +@@ -433,19 +441,15 @@ + } + + ResourceLocation resourcelocation = new ResourceLocation(name); +- REGISTRY.register(id, resourcelocation, clazz); +- KNOWN_TYPES.add(resourcelocation); +- +- while (OLD_NAMES.size() <= id) { +- OLD_NAMES.add(null); +- } +- +- OLD_NAMES.set(id, oldName); ++ net.minecraftforge.registries.GameData.registerEntity(id, resourcelocation, clazz, oldName); + } + + protected static EntityList.EntityEggInfo addSpawnInfo(String id, int primaryColor, int secondaryColor) { + ResourceLocation resourcelocation = new ResourceLocation(id); +- return ENTITY_EGGS.put(resourcelocation, new EntityList.EntityEggInfo(resourcelocation, primaryColor, secondaryColor)); ++ EntityList.EntityEggInfo egg = new EntityList.EntityEggInfo(resourcelocation, primaryColor, secondaryColor); ++ net.minecraftforge.fml.common.registry.EntityEntry entry = net.minecraftforge.fml.common.registry.ForgeRegistries.ENTITIES.getValue(resourcelocation); ++ if (entry != null) entry.setEgg(egg); ++ return (EntityList.EntityEggInfo)ENTITY_EGGS.put(resourcelocation, egg); + } + + public static class EntityEggInfo { +@@ -465,5 +469,15 @@ + this.killEntityStat = StatList.getStatKillEntity(this); + this.entityKilledByStat = StatList.getStatEntityKilledBy(this); + } ++ ++ // Forge start ++ public EntityEggInfo(ResourceLocation id, int primaryColor, int secondaryColor, StatBase killEntityStatistic, StatBase entityKilledByStatistic) { ++ this.spawnedID = id; ++ this.primaryColor = primaryColor; ++ this.secondaryColor = secondaryColor; ++ this.killEntityStat = killEntityStatistic; ++ this.entityKilledByStat = entityKilledByStatistic; ++ } ++ // Forge end + } + } diff --git a/module/minecraft/patches/net/minecraft/entity/EntityLiving.java.patch b/module/minecraft/patches/net/minecraft/entity/EntityLiving.java.patch new file mode 100644 index 000000000..a2e8abdb5 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/EntityLiving.java.patch @@ -0,0 +1,81 @@ +--- original/net/minecraft/entity/EntityLiving.java ++++ modified/net/minecraft/entity/EntityLiving.java +@@ -169,6 +169,7 @@ + /** Sets the active target the Task system uses for tracking */ + public void setAttackTarget(@Nullable EntityLivingBase entitylivingbaseIn) { + this.attackTarget = entitylivingbaseIn; ++ this.attackTarget = net.minecraftforge.common.ForgeHooks.onLivingSetAttackTarget(this, entitylivingbaseIn); + } + + /** Returns true if this entity can attack entities of the specified class. */ +@@ -518,7 +519,8 @@ + public void onLivingUpdate() { + super.onLivingUpdate(); + this.world.profiler.startSection("looting"); +- if (!this.world.isRemote && this.canPickUpLoot() && !this.dead && this.world.getGameRules().getBoolean("mobGriefing")) { ++ ++ if (!this.world.isRemote && this.canPickUpLoot() && !this.dead && net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.world, this)) { + for (EntityItem entityitem : this.world.getEntitiesWithinAABB(EntityItem.class, this.getEntityBoundingBox().grow(1.0, 0.0, 1.0))) { + if (!entityitem.isDead && !entityitem.getItem().isEmpty() && !entityitem.cannotPickup()) { + this.updateEquipmentIfNeeded(entityitem); +@@ -612,8 +614,15 @@ + + /** Makes the entity despawn if requirements are reached */ + protected void despawnEntity() { ++ net.minecraftforge.fml.common.eventhandler.Event.Result result = null; + if (this.persistenceRequired) { + this.idleTime = 0; ++ } else if ((this.idleTime & 0x1F) == 0x1F && (result = net.minecraftforge.event.ForgeEventFactory.canEntityDespawn(this)) != net.minecraftforge.fml.common.eventhandler.Event.Result.DEFAULT) { ++ if (result == net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) { ++ this.idleTime = 0; ++ } else { ++ this.setDead(); ++ } + } else { + Entity entity = this.world.getClosestPlayerToEntity(this, -1.0); + if (entity != null) { +@@ -730,8 +739,6 @@ + && this.world.checkNoEntityCollision(this.getEntityBoundingBox(), this); + } + +- /** Returns render size modifier */ +- @SideOnly(Side.CLIENT) + public float getRenderSizeModifier() { + return 1.0F; + } +@@ -862,6 +869,8 @@ + } + + public static EntityEquipmentSlot getSlotForItemStack(ItemStack stack) { ++ final EntityEquipmentSlot slot = stack.getItem().getEquipmentSlot(stack); ++ if (slot != null) return slot; // FORGE: Allow modders to set a non-default equipment slot for a stack; e.g. a non-armor chestplate-slot item + if (stack.getItem() == Item.getItemFromBlock(Blocks.PUMPKIN) || stack.getItem() == Items.SKULL) { + return EntityEquipmentSlot.HEAD; + } else if (stack.getItem() instanceof ItemArmor) { +@@ -869,7 +878,7 @@ + } else if (stack.getItem() == Items.ELYTRA) { + return EntityEquipmentSlot.CHEST; + } else { +- return stack.getItem() == Items.SHIELD ? EntityEquipmentSlot.OFFHAND : EntityEquipmentSlot.MAINHAND; ++ return stack.getItem().isShield(stack, null) ? EntityEquipmentSlot.OFFHAND : EntityEquipmentSlot.MAINHAND; + } + } + +@@ -1203,5 +1212,17 @@ + ON_GROUND, + IN_AIR, + IN_WATER; ++ ++ private final java.util.function.BiPredicate spawnPredicate; ++ ++ SpawnPlacementType() { this.spawnPredicate = null; } ++ ++ SpawnPlacementType(java.util.function.BiPredicate spawnPredicate) { ++ this.spawnPredicate = spawnPredicate; ++ } ++ ++ public boolean canSpawnAt(World world, BlockPos pos) { ++ return this.spawnPredicate != null ? this.spawnPredicate.test(world, pos) : net.minecraft.world.WorldEntitySpawner.canCreatureTypeSpawnBody(this, world, pos); ++ } + } + } diff --git a/module/minecraft/patches/net/minecraft/entity/EntityLivingBase.java.patch b/module/minecraft/patches/net/minecraft/entity/EntityLivingBase.java.patch new file mode 100644 index 000000000..941a319c0 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/EntityLivingBase.java.patch @@ -0,0 +1,540 @@ +--- original/net/minecraft/entity/EntityLivingBase.java ++++ modified/net/minecraft/entity/EntityLivingBase.java +@@ -81,11 +81,7 @@ + private static final Logger LOGGER = LogManager.getLogger(); + private static final UUID SPRINTING_SPEED_BOOST_ID = UUID.fromString("662A6B8D-DA3E-4C1C-8813-96EA6097278D"); + private static final AttributeModifier SPRINTING_SPEED_BOOST = new AttributeModifier(SPRINTING_SPEED_BOOST_ID, "Sprinting speed boost", 0.3F, 2).setSaved(false); +- /** +- * Hand states, used to trigger blocking/eating/drinking animation. +- * +- * Note that this is completely unrelated to {@link #isSwingInProgress}/{@link #swingingHand}, which is used for the swinging animation. +- */ ++ public static final net.minecraft.entity.ai.attributes.IAttribute SWIM_SPEED = new net.minecraft.entity.ai.attributes.RangedAttribute(null, "forge.swimSpeed", 1.0, 0.0, 1024.0).setShouldWatch(true); + protected static final DataParameter HAND_STATES = EntityDataManager.createKey(EntityLivingBase.class, DataSerializers.BYTE); + private static final DataParameter HEALTH = EntityDataManager.createKey(EntityLivingBase.class, DataSerializers.FLOAT); + private static final DataParameter POTION_EFFECTS = EntityDataManager.createKey(EntityLivingBase.class, DataSerializers.VARINT); +@@ -223,6 +219,7 @@ + this.getAttributeMap().registerAttribute(SharedMonsterAttributes.MOVEMENT_SPEED); + this.getAttributeMap().registerAttribute(SharedMonsterAttributes.ARMOR); + this.getAttributeMap().registerAttribute(SharedMonsterAttributes.ARMOR_TOUGHNESS); ++ this.getAttributeMap().registerAttribute(SWIM_SPEED); + } + + @Override +@@ -233,9 +230,10 @@ + + if (!this.world.isRemote && this.fallDistance > 3.0F && onGroundIn) { + float f = MathHelper.ceil(this.fallDistance - 3.0F); +- if (state.getMaterial() != Material.AIR) { ++ if (!state.getBlock().isAir(state, world, pos)) { + double d0 = Math.min(0.2F + f / 15.0F, 2.5); + int i = (int)(150.0 * d0); ++ if (!state.getBlock().addLandingEffects(state, (WorldServer)this.world, pos, state, this, i)) + ((WorldServer)this.world) + .spawnParticle( + EnumParticleTypes.BLOCK_DUST, +@@ -314,7 +312,7 @@ + } + } + +- if (!this.world.isRemote && this.isRiding() && this.getRidingEntity() instanceof EntityLivingBase) { ++ if (!this.world.isRemote && this.isRiding() && this.getRidingEntity() != null && this.getRidingEntity().shouldDismountInWater(this)) { + this.dismountRidingEntity(); + } + } +@@ -392,6 +390,7 @@ + && (this.isPlayer() || this.recentlyHit > 0 && this.canDropLoot() && this.world.getGameRules().getBoolean("doMobLoot"))) { + int i = this.getExperiencePoints(this.attackingPlayer); + ++ i = net.minecraftforge.event.ForgeEventFactory.getExperienceDrop(this, this.attackingPlayer, i); + while (i > 0) { + int j = EntityXPOrb.getXPSplit(i); + i -= j; +@@ -581,7 +580,7 @@ + Potion potion = iterator.next(); + PotionEffect potioneffect = this.activePotionsMap.get(potion); + if (!potioneffect.onUpdate(this)) { +- if (!this.world.isRemote) { ++ if (!this.world.isRemote && !net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.living.PotionEvent.PotionExpiryEvent(this, potioneffect))) { + iterator.remove(); + this.onFinishedPotionEffect(potioneffect); + } +@@ -639,8 +638,10 @@ + this.setInvisible(false); + } else { + Collection collection = this.activePotionsMap.values(); +- this.dataManager.set(HIDE_PARTICLES, areAllPotionsAmbient(collection)); +- this.dataManager.set(POTION_EFFECTS, PotionUtils.getPotionColorFromEffectList(collection)); ++ net.minecraftforge.event.entity.living.PotionColorCalculationEvent event = new net.minecraftforge.event.entity.living.PotionColorCalculationEvent(this, PotionUtils.getPotionColorFromEffectList(collection), areAllPotionsAmbient(collection), collection); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event); ++ this.dataManager.set(HIDE_PARTICLES, event.areParticlesHidden()); ++ this.dataManager.set(POTION_EFFECTS, event.getColor()); + this.setInvisible(this.isPotionActive(MobEffects.INVISIBILITY)); + } + } +@@ -667,7 +668,10 @@ + Iterator iterator = this.activePotionsMap.values().iterator(); + + while (iterator.hasNext()) { +- this.onFinishedPotionEffect(iterator.next()); ++ PotionEffect effect = iterator.next(); ++ if(net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.living.PotionEvent.PotionRemoveEvent(this, effect))) continue; ++ ++ this.onFinishedPotionEffect(effect); + iterator.remove(); + } + } +@@ -695,6 +699,8 @@ + public void addPotionEffect(PotionEffect potioneffectIn) { + if (this.isPotionApplicable(potioneffectIn)) { + PotionEffect potioneffect = this.activePotionsMap.get(potioneffectIn.getPotion()); ++ ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.living.PotionEvent.PotionAddedEvent(this, potioneffect, potioneffectIn)); + if (potioneffect == null) { + this.activePotionsMap.put(potioneffectIn.getPotion(), potioneffectIn); + this.onNewPotionEffect(potioneffectIn); +@@ -706,6 +712,9 @@ + } + + public boolean isPotionApplicable(PotionEffect potioneffectIn) { ++ net.minecraftforge.event.entity.living.PotionEvent.PotionApplicableEvent event = new net.minecraftforge.event.entity.living.PotionEvent.PotionApplicableEvent(this, potioneffectIn); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event); ++ if (event.getResult() != net.minecraftforge.fml.common.eventhandler.Event.Result.DEFAULT) return event.getResult() == net.minecraftforge.fml.common.eventhandler.Event.Result.ALLOW; + if (this.getCreatureAttribute() == EnumCreatureAttribute.UNDEAD) { + Potion potion = potioneffectIn.getPotion(); + if (potion == MobEffects.REGENERATION || potion == MobEffects.POISON) { +@@ -729,6 +738,7 @@ + + /** Removes the given potion effect. */ + public void removePotionEffect(Potion potionIn) { ++ if(net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.living.PotionEvent.PotionRemoveEvent(this, potionIn))) return; + PotionEffect potioneffect = this.removeActivePotionEffect(potionIn); + if (potioneffect != null) { + this.onFinishedPotionEffect(potioneffect); +@@ -760,6 +770,8 @@ + + /** Heal living entity (param: amount of half-hearts) */ + public void heal(float healAmount) { ++ healAmount = net.minecraftforge.event.ForgeEventFactory.onLivingHeal(this, healAmount); ++ if (healAmount <= 0) return; + float f = this.getHealth(); + if (f > 0.0F) { + this.setHealth(f + healAmount); +@@ -777,6 +789,7 @@ + /** Called when the entity is attacked. */ + @Override + public boolean attackEntityFrom(DamageSource source, float amount) { ++ if (!net.minecraftforge.common.ForgeHooks.onLivingAttack(this, source, amount)) return false; + if (this.isEntityInvulnerable(source)) { + return false; + } +@@ -843,8 +856,8 @@ + if (entity1 instanceof EntityPlayer) { + this.recentlyHit = 100; + this.attackingPlayer = (EntityPlayer)entity1; +- } else if (entity1 instanceof EntityWolf) { +- EntityWolf entitywolf = (EntityWolf)entity1; ++ } else if (entity1 instanceof net.minecraft.entity.passive.EntityTameable) { ++ net.minecraft.entity.passive.EntityTameable entitywolf = (net.minecraft.entity.passive.EntityTameable)entity1; + if (entitywolf.isTamed()) { + this.recentlyHit = 100; + this.attackingPlayer = null; +@@ -991,7 +1004,7 @@ + + /** Renders broken item particles using the given ItemStack */ + public void renderBrokenItemStack(ItemStack stack) { +- this.playSound(SoundEvents.ENTITY_ITEM_BREAK, 0.8F, 0.8F + this.world.rand.nextFloat() * 0.4F); ++ this.world.playSound(null, this.posX, this.posY, this.posZ, SoundEvents.ENTITY_ITEM_BREAK, this.getSoundCategory(), 0.8F, 0.8F + this.world.rand.nextFloat() * 0.4F); //Forge: Fix MC-2518 Items are not damaged on the client so client needs packet as well. + + for (int i = 0; i < 5; i++) { + Vec3d vec3d = new Vec3d((this.rand.nextFloat() - 0.5) * 0.1, Math.random() * 0.1 + 0.1, 0.0); +@@ -1002,22 +1015,28 @@ + vec3d1 = vec3d1.rotatePitch(-this.rotationPitch * (float) (Math.PI / 180.0)); + vec3d1 = vec3d1.rotateYaw(-this.rotationYaw * (float) (Math.PI / 180.0)); + vec3d1 = vec3d1.add(this.posX, this.posY + this.getEyeHeight(), this.posZ); +- this.world +- .spawnParticle( +- EnumParticleTypes.ITEM_CRACK, +- vec3d1.x, +- vec3d1.y, +- vec3d1.z, +- vec3d.x, +- vec3d.y + 0.05, +- vec3d.z, +- Item.getIdFromItem(stack.getItem()) +- ); ++ if (this.world instanceof WorldServer) //Forge: Fix MC-2518 spawnParticle is nooped on server, need to use server specific variant ++ ((WorldServer)this.world).spawnParticle(EnumParticleTypes.ITEM_CRACK, vec3d1.x, vec3d1.y, vec3d1.z, 0, vec3d.x, vec3d.y + 0.05, vec3d.z, 0.0, Item.getIdFromItem(stack.getItem()), stack.getMetadata()); ++ else //Fix the fact that spawning ItemCrack uses TWO arguments. ++ this.world ++ .spawnParticle( ++ EnumParticleTypes.ITEM_CRACK, ++ vec3d1.x, ++ vec3d1.y, ++ vec3d1.z, ++ vec3d.x, ++ vec3d.y + 0.05, ++ vec3d.z, ++ Item.getIdFromItem(stack.getItem()), ++ stack.getMetadata() ++ ); ++ + } + } + + /** Called when the mob's health reaches 0. */ + public void onDeath(DamageSource cause) { ++ if (net.minecraftforge.common.ForgeHooks.onLivingDeath(this, cause)) return; + if (!this.dead) { + Entity entity = cause.getTrueSource(); + EntityLivingBase entitylivingbase = this.getAttackingEntity(); +@@ -1032,15 +1051,23 @@ + this.dead = true; + this.getCombatTracker().reset(); + if (!this.world.isRemote) { +- int i = 0; +- if (entity instanceof EntityPlayer) { +- i = EnchantmentHelper.getLootingModifier((EntityLivingBase)entity); +- } ++ int i = net.minecraftforge.common.ForgeHooks.getLootingLevel(this, entity, cause); + ++ captureDrops = true; ++ capturedDrops.clear(); ++ + if (this.canDropLoot() && this.world.getGameRules().getBoolean("doMobLoot")) { + boolean flag = this.recentlyHit > 0; + this.dropLoot(flag, i, cause); + } ++ ++ captureDrops = false; ++ ++ if (!net.minecraftforge.common.ForgeHooks.onLivingDrops(this, cause, capturedDrops, i, recentlyHit > 0)) { ++ for (EntityItem item : capturedDrops) { ++ world.spawnEntity(item); ++ } ++ } + } + + this.world.setEntityState(this, (byte)3); +@@ -1063,7 +1090,10 @@ + * The entity's existing horizontal velocity is halved, and if the entity is on the ground the Y-velocity is too. + */ + public void knockBack(Entity entityIn, float strength, double xRatio, double zRatio) { +- if (!(this.rand.nextDouble() < this.getEntityAttribute(SharedMonsterAttributes.KNOCKBACK_RESISTANCE).getAttributeValue())) { ++ net.minecraftforge.event.entity.living.LivingKnockBackEvent event = net.minecraftforge.common.ForgeHooks.onLivingKnockBack(this, entityIn, strength, xRatio, zRatio); ++ if(event.isCanceled()) return; ++ strength = event.getStrength(); xRatio = event.getRatioX(); zRatio = event.getRatioZ(); ++ if (this.rand.nextDouble() >= this.getEntityAttribute(SharedMonsterAttributes.KNOCKBACK_RESISTANCE).getAttributeValue()) { + this.isAirBorne = true; + float f = MathHelper.sqrt(xRatio * xRatio + zRatio * zRatio); + this.motionX /= 2.0; +@@ -1110,9 +1140,7 @@ + BlockPos blockpos = new BlockPos(i, j, k); + IBlockState iblockstate = this.world.getBlockState(blockpos); + Block block = iblockstate.getBlock(); +- return block != Blocks.LADDER && block != Blocks.VINE +- ? block instanceof BlockTrapDoor && this.canGoThroughtTrapDoorOnLadder(blockpos, iblockstate) +- : true; ++ return net.minecraftforge.common.ForgeHooks.isLivingOnLadder(iblockstate, world, new BlockPos(i, j, k), this); + } + + private boolean canGoThroughtTrapDoorOnLadder(BlockPos pos, IBlockState state) { +@@ -1135,6 +1163,9 @@ + + @Override + public void fall(float distance, float damageMultiplier) { ++ float[] ret = net.minecraftforge.common.ForgeHooks.onLivingFall(this, distance, damageMultiplier); ++ if (ret == null) return; ++ distance = ret[0]; damageMultiplier = ret[1]; + super.fall(distance, damageMultiplier); + PotionEffect potioneffect = this.getActivePotionEffect(MobEffects.JUMP_BOOST); + float f = potioneffect == null ? 0.0F : potioneffect.getAmplifier() + 1; +@@ -1147,7 +1178,7 @@ + int l = MathHelper.floor(this.posZ); + IBlockState iblockstate = this.world.getBlockState(new BlockPos(j, k, l)); + if (iblockstate.getMaterial() != Material.AIR) { +- SoundType soundtype = iblockstate.getBlock().getSoundType(); ++ SoundType soundtype = iblockstate.getBlock().getSoundType(iblockstate, world, new BlockPos(j, k, l), this); + this.playSound(soundtype.getFallSound(), soundtype.getVolume() * 0.5F, soundtype.getPitch() * 0.75F); + } + } +@@ -1214,6 +1245,8 @@ + /** Deals damage to the entity. This will take the armor of the entity into consideration before damaging the health bar. */ + protected void damageEntity(DamageSource damageSrc, float damageAmount) { + if (!this.isEntityInvulnerable(damageSrc)) { ++ damageAmount = net.minecraftforge.common.ForgeHooks.onLivingHurt(this, damageSrc, damageAmount); ++ if (damageAmount <= 0) return; + damageAmount = this.applyArmorCalculations(damageSrc, damageAmount); + damageAmount = this.applyPotionDamageCalculations(damageSrc, damageAmount); + float f = damageAmount; +@@ -1221,8 +1254,8 @@ + this.setAbsorptionAmount(this.getAbsorptionAmount() - (f - damageAmount)); + if (damageAmount != 0.0F) { + float f1 = this.getHealth(); +- this.setHealth(f1 - damageAmount); + this.getCombatTracker().trackDamage(damageSrc, f1, damageAmount); ++ this.setHealth(f1 - damageAmount); // Forge: moved to fix MC-121048 + this.setAbsorptionAmount(this.getAbsorptionAmount() - damageAmount); + } + } +@@ -1269,6 +1302,10 @@ + } + + public void swingArm(EnumHand hand) { ++ ItemStack stack = this.getHeldItem(hand); ++ if (!stack.isEmpty()) { ++ if (stack.getItem().onEntitySwing(this, stack)) return; ++ } + if (!this.isSwingInProgress || this.swingProgressInt >= this.getArmSwingAnimationEnd() / 2 || this.swingProgressInt < 0) { + this.swingProgressInt = -1; + this.isSwingInProgress = true; +@@ -1473,20 +1510,21 @@ + double d12 = d6 + d10; + AxisAlignedBB axisalignedbb1 = axisalignedbb.offset(d9, 0.0, d10); + if (!this.world.collidesWithAnyBlock(axisalignedbb1)) { +- if (this.world.getBlockState(new BlockPos(d11, this.posY, d12)).isTopSolid()) { ++ if (this.world.getBlockState(new BlockPos(d11, this.posY, d12)).isSideSolid(world, new BlockPos(d11, this.posY, d12), EnumFacing.UP)) { + this.setPositionAndUpdate(d11, this.posY + 1.0, d12); + return; + } + + BlockPos blockpos = new BlockPos(d11, this.posY - 1.0, d12); +- if (this.world.getBlockState(blockpos).isTopSolid() +- || this.world.getBlockState(blockpos).getMaterial() == Material.WATER) { ++ ++ if (this.world.getBlockState(blockpos).isSideSolid(world, blockpos, EnumFacing.UP) ++ || this.world.getBlockState(blockpos).getMaterial() == Material.WATER) { + d1 = d11; + d13 = this.posY + 1.0; + d14 = d12; + } + } else if (!this.world.collidesWithAnyBlock(axisalignedbb1.offset(0.0, 1.0, 0.0)) +- && this.world.getBlockState(new BlockPos(d11, this.posY + 1.0, d12)).isTopSolid()) { ++ && this.world.getBlockState(new BlockPos(d11, this.posY + 1.0, d12)).isSideSolid(world, new BlockPos(d11, this.posY + 1.0, d12), EnumFacing.UP)) { + d1 = d11; + d13 = this.posY + 2.0; + d14 = d12; +@@ -1543,15 +1581,16 @@ + } + + this.isAirBorne = true; ++ net.minecraftforge.common.ForgeHooks.onLivingJump(this); + } + + /** Handles the jump when the entity is in water */ + protected void handleJumpWater() { +- this.motionY += 0.04F; ++ this.motionY += 0.04F * this.getEntityAttribute(SWIM_SPEED).getAttributeValue(); + } + + protected void handleJumpLava() { +- this.motionY += 0.04F; ++ this.motionY += 0.04F * this.getEntityAttribute(SWIM_SPEED).getAttributeValue(); + } + + protected float getWaterSlowDown() { +@@ -1617,7 +1656,8 @@ + this.posX, this.getEntityBoundingBox().minY - 1.0, this.posZ + ); + if (this.onGround) { +- f6 = this.world.getBlockState(blockpos$pooledmutableblockpos).getBlock().slipperiness * 0.91F; ++ IBlockState underState = this.world.getBlockState(blockpos$pooledmutableblockpos); ++ f6 = underState.getBlock().getSlipperiness(underState, this.world, blockpos$pooledmutableblockpos, this) * 0.91F; + } + + float f7 = 0.16277136F / (f6 * f6 * f6); +@@ -1631,15 +1671,11 @@ + this.moveRelative(strafe, vertical, forward, f8); + f6 = 0.91F; + if (this.onGround) { +- f6 = this.world +- .getBlockState( +- blockpos$pooledmutableblockpos.setPos( +- this.posX, this.getEntityBoundingBox().minY - 1.0, this.posZ +- ) +- ) +- .getBlock() +- .slipperiness +- * 0.91F; ++ IBlockState underState = this.world ++ .getBlockState( ++ blockpos$pooledmutableblockpos.setPos(this.posX, this.getEntityBoundingBox().minY - 1.0, this.posZ) ++ ); ++ f6 = underState.getBlock().getSlipperiness(underState, this.world, blockpos$pooledmutableblockpos, this) * 0.91F; + } + + if (this.isOnLadder()) { +@@ -1769,6 +1805,7 @@ + /** Called to update the entity's position/logic. */ + @Override + public void onUpdate() { ++ if (net.minecraftforge.common.ForgeHooks.onLivingUpdate(this)) return; + super.onUpdate(); + this.updateActiveHand(); + if (!this.world.isRemote) { +@@ -1799,9 +1836,12 @@ + + ItemStack itemstack1 = this.getItemStackFromSlot(entityequipmentslot); + if (!ItemStack.areItemStacksEqual(itemstack1, itemstack)) { ++ if (!ItemStack.areItemStacksEqualUsingNBTShareTag(itemstack1, itemstack)) + ((WorldServer)this.world) +- .getEntityTracker() +- .sendToTracking(this, new SPacketEntityEquipment(this.getEntityId(), entityequipmentslot, itemstack1)); ++ .getEntityTracker() ++ .sendToTracking(this, new SPacketEntityEquipment(this.getEntityId(), entityequipmentslot, itemstack1)); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.living.LivingEquipmentChangeEvent(this, entityequipmentslot, itemstack, itemstack1)); ++ + if (!itemstack.isEmpty()) { + this.getAttributeMap().removeAttributeModifiers(itemstack.getAttributeModifiers(entityequipmentslot)); + } +@@ -2210,6 +2250,36 @@ + this.potionsNeedUpdate = true; + } + ++ /*** ++ * Removes all potion effects that have curativeItem as a curative item for its effect ++ * @param curativeItem The itemstack we are using to cure potion effects ++ */ ++ public void curePotionEffects(ItemStack curativeItem) { ++ if (world.isRemote) return; ++ Iterator iterator = this.activePotionsMap.values().iterator(); ++ ++ while (iterator.hasNext()) { ++ PotionEffect effect = iterator.next(); ++ ++ if (effect.isCurativeItem(curativeItem) && !net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.living.PotionEvent.PotionRemoveEvent(this, effect))) { ++ onFinishedPotionEffect(effect); ++ iterator.remove(); ++ this.potionsNeedUpdate = true; ++ } ++ } ++ } ++ ++ /** ++ * Returns true if the entity's rider (EntityPlayer) should face forward when mounted. ++ * currently only used in vanilla code by pigs. ++ * ++ * @param player The player who is riding the entity. ++ * @return If the player should orient the same direction as this entity. ++ */ ++ public boolean shouldRiderFaceForward(EntityPlayer player) { ++ return this instanceof net.minecraft.entity.passive.EntityPig; ++ } ++ + public abstract EnumHandSide getPrimaryHand(); + + public boolean isHandActive() { +@@ -2223,12 +2293,20 @@ + protected void updateActiveHand() { + if (this.isHandActive()) { + ItemStack itemstack = this.getHeldItem(this.getActiveHand()); ++ if (net.minecraftforge.common.ForgeHooks.canContinueUsing(this.activeItemStack, itemstack)) this.activeItemStack = itemstack; ++ + if (itemstack == this.activeItemStack) { ++ if (!this.activeItemStack.isEmpty()) { ++ activeItemStackUseCount = net.minecraftforge.event.ForgeEventFactory.onItemUseTick(this, activeItemStack, activeItemStackUseCount); ++ if (activeItemStackUseCount > 0) ++ activeItemStack.getItem().onUsingTick(activeItemStack, this, activeItemStackUseCount); ++ } ++ + if (this.getItemInUseCount() <= 25 && this.getItemInUseCount() % 4 == 0) { + this.updateItemUse(this.activeItemStack, 5); + } + +- if (--this.activeItemStackUseCount == 0 && !this.world.isRemote) { ++ if (--this.activeItemStackUseCount <= 0 && !this.world.isRemote) { + this.onItemUseFinish(); + } + } else { +@@ -2240,8 +2318,11 @@ + public void setActiveHand(EnumHand hand) { + ItemStack itemstack = this.getHeldItem(hand); + if (!itemstack.isEmpty() && !this.isHandActive()) { ++ int duration = net.minecraftforge.event.ForgeEventFactory.onItemUseStart(this, itemstack, itemstack.getMaxItemUseDuration()); ++ if (duration <= 0) return; + this.activeItemStack = itemstack; +- this.activeItemStackUseCount = itemstack.getMaxItemUseDuration(); ++ this.activeItemStackUseCount = duration; ++ + if (!this.world.isRemote) { + int i = 1; + if (hand == EnumHand.OFF_HAND) { +@@ -2327,7 +2408,10 @@ + protected void onItemUseFinish() { + if (!this.activeItemStack.isEmpty() && this.isHandActive()) { + this.updateItemUse(this.activeItemStack, 16); +- this.setHeldItem(this.getActiveHand(), this.activeItemStack.onItemUseFinish(this.world, this)); ++ ItemStack activeItemStackCopy = this.activeItemStack.copy(); ++ ItemStack itemstack = this.activeItemStack.onItemUseFinish(this.world, this); ++ itemstack = net.minecraftforge.event.ForgeEventFactory.onItemUseFinish(this, activeItemStackCopy, getItemInUseCount(), itemstack); ++ this.setHeldItem(this.getActiveHand(), itemstack); + this.resetActiveHand(); + } + } +@@ -2346,7 +2430,8 @@ + + public void stopActiveHand() { + if (!this.activeItemStack.isEmpty()) { +- this.activeItemStack.onPlayerStoppedUsing(this.world, this, this.getItemInUseCount()); ++ if (!net.minecraftforge.event.ForgeEventFactory.onUseItemStop(this, activeItemStack, this.getItemInUseCount())) ++ this.activeItemStack.onPlayerStoppedUsing(this.world, this, this.getItemInUseCount()); + } + + this.resetActiveHand(); +@@ -2443,6 +2528,28 @@ + return true; + } + ++ // FORGE ++ private final net.minecraftforge.items.IItemHandlerModifiable handHandler = new net.minecraftforge.items.wrapper.EntityHandsInvWrapper(this); ++ private final net.minecraftforge.items.IItemHandlerModifiable armorHandler = new net.minecraftforge.items.wrapper.EntityArmorInvWrapper(this); ++ private final net.minecraftforge.items.IItemHandler joinedHandler = new net.minecraftforge.items.wrapper.CombinedInvWrapper(armorHandler, handHandler); ++ ++ @SuppressWarnings("unchecked") ++ @Override ++ @Nullable ++ public T getCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable net.minecraft.util.EnumFacing facing) { ++ if (capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { ++ if (facing == null) return (T) joinedHandler; ++ else if (facing.getAxis().isVertical()) return (T) handHandler; ++ else if (facing.getAxis().isHorizontal()) return (T) armorHandler; ++ } ++ return super.getCapability(capability, facing); ++ } ++ ++ @Override ++ public boolean hasCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable net.minecraft.util.EnumFacing facing) { ++ return capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY || super.hasCapability(capability, facing); ++ } ++ + public boolean attackable() { + return true; + } +@@ -2456,4 +2563,27 @@ + @SideOnly(Side.CLIENT) + public void setPartying(BlockPos pos, boolean isPartying) { + } ++ ++ @Override ++ public void moveRelative(float strafe, float up, float forward, float friction) { ++ float f = strafe * strafe + up * up + forward * forward; ++ if (f >= 1.0E-4F) { ++ f = MathHelper.sqrt(f); ++ if (f < 1.0F) f = 1.0F; ++ f = friction / f; ++ strafe = strafe * f; ++ up = up * f; ++ forward = forward * f; ++ if(this.isInWater() || this.isInLava()) { ++ strafe = strafe * (float)this.getEntityAttribute(SWIM_SPEED).getAttributeValue(); ++ up = up * (float)this.getEntityAttribute(SWIM_SPEED).getAttributeValue(); ++ forward = forward * (float)this.getEntityAttribute(SWIM_SPEED).getAttributeValue(); ++ } ++ float f1 = MathHelper.sin(this.rotationYaw * (float)(Math.PI / 180.0)); ++ float f2 = MathHelper.cos(this.rotationYaw * (float)(Math.PI / 180.0)); ++ this.motionX += (double)(strafe * f2 - forward * f1); ++ this.motionY += (double)up; ++ this.motionZ += (double)(forward * f2 + strafe * f1); ++ } ++ } + } diff --git a/module/minecraft/patches/net/minecraft/entity/EntitySpawnPlacementRegistry.java.patch b/module/minecraft/patches/net/minecraft/entity/EntitySpawnPlacementRegistry.java.patch new file mode 100644 index 000000000..5bc9698e4 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/EntitySpawnPlacementRegistry.java.patch @@ -0,0 +1,17 @@ +--- original/net/minecraft/entity/EntitySpawnPlacementRegistry.java ++++ modified/net/minecraft/entity/EntitySpawnPlacementRegistry.java +@@ -48,9 +48,13 @@ + private static final Map, EntityLiving.SpawnPlacementType> ENTITY_PLACEMENTS = Maps.newHashMap(); + + public static EntityLiving.SpawnPlacementType getPlacementForEntity(Class entityClass) { +- return ENTITY_PLACEMENTS.get(entityClass); ++ return ENTITY_PLACEMENTS.getOrDefault(entityClass, EntityLiving.SpawnPlacementType.ON_GROUND); + } + ++ public static void setPlacementType(Class entityClass, EntityLiving.SpawnPlacementType placementType) { ++ ENTITY_PLACEMENTS.putIfAbsent(entityClass, placementType); ++ } ++ + static { + ENTITY_PLACEMENTS.put(EntityBat.class, EntityLiving.SpawnPlacementType.ON_GROUND); + ENTITY_PLACEMENTS.put(EntityChicken.class, EntityLiving.SpawnPlacementType.ON_GROUND); diff --git a/module/minecraft/patches/net/minecraft/entity/EntityTracker.java.patch b/module/minecraft/patches/net/minecraft/entity/EntityTracker.java.patch new file mode 100644 index 000000000..ee4f8d353 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/EntityTracker.java.patch @@ -0,0 +1,36 @@ +--- original/net/minecraft/entity/EntityTracker.java ++++ modified/net/minecraft/entity/EntityTracker.java +@@ -75,6 +75,8 @@ + } + + public void track(Entity entityIn) { ++ if (net.minecraftforge.fml.common.registry.EntityRegistry.instance().tryTrackingEntity(this, entityIn)) return; ++ + if (entityIn instanceof EntityPlayerMP) { + this.track(entityIn, 512, 2); + EntityPlayerMP entityplayermp = (EntityPlayerMP)entityIn; +@@ -250,6 +252,24 @@ + } + } + ++ /* ======================================== FORGE START =====================================*/ ++ ++ // don't expose the EntityTrackerEntry directly so mods can't mess with the data in there as easily ++ /** ++ * Get all players tracking the given Entity. The Entity must be part of the World that this Tracker belongs to. ++ * @param entity the Entity ++ * @return all players tracking the Entity ++ */ ++ public Set getTrackingPlayers(Entity entity) { ++ EntityTrackerEntry entry = (EntityTrackerEntry) trackedEntityHashTable.lookup(entity.getEntityId()); ++ if (entry == null) ++ return java.util.Collections.emptySet(); ++ else ++ return java.util.Collections.unmodifiableSet(entry.trackingPlayers); ++ } ++ ++ /* ======================================== FORGE END =====================================*/ ++ + public void sendToTrackingAndSelf(Entity entityIn, Packet packetIn) { + EntityTrackerEntry entitytrackerentry = this.trackedEntityHashTable.lookup(entityIn.getEntityId()); + if (entitytrackerentry != null) { diff --git a/module/minecraft/patches/net/minecraft/entity/EntityTrackerEntry.java.patch b/module/minecraft/patches/net/minecraft/entity/EntityTrackerEntry.java.patch new file mode 100644 index 000000000..2364c5a18 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/EntityTrackerEntry.java.patch @@ -0,0 +1,42 @@ +--- original/net/minecraft/entity/EntityTrackerEntry.java ++++ modified/net/minecraft/entity/EntityTrackerEntry.java +@@ -154,12 +154,13 @@ + EntityItemFrame entityitemframe = (EntityItemFrame)this.trackedEntity; + ItemStack itemstack = entityitemframe.getDisplayedItem(); + if (itemstack.getItem() instanceof ItemMap) { +- MapData mapdata = Items.FILLED_MAP.getMapData(itemstack, this.trackedEntity.world); ++ MapData mapdata = ((ItemMap) itemstack.getItem()).getMapData(itemstack, this.trackedEntity.world); + + for (EntityPlayer entityplayer : players) { + EntityPlayerMP entityplayermp = (EntityPlayerMP)entityplayer; + mapdata.updateVisiblePlayers(entityplayermp, itemstack); +- Packet packet = Items.FILLED_MAP.createMapDataPacket(itemstack, this.trackedEntity.world, entityplayermp); ++ Packet packet = ((ItemMap) itemstack.getItem()).createMapDataPacket(itemstack, this.trackedEntity.world, entityplayermp); ++ + if (packet != null) { + entityplayermp.connection.sendPacket(packet); + } +@@ -415,11 +416,13 @@ + + this.trackedEntity.addTrackingPlayer(playerMP); + playerMP.addEntity(this.trackedEntity); ++ net.minecraftforge.event.ForgeEventFactory.onStartEntityTracking(trackedEntity, playerMP); + } + } else if (this.trackingPlayers.contains(playerMP)) { + this.trackingPlayers.remove(playerMP); + this.trackedEntity.removeTrackingPlayer(playerMP); + playerMP.removeEntity(this.trackedEntity); ++ net.minecraftforge.event.ForgeEventFactory.onStopEntityTracking(trackedEntity, playerMP); + } + } + } +@@ -447,6 +450,9 @@ + LOGGER.warn("Fetching addPacket for removed entity"); + } + ++ Packet pkt = net.minecraftforge.fml.common.network.internal.FMLNetworkHandler.getEntitySpawningPacket(this.trackedEntity); ++ if (pkt != null) return pkt; ++ + if (this.trackedEntity instanceof EntityPlayerMP) { + return new SPacketSpawnPlayer((EntityPlayer)this.trackedEntity); + } diff --git a/module/minecraft/patches/net/minecraft/entity/NpcMerchant.java.patch b/module/minecraft/patches/net/minecraft/entity/NpcMerchant.java.patch new file mode 100644 index 000000000..b26a706c3 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/NpcMerchant.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/entity/NpcMerchant.java ++++ modified/net/minecraft/entity/NpcMerchant.java +@@ -42,7 +42,7 @@ + @Nullable + @Override + public MerchantRecipeList getRecipes(EntityPlayer player) { +- return this.recipeList; ++ return net.minecraftforge.event.ForgeEventFactory.listTradeOffers(this, player, this.recipeList); + } + + @Override diff --git a/module/minecraft/patches/net/minecraft/entity/SharedMonsterAttributes.java.patch b/module/minecraft/patches/net/minecraft/entity/SharedMonsterAttributes.java.patch new file mode 100644 index 000000000..e63b95a9d --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/SharedMonsterAttributes.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/entity/SharedMonsterAttributes.java ++++ modified/net/minecraft/entity/SharedMonsterAttributes.java +@@ -15,7 +15,7 @@ + + public class SharedMonsterAttributes { + private static final Logger LOGGER = LogManager.getLogger(); +- public static final IAttribute MAX_HEALTH = new RangedAttribute(null, "generic.maxHealth", 20.0, 0.0, 1024.0) ++ public static final IAttribute MAX_HEALTH = (new RangedAttribute(null, "generic.maxHealth", 20.0, Float.MIN_VALUE, 1024.0)) // Forge: set smallest max-health value to fix MC-119183. This gets rounded to float so we use the smallest positive float value. + .setDescription("Max Health") + .setShouldWatch(true); + public static final IAttribute FOLLOW_RANGE = new RangedAttribute(null, "generic.followRange", 32.0, 0.0, 2048.0).setDescription("Follow Range"); diff --git a/module/minecraft/patches/net/minecraft/entity/ai/EntityAIAttackMelee.java.patch b/module/minecraft/patches/net/minecraft/entity/ai/EntityAIAttackMelee.java.patch new file mode 100644 index 000000000..e673c8755 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/ai/EntityAIAttackMelee.java.patch @@ -0,0 +1,54 @@ +--- original/net/minecraft/entity/ai/EntityAIAttackMelee.java ++++ modified/net/minecraft/entity/ai/EntityAIAttackMelee.java +@@ -24,6 +24,8 @@ + private double targetY; + private double targetZ; + protected final int attackInterval = 20; ++ private int failedPathFindingPenalty = 0; ++ private boolean canPenalize = false; + + public EntityAIAttackMelee(EntityCreature creature, double speedIn, boolean useLongMemory) { + this.attacker = creature; +@@ -45,6 +47,19 @@ + return false; + } + ++ if (canPenalize) ++ { ++ if (--this.delayCounter <= 0) ++ { ++ this.path = this.attacker.getNavigator().getPathToEntityLiving(entitylivingbase); ++ this.delayCounter = 4 + this.attacker.getRNG().nextInt(7); ++ return this.path != null; ++ } ++ else ++ { ++ return true; ++ } ++ } + this.path = this.attacker.getNavigator().getPathToEntityLiving(entitylivingbase); + return this.path != null + ? true +@@ -110,6 +125,22 @@ + this.targetY = entitylivingbase.getEntityBoundingBox().minY; + this.targetZ = entitylivingbase.posZ; + this.delayCounter = 4 + this.attacker.getRNG().nextInt(7); ++ if (this.canPenalize) ++ { ++ this.delayCounter += failedPathFindingPenalty; ++ if (this.attacker.getNavigator().getPath() != null) ++ { ++ net.minecraft.pathfinding.PathPoint finalPathPoint = this.attacker.getNavigator().getPath().getFinalPathPoint(); ++ if (finalPathPoint != null && entitylivingbase.getDistanceSq(finalPathPoint.x, finalPathPoint.y, finalPathPoint.z) < 1) ++ failedPathFindingPenalty = 0; ++ else ++ failedPathFindingPenalty += 10; ++ } ++ else ++ { ++ failedPathFindingPenalty += 10; ++ } ++ } + if (d0 > 1024.0) { + this.delayCounter += 10; + } else if (d0 > 256.0) { diff --git a/module/minecraft/patches/net/minecraft/entity/ai/EntityAIAttackRangedBow.java.patch b/module/minecraft/patches/net/minecraft/entity/ai/EntityAIAttackRangedBow.java.patch new file mode 100644 index 000000000..cf1db28d4 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/ai/EntityAIAttackRangedBow.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/entity/ai/EntityAIAttackRangedBow.java ++++ modified/net/minecraft/entity/ai/EntityAIAttackRangedBow.java +@@ -37,7 +37,7 @@ + } + + protected boolean isBowInMainhand() { +- return !this.entity.getHeldItemMainhand().isEmpty() && this.entity.getHeldItemMainhand().getItem() == Items.BOW; ++ return !this.entity.getHeldItemMainhand().isEmpty() && this.entity.getHeldItemMainhand().getItem() instanceof ItemBow; + } + + /** Returns whether an in-progress EntityAIBase should continue executing */ diff --git a/module/minecraft/patches/net/minecraft/entity/ai/EntityAIBreakDoor.java.patch b/module/minecraft/patches/net/minecraft/entity/ai/EntityAIBreakDoor.java.patch new file mode 100644 index 000000000..6c06cd78d --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/ai/EntityAIBreakDoor.java.patch @@ -0,0 +1,29 @@ +--- original/net/minecraft/entity/ai/EntityAIBreakDoor.java ++++ modified/net/minecraft/entity/ai/EntityAIBreakDoor.java +@@ -19,9 +19,23 @@ + if (!super.shouldExecute()) { + return false; + } else { +- return !this.entity.world.getGameRules().getBoolean("mobGriefing") +- ? false +- : !BlockDoor.isOpen(this.entity.world, this.doorPosition); ++ return !net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.entity.world, this.entity) ++ || !this.entity.world ++ .getBlockState(this.doorPosition) ++ .getBlock() ++ .canEntityDestroy( ++ this.entity.world.getBlockState(this.doorPosition), ++ this.entity.world, ++ this.doorPosition, ++ this.entity ++ ) ++ || !net.minecraftforge.event.ForgeEventFactory.onEntityDestroyBlock( ++ this.entity, ++ this.doorPosition, ++ this.entity.world.getBlockState(this.doorPosition) ++ ) ++ ? false ++ : !BlockDoor.isOpen(this.entity.world, this.doorPosition); + } + } + diff --git a/module/minecraft/patches/net/minecraft/entity/ai/EntityAIEatGrass.java.patch b/module/minecraft/patches/net/minecraft/entity/ai/EntityAIEatGrass.java.patch new file mode 100644 index 000000000..6f10d953f --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/ai/EntityAIEatGrass.java.patch @@ -0,0 +1,20 @@ +--- original/net/minecraft/entity/ai/EntityAIEatGrass.java ++++ modified/net/minecraft/entity/ai/EntityAIEatGrass.java +@@ -72,7 +72,7 @@ + if (this.eatingGrassTimer == 4) { + BlockPos blockpos = new BlockPos(this.grassEaterEntity.posX, this.grassEaterEntity.posY, this.grassEaterEntity.posZ); + if (IS_TALL_GRASS.apply(this.entityWorld.getBlockState(blockpos))) { +- if (this.entityWorld.getGameRules().getBoolean("mobGriefing")) { ++ if (net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.entityWorld, this.grassEaterEntity)) { + this.entityWorld.destroyBlock(blockpos, false); + } + +@@ -80,7 +80,7 @@ + } else { + BlockPos blockpos1 = blockpos.down(); + if (this.entityWorld.getBlockState(blockpos1).getBlock() == Blocks.GRASS) { +- if (this.entityWorld.getGameRules().getBoolean("mobGriefing")) { ++ if (net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.entityWorld, this.grassEaterEntity)) { + this.entityWorld.playEvent(2001, blockpos1, Block.getIdFromBlock(Blocks.GRASS)); + this.entityWorld.setBlockState(blockpos1, Blocks.DIRT.getDefaultState(), 2); + } diff --git a/module/minecraft/patches/net/minecraft/entity/ai/EntityAIHarvestFarmland.java.patch b/module/minecraft/patches/net/minecraft/entity/ai/EntityAIHarvestFarmland.java.patch new file mode 100644 index 000000000..2f9d6873f --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/ai/EntityAIHarvestFarmland.java.patch @@ -0,0 +1,23 @@ +--- original/net/minecraft/entity/ai/EntityAIHarvestFarmland.java ++++ modified/net/minecraft/entity/ai/EntityAIHarvestFarmland.java +@@ -29,7 +29,7 @@ + @Override + public boolean shouldExecute() { + if (this.runDelay <= 0) { +- if (!this.villager.world.getGameRules().getBoolean("mobGriefing")) { ++ if (!net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.villager.world, this.villager)) { + return false; + } + +@@ -86,6 +86,11 @@ + } else if (itemstack.getItem() == Items.BEETROOT_SEEDS) { + world.setBlockState(blockpos, Blocks.BEETROOTS.getDefaultState(), 3); + flag = true; ++ } else if (itemstack.getItem() instanceof net.minecraftforge.common.IPlantable) { ++ if(((net.minecraftforge.common.IPlantable)itemstack.getItem()).getPlantType(world,blockpos) == net.minecraftforge.common.EnumPlantType.Crop) { ++ world.setBlockState(blockpos, ((net.minecraftforge.common.IPlantable)itemstack.getItem()).getPlant(world,blockpos),3); ++ flag = true; ++ } + } + } + diff --git a/module/minecraft/patches/net/minecraft/entity/ai/EntityAIMate.java.patch b/module/minecraft/patches/net/minecraft/entity/ai/EntityAIMate.java.patch new file mode 100644 index 000000000..38dd26870 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/ai/EntityAIMate.java.patch @@ -0,0 +1,22 @@ +--- original/net/minecraft/entity/ai/EntityAIMate.java ++++ modified/net/minecraft/entity/ai/EntityAIMate.java +@@ -87,6 +87,19 @@ + /** Spawns a baby animal of the same type. */ + private void spawnBaby() { + EntityAgeable entityageable = this.animal.createChild(this.targetMate); ++ ++ final net.minecraftforge.event.entity.living.BabyEntitySpawnEvent event = new net.minecraftforge.event.entity.living.BabyEntitySpawnEvent(animal, targetMate, entityageable); ++ final boolean cancelled = net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event); ++ entityageable = event.getChild(); ++ if (cancelled) { ++ //Reset the "inLove" state for the animals ++ this.animal.setGrowingAge(6000); ++ this.targetMate.setGrowingAge(6000); ++ this.animal.resetInLove(); ++ this.targetMate.resetInLove(); ++ return; ++ } ++ + if (entityageable != null) { + EntityPlayerMP entityplayermp = this.animal.getLoveCause(); + if (entityplayermp == null && this.targetMate.getLoveCause() != null) { diff --git a/module/minecraft/patches/net/minecraft/entity/ai/EntityAIRunAroundLikeCrazy.java.patch b/module/minecraft/patches/net/minecraft/entity/ai/EntityAIRunAroundLikeCrazy.java.patch new file mode 100644 index 000000000..388fd3681 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/ai/EntityAIRunAroundLikeCrazy.java.patch @@ -0,0 +1,12 @@ +--- original/net/minecraft/entity/ai/EntityAIRunAroundLikeCrazy.java ++++ modified/net/minecraft/entity/ai/EntityAIRunAroundLikeCrazy.java +@@ -60,7 +60,8 @@ + if (entity instanceof EntityPlayer) { + int i = this.horseHost.getTemper(); + int j = this.horseHost.getMaxTemper(); +- if (j > 0 && this.horseHost.getRNG().nextInt(j) < i) { ++ ++ if (j > 0 && this.horseHost.getRNG().nextInt(j) < i && !net.minecraftforge.event.ForgeEventFactory.onAnimalTame(horseHost, (EntityPlayer)entity)) { + this.horseHost.setTamedBy((EntityPlayer)entity); + return; + } diff --git a/module/minecraft/patches/net/minecraft/entity/ai/EntityAIVillagerMate.java.patch b/module/minecraft/patches/net/minecraft/entity/ai/EntityAIVillagerMate.java.patch new file mode 100644 index 000000000..768a8dc04 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/ai/EntityAIVillagerMate.java.patch @@ -0,0 +1,19 @@ +--- original/net/minecraft/entity/ai/EntityAIVillagerMate.java ++++ modified/net/minecraft/entity/ai/EntityAIVillagerMate.java +@@ -96,11 +96,15 @@ + } + + private void giveBirth() { +- EntityVillager entityvillager = this.villager.createChild(this.mate); ++ net.minecraft.entity.EntityAgeable entityvillager = this.villager.createChild(this.mate); + this.mate.setGrowingAge(6000); + this.villager.setGrowingAge(6000); + this.mate.setIsWillingToMate(false); + this.villager.setIsWillingToMate(false); ++ ++ final net.minecraftforge.event.entity.living.BabyEntitySpawnEvent event = new net.minecraftforge.event.entity.living.BabyEntitySpawnEvent(villager, mate, entityvillager); ++ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event) || event.getChild() == null) { return; } ++ entityvillager = event.getChild(); + entityvillager.setGrowingAge(-24000); + entityvillager.setLocationAndAngles(this.villager.posX, this.villager.posY, this.villager.posZ, 0.0F, 0.0F); + this.world.spawnEntity(entityvillager); diff --git a/module/minecraft/patches/net/minecraft/entity/boss/EntityDragon.java.patch b/module/minecraft/patches/net/minecraft/entity/boss/EntityDragon.java.patch new file mode 100644 index 000000000..8c4a4ecda --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/boss/EntityDragon.java.patch @@ -0,0 +1,23 @@ +--- original/net/minecraft/entity/boss/EntityDragon.java ++++ modified/net/minecraft/entity/boss/EntityDragon.java +@@ -498,15 +498,12 @@ + BlockPos blockpos = new BlockPos(k1, l1, i2); + IBlockState iblockstate = this.world.getBlockState(blockpos); + Block block = iblockstate.getBlock(); +- if (iblockstate.getMaterial() != Material.AIR && iblockstate.getMaterial() != Material.FIRE) { +- if (!this.world.getGameRules().getBoolean("mobGriefing")) { ++ ++ if (!block.isAir(iblockstate, this.world, blockpos) && iblockstate.getMaterial() != Material.FIRE) { ++ if (!net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.world, this)) { + flag = true; +- } else if (block == Blocks.BARRIER +- || block == Blocks.OBSIDIAN +- || block == Blocks.END_STONE +- || block == Blocks.BEDROCK +- || block == Blocks.END_PORTAL +- || block == Blocks.END_PORTAL_FRAME) { ++ } else if (!block.canEntityDestroy(iblockstate, this.world, blockpos, this) ++ || !net.minecraftforge.event.ForgeEventFactory.onEntityDestroyBlock(this, blockpos, iblockstate)) { + flag = true; + } else if (block != Blocks.COMMAND_BLOCK + && block != Blocks.REPEATING_COMMAND_BLOCK diff --git a/module/minecraft/patches/net/minecraft/entity/boss/EntityWither.java.patch b/module/minecraft/patches/net/minecraft/entity/boss/EntityWither.java.patch new file mode 100644 index 000000000..a17046f82 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/boss/EntityWither.java.patch @@ -0,0 +1,49 @@ +--- original/net/minecraft/entity/boss/EntityWither.java ++++ modified/net/minecraft/entity/boss/EntityWither.java +@@ -261,15 +261,15 @@ + int j1 = this.getInvulTime() - 1; + if (j1 <= 0) { + this.world +- .newExplosion( +- this, +- this.posX, +- this.posY + this.getEyeHeight(), +- this.posZ, +- 7.0F, +- false, +- this.world.getGameRules().getBoolean("mobGriefing") +- ); ++ .newExplosion( ++ this, ++ this.posX, ++ this.posY + this.getEyeHeight(), ++ this.posZ, ++ 7.0F, ++ false, ++ net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.world, this) ++ ); + this.world.playBroadcastSound(1023, new BlockPos(this), 0); + } + +@@ -341,7 +341,8 @@ + + if (this.blockBreakCounter > 0) { + this.blockBreakCounter--; +- if (this.blockBreakCounter == 0 && this.world.getGameRules().getBoolean("mobGriefing")) { ++ ++ if (this.blockBreakCounter == 0 && net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.world, this)) { + int i1 = MathHelper.floor(this.posY); + int l1 = MathHelper.floor(this.posX); + int i2 = MathHelper.floor(this.posZ); +@@ -356,7 +357,10 @@ + BlockPos blockpos = new BlockPos(i3, k, l); + IBlockState iblockstate = this.world.getBlockState(blockpos); + Block block = iblockstate.getBlock(); +- if (iblockstate.getMaterial() != Material.AIR && canDestroyBlock(block)) { ++ ++ if (!block.isAir(iblockstate, this.world, blockpos) ++ && block.canEntityDestroy(iblockstate, world, blockpos, this) ++ && net.minecraftforge.event.ForgeEventFactory.onEntityDestroyBlock(this, blockpos, iblockstate)) { + flag = this.world.destroyBlock(blockpos, true) || flag; + } + } diff --git a/module/minecraft/patches/net/minecraft/entity/boss/dragon/phase/PhaseSittingFlaming.java.patch b/module/minecraft/patches/net/minecraft/entity/boss/dragon/phase/PhaseSittingFlaming.java.patch new file mode 100644 index 000000000..fd41b8bec --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/boss/dragon/phase/PhaseSittingFlaming.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/entity/boss/dragon/phase/PhaseSittingFlaming.java ++++ modified/net/minecraft/entity/boss/dragon/phase/PhaseSittingFlaming.java +@@ -84,7 +84,7 @@ + MathHelper.floor(d0), MathHelper.floor(d2), MathHelper.floor(d1) + ); + +- while (this.dragon.world.isAirBlock(blockpos$mutableblockpos)) { ++ while (this.dragon.world.isAirBlock(blockpos$mutableblockpos) && d2 >= 0) { //Forge: Fix infinite loop if ground is missing. + blockpos$mutableblockpos.setPos(MathHelper.floor(d0), MathHelper.floor(--d2), MathHelper.floor(d1)); + } + diff --git a/module/minecraft/patches/net/minecraft/entity/effect/EntityLightningBolt.java.patch b/module/minecraft/patches/net/minecraft/entity/effect/EntityLightningBolt.java.patch new file mode 100644 index 000000000..1812eb011 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/effect/EntityLightningBolt.java.patch @@ -0,0 +1,12 @@ +--- original/net/minecraft/entity/effect/EntityLightningBolt.java ++++ modified/net/minecraft/entity/effect/EntityLightningBolt.java +@@ -124,7 +124,8 @@ + + for (int i = 0; i < list.size(); i++) { + Entity entity = list.get(i); +- entity.onStruckByLightning(this); ++ if (!net.minecraftforge.event.ForgeEventFactory.onEntityStruckByLightning(entity, this)) ++ entity.onStruckByLightning(this); + } + } + } diff --git a/module/minecraft/patches/net/minecraft/entity/item/EntityArmorStand.java.patch b/module/minecraft/patches/net/minecraft/entity/item/EntityArmorStand.java.patch new file mode 100644 index 000000000..0fc001945 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/item/EntityArmorStand.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/entity/item/EntityArmorStand.java ++++ modified/net/minecraft/entity/item/EntityArmorStand.java +@@ -55,7 +55,7 @@ + public static final DataParameter RIGHT_LEG_ROTATION = EntityDataManager.createKey(EntityArmorStand.class, DataSerializers.ROTATIONS); + private static final Predicate IS_RIDEABLE_MINECART = new Predicate() { + public boolean apply(@Nullable Entity p_apply_1_) { +- return p_apply_1_ instanceof EntityMinecart && ((EntityMinecart)p_apply_1_).getType() == EntityMinecart.Type.RIDEABLE; ++ return p_apply_1_ instanceof EntityMinecart && ((EntityMinecart)p_apply_1_).canBeRidden(); + } + }; + private final NonNullList handItems = NonNullList.withSize(2, ItemStack.EMPTY); diff --git a/module/minecraft/patches/net/minecraft/entity/item/EntityBoat.java.patch b/module/minecraft/patches/net/minecraft/entity/item/EntityBoat.java.patch new file mode 100644 index 000000000..ebc44318a --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/item/EntityBoat.java.patch @@ -0,0 +1,78 @@ +--- original/net/minecraft/entity/item/EntityBoat.java ++++ modified/net/minecraft/entity/item/EntityBoat.java +@@ -413,6 +413,11 @@ + for (int i2 = i1; i2 < j1; i2++) { + blockpos$pooledmutableblockpos.setPos(l1, k1, i2); + IBlockState iblockstate = this.world.getBlockState(blockpos$pooledmutableblockpos); ++ Boolean result = iblockstate.getBlock().isAABBInsideMaterial(world, blockpos$pooledmutableblockpos, new AxisAlignedBB(blockpos$pooledmutableblockpos), Material.WATER); ++ if (result != null) { ++ if (!result) continue; ++ f = Math.max(f, iblockstate.getBlock().getBlockLiquidHeight(world, blockpos$pooledmutableblockpos, iblockstate, Material.WATER) + blockpos$pooledmutableblockpos.getY()); ++ } + if (iblockstate.getMaterial() == Material.WATER) { + f = Math.max(f, BlockLiquid.getBlockLiquidHeight(iblockstate, this.world, blockpos$pooledmutableblockpos)); + } +@@ -467,7 +472,7 @@ + IBlockState iblockstate = this.world.getBlockState(blockpos$pooledmutableblockpos); + iblockstate.addCollisionBoxToList(this.world, blockpos$pooledmutableblockpos, axisalignedbb1, list, this, false); + if (!list.isEmpty()) { +- f += iblockstate.getBlock().slipperiness; ++ f += iblockstate.getBlock().getSlipperiness(iblockstate, this.world, blockpos$pooledmutableblockpos, this); + k1++; + } + +@@ -502,6 +507,14 @@ + for (int i2 = i1; i2 < j1; i2++) { + blockpos$pooledmutableblockpos.setPos(k1, l1, i2); + IBlockState iblockstate = this.world.getBlockState(blockpos$pooledmutableblockpos); ++ Boolean result = iblockstate.getBlock().isAABBInsideMaterial(world, blockpos$pooledmutableblockpos, axisalignedbb, Material.WATER); ++ if (result != null) { ++ if (!result) continue; ++ ++ float f = iblockstate.getBlock().getBlockLiquidHeight(world, blockpos$pooledmutableblockpos, iblockstate, Material.WATER) + blockpos$pooledmutableblockpos.getY(); ++ this.waterLevel = Math.max(f, this.waterLevel); ++ flag |= axisalignedbb.minY < (double)f; ++ } + if (iblockstate.getMaterial() == Material.WATER) { + float f = BlockLiquid.getLiquidHeight(iblockstate, this.world, blockpos$pooledmutableblockpos); + this.waterLevel = Math.max(f, this.waterLevel); +@@ -537,6 +550,17 @@ + for (int i2 = i1; i2 < j1; i2++) { + blockpos$pooledmutableblockpos.setPos(k1, l1, i2); + IBlockState iblockstate = this.world.getBlockState(blockpos$pooledmutableblockpos); ++ Boolean result = iblockstate.getBlock().isAABBInsideMaterial(world, blockpos$pooledmutableblockpos, axisalignedbb, Material.WATER); ++ if (result != null) { ++ if (!result) continue; ++ ++ if(iblockstate.getBlock().getBlockLiquidHeight(world, blockpos$pooledmutableblockpos, iblockstate, Material.WATER) > 0) ++ { ++ blockpos$pooledmutableblockpos.release(); ++ return EntityBoat.Status.UNDER_FLOWING_WATER; ++ } else ++ continue; ++ } + if (iblockstate.getMaterial() == Material.WATER + && d0 < BlockLiquid.getLiquidHeight(iblockstate, this.world, blockpos$pooledmutableblockpos)) { + if (iblockstate.getValue(BlockLiquid.LEVEL) != 0) { +@@ -803,6 +827,21 @@ + this.forwardInputDown = p_184442_3_; + this.backInputDown = p_184442_4_; + } ++ // Forge: Fix MC-119811 by instantly completing lerp on board ++ @Override ++ protected void addPassenger(Entity passenger) ++ { ++ super.addPassenger(passenger); ++ if(this.canPassengerSteer() && this.lerpSteps > 0) ++ { ++ this.lerpSteps = 0; ++ this.posX = this.lerpX; ++ this.posY = this.lerpY; ++ this.posZ = this.lerpZ; ++ this.rotationYaw = (float)this.lerpYaw; ++ this.rotationPitch = (float)this.lerpPitch; ++ } ++ } + + public enum Status { + IN_WATER, diff --git a/module/minecraft/patches/net/minecraft/entity/item/EntityEnderPearl.java.patch b/module/minecraft/patches/net/minecraft/entity/item/EntityEnderPearl.java.patch new file mode 100644 index 000000000..c10bf1b31 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/item/EntityEnderPearl.java.patch @@ -0,0 +1,43 @@ +--- original/net/minecraft/entity/item/EntityEnderPearl.java ++++ modified/net/minecraft/entity/item/EntityEnderPearl.java +@@ -89,8 +89,11 @@ + if (entitylivingbase instanceof EntityPlayerMP) { + EntityPlayerMP entityplayermp = (EntityPlayerMP)entitylivingbase; + if (entityplayermp.connection.getNetworkManager().isChannelOpen() +- && entityplayermp.world == this.world +- && !entityplayermp.isPlayerSleeping()) { ++ && entityplayermp.world == this.world ++ && !entityplayermp.isPlayerSleeping()) { ++ net.minecraftforge.event.entity.living.EnderTeleportEvent event = new net.minecraftforge.event.entity.living.EnderTeleportEvent(entityplayermp, this.posX, this.posY, this.posZ, 5.0F); ++ if (!net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event)) ++ { // Don't indent to lower patch size + if (this.rand.nextFloat() < 0.05F && this.world.getGameRules().getBoolean("doMobSpawning")) { + EntityEndermite entityendermite = new EntityEndermite(this.world); + entityendermite.setSpawnedByPlayer(true); +@@ -108,9 +111,10 @@ + entitylivingbase.dismountRidingEntity(); + } + +- entitylivingbase.setPositionAndUpdate(this.posX, this.posY, this.posZ); ++ entitylivingbase.setPositionAndUpdate(event.getTargetX(), event.getTargetY(), event.getTargetZ()); + entitylivingbase.fallDistance = 0.0F; +- entitylivingbase.attackEntityFrom(DamageSource.FALL, 5.0F); ++ entitylivingbase.attackEntityFrom(DamageSource.FALL, event.getAttackDamage()); ++ } + } + } else if (entitylivingbase != null) { + entitylivingbase.setPositionAndUpdate(this.posX, this.posY, this.posZ); +@@ -134,11 +138,11 @@ + + @Nullable + @Override +- public Entity changeDimension(int dimensionIn) { ++ public Entity changeDimension(int dimensionIn, net.minecraftforge.common.util.ITeleporter teleporter) { + if (this.thrower.dimension != dimensionIn) { + this.thrower = null; + } + +- return super.changeDimension(dimensionIn); ++ return super.changeDimension(dimensionIn, teleporter); + } + } diff --git a/module/minecraft/patches/net/minecraft/entity/item/EntityFallingBlock.java.patch b/module/minecraft/patches/net/minecraft/entity/item/EntityFallingBlock.java.patch new file mode 100644 index 000000000..db235a74c --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/item/EntityFallingBlock.java.patch @@ -0,0 +1,30 @@ +--- original/net/minecraft/entity/item/EntityFallingBlock.java ++++ modified/net/minecraft/entity/item/EntityFallingBlock.java +@@ -148,6 +148,8 @@ + } + } else { + IBlockState iblockstate = this.world.getBlockState(blockpos1); ++ ++ if (this.world.isAirBlock(new BlockPos(this.posX, this.posY - 0.01F, this.posZ))) //Forge: Don't indent below. + if (!flag1 + && BlockFalling.canFallThrough( + this.world.getBlockState(new BlockPos(this.posX, this.posY - 0.01F, this.posZ)) +@@ -162,14 +164,14 @@ + if (iblockstate.getBlock() != Blocks.PISTON_EXTENSION) { + this.setDead(); + if (!this.dontSetBlock) { +- if (this.world.mayPlace(block, blockpos1, true, EnumFacing.UP, null) +- && (flag1 || !BlockFalling.canFallThrough(this.world.getBlockState(blockpos1.down()))) +- && this.world.setBlockState(blockpos1, this.fallTile, 3)) { ++ if (this.world.mayPlace(block, blockpos1, true, EnumFacing.UP, this) ++ && (flag1 || !BlockFalling.canFallThrough(this.world.getBlockState(blockpos1.down()))) ++ && this.world.setBlockState(blockpos1, this.fallTile, 3)) { + if (block instanceof BlockFalling) { + ((BlockFalling)block).onEndFalling(this.world, blockpos1, this.fallTile, iblockstate); + } + +- if (this.tileEntityData != null && block instanceof ITileEntityProvider) { ++ if (this.tileEntityData != null && block.hasTileEntity(this.fallTile)) { + TileEntity tileentity = this.world.getTileEntity(blockpos1); + if (tileentity != null) { + NBTTagCompound nbttagcompound = tileentity.writeToNBT(new NBTTagCompound()); diff --git a/module/minecraft/patches/net/minecraft/entity/item/EntityItem.java.patch b/module/minecraft/patches/net/minecraft/entity/item/EntityItem.java.patch new file mode 100644 index 000000000..b677b16e1 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/item/EntityItem.java.patch @@ -0,0 +1,146 @@ +--- original/net/minecraft/entity/item/EntityItem.java ++++ modified/net/minecraft/entity/item/EntityItem.java +@@ -40,6 +40,11 @@ + /** The EntityItem's random initial float height. */ + public float hoverStart = (float)(Math.random() * Math.PI * 2.0); + ++ /** ++ * The maximum age of this EntityItem. The item is expired once this is reached. ++ */ ++ public int lifespan = 6000; ++ + public EntityItem(World worldIn, double x, double y, double z) { + super(worldIn); + this.setSize(0.25F, 0.25F); +@@ -53,6 +58,7 @@ + public EntityItem(World worldIn, double x, double y, double z, ItemStack stack) { + this(worldIn, x, y, z); + this.setItem(stack); ++ this.lifespan = (stack.getItem() == null ? 6000 : stack.getItem().getEntityLifespan(stack, worldIn)); + } + + /** returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to prevent them from trampling crops */ +@@ -75,6 +81,7 @@ + /** Called to update the entity's position/logic. */ + @Override + public void onUpdate() { ++ if (getItem().getItem().onEntityItemUpdate(this)) return; + if (this.getItem().isEmpty()) { + this.setDead(); + } else { +@@ -120,17 +127,9 @@ + + float f = 0.98F; + if (this.onGround) { +- f = this.world +- .getBlockState( +- new BlockPos( +- MathHelper.floor(this.posX), +- MathHelper.floor(this.getEntityBoundingBox().minY) - 1, +- MathHelper.floor(this.posZ) +- ) +- ) +- .getBlock() +- .slipperiness +- * 0.98F; ++ BlockPos underPos = new BlockPos(MathHelper.floor(this.posX), MathHelper.floor(this.getEntityBoundingBox().minY) - 1, MathHelper.floor(this.posZ)); ++ net.minecraft.block.state.IBlockState underState = this.world.getBlockState(underPos); ++ f = underState.getBlock().getSlipperiness(underState, this.world, underPos, this) * 0.98F; + } + + this.motionX *= f; +@@ -155,7 +154,14 @@ + } + } + +- if (!this.world.isRemote && this.age >= 6000) { ++ ItemStack item = this.getItem(); ++ ++ if (!this.world.isRemote && this.age >= lifespan) { ++ int hook = net.minecraftforge.event.ForgeEventFactory.onItemExpire(this, item); ++ if (hook < 0) this.setDead(); ++ else this.lifespan += hook; ++ } ++ if (item.isEmpty()) { + this.setDead(); + } + } +@@ -208,6 +214,8 @@ + + if (itemstack1.getCount() + itemstack.getCount() > itemstack1.getMaxStackSize()) { + return false; ++ } else if (!itemstack.areCapsCompatible(itemstack1)) { ++ return false; + } + + itemstack1.grow(itemstack.getCount()); +@@ -254,6 +262,7 @@ + /** Called when the entity is attacked. */ + @Override + public boolean attackEntityFrom(DamageSource source, float amount) { ++ if (this.world.isRemote || this.isDead) return false; //Forge: Fixes MC-53850 + if (this.isEntityInvulnerable(source)) { + return false; + } +@@ -281,6 +290,8 @@ + compound.setShort("Health", (short)this.health); + compound.setShort("Age", (short)this.age); + compound.setShort("PickupDelay", (short)this.pickupDelay); ++ compound.setInteger("Lifespan", lifespan); ++ + if (this.getThrower() != null) { + compound.setString("Thrower", this.thrower); + } +@@ -316,20 +327,28 @@ + if (this.getItem().isEmpty()) { + this.setDead(); + } ++ if (compound.hasKey("Lifespan")) lifespan = compound.getInteger("Lifespan"); + } + + /** Called by a player entity when they collide with an entity */ + @Override + public void onCollideWithPlayer(EntityPlayer entityIn) { + if (!this.world.isRemote) { ++ if (this.pickupDelay > 0) return; + ItemStack itemstack = this.getItem(); + Item item = itemstack.getItem(); + int i = itemstack.getCount(); +- if (this.pickupDelay == 0 +- && (this.owner == null || 6000 - this.age <= 200 || this.owner.equals(entityIn.getName())) +- && entityIn.inventory.addItemStackToInventory(itemstack)) { +- entityIn.onItemPickup(this, i); ++ ++ int hook = net.minecraftforge.event.ForgeEventFactory.onItemPickup(this, entityIn); ++ if (hook < 0) return; ++ ItemStack clone = itemstack.copy(); ++ ++ if (this.pickupDelay <= 0 && (this.owner == null || lifespan - this.age <= 200 || this.owner.equals(entityIn.getName())) && (hook == 1 || i <= 0 || entityIn.inventory.addItemStackToInventory(itemstack) || clone.getCount() > this.getItem().getCount())) { ++ clone.setCount(clone.getCount() - this.getItem().getCount()); ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().firePlayerItemPickupEvent(entityIn, this, clone); ++ + if (itemstack.isEmpty()) { ++ entityIn.onItemPickup(this, i); + this.setDead(); + itemstack.setCount(i); + } +@@ -367,8 +386,9 @@ + + @Nullable + @Override +- public Entity changeDimension(int dimensionIn) { +- Entity entity = super.changeDimension(dimensionIn); ++ public Entity changeDimension(int dimensionIn, net.minecraftforge.common.util.ITeleporter teleporter) { ++ Entity entity = super.changeDimension(dimensionIn, teleporter); ++ + if (!this.world.isRemote && entity instanceof EntityItem) { + ((EntityItem)entity).searchForOtherItemsNearby(); + } +@@ -434,6 +454,6 @@ + + public void makeFakeItem() { + this.setInfinitePickupDelay(); +- this.age = 5999; ++ this.age = getItem().getItem().getEntityLifespan(getItem(), world) - 1; + } + } diff --git a/module/minecraft/patches/net/minecraft/entity/item/EntityItemFrame.java.patch b/module/minecraft/patches/net/minecraft/entity/item/EntityItemFrame.java.patch new file mode 100644 index 000000000..9446627ae --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/item/EntityItemFrame.java.patch @@ -0,0 +1,17 @@ +--- original/net/minecraft/entity/item/EntityItemFrame.java ++++ modified/net/minecraft/entity/item/EntityItemFrame.java +@@ -128,12 +128,13 @@ + /** Removes the dot representing this frame's position from the map when the item frame is broken. */ + private void removeFrameFromMap(ItemStack stack) { + if (!stack.isEmpty()) { +- if (stack.getItem() == Items.FILLED_MAP) { ++ if (stack.getItem() instanceof net.minecraft.item.ItemMap) { + MapData mapdata = ((ItemMap)stack.getItem()).getMapData(stack, this.world); + mapdata.mapDecorations.remove("frame-" + this.getEntityId()); + } + + stack.setItemFrame(null); ++ this.setDisplayedItem(ItemStack.EMPTY); //Forge: Fix MC-124833 Pistons duplicating Items. + } + } + diff --git a/module/minecraft/patches/net/minecraft/entity/item/EntityMinecart.java.patch b/module/minecraft/patches/net/minecraft/entity/item/EntityMinecart.java.patch new file mode 100644 index 000000000..16624a8ef --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/item/EntityMinecart.java.patch @@ -0,0 +1,460 @@ +--- original/net/minecraft/entity/item/EntityMinecart.java ++++ modified/net/minecraft/entity/item/EntityMinecart.java +@@ -71,6 +71,20 @@ + @SideOnly(Side.CLIENT) + private double velocityZ; + ++ /* Forge: Minecart Compatibility Layer Integration. */ ++ public static float defaultMaxSpeedAirLateral = 0.4f; ++ public static float defaultMaxSpeedAirVertical = -1f; ++ public static double defaultDragAir = 0.95; ++ protected boolean canUseRail = true; ++ protected boolean canBePushed = true; ++ private static net.minecraftforge.common.IMinecartCollisionHandler collisionHandler = null; ++ ++ /* Instance versions of the above physics properties */ ++ private float currentSpeedRail = getMaxCartSpeedOnRail(); ++ protected float maxSpeedAirLateral = defaultMaxSpeedAirLateral; ++ protected float maxSpeedAirVertical = defaultMaxSpeedAirVertical; ++ protected double dragAir = defaultDragAir; ++ + public EntityMinecart(World worldIn) { + super(worldIn); + this.preventEntitySpawning = true; +@@ -116,6 +130,7 @@ + @Nullable + @Override + public AxisAlignedBB getCollisionBox(Entity entityIn) { ++ if (getCollisionHandler() != null) return getCollisionHandler().getCollisionBox(this, entityIn); + return entityIn.canBePushed() ? entityIn.getEntityBoundingBox() : null; + } + +@@ -129,13 +144,14 @@ + @Nullable + @Override + public AxisAlignedBB getCollisionBoundingBox() { ++ if (getCollisionHandler() != null) return getCollisionHandler().getBoundingBox(this); + return null; + } + + /** Returns true if this entity should push and be pushed by other entities when colliding. */ + @Override + public boolean canBePushed() { +- return true; ++ return canBePushed; + } + + public EntityMinecart(World worldIn, double x, double y, double z) { +@@ -301,7 +317,8 @@ + + BlockPos blockpos = new BlockPos(k, l, i1); + IBlockState iblockstate = this.world.getBlockState(blockpos); +- if (BlockRailBase.isRailBlock(iblockstate)) { ++ ++ if (canUseRail() && BlockRailBase.isRailBlock(iblockstate)) { + this.moveAlongTrack(blockpos, iblockstate); + if (iblockstate.getBlock() == Blocks.ACTIVATOR_RAIL) { + this.onActivatorRailPass(k, l, i1, iblockstate.getValue(BlockRailPowered.POWERED)); +@@ -328,10 +345,15 @@ + } + + this.setRotation(this.rotationYaw, this.rotationPitch); +- if (this.getType() == EntityMinecart.Type.RIDEABLE +- && this.motionX * this.motionX + this.motionZ * this.motionZ > 0.01) { ++ ++ AxisAlignedBB box; ++ if (getCollisionHandler() != null) box = getCollisionHandler().getMinecartCollisionBox(this); ++ else box = this.getEntityBoundingBox().grow(0.2F, 0.0, 0.2F); ++ ++ if (canBeRidden() && this.motionX * this.motionX + this.motionZ * this.motionZ > 0.01) { + List list = this.world +- .getEntitiesInAABBexcluding(this, this.getEntityBoundingBox().grow(0.2F, 0.0, 0.2F), EntitySelectors.getTeamCollisionPredicate(this)); ++ .getEntitiesInAABBexcluding(this, box, EntitySelectors.getTeamCollisionPredicate(this)); ++ + if (!list.isEmpty()) { + for (int j1 = 0; j1 < list.size(); j1++) { + Entity entity1 = list.get(j1); +@@ -347,7 +369,7 @@ + } + } + } else { +- for (Entity entity : this.world.getEntitiesWithinAABBExcludingEntity(this, this.getEntityBoundingBox().grow(0.2F, 0.0, 0.2F))) { ++ for (Entity entity : this.world.getEntitiesWithinAABBExcludingEntity(this, box)) { + if (!this.isPassenger(entity) && entity.canBePushed() && entity instanceof EntityMinecart) { + entity.applyEntityCollision(this); + } +@@ -355,6 +377,7 @@ + } + + this.handleWaterMovement(); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.minecart.MinecartUpdateEvent(this, this.getCurrentRailPosition())); + } + } + +@@ -369,20 +392,31 @@ + + /** Moves a minecart that is not attached to a rail */ + protected void moveDerailedMinecart() { +- double d0 = this.getMaximumSpeed(); ++ double d0 = onGround ? this.getMaximumSpeed() : getMaxSpeedAirLateral(); + this.motionX = MathHelper.clamp(this.motionX, -d0, d0); + this.motionZ = MathHelper.clamp(this.motionZ, -d0, d0); ++ ++ double moveY = motionY; ++ if(getMaxSpeedAirVertical() > 0 && motionY > getMaxSpeedAirVertical()) { ++ moveY = getMaxSpeedAirVertical(); ++ if(Math.abs(motionX) < 0.3f && Math.abs(motionZ) < 0.3f) { ++ moveY = 0.15f; ++ motionY = moveY; ++ } ++ } ++ + if (this.onGround) { + this.motionX *= 0.5; + this.motionY *= 0.5; + this.motionZ *= 0.5; + } + +- this.move(MoverType.SELF, this.motionX, this.motionY, this.motionZ); ++ this.move(MoverType.SELF, this.motionX, moveY, this.motionZ); ++ + if (!this.onGround) { +- this.motionX *= 0.95F; +- this.motionY *= 0.95F; +- this.motionZ *= 0.95F; ++ this.motionX *= getDragAir(); ++ this.motionY *= getDragAir(); ++ this.motionZ *= getDragAir(); + } + } + +@@ -398,23 +432,24 @@ + flag1 = !flag; + } + +- double d0 = 0.0078125; +- BlockRailBase.EnumRailDirection blockrailbase$enumraildirection = state.getValue(blockrailbase.getShapeProperty()); ++ double slopeAdjustment = getSlopeAdjustment(); ++ BlockRailBase.EnumRailDirection blockrailbase$enumraildirection = blockrailbase.getRailDirection(world, pos, state, this); ++ + switch (blockrailbase$enumraildirection) { + case ASCENDING_EAST: +- this.motionX -= 0.0078125; ++ this.motionX -= slopeAdjustment; + this.posY++; + break; + case ASCENDING_WEST: +- this.motionX += 0.0078125; ++ this.motionX += slopeAdjustment; + this.posY++; + break; + case ASCENDING_NORTH: +- this.motionZ += 0.0078125; ++ this.motionZ += slopeAdjustment; + this.posY++; + break; + case ASCENDING_SOUTH: +- this.motionZ -= 0.0078125; ++ this.motionZ -= slopeAdjustment; + this.posY++; + } + +@@ -450,7 +485,7 @@ + } + } + +- if (flag1) { ++ if (flag1 && shouldDoRailFunctions()) { + double d17 = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ); + if (d17 < 0.03) { + this.motionX *= 0.0; +@@ -485,17 +520,8 @@ + this.posX = d18 + d1 * d10; + this.posZ = d19 + d2 * d10; + this.setPosition(this.posX, this.posY, this.posZ); +- double d22 = this.motionX; +- double d23 = this.motionZ; +- if (this.isBeingRidden()) { +- d22 *= 0.75; +- d23 *= 0.75; +- } ++ this.moveMinecartOnRail(pos); + +- double d13 = this.getMaximumSpeed(); +- d22 = MathHelper.clamp(d22, -d13, d13); +- d23 = MathHelper.clamp(d23, -d13, d13); +- this.move(MoverType.SELF, d22, 0.0, d23); + if (aint[0][1] != 0 + && MathHelper.floor(this.posX) - pos.getX() == aint[0][0] + && MathHelper.floor(this.posZ) - pos.getZ() == aint[0][2]) { +@@ -527,7 +553,12 @@ + this.motionZ = d5 * (i - pos.getZ()); + } + +- if (flag) { ++ ++ if(shouldDoRailFunctions()) { ++ ((BlockRailBase)state.getBlock()).onMinecartPass(world, this, pos); ++ } ++ ++ if (flag && shouldDoRailFunctions()) { + double d15 = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ); + if (d15 > 0.01) { + double d16 = 0.06; +@@ -584,9 +615,7 @@ + + IBlockState iblockstate = this.world.getBlockState(new BlockPos(i, j, k)); + if (BlockRailBase.isRailBlock(iblockstate)) { +- BlockRailBase.EnumRailDirection blockrailbase$enumraildirection = iblockstate.getValue( +- ((BlockRailBase)iblockstate.getBlock()).getShapeProperty() +- ); ++ BlockRailBase.EnumRailDirection blockrailbase$enumraildirection = ((BlockRailBase)iblockstate.getBlock()).getRailDirection(world, new BlockPos(i, j, k), iblockstate, this); + y = j; + if (blockrailbase$enumraildirection.isAscending()) { + y = j + 1; +@@ -623,9 +652,7 @@ + + IBlockState iblockstate = this.world.getBlockState(new BlockPos(i, j, k)); + if (BlockRailBase.isRailBlock(iblockstate)) { +- BlockRailBase.EnumRailDirection blockrailbase$enumraildirection = iblockstate.getValue( +- ((BlockRailBase)iblockstate.getBlock()).getShapeProperty() +- ); ++ BlockRailBase.EnumRailDirection blockrailbase$enumraildirection = ((BlockRailBase)iblockstate.getBlock()).getRailDirection(world, new BlockPos(i, j, k), iblockstate, this); + int[][] aint = MATRIX[blockrailbase$enumraildirection.getMetadata()]; + double d0 = i + 0.5 + aint[0][0] * 0.5; + double d1 = j + 0.0625 + aint[0][1] * 0.5; +@@ -708,6 +735,11 @@ + /** Applies a velocity to the entities, to push them away from eachother. */ + @Override + public void applyEntityCollision(Entity entityIn) { ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.minecart.MinecartCollisionEvent(this, entityIn)); ++ if (getCollisionHandler() != null) { ++ getCollisionHandler().onEntityCollision(this, entityIn); ++ return; ++ } + if (!this.world.isRemote) { + if (!entityIn.noClip && !this.noClip) { + if (!this.isPassenger(entityIn)) { +@@ -748,15 +780,14 @@ + + double d7 = entityIn.motionX + this.motionX; + double d8 = entityIn.motionZ + this.motionZ; +- if (((EntityMinecart)entityIn).getType() == EntityMinecart.Type.FURNACE +- && this.getType() != EntityMinecart.Type.FURNACE) { ++ ++ if (((EntityMinecart)entityIn).isPoweredCart() && !isPoweredCart()) { + this.motionX *= 0.2F; + this.motionZ *= 0.2F; + this.addVelocity(entityIn.motionX - d0, 0.0, entityIn.motionZ - d1); + entityIn.motionX *= 0.95F; + entityIn.motionZ *= 0.95F; +- } else if (((EntityMinecart)entityIn).getType() != EntityMinecart.Type.FURNACE +- && this.getType() == EntityMinecart.Type.FURNACE) { ++ } else if (!((EntityMinecart)entityIn).isPoweredCart() && isPoweredCart()) { + entityIn.motionX *= 0.2F; + entityIn.motionZ *= 0.2F; + entityIn.addVelocity(this.motionX + d0, 0.0, this.motionZ + d1); +@@ -877,6 +908,203 @@ + this.getDataManager().set(SHOW_BLOCK, showBlock); + } + ++ @Override ++ public boolean processInitialInteract(EntityPlayer player, net.minecraft.util.EnumHand hand) { ++ return net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.minecart.MinecartInteractEvent(this, player, hand)); ++ } ++ ++ /* =================================== FORGE START ===========================================*/ ++ private BlockPos getCurrentRailPosition() { ++ int x = MathHelper.floor(this.posX); ++ int y = MathHelper.floor(this.posY); ++ int z = MathHelper.floor(this.posZ); ++ ++ if (BlockRailBase.isRailBlock(this.world, new BlockPos(x, y - 1, z))) y--; ++ return new BlockPos(x, y, z); ++ } ++ ++ protected double getMaxSpeed() { ++ if (!canUseRail()) return getMaximumSpeed(); ++ BlockPos pos = this.getCurrentRailPosition(); ++ IBlockState state = this.world.getBlockState(pos); ++ if (!BlockRailBase.isRailBlock(state)) return getMaximumSpeed(); ++ ++ float railMaxSpeed = ((BlockRailBase)state.getBlock()).getRailMaxSpeed(world, this, pos); ++ return Math.min(railMaxSpeed, getCurrentCartSpeedCapOnRail()); ++ } ++ ++ /** ++ * Moved to allow overrides. ++ * This code handles minecart movement and speed capping when on a rail. ++ */ ++ public void moveMinecartOnRail(BlockPos pos) { ++ double mX = this.motionX; ++ double mZ = this.motionZ; ++ ++ if (this.isBeingRidden()) { ++ mX *= 0.75D; ++ mZ *= 0.75D; ++ } ++ ++ double max = this.getMaxSpeed(); ++ mX = MathHelper.clamp(mX, -max, max); ++ mZ = MathHelper.clamp(mZ, -max, max); ++ this.move(MoverType.SELF, mX, 0.0D, mZ); ++ } ++ ++ /** ++ * Gets the current global Minecart Collision handler if none ++ * is registered, returns null ++ * @return The collision handler or null ++ */ ++ @Nullable ++ public static net.minecraftforge.common.IMinecartCollisionHandler getCollisionHandler() { ++ return collisionHandler; ++ } ++ ++ /** ++ * Sets the global Minecart Collision handler, overwrites any ++ * that is currently set. ++ * @param handler The new handler ++ */ ++ public static void setCollisionHandler(net.minecraftforge.common.IMinecartCollisionHandler handler) { ++ collisionHandler = handler; ++ } ++ ++ /** ++ * This function returns an ItemStack that represents this cart. ++ * This should be an ItemStack that can be used by the player to place the cart, ++ * but is not necessary the item the cart drops when destroyed. ++ * @return An ItemStack that can be used to place the cart. ++ */ ++ public ItemStack getCartItem() { ++ if (this instanceof EntityMinecartFurnace) { ++ return new ItemStack(Items.FURNACE_MINECART); ++ } else if (this instanceof EntityMinecartChest) { ++ return new ItemStack(Items.CHEST_MINECART); ++ } else if (this instanceof EntityMinecartTNT) { ++ return new ItemStack(Items.TNT_MINECART); ++ } else if (this instanceof EntityMinecartHopper) { ++ return new ItemStack(Items.HOPPER_MINECART); ++ } else if (this instanceof EntityMinecartCommandBlock) { ++ return new ItemStack(Items.COMMAND_BLOCK_MINECART); ++ } ++ return new ItemStack(Items.MINECART); ++ } ++ ++ /** ++ * Returns true if this cart can currently use rails. ++ * This function is mainly used to gracefully detach a minecart from a rail. ++ * @return True if the minecart can use rails. ++ */ ++ public boolean canUseRail() { ++ return canUseRail; ++ } ++ ++ /** ++ * Set whether the minecart can use rails. ++ * This function is mainly used to gracefully detach a minecart from a rail. ++ * @param use Whether the minecart can currently use rails. ++ */ ++ public void setCanUseRail(boolean use) { ++ canUseRail = use; ++ } ++ ++ /** ++ * Return false if this cart should not call onMinecartPass() and should ignore Powered Rails. ++ * @return True if this cart should call onMinecartPass(). ++ */ ++ public boolean shouldDoRailFunctions() { ++ return true; ++ } ++ ++ /** ++ * Returns true if this cart is self propelled. ++ * @return True if powered. ++ */ ++ public boolean isPoweredCart() { ++ return getType() == EntityMinecart.Type.FURNACE; ++ } ++ ++ /** ++ * Returns true if this cart can be ridden by an Entity. ++ * @return True if this cart can be ridden. ++ */ ++ public boolean canBeRidden() { ++ return this.getType() == EntityMinecart.Type.RIDEABLE; ++ } ++ ++ /** ++ * Getters/setters for physics variables ++ */ ++ ++ /** ++ * Returns the carts max speed when traveling on rails. Carts going faster ++ * than 1.1 cause issues with chunk loading. Carts cant traverse slopes or ++ * corners at greater than 0.5 - 0.6. This value is compared with the rails ++ * max speed and the carts current speed cap to determine the carts current ++ * max speed. A normal rail's max speed is 0.4. ++ * ++ * @return Carts max speed. ++ */ ++ public float getMaxCartSpeedOnRail() { ++ return 1.2f; ++ } ++ ++ /** ++ * Returns the current speed cap for the cart when traveling on rails. This ++ * functions differs from getMaxCartSpeedOnRail() in that it controls ++ * current movement and cannot be overridden. The value however can never be ++ * higher than getMaxCartSpeedOnRail(). ++ * ++ * @return ++ */ ++ public final float getCurrentCartSpeedCapOnRail() { ++ return currentSpeedRail; ++ } ++ ++ public final void setCurrentCartSpeedCapOnRail(float value) { ++ value = Math.min(value, getMaxCartSpeedOnRail()); ++ currentSpeedRail = value; ++ } ++ ++ public float getMaxSpeedAirLateral() { ++ return maxSpeedAirLateral; ++ } ++ ++ public void setMaxSpeedAirLateral(float value) { ++ maxSpeedAirLateral = value; ++ } ++ ++ public float getMaxSpeedAirVertical() { ++ return maxSpeedAirVertical; ++ } ++ ++ public void setMaxSpeedAirVertical(float value) { ++ maxSpeedAirVertical = value; ++ } ++ ++ public double getDragAir() { ++ return dragAir; ++ } ++ ++ public void setDragAir(double value) { ++ dragAir = value; ++ } ++ ++ public double getSlopeAdjustment() { ++ return 0.0078125D; ++ } ++ ++ /** ++ * Called from Detector Rails to retrieve a redstone power level for comparators. ++ */ ++ public int getComparatorLevel() { ++ return -1; ++ } ++ ++ /* =================================== FORGE END ===========================================*/ ++ + public enum Type { + RIDEABLE(0, "MinecartRideable"), + CHEST(1, "MinecartChest"), diff --git a/module/minecraft/patches/net/minecraft/entity/item/EntityMinecartCommandBlock.java.patch b/module/minecraft/patches/net/minecraft/entity/item/EntityMinecartCommandBlock.java.patch new file mode 100644 index 000000000..49c26e4ae --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/item/EntityMinecartCommandBlock.java.patch @@ -0,0 +1,10 @@ +--- original/net/minecraft/entity/item/EntityMinecartCommandBlock.java ++++ modified/net/minecraft/entity/item/EntityMinecartCommandBlock.java +@@ -166,6 +166,7 @@ + + @Override + public boolean processInitialInteract(EntityPlayer player, EnumHand hand) { ++ if (super.processInitialInteract(player, hand)) return true; + this.commandBlockLogic.tryOpenEditCommandBlock(player); + return false; + } diff --git a/module/minecraft/patches/net/minecraft/entity/item/EntityMinecartContainer.java.patch b/module/minecraft/patches/net/minecraft/entity/item/EntityMinecartContainer.java.patch new file mode 100644 index 000000000..116018161 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/item/EntityMinecartContainer.java.patch @@ -0,0 +1,59 @@ +--- original/net/minecraft/entity/item/EntityMinecartContainer.java ++++ modified/net/minecraft/entity/item/EntityMinecartContainer.java +@@ -128,9 +128,9 @@ + + @Nullable + @Override +- public Entity changeDimension(int dimensionIn) { ++ public Entity changeDimension(int dimensionIn, net.minecraftforge.common.util.ITeleporter teleporter) { + this.dropContentsWhenDead = false; +- return super.changeDimension(dimensionIn); ++ return super.changeDimension(dimensionIn, teleporter); + } + + /** Will get destroyed next tick. */ +@@ -183,6 +183,7 @@ + + @Override + public boolean processInitialInteract(EntityPlayer player, EnumHand hand) { ++ if (super.processInitialInteract(player, hand)) return true; + if (!this.world.isRemote) { + player.displayGUIChest(this); + } +@@ -243,16 +244,34 @@ + random = new Random(this.lootTableSeed); + } + +- LootContext.Builder lootcontext$builder = new LootContext.Builder((WorldServer)this.world); ++ LootContext.Builder lootcontext$builder = new LootContext.Builder((WorldServer)this.world).withLootedEntity(this); // Forge: add looted entity to LootContext ++ + if (player != null) { +- lootcontext$builder.withLuck(player.getLuck()); ++ lootcontext$builder.withLuck(player.getLuck()).withPlayer(player); // Forge: add player to LootContext + } + + loottable.fillInventory(this, random, lootcontext$builder.build()); + } + } + ++ public net.minecraftforge.items.IItemHandler itemHandler = new net.minecraftforge.items.wrapper.InvWrapper(this); ++ ++ @SuppressWarnings("unchecked") + @Override ++ @Nullable ++ public T getCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable net.minecraft.util.EnumFacing facing) { ++ if (capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { ++ return (T) itemHandler; ++ } ++ return super.getCapability(capability, facing); ++ } ++ ++ @Override ++ public boolean hasCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable net.minecraft.util.EnumFacing facing) { ++ return capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY || super.hasCapability(capability, facing); ++ } ++ ++ @Override + public void clear() { + this.addLoot(null); + this.minecartContainerItems.clear(); diff --git a/module/minecraft/patches/net/minecraft/entity/item/EntityMinecartEmpty.java.patch b/module/minecraft/patches/net/minecraft/entity/item/EntityMinecartEmpty.java.patch new file mode 100644 index 000000000..48a2ae61d --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/item/EntityMinecartEmpty.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/entity/item/EntityMinecartEmpty.java ++++ modified/net/minecraft/entity/item/EntityMinecartEmpty.java +@@ -20,6 +20,8 @@ + + @Override + public boolean processInitialInteract(EntityPlayer player, EnumHand hand) { ++ if (super.processInitialInteract(player, hand)) return true; ++ + if (player.isSneaking()) { + return false; + } diff --git a/module/minecraft/patches/net/minecraft/entity/item/EntityMinecartFurnace.java.patch b/module/minecraft/patches/net/minecraft/entity/item/EntityMinecartFurnace.java.patch new file mode 100644 index 000000000..716565b7f --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/item/EntityMinecartFurnace.java.patch @@ -0,0 +1,12 @@ +--- original/net/minecraft/entity/item/EntityMinecartFurnace.java ++++ modified/net/minecraft/entity/item/EntityMinecartFurnace.java +@@ -125,6 +125,9 @@ + @Override + public boolean processInitialInteract(EntityPlayer player, EnumHand hand) { + ItemStack itemstack = player.getHeldItem(hand); ++ ++ if (super.processInitialInteract(player, hand)) return true; ++ + if (itemstack.getItem() == Items.COAL && this.fuel + 3600 <= 32000) { + if (!player.capabilities.isCreativeMode) { + itemstack.shrink(1); diff --git a/module/minecraft/patches/net/minecraft/entity/item/EntityMinecartHopper.java.patch b/module/minecraft/patches/net/minecraft/entity/item/EntityMinecartHopper.java.patch new file mode 100644 index 000000000..71ee815bb --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/item/EntityMinecartHopper.java.patch @@ -0,0 +1,10 @@ +--- original/net/minecraft/entity/item/EntityMinecartHopper.java ++++ modified/net/minecraft/entity/item/EntityMinecartHopper.java +@@ -55,6 +55,7 @@ + + @Override + public boolean processInitialInteract(EntityPlayer player, EnumHand hand) { ++ if (super.processInitialInteract(player, hand)) return true; + if (!this.world.isRemote) { + player.displayGUIChest(this); + } diff --git a/module/minecraft/patches/net/minecraft/entity/item/EntityMinecartMobSpawner.java.patch b/module/minecraft/patches/net/minecraft/entity/item/EntityMinecartMobSpawner.java.patch new file mode 100644 index 000000000..37c679506 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/item/EntityMinecartMobSpawner.java.patch @@ -0,0 +1,13 @@ +--- original/net/minecraft/entity/item/EntityMinecartMobSpawner.java ++++ modified/net/minecraft/entity/item/EntityMinecartMobSpawner.java +@@ -34,6 +34,10 @@ + public BlockPos getSpawnerPosition() { + return new BlockPos(EntityMinecartMobSpawner.this); + } ++ @Override ++ public net.minecraft.entity.Entity getSpawnerEntity() { ++ return EntityMinecartMobSpawner.this; ++ } + }; + + public EntityMinecartMobSpawner(World worldIn) { diff --git a/module/minecraft/patches/net/minecraft/entity/item/EntityXPOrb.java.patch b/module/minecraft/patches/net/minecraft/entity/item/EntityXPOrb.java.patch new file mode 100644 index 000000000..ca3cb2e8c --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/item/EntityXPOrb.java.patch @@ -0,0 +1,56 @@ +--- original/net/minecraft/entity/item/EntityXPOrb.java ++++ modified/net/minecraft/entity/item/EntityXPOrb.java +@@ -126,17 +126,9 @@ + this.move(MoverType.SELF, this.motionX, this.motionY, this.motionZ); + float f = 0.98F; + if (this.onGround) { +- f = this.world +- .getBlockState( +- new BlockPos( +- MathHelper.floor(this.posX), +- MathHelper.floor(this.getEntityBoundingBox().minY) - 1, +- MathHelper.floor(this.posZ) +- ) +- ) +- .getBlock() +- .slipperiness +- * 0.98F; ++ BlockPos underPos = new BlockPos(MathHelper.floor(this.posX), MathHelper.floor(this.getEntityBoundingBox().minY) - 1, MathHelper.floor(this.posZ)); ++ net.minecraft.block.state.IBlockState underState = this.world.getBlockState(underPos); ++ f = underState.getBlock().getSlipperiness(underState, this.world, underPos, this) * 0.98F; + } + + this.motionX *= f; +@@ -168,6 +160,7 @@ + /** Called when the entity is attacked. */ + @Override + public boolean attackEntityFrom(DamageSource source, float amount) { ++ if (this.world.isRemote || this.isDead) return false; //Forge: Fixes MC-53850 + if (this.isEntityInvulnerable(source)) { + return false; + } +@@ -202,11 +195,13 @@ + public void onCollideWithPlayer(EntityPlayer entityIn) { + if (!this.world.isRemote) { + if (this.delayBeforeCanPickup == 0 && entityIn.xpCooldown == 0) { ++ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.player.PlayerPickupXpEvent(entityIn, this))) return; + entityIn.xpCooldown = 2; + entityIn.onItemPickup(this, 1); + ItemStack itemstack = EnchantmentHelper.getEnchantedItem(Enchantments.MENDING, entityIn); + if (!itemstack.isEmpty() && itemstack.isItemDamaged()) { +- int i = Math.min(this.xpToDurability(this.xpValue), itemstack.getItemDamage()); ++ float ratio = itemstack.getItem().getXpRepairRatio(itemstack); ++ int i = Math.min(roundAverage(this.xpValue * ratio), itemstack.getItemDamage()); + this.xpValue = this.xpValue - this.durabilityToXp(i); + itemstack.setItemDamage(itemstack.getItemDamage() - i); + } +@@ -289,4 +284,9 @@ + public boolean canBeAttackedWithItem() { + return false; + } ++ ++ private static int roundAverage(float value) { ++ double floor = Math.floor(value); ++ return (int) floor + (Math.random() < value - floor ? 1 : 0); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/entity/monster/AbstractSkeleton.java.patch b/module/minecraft/patches/net/minecraft/entity/monster/AbstractSkeleton.java.patch new file mode 100644 index 000000000..8a632ca41 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/monster/AbstractSkeleton.java.patch @@ -0,0 +1,21 @@ +--- original/net/minecraft/entity/monster/AbstractSkeleton.java ++++ modified/net/minecraft/entity/monster/AbstractSkeleton.java +@@ -193,7 +193,8 @@ + this.tasks.removeTask(this.aiAttackOnCollide); + this.tasks.removeTask(this.aiArrowAttack); + ItemStack itemstack = this.getHeldItemMainhand(); +- if (itemstack.getItem() == Items.BOW) { ++ ++ if (itemstack.getItem() instanceof net.minecraft.item.ItemBow) { + int i = 20; + if (this.world.getDifficulty() != EnumDifficulty.HARD) { + i = 40; +@@ -211,6 +212,8 @@ + @Override + public void attackEntityWithRangedAttack(EntityLivingBase target, float distanceFactor) { + EntityArrow entityarrow = this.getArrow(distanceFactor); ++ if (this.getHeldItemMainhand().getItem() instanceof net.minecraft.item.ItemBow) ++ entityarrow = ((net.minecraft.item.ItemBow) this.getHeldItemMainhand().getItem()).customizeArrow(entityarrow); + double d0 = target.posX - this.posX; + double d1 = target.getEntityBoundingBox().minY + target.height / 3.0F - entityarrow.posY; + double d2 = target.posZ - this.posZ; diff --git a/module/minecraft/patches/net/minecraft/entity/monster/EntityCreeper.java.patch b/module/minecraft/patches/net/minecraft/entity/monster/EntityCreeper.java.patch new file mode 100644 index 000000000..51e48f6ce --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/monster/EntityCreeper.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/entity/monster/EntityCreeper.java ++++ modified/net/minecraft/entity/monster/EntityCreeper.java +@@ -258,7 +258,7 @@ + /** Creates an explosion as determined by this creeper's power and explosion radius. */ + private void explode() { + if (!this.world.isRemote) { +- boolean flag = this.world.getGameRules().getBoolean("mobGriefing"); ++ boolean flag = net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.world, this); + float f = this.getPowered() ? 2.0F : 1.0F; + this.dead = true; + this.world.createExplosion(this, this.posX, this.posY, this.posZ, this.explosionRadius * f, flag); diff --git a/module/minecraft/patches/net/minecraft/entity/monster/EntityEnderman.java.patch b/module/minecraft/patches/net/minecraft/entity/monster/EntityEnderman.java.patch new file mode 100644 index 000000000..870567796 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/monster/EntityEnderman.java.patch @@ -0,0 +1,67 @@ +--- original/net/minecraft/entity/monster/EntityEnderman.java ++++ modified/net/minecraft/entity/monster/EntityEnderman.java +@@ -267,7 +267,10 @@ + + /** Teleport the enderman */ + private boolean teleportTo(double x, double y, double z) { +- boolean flag = this.attemptTeleport(x, y, z); ++ net.minecraftforge.event.entity.living.EnderTeleportEvent event = new net.minecraftforge.event.entity.living.EnderTeleportEvent(this, x, y, z, 0); ++ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event)) return false; ++ boolean flag = this.attemptTeleport(event.getTargetX(), event.getTargetY(), event.getTargetZ()); ++ + if (flag) { + this.world + .playSound(null, this.prevPosX, this.prevPosY, this.prevPosZ, SoundEvents.ENTITY_ENDERMEN_TELEPORT, this.getSoundCategory(), 1.0F, 1.0F); +@@ -346,6 +349,16 @@ + } + } + ++ /*===================================== Forge Start ==============================*/ ++ public static void setCarriable(Block block, boolean canCarry) { ++ if (canCarry) CARRIABLE_BLOCKS.add(block); ++ else CARRIABLE_BLOCKS.remove(block); ++ } ++ public static boolean getCarriable(Block block) { ++ return CARRIABLE_BLOCKS.contains(block); ++ } ++ /*===================================== Forge End ==============================*/ ++ + public boolean isScreaming() { + return this.dataManager.get(SCREAMING); + } +@@ -473,7 +486,7 @@ + if (this.enderman.getHeldBlockState() == null) { + return false; + } else { +- return !this.enderman.world.getGameRules().getBoolean("mobGriefing") ++ return !net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.enderman.world, this.enderman) + ? false + : this.enderman.getRNG().nextInt(2000) == 0; + } +@@ -491,7 +504,16 @@ + IBlockState iblockstate = world.getBlockState(blockpos); + IBlockState iblockstate1 = world.getBlockState(blockpos.down()); + IBlockState iblockstate2 = this.enderman.getHeldBlockState(); +- if (iblockstate2 != null && this.canPlaceBlock(world, blockpos, iblockstate2.getBlock(), iblockstate, iblockstate1)) { ++ if (iblockstate2 != null && this.canPlaceBlock(world, blockpos, iblockstate2.getBlock(), iblockstate, iblockstate1) ++ && net.minecraftforge.event.ForgeEventFactory.onBlockPlace( ++ enderman, ++ new net.minecraftforge.common.util.BlockSnapshot( ++ world, ++ blockpos, ++ iblockstate2 ++ ), ++ net.minecraft.util.EnumFacing.UP ++ ).isCanceled()) { + world.setBlockState(blockpos, iblockstate2, 3); + this.enderman.setHeldBlockState(null); + } +@@ -521,7 +543,7 @@ + if (this.enderman.getHeldBlockState() != null) { + return false; + } else { +- return !this.enderman.world.getGameRules().getBoolean("mobGriefing") ++ return !net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.enderman.world, this.enderman) + ? false + : this.enderman.getRNG().nextInt(20) == 0; + } diff --git a/module/minecraft/patches/net/minecraft/entity/monster/EntityEvoker.java.patch b/module/minecraft/patches/net/minecraft/entity/monster/EntityEvoker.java.patch new file mode 100644 index 000000000..362e5b557 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/monster/EntityEvoker.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/entity/monster/EntityEvoker.java ++++ modified/net/minecraft/entity/monster/EntityEvoker.java +@@ -345,7 +345,7 @@ + return false; + } + +- if (!EntityEvoker.this.world.getGameRules().getBoolean("mobGriefing")) { ++ if (!net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(EntityEvoker.this.world, EntityEvoker.this)) { + return false; + } + diff --git a/module/minecraft/patches/net/minecraft/entity/monster/EntityIllusionIllager.java.patch b/module/minecraft/patches/net/minecraft/entity/monster/EntityIllusionIllager.java.patch new file mode 100644 index 000000000..8e5b10a13 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/monster/EntityIllusionIllager.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/entity/monster/EntityIllusionIllager.java ++++ modified/net/minecraft/entity/monster/EntityIllusionIllager.java +@@ -218,6 +218,8 @@ + @Override + public void attackEntityWithRangedAttack(EntityLivingBase target, float distanceFactor) { + EntityArrow entityarrow = this.createArrowEntity(distanceFactor); ++ if (this.getHeldItemMainhand().getItem() instanceof net.minecraft.item.ItemBow) ++ entityarrow = ((net.minecraft.item.ItemBow) this.getHeldItemMainhand().getItem()).customizeArrow(entityarrow); + double d0 = target.posX - this.posX; + double d1 = target.getEntityBoundingBox().minY + target.height / 3.0F - entityarrow.posY; + double d2 = target.posZ - this.posZ; diff --git a/module/minecraft/patches/net/minecraft/entity/monster/EntityIronGolem.java.patch b/module/minecraft/patches/net/minecraft/entity/monster/EntityIronGolem.java.patch new file mode 100644 index 000000000..d19cf3d3c --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/monster/EntityIronGolem.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/entity/monster/EntityIronGolem.java ++++ modified/net/minecraft/entity/monster/EntityIronGolem.java +@@ -269,7 +269,7 @@ + @Override + public void onDeath(DamageSource cause) { + if (!this.isPlayerCreated() && this.attackingPlayer != null && this.village != null) { +- this.village.modifyPlayerReputation(this.attackingPlayer.getName(), -5); ++ this.village.modifyPlayerReputation(this.attackingPlayer.getUniqueID(), -5); + } + + super.onDeath(cause); diff --git a/module/minecraft/patches/net/minecraft/entity/monster/EntityMagmaCube.java.patch b/module/minecraft/patches/net/minecraft/entity/monster/EntityMagmaCube.java.patch new file mode 100644 index 000000000..436e32929 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/monster/EntityMagmaCube.java.patch @@ -0,0 +1,10 @@ +--- original/net/minecraft/entity/monster/EntityMagmaCube.java ++++ modified/net/minecraft/entity/monster/EntityMagmaCube.java +@@ -101,6 +101,7 @@ + protected void jump() { + this.motionY = 0.42F + this.getSlimeSize() * 0.1F; + this.isAirBorne = true; ++ net.minecraftforge.common.ForgeHooks.onLivingJump(this); + } + + @Override diff --git a/module/minecraft/patches/net/minecraft/entity/monster/EntityMob.java.patch b/module/minecraft/patches/net/minecraft/entity/monster/EntityMob.java.patch new file mode 100644 index 000000000..01d0aadab --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/monster/EntityMob.java.patch @@ -0,0 +1,19 @@ +--- original/net/minecraft/entity/monster/EntityMob.java ++++ modified/net/minecraft/entity/monster/EntityMob.java +@@ -115,12 +115,12 @@ + ItemStack itemstack = this.getHeldItemMainhand(); + ItemStack itemstack1 = entityplayer.isHandActive() ? entityplayer.getActiveItemStack() : ItemStack.EMPTY; + if (!itemstack.isEmpty() +- && !itemstack1.isEmpty() +- && itemstack.getItem() instanceof ItemAxe +- && itemstack1.getItem() == Items.SHIELD) { ++ && !itemstack1.isEmpty() ++ && itemstack.getItem().canDisableShield(itemstack, itemstack1, entityplayer, this) ++ && itemstack1.getItem().isShield(itemstack1, entityplayer)) { + float f1 = 0.25F + EnchantmentHelper.getEfficiencyModifier(this) * 0.05F; + if (this.rand.nextFloat() < f1) { +- entityplayer.getCooldownTracker().setCooldown(Items.SHIELD, 100); ++ entityplayer.getCooldownTracker().setCooldown(itemstack1.getItem(), 100); + this.world.setEntityState(entityplayer, (byte)30); + } + } diff --git a/module/minecraft/patches/net/minecraft/entity/monster/EntityShulker.java.patch b/module/minecraft/patches/net/minecraft/entity/monster/EntityShulker.java.patch new file mode 100644 index 000000000..14cc946b7 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/monster/EntityShulker.java.patch @@ -0,0 +1,23 @@ +--- original/net/minecraft/entity/monster/EntityShulker.java ++++ modified/net/minecraft/entity/monster/EntityShulker.java +@@ -435,6 +435,12 @@ + } + + if (flag) { ++ net.minecraftforge.event.entity.living.EnderTeleportEvent event = new net.minecraftforge.event.entity.living.EnderTeleportEvent(this, blockpos1.getX(), blockpos1.getY(), blockpos1.getZ(), 0); ++ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event)) flag = false; ++ blockpos1 = new BlockPos(event.getTargetX(), event.getTargetY(), event.getTargetZ()); ++ } ++ ++ if (flag) { + this.playSound(SoundEvents.ENTITY_SHULKER_TELEPORT, 1.0F, 1.0F); + this.dataManager.set(ATTACHED_BLOCK_POS, Optional.of(blockpos1)); + this.dataManager.set(PEEK_TICK, (byte)0); +@@ -476,6 +482,7 @@ + this.posX = blockpos.getX() + 0.5; + this.posY = blockpos.getY(); + this.posZ = blockpos.getZ() + 0.5; ++ if (this.isAddedToWorld() && !this.world.isRemote) this.world.updateEntityWithOptionalForce(this, false); // Forge - Process chunk registration after moving. + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; diff --git a/module/minecraft/patches/net/minecraft/entity/monster/EntitySilverfish.java.patch b/module/minecraft/patches/net/minecraft/entity/monster/EntitySilverfish.java.patch new file mode 100644 index 000000000..ddb0ac8c0 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/monster/EntitySilverfish.java.patch @@ -0,0 +1,20 @@ +--- original/net/minecraft/entity/monster/EntitySilverfish.java ++++ modified/net/minecraft/entity/monster/EntitySilverfish.java +@@ -180,7 +180,7 @@ + } + + Random random = this.entity.getRNG(); +- if (this.entity.world.getGameRules().getBoolean("mobGriefing") && random.nextInt(10) == 0) { ++ if (net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.entity.world, this.entity) && random.nextInt(10) == 0) { + this.facing = EnumFacing.random(random); + BlockPos blockpos = new BlockPos(this.entity.posX, this.entity.posY + 0.5, this.entity.posZ) + .offset(this.facing); +@@ -261,7 +261,7 @@ + BlockPos blockpos1 = blockpos.add(j, i, k); + IBlockState iblockstate = world.getBlockState(blockpos1); + if (iblockstate.getBlock() == Blocks.MONSTER_EGG) { +- if (world.getGameRules().getBoolean("mobGriefing")) { ++ if (net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(world, this.silverfish)) { + world.destroyBlock(blockpos1, true); + } else { + world.setBlockState(blockpos1, iblockstate.getValue(BlockSilverfish.VARIANT).getModelBlock(), 3); diff --git a/module/minecraft/patches/net/minecraft/entity/monster/EntitySlime.java.patch b/module/minecraft/patches/net/minecraft/entity/monster/EntitySlime.java.patch new file mode 100644 index 000000000..b06159df6 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/monster/EntitySlime.java.patch @@ -0,0 +1,44 @@ +--- original/net/minecraft/entity/monster/EntitySlime.java ++++ modified/net/minecraft/entity/monster/EntitySlime.java +@@ -127,7 +127,7 @@ + super.onUpdate(); + if (this.onGround && !this.wasOnGround) { + int i = this.getSlimeSize(); +- ++ if (spawnCustomParticles()) { i = 0; } // don't spawn particles if it's handled by the implementation itself + for (int j = 0; j < i * 8; j++) { + float f = this.rand.nextFloat() * (float) (Math.PI * 2); + float f1 = this.rand.nextFloat() * 0.5F + 0.5F; +@@ -282,7 +282,8 @@ + public boolean getCanSpawnHere() { + BlockPos blockpos = new BlockPos(MathHelper.floor(this.posX), 0, MathHelper.floor(this.posZ)); + Chunk chunk = this.world.getChunk(blockpos); +- if (this.world.getWorldInfo().getTerrainType() == WorldType.FLAT && this.rand.nextInt(4) != 1) { ++ ++ if (this.world.getWorldInfo().getTerrainType().handleSlimeSpawnReduction(rand, world)) { + return false; + } + +@@ -327,6 +328,7 @@ + protected void jump() { + this.motionY = 0.42F; + this.isAirBorne = true; ++ net.minecraftforge.common.ForgeHooks.onLivingJump(this); + } + + /** +@@ -356,6 +358,14 @@ + return this.isSmallSlime() ? SoundEvents.ENTITY_SMALL_SLIME_JUMP : SoundEvents.ENTITY_SLIME_JUMP; + } + ++ /* ======================================== FORGE START =====================================*/ ++ /** ++ * Called when the slime spawns particles on landing, see onUpdate. ++ * Return true to prevent the spawning of the default particles. ++ */ ++ protected boolean spawnCustomParticles() { return false; } ++ /* ======================================== FORGE END =====================================*/ ++ + static class AISlimeAttack extends EntityAIBase { + private final EntitySlime slime; + private int growTieredTimer; diff --git a/module/minecraft/patches/net/minecraft/entity/monster/EntitySnowman.java.patch b/module/minecraft/patches/net/minecraft/entity/monster/EntitySnowman.java.patch new file mode 100644 index 000000000..cf7794cd5 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/monster/EntitySnowman.java.patch @@ -0,0 +1,48 @@ +--- original/net/minecraft/entity/monster/EntitySnowman.java ++++ modified/net/minecraft/entity/monster/EntitySnowman.java +@@ -31,7 +31,7 @@ + import net.minecraft.world.World; + import net.minecraft.world.storage.loot.LootTableList; + +-public class EntitySnowman extends EntityGolem implements IRangedAttackMob { ++public class EntitySnowman extends EntityGolem implements IRangedAttackMob, net.minecraftforge.common.IShearable { + private static final DataParameter PUMPKIN_EQUIPPED = EntityDataManager.createKey(EntitySnowman.class, DataSerializers.BYTE); + + public EntitySnowman(World worldIn) { +@@ -97,7 +97,7 @@ + this.attackEntityFrom(DamageSource.ON_FIRE, 1.0F); + } + +- if (!this.world.getGameRules().getBoolean("mobGriefing")) { ++ if (!net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.world, this)) { + return; + } + +@@ -143,7 +143,8 @@ + @Override + protected boolean processInteract(EntityPlayer player, EnumHand hand) { + ItemStack itemstack = player.getHeldItem(hand); +- if (itemstack.getItem() == Items.SHEARS && this.isPumpkinEquipped() && !this.world.isRemote) { ++ ++ if (false && itemstack.getItem() == Items.SHEARS && this.isPumpkinEquipped() && !this.world.isRemote) { //Forge: Moved to onSheared + this.setPumpkinEquipped(false); + itemstack.damageItem(1, player); + } +@@ -183,6 +184,17 @@ + } + + @Override ++ public boolean isShearable(ItemStack item, net.minecraft.world.IBlockAccess world, BlockPos pos) { ++ return this.isPumpkinEquipped(); ++ } ++ ++ @Override ++ public java.util.List onSheared(ItemStack item, net.minecraft.world.IBlockAccess world, BlockPos pos, int fortune) { ++ this.setPumpkinEquipped(false); ++ return com.google.common.collect.Lists.newArrayList(); ++ } ++ ++ @Override + public void setSwingingArms(boolean swingingArms) { + } + } diff --git a/module/minecraft/patches/net/minecraft/entity/monster/EntitySpider.java.patch b/module/minecraft/patches/net/minecraft/entity/monster/EntitySpider.java.patch new file mode 100644 index 000000000..aba3d03f8 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/monster/EntitySpider.java.patch @@ -0,0 +1,16 @@ +--- original/net/minecraft/entity/monster/EntitySpider.java ++++ modified/net/minecraft/entity/monster/EntitySpider.java +@@ -140,7 +140,12 @@ + + @Override + public boolean isPotionApplicable(PotionEffect potioneffectIn) { +- return potioneffectIn.getPotion() == MobEffects.POISON ? false : super.isPotionApplicable(potioneffectIn); ++ if(potioneffectIn.getPotion() == MobEffects.POISON) { ++ net.minecraftforge.event.entity.living.PotionEvent.PotionApplicableEvent event = new net.minecraftforge.event.entity.living.PotionEvent.PotionApplicableEvent(this, potioneffectIn); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event); ++ return event.getResult() == net.minecraftforge.fml.common.eventhandler.Event.Result.ALLOW; ++ } ++ return super.isPotionApplicable(potioneffectIn); + } + + /** Returns true if the WatchableObject (Byte) is 0x01 otherwise returns false. The WatchableObject is updated using setBesideClimableBlock. */ diff --git a/module/minecraft/patches/net/minecraft/entity/monster/EntityZombie.java.patch b/module/minecraft/patches/net/minecraft/entity/monster/EntityZombie.java.patch new file mode 100644 index 000000000..e9c350cfe --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/monster/EntityZombie.java.patch @@ -0,0 +1,74 @@ +--- original/net/minecraft/entity/monster/EntityZombie.java ++++ modified/net/minecraft/entity/monster/EntityZombie.java +@@ -100,7 +100,7 @@ + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.23F); + this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(3.0); + this.getEntityAttribute(SharedMonsterAttributes.ARMOR).setBaseValue(2.0); +- this.getAttributeMap().registerAttribute(SPAWN_REINFORCEMENTS_CHANCE).setBaseValue(this.rand.nextDouble() * 0.1F); ++ this.getAttributeMap().registerAttribute(SPAWN_REINFORCEMENTS_CHANCE).setBaseValue(this.rand.nextDouble() * net.minecraftforge.common.ForgeModContainer.zombieSummonBaseChance); + } + + @Override +@@ -220,28 +220,42 @@ + entitylivingbase = (EntityLivingBase)source.getTrueSource(); + } + +- if (entitylivingbase != null +- && this.world.getDifficulty() == EnumDifficulty.HARD +- && this.rand.nextFloat() < this.getEntityAttribute(SPAWN_REINFORCEMENTS_CHANCE).getAttributeValue() +- && this.world.getGameRules().getBoolean("doMobSpawning")) { +- int i = MathHelper.floor(this.posX); +- int j = MathHelper.floor(this.posY); +- int k = MathHelper.floor(this.posZ); +- EntityZombie entityzombie = new EntityZombie(this.world); ++ int i = MathHelper.floor(this.posX); ++ int j = MathHelper.floor(this.posY); ++ int k = MathHelper.floor(this.posZ); ++ net.minecraftforge.event.entity.living.ZombieEvent.SummonAidEvent summonAid ++ = net.minecraftforge.event.ForgeEventFactory.fireZombieSummonAid( ++ this, world, i, j, k, entitylivingbase, this.getEntityAttribute(SPAWN_REINFORCEMENTS_CHANCE).getAttributeValue() ++ ); ++ if (summonAid.getResult() == net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) return true; + ++ if (summonAid.getResult() == net.minecraftforge.fml.common.eventhandler.Event.Result.ALLOW ++ || entitylivingbase != null ++ && this.world.getDifficulty() == EnumDifficulty.HARD ++ && this.rand.nextFloat() < this.getEntityAttribute(SPAWN_REINFORCEMENTS_CHANCE).getAttributeValue() ++ && this.world.getGameRules().getBoolean("doMobSpawning")) { ++ EntityZombie entityzombie; ++ if (summonAid.getCustomSummonedAid() != null ++ && summonAid.getResult() == net.minecraftforge.fml.common.eventhandler.Event.Result.ALLOW) { ++ entityzombie = summonAid.getCustomSummonedAid(); ++ } else { ++ entityzombie = new EntityZombie(this.world); ++ } ++ + for (int l = 0; l < 50; l++) { + int i1 = i + MathHelper.getInt(this.rand, 7, 40) * MathHelper.getInt(this.rand, -1, 1); + int j1 = j + MathHelper.getInt(this.rand, 7, 40) * MathHelper.getInt(this.rand, -1, 1); + int k1 = k + MathHelper.getInt(this.rand, 7, 40) * MathHelper.getInt(this.rand, -1, 1); +- if (this.world.getBlockState(new BlockPos(i1, j1 - 1, k1)).isTopSolid() +- && this.world.getLightFromNeighbors(new BlockPos(i1, j1, k1)) < 10) { ++ ++ if (this.world.getBlockState(new BlockPos(i1, j1 - 1, k1)).isSideSolid(this.world, new BlockPos(i1, j1 - 1, k1), net.minecraft.util.EnumFacing.UP) ++ && this.world.getLightFromNeighbors(new BlockPos(i1, j1, k1)) < 10) { + entityzombie.setPosition(i1, j1, k1); + if (!this.world.isAnyPlayerWithinRangeAt(i1, j1, k1, 7.0) + && this.world.checkNoEntityCollision(entityzombie.getEntityBoundingBox(), entityzombie) + && this.world.getCollisionBoxes(entityzombie, entityzombie.getEntityBoundingBox()).isEmpty() + && !this.world.containsAnyLiquid(entityzombie.getEntityBoundingBox())) { + this.world.spawnEntity(entityzombie); +- entityzombie.setAttackTarget(entitylivingbase); ++ if (entitylivingbase != null) entityzombie.setAttackTarget(entitylivingbase); + entityzombie.onInitialSpawn(this.world.getDifficultyForLocation(new BlockPos(entityzombie)), null); + this.getEntityAttribute(SPAWN_REINFORCEMENTS_CHANCE).applyModifier(new AttributeModifier("Zombie reinforcement caller charge", -0.05F, 0)); + entityzombie.getEntityAttribute(SPAWN_REINFORCEMENTS_CHANCE).applyModifier(new AttributeModifier("Zombie reinforcement callee charge", -0.05F, 0)); +@@ -406,7 +420,7 @@ + float f = difficulty.getClampedAdditionalDifficulty(); + this.setCanPickUpLoot(this.rand.nextFloat() < 0.55F * f); + if (livingdata == null) { +- livingdata = new EntityZombie.GroupData(this.world.rand.nextFloat() < 0.05F); ++ livingdata = new EntityZombie.GroupData(this.world.rand.nextFloat() < net.minecraftforge.common.ForgeModContainer.zombieBabyChance); + } + + if (livingdata instanceof EntityZombie.GroupData) { diff --git a/module/minecraft/patches/net/minecraft/entity/monster/EntityZombieVillager.java.patch b/module/minecraft/patches/net/minecraft/entity/monster/EntityZombieVillager.java.patch new file mode 100644 index 000000000..305dbb675 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/monster/EntityZombieVillager.java.patch @@ -0,0 +1,89 @@ +--- original/net/minecraft/entity/monster/EntityZombieVillager.java ++++ modified/net/minecraft/entity/monster/EntityZombieVillager.java +@@ -52,10 +52,13 @@ + + public void setProfession(int profession) { + this.dataManager.set(PROFESSION, profession); ++ net.minecraftforge.fml.common.registry.VillagerRegistry.onSetProfession(this, profession); + } + ++ //Use Forge Variant below ++ @Deprecated + public int getProfession() { +- return Math.max(this.dataManager.get(PROFESSION) % 6, 0); ++ return Math.max(this.dataManager.get(PROFESSION), 0); + } + + public static void registerFixesZombieVillager(DataFixer fixer) { +@@ -67,6 +70,7 @@ + public void writeEntityToNBT(NBTTagCompound compound) { + super.writeEntityToNBT(compound); + compound.setInteger("Profession", this.getProfession()); ++ compound.setString("ProfessionName", this.getForgeProfession().getRegistryName().toString()); + compound.setInteger("ConversionTime", this.isConverting() ? this.conversionTime : -1); + if (this.converstionStarter != null) { + compound.setUniqueId("ConversionPlayer", this.converstionStarter); +@@ -78,6 +82,12 @@ + public void readEntityFromNBT(NBTTagCompound compound) { + super.readEntityFromNBT(compound); + this.setProfession(compound.getInteger("Profession")); ++ if (compound.hasKey("ProfessionName")) { ++ net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession p = net.minecraftforge.fml.common.registry.ForgeRegistries.VILLAGER_PROFESSIONS.getValue(new net.minecraft.util.ResourceLocation(compound.getString("ProfessionName"))); ++ if (p == null) p = net.minecraftforge.fml.common.registry.VillagerRegistry.FARMER; ++ this.setForgeProfession(p); ++ } ++ + if (compound.hasKey("ConversionTime", 99) && compound.getInteger("ConversionTime") > -1) { + this.startConverting( + compound.hasUniqueId("ConversionPlayer") ? compound.getUniqueId("ConversionPlayer") : null, compound.getInteger("ConversionTime") +@@ -98,7 +108,7 @@ + @Nullable + @Override + public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, @Nullable IEntityLivingData livingdata) { +- this.setProfession(this.world.rand.nextInt(6)); ++ net.minecraftforge.fml.common.registry.VillagerRegistry.setRandomProfession(this, this.world.rand); + return super.onInitialSpawn(difficulty, livingdata); + } + +@@ -186,7 +196,7 @@ + protected void finishConversion() { + EntityVillager entityvillager = new EntityVillager(this.world); + entityvillager.copyLocationAndAnglesFrom(this); +- entityvillager.setProfession(this.getProfession()); ++ entityvillager.setProfession(this.getForgeProfession()); + entityvillager.finalizeMobSpawn(this.world.getDifficultyForLocation(new BlockPos(entityvillager)), null, false); + entityvillager.setLookingForHome(); + if (this.isChild()) { +@@ -275,4 +285,32 @@ + protected ItemStack getSkullDrop() { + return ItemStack.EMPTY; + } ++ ++ /* ======================================== FORGE START =====================================*/ ++ ++ @Nullable ++ private net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession prof; ++ public void setForgeProfession(net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession prof) { ++ this.prof = prof; ++ this.setProfession(net.minecraftforge.fml.common.registry.VillagerRegistry.getId(prof)); ++ } ++ ++ public net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession getForgeProfession() { ++ if (this.prof == null) { ++ this.prof = net.minecraftforge.fml.common.registry.VillagerRegistry.getById(this.getProfession()); ++ if (this.prof == null) ++ return net.minecraftforge.fml.common.registry.VillagerRegistry.FARMER; ++ } ++ return this.prof; ++ } ++ ++ @Override ++ public void notifyDataManagerChange(DataParameter key) { ++ super.notifyDataManagerChange(key); ++ if (key.equals(PROFESSION)) { ++ net.minecraftforge.fml.common.registry.VillagerRegistry.onSetProfession(this, this.dataManager.get(PROFESSION)); ++ } ++ } ++ ++ /* ======================================== FORGE END =====================================*/ + } diff --git a/module/minecraft/patches/net/minecraft/entity/passive/AbstractHorse.java.patch b/module/minecraft/patches/net/minecraft/entity/passive/AbstractHorse.java.patch new file mode 100644 index 000000000..9b79cff19 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/passive/AbstractHorse.java.patch @@ -0,0 +1,31 @@ +--- original/net/minecraft/entity/passive/AbstractHorse.java ++++ modified/net/minecraft/entity/passive/AbstractHorse.java +@@ -296,6 +296,7 @@ + + this.horseChest.addInventoryChangeListener(this); + this.updateHorseSlots(); ++ this.itemHandler = new net.minecraftforge.items.wrapper.InvWrapper(this.horseChest); + } + + /** Updates the items in the saddle and armor slots of the horse's inventory. */ +@@ -1088,4 +1089,20 @@ + + return livingdata; + } ++ ++ // FORGE ++ private net.minecraftforge.items.IItemHandler itemHandler = null; // Initialized by initHorseChest above. ++ ++ @SuppressWarnings("unchecked") ++ @Override ++ @Nullable ++ public T getCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable net.minecraft.util.EnumFacing facing) { ++ if (capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return (T) itemHandler; ++ return super.getCapability(capability, facing); ++ } ++ ++ @Override ++ public boolean hasCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable net.minecraft.util.EnumFacing facing) { ++ return capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY || super.hasCapability(capability, facing); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/entity/passive/EntityHorse.java.patch b/module/minecraft/patches/net/minecraft/entity/passive/EntityHorse.java.patch new file mode 100644 index 000000000..0ed523a0a --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/passive/EntityHorse.java.patch @@ -0,0 +1,81 @@ +--- original/net/minecraft/entity/passive/EntityHorse.java ++++ modified/net/minecraft/entity/passive/EntityHorse.java +@@ -33,6 +33,7 @@ + private static final UUID ARMOR_MODIFIER_UUID = UUID.fromString("556E1665-8B10-40C8-8F9D-CF9B1667F295"); + private static final DataParameter HORSE_VARIANT = EntityDataManager.createKey(EntityHorse.class, DataSerializers.VARINT); + private static final DataParameter HORSE_ARMOR = EntityDataManager.createKey(EntityHorse.class, DataSerializers.VARINT); ++ private static final DataParameter HORSE_ARMOR_STACK = EntityDataManager.createKey(EntityHorse.class, DataSerializers.ITEM_STACK); + private static final String[] HORSE_TEXTURES = new String[]{ + "textures/entity/horse/horse_white.png", + "textures/entity/horse/horse_creamy.png", +@@ -63,6 +64,7 @@ + super.entityInit(); + this.dataManager.register(HORSE_VARIANT, 0); + this.dataManager.register(HORSE_ARMOR, HorseArmorType.NONE.getOrdinal()); ++ this.dataManager.register(HORSE_ARMOR_STACK, ItemStack.EMPTY); + } + + public static void registerFixesHorse(DataFixer fixer) { +@@ -87,7 +89,8 @@ + this.setHorseVariant(compound.getInteger("Variant")); + if (compound.hasKey("ArmorItem", 10)) { + ItemStack itemstack = new ItemStack(compound.getCompoundTag("ArmorItem")); +- if (!itemstack.isEmpty() && HorseArmorType.isHorseArmor(itemstack.getItem())) { ++ ++ if (!itemstack.isEmpty() && isArmor(itemstack)) { + this.horseChest.setInventorySlotContents(1, itemstack); + } + } +@@ -113,11 +116,12 @@ + int i = this.getHorseVariant(); + int j = (i & 0xFF) % 7; + int k = ((i & 0xFF00) >> 8) % 5; +- HorseArmorType horsearmortype = this.getHorseArmorType(); ++ ItemStack armorStack = this.dataManager.get(HORSE_ARMOR_STACK); ++ String texture = !armorStack.isEmpty() ? armorStack.getItem().getHorseArmorTexture(this, armorStack) : HorseArmorType.getByOrdinal(this.dataManager.get(HORSE_ARMOR)).getTextureName(); //If armorStack is empty, the server is vanilla so the texture should be determined the vanilla way + this.horseTexturesArray[0] = HORSE_TEXTURES[j]; + this.horseTexturesArray[1] = HORSE_MARKING_TEXTURES[k]; +- this.horseTexturesArray[2] = horsearmortype.getTextureName(); +- this.texturePrefix = "horse/" + HORSE_TEXTURES_ABBR[j] + HORSE_MARKING_TEXTURES_ABBR[k] + horsearmortype.getHash(); ++ this.horseTexturesArray[2] = texture; ++ this.texturePrefix = "horse/" + HORSE_TEXTURES_ABBR[j] + HORSE_MARKING_TEXTURES_ABBR[k] + texture; + } + + @SideOnly(Side.CLIENT) +@@ -149,6 +153,7 @@ + public void setHorseArmorStack(ItemStack itemStackIn) { + HorseArmorType horsearmortype = HorseArmorType.getByItemStack(itemStackIn); + this.dataManager.set(HORSE_ARMOR, horsearmortype.getOrdinal()); ++ this.dataManager.set(HORSE_ARMOR_STACK, itemStackIn); + this.resetTexturePrefix(); + if (!this.world.isRemote) { + this.getEntityAttribute(SharedMonsterAttributes.ARMOR).removeModifier(ARMOR_MODIFIER_UUID); +@@ -161,7 +166,9 @@ + } + + public HorseArmorType getHorseArmorType() { +- return HorseArmorType.getByOrdinal(this.dataManager.get(HORSE_ARMOR)); ++ HorseArmorType armor = HorseArmorType.getByItemStack(this.dataManager.get(HORSE_ARMOR_STACK)); //First check the Forge armor DataParameter ++ if (armor == HorseArmorType.NONE) armor = HorseArmorType.getByOrdinal(this.dataManager.get(HORSE_ARMOR)); //If the Forge armor DataParameter returns NONE, fallback to the vanilla armor DataParameter. This is necessary to prevent issues with Forge clients connected to vanilla servers. ++ return armor; + } + + /** Called by InventoryBasic.onInventoryChanged() on a array that is never filled. */ +@@ -199,6 +206,8 @@ + this.dataManager.setClean(); + this.resetTexturePrefix(); + } ++ ItemStack armor = this.horseChest.getStackInSlot(1); ++ if (isArmor(armor)) armor.getItem().onHorseArmorTick(world, this, armor); + } + + @Override +@@ -336,7 +345,7 @@ + + @Override + public boolean isArmor(ItemStack stack) { +- return HorseArmorType.isHorseArmor(stack.getItem()); ++ return HorseArmorType.isHorseArmor(stack); + } + + /** diff --git a/module/minecraft/patches/net/minecraft/entity/passive/EntityLlama.java.patch b/module/minecraft/patches/net/minecraft/entity/passive/EntityLlama.java.patch new file mode 100644 index 000000000..23fea12f8 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/passive/EntityLlama.java.patch @@ -0,0 +1,12 @@ +--- original/net/minecraft/entity/passive/EntityLlama.java ++++ modified/net/minecraft/entity/passive/EntityLlama.java +@@ -428,6 +428,9 @@ + + @Override + public void fall(float distance, float damageMultiplier) { ++ float[] ret = net.minecraftforge.common.ForgeHooks.onLivingFall(this, distance, damageMultiplier); ++ if (ret == null) return; ++ distance = ret[0]; damageMultiplier = ret[1]; + int i = MathHelper.ceil((distance * 0.5F - 3.0F) * damageMultiplier); + if (i > 0) { + if (distance >= 6.0F) { diff --git a/module/minecraft/patches/net/minecraft/entity/passive/EntityMooshroom.java.patch b/module/minecraft/patches/net/minecraft/entity/passive/EntityMooshroom.java.patch new file mode 100644 index 000000000..b7e1f60a6 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/passive/EntityMooshroom.java.patch @@ -0,0 +1,53 @@ +--- original/net/minecraft/entity/passive/EntityMooshroom.java ++++ modified/net/minecraft/entity/passive/EntityMooshroom.java +@@ -16,7 +16,7 @@ + import net.minecraft.world.World; + import net.minecraft.world.storage.loot.LootTableList; + +-public class EntityMooshroom extends EntityCow { ++public class EntityMooshroom extends EntityCow implements net.minecraftforge.common.IShearable { + public EntityMooshroom(World worldIn) { + super(worldIn); + this.setSize(0.9F, 1.4F); +@@ -39,7 +39,7 @@ + } + + return true; +- } else if (itemstack.getItem() == Items.SHEARS && this.getGrowingAge() >= 0) { ++ } else if (false && itemstack.getItem() == Items.SHEARS && this.getGrowingAge() >= 0) { //Forge Disable, Moved to onSheared + this.setDead(); + this.world + .spawnParticle( +@@ -83,6 +83,32 @@ + return new EntityMooshroom(this.world); + } + ++ @Override public boolean isShearable(ItemStack item, net.minecraft.world.IBlockAccess world, net.minecraft.util.math.BlockPos pos){ return getGrowingAge() >= 0; } ++ @Override ++ public java.util.List onSheared(ItemStack item, net.minecraft.world.IBlockAccess world, net.minecraft.util.math.BlockPos pos, int fortune) { ++ this.setDead(); ++ ((net.minecraft.world.WorldServer)this.world).spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, false, this.posX, this.posY + (double)(this.height / 2.0F), this.posZ, 1, 0.0D, 0.0D, 0.0D, 0.0D); ++ ++ EntityCow entitycow = new EntityCow(this.world); ++ entitycow.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, this.rotationPitch); ++ entitycow.setHealth(this.getHealth()); ++ entitycow.renderYawOffset = this.renderYawOffset; ++ ++ if (this.hasCustomName()) { ++ entitycow.setCustomNameTag(this.getCustomNameTag()); ++ } ++ ++ this.world.spawnEntity(entitycow); ++ ++ java.util.List ret = new java.util.ArrayList(); ++ for (int i = 0; i < 5; ++i) { ++ ret.add(new ItemStack(Blocks.RED_MUSHROOM)); ++ } ++ ++ this.playSound(SoundEvents.ENTITY_MOOSHROOM_SHEAR, 1.0F, 1.0F); ++ return ret; ++ } ++ + @Nullable + @Override + protected ResourceLocation getLootTable() { diff --git a/module/minecraft/patches/net/minecraft/entity/passive/EntityOcelot.java.patch b/module/minecraft/patches/net/minecraft/entity/passive/EntityOcelot.java.patch new file mode 100644 index 000000000..9753e576e --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/passive/EntityOcelot.java.patch @@ -0,0 +1,21 @@ +--- original/net/minecraft/entity/passive/EntityOcelot.java ++++ modified/net/minecraft/entity/passive/EntityOcelot.java +@@ -200,7 +200,7 @@ + } + + if (!this.world.isRemote) { +- if (this.rand.nextInt(3) == 0) { ++ if (this.rand.nextInt(3) == 0 && !net.minecraftforge.event.ForgeEventFactory.onAnimalTame(this, player)) { + this.setTamedBy(player); + this.setTameSkin(1 + this.world.rand.nextInt(3)); + this.playTameEffect(true); +@@ -281,7 +281,8 @@ + + IBlockState iblockstate = this.world.getBlockState(blockpos.down()); + Block block = iblockstate.getBlock(); +- if (block == Blocks.GRASS || iblockstate.getMaterial() == Material.LEAVES) { ++ ++ if (block == Blocks.GRASS || block.isLeaves(iblockstate, this.world, blockpos.down())) { + return true; + } + } diff --git a/module/minecraft/patches/net/minecraft/entity/passive/EntityParrot.java.patch b/module/minecraft/patches/net/minecraft/entity/passive/EntityParrot.java.patch new file mode 100644 index 000000000..f91c9390d --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/passive/EntityParrot.java.patch @@ -0,0 +1,130 @@ +--- original/net/minecraft/entity/passive/EntityParrot.java ++++ modified/net/minecraft/entity/passive/EntityParrot.java +@@ -1,6 +1,7 @@ + package net.minecraft.entity.passive; + + import com.google.common.base.Predicate; ++import com.google.common.collect.Maps; + import com.google.common.collect.Sets; + import it.unimi.dsi.fastutil.ints.Int2ObjectMap; + import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +@@ -88,12 +89,12 @@ + private static final Predicate CAN_MIMIC = new Predicate() { + public boolean apply(@Nullable EntityLiving p_apply_1_) { + return p_apply_1_ != null +- && EntityParrot.IMITATION_SOUND_EVENTS.containsKey(EntityList.REGISTRY.getIDForObject((Class)p_apply_1_.getClass())); ++ && EntityParrot.MIMIC_SOUNDS.containsKey(p_apply_1_.getClass()); + } + }; + private static final Item DEADLY_ITEM = Items.COOKIE; + private static final Set TAME_ITEMS = Sets.newHashSet(Items.WHEAT_SEEDS, Items.MELON_SEEDS, Items.PUMPKIN_SEEDS, Items.BEETROOT_SEEDS); +- private static final Int2ObjectMap IMITATION_SOUND_EVENTS = new Int2ObjectOpenHashMap<>(32); ++ private static final java.util.Map, SoundEvent> MIMIC_SOUNDS = Maps.newHashMapWithExpectedSize(32); + public float flap; + public float flapSpeed; + public float oFlapSpeed; +@@ -218,7 +219,7 @@ + if (!list.isEmpty()) { + EntityLiving entityliving = list.get(worldIn.rand.nextInt(list.size())); + if (!entityliving.isSilent()) { +- SoundEvent soundevent = getImitatedSound(EntityList.REGISTRY.getIDForObject((Class)entityliving.getClass())); ++ SoundEvent soundevent = MIMIC_SOUNDS.get(entityliving.getClass()); + worldIn.playSound( + null, + parrotIn.posX, +@@ -262,7 +263,7 @@ + } + + if (!this.world.isRemote) { +- if (this.rand.nextInt(10) == 0) { ++ if (this.rand.nextInt(10) == 0 && !net.minecraftforge.event.ForgeEventFactory.onAnimalTame(this, player)) { + this.setTamedBy(player); + this.playTameEffect(true); + this.world.setEntityState(this, (byte)7); +@@ -361,17 +362,14 @@ + + private static SoundEvent getAmbientSound(Random random) { + if (random.nextInt(1000) == 0) { +- List list = new ArrayList<>(IMITATION_SOUND_EVENTS.keySet()); +- return getImitatedSound(list.get(random.nextInt(list.size()))); ++ List list = new ArrayList(MIMIC_SOUNDS.values()); ++ SoundEvent ret = list.get(random.nextInt(list.size())); ++ return ret == null ? SoundEvents.ENTITY_PARROT_AMBIENT : ret; + } else { + return SoundEvents.ENTITY_PARROT_AMBIENT; + } + } + +- public static SoundEvent getImitatedSound(int p_191999_0_) { +- return IMITATION_SOUND_EVENTS.containsKey(p_191999_0_) ? IMITATION_SOUND_EVENTS.get(p_191999_0_) : SoundEvents.ENTITY_PARROT_AMBIENT; +- } +- + @Override + protected SoundEvent getHurtSound(DamageSource damageSourceIn) { + return SoundEvents.ENTITY_PARROT_HURT; +@@ -479,33 +477,37 @@ + } + + static { +- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityBlaze.class), SoundEvents.E_PARROT_IM_BLAZE); +- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityCaveSpider.class), SoundEvents.E_PARROT_IM_SPIDER); +- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityCreeper.class), SoundEvents.E_PARROT_IM_CREEPER); +- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityElderGuardian.class), SoundEvents.E_PARROT_IM_ELDER_GUARDIAN); +- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityDragon.class), SoundEvents.E_PARROT_IM_ENDERDRAGON); +- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityEnderman.class), SoundEvents.E_PARROT_IM_ENDERMAN); +- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityEndermite.class), SoundEvents.E_PARROT_IM_ENDERMITE); +- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityEvoker.class), SoundEvents.E_PARROT_IM_EVOCATION_ILLAGER); +- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityGhast.class), SoundEvents.E_PARROT_IM_GHAST); +- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityHusk.class), SoundEvents.E_PARROT_IM_HUSK); +- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityIllusionIllager.class), SoundEvents.E_PARROT_IM_ILLUSION_ILLAGER); +- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityMagmaCube.class), SoundEvents.E_PARROT_IM_MAGMACUBE); +- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityPigZombie.class), SoundEvents.E_PARROT_IM_ZOMBIE_PIGMAN); +- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityPolarBear.class), SoundEvents.E_PARROT_IM_POLAR_BEAR); +- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityShulker.class), SoundEvents.E_PARROT_IM_SHULKER); +- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntitySilverfish.class), SoundEvents.E_PARROT_IM_SILVERFISH); +- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntitySkeleton.class), SoundEvents.E_PARROT_IM_SKELETON); +- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntitySlime.class), SoundEvents.E_PARROT_IM_SLIME); +- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntitySpider.class), SoundEvents.E_PARROT_IM_SPIDER); +- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityStray.class), SoundEvents.E_PARROT_IM_STRAY); +- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityVex.class), SoundEvents.E_PARROT_IM_VEX); +- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityVindicator.class), SoundEvents.E_PARROT_IM_VINDICATION_ILLAGER); +- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityWitch.class), SoundEvents.E_PARROT_IM_WITCH); +- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityWither.class), SoundEvents.E_PARROT_IM_WITHER); +- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityWitherSkeleton.class), SoundEvents.E_PARROT_IM_WITHER_SKELETON); +- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityWolf.class), SoundEvents.E_PARROT_IM_WOLF); +- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityZombie.class), SoundEvents.E_PARROT_IM_ZOMBIE); +- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityZombieVillager.class), SoundEvents.E_PARROT_IM_ZOMBIE_VILLAGER); ++ registerMimicSound(EntityBlaze.class, SoundEvents.E_PARROT_IM_BLAZE); ++ registerMimicSound(EntityCaveSpider.class, SoundEvents.E_PARROT_IM_SPIDER); ++ registerMimicSound(EntityCreeper.class, SoundEvents.E_PARROT_IM_CREEPER); ++ registerMimicSound(EntityElderGuardian.class, SoundEvents.E_PARROT_IM_ELDER_GUARDIAN); ++ registerMimicSound(EntityDragon.class, SoundEvents.E_PARROT_IM_ENDERDRAGON); ++ registerMimicSound(EntityEnderman.class, SoundEvents.E_PARROT_IM_ENDERMAN); ++ registerMimicSound(EntityEndermite.class, SoundEvents.E_PARROT_IM_ENDERMITE); ++ registerMimicSound(EntityEvoker.class, SoundEvents.E_PARROT_IM_EVOCATION_ILLAGER); ++ registerMimicSound(EntityGhast.class, SoundEvents.E_PARROT_IM_GHAST); ++ registerMimicSound(EntityHusk.class, SoundEvents.E_PARROT_IM_HUSK); ++ registerMimicSound(EntityIllusionIllager.class, SoundEvents.E_PARROT_IM_ILLUSION_ILLAGER); ++ registerMimicSound(EntityMagmaCube.class, SoundEvents.E_PARROT_IM_MAGMACUBE); ++ registerMimicSound(EntityPigZombie.class, SoundEvents.E_PARROT_IM_ZOMBIE_PIGMAN); ++ registerMimicSound(EntityPolarBear.class, SoundEvents.E_PARROT_IM_POLAR_BEAR); ++ registerMimicSound(EntityShulker.class, SoundEvents.E_PARROT_IM_SHULKER); ++ registerMimicSound(EntitySilverfish.class, SoundEvents.E_PARROT_IM_SILVERFISH); ++ registerMimicSound(EntitySkeleton.class, SoundEvents.E_PARROT_IM_SKELETON); ++ registerMimicSound(EntitySlime.class, SoundEvents.E_PARROT_IM_SLIME); ++ registerMimicSound(EntitySpider.class, SoundEvents.E_PARROT_IM_SPIDER); ++ registerMimicSound(EntityStray.class, SoundEvents.E_PARROT_IM_STRAY); ++ registerMimicSound(EntityVex.class, SoundEvents.E_PARROT_IM_VEX); ++ registerMimicSound(EntityVindicator.class, SoundEvents.E_PARROT_IM_VINDICATION_ILLAGER); ++ registerMimicSound(EntityWitch.class, SoundEvents.E_PARROT_IM_WITCH); ++ registerMimicSound(EntityWither.class, SoundEvents.E_PARROT_IM_WITHER); ++ registerMimicSound(EntityWitherSkeleton.class, SoundEvents.E_PARROT_IM_WITHER_SKELETON); ++ registerMimicSound(EntityWolf.class, SoundEvents.E_PARROT_IM_WOLF); ++ registerMimicSound(EntityZombie.class, SoundEvents.E_PARROT_IM_ZOMBIE); ++ registerMimicSound(EntityZombieVillager.class, SoundEvents.E_PARROT_IM_ZOMBIE_VILLAGER); + } ++ ++ public static void registerMimicSound(Class cls, SoundEvent sound) { ++ MIMIC_SOUNDS.put(cls, sound); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/entity/passive/EntityRabbit.java.patch b/module/minecraft/patches/net/minecraft/entity/passive/EntityRabbit.java.patch new file mode 100644 index 000000000..09c045095 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/passive/EntityRabbit.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/entity/passive/EntityRabbit.java ++++ modified/net/minecraft/entity/passive/EntityRabbit.java +@@ -499,7 +499,7 @@ + @Override + public boolean shouldExecute() { + if (this.runDelay <= 0) { +- if (!this.rabbit.world.getGameRules().getBoolean("mobGriefing")) { ++ if (!net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.rabbit.world, this.rabbit)) { + return false; + } + diff --git a/module/minecraft/patches/net/minecraft/entity/passive/EntitySheep.java.patch b/module/minecraft/patches/net/minecraft/entity/passive/EntitySheep.java.patch new file mode 100644 index 000000000..6052e2d12 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/passive/EntitySheep.java.patch @@ -0,0 +1,47 @@ +--- original/net/minecraft/entity/passive/EntitySheep.java ++++ modified/net/minecraft/entity/passive/EntitySheep.java +@@ -46,7 +46,7 @@ + import net.minecraftforge.fml.relauncher.Side; + import net.minecraftforge.fml.relauncher.SideOnly; + +-public class EntitySheep extends EntityAnimal { ++public class EntitySheep extends EntityAnimal implements net.minecraftforge.common.IShearable { + private static final DataParameter DYE_COLOR = EntityDataManager.createKey(EntitySheep.class, DataSerializers.BYTE); + /** Internal crafting inventory used to check the result of mixing dyes corresponding to the fleece color when breeding sheep. */ + private final InventoryCrafting inventoryCrafting = new InventoryCrafting(new Container() { +@@ -202,7 +202,8 @@ + @Override + public boolean processInteract(EntityPlayer player, EnumHand hand) { + ItemStack itemstack = player.getHeldItem(hand); +- if (itemstack.getItem() == Items.SHEARS && !this.getSheared() && !this.isChild()) { ++ ++ if (false && itemstack.getItem() == Items.SHEARS && !this.getSheared() && !this.isChild()) { //Forge: Moved to onSheared + if (!this.world.isRemote) { + this.setSheared(true); + int i = 1 + this.rand.nextInt(3); +@@ -340,7 +341,24 @@ + return livingdata; + } + +- /** Attempts to mix both parent sheep to come up with a mixed dye color. */ ++ @Override ++ public boolean isShearable(ItemStack item, net.minecraft.world.IBlockAccess world, BlockPos pos) { ++ return !this.getSheared() && !this.isChild(); ++ } ++ ++ @Override ++ public java.util.List onSheared(ItemStack item, net.minecraft.world.IBlockAccess world, BlockPos pos, int fortune) { ++ this.setSheared(true); ++ int i = 1 + this.rand.nextInt(3); ++ ++ java.util.List ret = new java.util.ArrayList(); ++ for (int j = 0; j < i; ++j) ++ ret.add(new ItemStack(Item.getItemFromBlock(Blocks.WOOL), 1, this.getFleeceColor().getMetadata())); ++ ++ this.playSound(SoundEvents.ENTITY_SHEEP_SHEAR, 1.0F, 1.0F); ++ return ret; ++ } ++ + private EnumDyeColor getDyeColorMixFromParents(EntityAnimal father, EntityAnimal mother) { + int i = ((EntitySheep)father).getFleeceColor().getDyeDamage(); + int j = ((EntitySheep)mother).getFleeceColor().getDyeDamage(); diff --git a/module/minecraft/patches/net/minecraft/entity/passive/EntityVillager.java.patch b/module/minecraft/patches/net/minecraft/entity/passive/EntityVillager.java.patch new file mode 100644 index 000000000..d9190bd50 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/passive/EntityVillager.java.patch @@ -0,0 +1,228 @@ +--- original/net/minecraft/entity/passive/EntityVillager.java ++++ modified/net/minecraft/entity/passive/EntityVillager.java +@@ -111,12 +111,7 @@ + private boolean needsInitilization; + private boolean isWillingToMate; + private int wealth; +- /** +- * Last player to trade with this villager, used for aggressivity. +- * +- * MODDERS: Do not reference directly; will have a different type under forge +- */ +- private String lastBuyingPlayer; ++ private java.util.UUID lastBuyingPlayer; + private int careerId; + /** This is the EntityVillager's career level value */ + private int careerLevel; +@@ -465,7 +460,11 @@ + return true; + } + +- if (!this.holdingSpawnEggOfClass(itemstack, (Class)this.getClass()) && this.isEntityAlive() && !this.isTrading() && !this.isChild()) { ++ if (!this.holdingSpawnEggOfClass(itemstack, (Class)this.getClass()) ++ && this.isEntityAlive() ++ && !this.isTrading() ++ && !this.isChild() ++ && !player.isSneaking()) { + if (this.buyingList == null) { + this.populateBuyingList(); + } +@@ -528,6 +527,7 @@ + public void writeEntityToNBT(NBTTagCompound compound) { + super.writeEntityToNBT(compound); + compound.setInteger("Profession", this.getProfession()); ++ compound.setString("ProfessionName", this.getProfessionForge().getRegistryName().toString()); + compound.setInteger("Riches", this.wealth); + compound.setInteger("Career", this.careerId); + compound.setInteger("CareerLevel", this.careerLevel); +@@ -553,6 +553,13 @@ + public void readEntityFromNBT(NBTTagCompound compound) { + super.readEntityFromNBT(compound); + this.setProfession(compound.getInteger("Profession")); ++ if (compound.hasKey("ProfessionName")) { ++ net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession p = ++ net.minecraftforge.fml.common.registry.ForgeRegistries.VILLAGER_PROFESSIONS.getValue(new net.minecraft.util.ResourceLocation(compound.getString("ProfessionName"))); ++ if (p == null) ++ p = net.minecraftforge.fml.common.registry.ForgeRegistries.VILLAGER_PROFESSIONS.getValue(new net.minecraft.util.ResourceLocation("minecraft:farmer")); ++ this.setProfession(p); ++ } + this.wealth = compound.getInteger("Riches"); + this.careerId = compound.getInteger("Career"); + this.careerLevel = compound.getInteger("CareerLevel"); +@@ -603,13 +610,38 @@ + } + + public void setProfession(int professionId) { +- this.dataManager.set(PROFESSION, professionId); ++ this.dataManager.set(PROFESSION, Integer.valueOf(professionId)); ++ net.minecraftforge.fml.common.registry.VillagerRegistry.onSetProfession(this, professionId); + } + ++ @Deprecated //Use Forge Variant below + public int getProfession() { +- return Math.max(this.dataManager.get(PROFESSION) % 6, 0); ++ return Math.max(((Integer)this.dataManager.get(PROFESSION)).intValue(), 0); + } + ++ private net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession prof; ++ public void setProfession(net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession prof) { ++ this.prof = prof; ++ this.setProfession(net.minecraftforge.fml.common.registry.VillagerRegistry.getId(prof)); ++ } ++ ++ public net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession getProfessionForge() { ++ if (this.prof == null) { ++ this.prof = net.minecraftforge.fml.common.registry.VillagerRegistry.getById(this.getProfession()); ++ if (this.prof == null) ++ return net.minecraftforge.fml.common.registry.VillagerRegistry.getById(0); //Farmer ++ } ++ return this.prof; ++ } ++ ++ @Override ++ public void notifyDataManagerChange(DataParameter key) { ++ super.notifyDataManagerChange(key); ++ if (key.equals(PROFESSION)) { ++ net.minecraftforge.fml.common.registry.VillagerRegistry.onSetProfession(this, this.dataManager.get(PROFESSION)); ++ } ++ } ++ + public boolean isMating() { + return this.isMating; + } +@@ -638,7 +670,8 @@ + i = -3; + } + +- this.village.modifyPlayerReputation(livingBase.getName(), i); ++ this.village.modifyPlayerReputation(livingBase.getUniqueID(), i); ++ + if (this.isEntityAlive()) { + this.world.setEntityState(this, (byte)13); + } +@@ -653,7 +686,7 @@ + Entity entity = cause.getTrueSource(); + if (entity != null) { + if (entity instanceof EntityPlayer) { +- this.village.modifyPlayerReputation(entity.getName(), -2); ++ this.village.modifyPlayerReputation(entity.getUniqueID(), -2); + } else if (entity instanceof IMob) { + this.village.endMatingSeason(); + } +@@ -727,7 +760,7 @@ + this.needsInitilization = true; + this.isWillingToMate = true; + if (this.buyingPlayer != null) { +- this.lastBuyingPlayer = this.buyingPlayer.getName(); ++ this.lastBuyingPlayer = this.buyingPlayer.getUniqueID(); + } else { + this.lastBuyingPlayer = null; + } +@@ -766,15 +799,14 @@ + this.populateBuyingList(); + } + +- return this.buyingList; ++ return net.minecraftforge.event.ForgeEventFactory.listTradeOffers(this, player, buyingList); + } + + private void populateBuyingList() { +- EntityVillager.ITradeList[][][] aentityvillager$itradelist = DEFAULT_TRADE_LIST_MAP[this.getProfession()]; + if (this.careerId != 0 && this.careerLevel != 0) { + this.careerLevel++; + } else { +- this.careerId = this.rand.nextInt(aentityvillager$itradelist.length) + 1; ++ this.careerId = this.getProfessionForge().getRandomCareer(this.rand) + 1; + this.careerLevel = 1; + } + +@@ -784,14 +816,11 @@ + + int i = this.careerId - 1; + int j = this.careerLevel - 1; +- if (i >= 0 && i < aentityvillager$itradelist.length) { +- EntityVillager.ITradeList[][] aentityvillager$itradelist1 = aentityvillager$itradelist[i]; +- if (j >= 0 && j < aentityvillager$itradelist1.length) { +- EntityVillager.ITradeList[] aentityvillager$itradelist2 = aentityvillager$itradelist1[j]; ++ java.util.List trades = this.getProfessionForge().getCareer(i).getTrades(j); + +- for (EntityVillager.ITradeList entityvillager$itradelist : aentityvillager$itradelist2) { +- entityvillager$itradelist.addMerchantRecipe(this, this.buyingList, this.rand); +- } ++ if (trades != null) { ++ for (EntityVillager.ITradeList entityvillager$itradelist : trades) { ++ entityvillager$itradelist.addMerchantRecipe(this, this.buyingList, this.rand); + } + } + } +@@ -881,18 +910,15 @@ + s1 = "nitwit"; + } + +- if (s1 != null) { +- ITextComponent itextcomponent = new TextComponentTranslation("entity.Villager." + s1); +- itextcomponent.getStyle().setHoverEvent(this.getHoverEvent()); +- itextcomponent.getStyle().setInsertion(this.getCachedUniqueIdString()); +- if (team != null) { +- itextcomponent.getStyle().setColor(team.getColor()); +- } +- +- return itextcomponent; +- } else { +- return super.getDisplayName(); ++ s1 = this.getProfessionForge().getCareer(this.careerId - 1).getName(); ++ ITextComponent itextcomponent = new TextComponentTranslation("entity.Villager." + s1); ++ itextcomponent.getStyle().setHoverEvent(this.getHoverEvent()); ++ itextcomponent.getStyle().setInsertion(this.getCachedUniqueIdString()); ++ if (team != null) { ++ itextcomponent.getStyle().setColor(team.getColor()); + } ++ ++ return itextcomponent; + } + + @Override +@@ -953,7 +979,7 @@ + public IEntityLivingData finalizeMobSpawn(DifficultyInstance p_190672_1_, @Nullable IEntityLivingData p_190672_2_, boolean p_190672_3_) { + p_190672_2_ = super.onInitialSpawn(p_190672_1_, p_190672_2_); + if (p_190672_3_) { +- this.setProfession(this.world.rand.nextInt(6)); ++ net.minecraftforge.fml.common.registry.VillagerRegistry.setRandomProfession(this, this.world.rand); + } + + this.setAdditionalAItasks(); +@@ -1034,7 +1060,12 @@ + + public boolean wantsMoreFood() { + boolean flag = this.getProfession() == 0; +- return flag ? !this.hasEnoughItems(5) : !this.hasEnoughItems(1); ++ ++ if (flag) { ++ return !this.hasEnoughItems(5); ++ } else { ++ return !this.hasEnoughItems(1); ++ } + } + + /** Returns true if villager has enough items in inventory */ +@@ -1192,6 +1223,10 @@ + } + } + ++ public static ITradeList[][][][] GET_TRADES_DONT_USE() { ++ return DEFAULT_TRADE_LIST_MAP; ++ } ++ + public static class ListItemForEmeralds implements EntityVillager.ITradeList { + /** The item that is being bought for emeralds */ + public ItemStack itemToBuy; +@@ -1202,6 +1237,9 @@ + this.itemToBuy = new ItemStack(par1Item); + this.priceInfo = priceInfo; + } ++ //MODDERS DO NOT USE OR EDIT THIS IN ANY WAY IT WILL HAVE NO EFFECT, THIS IS JUST IN HERE TO ALLOW FORGE TO ACCESS IT ++ @Deprecated ++ public static ITradeList[][][][] GET_TRADES_DONT_USE(){ return DEFAULT_TRADE_LIST_MAP; } + + public ListItemForEmeralds(ItemStack stack, EntityVillager.PriceInfo priceInfo) { + this.itemToBuy = stack; diff --git a/module/minecraft/patches/net/minecraft/entity/passive/EntityWolf.java.patch b/module/minecraft/patches/net/minecraft/entity/passive/EntityWolf.java.patch new file mode 100644 index 000000000..bb5447748 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/passive/EntityWolf.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/entity/passive/EntityWolf.java ++++ modified/net/minecraft/entity/passive/EntityWolf.java +@@ -388,7 +388,7 @@ + } + + if (!this.world.isRemote) { +- if (this.rand.nextInt(3) == 0) { ++ if (this.rand.nextInt(3) == 0 && !net.minecraftforge.event.ForgeEventFactory.onAnimalTame(this, player)) { + this.setTamedBy(player); + this.navigator.clearPath(); + this.setAttackTarget(null); diff --git a/module/minecraft/patches/net/minecraft/entity/passive/HorseArmorType.java.patch b/module/minecraft/patches/net/minecraft/entity/passive/HorseArmorType.java.patch new file mode 100644 index 000000000..ff7b5edad --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/passive/HorseArmorType.java.patch @@ -0,0 +1,47 @@ +--- original/net/minecraft/entity/passive/HorseArmorType.java ++++ modified/net/minecraft/entity/passive/HorseArmorType.java +@@ -48,14 +48,16 @@ + return this.textureName; + } + ++ @Deprecated /**Forge: Use getByName. Ordinals of mod-added enum constants are dependent on load order, unlike names.**/ + public static HorseArmorType getByOrdinal(int ordinal) { + return values()[ordinal]; + } + + public static HorseArmorType getByItemStack(ItemStack stack) { +- return stack.isEmpty() ? NONE : getByItem(stack.getItem()); ++ return stack.getItem().getHorseArmorType(stack); + } + ++ @Deprecated //Forge: Use getByItemStack + public static HorseArmorType getByItem(Item itemIn) { + if (itemIn == Items.IRON_HORSE_ARMOR) { + return IRON; +@@ -66,7 +68,26 @@ + } + } + ++ @Deprecated //Forge: Use ItemStack sensitive overload + public static boolean isHorseArmor(Item itemIn) { + return getByItem(itemIn) != NONE; + } ++ ++ /* ======================================== FORGE START ======================================== */ ++ //Allows for textures located outside the vanilla horse armor folder ++ private HorseArmorType(String defaultTextureLocation, int armorStrengthIn) { ++ this.protection = armorStrengthIn; ++ this.textureName = defaultTextureLocation; ++ this.hash = "forge"; ++ } ++ ++ public static HorseArmorType getByName(String name) { ++ HorseArmorType type = HorseArmorType.valueOf(name); ++ return type != null ? type : NONE; ++ } ++ ++ public static boolean isHorseArmor(ItemStack stack) { ++ return getByItemStack(stack) != NONE; ++ } ++ /* ======================================== FORGE END ======================================== */ + } diff --git a/module/minecraft/patches/net/minecraft/entity/player/EntityPlayer.java.patch b/module/minecraft/patches/net/minecraft/entity/player/EntityPlayer.java.patch new file mode 100644 index 000000000..6d0c703ff --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/player/EntityPlayer.java.patch @@ -0,0 +1,648 @@ +--- original/net/minecraft/entity/player/EntityPlayer.java ++++ modified/net/minecraft/entity/player/EntityPlayer.java +@@ -94,7 +94,12 @@ + import net.minecraftforge.fml.relauncher.SideOnly; + + public abstract class EntityPlayer extends EntityLivingBase { +- /** The absorption data parameter */ ++ public static final String PERSISTED_NBT_TAG = "PlayerPersisted"; ++ protected java.util.HashMap spawnChunkMap = new java.util.HashMap<>(); ++ protected java.util.HashMap spawnForcedMap = new java.util.HashMap<>(); ++ public float eyeHeight = this.getDefaultEyeHeight(); ++ public static final net.minecraft.entity.ai.attributes.IAttribute REACH_DISTANCE = new net.minecraft.entity.ai.attributes.RangedAttribute(null, "generic.reachDistance", 5.0D, 0.0D, 1024.0D).setShouldWatch(true); ++ + private static final DataParameter ABSORPTION = EntityDataManager.createKey(EntityPlayer.class, DataSerializers.FLOAT); + private static final DataParameter PLAYER_SCORE = EntityDataManager.createKey(EntityPlayer.class, DataSerializers.VARINT); + protected static final DataParameter PLAYER_MODEL_FLAG = EntityDataManager.createKey(EntityPlayer.class, DataSerializers.BYTE); +@@ -187,6 +192,7 @@ + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.1F); + this.getAttributeMap().registerAttribute(SharedMonsterAttributes.ATTACK_SPEED); + this.getAttributeMap().registerAttribute(SharedMonsterAttributes.LUCK); ++ this.getAttributeMap().registerAttribute(REACH_DISTANCE); + } + + @Override +@@ -203,6 +209,7 @@ + /** Called to update the entity's position/logic. */ + @Override + public void onUpdate() { ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().onPlayerPreTick(this); + this.noClip = this.isSpectator(); + if (this.isSpectator()) { + this.onGround = false; +@@ -221,7 +228,7 @@ + if (!this.world.isRemote) { + if (!this.isInBed()) { + this.wakeUpPlayer(true, true, false); +- } else if (this.world.isDaytime()) { ++ } else if (!net.minecraftforge.event.ForgeEventFactory.fireSleepingTimeCheck(this, this.bedLocation)) { + this.wakeUpPlayer(false, true, true); + } + } +@@ -350,6 +357,7 @@ + this.setSize(f, f1); + } + } ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().onPlayerPostTick(this); + } + + /** Return the amount of time this entity should stay in a portal before being transported. */ +@@ -432,10 +440,11 @@ + this.prevCameraYaw = this.cameraYaw; + this.cameraYaw = 0.0F; + this.addMountedMovementStat(this.posX - d0, this.posY - d1, this.posZ - d2); +- if (this.getRidingEntity() instanceof EntityPig) { ++ ++ if (this.getRidingEntity() instanceof EntityLivingBase && ((EntityLivingBase)this.getRidingEntity()).shouldRiderFaceForward(this)) { + this.rotationPitch = f1; + this.rotationYaw = f; +- this.renderYawOffset = ((EntityPig)this.getRidingEntity()).renderYawOffset; ++ this.renderYawOffset = ((EntityLivingBase)this.getRidingEntity()).renderYawOffset; + } + } + } +@@ -561,10 +570,15 @@ + /** Called when the mob's health reaches 0. */ + @Override + public void onDeath(DamageSource cause) { ++ if (net.minecraftforge.common.ForgeHooks.onLivingDeath(this, cause)) return; + super.onDeath(cause); + this.setSize(0.2F, 0.2F); + this.setPosition(this.posX, this.posY, this.posZ); + this.motionY = 0.1F; ++ ++ captureDrops = true; ++ capturedDrops.clear(); ++ + if ("Notch".equals(this.getName())) { + this.dropItem(new ItemStack(Items.APPLE, 1), true, false); + } +@@ -574,6 +588,9 @@ + this.inventory.dropAllItems(); + } + ++ captureDrops = false; ++ if (!world.isRemote) net.minecraftforge.event.ForgeEventFactory.onPlayerDrops(this, cause, capturedDrops, recentlyHit > 0); ++ + if (cause != null) { + this.motionX = -MathHelper.cos((this.attackedAtYaw + this.rotationYaw) * (float) (Math.PI / 180.0)) * 0.1F; + this.motionZ = -MathHelper.sin((this.attackedAtYaw + this.rotationYaw) * (float) (Math.PI / 180.0)) * 0.1F; +@@ -614,15 +631,16 @@ + /** Drop one item out of the currently selected stack if {@code dropAll} is false. If {@code dropItem} is true the entire stack is dropped. */ + @Nullable + public EntityItem dropItem(boolean dropAll) { +- return this.dropItem( +- this.inventory +- .decrStackSize( +- this.inventory.currentItem, +- dropAll && !this.inventory.getCurrentItem().isEmpty() ? this.inventory.getCurrentItem().getCount() : 1 +- ), +- false, +- true +- ); ++ ItemStack stack = inventory.getCurrentItem(); ++ ++ if (stack.isEmpty()) { ++ return null; ++ } ++ if (stack.getItem().onDroppedByPlayer(stack, this)) { ++ int count = dropAll ? this.inventory.getCurrentItem().getCount() : 1; ++ return net.minecraftforge.common.ForgeHooks.onPlayerTossEvent(this, inventory.decrStackSize(inventory.currentItem, count), true); ++ } ++ return null; + } + + /** +@@ -632,7 +650,7 @@ + */ + @Nullable + public EntityItem dropItem(ItemStack itemStackIn, boolean unused) { +- return this.dropItem(itemStackIn, false, unused); ++ return net.minecraftforge.common.ForgeHooks.onPlayerTossEvent(this, itemStackIn, false); + } + + /** +@@ -689,11 +707,18 @@ + } + + public ItemStack dropItemAndGetStack(EntityItem p_184816_1_) { ++ if (captureDrops) capturedDrops.add(p_184816_1_); ++ else // Forge: Don't indent to keep patch smaller. + this.world.spawnEntity(p_184816_1_); + return p_184816_1_.getItem(); + } + ++ @Deprecated //Use location sensitive version below + public float getDigSpeed(IBlockState state) { ++ return getDigSpeed(state, null); ++ } ++ ++ public float getDigSpeed(IBlockState state, BlockPos pos) { + float f = this.inventory.getDestroySpeed(state); + if (f > 1.0F) { + int i = EnchantmentHelper.getEfficiencyModifier(this); +@@ -735,11 +760,12 @@ + f /= 5.0F; + } + +- return f; ++ f = net.minecraftforge.event.ForgeEventFactory.getBreakSpeed(this, state, f, pos); ++ return (f < 0 ? 0 : f); + } + + public boolean canHarvestBlock(IBlockState state) { +- return this.inventory.canHarvestBlock(state); ++ return net.minecraftforge.event.ForgeEventFactory.doPlayerHarvestCheck(this, state, this.inventory.canHarvestBlock(state)); + } + + public static void registerFixesPlayer(DataFixer fixer) { +@@ -797,6 +823,16 @@ + this.spawnForced = compound.getBoolean("SpawnForced"); + } + ++ NBTTagList spawnlist = null; ++ spawnlist = compound.getTagList("Spawns", 10); ++ for (int i = 0; i < spawnlist.tagCount(); i++) { ++ NBTTagCompound spawndata = (NBTTagCompound)spawnlist.getCompoundTagAt(i); ++ int spawndim = spawndata.getInteger("Dim"); ++ this.spawnChunkMap.put(spawndim, new BlockPos(spawndata.getInteger("SpawnX"), spawndata.getInteger("SpawnY"), spawndata.getInteger("SpawnZ"))); ++ this.spawnForcedMap.put(spawndim, spawndata.getBoolean("SpawnForced")); ++ } ++ this.spawnDimension = compound.getBoolean("HasSpawnDimensionSet") ? compound.getInteger("SpawnDimension") : null; ++ + this.foodStats.readNBT(compound); + this.capabilities.readCapabilitiesFromNBT(compound); + if (compound.hasKey("EnderItems", 9)) { +@@ -827,6 +863,8 @@ + compound.setInteger("XpTotal", this.experienceTotal); + compound.setInteger("XpSeed", this.xpSeed); + compound.setInteger("Score", this.getScore()); ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().getDataFixer().writeVersionData(compound); //Moved down so it doesn't keep missing every MC update. ++ + if (this.spawnPos != null) { + compound.setInteger("SpawnX", this.spawnPos.getX()); + compound.setInteger("SpawnY", this.spawnPos.getY()); +@@ -834,6 +872,26 @@ + compound.setBoolean("SpawnForced", this.spawnForced); + } + ++ NBTTagList spawnlist = new NBTTagList(); ++ for (java.util.Map.Entry entry : this.spawnChunkMap.entrySet()) { ++ BlockPos spawn = entry.getValue(); ++ if (spawn == null) continue; ++ Boolean forced = spawnForcedMap.get(entry.getKey()); ++ if (forced == null) forced = false; ++ NBTTagCompound spawndata = new NBTTagCompound(); ++ spawndata.setInteger("Dim", entry.getKey()); ++ spawndata.setInteger("SpawnX", spawn.getX()); ++ spawndata.setInteger("SpawnY", spawn.getY()); ++ spawndata.setInteger("SpawnZ", spawn.getZ()); ++ spawndata.setBoolean("SpawnForced", forced); ++ spawnlist.appendTag(spawndata); ++ } ++ compound.setTag("Spawns", spawnlist); ++ ++ compound.setBoolean("HasSpawnDimensionSet", this.hasSpawnDimension()); ++ if (this.hasSpawnDimension()) ++ compound.setInteger("SpawnDimension", this.getSpawnDimension()); ++ + this.foodStats.writeNBT(compound); + this.capabilities.writeCapabilitiesToNBT(compound); + compound.setTag("EnderItems", this.enderChest.saveInventoryToNBT()); +@@ -849,6 +907,7 @@ + /** Called when the entity is attacked. */ + @Override + public boolean attackEntityFrom(DamageSource source, float amount) { ++ if (!net.minecraftforge.common.ForgeHooks.onPlayerAttack(this, source, amount)) return false; + if (this.isEntityInvulnerable(source)) { + return false; + } +@@ -887,7 +946,8 @@ + @Override + protected void blockUsingShield(EntityLivingBase p_190629_1_) { + super.blockUsingShield(p_190629_1_); +- if (p_190629_1_.getHeldItemMainhand().getItem() instanceof ItemAxe) { ++ ++ if (p_190629_1_.getHeldItemMainhand().getItem().canDisableShield(p_190629_1_.getHeldItemMainhand(), this.getActiveItemStack(), this, p_190629_1_)) { + this.disableShield(true); + } + } +@@ -909,11 +969,14 @@ + + @Override + protected void damageShield(float damage) { +- if (damage >= 3.0F && this.activeItemStack.getItem() == Items.SHIELD) { ++ if (damage >= 3.0F && this.activeItemStack.getItem().isShield(this.activeItemStack, this)) { ++ ItemStack copyBeforeUse = this.activeItemStack.copy(); + int i = 1 + MathHelper.floor(damage); + this.activeItemStack.damageItem(i, this); + if (this.activeItemStack.isEmpty()) { + EnumHand enumhand = this.getActiveHand(); ++ net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(this, copyBeforeUse, enumhand); ++ + if (enumhand == EnumHand.MAIN_HAND) { + this.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, ItemStack.EMPTY); + } else { +@@ -943,11 +1006,15 @@ + @Override + protected void damageEntity(DamageSource damageSrc, float damageAmount) { + if (!this.isEntityInvulnerable(damageSrc)) { +- damageAmount = this.applyArmorCalculations(damageSrc, damageAmount); ++ damageAmount = net.minecraftforge.common.ForgeHooks.onLivingHurt(this, damageSrc, damageAmount); ++ if (damageAmount <= 0) return; ++ damageAmount = net.minecraftforge.common.ISpecialArmor.ArmorProperties.applyArmor(this, inventory.armorInventory, damageSrc, damageAmount); ++ if (damageAmount <= 0) return; + damageAmount = this.applyPotionDamageCalculations(damageSrc, damageAmount); + float f = damageAmount; + damageAmount = Math.max(damageAmount - this.getAbsorptionAmount(), 0.0F); + this.setAbsorptionAmount(this.getAbsorptionAmount() - (f - damageAmount)); ++ damageAmount = net.minecraftforge.common.ForgeHooks.onLivingDamage(this, damageSrc, damageAmount); + if (damageAmount != 0.0F) { + this.addExhaustion(damageSrc.getHungerDamage()); + float f1 = this.getHealth(); +@@ -996,6 +1063,8 @@ + + return EnumActionResult.PASS; + } else { ++ EnumActionResult cancelResult = net.minecraftforge.common.ForgeHooks.onInteractEntity(this, entityToInteractOn, hand); ++ if (cancelResult != null) return cancelResult; + ItemStack itemstack = this.getHeldItem(hand); + ItemStack itemstack1 = itemstack.isEmpty() ? ItemStack.EMPTY : itemstack.copy(); + if (entityToInteractOn.processInitialInteract(this, hand)) { +@@ -1004,7 +1073,9 @@ + { + itemstack.setCount(itemstack1.getCount()); + } +- ++ if (!this.capabilities.isCreativeMode && itemstack.isEmpty()) { ++ net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(this, itemstack1, hand); ++ } + return EnumActionResult.SUCCESS; + } else { + if (!itemstack.isEmpty() && entityToInteractOn instanceof EntityLivingBase) { +@@ -1014,6 +1085,7 @@ + + if (itemstack.interactWithEntity(this, (EntityLivingBase)entityToInteractOn, hand)) { + if (itemstack.isEmpty() && !this.capabilities.isCreativeMode) { ++ net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(this, itemstack1, hand); + this.setHeldItem(hand, ItemStack.EMPTY); + } + +@@ -1041,6 +1113,7 @@ + + /** Attacks for the player the targeted entity with the currently equipped item. The equipped item has hitEntity called on it. Args: targetEntity */ + public void attackTargetEntityWithCurrentItem(Entity targetEntity) { ++ if (!net.minecraftforge.common.ForgeHooks.onPlayerAttackTarget(this, targetEntity)) return; + if (targetEntity.canBeAttackedWithItem()) { + if (!targetEntity.hitByEntity(this)) { + float f = (float)this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).getAttributeValue(); +@@ -1085,8 +1158,11 @@ + && !this.isRiding() + && targetEntity instanceof EntityLivingBase; + flag2 = flag2 && !this.isSprinting(); ++ ++ net.minecraftforge.event.entity.player.CriticalHitEvent hitResult = net.minecraftforge.common.ForgeHooks.getCriticalHit(this, targetEntity, flag2, flag2 ? 1.5F : 1.0F); ++ flag2 = hitResult != null; + if (flag2) { +- f *= 1.5F; ++ f *= hitResult.getDamageModifier(); + } + + f += f1; +@@ -1241,8 +1317,10 @@ + } + + if (!itemstack1.isEmpty() && entity instanceof EntityLivingBase) { ++ ItemStack beforeHitCopy = itemstack1.copy(); + itemstack1.hitEntity((EntityLivingBase)entity, this); + if (itemstack1.isEmpty()) { ++ net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(this, beforeHitCopy, EnumHand.MAIN_HAND); + this.setHeldItem(EnumHand.MAIN_HAND, ItemStack.EMPTY); + } + } +@@ -1300,7 +1378,7 @@ + } + + if (this.rand.nextFloat() < f) { +- this.getCooldownTracker().setCooldown(Items.SHIELD, 100); ++ this.getCooldownTracker().setCooldown(this.getActiveItemStack().getItem(), 100); + this.resetActiveHand(); + this.world.setEntityState(this, (byte)30); + } +@@ -1363,7 +1441,12 @@ + } + + public EntityPlayer.SleepResult trySleep(BlockPos bedLocation) { +- EnumFacing enumfacing = this.world.getBlockState(bedLocation).getValue(BlockHorizontal.FACING); ++ EntityPlayer.SleepResult ret = net.minecraftforge.event.ForgeEventFactory.onPlayerSleepInBed(this, bedLocation); ++ if (ret != null) return ret; ++ final IBlockState state = this.world.isBlockLoaded(bedLocation) ? this.world.getBlockState(bedLocation) : null; ++ final boolean isBed = state != null && state.getBlock().isBed(state, this.world, bedLocation, this); ++ final EnumFacing enumfacing = isBed && state.getBlock() instanceof BlockHorizontal ? (EnumFacing)state.getValue(BlockHorizontal.FACING) : null; ++ + if (!this.world.isRemote) { + if (this.isPlayerSleeping() || !this.isEntityAlive()) { + return EntityPlayer.SleepResult.OTHER_PROBLEM; +@@ -1373,7 +1456,7 @@ + return EntityPlayer.SleepResult.NOT_POSSIBLE_HERE; + } + +- if (this.world.isDaytime()) { ++ if (!net.minecraftforge.event.ForgeEventFactory.fireSleepingTimeCheck(this, bedLocation)) { + return EntityPlayer.SleepResult.NOT_POSSIBLE_NOW; + } + +@@ -1407,7 +1490,8 @@ + + this.spawnShoulderEntities(); + this.setSize(0.2F, 0.2F); +- if (this.world.isBlockLoaded(bedLocation)) { ++ ++ if (enumfacing != null) { + float f1 = 0.5F + enumfacing.getXOffset() * 0.4F; + float f = 0.5F + enumfacing.getZOffset() * 0.4F; + this.setRenderOffsetForSleep(enumfacing); +@@ -1430,6 +1514,10 @@ + } + + private boolean bedInRange(BlockPos p_190774_1_, EnumFacing p_190774_2_) { ++ if (p_190774_2_ == null) { ++ return false; ++ } ++ + if (Math.abs(this.posX - p_190774_1_.getX()) <= 3.0 + && Math.abs(this.posY - p_190774_1_.getY()) <= 2.0 + && Math.abs(this.posZ - p_190774_1_.getZ()) <= 3.0) { +@@ -1449,16 +1537,21 @@ + + /** Wake up the player if they're sleeping. */ + public void wakeUpPlayer(boolean immediately, boolean updateWorldFlag, boolean setSpawn) { ++ net.minecraftforge.event.ForgeEventFactory.onPlayerWakeup(this, immediately, updateWorldFlag, setSpawn); + this.setSize(0.6F, 1.8F); +- IBlockState iblockstate = this.world.getBlockState(this.bedLocation); +- if (this.bedLocation != null && iblockstate.getBlock() == Blocks.BED) { +- this.world.setBlockState(this.bedLocation, iblockstate.withProperty(BlockBed.OCCUPIED, false), 4); +- BlockPos blockpos = BlockBed.getSafeExitLocation(this.world, this.bedLocation, 0); ++ IBlockState iblockstate = this.bedLocation == null ? null : this.world.getBlockState(this.bedLocation); ++ ++ if (this.bedLocation != null && iblockstate.getBlock().isBed(iblockstate, world, bedLocation, this)) { ++ iblockstate.getBlock().setBedOccupied(world, bedLocation, this, false); ++ BlockPos blockpos = iblockstate.getBlock().getBedSpawnPosition(iblockstate, world, bedLocation, this); ++ + if (blockpos == null) { + blockpos = this.bedLocation.up(); + } + + this.setPosition(blockpos.getX() + 0.5F, blockpos.getY() + 0.1F, blockpos.getZ() + 0.5F); ++ } else { ++ setSpawn = false; + } + + this.sleeping = false; +@@ -1473,14 +1566,16 @@ + } + + private boolean isInBed() { +- return this.world.getBlockState(this.bedLocation).getBlock() == Blocks.BED; ++ return net.minecraftforge.event.ForgeEventFactory.fireSleepingLocationCheck(this, this.bedLocation); + } + + /** Return null if bed is invalid */ + @Nullable + public static BlockPos getBedSpawnLocation(World worldIn, BlockPos bedLocation, boolean forceSpawn) { +- Block block = worldIn.getBlockState(bedLocation).getBlock(); +- if (block != Blocks.BED) { ++ IBlockState state = worldIn.getBlockState(bedLocation); ++ Block block = state.getBlock(); ++ ++ if (!block.isBed(state, worldIn, bedLocation, null)) { + if (!forceSpawn) { + return null; + } +@@ -1489,15 +1584,17 @@ + boolean flag1 = worldIn.getBlockState(bedLocation.up()).getBlock().canSpawnInBlock(); + return flag && flag1 ? bedLocation : null; + } else { +- return BlockBed.getSafeExitLocation(worldIn, bedLocation, 0); ++ return block.getBedSpawnPosition(state, worldIn, bedLocation, null); + } + } + + /** Returns the orientation of the bed in degrees. */ + @SideOnly(Side.CLIENT) + public float getBedOrientationInDegrees() { +- if (this.bedLocation != null) { +- EnumFacing enumfacing = this.world.getBlockState(this.bedLocation).getValue(BlockHorizontal.FACING); ++ IBlockState state = this.bedLocation == null ? null : this.world.getBlockState(bedLocation); ++ if (state != null && state.getBlock().isBed(state, world, bedLocation, this)) { ++ EnumFacing enumfacing = state.getBlock().getBedDirection(state, world, bedLocation); ++ + switch (enumfacing) { + case SOUTH: + return 90.0F; +@@ -1533,14 +1630,21 @@ + } + + public BlockPos getBedLocation() { +- return this.spawnPos; ++ return getBedLocation(this.dimension); + } + ++ @Deprecated // Use dimension-sensitive version. + public boolean isSpawnForced() { +- return this.spawnForced; ++ return isSpawnForced(this.dimension); + } + + public void setSpawnPoint(BlockPos pos, boolean forced) { ++ if(net.minecraftforge.event.ForgeEventFactory.onPlayerSpawnSet(this, pos, forced)) return; ++ if (this.dimension != 0) { ++ setSpawnChunk(pos, forced, this.dimension); ++ return; ++ } ++ + if (pos != null) { + this.spawnPos = pos; + this.spawnForced = forced; +@@ -1681,6 +1785,8 @@ + } + + super.fall(distance, damageMultiplier); ++ } else { ++ net.minecraftforge.event.ForgeEventFactory.onPlayerFall(this, distance, damageMultiplier); + } + } + +@@ -2018,7 +2124,10 @@ + */ + @Override + public ITextComponent getDisplayName() { +- ITextComponent itextcomponent = new TextComponentString(ScorePlayerTeam.formatPlayerName(this.getTeam(), this.getName())); ++ ITextComponent itextcomponent = new TextComponentString(""); ++ if (!prefixes.isEmpty()) for (ITextComponent prefix : prefixes) itextcomponent.appendSibling(prefix); ++ itextcomponent.appendSibling(new TextComponentString(ScorePlayerTeam.formatPlayerName(this.getTeam(), this.getDisplayNameString()))); ++ if (!suffixes.isEmpty()) for (ITextComponent suffix : suffixes) itextcomponent.appendSibling(suffix); + itextcomponent.getStyle().setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/msg " + this.getName() + " ")); + itextcomponent.getStyle().setHoverEvent(this.getHoverEvent()); + itextcomponent.getStyle().setInsertion(this.getName()); +@@ -2027,7 +2136,8 @@ + + @Override + public float getEyeHeight() { +- float f = 1.62F; ++ float f = eyeHeight; ++ + if (this.isPlayerSleeping()) { + f = 0.2F; + } else if (this.isSneaking() || this.height == 1.65F) { +@@ -2213,6 +2323,150 @@ + return this.capabilities.isCreativeMode && this.canUseCommand(2, ""); + } + ++ /** ++ * Opens a GUI with this player, uses FML's IGuiHandler system. ++ * Allows for extension by modders. ++ * ++ * @param mod The mod trying to open a GUI ++ * @param modGuiId GUI ID ++ * @param world Current World ++ * @param x Passed directly to IGuiHandler, data meaningless Typically world X position ++ * @param y Passed directly to IGuiHandler, data meaningless Typically world Y position ++ * @param z Passed directly to IGuiHandler, data meaningless Typically world Z position ++ */ ++ public void openGui(Object mod, int modGuiId, World world, int x, int y, int z) { ++ net.minecraftforge.fml.common.network.internal.FMLNetworkHandler.openGui(this, mod, modGuiId, world, x, y, z); ++ } ++ ++ ++ /* ======================================== FORGE START =====================================*/ ++ /** ++ * A dimension aware version of getBedLocation. ++ * @param dimension The dimension to get the bed spawn for ++ * @return The player specific spawn location for the dimension. May be null. ++ */ ++ public BlockPos getBedLocation(int dimension) { ++ return dimension == 0 ? spawnPos : spawnChunkMap.get(dimension); ++ } ++ ++ /** ++ * A dimension aware version of isSpawnForced. ++ * Noramally isSpawnForced is used to determine if the respawn system should check for a bed or not. ++ * This just extends that to be dimension aware. ++ * @param dimension The dimension to get whether to check for a bed before spawning for ++ * @return The player specific spawn location for the dimension. May be null. ++ */ ++ public boolean isSpawnForced(int dimension) { ++ if (dimension == 0) return this.spawnForced; ++ Boolean forced = this.spawnForcedMap.get(dimension); ++ return forced == null ? false : forced; ++ } ++ ++ /** ++ * A dimension aware version of setSpawnChunk. ++ * This functions identically, but allows you to specify which dimension to affect, rather than affecting the player's current dimension. ++ * @param pos The spawn point to set as the player-specific spawn point for the dimension ++ * @param forced Whether or not the respawn code should check for a bed at this location (true means it won't check for a bed) ++ * @param dimension Which dimension to apply the player-specific respawn point to ++ */ ++ public void setSpawnChunk(BlockPos pos, boolean forced, int dimension) { ++ if (dimension == 0) { ++ if (pos != null) { ++ spawnPos = pos; ++ spawnForced = forced; ++ } else { ++ spawnPos = null; ++ spawnForced = false; ++ } ++ return; ++ } ++ ++ if (pos != null) { ++ spawnChunkMap.put(dimension, pos); ++ spawnForcedMap.put(dimension, forced); ++ } else { ++ spawnChunkMap.remove(dimension); ++ spawnForcedMap.remove(dimension); ++ } ++ } ++ ++ private String displayname; ++ ++ /** ++ * Returns the default eye height of the player ++ * @return player default eye height ++ */ ++ public float getDefaultEyeHeight() { ++ return 1.62F; ++ } ++ ++ /** ++ * Get the currently computed display name, cached for efficiency. ++ * @return the current display name ++ */ ++ public String getDisplayNameString() { ++ if(this.displayname == null) { ++ this.displayname = net.minecraftforge.event.ForgeEventFactory.getPlayerDisplayName(this, this.getName()); ++ } ++ return this.displayname; ++ } ++ ++ /** ++ * Force the displayed name to refresh ++ */ ++ public void refreshDisplayName() { ++ this.displayname = net.minecraftforge.event.ForgeEventFactory.getPlayerDisplayName(this, this.getName()); ++ } ++ ++ private final java.util.Collection prefixes = new java.util.LinkedList(); ++ private final java.util.Collection suffixes = new java.util.LinkedList(); ++ ++ /** ++ * Add a prefix to the player's username in chat ++ * @param prefix The prefix ++ */ ++ public void addPrefix(ITextComponent prefix) { prefixes.add(prefix); } ++ ++ /** ++ * Add a suffix to the player's username in chat ++ * @param suffix The suffix ++ */ ++ public void addSuffix(ITextComponent suffix) { suffixes.add(suffix); } ++ ++ public java.util.Collection getPrefixes() { return this.prefixes; } ++ public java.util.Collection getSuffixes() { return this.suffixes; } ++ ++ private final net.minecraftforge.items.IItemHandler playerMainHandler = new net.minecraftforge.items.wrapper.PlayerMainInvWrapper(inventory); ++ private final net.minecraftforge.items.IItemHandler playerEquipmentHandler = new net.minecraftforge.items.wrapper.CombinedInvWrapper( ++ new net.minecraftforge.items.wrapper.PlayerArmorInvWrapper(inventory), ++ new net.minecraftforge.items.wrapper.PlayerOffhandInvWrapper(inventory)); ++ private final net.minecraftforge.items.IItemHandler playerJoinedHandler = new net.minecraftforge.items.wrapper.PlayerInvWrapper(inventory); ++ ++ @SuppressWarnings("unchecked") ++ @Override ++ @Nullable ++ public T getCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable net.minecraft.util.EnumFacing facing) { ++ if (capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { ++ if (facing == null) return (T) playerJoinedHandler; ++ else if (facing.getAxis().isVertical()) return (T) playerMainHandler; ++ else if (facing.getAxis().isHorizontal()) return (T) playerEquipmentHandler; ++ } ++ return super.getCapability(capability, facing); ++ } ++ ++ @Override ++ public boolean hasCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable net.minecraft.util.EnumFacing facing) { ++ return capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY || super.hasCapability(capability, facing); ++ } ++ ++ @Nullable ++ private Integer spawnDimension; ++ public boolean hasSpawnDimension() { return spawnDimension != null; } ++ public int getSpawnDimension() { return spawnDimension != null ? spawnDimension : 0; } ++ public void setSpawnDimension(@Nullable Integer dimension) { this.spawnDimension = dimension; } ++ ++ /* ======================================== FORGE END =====================================*/ ++ + public enum EnumChatVisibility { + FULL(0, "options.chat.visibility.full"), + SYSTEM(1, "options.chat.visibility.system"), diff --git a/module/minecraft/patches/net/minecraft/entity/player/EntityPlayerMP.java.patch b/module/minecraft/patches/net/minecraft/entity/player/EntityPlayerMP.java.patch new file mode 100644 index 000000000..2630e1c4b --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/player/EntityPlayerMP.java.patch @@ -0,0 +1,143 @@ +--- original/net/minecraft/entity/player/EntityPlayerMP.java ++++ modified/net/minecraft/entity/player/EntityPlayerMP.java +@@ -173,8 +173,9 @@ + super(worldIn, profile); + interactionManagerIn.player = this; + this.interactionManager = interactionManagerIn; +- BlockPos blockpos = worldIn.getSpawnPoint(); +- if (worldIn.provider.hasSkyLight() && worldIn.getWorldInfo().getGameType() != GameType.ADVENTURE) { ++ BlockPos blockpos = worldIn.provider.getRandomizedSpawnPoint(); ++ ++ if (false && worldIn.provider.hasSkyLight() && worldIn.getWorldInfo().getGameType() != GameType.ADVENTURE) { + int i = Math.max(0, server.getSpawnRadius(worldIn)); + int j = MathHelper.floor(worldIn.getWorldBorder().getClosestDistance(blockpos.getX(), blockpos.getZ())); + if (j < i) { +@@ -319,7 +320,8 @@ + } + + this.openContainer.detectAndSendChanges(); +- if (!this.world.isRemote && !this.openContainer.canInteractWith(this)) { ++ ++ if (!this.world.isRemote && this.openContainer != null && !this.openContainer.canInteractWith(this)) { + this.closeScreen(); + this.openContainer = this.inventoryContainer; + } +@@ -439,6 +441,7 @@ + /** Called when the mob's health reaches 0. */ + @Override + public void onDeath(DamageSource cause) { ++ if (net.minecraftforge.common.ForgeHooks.onLivingDeath(this, cause)) return; + boolean flag = this.world.getGameRules().getBoolean("showDeathMessages"); + this.connection.sendPacket(new SPacketCombatEvent(this.getCombatTracker(), SPacketCombatEvent.Event.ENTITY_DIED, flag)); + if (flag) { +@@ -454,8 +457,18 @@ + + this.spawnShoulderEntities(); + if (!this.world.getGameRules().getBoolean("keepInventory") && !this.isSpectator()) { ++ captureDrops = true; ++ capturedDrops.clear(); + this.destroyVanishingCursedItems(); + this.inventory.dropAllItems(); ++ ++ captureDrops = false; ++ net.minecraftforge.event.entity.player.PlayerDropsEvent event = new net.minecraftforge.event.entity.player.PlayerDropsEvent(this, cause, capturedDrops, recentlyHit > 0); ++ if (!net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event)) { ++ for (net.minecraft.entity.item.EntityItem item : capturedDrops) { ++ this.world.spawnEntity(item); ++ } ++ } + } + + for (ScoreObjective scoreobjective : this.world.getScoreboard().getObjectivesFromCriteria(IScoreCriteria.DEATH_COUNT)) { +@@ -568,7 +581,8 @@ + + @Nullable + @Override +- public Entity changeDimension(int dimensionIn) { ++ public Entity changeDimension(int dimensionIn, net.minecraftforge.common.util.ITeleporter teleporter) { ++ if (!net.minecraftforge.common.ForgeHooks.onTravelToDimension(this, dimensionIn)) return this; + this.invulnerableDimensionChange = true; + if (this.dimension == 0 && dimensionIn == -1) { + this.enteredNetherPosition = new Vec3d(this.posX, this.posY, this.posZ); +@@ -576,7 +590,7 @@ + this.enteredNetherPosition = null; + } + +- if (this.dimension == 1 && dimensionIn == 1) { ++ if (this.dimension == 1 && dimensionIn == 1 && teleporter.isVanilla()) { + this.world.removeEntity(this); + if (!this.queuedEndExit) { + this.queuedEndExit = true; +@@ -590,7 +604,7 @@ + dimensionIn = 1; + } + +- this.server.getPlayerList().changePlayerDimension(this, dimensionIn); ++ this.server.getPlayerList().transferPlayerToDimension(this, dimensionIn, teleporter); + this.connection.sendPacket(new SPacketEffect(1032, BlockPos.ORIGIN, 0, false)); + this.lastExperience = -1; + this.lastHealth = -1.0F; +@@ -702,7 +716,8 @@ + int k = MathHelper.floor(this.posZ); + BlockPos blockpos = new BlockPos(i, j, k); + IBlockState iblockstate = this.world.getBlockState(blockpos); +- if (iblockstate.getMaterial() == Material.AIR) { ++ ++ if (iblockstate.getBlock().isAir(iblockstate, this.world, blockpos)) { + BlockPos blockpos1 = blockpos.down(); + IBlockState iblockstate1 = this.world.getBlockState(blockpos1); + Block block = iblockstate1.getBlock(); +@@ -736,6 +751,7 @@ + this.openContainer = guiOwner.createContainer(this.inventory, this); + this.openContainer.windowId = this.currentWindowId; + this.openContainer.addListener(this); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.player.PlayerContainerEvent.Open(this, this.openContainer)); + } + } + +@@ -781,6 +797,7 @@ + + this.openContainer.windowId = this.currentWindowId; + this.openContainer.addListener(this); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.player.PlayerContainerEvent.Open(this, this.openContainer)); + } + } + +@@ -790,6 +807,7 @@ + this.openContainer = new ContainerMerchant(this.inventory, villager, this.world); + this.openContainer.windowId = this.currentWindowId; + this.openContainer.addListener(this); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.player.PlayerContainerEvent.Open(this, this.openContainer)); + IInventory iinventory = ((ContainerMerchant)this.openContainer).getMerchantInventory(); + ITextComponent itextcomponent = villager.getDisplayName(); + this.connection.sendPacket(new SPacketOpenWindow(this.currentWindowId, "minecraft:villager", itextcomponent, iinventory.getSizeInventory())); +@@ -891,6 +909,7 @@ + /** Closes the container the player currently has open. */ + public void closeContainer() { + this.openContainer.onContainerClosed(this); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.player.PlayerContainerEvent.Close(this, this.openContainer)); + this.openContainer = this.inventoryContainer; + } + +@@ -1016,6 +1035,21 @@ + this.enteredNetherPosition = that.enteredNetherPosition; + this.setLeftShoulderEntity(that.getLeftShoulderEntity()); + this.setRightShoulderEntity(that.getRightShoulderEntity()); ++ ++ this.spawnChunkMap = that.spawnChunkMap; ++ this.spawnForcedMap = that.spawnForcedMap; ++ if(that.dimension != 0) { ++ this.spawnPos = that.spawnPos; ++ this.spawnForced = that.spawnForced; ++ } ++ ++ //Copy over a section of the Entity Data from the old player. ++ //Allows mods to specify data that persists after players respawn. ++ NBTTagCompound old = that.getEntityData(); ++ if (old.hasKey(PERSISTED_NBT_TAG)) { ++ getEntityData().setTag(PERSISTED_NBT_TAG, old.getCompoundTag(PERSISTED_NBT_TAG)); ++ } ++ net.minecraftforge.event.ForgeEventFactory.onPlayerClone(this, that, !keepEverything); + } + + @Override diff --git a/module/minecraft/patches/net/minecraft/entity/player/InventoryPlayer.java.patch b/module/minecraft/patches/net/minecraft/entity/player/InventoryPlayer.java.patch new file mode 100644 index 000000000..39790ec5d --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/player/InventoryPlayer.java.patch @@ -0,0 +1,35 @@ +--- original/net/minecraft/entity/player/InventoryPlayer.java ++++ modified/net/minecraft/entity/player/InventoryPlayer.java +@@ -258,7 +258,8 @@ + int i = p_191973_2_.getCount(); + ItemStack itemstack = this.getStackInSlot(p_191973_1_); + if (itemstack.isEmpty()) { +- itemstack = new ItemStack(item, 0, p_191973_2_.getMetadata()); ++ itemstack = p_191973_2_.copy(); // Forge: Replace Item clone above to preserve item capabilities when picking the item up. ++ itemstack.setCount(0); + if (p_191973_2_.hasTagCompound()) { + itemstack.setTagCompound(p_191973_2_.getTagCompound().copy()); + } +@@ -313,6 +314,13 @@ + } + } + } ++ for (ItemStack is : armorInventory) // FORGE: Tick armor on animation ticks ++ { ++ if (!is.isEmpty()) ++ { ++ is.getItem().onArmorTick(player.world, player, is); ++ } ++ } + } + + /** Adds the item stack to the inventory, returns false if it is impossible. */ +@@ -365,6 +373,8 @@ + CrashReportCategory crashreportcategory = crashreport.makeCategory("Item being added"); + crashreportcategory.addCrashSection("Item ID", Item.getIdFromItem(p_191971_2_.getItem())); + crashreportcategory.addCrashSection("Item data", p_191971_2_.getMetadata()); ++ crashreportcategory.addDetail("Registry Name", () -> String.valueOf(p_191971_2_.getItem().getRegistryName())); ++ crashreportcategory.addDetail("Item Class", () -> p_191971_2_.getItem().getClass().getName()); + crashreportcategory.addDetail("Item name", new ICrashReportDetail() { + public String call() throws Exception { + return p_191971_2_.getDisplayName(); diff --git a/module/minecraft/patches/net/minecraft/entity/projectile/EntityArrow.java.patch b/module/minecraft/patches/net/minecraft/entity/projectile/EntityArrow.java.patch new file mode 100644 index 000000000..af7a949c3 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/projectile/EntityArrow.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/entity/projectile/EntityArrow.java ++++ modified/net/minecraft/entity/projectile/EntityArrow.java +@@ -235,7 +235,7 @@ + } + } + +- if (raytraceresult != null) { ++ if (raytraceresult != null && !net.minecraftforge.event.ForgeEventFactory.onProjectileImpact(this, raytraceresult)) { + this.onHit(raytraceresult); + } + diff --git a/module/minecraft/patches/net/minecraft/entity/projectile/EntityFireball.java.patch b/module/minecraft/patches/net/minecraft/entity/projectile/EntityFireball.java.patch new file mode 100644 index 000000000..0036448b6 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/projectile/EntityFireball.java.patch @@ -0,0 +1,12 @@ +--- original/net/minecraft/entity/projectile/EntityFireball.java ++++ modified/net/minecraft/entity/projectile/EntityFireball.java +@@ -86,7 +86,8 @@ + + this.ticksInAir++; + RayTraceResult raytraceresult = ProjectileHelper.forwardsRaycast(this, true, this.ticksInAir >= 25, this.shootingEntity); +- if (raytraceresult != null) { ++ ++ if (raytraceresult != null && !net.minecraftforge.event.ForgeEventFactory.onProjectileImpact(this, raytraceresult)) { + this.onImpact(raytraceresult); + } + diff --git a/module/minecraft/patches/net/minecraft/entity/projectile/EntityFishHook.java.patch b/module/minecraft/patches/net/minecraft/entity/projectile/EntityFishHook.java.patch new file mode 100644 index 000000000..21662e320 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/projectile/EntityFishHook.java.patch @@ -0,0 +1,77 @@ +--- original/net/minecraft/entity/projectile/EntityFishHook.java ++++ modified/net/minecraft/entity/projectile/EntityFishHook.java +@@ -240,8 +240,9 @@ + private boolean shouldStopFishing() { + ItemStack itemstack = this.angler.getHeldItemMainhand(); + ItemStack itemstack1 = this.angler.getHeldItemOffhand(); +- boolean flag = itemstack.getItem() == Items.FISHING_ROD; +- boolean flag1 = itemstack1.getItem() == Items.FISHING_ROD; ++ boolean flag = itemstack.getItem() instanceof net.minecraft.item.ItemFishingRod; ++ boolean flag1 = itemstack1.getItem() instanceof net.minecraft.item.ItemFishingRod; ++ + if (!this.angler.isDead && this.angler.isEntityAlive() && (flag || flag1) && !(this.getDistanceSq(this.angler) > 1024.0)) { + return false; + } +@@ -354,8 +355,9 @@ + double d0 = this.posX + f1 * this.ticksCatchableDelay * 0.1F; + double d1 = MathHelper.floor(this.getEntityBoundingBox().minY) + 1.0F; + double d2 = this.posZ + f2 * this.ticksCatchableDelay * 0.1F; +- Block block = worldserver.getBlockState(new BlockPos(d0, d1 - 1.0, d2)).getBlock(); +- if (block == Blocks.WATER || block == Blocks.FLOWING_WATER) { ++ IBlockState state = worldserver.getBlockState(new BlockPos(d0, d1 - 1.0, d2)); ++ ++ if (state.getMaterial() == Material.WATER) { + if (this.rand.nextFloat() < 0.15F) { + worldserver.spawnParticle(EnumParticleTypes.WATER_BUBBLE, d0, d1 - 0.1F, d2, 1, f1, 0.1, f2, 0.0); + } +@@ -410,8 +412,9 @@ + double d4 = this.posX + MathHelper.sin(f6) * f7 * 0.1F; + double d5 = MathHelper.floor(this.getEntityBoundingBox().minY) + 1.0F; + double d6 = this.posZ + MathHelper.cos(f6) * f7 * 0.1F; +- Block block1 = worldserver.getBlockState(new BlockPos((int)d4, (int)d5 - 1, (int)d6)).getBlock(); +- if (block1 == Blocks.WATER || block1 == Blocks.FLOWING_WATER) { ++ IBlockState state = worldserver.getBlockState(new BlockPos((int) d4, (int) d5 - 1, (int) d6)); ++ ++ if (state.getMaterial() == Material.WATER) { + worldserver.spawnParticle(EnumParticleTypes.WATER_SPLASH, d4, d5, d6, 2 + this.rand.nextInt(2), 0.1F, 0.0, 0.1F, 0.0); + } + } +@@ -443,18 +446,24 @@ + public int handleHookRetraction() { + if (!this.world.isRemote && this.angler != null) { + int i = 0; ++ ++ net.minecraftforge.event.entity.player.ItemFishedEvent event = null; + if (this.caughtEntity != null) { + this.bringInHookedEntity(); + this.world.setEntityState(this, (byte)31); + i = this.caughtEntity instanceof EntityItem ? 3 : 5; + } else if (this.ticksCatchable > 0) { + LootContext.Builder lootcontext$builder = new LootContext.Builder((WorldServer)this.world); +- lootcontext$builder.withLuck(this.luck + this.angler.getLuck()); ++ lootcontext$builder.withLuck((float)this.luck + this.angler.getLuck()).withPlayer(this.angler).withLootedEntity(this); // Forge: add player & looted entity to LootContext ++ List result = this.world.getLootTableManager().getLootTableFromLocation(LootTableList.GAMEPLAY_FISHING).generateLootForPools(this.rand, lootcontext$builder.build()); ++ event = new net.minecraftforge.event.entity.player.ItemFishedEvent(result, this.inGround ? 2 : 1, this); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event); ++ if (event.isCanceled()) { ++ this.setDead(); ++ return event.getRodDamage(); ++ } + +- for (ItemStack itemstack : this.world +- .getLootTableManager() +- .getLootTableFromLocation(LootTableList.GAMEPLAY_FISHING) +- .generateLootForPools(this.rand, lootcontext$builder.build())) { ++ for (ItemStack itemstack : result) { + EntityItem entityitem = new EntityItem(this.world, this.posX, this.posY, this.posZ, itemstack); + double d0 = this.angler.posX - this.posX; + double d1 = this.angler.posY - this.posY; +@@ -490,7 +499,7 @@ + } + + this.setDead(); +- return i; ++ return event == null ? i : event.getRodDamage(); + } else { + return 0; + } diff --git a/module/minecraft/patches/net/minecraft/entity/projectile/EntityLargeFireball.java.patch b/module/minecraft/patches/net/minecraft/entity/projectile/EntityLargeFireball.java.patch new file mode 100644 index 000000000..126b01eb2 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/projectile/EntityLargeFireball.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/entity/projectile/EntityLargeFireball.java ++++ modified/net/minecraft/entity/projectile/EntityLargeFireball.java +@@ -36,7 +36,7 @@ + this.applyEnchantments(this.shootingEntity, result.entityHit); + } + +- boolean flag = this.world.getGameRules().getBoolean("mobGriefing"); ++ boolean flag = net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.world, this.shootingEntity); + this.world.newExplosion(null, this.posX, this.posY, this.posZ, this.explosionPower, flag, flag); + this.setDead(); + } diff --git a/module/minecraft/patches/net/minecraft/entity/projectile/EntityLlamaSpit.java.patch b/module/minecraft/patches/net/minecraft/entity/projectile/EntityLlamaSpit.java.patch new file mode 100644 index 000000000..69c894415 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/projectile/EntityLlamaSpit.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/entity/projectile/EntityLlamaSpit.java ++++ modified/net/minecraft/entity/projectile/EntityLlamaSpit.java +@@ -80,7 +80,7 @@ + raytraceresult = new RayTraceResult(entity); + } + +- if (raytraceresult != null) { ++ if (raytraceresult != null && !net.minecraftforge.event.ForgeEventFactory.onProjectileImpact(this, raytraceresult)) { + this.onHit(raytraceresult); + } + diff --git a/module/minecraft/patches/net/minecraft/entity/projectile/EntityShulkerBullet.java.patch b/module/minecraft/patches/net/minecraft/entity/projectile/EntityShulkerBullet.java.patch new file mode 100644 index 000000000..21d41642e --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/projectile/EntityShulkerBullet.java.patch @@ -0,0 +1,12 @@ +--- original/net/minecraft/entity/projectile/EntityShulkerBullet.java ++++ modified/net/minecraft/entity/projectile/EntityShulkerBullet.java +@@ -268,7 +268,8 @@ + } + + RayTraceResult raytraceresult = ProjectileHelper.forwardsRaycast(this, true, false, this.owner); +- if (raytraceresult != null) { ++ ++ if (raytraceresult != null && !net.minecraftforge.event.ForgeEventFactory.onProjectileImpact(this, raytraceresult)) { + this.bulletHit(raytraceresult); + } + } diff --git a/module/minecraft/patches/net/minecraft/entity/projectile/EntitySmallFireball.java.patch b/module/minecraft/patches/net/minecraft/entity/projectile/EntitySmallFireball.java.patch new file mode 100644 index 000000000..2bbc958b7 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/projectile/EntitySmallFireball.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/entity/projectile/EntitySmallFireball.java ++++ modified/net/minecraft/entity/projectile/EntitySmallFireball.java +@@ -46,7 +46,7 @@ + } else { + boolean flag1 = true; + if (this.shootingEntity != null && this.shootingEntity instanceof EntityLiving) { +- flag1 = this.world.getGameRules().getBoolean("mobGriefing"); ++ flag1 = net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.world, this.shootingEntity); + } + + if (flag1) { diff --git a/module/minecraft/patches/net/minecraft/entity/projectile/EntityThrowable.java.patch b/module/minecraft/patches/net/minecraft/entity/projectile/EntityThrowable.java.patch new file mode 100644 index 000000000..b74aa11f7 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/projectile/EntityThrowable.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/entity/projectile/EntityThrowable.java ++++ modified/net/minecraft/entity/projectile/EntityThrowable.java +@@ -211,7 +211,7 @@ + if (raytraceresult.typeOfHit == RayTraceResult.Type.BLOCK + && this.world.getBlockState(raytraceresult.getBlockPos()).getBlock() == Blocks.PORTAL) { + this.setPortal(raytraceresult.getBlockPos()); +- } else { ++ } else if (!net.minecraftforge.event.ForgeEventFactory.onProjectileImpact(this, raytraceresult)) { + this.onImpact(raytraceresult); + } + } diff --git a/module/minecraft/patches/net/minecraft/entity/projectile/EntityWitherSkull.java.patch b/module/minecraft/patches/net/minecraft/entity/projectile/EntityWitherSkull.java.patch new file mode 100644 index 000000000..912404813 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/entity/projectile/EntityWitherSkull.java.patch @@ -0,0 +1,21 @@ +--- original/net/minecraft/entity/projectile/EntityWitherSkull.java ++++ modified/net/minecraft/entity/projectile/EntityWitherSkull.java +@@ -61,7 +61,8 @@ + public float getExplosionResistance(Explosion explosionIn, World worldIn, BlockPos pos, IBlockState blockStateIn) { + float f = super.getExplosionResistance(explosionIn, worldIn, pos, blockStateIn); + Block block = blockStateIn.getBlock(); +- if (this.isInvulnerable() && EntityWither.canDestroyBlock(block)) { ++ ++ if (this.isInvulnerable() && block.canEntityDestroy(blockStateIn, worldIn, pos, this) && net.minecraftforge.event.ForgeEventFactory.onEntityDestroyBlock(this.shootingEntity, pos, blockStateIn)) { + f = Math.min(0.8F, f); + } + +@@ -107,7 +108,7 @@ + this.posZ, + 1.0F, + false, +- this.world.getGameRules().getBoolean("mobGriefing") ++ net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.world, this.shootingEntity) + ); + this.setDead(); + } diff --git a/module/minecraft/patches/net/minecraft/init/Bootstrap.java.patch b/module/minecraft/patches/net/minecraft/init/Bootstrap.java.patch new file mode 100644 index 000000000..b9423415a --- /dev/null +++ b/module/minecraft/patches/net/minecraft/init/Bootstrap.java.patch @@ -0,0 +1,28 @@ +--- original/net/minecraft/init/Bootstrap.java ++++ modified/net/minecraft/init/Bootstrap.java +@@ -296,6 +296,9 @@ + }; + BlockDispenser.DISPENSE_BEHAVIOR_REGISTRY.putObject(Items.LAVA_BUCKET, ibehaviordispenseitem); + BlockDispenser.DISPENSE_BEHAVIOR_REGISTRY.putObject(Items.WATER_BUCKET, ibehaviordispenseitem); ++ BlockDispenser.DISPENSE_BEHAVIOR_REGISTRY.putObject(Items.MILK_BUCKET, net.minecraftforge.fluids.DispenseFluidContainer.getInstance()); ++ BlockDispenser.DISPENSE_BEHAVIOR_REGISTRY.putObject(Items.BUCKET, net.minecraftforge.fluids.DispenseFluidContainer.getInstance()); ++ if (false) + BlockDispenser.DISPENSE_BEHAVIOR_REGISTRY + .putObject( + Items.BUCKET, +@@ -492,6 +495,7 @@ + public static void register() { + if (!alreadyRegistered) { + alreadyRegistered = true; ++ if (false) // skip redirectOutputToLog, Forge already redirects stdout and stderr output to log so that they print with more context + redirectOutputToLog(); + SoundEvent.registerSounds(); + Block.registerBlocks(); +@@ -521,6 +525,7 @@ + LOGGER.error("Errors with built-in loot tables"); + } + } ++ net.minecraftforge.registries.GameData.vanillaSnapshot(); + } + } + diff --git a/module/minecraft/patches/net/minecraft/inventory/Container.java.patch b/module/minecraft/patches/net/minecraft/inventory/Container.java.patch new file mode 100644 index 000000000..c4c02fef0 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/inventory/Container.java.patch @@ -0,0 +1,44 @@ +--- original/net/minecraft/inventory/Container.java ++++ modified/net/minecraft/inventory/Container.java +@@ -78,9 +78,11 @@ + ItemStack itemstack = this.inventorySlots.get(i).getStack(); + ItemStack itemstack1 = this.inventoryItemStacks.get(i); + if (!ItemStack.areItemStacksEqual(itemstack1, itemstack)) { ++ boolean clientStackChanged = !ItemStack.areItemStacksEqualUsingNBTShareTag(itemstack1, itemstack); + itemstack1 = itemstack.isEmpty() ? ItemStack.EMPTY : itemstack.copy(); + this.inventoryItemStacks.set(i, itemstack1); + ++ if (clientStackChanged) + for (int j = 0; j < this.listeners.size(); j++) { + this.listeners.get(j).sendSlotContents(this, i, itemstack1); + } +@@ -460,14 +462,16 @@ + && (!stack.getHasSubtypes() || stack.getMetadata() == itemstack.getMetadata()) + && ItemStack.areItemStackTagsEqual(stack, itemstack)) { + int j = itemstack.getCount() + stack.getCount(); +- if (j <= stack.getMaxStackSize()) { ++ int maxSize = Math.min(slot.getSlotStackLimit(), stack.getMaxStackSize()); ++ ++ if (j <= maxSize) { + stack.setCount(0); + itemstack.setCount(j); + slot.onSlotChanged(); + flag = true; +- } else if (itemstack.getCount() < stack.getMaxStackSize()) { +- stack.shrink(stack.getMaxStackSize() - itemstack.getCount()); +- itemstack.setCount(stack.getMaxStackSize()); ++ } else if (itemstack.getCount() < maxSize) { ++ stack.shrink(maxSize - itemstack.getCount()); ++ itemstack.setCount(maxSize); + slot.onSlotChanged(); + flag = true; + } +@@ -561,7 +565,7 @@ + stack.setCount(1); + break; + case 2: +- stack.setCount(stack.getItem().getItemStackLimit()); ++ stack.setCount(stack.getMaxStackSize()); + } + + stack.grow(slotStackSize); diff --git a/module/minecraft/patches/net/minecraft/inventory/ContainerBeacon.java.patch b/module/minecraft/patches/net/minecraft/inventory/ContainerBeacon.java.patch new file mode 100644 index 000000000..e35c3f08a --- /dev/null +++ b/module/minecraft/patches/net/minecraft/inventory/ContainerBeacon.java.patch @@ -0,0 +1,25 @@ +--- original/net/minecraft/inventory/ContainerBeacon.java ++++ modified/net/minecraft/inventory/ContainerBeacon.java +@@ -78,10 +78,8 @@ + } + + slot.onSlotChange(itemstack1, itemstack); +- } else if (!this.beaconSlot.getHasStack() && this.beaconSlot.isItemValid(itemstack1) && itemstack1.getCount() == 1) { +- if (!this.mergeItemStack(itemstack1, 0, 1, false)) { +- return ItemStack.EMPTY; +- } ++ } else if (this.mergeItemStack(itemstack1, 0, 1, false)) { //Forge Fix Shift Clicking in beacons with stacks larger then 1. ++ return ItemStack.EMPTY; + } else if (index >= 1 && index < 28) { + if (!this.mergeItemStack(itemstack1, 28, 37, false)) { + return ItemStack.EMPTY; +@@ -118,8 +116,7 @@ + /** Check if the stack is allowed to be placed in this slot, used for armor slots as well as furnace fuel. */ + @Override + public boolean isItemValid(ItemStack stack) { +- Item item = stack.getItem(); +- return item == Items.EMERALD || item == Items.DIAMOND || item == Items.GOLD_INGOT || item == Items.IRON_INGOT; ++ return stack.getItem().isBeaconPayment(stack); + } + + /** Returns the maximum stack size for a given slot (usually the same as getInventoryStackLimit(), but 1 in the case of armor slots) */ diff --git a/module/minecraft/patches/net/minecraft/inventory/ContainerBrewingStand.java.patch b/module/minecraft/patches/net/minecraft/inventory/ContainerBrewingStand.java.patch new file mode 100644 index 000000000..39785e02e --- /dev/null +++ b/module/minecraft/patches/net/minecraft/inventory/ContainerBrewingStand.java.patch @@ -0,0 +1,29 @@ +--- original/net/minecraft/inventory/ContainerBrewingStand.java ++++ modified/net/minecraft/inventory/ContainerBrewingStand.java +@@ -166,7 +166,7 @@ + /** Check if the stack is allowed to be placed in this slot, used for armor slots as well as furnace fuel. */ + @Override + public boolean isItemValid(ItemStack stack) { +- return PotionHelper.isReagent(stack); ++ return net.minecraftforge.common.brewing.BrewingRecipeRegistry.isValidIngredient(stack); + } + + /** Returns the maximum stack size for a given slot (usually the same as getInventoryStackLimit(), but 1 in the case of armor slots) */ +@@ -197,6 +197,7 @@ + public ItemStack onTake(EntityPlayer thePlayer, ItemStack stack) { + PotionType potiontype = PotionUtils.getPotionFromItem(stack); + if (thePlayer instanceof EntityPlayerMP) { ++ net.minecraftforge.event.ForgeEventFactory.onPlayerBrewedPotion(thePlayer, stack); + CriteriaTriggers.BREWED_POTION.trigger((EntityPlayerMP)thePlayer, potiontype); + } + +@@ -206,8 +207,7 @@ + + /** Returns true if this itemstack can be filled with a potion */ + public static boolean canHoldPotion(ItemStack stack) { +- Item item = stack.getItem(); +- return item == Items.POTIONITEM || item == Items.SPLASH_POTION || item == Items.LINGERING_POTION || item == Items.GLASS_BOTTLE; ++ return net.minecraftforge.common.brewing.BrewingRecipeRegistry.isValidInput(stack); + } + } + } diff --git a/module/minecraft/patches/net/minecraft/inventory/ContainerEnchantment.java.patch b/module/minecraft/patches/net/minecraft/inventory/ContainerEnchantment.java.patch new file mode 100644 index 000000000..7d2b93e37 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/inventory/ContainerEnchantment.java.patch @@ -0,0 +1,95 @@ +--- original/net/minecraft/inventory/ContainerEnchantment.java ++++ modified/net/minecraft/inventory/ContainerEnchantment.java +@@ -71,10 +71,12 @@ + } + }); + this.addSlotToContainer(new Slot(this.tableInventory, 1, 35, 47) { +- /** Check if the stack is allowed to be placed in this slot, used for armor slots as well as furnace fuel. */ ++ java.util.List ores = net.minecraftforge.oredict.OreDictionary.getOres("gemLapis"); + @Override + public boolean isItemValid(ItemStack stack) { +- return stack.getItem() == Items.DYE && EnumDyeColor.byDyeDamage(stack.getMetadata()) == EnumDyeColor.BLUE; ++ for (ItemStack ore : ores) ++ if (net.minecraftforge.oredict.OreDictionary.itemMatches(ore, stack, false)) return true; ++ return false; + } + }); + +@@ -142,43 +144,21 @@ + ItemStack itemstack = inventoryIn.getStackInSlot(0); + if (!itemstack.isEmpty() && itemstack.isItemEnchantable()) { + if (!this.world.isRemote) { +- int l = 0; ++ float power = 0; + + for (int j = -1; j <= 1; j++) { + for (int k = -1; k <= 1; k++) { + if ((j != 0 || k != 0) + && this.world.isAirBlock(this.position.add(k, 0, j)) + && this.world.isAirBlock(this.position.add(k, 1, j))) { +- if (this.world.getBlockState(this.position.add(k * 2, 0, j * 2)).getBlock() +- == Blocks.BOOKSHELF) { +- l++; +- } ++ power += net.minecraftforge.common.ForgeHooks.getEnchantPower(world, position.add(k * 2, 0, j * 2)); ++ power += net.minecraftforge.common.ForgeHooks.getEnchantPower(world, position.add(k * 2, 1, j * 2)); + +- if (this.world.getBlockState(this.position.add(k * 2, 1, j * 2)).getBlock() +- == Blocks.BOOKSHELF) { +- l++; +- } +- + if (k != 0 && j != 0) { +- if (this.world.getBlockState(this.position.add(k * 2, 0, j)).getBlock() +- == Blocks.BOOKSHELF) { +- l++; +- } +- +- if (this.world.getBlockState(this.position.add(k * 2, 1, j)).getBlock() +- == Blocks.BOOKSHELF) { +- l++; +- } +- +- if (this.world.getBlockState(this.position.add(k, 0, j * 2)).getBlock() +- == Blocks.BOOKSHELF) { +- l++; +- } +- +- if (this.world.getBlockState(this.position.add(k, 1, j * 2)).getBlock() +- == Blocks.BOOKSHELF) { +- l++; +- } ++ power += net.minecraftforge.common.ForgeHooks.getEnchantPower(world, position.add(k * 2, 0, j)); ++ power += net.minecraftforge.common.ForgeHooks.getEnchantPower(world, position.add(k * 2, 1, j)); ++ power += net.minecraftforge.common.ForgeHooks.getEnchantPower(world, position.add(k, 0, j * 2)); ++ power += net.minecraftforge.common.ForgeHooks.getEnchantPower(world, position.add(k, 1, j * 2)); + } + } + } +@@ -187,12 +167,13 @@ + this.rand.setSeed(this.xpSeed); + + for (int i1 = 0; i1 < 3; i1++) { +- this.enchantLevels[i1] = EnchantmentHelper.calcItemStackEnchantability(this.rand, i1, l, itemstack); ++ this.enchantLevels[i1] = EnchantmentHelper.calcItemStackEnchantability(this.rand, i1, (int)power, itemstack); + this.enchantClue[i1] = -1; + this.worldClue[i1] = -1; + if (this.enchantLevels[i1] < i1 + 1) { + this.enchantLevels[i1] = 0; + } ++ this.enchantLevels[i1] = net.minecraftforge.event.ForgeEventFactory.onEnchantmentLevelSet(world, position, i1, (int)power, itemstack, enchantLevels[i1]); + } + + for (int j1 = 0; j1 < 3; j1++) { +@@ -346,9 +327,8 @@ + return ItemStack.EMPTY; + } + +- if (itemstack1.hasTagCompound() && itemstack1.getCount() == 1) { +- this.inventorySlots.get(0).putStack(itemstack1.copy()); +- itemstack1.setCount(0); ++ if (itemstack1.hasTagCompound()) { // Forge: Fix MC-17431 ++ this.inventorySlots.get(0).putStack(itemstack1.splitStack(1)); + } else if (!itemstack1.isEmpty()) { + this.inventorySlots.get(0).putStack(new ItemStack(itemstack1.getItem(), 1, itemstack1.getMetadata())); + itemstack1.shrink(1); diff --git a/module/minecraft/patches/net/minecraft/inventory/ContainerPlayer.java.patch b/module/minecraft/patches/net/minecraft/inventory/ContainerPlayer.java.patch new file mode 100644 index 000000000..88ee6b9a9 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/inventory/ContainerPlayer.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/inventory/ContainerPlayer.java ++++ modified/net/minecraft/inventory/ContainerPlayer.java +@@ -45,7 +45,7 @@ + /** Check if the stack is allowed to be placed in this slot, used for armor slots as well as furnace fuel. */ + @Override + public boolean isItemValid(ItemStack stack) { +- return entityequipmentslot == EntityLiving.getSlotForItemStack(stack); ++ return stack.getItem().isValidArmor(stack, entityequipmentslot, player); + } + + /** Return whether this slot's stack can be taken from this slot. */ diff --git a/module/minecraft/patches/net/minecraft/inventory/ContainerRepair.java.patch b/module/minecraft/patches/net/minecraft/inventory/ContainerRepair.java.patch new file mode 100644 index 000000000..566228f4e --- /dev/null +++ b/module/minecraft/patches/net/minecraft/inventory/ContainerRepair.java.patch @@ -0,0 +1,113 @@ +--- original/net/minecraft/inventory/ContainerRepair.java ++++ modified/net/minecraft/inventory/ContainerRepair.java +@@ -70,45 +70,51 @@ + } + + @Override +- public ItemStack onTake(EntityPlayer thePlayer, ItemStack stack) { +- if (!thePlayer.capabilities.isCreativeMode) { +- thePlayer.addExperienceLevel(-ContainerRepair.this.maximumCost); +- } ++ public ItemStack onTake(EntityPlayer thePlayer, ItemStack stack) { ++ if (!thePlayer.capabilities.isCreativeMode) { ++ thePlayer.addExperienceLevel(-ContainerRepair.this.maximumCost); ++ } + +- ContainerRepair.this.inputSlots.setInventorySlotContents(0, ItemStack.EMPTY); +- if (ContainerRepair.this.materialCost > 0) { +- ItemStack itemstack = ContainerRepair.this.inputSlots.getStackInSlot(1); +- if (!itemstack.isEmpty() && itemstack.getCount() > ContainerRepair.this.materialCost) { +- itemstack.shrink(ContainerRepair.this.materialCost); +- ContainerRepair.this.inputSlots.setInventorySlotContents(1, itemstack); +- } else { +- ContainerRepair.this.inputSlots.setInventorySlotContents(1, ItemStack.EMPTY); +- } ++ float breakChance = net.minecraftforge.common.ForgeHooks.onAnvilRepair(thePlayer, stack, ContainerRepair.this.inputSlots.getStackInSlot(0), ContainerRepair.this.inputSlots.getStackInSlot(1)); ++ ++ ContainerRepair.this.inputSlots.setInventorySlotContents(0, ItemStack.EMPTY); ++ ++ if (ContainerRepair.this.materialCost > 0) { ++ ItemStack itemstack = ContainerRepair.this.inputSlots.getStackInSlot(1); ++ ++ if (!itemstack.isEmpty() && itemstack.getCount() > ContainerRepair.this.materialCost) { ++ itemstack.shrink(ContainerRepair.this.materialCost); ++ ContainerRepair.this.inputSlots.setInventorySlotContents(1, itemstack); + } else { + ContainerRepair.this.inputSlots.setInventorySlotContents(1, ItemStack.EMPTY); + } ++ } else { ++ ContainerRepair.this.inputSlots.setInventorySlotContents(1, ItemStack.EMPTY); ++ } + +- ContainerRepair.this.maximumCost = 0; +- IBlockState iblockstate = worldIn.getBlockState(blockPosIn); +- if (!thePlayer.capabilities.isCreativeMode ++ ContainerRepair.this.maximumCost = 0; ++ IBlockState iblockstate = worldIn.getBlockState(blockPosIn); ++ ++ if (!thePlayer.capabilities.isCreativeMode + && !worldIn.isRemote + && iblockstate.getBlock() == Blocks.ANVIL +- && thePlayer.getRNG().nextFloat() < 0.12F) { +- int l = iblockstate.getValue(BlockAnvil.DAMAGE); +- if (++l > 2) { +- worldIn.setBlockToAir(blockPosIn); +- worldIn.playEvent(1029, blockPosIn, 0); +- } else { +- worldIn.setBlockState(blockPosIn, iblockstate.withProperty(BlockAnvil.DAMAGE, l), 2); +- worldIn.playEvent(1030, blockPosIn, 0); +- } +- } else if (!worldIn.isRemote) { ++ && thePlayer.getRNG().nextFloat() < breakChance) { ++ int l = iblockstate.getValue(BlockAnvil.DAMAGE); ++ ++ if (++l > 2) { ++ worldIn.setBlockToAir(blockPosIn); ++ worldIn.playEvent(1029, blockPosIn, 0); ++ } else { ++ worldIn.setBlockState(blockPosIn, iblockstate.withProperty(BlockAnvil.DAMAGE, l), 2); + worldIn.playEvent(1030, blockPosIn, 0); + } +- +- return stack; ++ } else if (!worldIn.isRemote) { ++ worldIn.playEvent(1030, blockPosIn, 0); + } ++ ++ return stack; + } ++ } + ); + + for (int i = 0; i < 3; i++) { +@@ -147,8 +153,12 @@ + Map map = EnchantmentHelper.getEnchantments(itemstack1); + j += itemstack.getRepairCost() + (itemstack2.isEmpty() ? 0 : itemstack2.getRepairCost()); + this.materialCost = 0; ++ boolean flag = false; ++ + if (!itemstack2.isEmpty()) { +- boolean flag = itemstack2.getItem() == Items.ENCHANTED_BOOK && !ItemEnchantedBook.getEnchantments(itemstack2).isEmpty(); ++ if (!net.minecraftforge.common.ForgeHooks.onAnvilChange(this, itemstack, itemstack2, outputSlot, repairedItemName, j, player)) return; ++ flag = itemstack2.getItem() == Items.ENCHANTED_BOOK && !ItemEnchantedBook.getEnchantments(itemstack2).isEmpty(); ++ + if (itemstack1.isItemStackDamageable() && itemstack1.getItem().getIsRepairable(itemstack, itemstack2)) { + int l2 = Math.min(itemstack1.getItemDamage(), itemstack1.getMaxDamage() / 4); + if (l2 <= 0) { +@@ -183,7 +193,7 @@ + l1 = 0; + } + +- if (l1 < itemstack1.getMetadata()) { ++ if (l1 < itemstack1.getItemDamage()) { // vanilla uses metadata here instead of damage. + itemstack1.setItemDamage(l1); + i += 2; + } +@@ -265,6 +275,7 @@ + i += k; + itemstack1.setStackDisplayName(this.repairedItemName); + } ++ if (flag && !itemstack1.getItem().isBookEnchantable(itemstack1, itemstack2)) itemstack1 = ItemStack.EMPTY; + + this.maximumCost = j + i; + if (i <= 0) { diff --git a/module/minecraft/patches/net/minecraft/inventory/Slot.java.patch b/module/minecraft/patches/net/minecraft/inventory/Slot.java.patch new file mode 100644 index 000000000..4da53eb81 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/inventory/Slot.java.patch @@ -0,0 +1,79 @@ +--- original/net/minecraft/inventory/Slot.java ++++ modified/net/minecraft/inventory/Slot.java +@@ -87,7 +87,7 @@ + @Nullable + @SideOnly(Side.CLIENT) + public String getSlotTexture() { +- return null; ++ return backgroundName; + } + + /** Decrease the size of the stack in slot (first int arg) by the amount of the second int arg. Returns the new stack. */ +@@ -110,4 +110,67 @@ + public boolean isEnabled() { + return true; + } ++ ++ /*========================================= FORGE START =====================================*/ ++ protected String backgroundName = null; ++ protected net.minecraft.util.ResourceLocation backgroundLocation = null; ++ protected Object backgroundMap; ++ /** ++ * Gets the path of the texture file to use for the background image of this slot when drawing the GUI. ++ * @return The resource location for the background image ++ */ ++ @SideOnly(Side.CLIENT) ++ public net.minecraft.util.ResourceLocation getBackgroundLocation() { ++ return (backgroundLocation == null ? net.minecraft.client.renderer.texture.TextureMap.LOCATION_BLOCKS_TEXTURE : backgroundLocation); ++ } ++ ++ /** ++ * Sets the texture file to use for the background image of the slot when it's empty. ++ * @param texture the resourcelocation for the texture ++ */ ++ @SideOnly(Side.CLIENT) ++ public void setBackgroundLocation(net.minecraft.util.ResourceLocation texture) { ++ this.backgroundLocation = texture; ++ } ++ ++ /** ++ * Sets which icon index to use as the background image of the slot when it's empty. ++ * @param name The icon to use, null for none ++ */ ++ public void setBackgroundName(@Nullable String name) { ++ this.backgroundName = name; ++ } ++ ++ @Nullable ++ @SideOnly(Side.CLIENT) ++ public net.minecraft.client.renderer.texture.TextureAtlasSprite getBackgroundSprite() { ++ String name = getSlotTexture(); ++ return name == null ? null : getBackgroundMap().getAtlasSprite(name); ++ } ++ ++ @SideOnly(Side.CLIENT) ++ protected net.minecraft.client.renderer.texture.TextureMap getBackgroundMap() { ++ if (backgroundMap == null) backgroundMap = net.minecraft.client.Minecraft.getMinecraft().getTextureMapBlocks(); ++ return (net.minecraft.client.renderer.texture.TextureMap)backgroundMap; ++ } ++ ++ /** ++ * Retrieves the index in the inventory for this slot, this value should typically not ++ * be used, but can be useful for some occasions. ++ * ++ * @return Index in associated inventory for this slot. ++ */ ++ public int getSlotIndex() { ++ return slotIndex; ++ } ++ ++ /** ++ * Checks if the other slot is in the same inventory, by comparing the inventory reference. ++ * @param other ++ * @return true if the other slot is in the same inventory ++ */ ++ public boolean isSameInventory(Slot other) { ++ return this.inventory == other.inventory; ++ } ++ /*========================================= FORGE END =====================================*/ + } diff --git a/module/minecraft/patches/net/minecraft/inventory/SlotCrafting.java.patch b/module/minecraft/patches/net/minecraft/inventory/SlotCrafting.java.patch new file mode 100644 index 000000000..8f2120d6c --- /dev/null +++ b/module/minecraft/patches/net/minecraft/inventory/SlotCrafting.java.patch @@ -0,0 +1,20 @@ +--- original/net/minecraft/inventory/SlotCrafting.java ++++ modified/net/minecraft/inventory/SlotCrafting.java +@@ -54,6 +54,7 @@ + protected void onCrafting(ItemStack stack) { + if (this.amountCrafted > 0) { + stack.onCrafting(this.player.world, this.player, this.amountCrafted); ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().firePlayerCraftingEvent(this.player, stack, craftMatrix); + } + + this.amountCrafted = 0; +@@ -68,7 +69,9 @@ + @Override + public ItemStack onTake(EntityPlayer thePlayer, ItemStack stack) { + this.onCrafting(stack); ++ net.minecraftforge.common.ForgeHooks.setCraftingPlayer(thePlayer); + NonNullList nonnulllist = CraftingManager.getRemainingItems(this.craftMatrix, thePlayer.world); ++ net.minecraftforge.common.ForgeHooks.setCraftingPlayer(null); + + for (int i = 0; i < nonnulllist.size(); i++) { + ItemStack itemstack = this.craftMatrix.getStackInSlot(i); diff --git a/module/minecraft/patches/net/minecraft/inventory/SlotFurnaceOutput.java.patch b/module/minecraft/patches/net/minecraft/inventory/SlotFurnaceOutput.java.patch new file mode 100644 index 000000000..8cb8ed026 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/inventory/SlotFurnaceOutput.java.patch @@ -0,0 +1,9 @@ +--- original/net/minecraft/inventory/SlotFurnaceOutput.java ++++ modified/net/minecraft/inventory/SlotFurnaceOutput.java +@@ -82,5 +82,6 @@ + } + + this.removeCount = 0; ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().firePlayerSmeltedEvent(player, stack); + } + } diff --git a/module/minecraft/patches/net/minecraft/item/EnumRarity.java.patch b/module/minecraft/patches/net/minecraft/item/EnumRarity.java.patch new file mode 100644 index 000000000..53ecfb18d --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/EnumRarity.java.patch @@ -0,0 +1,26 @@ +--- original/net/minecraft/item/EnumRarity.java ++++ modified/net/minecraft/item/EnumRarity.java +@@ -2,7 +2,7 @@ + + import net.minecraft.util.text.TextFormatting; + +-public enum EnumRarity { ++public enum EnumRarity implements net.minecraftforge.common.IRarity { + COMMON(TextFormatting.WHITE, "Common"), + UNCOMMON(TextFormatting.YELLOW, "Uncommon"), + RARE(TextFormatting.AQUA, "Rare"), +@@ -17,4 +17,14 @@ + this.color = color; + this.rarityName = name; + } ++ ++ @Override ++ public TextFormatting getColor() { ++ return this.color; ++ } ++ ++ @Override ++ public String getName() { ++ return this.rarityName; ++ } + } diff --git a/module/minecraft/patches/net/minecraft/item/Item.java.patch b/module/minecraft/patches/net/minecraft/item/Item.java.patch new file mode 100644 index 000000000..350f1685b --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/Item.java.patch @@ -0,0 +1,838 @@ +--- original/net/minecraft/item/Item.java ++++ modified/net/minecraft/item/Item.java +@@ -58,9 +58,9 @@ + import net.minecraftforge.fml.relauncher.Side; + import net.minecraftforge.fml.relauncher.SideOnly; + +-public class Item { +- public static final RegistryNamespaced REGISTRY = new RegistryNamespaced<>(); +- private static final Map BLOCK_TO_ITEM = Maps.newHashMap(); ++public class Item extends net.minecraftforge.registries.IForgeRegistryEntry.Impl { ++ public static final RegistryNamespaced REGISTRY = net.minecraftforge.registries.GameData.getWrapper(Item.class); ++ private static final Map BLOCK_TO_ITEM = net.minecraftforge.registries.GameData.getBlockItemMap(); + private static final IItemPropertyGetter DAMAGED_GETTER = new IItemPropertyGetter() { + @SideOnly(Side.CLIENT) + @Override +@@ -193,7 +193,7 @@ + return stack; + } + +- /** Returns the maximum size of the stack for a specific item. */ ++ @Deprecated // Use ItemStack sensitive version below. + public int getItemStackLimit() { + return this.maxStackSize; + } +@@ -212,7 +212,7 @@ + return this; + } + +- /** Returns the maximum damage an item can take. */ ++ @Deprecated + public int getMaxDamage() { + return this.maxDamage; + } +@@ -306,7 +306,7 @@ + return this.containerItem; + } + +- /** True if this Item has a container item (a.k.a. crafting result) */ ++ @Deprecated // Use ItemStack sensitive version below. + public boolean hasContainerItem() { + return this.containerItem != null; + } +@@ -357,14 +357,14 @@ + return stack.isItemEnchanted(); + } + +- /** Return an item rarity from EnumRarity */ ++ @Deprecated // use Forge version + public EnumRarity getRarity(ItemStack stack) { + return stack.isItemEnchanted() ? EnumRarity.RARE : EnumRarity.COMMON; + } + + /** Checks isDamagable and if it cannot be stacked */ + public boolean isEnchantable(ItemStack stack) { +- return this.getItemStackLimit() == 1 && this.isDamageable(); ++ return this.getItemStackLimit(stack) == 1 && this.isDamageable(); + } + + protected RayTraceResult rayTrace(World worldIn, EntityPlayer playerIn, boolean useLiquids) { +@@ -381,8 +381,8 @@ + float f6 = f3 * f4; + float f7 = f5; + float f8 = f2 * f4; +- double d3 = 5.0; +- Vec3d vec3d1 = vec3d.add(f6 * 5.0, f7 * 5.0, f8 * 5.0); ++ double d3 = playerIn.getEntityAttribute(EntityPlayer.REACH_DISTANCE).getAttributeValue(); ++ Vec3d vec3d1 = vec3d.add(f6 * d3, f7 * d3, f8 * d3); + return worldIn.rayTraceBlocks(vec3d, vec3d1, useLiquids, !useLiquids, false); + } + +@@ -399,6 +399,9 @@ + } + + protected boolean isInCreativeTab(CreativeTabs targetTab) { ++ for (CreativeTabs tab : this.getCreativeTabs()) ++ if (tab == targetTab) ++ return true; + CreativeTabs creativetabs = this.getCreativeTab(); + return creativetabs != null && (targetTab == CreativeTabs.SEARCH || targetTab == creativetabs); + } +@@ -435,11 +438,719 @@ + return false; + } + +- /** Gets a map of item attribute modifiers, used by ItemSword to increase hit damage. */ ++ @Deprecated // Use ItemStack sensitive version below. + public Multimap getItemAttributeModifiers(EntityEquipmentSlot equipmentSlot) { + return HashMultimap.create(); + } + ++ /* ======================================== FORGE START =====================================*/ ++ /** ++ * ItemStack sensitive version of getItemAttributeModifiers ++ */ ++ public Multimap getAttributeModifiers(EntityEquipmentSlot slot, ItemStack stack) { ++ return this.getItemAttributeModifiers(slot); ++ } ++ ++ /** ++ * Called when a player drops the item into the world, ++ * returning false from this will prevent the item from ++ * being removed from the players inventory and spawning ++ * in the world ++ * ++ * @param player The player that dropped the item ++ * @param item The item stack, before the item is removed. ++ */ ++ public boolean onDroppedByPlayer(ItemStack item, EntityPlayer player) { ++ return true; ++ } ++ ++ /** ++ * Allow the item one last chance to modify its name used for the ++ * tool highlight useful for adding something extra that can't be removed ++ * by a user in the displayed name, such as a mode of operation. ++ * ++ * @param item the ItemStack for the item. ++ * @param displayName the name that will be displayed unless it is changed in this method. ++ */ ++ public String getHighlightTip( ItemStack item, String displayName ) { ++ return displayName; ++ } ++ ++ /** ++ * This is called when the item is used, before the block is activated. ++ * @param stack The Item Stack ++ * @param player The Player that used the item ++ * @param world The Current World ++ * @param pos Target position ++ * @param side The side of the target hit ++ * @param hand Which hand the item is being held in. ++ * @return Return PASS to allow vanilla handling, any other to skip normal code. ++ */ ++ public EnumActionResult onItemUseFirst(EntityPlayer player, World world, BlockPos pos, EnumFacing side, float hitX, float hitY, float hitZ, EnumHand hand) { ++ return EnumActionResult.PASS; ++ } ++ ++ protected boolean canRepair = true; ++ /** ++ * Called by CraftingManager to determine if an item is reparable. ++ * @return True if reparable ++ */ ++ public boolean isRepairable() { ++ return canRepair && isDamageable(); ++ } ++ ++ /** ++ * Call to disable repair recipes. ++ * @return The current Item instance ++ */ ++ public Item setNoRepair() { ++ canRepair = false; ++ return this; ++ } ++ ++ /** ++ * Determines the amount of durability the mending enchantment ++ * will repair, on average, per point of experience. ++ */ ++ public float getXpRepairRatio(ItemStack stack) { ++ return 2f; ++ } ++ ++ /** ++ * Override this method to change the NBT data being sent to the client. ++ * You should ONLY override this when you have no other choice, as this might change behavior client side! ++ * ++ * Note that this will sometimes be applied multiple times, the following MUST be supported: ++ * Item item = stack.getItem(); ++ * NBTTagCompound nbtShare1 = item.getNBTShareTag(stack); ++ * stack.setTagCompound(nbtShare1); ++ * NBTTagCompound nbtShare2 = item.getNBTShareTag(stack); ++ * assert nbtShare1.equals(nbtShare2); ++ * ++ * @param stack The stack to send the NBT tag for ++ * @return The NBT tag ++ */ ++ @Nullable ++ public NBTTagCompound getNBTShareTag(ItemStack stack) { ++ return stack.getTagCompound(); ++ } ++ ++ /** ++ * Override this method to decide what to do with the NBT data received from getNBTShareTag(). ++ * ++ * @param stack The stack that received NBT ++ * @param nbt Received NBT, can be null ++ */ ++ public void readNBTShareTag(ItemStack stack, @Nullable NBTTagCompound nbt) { ++ stack.setTagCompound(nbt); ++ } ++ ++ /** ++ * Called before a block is broken. Return true to prevent default block harvesting. ++ * ++ * Note: In SMP, this is called on both client and server sides! ++ * ++ * @param itemstack The current ItemStack ++ * @param pos Block's position in world ++ * @param player The Player that is wielding the item ++ * @return True to prevent harvesting, false to continue as normal ++ */ ++ public boolean onBlockStartBreak(ItemStack itemstack, BlockPos pos, EntityPlayer player) { ++ return false; ++ } ++ ++ /** ++ * Called each tick while using an item. ++ * @param stack The Item being used ++ * @param player The Player using the item ++ * @param count The amount of time in tick the item has been used for continuously ++ */ ++ public void onUsingTick(ItemStack stack, EntityLivingBase player, int count) { ++ } ++ ++ /** ++ * Called when the player Left Clicks (attacks) an entity. ++ * Processed before damage is done, if return value is true further processing is canceled ++ * and the entity is not attacked. ++ * ++ * @param stack The Item being used ++ * @param player The player that is attacking ++ * @param entity The entity being attacked ++ * @return True to cancel the rest of the interaction. ++ */ ++ public boolean onLeftClickEntity(ItemStack stack, EntityPlayer player, Entity entity) { ++ return false; ++ } ++ ++ /** ++ * ItemStack sensitive version of getContainerItem. ++ * Returns a full ItemStack instance of the result. ++ * ++ * @param itemStack The current ItemStack ++ * @return The resulting ItemStack ++ */ ++ public ItemStack getContainerItem(ItemStack itemStack) { ++ if (!hasContainerItem(itemStack)) { ++ return ItemStack.EMPTY; ++ } ++ return new ItemStack(getContainerItem()); ++ } ++ ++ /** ++ * ItemStack sensitive version of hasContainerItem ++ * @param stack The current item stack ++ * @return True if this item has a 'container' ++ */ ++ public boolean hasContainerItem(ItemStack stack) { ++ return hasContainerItem(); ++ } ++ ++ /** ++ * Retrieves the normal 'lifespan' of this item when it is dropped on the ground as a EntityItem. ++ * This is in ticks, standard result is 6000, or 5 mins. ++ * ++ * @param itemStack The current ItemStack ++ * @param world The world the entity is in ++ * @return The normal lifespan in ticks. ++ */ ++ public int getEntityLifespan(ItemStack itemStack, World world) { ++ return 6000; ++ } ++ ++ /** ++ * Determines if this Item has a special entity for when they are in the world. ++ * Is called when a EntityItem is spawned in the world, if true and Item#createCustomEntity ++ * returns non null, the EntityItem will be destroyed and the new Entity will be added to the world. ++ * ++ * @param stack The current item stack ++ * @return True of the item has a custom entity, If true, Item#createCustomEntity will be called ++ */ ++ public boolean hasCustomEntity(ItemStack stack) { ++ return false; ++ } ++ ++ /** ++ * This function should return a new entity to replace the dropped item. ++ * Returning null here will not kill the EntityItem and will leave it to function normally. ++ * Called when the item it placed in a world. ++ * ++ * @param world The world object ++ * @param location The EntityItem object, useful for getting the position of the entity ++ * @param itemstack The current item stack ++ * @return A new Entity object to spawn or null ++ */ ++ @Nullable ++ public Entity createEntity(World world, Entity location, ItemStack itemstack) { ++ return null; ++ } ++ ++ /** ++ * Called by the default implemetation of EntityItem's onUpdate method, allowing for cleaner ++ * control over the update of the item without having to write a subclass. ++ * ++ * @param entityItem The entity Item ++ * @return Return true to skip any further update code. ++ */ ++ public boolean onEntityItemUpdate(net.minecraft.entity.item.EntityItem entityItem) { ++ return false; ++ } ++ ++ /** ++ * Gets a list of tabs that items belonging to this class can display on, ++ * combined properly with getSubItems allows for a single item to span ++ * many sub-items across many tabs. ++ * ++ * @return A list of all tabs that this item could possibly be one. ++ */ ++ public CreativeTabs[] getCreativeTabs() { ++ return new CreativeTabs[]{ getCreativeTab() }; ++ } ++ ++ /** ++ * Determines the base experience for a player when they remove this item from a furnace slot. ++ * This number must be between 0 and 1 for it to be valid. ++ * This number will be multiplied by the stack size to get the total experience. ++ * ++ * @param item The item stack the player is picking up. ++ * @return The amount to award for each item. ++ */ ++ public float getSmeltingExperience(ItemStack item) { ++ return -1; //-1 will default to the old lookups. ++ } ++ ++ /** ++ * ++ * Should this item, when held, allow sneak-clicks to pass through to the underlying block? ++ * ++ * @param world The world ++ * @param pos Block position in world ++ * @param player The Player that is wielding the item ++ * @return ++ */ ++ public boolean doesSneakBypassUse(ItemStack stack, net.minecraft.world.IBlockAccess world, BlockPos pos, EntityPlayer player) { ++ return false; ++ } ++ ++ /** ++ * Called to tick armor in the armor slot. Override to do something ++ */ ++ public void onArmorTick(World world, EntityPlayer player, ItemStack itemStack){} ++ ++ /** ++ * Determines if the specific ItemStack can be placed in the specified armor slot, for the entity. ++ * ++ * TODO: Change name to canEquip in 1.13? ++ * ++ * @param stack The ItemStack ++ * @param armorType Armor slot to be verified. ++ * @param entity The entity trying to equip the armor ++ * @return True if the given ItemStack can be inserted in the slot ++ */ ++ public boolean isValidArmor(ItemStack stack, EntityEquipmentSlot armorType, Entity entity) { ++ return net.minecraft.entity.EntityLiving.getSlotForItemStack(stack) == armorType; ++ } ++ ++ /** ++ * Override this to set a non-default armor slot for an ItemStack, but ++ * do not use this to get the armor slot of said stack; for that, use ++ * {@link net.minecraft.entity.EntityLiving#getSlotForItemStack(ItemStack)}. ++ * ++ * @param stack the ItemStack ++ * @return the armor slot of the ItemStack, or {@code null} to let the default ++ * vanilla logic as per {@code EntityLiving.getSlotForItemStack(stack)} decide ++ */ ++ @Nullable ++ public EntityEquipmentSlot getEquipmentSlot(ItemStack stack) { ++ return null; ++ } ++ ++ /** ++ * Allow or forbid the specific book/item combination as an anvil enchant ++ * ++ * @param stack The item ++ * @param book The book ++ * @return if the enchantment is allowed ++ */ ++ public boolean isBookEnchantable(ItemStack stack, ItemStack book) { ++ return true; ++ } ++ ++ /** ++ * Called by RenderBiped and RenderPlayer to determine the armor texture that ++ * should be use for the currently equipped item. ++ * This will only be called on instances of ItemArmor. ++ * ++ * Returning null from this function will use the default value. ++ * ++ * @param stack ItemStack for the equipped armor ++ * @param entity The entity wearing the armor ++ * @param slot The slot the armor is in ++ * @param type The subtype, can be null or "overlay" ++ * @return Path of texture to bind, or null to use default ++ */ ++ @Nullable ++ public String getArmorTexture(ItemStack stack, Entity entity, EntityEquipmentSlot slot, String type) { ++ return null; ++ } ++ ++ /** ++ * Returns the font renderer used to render tooltips and overlays for this item. ++ * Returning null will use the standard font renderer. ++ * ++ * @param stack The current item stack ++ * @return A instance of FontRenderer or null to use default ++ */ ++ @SideOnly(Side.CLIENT) ++ @Nullable ++ public net.minecraft.client.gui.FontRenderer getFontRenderer(ItemStack stack) { ++ return null; ++ } ++ ++ /** ++ * Override this method to have an item handle its own armor rendering. ++ * ++ * @param entityLiving The entity wearing the armor ++ * @param itemStack The itemStack to render the model of ++ * @param armorSlot The slot the armor is in ++ * @param _default Original armor model. Will have attributes set. ++ * @return A ModelBiped to render instead of the default ++ */ ++ @SideOnly(Side.CLIENT) ++ @Nullable ++ public net.minecraft.client.model.ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack itemStack, EntityEquipmentSlot armorSlot, net.minecraft.client.model.ModelBiped _default) { ++ return null; ++ } ++ ++ /** ++ * Called when a entity tries to play the 'swing' animation. ++ * ++ * @param entityLiving The entity swinging the item. ++ * @param stack The Item stack ++ * @return True to cancel any further processing by EntityLiving ++ */ ++ public boolean onEntitySwing(EntityLivingBase entityLiving, ItemStack stack) { ++ return false; ++ } ++ ++ /** ++ * Called when the client starts rendering the HUD, for whatever item the player currently has as a helmet. ++ * This is where pumpkins would render there overlay. ++ * ++ * @param stack The ItemStack that is equipped ++ * @param player Reference to the current client entity ++ * @param resolution Resolution information about the current viewport and configured GUI Scale ++ * @param partialTicks Partial ticks for the renderer, useful for interpolation ++ */ ++ @SideOnly(Side.CLIENT) ++ public void renderHelmetOverlay(ItemStack stack, EntityPlayer player, net.minecraft.client.gui.ScaledResolution resolution, float partialTicks){} ++ ++ /** ++ * Return the itemDamage represented by this ItemStack. Defaults to the itemDamage field on ItemStack, but can be overridden here for other sources such as NBT. ++ * ++ * @param stack The itemstack that is damaged ++ * @return the damage value ++ */ ++ public int getDamage(ItemStack stack) { ++ return stack.itemDamage; ++ } ++ ++ /** ++ * This used to be 'display damage' but its really just 'aux' data in the ItemStack, usually shares the same variable as damage. ++ * @param stack ++ * @return ++ */ ++ public int getMetadata(ItemStack stack) { ++ return stack.itemDamage; ++ } ++ ++ /** ++ * Determines if the durability bar should be rendered for this item. ++ * Defaults to vanilla stack.isDamaged behavior. ++ * But modders can use this for any data they wish. ++ * ++ * @param stack The current Item Stack ++ * @return True if it should render the 'durability' bar. ++ */ ++ public boolean showDurabilityBar(ItemStack stack) { ++ return stack.isItemDamaged(); ++ } ++ ++ /** ++ * Queries the percentage of the 'Durability' bar that should be drawn. ++ * ++ * @param stack The current ItemStack ++ * @return 0.0 for 100% (no damage / full bar), 1.0 for 0% (fully damaged / empty bar) ++ */ ++ public double getDurabilityForDisplay(ItemStack stack) { ++ return (double)stack.getItemDamage() / (double)stack.getMaxDamage(); ++ } ++ ++ /** ++ * Returns the packed int RGB value used to render the durability bar in the GUI. ++ * Defaults to a value based on the hue scaled based on {@link #getDurabilityForDisplay}, but can be overriden. ++ * ++ * @param stack Stack to get durability from ++ * @return A packed RGB value for the durability colour (0x00RRGGBB) ++ */ ++ public int getRGBDurabilityForDisplay(ItemStack stack) { ++ return MathHelper.hsvToRGB(Math.max(0.0F, (float) (1.0F - getDurabilityForDisplay(stack))) / 3.0F, 1.0F, 1.0F); ++ } ++ /** ++ * Return the maxDamage for this ItemStack. Defaults to the maxDamage field in this item, ++ * but can be overridden here for other sources such as NBT. ++ * ++ * @param stack The itemstack that is damaged ++ * @return the damage value ++ */ ++ public int getMaxDamage(ItemStack stack) { ++ return getMaxDamage(); ++ } ++ ++ /** ++ * Return if this itemstack is damaged. Note only called if {@link #isDamageable()} is true. ++ * @param stack the stack ++ * @return if the stack is damaged ++ */ ++ public boolean isDamaged(ItemStack stack) { ++ return stack.itemDamage > 0; ++ } ++ ++ /** ++ * Set the damage for this itemstack. Note, this method is responsible for zero checking. ++ * @param stack the stack ++ * @param damage the new damage value ++ */ ++ public void setDamage(ItemStack stack, int damage) { ++ stack.itemDamage = damage; ++ ++ if (stack.itemDamage < 0) { ++ stack.itemDamage = 0; ++ } ++ } ++ ++ /** ++ * Checked from {@link net.minecraft.client.multiplayer.PlayerControllerMP#onPlayerDestroyBlock(BlockPos pos) PlayerControllerMP.onPlayerDestroyBlock()} ++ * when a creative player left-clicks a block with this item. ++ * Also checked from {@link net.minecraftforge.common.ForgeHooks#onBlockBreakEvent(World, GameType, EntityPlayerMP, BlockPos) ForgeHooks.onBlockBreakEvent()} ++ * to prevent sending an event. ++ * @return true if the given player can destroy specified block in creative mode with this item ++ */ ++ public boolean canDestroyBlockInCreative(World world, BlockPos pos, ItemStack stack, EntityPlayer player) { ++ return !(this instanceof ItemSword); ++ } ++ ++ /** ++ * ItemStack sensitive version of {@link #canHarvestBlock(IBlockState)} ++ * @param state The block trying to harvest ++ * @param stack The itemstack used to harvest the block ++ * @return true if can harvest the block ++ */ ++ public boolean canHarvestBlock(IBlockState state, ItemStack stack) { ++ return canHarvestBlock(state); ++ } ++ ++ /** ++ * Gets the maximum number of items that this stack should be able to hold. ++ * This is a ItemStack (and thus NBT) sensitive version of Item.getItemStackLimit() ++ * ++ * @param stack The ItemStack ++ * @return The maximum number this item can be stacked to ++ */ ++ public int getItemStackLimit(ItemStack stack) { ++ return this.getItemStackLimit(); ++ } ++ ++ private java.util.Map toolClasses = new java.util.HashMap(); ++ /** ++ * Sets or removes the harvest level for the specified tool class. ++ * ++ * @param toolClass Class ++ * @param level Harvest level: ++ * Wood: 0 ++ * Stone: 1 ++ * Iron: 2 ++ * Diamond: 3 ++ * Gold: 0 ++ */ ++ public void setHarvestLevel(String toolClass, int level) { ++ if (level < 0) ++ toolClasses.remove(toolClass); ++ else ++ toolClasses.put(toolClass, level); ++ } ++ ++ public java.util.Set getToolClasses(ItemStack stack) { ++ return toolClasses.keySet(); ++ } ++ ++ /** ++ * Queries the harvest level of this item stack for the specified tool class, ++ * Returns -1 if this tool is not of the specified type ++ * ++ * @param stack This item stack instance ++ * @param toolClass Tool Class ++ * @param player The player trying to harvest the given blockstate ++ * @param blockState The block to harvest ++ * @return Harvest level, or -1 if not the specified tool type. ++ */ ++ public int getHarvestLevel(ItemStack stack, String toolClass, @Nullable EntityPlayer player, @Nullable IBlockState blockState) { ++ Integer ret = toolClasses.get(toolClass); ++ return ret == null ? -1 : ret; ++ } ++ ++ /** ++ * ItemStack sensitive version of getItemEnchantability ++ * ++ * @param stack The ItemStack ++ * @return the item echantability value ++ */ ++ public int getItemEnchantability(ItemStack stack) { ++ return getItemEnchantability(); ++ } ++ ++ /** ++ * Checks whether an item can be enchanted with a certain enchantment. This applies specifically to enchanting an item in the enchanting table and is called when retrieving the list of possible enchantments for an item. ++ * Enchantments may additionally (or exclusively) be doing their own checks in {@link net.minecraft.enchantment.Enchantment#canApplyAtEnchantingTable(ItemStack)}; check the individual implementation for reference. ++ * By default this will check if the enchantment type is valid for this item type. ++ * @param stack the item stack to be enchanted ++ * @param enchantment the enchantment to be applied ++ * @return true if the enchantment can be applied to this item ++ */ ++ public boolean canApplyAtEnchantingTable(ItemStack stack, net.minecraft.enchantment.Enchantment enchantment) { ++ return enchantment.type.canEnchantItem(stack.getItem()); ++ } ++ ++ /** ++ * Whether this Item can be used as a payment to activate the vanilla beacon. ++ * @param stack the ItemStack ++ * @return true if this Item can be used ++ */ ++ public boolean isBeaconPayment(ItemStack stack) { ++ return this == Items.EMERALD || this == Items.DIAMOND || this == Items.GOLD_INGOT || this == Items.IRON_INGOT; ++ } ++ ++ /** ++ * Determine if the player switching between these two item stacks ++ * @param oldStack The old stack that was equipped ++ * @param newStack The new stack ++ * @param slotChanged If the current equipped slot was changed, ++ * Vanilla does not play the animation if you switch between two ++ * slots that hold the exact same item. ++ * @return True to play the item change animation ++ */ ++ public boolean shouldCauseReequipAnimation(ItemStack oldStack, ItemStack newStack, boolean slotChanged) { ++ return !oldStack.equals(newStack); //!ItemStack.areItemStacksEqual(oldStack, newStack); ++ } ++ ++ /** ++ * Called when the player is mining a block and the item in his hand changes. ++ * Allows to not reset blockbreaking if only NBT or similar changes. ++ * @param oldStack The old stack that was used for mining. Item in players main hand ++ * @param newStack The new stack ++ * @return True to reset block break progress ++ */ ++ public boolean shouldCauseBlockBreakReset(ItemStack oldStack, ItemStack newStack) { ++ return !(newStack.getItem() == oldStack.getItem() && ItemStack.areItemStackTagsEqual(newStack, oldStack) && (newStack.isItemStackDamageable() || newStack.getMetadata() == oldStack.getMetadata())); ++ } ++ ++ /** ++ * Called while an item is in 'active' use to determine if usage should continue. ++ * Allows items to continue being used while sustaining damage, for example. ++ * ++ * @param oldStack the previous 'active' stack ++ * @param newStack the stack currently in the active hand ++ * @return true to set the new stack to active and continue using it ++ */ ++ public boolean canContinueUsing(ItemStack oldStack, ItemStack newStack) { ++ return oldStack.equals(newStack); ++ } ++ ++ /** ++ * Called to get the Mod ID of the mod that *created* the ItemStack, ++ * instead of the real Mod ID that *registered* it. ++ * ++ * For example the Forge Universal Bucket creates a subitem for each modded fluid, ++ * and it returns the modded fluid's Mod ID here. ++ * ++ * Mods that register subitems for other mods can override this. ++ * Informational mods can call it to show the mod that created the item. ++ * ++ * @param itemStack the ItemStack to check ++ * @return the Mod ID for the ItemStack, or ++ * null when there is no specially associated mod and {@link #getRegistryName()} would return null. ++ */ ++ @Nullable ++ public String getCreatorModId(ItemStack itemStack) { ++ return net.minecraftforge.common.ForgeHooks.getDefaultCreatorModId(itemStack); ++ } ++ ++ /** ++ * Called from ItemStack.setItem, will hold extra data for the life of this ItemStack. ++ * Can be retrieved from stack.getCapabilities() ++ * The NBT can be null if this is not called from readNBT or if the item the stack is ++ * changing FROM is different then this item, or the previous item had no capabilities. ++ * ++ * This is called BEFORE the stacks item is set so you can use stack.getItem() to see the OLD item. ++ * Remember that getItem CAN return null. ++ * ++ * @param stack The ItemStack ++ * @param nbt NBT of this item serialized, or null. ++ * @return A holder instance associated with this ItemStack where you can hold capabilities for the life of this item. ++ */ ++ @Nullable ++ public net.minecraftforge.common.capabilities.ICapabilityProvider initCapabilities(ItemStack stack, @Nullable NBTTagCompound nbt) { ++ return null; ++ } ++ ++ public com.google.common.collect.ImmutableMap getAnimationParameters(final ItemStack stack, final World world, final EntityLivingBase entity) { ++ com.google.common.collect.ImmutableMap.Builder builder = com.google.common.collect.ImmutableMap.builder(); ++ for(ResourceLocation location : properties.getKeys()) { ++ final IItemPropertyGetter parameter = properties.getObject(location); ++ builder.put(location.toString(), new net.minecraftforge.common.animation.ITimeValue() { ++ public float apply(float input) { ++ return parameter.apply(stack, world, entity); ++ } ++ }); ++ } ++ return builder.build(); ++ } ++ ++ /** ++ * Can this Item disable a shield ++ * @param stack The ItemStack ++ * @param shield The shield in question ++ * @param entity The EntityLivingBase holding the shield ++ * @param attacker The EntityLivingBase holding the ItemStack ++ * @retrun True if this ItemStack can disable the shield in question. ++ */ ++ public boolean canDisableShield(ItemStack stack, ItemStack shield, EntityLivingBase entity, EntityLivingBase attacker) { ++ return this instanceof ItemAxe; ++ } ++ ++ /** ++ * Is this Item a shield ++ * @param stack The ItemStack ++ * @param entity The Entity holding the ItemStack ++ * @return True if the ItemStack is considered a shield ++ */ ++ public boolean isShield(ItemStack stack, @Nullable EntityLivingBase entity) { ++ return stack.getItem() == Items.SHIELD; ++ } ++ ++ /** ++ * @return the fuel burn time for this itemStack in a furnace. ++ * Return 0 to make it not act as a fuel. ++ * Return -1 to let the default vanilla logic decide. ++ */ ++ public int getItemBurnTime(ItemStack itemStack) { ++ return -1; ++ } ++ ++ /** ++ * Returns an enum constant of type {@code HorseArmorType}. ++ * The returned enum constant will be used to determine the armor value and texture of this item when equipped. ++ * @param stack the armor stack ++ * @return an enum constant of type {@code HorseArmorType}. Return HorseArmorType.NONE if this is not horse armor ++ */ ++ public net.minecraft.entity.passive.HorseArmorType getHorseArmorType(ItemStack stack) { ++ return net.minecraft.entity.passive.HorseArmorType.getByItem(stack.getItem()); ++ } ++ ++ public String getHorseArmorTexture(net.minecraft.entity.EntityLiving wearer, ItemStack stack) { ++ return getHorseArmorType(stack).getTextureName(); ++ } ++ ++ /** ++ * Called every tick from {@link EntityHorse#onUpdate()} on the item in the armor slot. ++ * @param world the world the horse is in ++ * @param horse the horse wearing this armor ++ * @param armor the armor itemstack ++ */ ++ public void onHorseArmorTick(World world, net.minecraft.entity.EntityLiving horse, ItemStack armor) {} ++ ++ @SideOnly(Side.CLIENT) ++ @Nullable ++ private net.minecraft.client.renderer.tileentity.TileEntityItemStackRenderer teisr; ++ ++ /** ++ * @return This Item's renderer, or the default instance if it does not have one. ++ */ ++ @SideOnly(Side.CLIENT) ++ public final net.minecraft.client.renderer.tileentity.TileEntityItemStackRenderer getTileEntityItemStackRenderer() { ++ return teisr != null ? teisr : net.minecraft.client.renderer.tileentity.TileEntityItemStackRenderer.instance; ++ } ++ ++ @SideOnly(Side.CLIENT) ++ public void setTileEntityItemStackRenderer(@Nullable net.minecraft.client.renderer.tileentity.TileEntityItemStackRenderer teisr) { ++ this.teisr = teisr; ++ } ++ ++ public net.minecraftforge.common.IRarity getForgeRarity(ItemStack stack) { ++ return this.getRarity(stack); ++ } ++ ++ /* ======================================== FORGE END =====================================*/ ++ + public static void registerItems() { + registerItemBlock(Blocks.AIR, new ItemAir(Blocks.AIR)); + registerItemBlock(Blocks.STONE, new ItemMultiTexture(Blocks.STONE, Blocks.STONE, new ItemMultiTexture.Mapper() { +@@ -999,6 +1710,8 @@ + private final float attackDamage; + /** Defines the natural enchantability factor of the material. */ + private final int enchantability; ++ //Added by forge for custom Tool materials. ++ private ItemStack repairMaterial = ItemStack.EMPTY; + + ToolMaterial(int harvestLevel, int maxUses, float efficiency, float damageVsEntity, int enchantability) { + this.harvestLevel = harvestLevel; +@@ -1033,6 +1746,7 @@ + return this.enchantability; + } + ++ @Deprecated // Use getRepairItemStack below + public Item getRepairItem() { + if (this == WOOD) { + return Item.getItemFromBlock(Blocks.PLANKS); +@@ -1046,5 +1760,19 @@ + return this == DIAMOND ? Items.DIAMOND : null; + } + } ++ ++ public ToolMaterial setRepairItem(ItemStack stack) { ++ if (!this.repairMaterial.isEmpty()) throw new RuntimeException("Repair material has already been set"); ++ if (this == WOOD || this == STONE || this == GOLD || this == IRON || this == DIAMOND) throw new RuntimeException("Can not change vanilla tool repair materials"); ++ this.repairMaterial = stack; ++ return this; ++ } ++ ++ public ItemStack getRepairItemStack() { ++ if (!repairMaterial.isEmpty()) return repairMaterial; ++ Item ret = this.getRepairItem(); ++ if (ret != null) repairMaterial = new ItemStack(ret, 1, net.minecraftforge.oredict.OreDictionary.WILDCARD_VALUE); ++ return repairMaterial; ++ } + } + } diff --git a/module/minecraft/patches/net/minecraft/item/ItemArmor.java.patch b/module/minecraft/patches/net/minecraft/item/ItemArmor.java.patch new file mode 100644 index 000000000..e03cd72f4 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/ItemArmor.java.patch @@ -0,0 +1,70 @@ +--- original/net/minecraft/item/ItemArmor.java ++++ modified/net/minecraft/item/ItemArmor.java +@@ -182,7 +182,9 @@ + */ + @Override + public boolean getIsRepairable(ItemStack toRepair, ItemStack repair) { +- return this.material.getRepairItem() == repair.getItem() ? true : super.getIsRepairable(toRepair, repair); ++ ItemStack mat = this.material.getRepairItemStack(); ++ if (!mat.isEmpty() && net.minecraftforge.oredict.OreDictionary.itemMatches(mat,repair,false)) return true; ++ return super.getIsRepairable(toRepair, repair); + } + + /** Called when the equipped item is right clicked. */ +@@ -217,6 +219,18 @@ + + return multimap; + } ++ /** ++ * Determines if this armor will be rendered with the secondary 'overlay' texture. ++ * If this is true, the first texture will be rendered using a tint of the color ++ * specified by getColor(ItemStack) ++ * ++ * @param stack The stack ++ * @return true/false ++ */ ++ public boolean hasOverlay(ItemStack stack) ++ { ++ return this.material == ItemArmor.ArmorMaterial.LEATHER || getColor(stack) != 0x00FFFFFF; ++ } + + public enum ArmorMaterial { + LEATHER("leather", 5, new int[]{1, 2, 3, 1}, 15, SoundEvents.ITEM_ARMOR_EQUIP_LEATHER, 0.0F), +@@ -234,6 +248,8 @@ + private final int enchantability; + private final SoundEvent soundEvent; + private final float toughness; ++ //Added by forge for custom Armor materials. ++ public ItemStack repairMaterial = ItemStack.EMPTY; + + ArmorMaterial(String nameIn, int maxDamageFactorIn, int[] damageReductionAmountArrayIn, int enchantabilityIn, SoundEvent soundEventIn, float toughnessIn) { + this.name = nameIn; +@@ -262,6 +278,7 @@ + public SoundEvent getSoundEvent() { + return this.soundEvent; + } ++ @Deprecated // Use getRepairItemStack below + + /** Get a main crafting component of this Armor Material (example is Items.iron_ingot) */ + public Item getRepairItem() { +@@ -286,5 +303,20 @@ + public float getToughness() { + return this.toughness; + } ++ public ArmorMaterial setRepairItem(ItemStack stack) ++ { ++ if (!this.repairMaterial.isEmpty()) throw new RuntimeException("Repair material has already been set"); ++ if (this == LEATHER || this == CHAIN || this == GOLD || this == IRON || this == DIAMOND) throw new RuntimeException("Can not change vanilla armor repair materials"); ++ this.repairMaterial = stack; ++ return this; ++ } ++ ++ public ItemStack getRepairItemStack() ++ { ++ if (!repairMaterial.isEmpty()) return repairMaterial; ++ Item ret = this.getRepairItem(); ++ if (ret != null) repairMaterial = new ItemStack(ret,1,net.minecraftforge.oredict.OreDictionary.WILDCARD_VALUE); ++ return repairMaterial; + } + } ++} diff --git a/module/minecraft/patches/net/minecraft/item/ItemArrow.java.patch b/module/minecraft/patches/net/minecraft/item/ItemArrow.java.patch new file mode 100644 index 000000000..37c643f0c --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/ItemArrow.java.patch @@ -0,0 +1,12 @@ +--- original/net/minecraft/item/ItemArrow.java ++++ modified/net/minecraft/item/ItemArrow.java +@@ -16,4 +16,9 @@ + entitytippedarrow.setPotionEffect(stack); + return entitytippedarrow; + } ++ ++ public boolean isInfinite(ItemStack stack, ItemStack bow, net.minecraft.entity.player.EntityPlayer player) { ++ int enchant = net.minecraft.enchantment.EnchantmentHelper.getEnchantmentLevel(net.minecraft.init.Enchantments.INFINITY, bow); ++ return enchant <= 0 ? false : this.getClass() == ItemArrow.class; ++ } + } diff --git a/module/minecraft/patches/net/minecraft/item/ItemAxe.java.patch b/module/minecraft/patches/net/minecraft/item/ItemAxe.java.patch new file mode 100644 index 000000000..063ddace2 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/ItemAxe.java.patch @@ -0,0 +1,15 @@ +--- original/net/minecraft/item/ItemAxe.java ++++ modified/net/minecraft/item/ItemAxe.java +@@ -30,6 +30,12 @@ + this.attackSpeed = ATTACK_SPEEDS[material.ordinal()]; + } + ++ protected ItemAxe(Item.ToolMaterial material, float damage, float speed) { ++ super(material, EFFECTIVE_ON); ++ this.attackDamage = damage; ++ this.attackSpeed = speed; ++ } ++ + @Override + public float getDestroySpeed(ItemStack stack, IBlockState state) { + Material material = state.getMaterial(); diff --git a/module/minecraft/patches/net/minecraft/item/ItemBed.java.patch b/module/minecraft/patches/net/minecraft/item/ItemBed.java.patch new file mode 100644 index 000000000..551f3be3a --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/ItemBed.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/item/ItemBed.java ++++ modified/net/minecraft/item/ItemBed.java +@@ -74,7 +74,7 @@ + .withProperty(BlockBed.PART, BlockBed.EnumPartType.FOOT); + worldIn.setBlockState(pos, iblockstate2, 10); + worldIn.setBlockState(blockpos, iblockstate2.withProperty(BlockBed.PART, BlockBed.EnumPartType.HEAD), 10); +- SoundType soundtype = iblockstate2.getBlock().getSoundType(); ++ SoundType soundtype = iblockstate2.getBlock().getSoundType(iblockstate2, worldIn, pos, player); + worldIn.playSound( + null, + pos, diff --git a/module/minecraft/patches/net/minecraft/item/ItemBlock.java.patch b/module/minecraft/patches/net/minecraft/item/ItemBlock.java.patch new file mode 100644 index 000000000..6c0422ea3 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/ItemBlock.java.patch @@ -0,0 +1,82 @@ +--- original/net/minecraft/item/ItemBlock.java ++++ modified/net/minecraft/item/ItemBlock.java +@@ -51,22 +51,15 @@ + + ItemStack itemstack = player.getHeldItem(hand); + if (!itemstack.isEmpty() +- && player.canPlayerEdit(pos, facing, itemstack) +- && worldIn.mayPlace(this.block, pos, false, facing, null)) { ++ && player.canPlayerEdit(pos, facing, itemstack) ++ && worldIn.mayPlace(this.block, pos, false, facing, player)) { + int i = this.getMetadata(itemstack.getMetadata()); + IBlockState iblockstate1 = this.block +- .getStateForPlacement(worldIn, pos, facing, hitX, hitY, hitZ, i, player); +- if (worldIn.setBlockState(pos, iblockstate1, 11)) { +- iblockstate1 = worldIn.getBlockState(pos); +- if (iblockstate1.getBlock() == this.block) { +- setTileEntityNBT(worldIn, player, pos, itemstack); +- this.block.onBlockPlacedBy(worldIn, pos, iblockstate1, player, itemstack); +- if (player instanceof EntityPlayerMP) { +- CriteriaTriggers.PLACED_BLOCK.trigger((EntityPlayerMP)player, pos, itemstack); +- } +- } ++ .getStateForPlacement(worldIn, pos, facing, hitX, hitY, hitZ, i, player, hand); + +- SoundType soundtype = this.block.getSoundType(); ++ if (placeBlockAt(itemstack, player, worldIn, pos, facing, hitX, hitY, hitZ, iblockstate1)) { ++ iblockstate1 = worldIn.getBlockState(pos); ++ SoundType soundtype = iblockstate1.getBlock().getSoundType(iblockstate1, worldIn, pos, player); + worldIn.playSound( + player, + pos, +@@ -118,13 +111,14 @@ + @SideOnly(Side.CLIENT) + public boolean canPlaceBlockOnSide(World worldIn, BlockPos pos, EnumFacing side, EntityPlayer player, ItemStack stack) { + Block block = worldIn.getBlockState(pos).getBlock(); +- if (block == Blocks.SNOW_LAYER) { ++ ++ if (block == Blocks.SNOW_LAYER && block.isReplaceable(worldIn, pos)) { + side = EnumFacing.UP; + } else if (!block.isReplaceable(worldIn, pos)) { + pos = pos.offset(side); + } + +- return worldIn.mayPlace(this.block, pos, false, side, null); ++ return worldIn.mayPlace(this.block, pos, false, side, player); + } + + /** Returns the unlocalized name of this item. This version accepts an ItemStack so different stacks can have different names based on their damage or NBT. */ +@@ -162,6 +156,33 @@ + } + + public Block getBlock() { ++ return this.getBlockRaw() == null ? null : this.getBlockRaw().delegate.get(); ++ } ++ ++ private Block getBlockRaw() { + return this.block; + } ++ ++ /** ++ * Called to actually place the block, after the location is determined ++ * and all permission checks have been made. ++ * ++ * @param stack The item stack that was used to place the block. This can be changed inside the method. ++ * @param player The player who is placing the block. Can be null if the block is not being placed by a player. ++ * @param side The side the player (or machine) right-clicked on. ++ */ ++ public boolean placeBlockAt(ItemStack stack, EntityPlayer player, World world, BlockPos pos, EnumFacing side, float hitX, float hitY, float hitZ, IBlockState newState) { ++ if (!world.setBlockState(pos, newState, 11)) return false; ++ ++ IBlockState state = world.getBlockState(pos); ++ if (state.getBlock() == this.block) { ++ setTileEntityNBT(world, player, pos, stack); ++ this.block.onBlockPlacedBy(world, pos, state, player, stack); ++ ++ if (player instanceof EntityPlayerMP) ++ CriteriaTriggers.PLACED_BLOCK.trigger((EntityPlayerMP)player, pos, stack); ++ } ++ ++ return true; ++ } + } diff --git a/module/minecraft/patches/net/minecraft/item/ItemBlockSpecial.java.patch b/module/minecraft/patches/net/minecraft/item/ItemBlockSpecial.java.patch new file mode 100644 index 000000000..c8c9c7c6b --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/ItemBlockSpecial.java.patch @@ -0,0 +1,39 @@ +--- original/net/minecraft/item/ItemBlockSpecial.java ++++ modified/net/minecraft/item/ItemBlockSpecial.java +@@ -44,10 +44,11 @@ + + ItemStack itemstack = player.getHeldItem(hand); + if (!itemstack.isEmpty() +- && player.canPlayerEdit(pos, facing, itemstack) +- && worldIn.mayPlace(this.block, pos, false, facing, null)) { ++ && player.canPlayerEdit(pos, facing, itemstack) ++ && worldIn.mayPlace(this.block, pos, false, facing, player)) { + IBlockState iblockstate1 = this.block +- .getStateForPlacement(worldIn, pos, facing, hitX, hitY, hitZ, 0, player); ++ .getStateForPlacement(worldIn, pos, facing, hitX, hitY, hitZ, 0, player, hand); ++ + if (!worldIn.setBlockState(pos, iblockstate1, 11)) { + return EnumActionResult.FAIL; + } +@@ -61,7 +62,7 @@ + } + } + +- SoundType soundtype = this.block.getSoundType(); ++ SoundType soundtype = iblockstate1.getBlock().getSoundType(iblockstate1, worldIn, pos, player); + worldIn.playSound( + player, + pos, +@@ -76,4 +77,12 @@ + return EnumActionResult.FAIL; + } + } ++ ++ public Block getBlock() { ++ return this.getBlockRaw() == null ? null : this.getBlockRaw().delegate.get(); ++ } ++ ++ private Block getBlockRaw() { ++ return this.block; ++ } + } diff --git a/module/minecraft/patches/net/minecraft/item/ItemBow.java.patch b/module/minecraft/patches/net/minecraft/item/ItemBow.java.patch new file mode 100644 index 000000000..8d1b8cdc2 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/ItemBow.java.patch @@ -0,0 +1,53 @@ +--- original/net/minecraft/item/ItemBow.java ++++ modified/net/minecraft/item/ItemBow.java +@@ -33,7 +33,7 @@ + if (entityIn == null) { + return 0.0F; + } else { +- return entityIn.getActiveItemStack().getItem() != Items.BOW ++ return !(entityIn.getActiveItemStack().getItem() instanceof ItemBow) + ? 0.0F + : (stack.getMaxItemUseDuration() - entityIn.getItemInUseCount()) / 20.0F; + } +@@ -79,18 +79,21 @@ + EntityPlayer entityplayer = (EntityPlayer)entityLiving; + boolean flag = entityplayer.capabilities.isCreativeMode || EnchantmentHelper.getEnchantmentLevel(Enchantments.INFINITY, stack) > 0; + ItemStack itemstack = this.findAmmo(entityplayer); ++ int i = this.getMaxItemUseDuration(stack) - timeLeft; ++ i = net.minecraftforge.event.ForgeEventFactory.onArrowLoose(stack, worldIn, entityplayer, i, !itemstack.isEmpty() || flag); ++ if (i < 0) return; + if (!itemstack.isEmpty() || flag) { + if (itemstack.isEmpty()) { + itemstack = new ItemStack(Items.ARROW); + } + +- int i = this.getMaxItemUseDuration(stack) - timeLeft; + float f = getArrowVelocity(i); + if (!(f < 0.1)) { +- boolean flag1 = flag && itemstack.getItem() == Items.ARROW; ++ boolean flag1 = entityplayer.capabilities.isCreativeMode || (itemstack.getItem() instanceof ItemArrow && ((ItemArrow) itemstack.getItem()).isInfinite(itemstack, stack, entityplayer)); + if (!worldIn.isRemote) { + ItemArrow itemarrow = (ItemArrow)(itemstack.getItem() instanceof ItemArrow ? itemstack.getItem() : Items.ARROW); + EntityArrow entityarrow = itemarrow.createArrow(worldIn, itemstack, entityplayer); ++ entityarrow = this.customizeArrow(entityarrow); + entityarrow.shoot(entityplayer, entityplayer.rotationPitch, entityplayer.rotationYaw, 0.0F, f * 3.0F, 1.0F); + if (f == 1.0F) { + entityarrow.setIsCritical(true); +@@ -171,6 +174,8 @@ + public ActionResult onItemRightClick(World worldIn, EntityPlayer playerIn, EnumHand handIn) { + ItemStack itemstack = playerIn.getHeldItem(handIn); + boolean flag = !this.findAmmo(playerIn).isEmpty(); ++ ActionResult ret = net.minecraftforge.event.ForgeEventFactory.onArrowNock(itemstack, worldIn, playerIn, handIn, flag); ++ if (ret != null) return ret; + if (playerIn.capabilities.isCreativeMode || flag) { + playerIn.setActiveHand(handIn); + return new ActionResult<>(EnumActionResult.SUCCESS, itemstack); +@@ -184,4 +189,8 @@ + public int getItemEnchantability() { + return 1; + } ++ public EntityArrow customizeArrow(EntityArrow arrow) ++ { ++ return arrow; + } ++} diff --git a/module/minecraft/patches/net/minecraft/item/ItemBucket.java.patch b/module/minecraft/patches/net/minecraft/item/ItemBucket.java.patch new file mode 100644 index 000000000..73a6bfd6f --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/ItemBucket.java.patch @@ -0,0 +1,26 @@ +--- original/net/minecraft/item/ItemBucket.java ++++ modified/net/minecraft/item/ItemBucket.java +@@ -40,6 +40,9 @@ + boolean flag = this.containedBlock == Blocks.AIR; + ItemStack itemstack = playerIn.getHeldItem(handIn); + RayTraceResult raytraceresult = this.rayTrace(worldIn, playerIn, flag); ++ ActionResult ret = net.minecraftforge.event.ForgeEventFactory.onBucketUse(playerIn, worldIn, itemstack, raytraceresult); ++ if (ret != null) return ret; ++ + if (raytraceresult == null) { + return new ActionResult<>(EnumActionResult.PASS, itemstack); + } +@@ -153,4 +156,13 @@ + + return true; + } ++ ++ @Override ++ public net.minecraftforge.common.capabilities.ICapabilityProvider initCapabilities(ItemStack stack, @Nullable net.minecraft.nbt.NBTTagCompound nbt) { ++ if (this.getClass() == ItemBucket.class) { ++ return new net.minecraftforge.fluids.capability.wrappers.FluidBucketWrapper(stack); ++ } else { ++ return super.initCapabilities(stack, nbt); ++ } ++ } + } diff --git a/module/minecraft/patches/net/minecraft/item/ItemBucketMilk.java.patch b/module/minecraft/patches/net/minecraft/item/ItemBucketMilk.java.patch new file mode 100644 index 000000000..bead550f6 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/ItemBucketMilk.java.patch @@ -0,0 +1,32 @@ +--- original/net/minecraft/item/ItemBucketMilk.java ++++ modified/net/minecraft/item/ItemBucketMilk.java +@@ -21,6 +21,7 @@ + /** Called when the player finishes using this Item (E.g. finishes eating.). Not called when the player stops using the Item before the action is complete. */ + @Override + public ItemStack onItemUseFinish(ItemStack stack, World worldIn, EntityLivingBase entityLiving) { ++ if (!worldIn.isRemote) entityLiving.curePotionEffects(stack); // FORGE - move up so stack.shrink does not turn stack into air + if (entityLiving instanceof EntityPlayerMP) { + EntityPlayerMP entityplayermp = (EntityPlayerMP)entityLiving; + CriteriaTriggers.CONSUME_ITEM.trigger(entityplayermp, stack); +@@ -31,10 +32,6 @@ + stack.shrink(1); + } + +- if (!worldIn.isRemote) { +- entityLiving.clearActivePotions(); +- } +- + return stack.isEmpty() ? new ItemStack(Items.BUCKET) : stack; + } + +@@ -52,6 +49,10 @@ + + /** Called when the equipped item is right clicked. */ + @Override ++ public net.minecraftforge.common.capabilities.ICapabilityProvider initCapabilities(ItemStack stack, net.minecraft.nbt.NBTTagCompound nbt) { ++ return new net.minecraftforge.fluids.capability.wrappers.FluidBucketWrapper(stack); ++ } ++ + public ActionResult onItemRightClick(World worldIn, EntityPlayer playerIn, EnumHand handIn) { + playerIn.setActiveHand(handIn); + return new ActionResult<>(EnumActionResult.SUCCESS, playerIn.getHeldItem(handIn)); diff --git a/module/minecraft/patches/net/minecraft/item/ItemDoor.java.patch b/module/minecraft/patches/net/minecraft/item/ItemDoor.java.patch new file mode 100644 index 000000000..6e402a2ff --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/ItemDoor.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/item/ItemDoor.java ++++ modified/net/minecraft/item/ItemDoor.java +@@ -50,7 +50,7 @@ + int j = enumfacing.getZOffset(); + boolean flag = i < 0 && hitZ < 0.5F || i > 0 && hitZ > 0.5F || j < 0 && hitX > 0.5F || j > 0 && hitX < 0.5F; + placeDoor(worldIn, pos, enumfacing, this.block, flag); +- SoundType soundtype = this.block.getSoundType(); ++ SoundType soundtype = worldIn.getBlockState(pos).getBlock().getSoundType(worldIn.getBlockState(pos), worldIn, pos, player); + worldIn.playSound( + player, + pos, diff --git a/module/minecraft/patches/net/minecraft/item/ItemDye.java.patch b/module/minecraft/patches/net/minecraft/item/ItemDye.java.patch new file mode 100644 index 000000000..efccbd22a --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/ItemDye.java.patch @@ -0,0 +1,60 @@ +--- original/net/minecraft/item/ItemDye.java ++++ modified/net/minecraft/item/ItemDye.java +@@ -58,7 +58,7 @@ + + EnumDyeColor enumdyecolor = EnumDyeColor.byDyeDamage(itemstack.getMetadata()); + if (enumdyecolor == EnumDyeColor.WHITE) { +- if (applyBonemeal(itemstack, worldIn, pos)) { ++ if (applyBonemeal(itemstack, worldIn, pos, player, hand)) { + if (!worldIn.isRemote) { + worldIn.playEvent(2005, pos, 0); + } +@@ -76,7 +76,7 @@ + pos = pos.offset(facing); + if (worldIn.isAirBlock(pos)) { + IBlockState iblockstate1 = Blocks.COCOA +- .getStateForPlacement(worldIn, pos, facing, hitX, hitY, hitZ, 0, player); ++ .getStateForPlacement(worldIn, pos, facing, hitX, hitY, hitZ, 0, player, hand); + worldIn.setBlockState(pos, iblockstate1, 10); + if (!player.capabilities.isCreativeMode) { + itemstack.shrink(1); +@@ -93,7 +93,17 @@ + } + + public static boolean applyBonemeal(ItemStack stack, World worldIn, BlockPos target) { ++ if (worldIn instanceof net.minecraft.world.WorldServer) ++ return applyBonemeal(stack, worldIn, target, net.minecraftforge.common.util.FakePlayerFactory.getMinecraft((net.minecraft.world.WorldServer)worldIn), null); ++ return false; ++ } ++ ++ public static boolean applyBonemeal(ItemStack stack, World worldIn, BlockPos target, EntityPlayer player, @javax.annotation.Nullable EnumHand hand) { + IBlockState iblockstate = worldIn.getBlockState(target); ++ ++ int hook = net.minecraftforge.event.ForgeEventFactory.onApplyBonemeal(player, worldIn, target, iblockstate, stack, hand); ++ if (hook != 0) return hook > 0; ++ + if (iblockstate.getBlock() instanceof IGrowable) { + IGrowable igrowable = (IGrowable)iblockstate.getBlock(); + if (igrowable.canGrow(worldIn, target, iblockstate, worldIn.isRemote)) { +@@ -134,6 +144,21 @@ + d2 + ); + } ++ } else { ++ for (int i1 = 0; i1 < amount; ++i1) { ++ double d0 = itemRand.nextGaussian() * 0.02; ++ double d1 = itemRand.nextGaussian() * 0.02; ++ double d2 = itemRand.nextGaussian() * 0.02; ++ worldIn.spawnParticle( ++ EnumParticleTypes.VILLAGER_HAPPY, ++ pos.getX() + itemRand.nextFloat(), ++ pos.getY() + itemRand.nextFloat() * 1.0f, ++ pos.getZ() + itemRand.nextFloat(), ++ d0, ++ d1, ++ d2 ++ ); ++ } + } + } + diff --git a/module/minecraft/patches/net/minecraft/item/ItemFlintAndSteel.java.patch b/module/minecraft/patches/net/minecraft/item/ItemFlintAndSteel.java.patch new file mode 100644 index 000000000..4e8dcca5e --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/ItemFlintAndSteel.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/item/ItemFlintAndSteel.java ++++ modified/net/minecraft/item/ItemFlintAndSteel.java +@@ -39,7 +39,7 @@ + return EnumActionResult.FAIL; + } + +- if (worldIn.getBlockState(pos).getMaterial() == Material.AIR) { ++ if (worldIn.isAirBlock(pos)) { + worldIn.playSound( + player, pos, SoundEvents.ITEM_FLINTANDSTEEL_USE, SoundCategory.BLOCKS, 1.0F, itemRand.nextFloat() * 0.4F + 0.8F + ); diff --git a/module/minecraft/patches/net/minecraft/item/ItemHoe.java.patch b/module/minecraft/patches/net/minecraft/item/ItemHoe.java.patch new file mode 100644 index 000000000..bb3648191 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/ItemHoe.java.patch @@ -0,0 +1,16 @@ +--- original/net/minecraft/item/ItemHoe.java ++++ modified/net/minecraft/item/ItemHoe.java +@@ -51,9 +51,12 @@ + return EnumActionResult.FAIL; + } + ++ int hook = net.minecraftforge.event.ForgeEventFactory.onHoeUse(itemstack, player, worldIn, pos); ++ if (hook != 0) return hook > 0 ? EnumActionResult.SUCCESS : EnumActionResult.FAIL; ++ + IBlockState iblockstate = worldIn.getBlockState(pos); + Block block = iblockstate.getBlock(); +- if (facing != EnumFacing.DOWN && worldIn.getBlockState(pos.up()).getMaterial() == Material.AIR) { ++ if (facing != EnumFacing.DOWN && worldIn.isAirBlock(pos.up())) { + if (block == Blocks.GRASS || block == Blocks.GRASS_PATH) { + this.setBlock(itemstack, player, worldIn, pos, Blocks.FARMLAND.getDefaultState()); + return EnumActionResult.SUCCESS; diff --git a/module/minecraft/patches/net/minecraft/item/ItemLilyPad.java.patch b/module/minecraft/patches/net/minecraft/item/ItemLilyPad.java.patch new file mode 100644 index 000000000..642b0872e --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/ItemLilyPad.java.patch @@ -0,0 +1,17 @@ +--- original/net/minecraft/item/ItemLilyPad.java ++++ modified/net/minecraft/item/ItemLilyPad.java +@@ -44,6 +44,14 @@ + if (iblockstate.getMaterial() == Material.WATER + && iblockstate.getValue(BlockLiquid.LEVEL) == 0 + && worldIn.isAirBlock(blockpos1)) { ++ // special case for handling block placement with water lilies ++ net.minecraftforge.common.util.BlockSnapshot blocksnapshot = net.minecraftforge.common.util.BlockSnapshot.getBlockSnapshot(worldIn, blockpos1); ++ worldIn.setBlockState(blockpos1, Blocks.WATERLILY.getDefaultState()); ++ if (net.minecraftforge.event.ForgeEventFactory.onPlayerBlockPlace(playerIn, blocksnapshot, net.minecraft.util.EnumFacing.UP, handIn).isCanceled()) ++ { ++ blocksnapshot.restore(true, false); ++ return new ActionResult(EnumActionResult.FAIL, itemstack); ++ } + worldIn.setBlockState(blockpos1, Blocks.WATERLILY.getDefaultState(), 11); + if (playerIn instanceof EntityPlayerMP) { + CriteriaTriggers.PLACED_BLOCK.trigger((EntityPlayerMP)playerIn, blockpos1, itemstack); diff --git a/module/minecraft/patches/net/minecraft/item/ItemMap.java.patch b/module/minecraft/patches/net/minecraft/item/ItemMap.java.patch new file mode 100644 index 000000000..cb3d6d74d --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/ItemMap.java.patch @@ -0,0 +1,44 @@ +--- original/net/minecraft/item/ItemMap.java ++++ modified/net/minecraft/item/ItemMap.java +@@ -39,7 +39,7 @@ + worldIn.setData(s, mapdata); + mapdata.scale = scale; + mapdata.calculateMapCenter(worldX, worldZ, mapdata.scale); +- mapdata.dimension = (byte)worldIn.provider.getDimensionType().getId(); ++ mapdata.dimension = worldIn.provider.getDimension(); + mapdata.trackingPosition = trackingPosition; + mapdata.unlimitedTracking = unlimitedTracking; + mapdata.markDirty(); +@@ -63,7 +63,7 @@ + mapdata = new MapData(s); + mapdata.scale = 3; + mapdata.calculateMapCenter(worldIn.getWorldInfo().getSpawnX(), worldIn.getWorldInfo().getSpawnZ(), mapdata.scale); +- mapdata.dimension = (byte)worldIn.provider.getDimensionType().getId(); ++ mapdata.dimension = worldIn.provider.getDimension(); + mapdata.markDirty(); + worldIn.setData(s, mapdata); + } +@@ -72,7 +72,7 @@ + } + + public void updateMapData(World worldIn, Entity viewer, MapData data) { +- if (worldIn.provider.getDimensionType().getId() == data.dimension && viewer instanceof EntityPlayer) { ++ if (worldIn.provider.getDimension() == data.dimension && viewer instanceof EntityPlayer) { + int i = 1 << data.scale; + int j = data.xCenter; + int k = data.zCenter; +@@ -206,10 +206,11 @@ + + /** Draws ambiguous landmasses representing unexplored terrain onto a treasure map */ + public static void renderBiomePreviewMap(World worldIn, ItemStack map) { +- if (map.getItem() == Items.FILLED_MAP) { +- MapData mapdata = Items.FILLED_MAP.getMapData(map, worldIn); ++ if (map.getItem() instanceof ItemMap) { ++ MapData mapdata = ((ItemMap) map.getItem()).getMapData(map, worldIn); ++ + if (mapdata != null) { +- if (worldIn.provider.getDimensionType().getId() == mapdata.dimension) { ++ if (worldIn.provider.getDimension() == mapdata.dimension) { + int i = 1 << mapdata.scale; + int j = mapdata.xCenter; + int k = mapdata.zCenter; diff --git a/module/minecraft/patches/net/minecraft/item/ItemMinecart.java.patch b/module/minecraft/patches/net/minecraft/item/ItemMinecart.java.patch new file mode 100644 index 000000000..1f9fc367b --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/ItemMinecart.java.patch @@ -0,0 +1,29 @@ +--- original/net/minecraft/item/ItemMinecart.java ++++ modified/net/minecraft/item/ItemMinecart.java +@@ -31,7 +31,7 @@ + BlockPos blockpos = source.getBlockPos().offset(enumfacing); + IBlockState iblockstate = world.getBlockState(blockpos); + BlockRailBase.EnumRailDirection blockrailbase$enumraildirection = iblockstate.getBlock() instanceof BlockRailBase +- ? iblockstate.getValue(((BlockRailBase)iblockstate.getBlock()).getShapeProperty()) ++ ? ((BlockRailBase)iblockstate.getBlock()).getRailDirection(world, blockpos, iblockstate, null) + : BlockRailBase.EnumRailDirection.NORTH_SOUTH; + double d3; + if (BlockRailBase.isRailBlock(iblockstate)) { +@@ -47,7 +47,7 @@ + + IBlockState iblockstate1 = world.getBlockState(blockpos.down()); + BlockRailBase.EnumRailDirection blockrailbase$enumraildirection1 = iblockstate1.getBlock() instanceof BlockRailBase +- ? iblockstate1.getValue(((BlockRailBase)iblockstate1.getBlock()).getShapeProperty()) ++ ? ((BlockRailBase)iblockstate1.getBlock()).getRailDirection(world, blockpos.down(), iblockstate1, null) + : BlockRailBase.EnumRailDirection.NORTH_SOUTH; + if (enumfacing != EnumFacing.DOWN && blockrailbase$enumraildirection1.isAscending()) { + d3 = -0.4; +@@ -101,7 +101,7 @@ + ItemStack itemstack = player.getHeldItem(hand); + if (!worldIn.isRemote) { + BlockRailBase.EnumRailDirection blockrailbase$enumraildirection = iblockstate.getBlock() instanceof BlockRailBase +- ? iblockstate.getValue(((BlockRailBase)iblockstate.getBlock()).getShapeProperty()) ++ ? ((BlockRailBase)iblockstate.getBlock()).getRailDirection(worldIn, pos, iblockstate, null) + : BlockRailBase.EnumRailDirection.NORTH_SOUTH; + double d0 = 0.0; + if (blockrailbase$enumraildirection.isAscending()) { diff --git a/module/minecraft/patches/net/minecraft/item/ItemMonsterPlacer.java.patch b/module/minecraft/patches/net/minecraft/item/ItemMonsterPlacer.java.patch new file mode 100644 index 000000000..a908a332d --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/ItemMonsterPlacer.java.patch @@ -0,0 +1,10 @@ +--- original/net/minecraft/item/ItemMonsterPlacer.java ++++ modified/net/minecraft/item/ItemMonsterPlacer.java +@@ -197,6 +197,7 @@ + entity.setLocationAndAngles(x, y, z, MathHelper.wrapDegrees(worldIn.rand.nextFloat() * 360.0F), 0.0F); + entityliving.rotationYawHead = entityliving.rotationYaw; + entityliving.renderYawOffset = entityliving.rotationYaw; ++ if (net.minecraftforge.event.ForgeEventFactory.doSpecialSpawn(entityliving, worldIn, (float) x, (float) y, (float) z, null)) return null; + entityliving.onInitialSpawn(worldIn.getDifficultyForLocation(new BlockPos(entityliving)), null); + worldIn.spawnEntity(entity); + entityliving.playLivingSound(); diff --git a/module/minecraft/patches/net/minecraft/item/ItemRedstone.java.patch b/module/minecraft/patches/net/minecraft/item/ItemRedstone.java.patch new file mode 100644 index 000000000..4de0c21a6 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/ItemRedstone.java.patch @@ -0,0 +1,13 @@ +--- original/net/minecraft/item/ItemRedstone.java ++++ modified/net/minecraft/item/ItemRedstone.java +@@ -32,8 +32,8 @@ + BlockPos blockpos = flag ? pos : pos.offset(facing); + ItemStack itemstack = player.getHeldItem(hand); + if (player.canPlayerEdit(blockpos, facing, itemstack) +- && worldIn.mayPlace(worldIn.getBlockState(blockpos).getBlock(), blockpos, false, facing, null) +- && Blocks.REDSTONE_WIRE.canPlaceBlockAt(worldIn, blockpos)) { ++ && worldIn.mayPlace(worldIn.getBlockState(blockpos).getBlock(), blockpos, false, facing, player) ++ && Blocks.REDSTONE_WIRE.canPlaceBlockAt(worldIn, blockpos)) { + worldIn.setBlockState(blockpos, Blocks.REDSTONE_WIRE.getDefaultState()); + if (player instanceof EntityPlayerMP) { + CriteriaTriggers.PLACED_BLOCK.trigger((EntityPlayerMP)player, blockpos, itemstack); diff --git a/module/minecraft/patches/net/minecraft/item/ItemSeedFood.java.patch b/module/minecraft/patches/net/minecraft/item/ItemSeedFood.java.patch new file mode 100644 index 000000000..61239ad84 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/ItemSeedFood.java.patch @@ -0,0 +1,42 @@ +--- original/net/minecraft/item/ItemSeedFood.java ++++ modified/net/minecraft/item/ItemSeedFood.java +@@ -8,7 +8,7 @@ + import net.minecraft.util.math.BlockPos; + import net.minecraft.world.World; + +-public class ItemSeedFood extends ItemFood { ++public class ItemSeedFood extends ItemFood implements net.minecraftforge.common.IPlantable { + private final Block crops; + /** Block ID of the soil this seed food should be planted on. */ + private final Block soilId; +@@ -32,10 +32,12 @@ + float hitZ + ) { + ItemStack itemstack = player.getHeldItem(hand); ++ ++ net.minecraft.block.state.IBlockState state = worldIn.getBlockState(pos); + if (facing == EnumFacing.UP +- && player.canPlayerEdit(pos.offset(facing), facing, itemstack) +- && worldIn.getBlockState(pos).getBlock() == this.soilId +- && worldIn.isAirBlock(pos.up())) { ++ && player.canPlayerEdit(pos.offset(facing), facing, itemstack) ++ && state.getBlock().canSustainPlant(state, worldIn, pos, EnumFacing.UP, this) ++ && worldIn.isAirBlock(pos.up())) { + worldIn.setBlockState(pos.up(), this.crops.getDefaultState(), 11); + itemstack.shrink(1); + return EnumActionResult.SUCCESS; +@@ -43,4 +45,14 @@ + return EnumActionResult.FAIL; + } + } ++ ++ @Override ++ public net.minecraftforge.common.EnumPlantType getPlantType(net.minecraft.world.IBlockAccess world, BlockPos pos) { ++ return net.minecraftforge.common.EnumPlantType.Crop; ++ } ++ ++ @Override ++ public net.minecraft.block.state.IBlockState getPlant(net.minecraft.world.IBlockAccess world, BlockPos pos) { ++ return this.crops.getDefaultState(); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/item/ItemSeeds.java.patch b/module/minecraft/patches/net/minecraft/item/ItemSeeds.java.patch new file mode 100644 index 000000000..cc1e76745 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/ItemSeeds.java.patch @@ -0,0 +1,42 @@ +--- original/net/minecraft/item/ItemSeeds.java ++++ modified/net/minecraft/item/ItemSeeds.java +@@ -11,7 +11,7 @@ + import net.minecraft.util.math.BlockPos; + import net.minecraft.world.World; + +-public class ItemSeeds extends Item { ++public class ItemSeeds extends Item implements net.minecraftforge.common.IPlantable { + private final Block crops; + /** BlockID of the block the seeds can be planted on. */ + private final Block soilBlockID; +@@ -35,10 +35,12 @@ + float hitZ + ) { + ItemStack itemstack = player.getHeldItem(hand); ++ ++ net.minecraft.block.state.IBlockState state = worldIn.getBlockState(pos); + if (facing == EnumFacing.UP +- && player.canPlayerEdit(pos.offset(facing), facing, itemstack) +- && worldIn.getBlockState(pos).getBlock() == this.soilBlockID +- && worldIn.isAirBlock(pos.up())) { ++ && player.canPlayerEdit(pos.offset(facing), facing, itemstack) ++ && state.getBlock().canSustainPlant(state, worldIn, pos, EnumFacing.UP, this) ++ && worldIn.isAirBlock(pos.up())) { + worldIn.setBlockState(pos.up(), this.crops.getDefaultState()); + if (player instanceof EntityPlayerMP) { + CriteriaTriggers.PLACED_BLOCK.trigger((EntityPlayerMP)player, pos.up(), itemstack); +@@ -50,4 +52,14 @@ + return EnumActionResult.FAIL; + } + } ++ ++ @Override ++ public net.minecraftforge.common.EnumPlantType getPlantType(net.minecraft.world.IBlockAccess world, BlockPos pos) { ++ return this.crops == net.minecraft.init.Blocks.NETHER_WART ? net.minecraftforge.common.EnumPlantType.Nether : net.minecraftforge.common.EnumPlantType.Crop; ++ } ++ ++ @Override ++ public net.minecraft.block.state.IBlockState getPlant(net.minecraft.world.IBlockAccess world, BlockPos pos) { ++ return this.crops.getDefaultState(); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/item/ItemShears.java.patch b/module/minecraft/patches/net/minecraft/item/ItemShears.java.patch new file mode 100644 index 000000000..9bb3d1eae --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/ItemShears.java.patch @@ -0,0 +1,74 @@ +--- original/net/minecraft/item/ItemShears.java ++++ modified/net/minecraft/item/ItemShears.java +@@ -24,6 +24,7 @@ + } + + Block block = state.getBlock(); ++ if (block instanceof net.minecraftforge.common.IShearable) return true; + return state.getMaterial() != Material.LEAVES + && block != Blocks.WEB + && block != Blocks.TALLGRASS +@@ -42,6 +43,63 @@ + } + + @Override ++ public boolean itemInteractionForEntity(ItemStack itemstack, net.minecraft.entity.player.EntityPlayer player, EntityLivingBase entity, net.minecraft.util.EnumHand hand) { ++ if (entity.world.isRemote) { ++ return false; ++ } ++ if (entity instanceof net.minecraftforge.common.IShearable) { ++ net.minecraftforge.common.IShearable target = (net.minecraftforge.common.IShearable)entity; ++ BlockPos pos = new BlockPos(entity.posX, entity.posY, entity.posZ); ++ if (target.isShearable(itemstack, entity.world, pos)) { ++ java.util.List drops = target.onSheared(itemstack, entity.world, pos, ++ net.minecraft.enchantment.EnchantmentHelper.getEnchantmentLevel(net.minecraft.init.Enchantments.FORTUNE, itemstack)); ++ ++ java.util.Random rand = new java.util.Random(); ++ for(ItemStack stack : drops) { ++ net.minecraft.entity.item.EntityItem ent = entity.entityDropItem(stack, 1.0F); ++ ent.motionY += rand.nextFloat() * 0.05F; ++ ent.motionX += (rand.nextFloat() - rand.nextFloat()) * 0.1F; ++ ent.motionZ += (rand.nextFloat() - rand.nextFloat()) * 0.1F; ++ } ++ itemstack.damageItem(1, entity); ++ } ++ return true; ++ } ++ return false; ++ } ++ ++ @Override ++ public boolean onBlockStartBreak(ItemStack itemstack, BlockPos pos, net.minecraft.entity.player.EntityPlayer player) { ++ if (player.world.isRemote || player.capabilities.isCreativeMode) { ++ return false; ++ } ++ Block block = player.world.getBlockState(pos).getBlock(); ++ if (block instanceof net.minecraftforge.common.IShearable) { ++ net.minecraftforge.common.IShearable target = (net.minecraftforge.common.IShearable)block; ++ if (target.isShearable(itemstack, player.world, pos)) { ++ java.util.List drops = target.onSheared(itemstack, player.world, pos, ++ net.minecraft.enchantment.EnchantmentHelper.getEnchantmentLevel(net.minecraft.init.Enchantments.FORTUNE, itemstack)); ++ java.util.Random rand = new java.util.Random(); ++ ++ for (ItemStack stack : drops) { ++ float f = 0.7F; ++ double d = (rand.nextFloat() * f) + (1.0F - f) * 0.5D; ++ double d1 = (rand.nextFloat() * f) + (1.0F - f) * 0.5D; ++ double d2 = (rand.nextFloat() * f) + (1.0F - f) * 0.5D; ++ net.minecraft.entity.item.EntityItem entityitem = new net.minecraft.entity.item.EntityItem(player.world, pos.getX() + d, pos.getY() + d1, pos.getZ() + d2, stack); ++ entityitem.setDefaultPickupDelay(); ++ player.world.spawnEntity(entityitem); ++ } ++ ++ itemstack.damageItem(1, player); ++ player.addStat(net.minecraft.stats.StatList.getBlockStats(block)); ++ player.world.setBlockState(pos, Blocks.AIR.getDefaultState(), 11); //TODO: Move to IShearable implementors in 1.12+ ++ return true; ++ } ++ } ++ return false; ++ } ++ + public float getDestroySpeed(ItemStack stack, IBlockState state) { + Block block = state.getBlock(); + if (block == Blocks.WEB || state.getMaterial() == Material.LEAVES) { diff --git a/module/minecraft/patches/net/minecraft/item/ItemSkull.java.patch b/module/minecraft/patches/net/minecraft/item/ItemSkull.java.patch new file mode 100644 index 000000000..97f3a6ef6 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/ItemSkull.java.patch @@ -0,0 +1,20 @@ +--- original/net/minecraft/item/ItemSkull.java ++++ modified/net/minecraft/item/ItemSkull.java +@@ -48,11 +48,16 @@ + return EnumActionResult.FAIL; + } + ++ if (worldIn.getBlockState(pos).getBlock().isReplaceable(worldIn, pos)) { ++ facing = EnumFacing.UP; ++ pos = pos.down(); ++ } ++ + IBlockState iblockstate = worldIn.getBlockState(pos); + Block block = iblockstate.getBlock(); + boolean flag = block.isReplaceable(worldIn, pos); + if (!flag) { +- if (!worldIn.getBlockState(pos).getMaterial().isSolid()) { ++ if (!worldIn.getBlockState(pos).getMaterial().isSolid() && !worldIn.isSideSolid(pos, facing, true)) { + return EnumActionResult.FAIL; + } + diff --git a/module/minecraft/patches/net/minecraft/item/ItemSlab.java.patch b/module/minecraft/patches/net/minecraft/item/ItemSlab.java.patch new file mode 100644 index 000000000..5bfff9bd9 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/ItemSlab.java.patch @@ -0,0 +1,28 @@ +--- original/net/minecraft/item/ItemSlab.java ++++ modified/net/minecraft/item/ItemSlab.java +@@ -70,9 +70,9 @@ + IBlockState iblockstate1 = this.makeState(iproperty, comparable1); + AxisAlignedBB axisalignedbb = iblockstate1.getCollisionBoundingBox(worldIn, pos); + if (axisalignedbb != Block.NULL_AABB +- && worldIn.checkNoEntityCollision(axisalignedbb.offset(pos)) +- && worldIn.setBlockState(pos, iblockstate1, 11)) { +- SoundType soundtype = this.doubleSlab.getSoundType(); ++ && worldIn.checkNoEntityCollision(axisalignedbb.offset(pos)) ++ && worldIn.setBlockState(pos, iblockstate1, 11)) { ++ SoundType soundtype = this.doubleSlab.getSoundType(iblockstate1, worldIn, pos, player); + worldIn.playSound( + player, + pos, +@@ -128,9 +128,9 @@ + IBlockState iblockstate1 = this.makeState(this.singleSlab.getVariantProperty(), comparable); + AxisAlignedBB axisalignedbb = iblockstate1.getCollisionBoundingBox(worldIn, pos); + if (axisalignedbb != Block.NULL_AABB +- && worldIn.checkNoEntityCollision(axisalignedbb.offset(pos)) +- && worldIn.setBlockState(pos, iblockstate1, 11)) { +- SoundType soundtype = this.doubleSlab.getSoundType(); ++ && worldIn.checkNoEntityCollision(axisalignedbb.offset(pos)) ++ && worldIn.setBlockState(pos, iblockstate1, 11)) { ++ SoundType soundtype = this.doubleSlab.getSoundType(iblockstate1, worldIn, pos, player); + worldIn.playSound( + player, + pos, diff --git a/module/minecraft/patches/net/minecraft/item/ItemSnow.java.patch b/module/minecraft/patches/net/minecraft/item/ItemSnow.java.patch new file mode 100644 index 000000000..8a13b55f2 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/ItemSnow.java.patch @@ -0,0 +1,26 @@ +--- original/net/minecraft/item/ItemSnow.java ++++ modified/net/minecraft/item/ItemSnow.java +@@ -50,9 +50,9 @@ + IBlockState iblockstate1 = iblockstate.withProperty(BlockSnow.LAYERS, i + 1); + AxisAlignedBB axisalignedbb = iblockstate1.getCollisionBoundingBox(worldIn, blockpos); + if (axisalignedbb != Block.NULL_AABB +- && worldIn.checkNoEntityCollision(axisalignedbb.offset(blockpos)) +- && worldIn.setBlockState(blockpos, iblockstate1, 10)) { +- SoundType soundtype = this.block.getSoundType(); ++ && worldIn.checkNoEntityCollision(axisalignedbb.offset(blockpos)) ++ && worldIn.setBlockState(blockpos, iblockstate1, 10)) { ++ SoundType soundtype = this.block.getSoundType(iblockstate1, worldIn, pos, player); + worldIn.playSound( + player, + blockpos, +@@ -82,4 +82,10 @@ + public int getMetadata(int damage) { + return damage; + } ++ ++ @Override ++ public boolean canPlaceBlockOnSide(World world, BlockPos pos, EnumFacing side, EntityPlayer player, ItemStack stack) { ++ IBlockState state = world.getBlockState(pos); ++ return state.getBlock() == net.minecraft.init.Blocks.SNOW_LAYER && state.getValue(BlockSnow.LAYERS) <= 7 || super.canPlaceBlockOnSide(world, pos, side, player, stack); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/item/ItemStack.java.patch b/module/minecraft/patches/net/minecraft/item/ItemStack.java.patch new file mode 100644 index 000000000..929392018 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/ItemStack.java.patch @@ -0,0 +1,402 @@ +--- original/net/minecraft/item/ItemStack.java ++++ modified/net/minecraft/item/ItemStack.java +@@ -50,7 +50,7 @@ + import net.minecraftforge.fml.relauncher.Side; + import net.minecraftforge.fml.relauncher.SideOnly; + +-public final class ItemStack { ++public final class ItemStack implements net.minecraftforge.common.capabilities.ICapabilitySerializable { + public static final ItemStack EMPTY = new ItemStack((Item)null); + public static final DecimalFormat DECIMALFORMAT = new DecimalFormat("#.##"); + /** Size of the stack. */ +@@ -69,6 +69,10 @@ + private Block canPlaceOnCacheBlock; + private boolean canPlaceOnCacheResult; + ++ private net.minecraftforge.registries.IRegistryDelegate delegate; ++ private net.minecraftforge.common.capabilities.CapabilityDispatcher capabilities; ++ private NBTTagCompound capNBT; ++ + public ItemStack(Block blockIn) { + this(blockIn, 1); + } +@@ -89,7 +93,9 @@ + this(itemIn, amount, 0); + } + +- public ItemStack(Item itemIn, int amount, int meta) { ++ public ItemStack(Item itemIn, int amount, int meta){ this(itemIn, amount, meta, null); } ++ public ItemStack(Item itemIn, int amount, int meta, @Nullable NBTTagCompound capNBT) { ++ this.capNBT = capNBT; + this.item = itemIn; + this.itemDamage = meta; + this.stackSize = amount; +@@ -98,6 +104,7 @@ + } + + this.updateEmptyState(); ++ this.forgeInit(); + } + + private void updateEmptyState() { +@@ -105,7 +112,8 @@ + } + + public ItemStack(NBTTagCompound compound) { +- this.item = Item.getByNameOrId(compound.getString("id")); ++ this.capNBT = compound.hasKey("ForgeCaps") ? compound.getCompoundTag("ForgeCaps") : null; ++ this.item = compound.hasKey("id", 8) ? Item.getByNameOrId(compound.getString("id")) : Items.AIR; //Forge fix tons of NumberFormatExceptions that are caused by deserializing EMPTY ItemStacks. + this.stackSize = compound.getByte("Count"); + this.itemDamage = Math.max(0, compound.getShort("Damage")); + if (compound.hasKey("tag", 10)) { +@@ -116,12 +124,17 @@ + } + + this.updateEmptyState(); ++ this.forgeInit(); + } + ++ private ItemStack(Item item, Object unused) { ++ this.item = item; ++ } ++ + public boolean isEmpty() { + if (this == EMPTY) { + return true; +- } else if (this.item == null || this.item == Item.getItemFromBlock(Blocks.AIR)) { ++ } else if (this.getItemRaw() == null || this.getItemRaw() == Items.AIR) { + return true; + } else { + return this.stackSize <= 0 ? true : this.itemDamage < -32768 || this.itemDamage > 65535; +@@ -144,7 +157,7 @@ + + /** Returns the object corresponding to the stack. */ + public Item getItem() { +- return this.isEmpty ? Item.getItemFromBlock(Blocks.AIR) : this.item; ++ return this.isEmpty || this.delegate == null ? Items.AIR : this.delegate.get(); + } + + /** Called when the player uses this ItemStack on a Block (right-click). Places blocks, etc. (Legacy name: tryPlaceItemIntoWorld) */ +@@ -158,6 +171,7 @@ + float hitY, + float hitZ + ) { ++ if (!worldIn.isRemote) return net.minecraftforge.common.ForgeHooks.onPlaceItemIntoWorld(this, playerIn, worldIn, pos, side, hitX, hitY, hitZ, hand); + EnumActionResult enumactionresult = this.getItem() + .onItemUse(playerIn, worldIn, pos, hand, side, hitX, hitY, hitZ); + if (enumactionresult == EnumActionResult.SUCCESS) { +@@ -167,6 +181,26 @@ + return enumactionresult; + } + ++ public EnumActionResult onItemUseFirst( ++ EntityPlayer playerIn, ++ World worldIn, ++ BlockPos pos, ++ EnumHand hand, ++ EnumFacing side, ++ float hitX, ++ float hitY, ++ float hitZ ++ ) { ++ // copy of onitemuse but for onitemusefirst ++ EnumActionResult enumactionresult = this.getItem().onItemUseFirst(playerIn, worldIn, pos, side, hitX, hitY, hitZ, hand); ++ ++ if (enumactionresult == EnumActionResult.SUCCESS) { ++ playerIn.addStat(StatList.getObjectUseStats(this.item)); ++ } ++ ++ return enumactionresult; ++ } ++ + public float getDestroySpeed(IBlockState blockIn) { + return this.getItem().getDestroySpeed(this, blockIn); + } +@@ -191,12 +225,17 @@ + nbt.setTag("tag", this.stackTagCompound); + } + ++ if (this.capabilities != null) { ++ NBTTagCompound cnbt = this.capabilities.serializeNBT(); ++ if (!cnbt.isEmpty()) nbt.setTag("ForgeCaps", cnbt); ++ } ++ + return nbt; + } + + /** Returns maximum size of the stack. */ + public int getMaxStackSize() { +- return this.getItem().getItemStackLimit(); ++ return this.getItem().getItemStackLimit(this); + } + + /** Returns true if the ItemStack can hold 2 or more units of the item. */ +@@ -209,7 +248,7 @@ + if (this.isEmpty) { + return false; + } else { +- return this.item.getMaxDamage() <= 0 ? false : !this.hasTagCompound() || !this.getTagCompound().getBoolean("Unbreakable"); ++ return this.item.getMaxDamage(this) <= 0 ? false : !this.hasTagCompound() || !this.getTagCompound().getBoolean("Unbreakable"); + } + } + +@@ -219,27 +258,24 @@ + + /** returns true when a damageable item is damaged */ + public boolean isItemDamaged() { +- return this.isItemStackDamageable() && this.itemDamage > 0; ++ return this.isItemStackDamageable() && getItem().isDamaged(this); + } + + public int getItemDamage() { +- return this.itemDamage; ++ return getItem().getDamage(this); + } + + public int getMetadata() { +- return this.itemDamage; ++ return getItem().getMetadata(this); + } + + public void setItemDamage(int meta) { +- this.itemDamage = meta; +- if (this.itemDamage < 0) { +- this.itemDamage = 0; +- } ++ getItem().setDamage(this, meta); + } + + /** Returns the max damage an item in the stack can take. */ + public int getMaxDamage() { +- return this.getItem().getMaxDamage(); ++ return this.getItem().getMaxDamage(this); + } + + /** Attempts to damage the ItemStack with par1 amount of damage, If the ItemStack has the Unbreaking enchantment there is a chance for each point of damage to be negated. Returns true if it takes more damage than getMaxDamage(). Returns false otherwise or if the ItemStack can't be damaged or if all points of damage are negated. */ +@@ -268,8 +304,8 @@ + CriteriaTriggers.ITEM_DURABILITY_CHANGED.trigger(damager, this, this.itemDamage + amount); + } + +- this.itemDamage += amount; +- return this.itemDamage > this.getMaxDamage(); ++ setItemDamage(getItemDamage() + amount); //Redirect through Item's callback if applicable. ++ return getItemDamage() > getMaxDamage(); + } + + /** Damages the item in the ItemStack */ +@@ -308,7 +344,7 @@ + + /** Check whether the given Block can be harvested using this ItemStack. */ + public boolean canHarvestBlock(IBlockState blockIn) { +- return this.getItem().canHarvestBlock(blockIn); ++ return this.getItem().canHarvestBlock(blockIn, this); + } + + public boolean interactWithEntity(EntityPlayer playerIn, EntityLivingBase entityIn, EnumHand hand) { +@@ -317,13 +353,27 @@ + + /** Returns a new stack with the same properties. */ + public ItemStack copy() { +- ItemStack itemstack = new ItemStack(this.item, this.stackSize, this.itemDamage); +- itemstack.setAnimationsToGo(this.getAnimationsToGo()); ++ if (this.isEmpty()) { ++ return EMPTY; ++ } ++ ItemStack copy = new ItemStack(this.item, null); ++ copy.stackSize = this.stackSize; ++ copy.itemDamage = this.itemDamage; ++ copy.animationsToGo = this.animationsToGo; + if (this.stackTagCompound != null) { +- itemstack.stackTagCompound = this.stackTagCompound.copy(); ++ copy.stackTagCompound = this.stackTagCompound.copy(); + } ++ if (this.capabilities != null) { ++ copy.capNBT = this.capabilities.serializeNBT(); ++ } ++ copy.delegate = this.delegate; ++ net.minecraftforge.common.capabilities.ICapabilityProvider provider = copy.item.initCapabilities(copy, copy.capNBT); ++ copy.capabilities = net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(copy, provider); ++ if (copy.capNBT != null && copy.capabilities != null) { ++ copy.capabilities.deserializeNBT(copy.capNBT); ++ } + +- return itemstack; ++ return copy; + } + + public static boolean areItemStackTagsEqual(ItemStack stackA, ItemStack stackB) { +@@ -333,8 +383,8 @@ + return false; + } else { + return stackA.stackTagCompound == null && stackB.stackTagCompound != null +- ? false +- : stackA.stackTagCompound == null || stackA.stackTagCompound.equals(stackB.stackTagCompound); ++ ? false ++ : stackA.stackTagCompound == null || stackA.stackTagCompound.equals(stackB.stackTagCompound) && stackA.areCapsCompatible(stackB); + } + } + +@@ -357,8 +407,8 @@ + return false; + } else { + return this.stackTagCompound == null && other.stackTagCompound != null +- ? false +- : this.stackTagCompound == null || this.stackTagCompound.equals(other.stackTagCompound); ++ ? false ++ : this.stackTagCompound == null || this.stackTagCompound.equals(other.stackTagCompound) && this.areCapsCompatible(other); + } + } + +@@ -646,6 +696,7 @@ + I18n.translateToLocal("attribute.name." + entry.getKey()) + ) + ); ++ list.add(" " + I18n.translateToLocalFormatted("attribute.modifier.equals." + attributemodifier.getOperation(), DECIMALFORMAT.format(d1), I18n.translateToLocal("attribute.name." + (String)entry.getKey()))); + } + } + } +@@ -700,6 +751,7 @@ + } + } + ++ net.minecraftforge.event.ForgeEventFactory.onItemTooltip(this, playerIn, list, advanced); + return list; + } + +@@ -708,6 +760,7 @@ + return this.getItem().hasEffect(this); + } + ++ @Deprecated // use Forge version on item + public EnumRarity getRarity() { + return this.getItem().getRarity(this); + } +@@ -808,7 +861,7 @@ + } + } + } else { +- multimap = this.getItem().getItemAttributeModifiers(equipmentSlot); ++ multimap = this.getItem().getAttributeModifiers(equipmentSlot, this); + } + + return multimap; +@@ -844,7 +897,7 @@ + if (!this.isEmpty) { + NBTTagCompound nbttagcompound = this.writeToNBT(new NBTTagCompound()); + itextcomponent.getStyle().setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_ITEM, new TextComponentString(nbttagcompound.toString()))); +- itextcomponent.getStyle().setColor(this.getRarity().color); ++ itextcomponent.getStyle().setColor(this.getItem().getForgeRarity(this).getColor()); + } + + return itextcomponent; +@@ -925,4 +978,110 @@ + public void shrink(int quantity) { + this.grow(-quantity); + } ++ ++ @Override ++ public boolean hasCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable net.minecraft.util.EnumFacing facing) { ++ return this.isEmpty || this.capabilities == null ? false : this.capabilities.hasCapability(capability, facing); ++ } ++ ++ @Override ++ @Nullable ++ public T getCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable net.minecraft.util.EnumFacing facing) { ++ return this.isEmpty || this.capabilities == null ? null : this.capabilities.getCapability(capability, facing); ++ } ++ ++ public void deserializeNBT(NBTTagCompound nbt) { ++ // TODO do this better while respecting new rules ++ final ItemStack itemStack = new ItemStack(nbt); ++ this.stackTagCompound = itemStack.stackTagCompound; ++ this.capNBT = itemStack.capNBT; ++ } ++ ++ public NBTTagCompound serializeNBT() { ++ NBTTagCompound ret = new NBTTagCompound(); ++ this.writeToNBT(ret); ++ return ret; ++ } ++ ++ public boolean areCapsCompatible(ItemStack other) { ++ if (this.capabilities == null) { ++ if (other.capabilities == null) { ++ return true; ++ } else { ++ return other.capabilities.areCompatible(null); ++ } ++ } else { ++ return this.capabilities.areCompatible(other.capabilities); ++ } ++ } ++ ++ /** ++ * Set up forge's ItemStack additions. ++ */ ++ private void forgeInit() { ++ Item item = getItemRaw(); ++ if (item != null) { ++ this.delegate = item.delegate; ++ net.minecraftforge.common.capabilities.ICapabilityProvider provider = item.initCapabilities(this, this.capNBT); ++ this.capabilities = net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(this, provider); ++ if (this.capNBT != null && this.capabilities != null) this.capabilities.deserializeNBT(this.capNBT); ++ } ++ } ++ ++ /** ++ * Internal call to get the actual item, not the delegate. ++ * In all other methods, FML replaces calls to this.item with the item delegate. ++ */ ++ @Nullable ++ private Item getItemRaw() { ++ return this.item; ++ } ++ ++ /** ++ * Modeled after ItemStack.areItemStacksEqual ++ * Uses Item.getNBTShareTag for comparison instead of NBT and capabilities. ++ * Only used for comparing itemStacks that were transferred from server to client using Item.getNBTShareTag. ++ */ ++ public static boolean areItemStacksEqualUsingNBTShareTag(ItemStack stackA, ItemStack stackB) { ++ if (stackA.isEmpty()) ++ return stackB.isEmpty(); ++ else ++ return !stackB.isEmpty() && stackA.isItemStackEqualUsingNBTShareTag(stackB); ++ } ++ ++ /** ++ * Modeled after ItemStack.isItemStackEqual ++ * Uses Item.getNBTShareTag for comparison instead of NBT and capabilities. ++ * Only used for comparing itemStacks that were transferred from server to client using Item.getNBTShareTag. ++ */ ++ private boolean isItemStackEqualUsingNBTShareTag(ItemStack other) { ++ return this.stackSize == other.stackSize && this.getItem() == other.getItem() && this.itemDamage == other.itemDamage && areItemStackShareTagsEqual(this, other); ++ } ++ ++ /** ++ * Modeled after ItemStack.areItemStackTagsEqual ++ * Uses Item.getNBTShareTag for comparison instead of NBT and capabilities. ++ * Only used for comparing itemStacks that were transferred from server to client using Item.getNBTShareTag. ++ */ ++ public static boolean areItemStackShareTagsEqual(ItemStack stackA, ItemStack stackB) { ++ NBTTagCompound shareTagA = stackA.getItem().getNBTShareTag(stackA); ++ NBTTagCompound shareTagB = stackB.getItem().getNBTShareTag(stackB); ++ if (shareTagA == null) ++ return shareTagB == null; ++ else ++ return shareTagB != null && shareTagA.equals(shareTagB); ++ } ++ ++ /** ++ * ++ * Should this item, when held, allow sneak-clicks to pass through to the underlying block? ++ * ++ * @param world The world ++ * @param pos Block position in world ++ * @param player The Player that is wielding the item ++ * @return ++ */ ++ public boolean doesSneakBypassUse(net.minecraft.world.IBlockAccess world, BlockPos pos, EntityPlayer player) { ++ return this.isEmpty() || this.getItem().doesSneakBypassUse(this, world, pos, player); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/item/ItemSword.java.patch b/module/minecraft/patches/net/minecraft/item/ItemSword.java.patch new file mode 100644 index 000000000..3ec0e030b --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/ItemSword.java.patch @@ -0,0 +1,13 @@ +--- original/net/minecraft/item/ItemSword.java ++++ modified/net/minecraft/item/ItemSword.java +@@ -98,7 +98,9 @@ + */ + @Override + public boolean getIsRepairable(ItemStack toRepair, ItemStack repair) { +- return this.material.getRepairItem() == repair.getItem() ? true : super.getIsRepairable(toRepair, repair); ++ ItemStack mat = this.material.getRepairItemStack(); ++ if (!mat.isEmpty() && net.minecraftforge.oredict.OreDictionary.itemMatches(mat, repair, false)) return true; ++ return super.getIsRepairable(toRepair, repair); + } + + /** Gets a map of item attribute modifiers, used by ItemSword to increase hit damage. */ diff --git a/module/minecraft/patches/net/minecraft/item/ItemTool.java.patch b/module/minecraft/patches/net/minecraft/item/ItemTool.java.patch new file mode 100644 index 000000000..863de2cd8 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/ItemTool.java.patch @@ -0,0 +1,62 @@ +--- original/net/minecraft/item/ItemTool.java ++++ modified/net/minecraft/item/ItemTool.java +@@ -33,6 +33,13 @@ + this.attackDamage = attackDamageIn + materialIn.getAttackDamage(); + this.attackSpeed = attackSpeedIn; + this.setCreativeTab(CreativeTabs.TOOLS); ++ if (this instanceof ItemPickaxe) { ++ toolClass = "pickaxe"; ++ } else if (this instanceof ItemAxe) { ++ toolClass = "axe"; ++ } else if (this instanceof ItemSpade) { ++ toolClass = "shovel"; ++ } + } + + protected ItemTool(Item.ToolMaterial materialIn, Set effectiveBlocksIn) { +@@ -41,6 +48,10 @@ + + @Override + public float getDestroySpeed(ItemStack stack, IBlockState state) { ++ for (String type : getToolClasses(stack)) { ++ if (state.getBlock().isToolEffective(type, state)) ++ return efficiency; ++ } + return this.effectiveBlocks.contains(state.getBlock()) ? this.efficiency : 1.0F; + } + +@@ -87,7 +98,9 @@ + */ + @Override + public boolean getIsRepairable(ItemStack toRepair, ItemStack repair) { +- return this.toolMaterial.getRepairItem() == repair.getItem() ? true : super.getIsRepairable(toRepair, repair); ++ ItemStack mat = this.toolMaterial.getRepairItemStack(); ++ if (!mat.isEmpty() && net.minecraftforge.oredict.OreDictionary.itemMatches(mat, repair, false)) return true; ++ return super.getIsRepairable(toRepair, repair); + } + + /** Gets a map of item attribute modifiers, used by ItemSword to increase hit damage. */ +@@ -101,4 +114,23 @@ + + return multimap; + } ++ ++ /*===================================== FORGE START =================================*/ ++ @javax.annotation.Nullable ++ private String toolClass; ++ @Override ++ public int getHarvestLevel(ItemStack stack, String toolClass, @javax.annotation.Nullable net.minecraft.entity.player.EntityPlayer player, @javax.annotation.Nullable IBlockState blockState) { ++ int level = super.getHarvestLevel(stack, toolClass, player, blockState); ++ if (level == -1 && toolClass.equals(this.toolClass)) { ++ return this.toolMaterial.getHarvestLevel(); ++ } else { ++ return level; ++ } ++ } ++ ++ @Override ++ public Set getToolClasses(ItemStack stack) { ++ return toolClass != null ? com.google.common.collect.ImmutableSet.of(toolClass) : super.getToolClasses(stack); ++ } ++ /*===================================== FORGE END =================================*/ + } diff --git a/module/minecraft/patches/net/minecraft/item/crafting/CraftingManager.java.patch b/module/minecraft/patches/net/minecraft/item/crafting/CraftingManager.java.patch new file mode 100644 index 000000000..d122d5ab5 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/crafting/CraftingManager.java.patch @@ -0,0 +1,40 @@ +--- original/net/minecraft/item/crafting/CraftingManager.java ++++ modified/net/minecraft/item/crafting/CraftingManager.java +@@ -33,7 +33,7 @@ + public class CraftingManager { + private static final Logger LOGGER = LogManager.getLogger(); + private static int nextAvailableId; +- public static final RegistryNamespaced REGISTRY = new RegistryNamespaced<>(); ++ public static final RegistryNamespaced REGISTRY = net.minecraftforge.registries.GameData.getWrapper(IRecipe.class); + + public static boolean init() { + try { +@@ -124,11 +124,13 @@ + } + } + +- public static void register(String name, IRecipe recipe) { ++ //Forge: Made private use GameData/Registry events! ++ private static void register(String name, IRecipe recipe) { + register(new ResourceLocation(name), recipe); + } + +- public static void register(ResourceLocation name, IRecipe recipe) { ++ //Forge: Made private use GameData/Registry events! ++ private static void register(ResourceLocation name, IRecipe recipe) { + if (REGISTRY.containsKey(name)) { + throw new IllegalStateException("Duplicate recipe ignored with ID " + name); + } +@@ -179,10 +181,12 @@ + return REGISTRY.getObject(name); + } + ++ @Deprecated //DO NOT USE THIS + public static int getIDForRecipe(IRecipe recipe) { + return REGISTRY.getIDForObject(recipe); + } + ++ @Deprecated //DO NOT USE THIS + @Nullable + public static IRecipe getRecipeById(int id) { + return REGISTRY.getObjectById(id); diff --git a/module/minecraft/patches/net/minecraft/item/crafting/FurnaceRecipes.java.patch b/module/minecraft/patches/net/minecraft/item/crafting/FurnaceRecipes.java.patch new file mode 100644 index 000000000..5a0ef1d47 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/crafting/FurnaceRecipes.java.patch @@ -0,0 +1,20 @@ +--- original/net/minecraft/item/crafting/FurnaceRecipes.java ++++ modified/net/minecraft/item/crafting/FurnaceRecipes.java +@@ -119,6 +119,7 @@ + + /** Adds a smelting recipe using an ItemStack as the input for the recipe. */ + public void addSmeltingRecipe(ItemStack input, ItemStack stack, float experience) { ++ if (getSmeltingResult(input) != ItemStack.EMPTY) { net.minecraftforge.fml.common.FMLLog.log.info("Ignored smelting recipe with conflicting input: {} = {}", input, stack); return; } + this.smeltingList.put(input, stack); + this.experienceList.put(stack, experience); + } +@@ -145,6 +146,9 @@ + } + + public float getSmeltingExperience(ItemStack stack) { ++ float ret = stack.getItem().getSmeltingExperience(stack); ++ if (ret != -1) return ret; ++ + for (Entry entry : this.experienceList.entrySet()) { + if (this.compareItemStacks(stack, entry.getKey())) { + return entry.getValue(); diff --git a/module/minecraft/patches/net/minecraft/item/crafting/IRecipe.java.patch b/module/minecraft/patches/net/minecraft/item/crafting/IRecipe.java.patch new file mode 100644 index 000000000..b7d2a63ca --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/crafting/IRecipe.java.patch @@ -0,0 +1,42 @@ +--- original/net/minecraft/item/crafting/IRecipe.java ++++ modified/net/minecraft/item/crafting/IRecipe.java +@@ -4,10 +4,8 @@ + import net.minecraft.item.ItemStack; + import net.minecraft.util.NonNullList; + import net.minecraft.world.World; +-import net.minecraftforge.fml.relauncher.Side; +-import net.minecraftforge.fml.relauncher.SideOnly; + +-public interface IRecipe { ++public interface IRecipe extends net.minecraftforge.registries.IForgeRegistryEntry { + /** Used to check if a recipe matches current crafting inventory */ + boolean matches(InventoryCrafting var1, World var2); + +@@ -15,13 +13,14 @@ + ItemStack getCraftingResult(InventoryCrafting var1); + + /** Used to determine if this recipe can fit in a grid of the given width/height */ +- @SideOnly(Side.CLIENT) + boolean canFit(int var1, int var2); + + /** Get the result of this recipe, usually for display purposes (e.g. recipe book). If your recipe has more than one possible result (e.g. it's dynamic and depends on its inputs), then return an empty stack. */ + ItemStack getRecipeOutput(); + +- NonNullList getRemainingItems(InventoryCrafting var1); ++ default NonNullList getRemainingItems(InventoryCrafting inv) { ++ return net.minecraftforge.common.ForgeHooks.defaultRecipeGetRemainingItems(inv); ++ } + + default NonNullList getIngredients() { + return NonNullList.create(); +@@ -32,9 +31,7 @@ + return false; + } + +- /** Recipes with equal group are combined into one button in the recipe book */ +- @SideOnly(Side.CLIENT) +- default String getGroup() { ++default String getGroup() { + return ""; + } + } diff --git a/module/minecraft/patches/net/minecraft/item/crafting/Ingredient.java.patch b/module/minecraft/patches/net/minecraft/item/crafting/Ingredient.java.patch new file mode 100644 index 000000000..0fe213e9c --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/crafting/Ingredient.java.patch @@ -0,0 +1,102 @@ +--- original/net/minecraft/item/crafting/Ingredient.java ++++ modified/net/minecraft/item/crafting/Ingredient.java +@@ -9,10 +9,10 @@ + import net.minecraft.client.util.RecipeItemHelper; + import net.minecraft.item.Item; + import net.minecraft.item.ItemStack; +-import net.minecraftforge.fml.relauncher.Side; +-import net.minecraftforge.fml.relauncher.SideOnly; + + public class Ingredient implements Predicate { ++ // Invalidate Mojang's caches ++ private static final java.util.Set INSTANCES = java.util.Collections.newSetFromMap(new java.util.WeakHashMap()); + public static final Ingredient EMPTY = new Ingredient() { + @Override + public boolean apply(@Nullable ItemStack p_apply_1_) { +@@ -20,15 +20,35 @@ + } + }; + private final ItemStack[] matchingStacks; ++ private final ItemStack[] matchingStacksExploded; + private IntList matchingStacksPacked; ++ private final boolean isSimple; + ++ protected Ingredient(int size) { ++ this(new ItemStack[size]); ++ } ++ + protected Ingredient(ItemStack... p_i47503_1_) { ++ boolean simple = true; + this.matchingStacks = p_i47503_1_; ++ net.minecraft.util.NonNullList lst = net.minecraft.util.NonNullList.create(); ++ for (ItemStack s : p_i47503_1_) { ++ if (s.isEmpty()) ++ continue; ++ if (s.getItem().isDamageable()) ++ simple = false; ++ if (s.getMetadata() == net.minecraftforge.oredict.OreDictionary.WILDCARD_VALUE) ++ s.getItem().getSubItems(net.minecraft.creativetab.CreativeTabs.SEARCH, lst); ++ else ++ lst.add(s); ++ } ++ this.matchingStacksExploded = lst.toArray(new ItemStack[lst.size()]); ++ this.isSimple = simple && this.matchingStacksExploded.length > 0; ++ Ingredient.INSTANCES.add(this); + } + +- @SideOnly(Side.CLIENT) + public ItemStack[] getMatchingStacks() { +- return this.matchingStacks; ++ return this.matchingStacksExploded; + } + + public boolean apply(@Nullable ItemStack p_apply_1_) { +@@ -50,9 +70,9 @@ + + public IntList getValidItemStacksPacked() { + if (this.matchingStacksPacked == null) { +- this.matchingStacksPacked = new IntArrayList(this.matchingStacks.length); ++ this.matchingStacksPacked = new IntArrayList(this.matchingStacksExploded.length); + +- for (ItemStack itemstack : this.matchingStacks) { ++ for (ItemStack itemstack : this.matchingStacksExploded) { + this.matchingStacksPacked.add(RecipeItemHelper.pack(itemstack)); + } + +@@ -62,6 +82,16 @@ + return this.matchingStacksPacked; + } + ++ public static void invalidateAll() { ++ for (Ingredient ing : INSTANCES) ++ if (ing != null) ++ ing.invalidate(); ++ } ++ ++ protected void invalidate() { ++ this.matchingStacksPacked = null; ++ } ++ + public static Ingredient fromItem(Item p_193367_0_) { + return fromStacks(new ItemStack(p_193367_0_, 1, 32767)); + } +@@ -87,4 +117,19 @@ + + return EMPTY; + } ++ ++ // Merges several vanilla Ingredients together. As a qwerk of how the json is structured, we can't tell if its a single Ingredient type or multiple so we split per item and remerge here. ++ //Only public for internal use, so we can access a private field in here. ++ public static Ingredient merge(java.util.Collection parts) { ++ net.minecraft.util.NonNullList lst = net.minecraft.util.NonNullList.create(); ++ for (Ingredient part : parts) { ++ for (ItemStack stack : part.matchingStacks) ++ lst.add(stack); ++ } ++ return new Ingredient(lst.toArray(new ItemStack[lst.size()])); ++ } ++ ++ public boolean isSimple() { ++ return isSimple || this == EMPTY; ++ } + } diff --git a/module/minecraft/patches/net/minecraft/item/crafting/RecipeBookCloning.java.patch b/module/minecraft/patches/net/minecraft/item/crafting/RecipeBookCloning.java.patch new file mode 100644 index 000000000..3a32a56ed --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/crafting/RecipeBookCloning.java.patch @@ -0,0 +1,24 @@ +--- original/net/minecraft/item/crafting/RecipeBookCloning.java ++++ modified/net/minecraft/item/crafting/RecipeBookCloning.java +@@ -6,11 +6,8 @@ + import net.minecraft.item.ItemWrittenBook; + import net.minecraft.util.NonNullList; + import net.minecraft.world.World; +-import net.minecraftforge.fml.relauncher.Side; +-import net.minecraftforge.fml.relauncher.SideOnly; + +-public class RecipeBookCloning implements IRecipe { +- /** Used to check if a recipe matches current crafting inventory */ ++public class RecipeBookCloning extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe { + @Override + public boolean matches(InventoryCrafting inv, World worldIn) { + int i = 0; +@@ -106,8 +103,6 @@ + return true; + } + +- /** Used to determine if this recipe can fit in a grid of the given width/height */ +- @SideOnly(Side.CLIENT) + @Override + public boolean canFit(int width, int height) { + return width >= 3 && height >= 3; diff --git a/module/minecraft/patches/net/minecraft/item/crafting/RecipeFireworks.java.patch b/module/minecraft/patches/net/minecraft/item/crafting/RecipeFireworks.java.patch new file mode 100644 index 000000000..c3fbf9982 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/crafting/RecipeFireworks.java.patch @@ -0,0 +1,66 @@ +--- original/net/minecraft/item/crafting/RecipeFireworks.java ++++ modified/net/minecraft/item/crafting/RecipeFireworks.java +@@ -10,10 +10,8 @@ + import net.minecraft.nbt.NBTTagList; + import net.minecraft.util.NonNullList; + import net.minecraft.world.World; +-import net.minecraftforge.fml.relauncher.Side; +-import net.minecraftforge.fml.relauncher.SideOnly; + +-public class RecipeFireworks implements IRecipe { ++public class RecipeFireworks extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe { + private ItemStack resultItem = ItemStack.EMPTY; + + /** Used to check if a recipe matches current crafting inventory */ +@@ -34,7 +32,7 @@ + j++; + } else if (itemstack.getItem() == Items.FIREWORK_CHARGE) { + l++; +- } else if (itemstack.getItem() == Items.DYE) { ++ } else if (net.minecraftforge.oredict.DyeUtils.isDye(itemstack)) { + k++; + } else if (itemstack.getItem() == Items.PAPER) { + i++; +@@ -96,8 +94,8 @@ + for (int l1 = 0; l1 < inv.getSizeInventory(); l1++) { + ItemStack itemstack2 = inv.getStackInSlot(l1); + if (!itemstack2.isEmpty()) { +- if (itemstack2.getItem() == Items.DYE) { +- list.add(ItemDye.DYE_COLORS[itemstack2.getMetadata() & 15]); ++ if (net.minecraftforge.oredict.DyeUtils.isDye(itemstack2)) { ++ list.add(ItemDye.DYE_COLORS[net.minecraftforge.oredict.DyeUtils.rawDyeDamageFromStack(itemstack2) & 15]); + } else if (itemstack2.getItem() == Items.GLOWSTONE_DUST) { + nbttagcompound2.setBoolean("Flicker", true); + } else if (itemstack2.getItem() == Items.DIAMOND) { +@@ -131,8 +129,8 @@ + for (int i2 = 0; i2 < inv.getSizeInventory(); i2++) { + ItemStack itemstack1 = inv.getStackInSlot(i2); + if (!itemstack1.isEmpty()) { +- if (itemstack1.getItem() == Items.DYE) { +- list1.add(ItemDye.DYE_COLORS[itemstack1.getMetadata() & 15]); ++ if (net.minecraftforge.oredict.DyeUtils.isDye(itemstack1)) { ++ list1.add(ItemDye.DYE_COLORS[net.minecraftforge.oredict.DyeUtils.rawDyeDamageFromStack(itemstack1) & 15]); + } else if (itemstack1.getItem() == Items.FIREWORK_CHARGE) { + this.resultItem = itemstack1.copy(); + this.resultItem.setCount(1); +@@ -180,9 +178,8 @@ + + for (int i = 0; i < nonnulllist.size(); i++) { + ItemStack itemstack = inv.getStackInSlot(i); +- if (itemstack.getItem().hasContainerItem()) { +- nonnulllist.set(i, new ItemStack(itemstack.getItem().getContainerItem())); +- } ++ ++ nonnulllist.set(i, net.minecraftforge.common.ForgeHooks.getContainerItem(itemstack)); + } + + return nonnulllist; +@@ -194,8 +191,6 @@ + return true; + } + +- /** Used to determine if this recipe can fit in a grid of the given width/height */ +- @SideOnly(Side.CLIENT) + @Override + public boolean canFit(int width, int height) { + return width * height >= 1; diff --git a/module/minecraft/patches/net/minecraft/item/crafting/RecipeRepairItem.java.patch b/module/minecraft/patches/net/minecraft/item/crafting/RecipeRepairItem.java.patch new file mode 100644 index 000000000..8a1391fe2 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/crafting/RecipeRepairItem.java.patch @@ -0,0 +1,85 @@ +--- original/net/minecraft/item/crafting/RecipeRepairItem.java ++++ modified/net/minecraft/item/crafting/RecipeRepairItem.java +@@ -7,11 +7,8 @@ + import net.minecraft.item.ItemStack; + import net.minecraft.util.NonNullList; + import net.minecraft.world.World; +-import net.minecraftforge.fml.relauncher.Side; +-import net.minecraftforge.fml.relauncher.SideOnly; + +-public class RecipeRepairItem implements IRecipe { +- /** Used to check if a recipe matches current crafting inventory */ ++public class RecipeRepairItem extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe { + @Override + public boolean matches(InventoryCrafting inv, World worldIn) { + List list = Lists.newArrayList(); +@@ -23,9 +20,9 @@ + if (list.size() > 1) { + ItemStack itemstack1 = list.get(0); + if (itemstack.getItem() != itemstack1.getItem() +- || itemstack1.getCount() != 1 +- || itemstack.getCount() != 1 +- || !itemstack1.getItem().isDamageable()) { ++ || itemstack1.getCount() != 1 ++ || itemstack.getCount() != 1 ++ || !itemstack1.getItem().isRepairable()) { + return false; + } + } +@@ -47,9 +44,9 @@ + if (list.size() > 1) { + ItemStack itemstack1 = list.get(0); + if (itemstack.getItem() != itemstack1.getItem() +- || itemstack1.getCount() != 1 +- || itemstack.getCount() != 1 +- || !itemstack1.getItem().isDamageable()) { ++ || itemstack1.getCount() != 1 ++ || itemstack.getCount() != 1 ++ || !itemstack1.getItem().isRepairable()) { + return ItemStack.EMPTY; + } + } +@@ -60,14 +57,15 @@ + ItemStack itemstack2 = list.get(0); + ItemStack itemstack3 = list.get(1); + if (itemstack2.getItem() == itemstack3.getItem() +- && itemstack2.getCount() == 1 +- && itemstack3.getCount() == 1 +- && itemstack2.getItem().isDamageable()) { +- Item item = itemstack2.getItem(); +- int j = item.getMaxDamage() - itemstack2.getItemDamage(); +- int k = item.getMaxDamage() - itemstack3.getItemDamage(); +- int l = j + k + item.getMaxDamage() * 5 / 100; +- int i1 = item.getMaxDamage() - l; ++ && itemstack2.getCount() == 1 ++ && itemstack3.getCount() == 1 ++ && itemstack2.getItem().isRepairable()) { ++ // FORGE: Make itemstack sensitive // Item item = itemstack2.getItem(); ++ int j = itemstack2.getMaxDamage() - itemstack2.getItemDamage(); ++ int k = itemstack2.getMaxDamage() - itemstack3.getItemDamage(); ++ int l = j + k + itemstack2.getMaxDamage() * 5 / 100; ++ int i1 = itemstack2.getMaxDamage() - l; ++ + if (i1 < 0) { + i1 = 0; + } +@@ -91,9 +89,7 @@ + + for (int i = 0; i < nonnulllist.size(); i++) { + ItemStack itemstack = inv.getStackInSlot(i); +- if (itemstack.getItem().hasContainerItem()) { +- nonnulllist.set(i, new ItemStack(itemstack.getItem().getContainerItem())); +- } ++ nonnulllist.set(i, net.minecraftforge.common.ForgeHooks.getContainerItem(itemstack)); + } + + return nonnulllist; +@@ -105,8 +101,6 @@ + return true; + } + +- /** Used to determine if this recipe can fit in a grid of the given width/height */ +- @SideOnly(Side.CLIENT) + @Override + public boolean canFit(int width, int height) { + return width * height >= 2; diff --git a/module/minecraft/patches/net/minecraft/item/crafting/RecipeTippedArrow.java.patch b/module/minecraft/patches/net/minecraft/item/crafting/RecipeTippedArrow.java.patch new file mode 100644 index 000000000..4d5d51acb --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/crafting/RecipeTippedArrow.java.patch @@ -0,0 +1,24 @@ +--- original/net/minecraft/item/crafting/RecipeTippedArrow.java ++++ modified/net/minecraft/item/crafting/RecipeTippedArrow.java +@@ -7,11 +7,8 @@ + import net.minecraft.potion.PotionUtils; + import net.minecraft.util.NonNullList; + import net.minecraft.world.World; +-import net.minecraftforge.fml.relauncher.Side; +-import net.minecraftforge.fml.relauncher.SideOnly; + +-public class RecipeTippedArrow implements IRecipe { +- /** Used to check if a recipe matches current crafting inventory */ ++public class RecipeTippedArrow extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe { + @Override + public boolean matches(InventoryCrafting inv, World worldIn) { + if (inv.getWidth() == 3 && inv.getHeight() == 3) { +@@ -70,8 +67,6 @@ + return true; + } + +- /** Used to determine if this recipe can fit in a grid of the given width/height */ +- @SideOnly(Side.CLIENT) + @Override + public boolean canFit(int width, int height) { + return width >= 2 && height >= 2; diff --git a/module/minecraft/patches/net/minecraft/item/crafting/RecipesArmorDyes.java.patch b/module/minecraft/patches/net/minecraft/item/crafting/RecipesArmorDyes.java.patch new file mode 100644 index 000000000..06709ff5f --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/crafting/RecipesArmorDyes.java.patch @@ -0,0 +1,58 @@ +--- original/net/minecraft/item/crafting/RecipesArmorDyes.java ++++ modified/net/minecraft/item/crafting/RecipesArmorDyes.java +@@ -9,11 +9,8 @@ + import net.minecraft.item.ItemStack; + import net.minecraft.util.NonNullList; + import net.minecraft.world.World; +-import net.minecraftforge.fml.relauncher.Side; +-import net.minecraftforge.fml.relauncher.SideOnly; + +-public class RecipesArmorDyes implements IRecipe { +- /** Used to check if a recipe matches current crafting inventory */ ++public class RecipesArmorDyes extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe { + @Override + public boolean matches(InventoryCrafting inv, World worldIn) { + ItemStack itemstack = ItemStack.EMPTY; +@@ -30,7 +27,7 @@ + + itemstack = itemstack1; + } else { +- if (itemstack1.getItem() != Items.DYE) { ++ if (!net.minecraftforge.oredict.DyeUtils.isDye(itemstack1)) { + return false; + } + +@@ -74,11 +71,11 @@ + j++; + } + } else { +- if (itemstack1.getItem() != Items.DYE) { ++ if (!net.minecraftforge.oredict.DyeUtils.isDye(itemstack1)) { + return ItemStack.EMPTY; + } + +- float[] afloat = EnumDyeColor.byDyeDamage(itemstack1.getMetadata()).getColorComponentValues(); ++ float[] afloat = net.minecraftforge.oredict.DyeUtils.colorFromStack(itemstack1).get().getColorComponentValues(); + int l1 = (int)(afloat[0] * 255.0F); + int i2 = (int)(afloat[1] * 255.0F); + int j2 = (int)(afloat[2] * 255.0F); +@@ -122,9 +119,7 @@ + + for (int i = 0; i < nonnulllist.size(); i++) { + ItemStack itemstack = inv.getStackInSlot(i); +- if (itemstack.getItem().hasContainerItem()) { +- nonnulllist.set(i, new ItemStack(itemstack.getItem().getContainerItem())); +- } ++ nonnulllist.set(i, net.minecraftforge.common.ForgeHooks.getContainerItem(itemstack)); + } + + return nonnulllist; +@@ -136,8 +131,6 @@ + return true; + } + +- /** Used to determine if this recipe can fit in a grid of the given width/height */ +- @SideOnly(Side.CLIENT) + @Override + public boolean canFit(int width, int height) { + return width * height >= 2; diff --git a/module/minecraft/patches/net/minecraft/item/crafting/RecipesBanners.java.patch b/module/minecraft/patches/net/minecraft/item/crafting/RecipesBanners.java.patch new file mode 100644 index 000000000..4a689ec3d --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/crafting/RecipesBanners.java.patch @@ -0,0 +1,91 @@ +--- original/net/minecraft/item/crafting/RecipesBanners.java ++++ modified/net/minecraft/item/crafting/RecipesBanners.java +@@ -12,11 +12,9 @@ + import net.minecraft.tileentity.TileEntityBanner; + import net.minecraft.util.NonNullList; + import net.minecraft.world.World; +-import net.minecraftforge.fml.relauncher.Side; +-import net.minecraftforge.fml.relauncher.SideOnly; + + public class RecipesBanners { +- public static class RecipeAddPattern implements IRecipe { ++ public static class RecipeAddPattern extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe { + /** Used to check if a recipe matches current crafting inventory */ + @Override + public boolean matches(InventoryCrafting inv, World worldIn) { +@@ -60,8 +58,9 @@ + + for (int j = 0; j < inv.getSizeInventory(); j++) { + ItemStack itemstack2 = inv.getStackInSlot(j); +- if (itemstack2.getItem() == Items.DYE) { +- k = itemstack2.getMetadata(); ++ int color = net.minecraftforge.oredict.DyeUtils.rawDyeDamageFromStack(itemstack2); ++ if (color != -1) { ++ k = color; + break; + } + } +@@ -96,9 +95,7 @@ + + for (int i = 0; i < nonnulllist.size(); i++) { + ItemStack itemstack = inv.getStackInSlot(i); +- if (itemstack.getItem().hasContainerItem()) { +- nonnulllist.set(i, new ItemStack(itemstack.getItem().getContainerItem())); +- } ++ nonnulllist.set(i, net.minecraftforge.common.ForgeHooks.getContainerItem(itemstack)); + } + + return nonnulllist; +@@ -116,7 +113,7 @@ + for (int i = 0; i < p_190933_1_.getSizeInventory() && flag; i++) { + ItemStack itemstack = p_190933_1_.getStackInSlot(i); + if (!itemstack.isEmpty() && itemstack.getItem() != Items.BANNER) { +- if (itemstack.getItem() == Items.DYE) { ++ if (net.minecraftforge.oredict.DyeUtils.isDye(itemstack)) { + if (flag2) { + flag = false; + break; +@@ -145,7 +142,7 @@ + int i1 = k % 3; + ItemStack itemstack1 = p_190933_1_.getStackInSlot(k); + if (!itemstack1.isEmpty() && itemstack1.getItem() != Items.BANNER) { +- if (itemstack1.getItem() != Items.DYE) { ++ if (!net.minecraftforge.oredict.DyeUtils.isDye(itemstack1)) { + flag = false; + break; + } +@@ -186,14 +183,13 @@ + } + + /** Used to determine if this recipe can fit in a grid of the given width/height */ +- @SideOnly(Side.CLIENT) + @Override + public boolean canFit(int width, int height) { + return width >= 3 && height >= 3; + } + } + +- public static class RecipeDuplicatePattern implements IRecipe { ++ public static class RecipeDuplicatePattern extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe { + /** Used to check if a recipe matches current crafting inventory */ + @Override + public boolean matches(InventoryCrafting inv, World worldIn) { +@@ -272,8 +268,8 @@ + for (int i = 0; i < nonnulllist.size(); i++) { + ItemStack itemstack = inv.getStackInSlot(i); + if (!itemstack.isEmpty()) { +- if (itemstack.getItem().hasContainerItem()) { +- nonnulllist.set(i, new ItemStack(itemstack.getItem().getContainerItem())); ++ if (itemstack.getItem().hasContainerItem(itemstack)) { ++ nonnulllist.set(i, net.minecraftforge.common.ForgeHooks.getContainerItem(itemstack)); + } else if (itemstack.hasTagCompound() && TileEntityBanner.getPatterns(itemstack) > 0) { + ItemStack itemstack1 = itemstack.copy(); + itemstack1.setCount(1); +@@ -292,7 +288,6 @@ + } + + /** Used to determine if this recipe can fit in a grid of the given width/height */ +- @SideOnly(Side.CLIENT) + @Override + public boolean canFit(int width, int height) { + return width * height >= 2; diff --git a/module/minecraft/patches/net/minecraft/item/crafting/RecipesMapCloning.java.patch b/module/minecraft/patches/net/minecraft/item/crafting/RecipesMapCloning.java.patch new file mode 100644 index 000000000..8d96eb919 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/crafting/RecipesMapCloning.java.patch @@ -0,0 +1,35 @@ +--- original/net/minecraft/item/crafting/RecipesMapCloning.java ++++ modified/net/minecraft/item/crafting/RecipesMapCloning.java +@@ -5,11 +5,8 @@ + import net.minecraft.item.ItemStack; + import net.minecraft.util.NonNullList; + import net.minecraft.world.World; +-import net.minecraftforge.fml.relauncher.Side; +-import net.minecraftforge.fml.relauncher.SideOnly; + +-public class RecipesMapCloning implements IRecipe { +- /** Used to check if a recipe matches current crafting inventory */ ++public class RecipesMapCloning extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe { + @Override + public boolean matches(InventoryCrafting inv, World worldIn) { + int i = 0; +@@ -90,9 +87,7 @@ + + for (int i = 0; i < nonnulllist.size(); i++) { + ItemStack itemstack = inv.getStackInSlot(i); +- if (itemstack.getItem().hasContainerItem()) { +- nonnulllist.set(i, new ItemStack(itemstack.getItem().getContainerItem())); +- } ++ nonnulllist.set(i, net.minecraftforge.common.ForgeHooks.getContainerItem(itemstack)); + } + + return nonnulllist; +@@ -104,8 +99,6 @@ + return true; + } + +- /** Used to determine if this recipe can fit in a grid of the given width/height */ +- @SideOnly(Side.CLIENT) + @Override + public boolean canFit(int width, int height) { + return width >= 3 && height >= 3; diff --git a/module/minecraft/patches/net/minecraft/item/crafting/ShapedRecipes.java.patch b/module/minecraft/patches/net/minecraft/item/crafting/ShapedRecipes.java.patch new file mode 100644 index 000000000..125ce46cf --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/crafting/ShapedRecipes.java.patch @@ -0,0 +1,81 @@ +--- original/net/minecraft/item/crafting/ShapedRecipes.java ++++ modified/net/minecraft/item/crafting/ShapedRecipes.java +@@ -19,10 +19,8 @@ + import net.minecraft.util.NonNullList; + import net.minecraft.util.ResourceLocation; + import net.minecraft.world.World; +-import net.minecraftforge.fml.relauncher.Side; +-import net.minecraftforge.fml.relauncher.SideOnly; + +-public class ShapedRecipes implements IRecipe { ++public class ShapedRecipes extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements net.minecraftforge.common.crafting.IShapedRecipe { + /** How many horizontal slots this recipe is wide. */ + public final int recipeWidth; + /** How many vertical slots this recipe uses. */ +@@ -41,8 +39,6 @@ + this.recipeOutput = result; + } + +- /** Recipes with equal group are combined into one button in the recipe book */ +- @SideOnly(Side.CLIENT) + @Override + public String getGroup() { + return this.group; +@@ -60,9 +56,8 @@ + + for (int i = 0; i < nonnulllist.size(); i++) { + ItemStack itemstack = inv.getStackInSlot(i); +- if (itemstack.getItem().hasContainerItem()) { +- nonnulllist.set(i, new ItemStack(itemstack.getItem().getContainerItem())); +- } ++ ++ nonnulllist.set(i, net.minecraftforge.common.ForgeHooks.getContainerItem(itemstack)); + } + + return nonnulllist; +@@ -73,8 +68,6 @@ + return this.recipeItems; + } + +- /** Used to determine if this recipe can fit in a grid of the given width/height */ +- @SideOnly(Side.CLIENT) + @Override + public boolean canFit(int width, int height) { + return width >= this.recipeWidth && height >= this.recipeHeight; +@@ -83,8 +76,8 @@ + /** Used to check if a recipe matches current crafting inventory */ + @Override + public boolean matches(InventoryCrafting inv, World worldIn) { +- for (int i = 0; i <= 3 - this.recipeWidth; i++) { +- for (int j = 0; j <= 3 - this.recipeHeight; j++) { ++ for (int i = 0; i <= inv.getWidth() - this.recipeWidth; ++i) { ++ for (int j = 0; j <= inv.getHeight() - this.recipeHeight; ++j) { + if (this.checkMatch(inv, i, j, true)) { + return true; + } +@@ -100,8 +93,8 @@ + + /** Checks if the region of a crafting inventory is match for the recipe. */ + private boolean checkMatch(InventoryCrafting craftingInventory, int p_77573_2_, int p_77573_3_, boolean p_77573_4_) { +- for (int i = 0; i < 3; i++) { +- for (int j = 0; j < 3; j++) { ++ for (int i = 0; i < craftingInventory.getWidth(); ++i) { ++ for (int j = 0; j < craftingInventory.getHeight(); ++j) { + int k = i - p_77573_2_; + int l = j - p_77573_3_; + Ingredient ingredient = Ingredient.EMPTY; +@@ -319,4 +312,14 @@ + int j = useCount ? JsonUtils.getInt(json, "count", 1) : 1; + return new ItemStack(item, j, i); + } ++ ++ //================================================ FORGE START ================================================ ++ @Override ++ public int getRecipeWidth() { ++ return this.getWidth(); ++ } ++ @Override ++ public int getRecipeHeight() { ++ return this.getHeight(); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/item/crafting/ShapelessRecipes.java.patch b/module/minecraft/patches/net/minecraft/item/crafting/ShapelessRecipes.java.patch new file mode 100644 index 000000000..f41512cb6 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/crafting/ShapelessRecipes.java.patch @@ -0,0 +1,100 @@ +--- original/net/minecraft/item/crafting/ShapelessRecipes.java ++++ modified/net/minecraft/item/crafting/ShapelessRecipes.java +@@ -10,24 +10,24 @@ + import net.minecraft.util.JsonUtils; + import net.minecraft.util.NonNullList; + import net.minecraft.world.World; +-import net.minecraftforge.fml.relauncher.Side; +-import net.minecraftforge.fml.relauncher.SideOnly; + +-public class ShapelessRecipes implements IRecipe { +- /** Is the ItemStack that you get when craft the recipe. */ ++public class ShapelessRecipes extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe { + private final ItemStack recipeOutput; + /** Is a List of ItemStack that composes the recipe. */ + public final NonNullList recipeItems; + private final String group; ++ private final boolean isSimple; + + public ShapelessRecipes(String group, ItemStack output, NonNullList ingredients) { + this.group = group; + this.recipeOutput = output; + this.recipeItems = ingredients; ++ boolean simple = true; ++ for (Ingredient i : ingredients) ++ simple &= i.isSimple(); ++ this.isSimple = simple; + } + +- /** Recipes with equal group are combined into one button in the recipe book */ +- @SideOnly(Side.CLIENT) + @Override + public String getGroup() { + return this.group; +@@ -50,9 +50,8 @@ + + for (int i = 0; i < nonnulllist.size(); i++) { + ItemStack itemstack = inv.getStackInSlot(i); +- if (itemstack.getItem().hasContainerItem()) { +- nonnulllist.set(i, new ItemStack(itemstack.getItem().getContainerItem())); +- } ++ ++ nonnulllist.set(i, net.minecraftforge.common.ForgeHooks.getContainerItem(itemstack)); + } + + return nonnulllist; +@@ -61,30 +60,30 @@ + /** Used to check if a recipe matches current crafting inventory */ + @Override + public boolean matches(InventoryCrafting inv, World worldIn) { +- List list = Lists.newArrayList(this.recipeItems); ++ int ingredientCount = 0; ++ net.minecraft.client.util.RecipeItemHelper recipeItemHelper = new net.minecraft.client.util.RecipeItemHelper(); ++ List inputs = Lists.newArrayList(); + + for (int i = 0; i < inv.getHeight(); i++) { + for (int j = 0; j < inv.getWidth(); j++) { + ItemStack itemstack = inv.getStackInRowAndColumn(j, i); + if (!itemstack.isEmpty()) { +- boolean flag = false; +- +- for (Ingredient ingredient : list) { +- if (ingredient.apply(itemstack)) { +- flag = true; +- list.remove(ingredient); +- break; +- } +- } +- +- if (!flag) { +- return false; +- } ++ ++ingredientCount; ++ if (this.isSimple) ++ recipeItemHelper.accountStack(itemstack, 1); ++ else ++ inputs.add(itemstack); + } + } + } + +- return list.isEmpty(); ++ if (ingredientCount != this.recipeItems.size()) ++ return false; ++ ++ if (this.isSimple) ++ return recipeItemHelper.canCraft(this, null); ++ ++ return net.minecraftforge.common.util.RecipeMatcher.findMatches(inputs, this.recipeItems) != null; + } + + /** Returns an Item that is the result of this recipe */ +@@ -121,8 +120,6 @@ + return nonnulllist; + } + +- /** Used to determine if this recipe can fit in a grid of the given width/height */ +- @SideOnly(Side.CLIENT) + @Override + public boolean canFit(int width, int height) { + return width * height >= this.recipeItems.size(); diff --git a/module/minecraft/patches/net/minecraft/item/crafting/ShieldRecipes.java.patch b/module/minecraft/patches/net/minecraft/item/crafting/ShieldRecipes.java.patch new file mode 100644 index 000000000..b5c4d0685 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/crafting/ShieldRecipes.java.patch @@ -0,0 +1,23 @@ +--- original/net/minecraft/item/crafting/ShieldRecipes.java ++++ modified/net/minecraft/item/crafting/ShieldRecipes.java +@@ -6,11 +6,9 @@ + import net.minecraft.nbt.NBTTagCompound; + import net.minecraft.util.NonNullList; + import net.minecraft.world.World; +-import net.minecraftforge.fml.relauncher.Side; +-import net.minecraftforge.fml.relauncher.SideOnly; + + public class ShieldRecipes { +- public static class Decoration implements IRecipe { ++ public static class Decoration extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe { + /** Used to check if a recipe matches current crafting inventory */ + @Override + public boolean matches(InventoryCrafting inv, World worldIn) { +@@ -102,7 +100,6 @@ + } + + /** Used to determine if this recipe can fit in a grid of the given width/height */ +- @SideOnly(Side.CLIENT) + @Override + public boolean canFit(int width, int height) { + return width * height >= 2; diff --git a/module/minecraft/patches/net/minecraft/item/crafting/ShulkerBoxRecipes.java.patch b/module/minecraft/patches/net/minecraft/item/crafting/ShulkerBoxRecipes.java.patch new file mode 100644 index 000000000..2e62cca88 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/item/crafting/ShulkerBoxRecipes.java.patch @@ -0,0 +1,48 @@ +--- original/net/minecraft/item/crafting/ShulkerBoxRecipes.java ++++ modified/net/minecraft/item/crafting/ShulkerBoxRecipes.java +@@ -8,11 +8,9 @@ + import net.minecraft.item.ItemStack; + import net.minecraft.util.NonNullList; + import net.minecraft.world.World; +-import net.minecraftforge.fml.relauncher.Side; +-import net.minecraftforge.fml.relauncher.SideOnly; + + public class ShulkerBoxRecipes { +- public static class ShulkerBoxColoring implements IRecipe { ++ public static class ShulkerBoxColoring extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe { + /** Used to check if a recipe matches current crafting inventory */ + @Override + public boolean matches(InventoryCrafting inv, World worldIn) { +@@ -25,7 +23,7 @@ + if (Block.getBlockFromItem(itemstack.getItem()) instanceof BlockShulkerBox) { + i++; + } else { +- if (itemstack.getItem() != Items.DYE) { ++ if (!net.minecraftforge.oredict.DyeUtils.isDye(itemstack)) { + return false; + } + +@@ -52,13 +50,13 @@ + if (!itemstack2.isEmpty()) { + if (Block.getBlockFromItem(itemstack2.getItem()) instanceof BlockShulkerBox) { + itemstack = itemstack2; +- } else if (itemstack2.getItem() == Items.DYE) { ++ } else if (net.minecraftforge.oredict.DyeUtils.isDye(itemstack2)) { + itemstack1 = itemstack2; + } + } + } + +- ItemStack itemstack3 = BlockShulkerBox.getColoredItemStack(EnumDyeColor.byDyeDamage(itemstack1.getMetadata())); ++ ItemStack itemstack3 = BlockShulkerBox.getColoredItemStack(net.minecraftforge.oredict.DyeUtils.colorFromStack(itemstack1).get()); + if (itemstack.hasTagCompound()) { + itemstack3.setTagCompound(itemstack.getTagCompound().copy()); + } +@@ -93,7 +91,6 @@ + } + + /** Used to determine if this recipe can fit in a grid of the given width/height */ +- @SideOnly(Side.CLIENT) + @Override + public boolean canFit(int width, int height) { + return width * height >= 2; diff --git a/module/minecraft/patches/net/minecraft/nbt/CompressedStreamTools.java.patch b/module/minecraft/patches/net/minecraft/nbt/CompressedStreamTools.java.patch new file mode 100644 index 000000000..b10ff256b --- /dev/null +++ b/module/minecraft/patches/net/minecraft/nbt/CompressedStreamTools.java.patch @@ -0,0 +1,50 @@ +--- original/net/minecraft/nbt/CompressedStreamTools.java ++++ modified/net/minecraft/nbt/CompressedStreamTools.java +@@ -18,8 +18,6 @@ + import net.minecraft.crash.CrashReport; + import net.minecraft.crash.CrashReportCategory; + import net.minecraft.util.ReportedException; +-import net.minecraftforge.fml.relauncher.Side; +-import net.minecraftforge.fml.relauncher.SideOnly; + + public class CompressedStreamTools { + /** Load the gzipped compound from the inputstream. */ +@@ -44,7 +42,6 @@ + } + } + +- @SideOnly(Side.CLIENT) + public static void safeWrite(NBTTagCompound compound, File fileIn) throws IOException { + File file1 = new File(fileIn.getAbsolutePath() + "_tmp"); + if (file1.exists()) { +@@ -63,7 +60,6 @@ + file1.renameTo(fileIn); + } + +- @SideOnly(Side.CLIENT) + public static void write(NBTTagCompound compound, File fileIn) throws IOException { + DataOutputStream dataoutputstream = new DataOutputStream(new FileOutputStream(fileIn)); + +@@ -75,7 +71,6 @@ + } + + @Nullable +- @SideOnly(Side.CLIENT) + public static NBTTagCompound read(File fileIn) throws IOException { + if (!fileIn.exists()) { + return null; +@@ -119,11 +114,13 @@ + + private static NBTBase read(DataInput input, int depth, NBTSizeTracker accounter) throws IOException { + byte b0 = input.readByte(); ++ accounter.read(8); // Forge: Count everything! + if (b0 == 0) { + return new NBTTagEnd(); + } + +- input.readUTF(); ++ NBTSizeTracker.readUTF(accounter, input.readUTF()); //Forge: Count this string. ++ accounter.read(32); //Forge: 4 extra bytes for the object allocation. + NBTBase nbtbase = NBTBase.create(b0); + + try { diff --git a/module/minecraft/patches/net/minecraft/nbt/NBTSizeTracker.java.patch b/module/minecraft/patches/net/minecraft/nbt/NBTSizeTracker.java.patch new file mode 100644 index 000000000..506300be4 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/nbt/NBTSizeTracker.java.patch @@ -0,0 +1,35 @@ +--- original/net/minecraft/nbt/NBTSizeTracker.java ++++ modified/net/minecraft/nbt/NBTSizeTracker.java +@@ -23,4 +23,32 @@ + ); + } + } ++ ++ /* ++ * UTF8 is not a simple encoding system, each character can be either ++ * 1, 2, or 3 bytes. Depending on where it's numerical value falls. ++ * We have to count up each character individually to see the true ++ * length of the data. ++ * ++ * Basic concept is that it uses the MSB of each byte as a 'read more' signal. ++ * So it has to shift each 7-bit segment. ++ * ++ * This will accurately count the correct byte length to encode this string, plus the 2 bytes for it's length prefix. ++ */ ++ public static void readUTF(NBTSizeTracker tracker, String data) { ++ tracker.read(16); //Header length ++ if (data == null) ++ return; ++ ++ int len = data.length(); ++ int utflen = 0; ++ ++ for (int i = 0; i < len; i++) { ++ int c = data.charAt(i); ++ if ((c >= 0x0001) && (c <= 0x007F)) utflen += 1; ++ else if (c > 0x07FF) utflen += 3; ++ else utflen += 2; ++ } ++ tracker.read(8 * utflen); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/nbt/NBTTagCompound.java.patch b/module/minecraft/patches/net/minecraft/nbt/NBTTagCompound.java.patch new file mode 100644 index 000000000..667df3d9b --- /dev/null +++ b/module/minecraft/patches/net/minecraft/nbt/NBTTagCompound.java.patch @@ -0,0 +1,26 @@ +--- original/net/minecraft/nbt/NBTTagCompound.java ++++ modified/net/minecraft/nbt/NBTTagCompound.java +@@ -75,6 +75,7 @@ + + /** Stores the given tag into the map with the given string key. This is mostly used to store tag lists. */ + public void setTag(String key, NBTBase value) { ++ if (value == null) throw new IllegalArgumentException("Invalid null NBT value with key " + key); + this.tagMap.put(key, value); + } + +@@ -394,6 +395,7 @@ + } + + private static byte readType(DataInput input, NBTSizeTracker sizeTracker) throws IOException { ++ sizeTracker.read(8); + return input.readByte(); + } + +@@ -402,6 +404,7 @@ + } + + static NBTBase readNBT(byte id, String key, DataInput input, int depth, NBTSizeTracker sizeTracker) throws IOException { ++ sizeTracker.read(32); //Forge: 4 extra bytes for the object allocation. + NBTBase nbtbase = NBTBase.create(id); + + try { diff --git a/module/minecraft/patches/net/minecraft/nbt/NBTTagList.java.patch b/module/minecraft/patches/net/minecraft/nbt/NBTTagList.java.patch new file mode 100644 index 000000000..f95dda7dd --- /dev/null +++ b/module/minecraft/patches/net/minecraft/nbt/NBTTagList.java.patch @@ -0,0 +1,17 @@ +--- original/net/minecraft/nbt/NBTTagList.java ++++ modified/net/minecraft/nbt/NBTTagList.java +@@ -9,7 +9,7 @@ + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + +-public class NBTTagList extends NBTBase { ++public class NBTTagList extends NBTBase implements java.lang.Iterable { + private static final Logger LOGGER = LogManager.getLogger(); + /** The array list containing the tags encapsulated in this list. */ + private List tagList = Lists.newArrayList(); +@@ -229,4 +229,5 @@ + public int getTagType() { + return this.tagType; + } ++ @Override public java.util.Iterator iterator() {return tagList.iterator();} + } diff --git a/module/minecraft/patches/net/minecraft/nbt/NBTTagString.java.patch b/module/minecraft/patches/net/minecraft/nbt/NBTTagString.java.patch new file mode 100644 index 000000000..0b3c9df57 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/nbt/NBTTagString.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/nbt/NBTTagString.java ++++ modified/net/minecraft/nbt/NBTTagString.java +@@ -28,7 +28,7 @@ + void read(DataInput input, int depth, NBTSizeTracker sizeTracker) throws IOException { + sizeTracker.read(288L); + this.data = input.readUTF(); +- sizeTracker.read(16 * this.data.length()); ++ NBTSizeTracker.readUTF(sizeTracker, data); // Forge: Correctly read String length including header. + } + + /** Gets the type byte for the tag. */ diff --git a/module/minecraft/patches/net/minecraft/network/NetHandlerPlayServer.java.patch b/module/minecraft/patches/net/minecraft/network/NetHandlerPlayServer.java.patch new file mode 100644 index 000000000..ba514ddee --- /dev/null +++ b/module/minecraft/patches/net/minecraft/network/NetHandlerPlayServer.java.patch @@ -0,0 +1,115 @@ +--- original/net/minecraft/network/NetHandlerPlayServer.java ++++ modified/net/minecraft/network/NetHandlerPlayServer.java +@@ -351,9 +351,11 @@ + } + + entity.setPositionAndRotation(d3, d4, d5, f, f1); ++ this.player.setPositionAndRotation(d3, d4, d5, this.player.rotationYaw, this.player.rotationPitch); // Forge - Resync player position on vehicle moving + boolean flag2 = worldserver.getCollisionBoxes(entity, entity.getEntityBoundingBox().shrink(0.0625)).isEmpty(); + if (flag && (flag1 || !flag2)) { + entity.setPositionAndRotation(d0, d1, d2, f, f1); ++ this.player.setPositionAndRotation(d0, d1, d2, this.player.rotationYaw, this.player.rotationPitch); // Forge - Resync player position on vehicle moving + this.netManager.sendPacket(new SPacketMoveVehicle(entity)); + return; + } +@@ -649,7 +651,11 @@ + double d1 = this.player.posY - (blockpos.getY() + 0.5) + 1.5; + double d2 = this.player.posZ - (blockpos.getZ() + 0.5); + double d3 = d0 * d0 + d1 * d1 + d2 * d2; +- if (d3 > 36.0) { ++ ++ double dist = player.getEntityAttribute(EntityPlayer.REACH_DISTANCE).getAttributeValue() + 1; ++ dist *= dist; ++ ++ if (d3 > dist) { + return; + } else if (blockpos.getY() >= this.server.getBuildLimit()) { + return; +@@ -690,11 +696,13 @@ + EnumFacing enumfacing = packetIn.getDirection(); + this.player.markPlayerActive(); + if (blockpos.getY() < this.server.getBuildLimit() - 1 +- || enumfacing != EnumFacing.UP && blockpos.getY() < this.server.getBuildLimit()) { ++ || enumfacing != EnumFacing.UP && blockpos.getY() < this.server.getBuildLimit()) { ++ double dist = player.getEntityAttribute(EntityPlayer.REACH_DISTANCE).getAttributeValue() + 3; ++ dist *= dist; + if (this.targetPos == null +- && this.player.getDistanceSq(blockpos.getX() + 0.5, blockpos.getY() + 0.5, blockpos.getZ() + 0.5) < 64.0 +- && !this.server.isBlockProtected(worldserver, blockpos, this.player) +- && worldserver.getWorldBorder().contains(blockpos)) { ++ && this.player.getDistanceSq(blockpos.getX() + 0.5, blockpos.getY() + 0.5, blockpos.getZ() + 0.5) < dist ++ && !this.server.isBlockProtected(worldserver, blockpos, this.player) ++ && worldserver.getWorldBorder().contains(blockpos)) { + this.player + .interactionManager + .processRightClickBlock( +@@ -752,18 +760,19 @@ + this.player.dismountRidingEntity(); + if (entity.world == this.player.world) { + this.player.setPositionAndUpdate(entity.posX, entity.posY, entity.posZ); +- } else { ++ } else if (net.minecraftforge.common.ForgeHooks.onTravelToDimension(this.player, entity.dimension)) { ++ int prevDimension = this.player.dimension; + WorldServer worldserver1 = this.player.getServerWorld(); + WorldServer worldserver2 = (WorldServer)entity.world; + this.player.dimension = entity.dimension; + this.sendPacket( + new SPacketRespawn( + this.player.dimension, +- worldserver1.getDifficulty(), +- worldserver1.getWorldInfo().getTerrainType(), ++ worldserver2.getDifficulty(), ++ worldserver2.getWorldInfo().getTerrainType(), + this.player.interactionManager.getGameType() + ) +- ); ++ ); // Forge: Use new dimensions information + this.server.getPlayerList().updatePermissionLevel(this.player); + worldserver1.removeEntityDangerously(this.player); + this.player.isDead = false; +@@ -781,6 +790,7 @@ + this.player.interactionManager.setWorld(worldserver2); + this.server.getPlayerList().updateTimeAndWeatherForPlayer(this.player, worldserver2); + this.server.getPlayerList().syncPlayerInventory(this.player); ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().firePlayerChangedDimensionEvent(this.player, prevDimension, this.player.dimension); + } + } + } +@@ -877,7 +887,9 @@ + if (s.startsWith("/")) { + this.handleSlashCommand(s); + } else { +- ITextComponent itextcomponent = new TextComponentTranslation("chat.type.text", this.player.getDisplayName(), s); ++ ITextComponent itextcomponent = new TextComponentTranslation("chat.type.text", this.player.getDisplayName(), net.minecraftforge.common.ForgeHooks.newChatWithLinks(s)); ++ itextcomponent = net.minecraftforge.common.ForgeHooks.onServerChatEvent(this, s, itextcomponent); ++ if (itextcomponent == null) return; + this.server.getPlayerList().sendMessage(itextcomponent, false); + } + +@@ -982,6 +994,7 @@ + this.player.interactOn(entity, enumhand); + } else if (packetIn.getAction() == CPacketUseEntity.Action.INTERACT_AT) { + EnumHand enumhand1 = packetIn.getHand(); ++ if(net.minecraftforge.common.ForgeHooks.onInteractEntityAt(player, entity, packetIn.getHitVec(), enumhand1) != null) return; + entity.applyPlayerInteraction(this.player, packetIn.getHitVec(), enumhand1); + } else if (packetIn.getAction() == CPacketUseEntity.Action.ATTACK) { + if (entity instanceof EntityItem || entity instanceof EntityXPOrb || entity instanceof EntityArrow || entity == this.player) { +@@ -1013,7 +1026,8 @@ + return; + } + +- this.player = this.server.getPlayerList().recreatePlayerEntity(this.player, 0, false); ++ this.player = this.server.getPlayerList().recreatePlayerEntity(this.player, player.dimension, false); ++ + if (this.server.isHardcore()) { + this.player.setGameType(GameType.SPECTATOR); + this.player.getServerWorld().getGameRules().setOrCreateGameRule("spectatorsGenerateChunks", "false"); +@@ -1051,7 +1065,7 @@ + ItemStack itemstack2 = this.player + .openContainer + .slotClick(packetIn.getSlotId(), packetIn.getUsedButton(), packetIn.getClickType(), this.player); +- if (ItemStack.areItemStacksEqual(packetIn.getClickedItem(), itemstack2)) { ++ if (ItemStack.areItemStacksEqualUsingNBTShareTag(packetIn.getClickedItem(), itemstack2)) { + this.player + .connection + .sendPacket(new SPacketConfirmTransaction(packetIn.getWindowId(), packetIn.getActionNumber(), true)); diff --git a/module/minecraft/patches/net/minecraft/network/NettyPacketEncoder.java.patch b/module/minecraft/patches/net/minecraft/network/NettyPacketEncoder.java.patch new file mode 100644 index 000000000..77135730b --- /dev/null +++ b/module/minecraft/patches/net/minecraft/network/NettyPacketEncoder.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/network/NettyPacketEncoder.java ++++ modified/net/minecraft/network/NettyPacketEncoder.java +@@ -41,7 +41,7 @@ + try { + p_encode_2_.writePacketData(packetbuffer); + } catch (Throwable throwable) { +- LOGGER.error(throwable); ++ throw throwable; // Forge: throw this instead of logging it, to prevent corrupt packets from being sent to the client where they are much harder to debug. + } + } + } diff --git a/module/minecraft/patches/net/minecraft/network/NetworkManager.java.patch b/module/minecraft/patches/net/minecraft/network/NetworkManager.java.patch new file mode 100644 index 000000000..c923afd99 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/network/NetworkManager.java.patch @@ -0,0 +1,58 @@ +--- original/net/minecraft/network/NetworkManager.java ++++ modified/net/minecraft/network/NetworkManager.java +@@ -85,6 +85,10 @@ + this.direction = packetDirection; + } + ++ public EnumPacketDirection getDirection() { ++ return this.direction; ++ } ++ + @Override + public void channelActive(ChannelHandlerContext p_channelActive_1_) throws Exception { + super.channelActive(p_channelActive_1_); +@@ -178,13 +182,14 @@ + private void dispatchPacket(final Packet inPacket, @Nullable final GenericFutureListener>[] futureListeners) { + final EnumConnectionState enumconnectionstate = EnumConnectionState.getFromPacket(inPacket); + final EnumConnectionState enumconnectionstate1 = this.channel.attr(PROTOCOL_ATTRIBUTE_KEY).get(); +- if (enumconnectionstate1 != enumconnectionstate) { ++ ++ if (enumconnectionstate1 != enumconnectionstate && !( inPacket instanceof net.minecraftforge.fml.common.network.internal.FMLProxyPacket)) { + LOGGER.debug("Disabled auto read"); + this.channel.config().setAutoRead(false); + } + + if (this.channel.eventLoop().inEventLoop()) { +- if (enumconnectionstate != enumconnectionstate1) { ++ if (enumconnectionstate != enumconnectionstate1 && !( inPacket instanceof net.minecraftforge.fml.common.network.internal.FMLProxyPacket)) { + this.setConnectionState(enumconnectionstate); + } + +@@ -198,7 +203,7 @@ + this.channel.eventLoop().execute(new Runnable() { + @Override + public void run() { +- if (enumconnectionstate != enumconnectionstate1) { ++ if (enumconnectionstate != enumconnectionstate1 && !( inPacket instanceof net.minecraftforge.fml.common.network.internal.FMLProxyPacket)) { + NetworkManager.this.setConnectionState(enumconnectionstate); + } + +@@ -264,6 +269,7 @@ + /** Create a new NetworkManager from the server host and connect it to the server */ + @SideOnly(Side.CLIENT) + public static NetworkManager createNetworkManagerAndConnect(InetAddress address, int serverPort, boolean useNativeTransport) { ++ if (address instanceof java.net.Inet6Address) System.setProperty("java.net.preferIPv4Stack", "false"); + final NetworkManager networkmanager = new NetworkManager(EnumPacketDirection.CLIENTBOUND); + Class oclass; + LazyLoadBase lazyloadbase; +@@ -390,6 +396,10 @@ + } + } + ++ public Channel channel() { ++ return channel; ++ } ++ + static class InboundHandlerTuplePacketListener { + private final Packet packet; + private final GenericFutureListener>[] futureListeners; diff --git a/module/minecraft/patches/net/minecraft/network/NetworkSystem.java.patch b/module/minecraft/patches/net/minecraft/network/NetworkSystem.java.patch new file mode 100644 index 000000000..f629946b7 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/network/NetworkSystem.java.patch @@ -0,0 +1,93 @@ +--- original/net/minecraft/network/NetworkSystem.java ++++ modified/net/minecraft/network/NetworkSystem.java +@@ -37,6 +37,7 @@ + import net.minecraft.util.LazyLoadBase; + import net.minecraft.util.ReportedException; + import net.minecraft.util.text.TextComponentString; ++import net.minecraftforge.fml.common.thread.SidedThreadGroups; + import net.minecraftforge.fml.relauncher.Side; + import net.minecraftforge.fml.relauncher.SideOnly; + import org.apache.logging.log4j.LogManager; +@@ -46,17 +47,17 @@ + private static final Logger LOGGER = LogManager.getLogger(); + public static final LazyLoadBase SERVER_NIO_EVENTLOOP = new LazyLoadBase() { + protected NioEventLoopGroup load() { +- return new NioEventLoopGroup(0, new ThreadFactoryBuilder().setNameFormat("Netty Server IO #%d").setDaemon(true).build()); ++ return new NioEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Server IO #%d").setDaemon(true).setThreadFactory(net.minecraftforge.fml.common.thread.SidedThreadGroups.SERVER).build()); + } + }; + public static final LazyLoadBase SERVER_EPOLL_EVENTLOOP = new LazyLoadBase() { + protected EpollEventLoopGroup load() { +- return new EpollEventLoopGroup(0, new ThreadFactoryBuilder().setNameFormat("Netty Epoll Server IO #%d").setDaemon(true).build()); ++ return new EpollEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Epoll Server IO #%d").setDaemon(true).setThreadFactory(net.minecraftforge.fml.common.thread.SidedThreadGroups.SERVER).build()); + } + }; + public static final LazyLoadBase SERVER_LOCAL_EVENTLOOP = new LazyLoadBase() { + protected LocalEventLoopGroup load() { +- return new LocalEventLoopGroup(0, new ThreadFactoryBuilder().setNameFormat("Netty Local Server IO #%d").setDaemon(true).build()); ++ return new LocalEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Local Server IO #%d").setDaemon(true).setThreadFactory(SidedThreadGroups.SERVER).build()); + } + }; + /** Reference to the MinecraftServer object. */ +@@ -75,6 +76,7 @@ + + /** Adds a channel that listens on publicly accessible network ports */ + public void addEndpoint(InetAddress address, int port) throws IOException { ++ if (address instanceof java.net.Inet6Address) System.setProperty("java.net.preferIPv4Stack", "false"); + synchronized (this.endpoints) { + Class oclass; + LazyLoadBase lazyloadbase; +@@ -101,25 +103,25 @@ + } catch (ChannelException channelexception) { + } + +- p_initChannel_1_.pipeline() +- .addLast("timeout", new ReadTimeoutHandler(30)) +- .addLast("legacy_query", new LegacyPingHandler(NetworkSystem.this)) +- .addLast("splitter", new NettyVarint21FrameDecoder()) +- .addLast("decoder", new NettyPacketDecoder(EnumPacketDirection.SERVERBOUND)) +- .addLast("prepender", new NettyVarint21FrameEncoder()) +- .addLast("encoder", new NettyPacketEncoder(EnumPacketDirection.CLIENTBOUND)); +- NetworkManager networkmanager = new NetworkManager(EnumPacketDirection.SERVERBOUND); +- NetworkSystem.this.networkManagers.add(networkmanager); +- p_initChannel_1_.pipeline().addLast("packet_handler", networkmanager); +- networkmanager.setNetHandler(new NetHandlerHandshakeTCP(NetworkSystem.this.server, networkmanager)); +- } +- } +- ) +- .group(lazyloadbase.getValue()) +- .localAddress(address, port) +- .bind() +- .syncUninterruptibly() +- ); ++ p_initChannel_1_.pipeline() ++ .addLast("timeout", new ReadTimeoutHandler(net.minecraftforge.fml.common.network.internal.FMLNetworkHandler.READ_TIMEOUT)) ++ .addLast("legacy_query", new LegacyPingHandler(NetworkSystem.this)) ++ .addLast("splitter", new NettyVarint21FrameDecoder()) ++ .addLast("decoder", new NettyPacketDecoder(EnumPacketDirection.SERVERBOUND)) ++ .addLast("prepender", new NettyVarint21FrameEncoder()) ++ .addLast("encoder", new NettyPacketEncoder(EnumPacketDirection.CLIENTBOUND)); ++ NetworkManager networkmanager = new NetworkManager(EnumPacketDirection.SERVERBOUND); ++ NetworkSystem.this.networkManagers.add(networkmanager); ++ p_initChannel_1_.pipeline().addLast("packet_handler", networkmanager); ++ networkmanager.setNetHandler(new NetHandlerHandshakeTCP(NetworkSystem.this.server, networkmanager)); ++ } ++ } ++ ) ++ .group(lazyloadbase.getValue()) ++ .localAddress(address, port) ++ .bind() ++ .syncUninterruptibly() ++ ); + } + } + +@@ -136,7 +138,7 @@ + NetworkSystem.this.networkManagers.add(networkmanager); + p_initChannel_1_.pipeline().addLast("packet_handler", networkmanager); + } +- }).group(SERVER_NIO_EVENTLOOP.getValue()).localAddress(LocalAddress.ANY).bind().syncUninterruptibly(); ++ }).group(SERVER_LOCAL_EVENTLOOP.getValue()).localAddress(LocalAddress.ANY).bind().syncUninterruptibly(); + this.endpoints.add(channelfuture); + } + diff --git a/module/minecraft/patches/net/minecraft/network/PacketBuffer.java.patch b/module/minecraft/patches/net/minecraft/network/PacketBuffer.java.patch new file mode 100644 index 000000000..0a0669045 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/network/PacketBuffer.java.patch @@ -0,0 +1,20 @@ +--- original/net/minecraft/network/PacketBuffer.java ++++ modified/net/minecraft/network/PacketBuffer.java +@@ -267,7 +267,7 @@ + this.writeShort(stack.getMetadata()); + NBTTagCompound nbttagcompound = null; + if (stack.getItem().isDamageable() || stack.getItem().getShareTag()) { +- nbttagcompound = stack.getTagCompound(); ++ nbttagcompound = stack.getItem().getNBTShareTag(stack); + } + + this.writeCompoundTag(nbttagcompound); +@@ -286,7 +286,7 @@ + int j = this.readByte(); + int k = this.readShort(); + ItemStack itemstack = new ItemStack(Item.getItemById(i), j, k); +- itemstack.setTagCompound(this.readCompoundTag()); ++ itemstack.getItem().readNBTShareTag(itemstack, this.readCompoundTag()); + return itemstack; + } + diff --git a/module/minecraft/patches/net/minecraft/network/ServerStatusResponse.java.patch b/module/minecraft/patches/net/minecraft/network/ServerStatusResponse.java.patch new file mode 100644 index 000000000..b8557ed8d --- /dev/null +++ b/module/minecraft/patches/net/minecraft/network/ServerStatusResponse.java.patch @@ -0,0 +1,90 @@ +--- original/net/minecraft/network/ServerStatusResponse.java ++++ modified/net/minecraft/network/ServerStatusResponse.java +@@ -26,6 +26,7 @@ + + public void setServerDescription(ITextComponent descriptionIn) { + this.description = descriptionIn; ++ invalidateJson(); + } + + public ServerStatusResponse.Players getPlayers() { +@@ -34,6 +35,7 @@ + + public void setPlayers(ServerStatusResponse.Players playersIn) { + this.players = playersIn; ++ invalidateJson(); + } + + public ServerStatusResponse.Version getVersion() { +@@ -42,10 +44,12 @@ + + public void setVersion(ServerStatusResponse.Version versionIn) { + this.version = versionIn; ++ invalidateJson(); + } + + public void setFavicon(String faviconBlob) { + this.favicon = faviconBlob; ++ invalidateJson(); + } + + public String getFavicon() { +@@ -145,6 +149,7 @@ + serverstatusresponse.setFavicon(JsonUtils.getString(jsonobject, "favicon")); + } + ++ net.minecraftforge.fml.client.FMLClientHandler.instance().captureAdditionalData(serverstatusresponse, jsonobject); + return serverstatusresponse; + } + +@@ -166,10 +171,50 @@ + jsonobject.addProperty("favicon", p_serialize_1_.getFavicon()); + } + ++ net.minecraftforge.fml.common.network.internal.FMLNetworkHandler.enhanceStatusQuery(jsonobject); + return jsonobject; + } + } + ++private java.util.concurrent.Semaphore mutex = new java.util.concurrent.Semaphore(1); ++private String json = null; ++/** ++ * Returns this object as a Json string. ++ * Converting to JSON if a cached version is not available. ++ * ++ * Also to prevent potentially large memory allocations on the server ++ * this is moved from the S00PacketServerInfo writePacket function ++ * ++ * As this method is called from the network threads thread safety is important! ++ * ++ * @return ++ */ ++public String getJson() ++{ ++ String ret = this.json; ++ if (ret == null) ++ { ++ mutex.acquireUninterruptibly(); ++ ret = this.json; ++ if (ret == null) ++ { ++ ret = net.minecraft.network.status.server.SPacketServerInfo.GSON.toJson(this); ++ this.json = ret; ++ } ++ mutex.release(); ++ } ++ return ret; ++} ++ ++/** ++ * Invalidates the cached json, causing the next call to getJson to rebuild it. ++ * This is needed externally because PlayerCountData.setPlayer's is public. ++ */ ++public void invalidateJson() ++{ ++ this.json = null; ++ } ++ + public static class Version { + private final String name; + private final int protocol; diff --git a/module/minecraft/patches/net/minecraft/network/datasync/DataSerializers.java.patch b/module/minecraft/patches/net/minecraft/network/datasync/DataSerializers.java.patch new file mode 100644 index 000000000..651186912 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/network/datasync/DataSerializers.java.patch @@ -0,0 +1,24 @@ +--- original/net/minecraft/network/datasync/DataSerializers.java ++++ modified/net/minecraft/network/datasync/DataSerializers.java +@@ -283,17 +283,18 @@ + } + }; + ++ @Deprecated // Forge: ONLY FOR VANILLA - mods should use the Forge registry + public static void registerSerializer(DataSerializer serializer) { +- REGISTRY.add(serializer); ++ if (REGISTRY.add(serializer) >= 256) throw new RuntimeException("Vanilla DataSerializer ID limit exceeded"); + } + + @Nullable + public static DataSerializer getSerializer(int id) { +- return REGISTRY.get(id); ++ return net.minecraftforge.common.ForgeHooks.getSerializer(id, REGISTRY); + } + + public static int getSerializerId(DataSerializer serializer) { +- return REGISTRY.getId(serializer); ++ return net.minecraftforge.common.ForgeHooks.getSerializerId(serializer, REGISTRY); + } + + static { diff --git a/module/minecraft/patches/net/minecraft/network/datasync/EntityDataManager.java.patch b/module/minecraft/patches/net/minecraft/network/datasync/EntityDataManager.java.patch new file mode 100644 index 000000000..a79cb2a26 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/network/datasync/EntityDataManager.java.patch @@ -0,0 +1,18 @@ +--- original/net/minecraft/network/datasync/EntityDataManager.java ++++ modified/net/minecraft/network/datasync/EntityDataManager.java +@@ -36,11 +36,13 @@ + } + + public static DataParameter createKey(Class clazz, DataSerializer serializer) { +- if (LOGGER.isDebugEnabled()) { ++ if (true || LOGGER.isDebugEnabled()) { //Forge: This is very useful for mods that register keys on classes that are not their own + try { + Class oclass = Class.forName(Thread.currentThread().getStackTrace()[2].getClassName()); + if (!oclass.equals(clazz)) { +- LOGGER.debug("defineId called for: {} from {}", clazz, oclass, new RuntimeException()); ++ //Forge: log at warn, mods should not add to classes that they don't own, and only add stacktrace when in debug is enabled as it is mostly not needed and consumes time ++ if (LOGGER.isDebugEnabled()) LOGGER.warn("defineId called for: {} from {}", clazz, oclass, new RuntimeException()); ++ else LOGGER.warn("defineId called for: {} from {}", clazz, oclass); + } + } catch (ClassNotFoundException classnotfoundexception) { + } diff --git a/module/minecraft/patches/net/minecraft/network/handshake/client/C00Handshake.java.patch b/module/minecraft/patches/net/minecraft/network/handshake/client/C00Handshake.java.patch new file mode 100644 index 000000000..0e19e8ac5 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/network/handshake/client/C00Handshake.java.patch @@ -0,0 +1,48 @@ +--- original/net/minecraft/network/handshake/client/C00Handshake.java ++++ modified/net/minecraft/network/handshake/client/C00Handshake.java +@@ -13,6 +13,7 @@ + private String ip; + private int port; + private EnumConnectionState requestedState; ++ private boolean hasFMLMarker = false; + + public C00Handshake() { + } +@@ -25,20 +26,26 @@ + this.requestedState = p_i47613_3_; + } + +- /** Reads the raw packet data from the data stream. */ ++ public C00Handshake(String address, int port, EnumConnectionState state, boolean addFMLMarker) { ++ this(address, port, state); ++ this.hasFMLMarker = addFMLMarker; ++ } ++ + @Override + public void readPacketData(PacketBuffer buf) throws IOException { + this.protocolVersion = buf.readVarInt(); + this.ip = buf.readString(255); + this.port = buf.readUnsignedShort(); + this.requestedState = EnumConnectionState.getById(buf.readVarInt()); ++ this.hasFMLMarker = this.ip.contains("\0FML\0"); ++ this.ip = this.ip.split("\0")[0]; + } + + /** Writes the raw packet data to the data stream. */ + @Override + public void writePacketData(PacketBuffer buf) throws IOException { + buf.writeVarInt(this.protocolVersion); +- buf.writeString(this.ip); ++ buf.writeString(this.ip + "\0FML\0"); + buf.writeShort(this.port); + buf.writeVarInt(this.requestedState.getId()); + } +@@ -55,4 +62,8 @@ + public int getProtocolVersion() { + return this.protocolVersion; + } ++ ++ public boolean hasFMLMarker() { ++ return this.hasFMLMarker; ++ } + } diff --git a/module/minecraft/patches/net/minecraft/network/login/server/SPacketLoginSuccess.java.patch b/module/minecraft/patches/net/minecraft/network/login/server/SPacketLoginSuccess.java.patch new file mode 100644 index 000000000..ca93b230d --- /dev/null +++ b/module/minecraft/patches/net/minecraft/network/login/server/SPacketLoginSuccess.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/network/login/server/SPacketLoginSuccess.java ++++ modified/net/minecraft/network/login/server/SPacketLoginSuccess.java +@@ -24,7 +24,7 @@ + public void readPacketData(PacketBuffer buf) throws IOException { + String s = buf.readString(36); + String s1 = buf.readString(16); +- UUID uuid = UUID.fromString(s); ++ UUID uuid = s.length() > 0 ? UUID.fromString(s) : null; + this.profile = new GameProfile(uuid, s1); + } + diff --git a/module/minecraft/patches/net/minecraft/network/play/client/CPacketClickWindow.java.patch b/module/minecraft/patches/net/minecraft/network/play/client/CPacketClickWindow.java.patch new file mode 100644 index 000000000..defa07c74 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/network/play/client/CPacketClickWindow.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/network/play/client/CPacketClickWindow.java ++++ modified/net/minecraft/network/play/client/CPacketClickWindow.java +@@ -60,7 +60,7 @@ + buf.writeByte(this.packedClickData); + buf.writeShort(this.actionNumber); + buf.writeEnumValue(this.mode); +- buf.writeItemStack(this.clickedItem); ++ net.minecraftforge.common.util.PacketUtil.writeItemStackFromClientToServer(buf, this.clickedItem); + } + + public int getWindowId() { diff --git a/module/minecraft/patches/net/minecraft/network/play/client/CPacketCreativeInventoryAction.java.patch b/module/minecraft/patches/net/minecraft/network/play/client/CPacketCreativeInventoryAction.java.patch new file mode 100644 index 000000000..3627d304e --- /dev/null +++ b/module/minecraft/patches/net/minecraft/network/play/client/CPacketCreativeInventoryAction.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/network/play/client/CPacketCreativeInventoryAction.java ++++ modified/net/minecraft/network/play/client/CPacketCreativeInventoryAction.java +@@ -37,7 +37,7 @@ + @Override + public void writePacketData(PacketBuffer buf) throws IOException { + buf.writeShort(this.slotId); +- buf.writeItemStack(this.stack); ++ net.minecraftforge.common.util.PacketUtil.writeItemStackFromClientToServer(buf, this.stack); + } + + public int getSlotId() { diff --git a/module/minecraft/patches/net/minecraft/network/play/client/CPacketCustomPayload.java.patch b/module/minecraft/patches/net/minecraft/network/play/client/CPacketCustomPayload.java.patch new file mode 100644 index 000000000..e53dc9bc8 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/network/play/client/CPacketCustomPayload.java.patch @@ -0,0 +1,14 @@ +--- original/net/minecraft/network/play/client/CPacketCustomPayload.java ++++ modified/net/minecraft/network/play/client/CPacketCustomPayload.java +@@ -39,7 +39,11 @@ + @Override + public void writePacketData(PacketBuffer buf) throws IOException { + buf.writeString(this.channel); ++ synchronized(this.data) { //This may be access multiple times, from multiple threads, lets be safe. ++ this.data.markReaderIndex(); + buf.writeBytes(this.data); ++ this.data.resetReaderIndex(); ++ } + } + + /** Passes this Packet on to the NetHandler for processing. */ diff --git a/module/minecraft/patches/net/minecraft/network/play/server/SPacketCustomPayload.java.patch b/module/minecraft/patches/net/minecraft/network/play/server/SPacketCustomPayload.java.patch new file mode 100644 index 000000000..bde787433 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/network/play/server/SPacketCustomPayload.java.patch @@ -0,0 +1,21 @@ +--- original/net/minecraft/network/play/server/SPacketCustomPayload.java ++++ modified/net/minecraft/network/play/server/SPacketCustomPayload.java +@@ -38,12 +38,18 @@ + @Override + public void writePacketData(PacketBuffer buf) throws IOException { + buf.writeString(this.channel); ++ synchronized(this.data) { //This may be access multiple times, from multiple threads, lets be safe. ++ this.data.markReaderIndex(); + buf.writeBytes(this.data); ++ this.data.resetReaderIndex(); ++ } + } + + /** Passes this Packet on to the NetHandler for processing. */ + public void processPacket(INetHandlerPlayClient handler) { + handler.handleCustomPayload(this); ++ // Forge: fix network buffer leaks (MC-121884) ++ if (this.data != null) this.data.release(); + } + + @SideOnly(Side.CLIENT) diff --git a/module/minecraft/patches/net/minecraft/network/play/server/SPacketSpawnMob.java.patch b/module/minecraft/patches/net/minecraft/network/play/server/SPacketSpawnMob.java.patch new file mode 100644 index 000000000..ffb1747d7 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/network/play/server/SPacketSpawnMob.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/network/play/server/SPacketSpawnMob.java ++++ modified/net/minecraft/network/play/server/SPacketSpawnMob.java +@@ -36,7 +36,7 @@ + public SPacketSpawnMob(EntityLivingBase entityIn) { + this.entityId = entityIn.getEntityId(); + this.uniqueId = entityIn.getUniqueID(); +- this.type = EntityList.REGISTRY.getIDForObject((Class)entityIn.getClass()); ++ this.type = EntityList.getID(entityIn.getClass()); + this.x = entityIn.posX; + this.y = entityIn.posY; + this.z = entityIn.posZ; diff --git a/module/minecraft/patches/net/minecraft/pathfinding/FlyingNodeProcessor.java.patch b/module/minecraft/patches/net/minecraft/pathfinding/FlyingNodeProcessor.java.patch new file mode 100644 index 000000000..e7db8ecd6 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/pathfinding/FlyingNodeProcessor.java.patch @@ -0,0 +1,29 @@ +--- original/net/minecraft/pathfinding/FlyingNodeProcessor.java ++++ modified/net/minecraft/pathfinding/FlyingNodeProcessor.java +@@ -236,6 +236,7 @@ + EnumSet enumset = EnumSet.noneOf(PathNodeType.class); + PathNodeType pathnodetype = PathNodeType.BLOCKED; + BlockPos blockpos = new BlockPos(entitylivingIn); ++ this.currentEntity = entitylivingIn; + pathnodetype = this.getPathNodeType( + blockaccessIn, + x, +@@ -250,6 +251,8 @@ + pathnodetype, + blockpos + ); ++ this.currentEntity = null; ++ + if (enumset.contains(PathNodeType.FENCE)) { + return PathNodeType.FENCE; + } +@@ -279,7 +282,8 @@ + pathnodetype = PathNodeType.DAMAGE_FIRE; + } else if (pathnodetype1 == PathNodeType.DAMAGE_CACTUS) { + pathnodetype = PathNodeType.DAMAGE_CACTUS; +- } else { ++ } else if (pathnodetype1 == PathNodeType.DAMAGE_OTHER) pathnodetype = PathNodeType.DAMAGE_OTHER; ++ else { + pathnodetype = pathnodetype1 != PathNodeType.WALKABLE && pathnodetype1 != PathNodeType.OPEN && pathnodetype1 != PathNodeType.WATER + ? PathNodeType.WALKABLE + : PathNodeType.OPEN; diff --git a/module/minecraft/patches/net/minecraft/pathfinding/PathNavigateClimber.java.patch b/module/minecraft/patches/net/minecraft/pathfinding/PathNavigateClimber.java.patch new file mode 100644 index 000000000..bd70517db --- /dev/null +++ b/module/minecraft/patches/net/minecraft/pathfinding/PathNavigateClimber.java.patch @@ -0,0 +1,12 @@ +--- original/net/minecraft/pathfinding/PathNavigateClimber.java ++++ modified/net/minecraft/pathfinding/PathNavigateClimber.java +@@ -47,7 +47,8 @@ + super.onUpdateNavigation(); + } else { + if (this.targetPosition != null) { +- double d0 = this.entity.width * this.entity.width; ++ double d0 = Math.max((this.entity.width * this.entity.width), 1.0); ++ + if (!(this.entity.getDistanceSqToCenter(this.targetPosition) < d0) + && ( + !(this.entity.posY > this.targetPosition.getY()) diff --git a/module/minecraft/patches/net/minecraft/pathfinding/WalkNodeProcessor.java.patch b/module/minecraft/patches/net/minecraft/pathfinding/WalkNodeProcessor.java.patch new file mode 100644 index 000000000..be8dfe49c --- /dev/null +++ b/module/minecraft/patches/net/minecraft/pathfinding/WalkNodeProcessor.java.patch @@ -0,0 +1,68 @@ +--- original/net/minecraft/pathfinding/WalkNodeProcessor.java ++++ modified/net/minecraft/pathfinding/WalkNodeProcessor.java +@@ -22,6 +22,7 @@ + + public class WalkNodeProcessor extends NodeProcessor { + protected float avoidsWater; ++ protected EntityLiving currentEntity; + + @Override + public void init(IBlockAccess sourceIn, EntityLiving mob) { +@@ -282,6 +283,7 @@ + PathNodeType pathnodetype = PathNodeType.BLOCKED; + double d0 = entitylivingIn.width / 2.0; + BlockPos blockpos = new BlockPos(entitylivingIn); ++ this.currentEntity = entitylivingIn; + pathnodetype = this.getPathNodeType( + blockaccessIn, + x, +@@ -296,6 +298,8 @@ + pathnodetype, + blockpos + ); ++ this.currentEntity = null; ++ + if (enumset.contains(PathNodeType.FENCE)) { + return PathNodeType.FENCE; + } +@@ -400,6 +404,8 @@ + if (pathnodetype1 == PathNodeType.DAMAGE_CACTUS) { + pathnodetype = PathNodeType.DAMAGE_CACTUS; + } ++ ++ if (pathnodetype1 == PathNodeType.DAMAGE_OTHER) pathnodetype = PathNodeType.DAMAGE_OTHER; + } + + return this.checkNeighborBlocks(blockaccessIn, x, y, z, pathnodetype); +@@ -411,13 +417,15 @@ + for (int i = -1; i <= 1; i++) { + for (int j = -1; j <= 1; j++) { + if (i != 0 || j != 0) { +- Block block = p_193578_1_.getBlockState(blockpos$pooledmutableblockpos.setPos(i + p_193578_2_, p_193578_3_, j + p_193578_4_)) +- .getBlock(); +- if (block == Blocks.CACTUS) { ++ IBlockState state = p_193578_1_.getBlockState(blockpos$pooledmutableblockpos.setPos(i + p_193578_2_, p_193578_3_, j + p_193578_4_)); ++ Block block = state.getBlock(); ++ PathNodeType type = block.getAiPathNodeType(state, p_193578_1_, blockpos$pooledmutableblockpos, this.currentEntity); ++ ++ if (block == Blocks.CACTUS || type == PathNodeType.DAMAGE_CACTUS) { + p_193578_5_ = PathNodeType.DANGER_CACTUS; +- } else if (block == Blocks.FIRE) { ++ } else if (block == Blocks.FIRE || type == PathNodeType.DAMAGE_FIRE) { + p_193578_5_ = PathNodeType.DANGER_FIRE; +- } ++ } else if (type == PathNodeType.DAMAGE_OTHER) p_193578_5_ = PathNodeType.DANGER_OTHER; + } + } + } +@@ -432,6 +440,10 @@ + IBlockState iblockstate = p_189553_1_.getBlockState(blockpos); + Block block = iblockstate.getBlock(); + Material material = iblockstate.getMaterial(); ++ ++ PathNodeType type = block.getAiPathNodeType(iblockstate, p_189553_1_, blockpos, this.currentEntity); ++ if (type != null) return type; ++ + if (material == Material.AIR) { + return PathNodeType.OPEN; + } diff --git a/module/minecraft/patches/net/minecraft/potion/Potion.java.patch b/module/minecraft/patches/net/minecraft/potion/Potion.java.patch new file mode 100644 index 000000000..a3ba6f3cc --- /dev/null +++ b/module/minecraft/patches/net/minecraft/potion/Potion.java.patch @@ -0,0 +1,141 @@ +--- original/net/minecraft/potion/Potion.java ++++ modified/net/minecraft/potion/Potion.java +@@ -22,9 +22,8 @@ + import net.minecraftforge.fml.relauncher.Side; + import net.minecraftforge.fml.relauncher.SideOnly; + +-public class Potion { +- public static final RegistryNamespaced REGISTRY = new RegistryNamespaced<>(); +- /** Contains a Map of the AttributeModifiers registered by potions */ ++public class Potion extends net.minecraftforge.registries.IForgeRegistryEntry.Impl { ++ public static final RegistryNamespaced REGISTRY = net.minecraftforge.registries.GameData.getWrapper(Potion.class); + private final Map attributeModifierMap = Maps.newHashMap(); + /** This field indicated if the effect is 'bad' - negative - for the entity. */ + private final boolean isBadEffect; +@@ -156,8 +155,6 @@ + return this.statusIconIndex; + } + +- /** This method returns true if the potion effect is bad - negative - for the entity. */ +- @SideOnly(Side.CLIENT) + public boolean isBadEffect() { + return this.isBadEffect; + } +@@ -225,8 +222,116 @@ + return modifier.getAmount() * (amplifier + 1); + } + +- /** Get if the potion is beneficial to the player. Beneficial potions are shown on the first row of the HUD */ ++ /* ======================================== FORGE START =====================================*/ ++ ++ /** ++ * If the Potion effect should be displayed in the players inventory ++ * @param effect the active PotionEffect ++ * @return true to display it (default), false to hide it. ++ */ ++ public boolean shouldRender(PotionEffect effect) { return true; } ++ ++ /** ++ * If the standard PotionEffect text (name and duration) should be drawn when this potion is active. ++ * @param effect the active PotionEffect ++ * @return true to draw the standard text ++ */ ++ public boolean shouldRenderInvText(PotionEffect effect) { ++ return true; ++ } ++ ++ /** ++ * If the Potion effect should be displayed in the player's ingame HUD ++ * @param effect the active PotionEffect ++ * @return true to display it (default), false to hide it. ++ */ ++ public boolean shouldRenderHUD(PotionEffect effect) { ++ return true; ++ } ++ ++ /** ++ * Called to draw the this Potion onto the player's inventory when it's active. ++ * This can be used to e.g. render Potion icons from your own texture. ++ * @param x the x coordinate ++ * @param y the y coordinate ++ * @param effect the active PotionEffect ++ * @param mc the Minecraft instance, for convenience ++ * @deprecated use {@link #renderInventoryEffect(PotionEffect, net.minecraft.client.gui.Gui, int, int, float)} ++ */ + @SideOnly(Side.CLIENT) ++ @Deprecated // TODO: remove ++ public void renderInventoryEffect(int x, int y, PotionEffect effect, net.minecraft.client.Minecraft mc) { } ++ ++ /** ++ * Called to draw the this Potion onto the player's inventory when it's active. ++ * This can be used to e.g. render Potion icons from your own texture. ++ * ++ * @param effect the active PotionEffect ++ * @param gui the gui instance ++ * @param x the x coordinate ++ * @param y the y coordinate ++ * @param z the z level ++ */ ++ @SideOnly(Side.CLIENT) ++ public void renderInventoryEffect(PotionEffect effect, net.minecraft.client.gui.Gui gui, int x, int y, float z) { ++ renderInventoryEffect(x, y, effect, net.minecraft.client.Minecraft.getMinecraft()); ++ } ++ ++ /** ++ * Called to draw the this Potion onto the player's ingame HUD when it's active. ++ * This can be used to e.g. render Potion icons from your own texture. ++ * @param x the x coordinate ++ * @param y the y coordinate ++ * @param effect the active PotionEffect ++ * @param mc the Minecraft instance, for convenience ++ * @param alpha the alpha value, blinks when the potion is about to run out ++ * @deprecated use {@link #renderHUDEffect(PotionEffect, net.minecraft.client.gui.Gui, int, int, float, float)} ++ */ ++ @SideOnly(Side.CLIENT) ++ @Deprecated // TODO: remove ++ public void renderHUDEffect(int x, int y, PotionEffect effect, net.minecraft.client.Minecraft mc, float alpha) { } ++ ++ /** ++ * Called to draw the this Potion onto the player's ingame HUD when it's active. ++ * This can be used to e.g. render Potion icons from your own texture. ++ * ++ * @param effect the active PotionEffect ++ * @param gui the gui instance ++ * @param x the x coordinate ++ * @param y the y coordinate ++ * @param z the z level ++ * @param alpha the alpha value, blinks when the potion is about to run out ++ */ ++ @SideOnly(Side.CLIENT) ++ public void renderHUDEffect(PotionEffect effect, net.minecraft.client.gui.Gui gui, int x, int y, float z, float alpha) { ++ renderHUDEffect(x, y, effect, net.minecraft.client.Minecraft.getMinecraft(), alpha); ++ } ++ ++ /** ++ * Get a fresh list of items that can cure this Potion. ++ * All new PotionEffects created from this Potion will call this to initialize the default curative items ++ * @see PotionEffect#getCurativeItems ++ * @return A list of items that can cure this Potion ++ */ ++ public java.util.List getCurativeItems() { ++ java.util.ArrayList ret = new java.util.ArrayList(); ++ ret.add(new net.minecraft.item.ItemStack(net.minecraft.init.Items.MILK_BUCKET)); ++ return ret; ++ } ++ ++ /** ++ * Used for determining {@code PotionEffect} sort order in GUIs. ++ * Defaults to the {@code PotionEffect}'s liquid color. ++ * @param potionEffect the {@code PotionEffect} instance containing the potion ++ * @return a value used to sort {@code PotionEffect}s in GUIs ++ */ ++ public int getGuiSortColor(PotionEffect potionEffect) { ++ return this.getLiquidColor(); ++ } ++ ++ /* ======================================== FORGE END =====================================*/ ++ ++ @SideOnly(Side.CLIENT) + public boolean isBeneficial() { + return this.beneficial; + } diff --git a/module/minecraft/patches/net/minecraft/potion/PotionEffect.java.patch b/module/minecraft/patches/net/minecraft/potion/PotionEffect.java.patch new file mode 100644 index 000000000..cb6a98b48 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/potion/PotionEffect.java.patch @@ -0,0 +1,146 @@ +--- original/net/minecraft/potion/PotionEffect.java ++++ modified/net/minecraft/potion/PotionEffect.java +@@ -23,6 +23,8 @@ + @SideOnly(Side.CLIENT) + private boolean isPotionDurationMax; + private boolean showParticles; ++ /** List of ItemStack that can cure the potion effect **/ ++ private java.util.List curativeItems; + + public PotionEffect(Potion potionIn) { + this(potionIn, 0, 0); +@@ -50,6 +52,7 @@ + this.amplifier = other.amplifier; + this.isAmbient = other.isAmbient; + this.showParticles = other.showParticles; ++ this.curativeItems = other.curativeItems == null ? null : new java.util.ArrayList(other.curativeItems); + } + + /** merges the input PotionEffect into this one if this.amplifier <= tomerge.amplifier. The duration in the supplied potion effect is assumed to be greater. */ +@@ -71,6 +74,10 @@ + } + + public Potion getPotion() { ++ return this.getPotionRaw() == null ? null : this.getPotionRaw().delegate.get(); ++ } ++ ++ private Potion getPotionRaw() { + return this.potion; + } + +@@ -172,12 +179,13 @@ + nbt.setInteger("Duration", this.getDuration()); + nbt.setBoolean("Ambient", this.getIsAmbient()); + nbt.setBoolean("ShowParticles", this.doesShowParticles()); ++ writeCurativeItems(nbt); + return nbt; + } + + /** Read a custom potion effect from a potion item's NBT data. */ + public static PotionEffect readCustomPotionEffectFromNBT(NBTTagCompound nbt) { +- int i = nbt.getByte("Id"); ++ int i = nbt.getByte("Id") & 0xFF; + Potion potion = Potion.getPotionById(i); + if (potion == null) { + return null; +@@ -191,7 +199,7 @@ + flag1 = nbt.getBoolean("ShowParticles"); + } + +- return new PotionEffect(potion, k, j < 0 ? 0 : j, flag, flag1); ++ return readCurativeItems(new PotionEffect(potion, k, j < 0 ? 0 : j, flag, flag1), nbt); + } + + /** Toggle the isPotionDurationMax field. */ +@@ -209,14 +217,82 @@ + public int compareTo(PotionEffect p_compareTo_1_) { + int i = 32147; + return (this.getDuration() <= 32147 || p_compareTo_1_.getDuration() <= 32147) && (!this.getIsAmbient() || !p_compareTo_1_.getIsAmbient()) +- ? ComparisonChain.start() +- .compare(this.getIsAmbient(), p_compareTo_1_.getIsAmbient()) +- .compare(this.getDuration(), p_compareTo_1_.getDuration()) +- .compare(this.getPotion().getLiquidColor(), p_compareTo_1_.getPotion().getLiquidColor()) +- .result() +- : ComparisonChain.start() +- .compare(this.getIsAmbient(), p_compareTo_1_.getIsAmbient()) +- .compare(this.getPotion().getLiquidColor(), p_compareTo_1_.getPotion().getLiquidColor()) +- .result(); ++ ? ComparisonChain.start() ++ .compare(this.getIsAmbient(), p_compareTo_1_.getIsAmbient()) ++ .compare(this.getDuration(), p_compareTo_1_.getDuration()) ++ .compare(this.getPotion().getGuiSortColor(this), p_compareTo_1_.getPotion().getGuiSortColor(p_compareTo_1_)) ++ .result() ++ : ComparisonChain.start() ++ .compare(this.getIsAmbient(), p_compareTo_1_.getIsAmbient()) ++ .compare(this.getPotion().getGuiSortColor(this), p_compareTo_1_.getPotion().getGuiSortColor(p_compareTo_1_)) ++ .result(); + } ++ ++ /* ======================================== FORGE START =====================================*/ ++ /*** ++ * Returns a list of curative items for the potion effect ++ * By default, this list is initialized using {@link Potion#getCurativeItems} ++ * ++ * @return The list (ItemStack) of curative items for the potion effect ++ */ ++ public java.util.List getCurativeItems() { ++ if (this.curativeItems == null) { //Lazy load this so that we don't create a circular dep on Items. ++ this.curativeItems = getPotion().getCurativeItems(); ++ } ++ return this.curativeItems; ++ } ++ ++ /*** ++ * Checks the given ItemStack to see if it is in the list of curative items for the potion effect ++ * @param stack The ItemStack being checked against the list of curative items for this PotionEffect ++ * @return true if the given ItemStack is in the list of curative items for this PotionEffect, false otherwise ++ */ ++ public boolean isCurativeItem(net.minecraft.item.ItemStack stack) { ++ for (net.minecraft.item.ItemStack curativeItem : this.getCurativeItems()) { ++ if (curativeItem.isItemEqual(stack)) { ++ return true; ++ } ++ } ++ ++ return false; ++ } ++ ++ /*** ++ * Sets the list of curative items for this potion effect, overwriting any already present ++ * @param curativeItems The list of ItemStacks being set to the potion effect ++ */ ++ public void setCurativeItems(java.util.List curativeItems) { ++ this.curativeItems = curativeItems; ++ } ++ ++ /*** ++ * Adds the given stack to the list of curative items for this PotionEffect ++ * @param stack The ItemStack being added to the curative item list ++ */ ++ public void addCurativeItem(net.minecraft.item.ItemStack stack) { ++ if (!this.isCurativeItem(stack)) { ++ this.getCurativeItems().add(stack); ++ } ++ } ++ ++ private void writeCurativeItems(NBTTagCompound nbt) { ++ net.minecraft.nbt.NBTTagList list = new net.minecraft.nbt.NBTTagList(); ++ for (net.minecraft.item.ItemStack stack : getCurativeItems()) { ++ list.appendTag(stack.writeToNBT(new NBTTagCompound())); ++ } ++ nbt.setTag("CurativeItems", list); ++ } ++ ++ private static PotionEffect readCurativeItems(PotionEffect effect, NBTTagCompound nbt) { ++ if (nbt.hasKey("CurativeItems", net.minecraftforge.common.util.Constants.NBT.TAG_LIST)) { ++ java.util.List items = new java.util.ArrayList(); ++ net.minecraft.nbt.NBTTagList list = nbt.getTagList("CurativeItems", net.minecraftforge.common.util.Constants.NBT.TAG_COMPOUND); ++ for (int i = 0; i < list.tagCount(); i++) { ++ items.add(new net.minecraft.item.ItemStack(list.getCompoundTagAt(i))); ++ } ++ effect.setCurativeItems(items); ++ } ++ ++ return effect; ++ } + } diff --git a/module/minecraft/patches/net/minecraft/potion/PotionHelper.java.patch b/module/minecraft/patches/net/minecraft/potion/PotionHelper.java.patch new file mode 100644 index 000000000..989d83cef --- /dev/null +++ b/module/minecraft/patches/net/minecraft/potion/PotionHelper.java.patch @@ -0,0 +1,67 @@ +--- original/net/minecraft/potion/PotionHelper.java ++++ modified/net/minecraft/potion/PotionHelper.java +@@ -65,7 +65,8 @@ + + for (int j = POTION_ITEM_CONVERSIONS.size(); i < j; i++) { + PotionHelper.MixPredicate mixpredicate = POTION_ITEM_CONVERSIONS.get(i); +- if (mixpredicate.input == item && mixpredicate.reagent.apply(reagent)) { ++ ++ if (mixpredicate.input.get() == item && mixpredicate.reagent.apply(reagent)) { + return true; + } + } +@@ -79,7 +80,8 @@ + + for (int j = POTION_TYPE_CONVERSIONS.size(); i < j; i++) { + PotionHelper.MixPredicate mixpredicate = POTION_TYPE_CONVERSIONS.get(i); +- if (mixpredicate.input == potiontype && mixpredicate.reagent.apply(reagent)) { ++ ++ if (mixpredicate.input.get() == potiontype && mixpredicate.reagent.apply(reagent)) { + return true; + } + } +@@ -95,8 +97,9 @@ + + for (int j = POTION_ITEM_CONVERSIONS.size(); i < j; i++) { + PotionHelper.MixPredicate mixpredicate = POTION_ITEM_CONVERSIONS.get(i); +- if (mixpredicate.input == item && mixpredicate.reagent.apply(reagent)) { +- return PotionUtils.addPotionToItemStack(new ItemStack(mixpredicate.output), potiontype); ++ ++ if (mixpredicate.input.get() == item && mixpredicate.reagent.apply(reagent)) { ++ return PotionUtils.addPotionToItemStack(new ItemStack(mixpredicate.output.get()), potiontype); + } + } + +@@ -104,8 +107,9 @@ + + for (int k = POTION_TYPE_CONVERSIONS.size(); i < k; i++) { + PotionHelper.MixPredicate mixpredicate1 = POTION_TYPE_CONVERSIONS.get(i); +- if (mixpredicate1.input == potiontype && mixpredicate1.reagent.apply(reagent)) { +- return PotionUtils.addPotionToItemStack(new ItemStack(item), mixpredicate1.output); ++ ++ if (mixpredicate1.input.get() == potiontype && mixpredicate1.reagent.apply(reagent)) { ++ return PotionUtils.addPotionToItemStack(new ItemStack(item), mixpredicate1.output.get()); + } + } + } +@@ -190,15 +194,15 @@ + POTION_TYPE_CONVERSIONS.add(new PotionHelper.MixPredicate<>(p_193356_0_, p_193356_1_, p_193356_2_)); + } + +- static class MixPredicate { +- final T input; ++ static class MixPredicate> { ++ final net.minecraftforge.registries.IRegistryDelegate input; + final Ingredient reagent; +- final T output; ++ final net.minecraftforge.registries.IRegistryDelegate output; + + public MixPredicate(T p_i47570_1_, Ingredient p_i47570_2_, T p_i47570_3_) { +- this.input = p_i47570_1_; ++ this.input = p_i47570_1_.delegate; + this.reagent = p_i47570_2_; +- this.output = p_i47570_3_; ++ this.output = p_i47570_3_.delegate; + } + } + } diff --git a/module/minecraft/patches/net/minecraft/potion/PotionType.java.patch b/module/minecraft/patches/net/minecraft/potion/PotionType.java.patch new file mode 100644 index 000000000..f18e05a0b --- /dev/null +++ b/module/minecraft/patches/net/minecraft/potion/PotionType.java.patch @@ -0,0 +1,15 @@ +--- original/net/minecraft/potion/PotionType.java ++++ modified/net/minecraft/potion/PotionType.java +@@ -7,9 +7,10 @@ + import net.minecraft.util.ResourceLocation; + import net.minecraft.util.registry.RegistryNamespacedDefaultedByKey; + +-public class PotionType { ++public class PotionType extends net.minecraftforge.registries.IForgeRegistryEntry.Impl { ++ @Deprecated // unused + private static final ResourceLocation EMPTY = new ResourceLocation("empty"); +- public static final RegistryNamespacedDefaultedByKey REGISTRY = new RegistryNamespacedDefaultedByKey<>(EMPTY); ++ public static final RegistryNamespacedDefaultedByKey REGISTRY = net.minecraftforge.registries.GameData.getWrapperDefaulted(PotionType.class); + private static int nextPotionTypeId; + /** The unlocalized name of this PotionType. If null, the registry name is used. */ + private final String baseName; diff --git a/module/minecraft/patches/net/minecraft/profiler/Profiler.java.patch b/module/minecraft/patches/net/minecraft/profiler/Profiler.java.patch new file mode 100644 index 000000000..92012a996 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/profiler/Profiler.java.patch @@ -0,0 +1,18 @@ +--- original/net/minecraft/profiler/Profiler.java ++++ modified/net/minecraft/profiler/Profiler.java +@@ -166,4 +166,15 @@ + return (this.profilerName.hashCode() & 11184810) + 4473924; + } + } ++ /** ++ * Forge: Fix for MC-117087, World.updateEntities is wasting time calling Class.getSimpleName() when the profiler is not active ++ */ ++ @Deprecated // TODO: remove (1.13) ++ public void startSection(Class profiledClass) ++ { ++ if (this.profilingEnabled) ++ { ++ startSection(profiledClass.getSimpleName()); + } ++ } ++} diff --git a/module/minecraft/patches/net/minecraft/realms/RealmsConnect.java.patch b/module/minecraft/patches/net/minecraft/realms/RealmsConnect.java.patch new file mode 100644 index 000000000..38187e669 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/realms/RealmsConnect.java.patch @@ -0,0 +1,19 @@ +--- original/net/minecraft/realms/RealmsConnect.java ++++ modified/net/minecraft/realms/RealmsConnect.java +@@ -33,6 +33,7 @@ + InetAddress inetaddress = null; + + try { ++ net.minecraftforge.fml.client.FMLClientHandler.instance().connectToRealmsServer(p_connect_1_, p_connect_2_); + inetaddress = InetAddress.getByName(p_connect_1_); + if (RealmsConnect.this.aborted) { + return; +@@ -53,7 +54,7 @@ + return; + } + +- RealmsConnect.this.connection.sendPacket(new C00Handshake(p_connect_1_, p_connect_2_, EnumConnectionState.LOGIN)); ++ RealmsConnect.this.connection.sendPacket(new C00Handshake(p_connect_1_, p_connect_2_, EnumConnectionState.LOGIN, true)); + if (RealmsConnect.this.aborted) { + return; + } diff --git a/module/minecraft/patches/net/minecraft/server/MinecraftServer.java.patch b/module/minecraft/patches/net/minecraft/server/MinecraftServer.java.patch new file mode 100644 index 000000000..e16124c57 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/server/MinecraftServer.java.patch @@ -0,0 +1,317 @@ +--- original/net/minecraft/server/MinecraftServer.java ++++ modified/net/minecraft/server/MinecraftServer.java +@@ -106,9 +106,7 @@ + private String hostname; + /** The server's port. */ + private int serverPort = -1; +- /** The server world instances. */ +- public WorldServer[] worlds; +- /** The player list for this server */ ++ public WorldServer[] worlds = new WorldServer[0]; + private PlayerList playerList; + /** Indicates whether the server is running or not. Set to false to initiate a shutdown. */ + private boolean serverRunning = true; +@@ -137,8 +135,8 @@ + private int buildLimit; + private int maxPlayerIdleMinutes; + public final long[] tickTimeArray = new long[100]; +- /** Stats are [dimension][tick%100] system.nanoTime is stored. */ +- public long[][] timeOfLastDimensionTick; ++ //public long[][] timeOfLastDimensionTick; ++ public java.util.Hashtable worldTickTimes = new java.util.Hashtable<>(); + private KeyPair serverKeyPair; + /** Username of the server owner (for integrated servers) */ + private String serverOwner; +@@ -200,9 +198,7 @@ + LOGGER.info("Converting map!"); + this.setUserMessage("menu.convertingLevel"); + this.getActiveAnvilConverter().convertMapFormat(worldNameIn, new IProgressUpdate() { +- private long startTime = MinecraftServer.getCurrentTimeMillis(); +- +- /** Shows the 'Saving level' string. */ ++ private long startTime = System.currentTimeMillis(); + @Override + public void displaySavingString(String message) { + } +@@ -216,8 +212,8 @@ + /** Updates the progress bar on the loading screen to the specified amount. */ + @Override + public void setLoadingProgress(int progress) { +- if (MinecraftServer.getCurrentTimeMillis() - this.startTime >= 1000L) { +- this.startTime = MinecraftServer.getCurrentTimeMillis(); ++ if (System.currentTimeMillis() - this.startTime >= 1000L) { ++ this.startTime = System.currentTimeMillis(); + MinecraftServer.LOGGER.info("Converting... {}%", progress); + } + } +@@ -249,8 +245,6 @@ + public void loadAllWorlds(String saveName, String worldNameIn, long seed, WorldType type, String generatorOptions) { + this.convertMapIfNeeded(saveName); + this.setUserMessage("menu.loadingLevel"); +- this.worlds = new WorldServer[3]; +- this.timeOfLastDimensionTick = new long[this.worlds.length][100]; + ISaveHandler isavehandler = this.anvilConverterForAnvilFile.getSaveLoader(saveName, true); + this.setResourcePackFromWorld(this.getFolderName(), isavehandler); + WorldInfo worldinfo = isavehandler.loadWorldInfo(); +@@ -272,6 +266,7 @@ + worldsettings = new WorldSettings(worldinfo); + } + ++ if (false) { //Forge Dead code, reimplemented below + for (int i = 0; i < this.worlds.length; i++) { + int j = 0; + if (i == 1) { +@@ -299,8 +294,21 @@ + this.worlds[i].getWorldInfo().setGameType(this.getGameType()); + } + } ++ } //Forge: End dead code + +- this.playerList.setPlayerManager(this.worlds); ++ WorldServer overWorld = (WorldServer)(isDemo() ? new WorldServerDemo(this, isavehandler, worldinfo, 0, profiler).init() : new WorldServer(this, isavehandler, worldinfo, 0, profiler).init()); ++ overWorld.initialize(worldsettings); ++ for (int dim : net.minecraftforge.common.DimensionManager.getStaticDimensionIDs()) { ++ WorldServer world = (dim == 0 ? overWorld : (WorldServer)new WorldServerMulti(this, isavehandler, dim, overWorld, profiler).init()); ++ world.addEventListener(new ServerWorldEventHandler(this, world)); ++ ++ if (!this.isSinglePlayer()) { ++ world.getWorldInfo().setGameType(this.getGameType()); ++ } ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.WorldEvent.Load(world)); ++ } ++ ++ this.playerList.setPlayerManager(new WorldServer[]{ overWorld }); + this.setDifficultyForAllWorlds(this.getDifficulty()); + this.initialWorldChunkLoad(); + } +@@ -314,7 +322,7 @@ + this.setUserMessage("menu.generatingTerrain"); + int j1 = 0; + LOGGER.info("Preparing start region for level 0"); +- WorldServer worldserver = this.worlds[0]; ++ WorldServer worldserver = net.minecraftforge.common.DimensionManager.getWorld(j1); + BlockPos blockpos = worldserver.getSpawnPoint(); + long k1 = getCurrentTimeMillis(); + +@@ -421,14 +429,22 @@ + + for (WorldServer worldserver1 : this.worlds) { + if (worldserver1 != null) { ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.WorldEvent.Unload(worldserver1)); + worldserver1.flush(); + } + } ++ ++ WorldServer[] tmp = worlds; ++ for (WorldServer world : tmp) { ++ net.minecraftforge.common.DimensionManager.setWorld(world.provider.getDimension(), null, this); ++ } + } + + if (this.usageSnooper.isSnooperRunning()) { + this.usageSnooper.stopSnooper(); + } ++ ++ CommandBase.setCommandListener(null); // Forge: fix MC-128561 + } + + /** "getHostname" is already taken, but both return the hostname. */ +@@ -455,6 +471,7 @@ + public void run() { + try { + if (this.init()) { ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().handleServerStarted(); + this.currentTime = getCurrentTimeMillis(); + long i = 0L; + this.statusResponse.setServerDescription(new TextComponentString(this.motd)); +@@ -492,9 +509,15 @@ + Thread.sleep(Math.max(1L, 50L - i)); + this.serverIsRunning = true; + } ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().handleServerStopping(); ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().expectServerStopped(); // has to come before finalTick to avoid race conditions + } else { ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().expectServerStopped(); // has to come before finalTick to avoid race conditions + this.finalTick(null); + } ++ } catch (net.minecraftforge.fml.common.StartupQuery.AbortedException e) { ++ // ignore silently ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().expectServerStopped(); // has to come before finalTick to avoid race conditions + } catch (Throwable throwable1) { + LOGGER.error("Encountered an unexpected exception", throwable1); + CrashReport crashreport = null; +@@ -513,14 +536,16 @@ + LOGGER.error("We were unable to save this crash report to disk."); + } + ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().expectServerStopped(); // has to come before finalTick to avoid race conditions + this.finalTick(crashreport); + } finally { + try { +- this.serverStopped = true; + this.stopServer(); + } catch (Throwable throwable) { + LOGGER.error("Exception stopping the server", throwable); + } finally { ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().handleServerStopped(); ++ this.serverStopped = true; + this.systemExitNow(); + } + } +@@ -542,6 +567,7 @@ + ImageIO.write(bufferedimage, "PNG", new ByteBufOutputStream(bytebuf)); + ByteBuf bytebuf1 = Base64.encode(bytebuf); + response.setFavicon("data:image/png;base64," + bytebuf1.toString(StandardCharsets.UTF_8)); ++ bytebuf1.release(); // Forge: fix MC-122085 + } catch (Exception exception) { + LOGGER.error("Couldn't load server icon", exception); + } finally { +@@ -576,6 +602,7 @@ + /** Main function called by run() every loop. */ + public void tick() { + long i = System.nanoTime(); ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().onPreServerTick(); + this.tickCounter++; + if (this.startProfiling) { + this.startProfiling = false; +@@ -597,6 +624,7 @@ + + Collections.shuffle(Arrays.asList(agameprofile)); + this.statusResponse.getPlayers().setPlayers(agameprofile); ++ this.statusResponse.invalidateJson(); + } + + if (this.tickCounter % 900 == 0) { +@@ -620,6 +648,7 @@ + + this.profiler.endSection(); + this.profiler.endSection(); ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().onPostServerTick(); + } + + public void updateTimeLightAndEntities() { +@@ -631,11 +660,15 @@ + } + + this.profiler.endStartSection("levels"); ++ net.minecraftforge.common.chunkio.ChunkIOExecutor.tick(); + +- for (int j = 0; j < this.worlds.length; j++) { ++ Integer[] ids = net.minecraftforge.common.DimensionManager.getIDs(this.tickCounter % 200 == 0); ++ for (int x = 0; x < ids.length; x++) { ++ int id = ids[x]; + long i = System.nanoTime(); +- if (j == 0 || this.getAllowNether()) { +- WorldServer worldserver = this.worlds[j]; ++ ++ if (id == 0 || this.getAllowNether()) { ++ WorldServer worldserver = net.minecraftforge.common.DimensionManager.getWorld(id); + this.profiler.func_194340_a(() -> worldserver.getWorldInfo().getWorldName()); + if (this.tickCounter % 20 == 0) { + this.profiler.startSection("timeSync"); +@@ -644,12 +677,13 @@ + new SPacketTimeUpdate( + worldserver.getTotalWorldTime(), worldserver.getWorldTime(), worldserver.getGameRules().getBoolean("doDaylightCycle") + ), +- worldserver.provider.getDimensionType().getId() ++ worldserver.provider.getDimension() + ); + this.profiler.endSection(); + } + + this.profiler.startSection("tick"); ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().onPreWorldTick(worldserver); + + try { + worldserver.tick(); +@@ -667,6 +701,7 @@ + throw new ReportedException(crashreport1); + } + ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().onPostWorldTick(worldserver); + this.profiler.endSection(); + this.profiler.startSection("tracker"); + worldserver.getEntityTracker().tick(); +@@ -674,9 +709,11 @@ + this.profiler.endSection(); + } + +- this.timeOfLastDimensionTick[j][this.tickCounter % 100] = System.nanoTime() - i; ++ worldTickTimes.get(id)[this.tickCounter % 100] = System.nanoTime() - i; + } + ++ this.profiler.endStartSection("dim_unloading"); ++ net.minecraftforge.common.DimensionManager.unloadWorlds(worldTickTimes); + this.profiler.endStartSection("connection"); + this.getNetworkSystem().networkTick(); + this.profiler.endStartSection("players"); +@@ -703,6 +740,15 @@ + + @SideOnly(Side.SERVER) + public static void main(String[] p_main_0_) { ++ //Forge: Copied from DedicatedServer.init as to run as early as possible, Old code left in place intentionally. ++ //Done in good faith with permission: https://github.com/MinecraftForge/MinecraftForge/issues/3659#issuecomment-390467028 ++ ServerEula eula = new ServerEula(new File("eula.txt")); ++ if (!eula.hasAcceptedEULA()) { ++ LOGGER.info("You need to agree to the EULA in order to run the server. Go to eula.txt for more info."); ++ eula.createEULAFile(); ++ return; ++ } ++ + Bootstrap.register(); + + try { +@@ -796,7 +842,8 @@ + } + + public void startServerThread() { +- this.serverThread = new Thread(this, "Server thread"); ++ net.minecraftforge.fml.common.StartupQuery.reset(); ++ this.serverThread = new Thread(net.minecraftforge.fml.common.thread.SidedThreadGroups.SERVER, this, "Server thread"); + this.serverThread.start(); + } + +@@ -818,11 +865,12 @@ + + /** Gets the worldServer by the given dimension. */ + public WorldServer getWorld(int dimension) { +- if (dimension == -1) { +- return this.worlds[1]; +- } else { +- return dimension == 1 ? this.worlds[2] : this.worlds[0]; ++ WorldServer ret = net.minecraftforge.common.DimensionManager.getWorld(dimension, true); ++ if (ret == null) { ++ net.minecraftforge.common.DimensionManager.initDimension(dimension); ++ ret = net.minecraftforge.common.DimensionManager.getWorld(dimension); + } ++ return ret; + } + + /** Returns the server's Minecraft version as string. */ +@@ -871,7 +919,7 @@ + } + + public String getServerModName() { +- return "vanilla"; ++ return net.minecraftforge.fml.common.FMLCommonHandler.instance().getModName(); + } + + /** Adds the server info, including from theWorldServer, to the crash report. */ +@@ -1354,7 +1402,7 @@ + try { + return Futures.immediateFuture(callable.call()); + } catch (Exception exception) { +- return Futures.immediateFailedCheckedFuture(exception); ++ return Futures.immediateFailedFuture(exception); + } + } + } +@@ -1408,4 +1456,8 @@ + this.addScheduledTask(this::reload); + } + } ++ ++ public DataFixer getDataFixer() { ++ return this.dataFixer; ++ } + } diff --git a/module/minecraft/patches/net/minecraft/server/dedicated/DedicatedServer.java.patch b/module/minecraft/patches/net/minecraft/server/dedicated/DedicatedServer.java.patch new file mode 100644 index 000000000..fc494a321 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/server/dedicated/DedicatedServer.java.patch @@ -0,0 +1,77 @@ +--- original/net/minecraft/server/dedicated/DedicatedServer.java ++++ modified/net/minecraft/server/dedicated/DedicatedServer.java +@@ -61,6 +61,7 @@ + private boolean canSpawnStructures; + private GameType gameType; + private boolean guiIsEnabled; ++ public static boolean allowPlayerLogins = false; + + public DedicatedServer( + File anvilFileIn, +@@ -71,9 +72,11 @@ + PlayerProfileCache profileCacheIn + ) { + super(anvilFileIn, Proxy.NO_PROXY, dataFixerIn, authServiceIn, sessionServiceIn, profileRepoIn, profileCacheIn); +- new Thread("Server Infinisleeper") { ++ if (!org.apache.commons.lang3.SystemUtils.IS_OS_WINDOWS) return; ++ Thread thread = new Thread("Server Infinisleeper") { + { + this.setDaemon(true); ++ this.setPriority(Thread.MIN_PRIORITY); + this.start(); + } + +@@ -95,6 +98,7 @@ + Thread thread = new Thread("Server console handler") { + @Override + public void run() { ++ if (net.minecraftforge.server.console.TerminalHandler.handleCommands(DedicatedServer.this)) return; + BufferedReader bufferedreader = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8)); + + String s4; +@@ -114,6 +118,8 @@ + LOGGER.warn("To start the server with more ram, launch it as \"java -Xmx1024M -Xms1024M -jar minecraft_server.jar\""); + } + ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().onServerStart(this); ++ + LOGGER.info("Loading properties"); + this.settings = new PropertyManager(new File("server.properties")); + this.eula = new ServerEula(new File("eula.txt")); +@@ -188,6 +194,7 @@ + return false; + } + ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().onServerStarted(); + this.setPlayerList(new DedicatedPlayerList(this)); + long j = System.nanoTime(); + if (this.getFolderName() == null) { +@@ -258,7 +265,8 @@ + } + + Items.AIR.getSubItems(CreativeTabs.SEARCH, NonNullList.create()); +- return true; ++ // <3 you Grum for this, saves us ~30 patch files! --^ ++ return net.minecraftforge.fml.common.FMLCommonHandler.instance().handleServerStarting(this); + } + + public String loadResourcePackSHA() { +@@ -478,7 +486,7 @@ + + @Override + public boolean isBlockProtected(World worldIn, BlockPos pos, EntityPlayer playerIn) { +- if (worldIn.provider.getDimensionType().getId() != 0) { ++ if (worldIn.provider.getDimension() != 0) { + return false; + } + +@@ -543,6 +551,9 @@ + return this.settings.getIntProperty("network-compression-threshold", super.getNetworkCompressionThreshold()); + } + ++ //Forge: Enable formated text for colors in console. ++ @Override public void sendMessage(net.minecraft.util.text.ITextComponent message) { LOGGER.info(message.getFormattedText()); } ++ + protected boolean convertFiles() throws IOException { + boolean flag = false; + diff --git a/module/minecraft/patches/net/minecraft/server/dedicated/ServerHangWatchdog.java.patch b/module/minecraft/patches/net/minecraft/server/dedicated/ServerHangWatchdog.java.patch new file mode 100644 index 000000000..e45cd0b16 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/server/dedicated/ServerHangWatchdog.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/server/dedicated/ServerHangWatchdog.java ++++ modified/net/minecraft/server/dedicated/ServerHangWatchdog.java +@@ -41,7 +41,7 @@ + ThreadMXBean threadmxbean = ManagementFactory.getThreadMXBean(); + ThreadInfo[] athreadinfo = threadmxbean.dumpAllThreads(true, true); + StringBuilder stringbuilder = new StringBuilder(); +- Error error = new Error(); ++ Error error = new Error(String.format("ServerHangWatchdog detected that a single server tick took %.2f seconds (should be max 0.05)", k / 1000F)); // Forge: don't just make a crash report with a seemingly-inexplicable Error + + for (ThreadInfo threadinfo : athreadinfo) { + if (threadinfo.getThreadId() == this.server.getServerThread().getId()) { diff --git a/module/minecraft/patches/net/minecraft/server/gui/MinecraftServerGui.java.patch b/module/minecraft/patches/net/minecraft/server/gui/MinecraftServerGui.java.patch new file mode 100644 index 000000000..82a50391f --- /dev/null +++ b/module/minecraft/patches/net/minecraft/server/gui/MinecraftServerGui.java.patch @@ -0,0 +1,22 @@ +--- original/net/minecraft/server/gui/MinecraftServerGui.java ++++ modified/net/minecraft/server/gui/MinecraftServerGui.java +@@ -65,6 +65,7 @@ + System.exit(0); + } + }); ++ minecraftservergui.latch.countDown(); + } + + public MinecraftServerGui(DedicatedServer serverIn) { +@@ -137,7 +138,11 @@ + return jpanel; + } + ++ private java.util.concurrent.CountDownLatch latch = new java.util.concurrent.CountDownLatch(1); + public void appendLine(final JTextArea textArea, final JScrollPane scrollPane, final String line) { ++ try { ++ latch.await(); ++ } catch (InterruptedException e){} //Prevent logging until after constructor has ended. + if (!SwingUtilities.isEventDispatchThread()) { + SwingUtilities.invokeLater(new Runnable() { + @Override diff --git a/module/minecraft/patches/net/minecraft/server/integrated/IntegratedServer.java.patch b/module/minecraft/patches/net/minecraft/server/integrated/IntegratedServer.java.patch new file mode 100644 index 000000000..93aece3aa --- /dev/null +++ b/module/minecraft/patches/net/minecraft/server/integrated/IntegratedServer.java.patch @@ -0,0 +1,75 @@ +--- original/net/minecraft/server/integrated/IntegratedServer.java ++++ modified/net/minecraft/server/integrated/IntegratedServer.java +@@ -83,8 +83,6 @@ + @Override + public void loadAllWorlds(String saveName, String worldNameIn, long seed, WorldType type, String generatorOptions) { + this.convertMapIfNeeded(saveName); +- this.worlds = new WorldServer[3]; +- this.timeOfLastDimensionTick = new long[this.worlds.length][100]; + ISaveHandler isavehandler = this.getActiveAnvilConverter().getSaveLoader(saveName, true); + this.setResourcePackFromWorld(this.getFolderName(), isavehandler); + WorldInfo worldinfo = isavehandler.loadWorldInfo(); +@@ -94,6 +92,7 @@ + worldinfo.setWorldName(worldNameIn); + } + ++ if (false) { //Forge: Dead Code, implement below. + for (int i = 0; i < this.worlds.length; i++) { + int j = 0; + if (i == 1) { +@@ -118,9 +117,23 @@ + + this.worlds[i].addEventListener(new ServerWorldEventHandler(this, this.worlds[i])); + } ++ }// Forge: End Dead Code + +- this.getPlayerList().setPlayerManager(this.worlds); +- if (this.worlds[0].getWorldInfo().getDifficulty() == null) { ++ WorldServer overWorld = (isDemo() ? (WorldServer)(new WorldServerDemo(this, isavehandler, worldinfo, 0, this.profiler)).init() : ++ (WorldServer)(new WorldServer(this, isavehandler, worldinfo, 0, this.profiler)).init()); ++ overWorld.initialize(this.worldSettings); ++ for (int dim : net.minecraftforge.common.DimensionManager.getStaticDimensionIDs()) { ++ WorldServer world = (dim == 0 ? overWorld : (WorldServer)(new WorldServerMulti(this, isavehandler, dim, overWorld, this.profiler)).init()); ++ world.addEventListener(new ServerWorldEventHandler(this, world)); ++ if (!this.isSinglePlayer()) { ++ world.getWorldInfo().setGameType(getGameType()); ++ } ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.WorldEvent.Load(world)); ++ } ++ ++ this.getPlayerList().setPlayerManager(new WorldServer[]{ overWorld }); ++ ++ if (overWorld.getWorldInfo().getDifficulty() == null) { + this.setDifficultyForAllWorlds(this.mc.gameSettings.difficulty); + } + +@@ -138,11 +151,12 @@ + this.setAllowFlight(true); + LOGGER.info("Generating keypair"); + this.setKeyPair(CryptManager.generateKeyPair()); ++ if (!net.minecraftforge.fml.common.FMLCommonHandler.instance().handleServerAboutToStart(this)) return false; + this.loadAllWorlds( + this.getFolderName(), this.getWorldName(), this.worldSettings.getSeed(), this.worldSettings.getTerrainType(), this.worldSettings.getGeneratorOptions() + ); + this.setMOTD(this.getServerOwner() + " - " + this.worlds[0].getWorldInfo().getWorldName()); +- return true; ++ return net.minecraftforge.fml.common.FMLCommonHandler.instance().handleServerStarting(this); + } + + /** Main function called by run() every loop. */ +@@ -203,6 +217,7 @@ + /** Get the server's difficulty */ + @Override + public EnumDifficulty getDifficulty() { ++ if (this.mc.world == null) return this.mc.gameSettings.difficulty; // Fix NPE just in case. + return this.mc.world.getWorldInfo().getDifficulty(); + } + +@@ -347,6 +362,7 @@ + /** Sets the serverRunning variable to false, in order to get the server to shut down. */ + @Override + public void initiateShutdown() { ++ if (isServerRunning()) + Futures.getUnchecked(this.addScheduledTask(new Runnable() { + @Override + public void run() { diff --git a/module/minecraft/patches/net/minecraft/server/management/PlayerChunkMapEntry.java.patch b/module/minecraft/patches/net/minecraft/server/management/PlayerChunkMapEntry.java.patch new file mode 100644 index 000000000..3385b34ab --- /dev/null +++ b/module/minecraft/patches/net/minecraft/server/management/PlayerChunkMapEntry.java.patch @@ -0,0 +1,147 @@ +--- original/net/minecraft/server/management/PlayerChunkMapEntry.java ++++ modified/net/minecraft/server/management/PlayerChunkMapEntry.java +@@ -31,11 +31,18 @@ + private int changedSectionFilter; + private long lastUpdateInhabitedTime; + private boolean sentToPlayers; ++ private Runnable loadedRunnable = new Runnable() { ++ public void run() { ++ PlayerChunkMapEntry.this.chunk = PlayerChunkMapEntry.this.playerChunkMap.getWorldServer().getChunkProvider().loadChunk(PlayerChunkMapEntry.this.pos.x, PlayerChunkMapEntry.this.pos.z); ++ PlayerChunkMapEntry.this.loading = false; ++ } ++ }; ++ private boolean loading = true; + + public PlayerChunkMapEntry(PlayerChunkMap mapIn, int chunkX, int chunkZ) { + this.playerChunkMap = mapIn; + this.pos = new ChunkPos(chunkX, chunkZ); +- this.chunk = mapIn.getWorldServer().getChunkProvider().loadChunk(chunkX, chunkZ); ++ mapIn.getWorldServer().getChunkProvider().loadChunk(chunkX, chunkZ, this.loadedRunnable); + } + + public ChunkPos getPos() { +@@ -55,17 +62,34 @@ + this.players.add(player); + if (this.sentToPlayers) { + this.sendToPlayer(player); ++ // chunk watch event - the chunk is ready ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.ChunkWatchEvent.Watch(this.chunk, player)); + } + } + } + + public void removePlayer(EntityPlayerMP player) { + if (this.players.contains(player)) { ++ // If we haven't loaded yet don't load the chunk just so we can clean it up ++ if (this.chunk == null) { ++ this.players.remove(player); ++ ++ if (this.players.isEmpty()) { ++ if (this.loading) net.minecraftforge.common.chunkio.ChunkIOExecutor.dropQueuedChunkLoad(this.playerChunkMap.getWorldServer(), this.pos.x, this.pos.z, this.loadedRunnable); ++ this.playerChunkMap.removeEntry(this); ++ } ++ ++ return; ++ } ++ + if (this.sentToPlayers) { + player.connection.sendPacket(new SPacketUnloadChunk(this.pos.x, this.pos.z)); + } + + this.players.remove(player); ++ ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.ChunkWatchEvent.UnWatch(this.chunk, player)); ++ + if (this.players.isEmpty()) { + this.playerChunkMap.removeEntry(this); + } +@@ -74,6 +98,7 @@ + + /** Provide the chunk at the player's location. Can fail, returning false, if the player is a spectator floating outside of any pre-existing chunks, and the server is not configured to allow chunk generation for spectators. */ + public boolean providePlayerChunk(boolean canGenerate) { ++ if (this.loading) return false; + if (this.chunk != null) { + return true; + } +@@ -109,11 +134,14 @@ + this.changes = 0; + this.changedSectionFilter = 0; + this.sentToPlayers = true; ++ if (this.players.isEmpty()) return true; // Forge: fix MC-120780 + Packet packet = new SPacketChunkData(this.chunk, 65535); + + for (EntityPlayerMP entityplayermp : this.players) { + entityplayermp.connection.sendPacket(packet); + this.playerChunkMap.getWorldServer().getEntityTracker().sendLeashedEntitiesInChunk(entityplayermp, this.chunk); ++ // chunk watch event - delayed to here as the chunk wasn't ready in addPlayer ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.ChunkWatchEvent.Watch(this.chunk, entityplayermp)); + } + + return true; +@@ -143,7 +171,8 @@ + } + + this.changedSectionFilter |= 1 << (y >> 4); +- if (this.changes < 64) { ++ ++ { //Forge; Cache everything, so always run + short short1 = (short)(x << 12 | z << 8 | y); + + for (int i = 0; i < this.changes; i++) { +@@ -152,6 +181,8 @@ + } + } + ++ if (this.changes == this.changedBlocks.length) ++ this.changedBlocks = java.util.Arrays.copyOf(this.changedBlocks, this.changedBlocks.length << 1); + this.changedBlocks[this.changes++] = short1; + } + } +@@ -165,6 +196,7 @@ + } + } + ++ @SuppressWarnings("unused") + public void update() { + if (this.sentToPlayers && this.chunk != null) { + if (this.changes != 0) { +@@ -174,20 +206,27 @@ + int k = (this.changedBlocks[0] >> 8 & 15) + this.pos.z * 16; + BlockPos blockpos = new BlockPos(i, j, k); + this.sendPacket(new SPacketBlockChange(this.playerChunkMap.getWorldServer(), blockpos)); +- if (this.playerChunkMap.getWorldServer().getBlockState(blockpos).getBlock().hasTileEntity()) { ++ net.minecraft.block.state.IBlockState state = this.playerChunkMap.getWorldServer().getBlockState(blockpos); ++ ++ if (state.getBlock().hasTileEntity(state)) { + this.sendBlockEntity(this.playerChunkMap.getWorldServer().getTileEntity(blockpos)); + } +- } else if (this.changes == 64) { ++ } else if (this.changes >= net.minecraftforge.common.ForgeModContainer.clumpingThreshold) { + this.sendPacket(new SPacketChunkData(this.chunk, this.changedSectionFilter)); ++ //TODO: FDix Mojang's fuckup to modded by combining all TE data into the chunk data packet... seriously... packet size explosion! + } else { + this.sendPacket(new SPacketMultiBlockChange(this.changes, this.changedBlocks, this.chunk)); + ++ //} Keep this in the else until we figure out a fix for mojang's derpitude on the data packet so we don't double send crap. ++ //{// Forge: Send only the tile entities that are updated, Adding this brace lets us keep the indent and the patch small + for (int l = 0; l < this.changes; l++) { + int i1 = (this.changedBlocks[l] >> 12 & 15) + this.pos.x * 16; + int j1 = this.changedBlocks[l] & 255; + int k1 = (this.changedBlocks[l] >> 8 & 15) + this.pos.z * 16; + BlockPos blockpos1 = new BlockPos(i1, j1, k1); +- if (this.playerChunkMap.getWorldServer().getBlockState(blockpos1).getBlock().hasTileEntity()) { ++ net.minecraft.block.state.IBlockState state = this.playerChunkMap.getWorldServer().getBlockState(blockpos1); ++ ++ if (state.getBlock().hasTileEntity(state)) { + this.sendBlockEntity(this.playerChunkMap.getWorldServer().getTileEntity(blockpos1)); + } + } +@@ -250,4 +289,8 @@ + + return d0; + } ++ ++ public List getWatchingPlayers() { ++ return isSentToPlayers() ? java.util.Collections.unmodifiableList(players) : java.util.Collections.emptyList(); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/server/management/PlayerInteractionManager.java.patch b/module/minecraft/patches/net/minecraft/server/management/PlayerInteractionManager.java.patch new file mode 100644 index 000000000..4636e5534 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/server/management/PlayerInteractionManager.java.patch @@ -0,0 +1,263 @@ +--- original/net/minecraft/server/management/PlayerInteractionManager.java ++++ modified/net/minecraft/server/management/PlayerInteractionManager.java +@@ -85,7 +85,8 @@ + if (this.receivedFinishDiggingPacket) { + int i = this.curblockDamage - this.initialBlockDamage; + IBlockState iblockstate = this.world.getBlockState(this.delayedDestroyPos); +- if (iblockstate.getMaterial() == Material.AIR) { ++ ++ if (iblockstate.getBlock().isAir(iblockstate, world, delayedDestroyPos)) { + this.receivedFinishDiggingPacket = false; + } else { + float f = iblockstate.getPlayerRelativeBlockHardness(this.player, this.player.world, this.delayedDestroyPos) * (i + 1); +@@ -102,13 +103,14 @@ + } + } else if (this.isDestroyingBlock) { + IBlockState iblockstate1 = this.world.getBlockState(this.destroyPos); +- if (iblockstate1.getMaterial() == Material.AIR) { ++ ++ if (iblockstate1.getBlock().isAir(iblockstate1, world, destroyPos)) { + this.world.sendBlockBreakProgress(this.player.getEntityId(), this.destroyPos, -1); + this.durabilityRemainingOnBlock = -1; + this.isDestroyingBlock = false; + } else { + int k = this.curblockDamage - this.initialDamage; +- float f1 = iblockstate1.getPlayerRelativeBlockHardness(this.player, this.player.world, this.delayedDestroyPos) * (k + 1); ++ float f1 = iblockstate1.getPlayerRelativeBlockHardness(this.player, this.player.world, this.destroyPos) * (k + 1); // Forge: Fix network break progress using wrong position + int l = (int)(f1 * 10.0F); + if (l != this.durabilityRemainingOnBlock) { + this.world.sendBlockBreakProgress(this.player.getEntityId(), this.destroyPos, l); +@@ -120,6 +122,15 @@ + + /** If not creative, it calls sendBlockBreakProgress until the block is broken first. tryHarvestBlock can also be the result of this call. */ + public void onBlockClicked(BlockPos pos, EnumFacing side) { ++ double reachDist = player.getEntityAttribute(EntityPlayer.REACH_DISTANCE).getAttributeValue(); ++ net.minecraftforge.event.entity.player.PlayerInteractEvent.LeftClickBlock event = net.minecraftforge.common.ForgeHooks.onLeftClickBlock(player, pos, side, net.minecraftforge.common.ForgeHooks.rayTraceEyeHitVec(player, reachDist + 1)); ++ if (event.isCanceled()) { ++ // Restore block and te data ++ player.connection.sendPacket(new SPacketBlockChange(world, pos)); ++ world.notifyBlockUpdate(pos, world.getBlockState(pos), world.getBlockState(pos), 3); ++ return; ++ } ++ + if (this.isCreative()) { + if (!this.world.extinguishFire(null, pos, side)) { + this.tryHarvestBlock(pos); +@@ -144,15 +155,30 @@ + } + } + +- this.world.extinguishFire(null, pos, side); + this.initialDamage = this.curblockDamage; + float f = 1.0F; +- if (iblockstate.getMaterial() != Material.AIR) { +- block.onBlockClicked(this.world, pos, this.player); ++ ++ if (!iblockstate.getBlock().isAir(iblockstate, world, pos)) { ++ if (event.getUseBlock() != net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) { ++ block.onBlockClicked(this.world, pos, this.player); ++ this.world.extinguishFire(null, pos, side); ++ } else { ++ // Restore block and te data ++ player.connection.sendPacket(new SPacketBlockChange(world, pos)); ++ world.notifyBlockUpdate(pos, world.getBlockState(pos), world.getBlockState(pos), 3); ++ } + f = iblockstate.getPlayerRelativeBlockHardness(this.player, this.player.world, pos); + } ++ if (event.getUseItem() == net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) { ++ if (f >= 1.0F) { ++ // Restore block and te data ++ player.connection.sendPacket(new SPacketBlockChange(world, pos)); ++ world.notifyBlockUpdate(pos, world.getBlockState(pos), world.getBlockState(pos), 3); ++ } ++ return; ++ } + +- if (iblockstate.getMaterial() != Material.AIR && f >= 1.0F) { ++ if (!iblockstate.getBlock().isAir(iblockstate, world, pos) && f >= 1.0F) { + this.tryHarvestBlock(pos); + } else { + this.isDestroyingBlock = true; +@@ -168,8 +194,10 @@ + if (pos.equals(this.destroyPos)) { + int i = this.curblockDamage - this.initialDamage; + IBlockState iblockstate = this.world.getBlockState(pos); +- if (iblockstate.getMaterial() != Material.AIR) { +- float f = iblockstate.getPlayerRelativeBlockHardness(this.player, this.player.world, pos) * (i + 1); ++ ++ if (!iblockstate.getBlock().isAir(iblockstate, world, pos)) { ++ float f = iblockstate.getPlayerRelativeBlockHardness(this.player, this.player.world, pos) * (float)(i + 1); ++ + if (f >= 0.7F) { + this.isDestroyingBlock = false; + this.world.sendBlockBreakProgress(this.player.getEntityId(), pos, -1); +@@ -192,9 +220,13 @@ + + /** Removes a block and triggers the appropriate events */ + private boolean removeBlock(BlockPos pos) { ++ return removeBlock(pos, false); ++ } ++ ++ private boolean removeBlock(BlockPos pos, boolean canHarvest) { + IBlockState iblockstate = this.world.getBlockState(pos); +- iblockstate.getBlock().onBlockHarvested(this.world, pos, iblockstate, this.player); +- boolean flag = this.world.setBlockToAir(pos); ++ boolean flag = iblockstate.getBlock().removedByPlayer(iblockstate, world, pos, player, canHarvest); ++ + if (flag) { + iblockstate.getBlock().onPlayerDestroy(this.world, pos, iblockstate); + } +@@ -204,9 +236,8 @@ + + /** Attempts to harvest a block */ + public boolean tryHarvestBlock(BlockPos pos) { +- if (this.gameType.isCreative() +- && !this.player.getHeldItemMainhand().isEmpty() +- && this.player.getHeldItemMainhand().getItem() instanceof ItemSword) { ++ int exp = net.minecraftforge.common.ForgeHooks.onBlockBreakEvent(world, gameType, player, pos); ++ if (exp == -1) { + return false; + } + +@@ -218,40 +249,34 @@ + return false; + } + +- if (this.gameType.hasLimitedInteractions()) { +- if (this.gameType == GameType.SPECTATOR) { +- return false; +- } ++ ItemStack stack = player.getHeldItemMainhand(); ++ if (!stack.isEmpty() && stack.getItem().onBlockStartBreak(stack, pos, player)) return false; + +- if (!this.player.isAllowEdit()) { +- ItemStack itemstack = this.player.getHeldItemMainhand(); +- if (itemstack.isEmpty()) { +- return false; +- } +- +- if (!itemstack.canDestroy(block)) { +- return false; +- } +- } +- } +- + this.world.playEvent(this.player, 2001, pos, Block.getStateId(iblockstate)); +- boolean flag1 = this.removeBlock(pos); ++ boolean flag1 = false; + if (this.isCreative()) { ++ flag1 = this.removeBlock(pos); + this.player.connection.sendPacket(new SPacketBlockChange(this.world, pos)); + } else { + ItemStack itemstack1 = this.player.getHeldItemMainhand(); + ItemStack itemstack2 = itemstack1.isEmpty() ? ItemStack.EMPTY : itemstack1.copy(); +- boolean flag = this.player.canHarvestBlock(iblockstate); ++ boolean flag = iblockstate.getBlock().canHarvestBlock(world, pos, player); + if (!itemstack1.isEmpty()) { + itemstack1.onBlockDestroyed(this.world, iblockstate, pos, this.player); ++ if (itemstack1.isEmpty()) net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(this.player, itemstack2, EnumHand.MAIN_HAND); + } + ++ flag1 = this.removeBlock(pos, flag); + if (flag1 && flag) { + iblockstate.getBlock().harvestBlock(this.world, this.player, pos, iblockstate, tileentity, itemstack2); + } + } + ++ // Drop experience ++ if (!this.isCreative() && flag1 && exp > 0) { ++ iblockstate.getBlock().dropXpOnBlockBreak(world, pos, exp); ++ } ++ + return flag1; + } + +@@ -264,8 +289,11 @@ + return EnumActionResult.PASS; + } + ++ EnumActionResult cancelResult = net.minecraftforge.common.ForgeHooks.onItemRightClick(player, hand); ++ if (cancelResult != null) return cancelResult; + int i = stack.getCount(); + int j = stack.getMetadata(); ++ ItemStack copyBeforeUse = stack.copy(); + ActionResult actionresult = stack.useItemRightClick(worldIn, player, hand); + ItemStack itemstack = actionresult.getResult(); + if (itemstack == stack && itemstack.getCount() == i && itemstack.getMaxItemUseDuration() <= 0 && itemstack.getMetadata() == j) { +@@ -285,6 +313,7 @@ + } + + if (itemstack.isEmpty()) { ++ net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(player, copyBeforeUse, hand); + player.setHeldItem(hand, ItemStack.EMPTY); + } + +@@ -326,11 +355,24 @@ + + return EnumActionResult.PASS; + } else { +- if (!player.isSneaking() || player.getHeldItemMainhand().isEmpty() && player.getHeldItemOffhand().isEmpty()) { ++ double reachDist = player.getEntityAttribute(EntityPlayer.REACH_DISTANCE).getAttributeValue(); ++ net.minecraftforge.event.entity.player.PlayerInteractEvent.RightClickBlock event = net.minecraftforge.common.ForgeHooks ++ .onRightClickBlock(player, hand, pos, facing, net.minecraftforge.common.ForgeHooks.rayTraceEyeHitVec(player, reachDist + 1)); ++ if (event.isCanceled()) return event.getCancellationResult(); ++ ++ EnumActionResult result = EnumActionResult.PASS; ++ if (event.getUseItem() != net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) { ++ result = stack.onItemUseFirst(player, worldIn, pos, hand, facing, hitX, hitY, hitZ); ++ if (result != EnumActionResult.PASS) return result ; ++ } ++ ++ boolean bypass = player.getHeldItemMainhand().doesSneakBypassUse(worldIn, pos, player) && player.getHeldItemOffhand().doesSneakBypassUse(worldIn, pos, player); ++ ++ if (!player.isSneaking() || bypass || event.getUseBlock() == net.minecraftforge.fml.common.eventhandler.Event.Result.ALLOW) { + IBlockState iblockstate = worldIn.getBlockState(pos); +- if (iblockstate.getBlock() +- .onBlockActivated(worldIn, pos, iblockstate, player, hand, facing, hitX, hitY, hitZ)) { +- return EnumActionResult.SUCCESS; ++ if(event.getUseBlock() != net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) ++ if (iblockstate.getBlock().onBlockActivated(worldIn, pos, iblockstate, player, hand, facing, hitX, hitY, hitZ)) { ++ result = EnumActionResult.SUCCESS; + } + } + +@@ -352,14 +394,20 @@ + if (this.isCreative()) { + int j = stack.getMetadata(); + int i = stack.getCount(); +- EnumActionResult enumactionresult = stack.onItemUse( +- player, worldIn, pos, hand, facing, hitX, hitY, hitZ +- ); ++ if (result != EnumActionResult.SUCCESS && event.getUseItem() != net.minecraftforge.fml.common.eventhandler.Event.Result.DENY ++ || result == EnumActionResult.SUCCESS && event.getUseItem() == net.minecraftforge.fml.common.eventhandler.Event.Result.ALLOW) { ++ EnumActionResult enumactionresult = stack.onItemUse(player, worldIn, pos, hand, facing, hitX, hitY, hitZ); + stack.setItemDamage(j); + stack.setCount(i); + return enumactionresult; ++ } else return result; + } else { +- return stack.onItemUse(player, worldIn, pos, hand, facing, hitX, hitY, hitZ); ++ if (result != EnumActionResult.SUCCESS && event.getUseItem() != net.minecraftforge.fml.common.eventhandler.Event.Result.DENY ++ || result == EnumActionResult.SUCCESS && event.getUseItem() == net.minecraftforge.fml.common.eventhandler.Event.Result.ALLOW) { ++ ItemStack copyBeforeUse = stack.copy(); ++ result = stack.onItemUse(player, worldIn, pos, hand, facing, hitX, hitY, hitZ); ++ if (stack.isEmpty()) net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(player, copyBeforeUse, hand); ++ } return result; + } + } + } +@@ -368,4 +416,14 @@ + public void setWorld(WorldServer serverWorld) { + this.world = serverWorld; + } ++ ++ @Deprecated // use the attribute directly ++ public double getBlockReachDistance() { ++ return player.getEntityAttribute(EntityPlayer.REACH_DISTANCE).getAttributeValue(); ++ } ++ ++ @Deprecated // use an attribute modifier ++ public void setBlockReachDistance(double distance) { ++ player.getEntityAttribute(EntityPlayer.REACH_DISTANCE).setBaseValue(distance); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/server/management/PlayerList.java.patch b/module/minecraft/patches/net/minecraft/server/management/PlayerList.java.patch new file mode 100644 index 000000000..364c770fc --- /dev/null +++ b/module/minecraft/patches/net/minecraft/server/management/PlayerList.java.patch @@ -0,0 +1,259 @@ +--- original/net/minecraft/server/management/PlayerList.java ++++ modified/net/minecraft/server/management/PlayerList.java +@@ -109,7 +109,7 @@ + this.maxPlayers = 8; + } + +- public void initializeConnectionToPlayer(NetworkManager netManager, EntityPlayerMP playerIn) { ++ public void initializeConnectionToPlayer(NetworkManager netManager, EntityPlayerMP playerIn, NetHandlerPlayServer nethandlerplayserver) { + GameProfile gameprofile = playerIn.getGameProfile(); + PlayerProfileCache playerprofilecache = this.server.getPlayerProfileCache(); + GameProfile gameprofile1 = playerprofilecache.getProfileByUUID(gameprofile.getId()); +@@ -117,6 +117,16 @@ + playerprofilecache.addEntry(gameprofile); + NBTTagCompound nbttagcompound = this.readPlayerDataFromFile(playerIn); + playerIn.setWorld(this.server.getWorld(playerIn.dimension)); ++ ++ World playerWorld = this.server.getWorld(playerIn.dimension); ++ if (playerWorld == null) { ++ playerIn.dimension = 0; ++ playerWorld = this.server.getWorld(0); ++ BlockPos spawnPoint = playerWorld.provider.getRandomizedSpawnPoint(); ++ playerIn.setPosition(spawnPoint.getX(), spawnPoint.getY(), spawnPoint.getZ()); ++ } ++ ++ playerIn.setWorld(playerWorld); + playerIn.interactionManager.setWorld((WorldServer)playerIn.world); + String s1 = "local"; + if (netManager.getRemoteAddress() != null) { +@@ -135,13 +145,14 @@ + WorldServer worldserver = this.server.getWorld(playerIn.dimension); + WorldInfo worldinfo = worldserver.getWorldInfo(); + this.setPlayerGameTypeBasedOnOther(playerIn, null, worldserver); +- NetHandlerPlayServer nethandlerplayserver = new NetHandlerPlayServer(this.server, netManager, playerIn); ++ playerIn.connection = nethandlerplayserver; ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().fireServerConnectionEvent(netManager); + nethandlerplayserver.sendPacket( + new SPacketJoinGame( + playerIn.getEntityId(), + playerIn.interactionManager.getGameType(), + worldinfo.isHardcoreModeEnabled(), +- worldserver.provider.getDimensionType().getId(), ++ worldserver.provider.getDimension(), + worldserver.getDifficulty(), + this.getMaxPlayers(), + worldinfo.getTerrainType(), +@@ -209,6 +220,7 @@ + } + + playerIn.addSelfToInternalCraftingInventory(); ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().firePlayerLoggedIn(playerIn); + } + + protected void sendScoreboard(ServerScoreboard scoreboardIn, EntityPlayerMP playerIn) { +@@ -301,6 +313,7 @@ + nbttagcompound1 = nbttagcompound; + playerIn.readFromNBT(nbttagcompound1); + LOGGER.debug("loading single player"); ++ net.minecraftforge.event.ForgeEventFactory.firePlayerLoadingEvent(playerIn, this.playerDataManager, playerIn.getUniqueID().toString()); + } else { + nbttagcompound1 = this.playerDataManager.readPlayerData(playerIn); + } +@@ -308,8 +321,19 @@ + return nbttagcompound1; + } + +- /** also stores the NBTTags if this is an intergratedPlayerList */ ++ public NBTTagCompound getPlayerNBT(EntityPlayerMP player) { ++ // Hacky method to allow loading the NBT for a player prior to login ++ NBTTagCompound nbttagcompound = this.server.worlds[0].getWorldInfo().getPlayerNBTTagCompound(); ++ if (player.getName().equals(this.server.getServerOwner()) && nbttagcompound != null) { ++ return nbttagcompound; ++ } else { ++ return ((net.minecraft.world.storage.SaveHandler)this.playerDataManager).getPlayerNBT(player); ++ } ++ } ++ + protected void writePlayerData(EntityPlayerMP playerIn) { ++ if (playerIn.connection == null) return; ++ + this.playerDataManager.writePlayerData(playerIn); + StatisticsManagerServer statisticsmanagerserver = this.playerStatFiles.get(playerIn.getUniqueID()); + if (statisticsmanagerserver != null) { +@@ -333,6 +357,7 @@ + playerIn.connection.sendPacket(new SPacketPlayerListItem(SPacketPlayerListItem.Action.ADD_PLAYER, this.playerEntityList.get(i))); + } + ++ net.minecraftforge.common.chunkio.ChunkIOExecutor.adjustPoolSize(this.getCurrentPlayerCount()); + worldserver.spawnEntity(playerIn); + this.preparePlayer(playerIn, null); + } +@@ -344,6 +369,7 @@ + + /** Called when a player disconnects from the game. Writes player data to disk and removes them from the world. */ + public void playerLoggedOut(EntityPlayerMP playerIn) { ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().firePlayerLoggedOut(playerIn); + WorldServer worldserver = playerIn.getServerWorld(); + playerIn.addStat(StatList.LEAVE_GAME); + this.writePlayerData(playerIn); +@@ -361,6 +387,7 @@ + worldserver.getChunk(playerIn.chunkCoordX, playerIn.chunkCoordZ).markDirty(); + } + } ++ net.minecraftforge.common.chunkio.ChunkIOExecutor.adjustPoolSize(this.getCurrentPlayerCount()); + + worldserver.removeEntity(playerIn); + worldserver.getPlayerChunkMap().removePlayer(playerIn); +@@ -439,13 +466,21 @@ + + /** Destroys the given player entity and recreates another in the given dimension. Used when respawning after death or returning from the End */ + public EntityPlayerMP recreatePlayerEntity(EntityPlayerMP playerIn, int dimension, boolean conqueredEnd) { ++ World world = server.getWorld(dimension); ++ if (world == null) { ++ dimension = playerIn.getSpawnDimension(); ++ } else if (!world.provider.canRespawnHere()) { ++ dimension = world.provider.getRespawnDimension(playerIn); ++ } ++ if (server.getWorld(dimension) == null) dimension = 0; ++ + playerIn.getServerWorld().getEntityTracker().removePlayerFromTrackers(playerIn); + playerIn.getServerWorld().getEntityTracker().untrack(playerIn); + playerIn.getServerWorld().getPlayerChunkMap().removePlayer(playerIn); + this.playerEntityList.remove(playerIn); + this.server.getWorld(playerIn.dimension).removeEntityDangerously(playerIn); +- BlockPos blockpos = playerIn.getBedLocation(); +- boolean flag = playerIn.isSpawnForced(); ++ BlockPos blockpos = playerIn.getBedLocation(dimension); ++ boolean flag = playerIn.isSpawnForced(dimension); + playerIn.dimension = dimension; + PlayerInteractionManager playerinteractionmanager; + if (this.server.isDemo()) { +@@ -459,6 +494,7 @@ + ); + entityplayermp.connection = playerIn.connection; + entityplayermp.copyFrom(playerIn, conqueredEnd); ++ entityplayermp.dimension = dimension; + entityplayermp.setEntityId(playerIn.getEntityId()); + entityplayermp.setCommandStats(playerIn); + entityplayermp.setPrimaryHand(playerIn.getPrimaryHand()); +@@ -514,6 +550,7 @@ + this.uuidToPlayerMap.put(entityplayermp.getUniqueID(), entityplayermp); + entityplayermp.addSelfToInternalCraftingInventory(); + entityplayermp.setHealth(entityplayermp.getHealth()); ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().firePlayerRespawnEvent(entityplayermp, conqueredEnd); + return entityplayermp; + } + +@@ -526,23 +563,32 @@ + } + + public void changePlayerDimension(EntityPlayerMP player, int dimensionIn) { ++ transferPlayerToDimension(player, dimensionIn, server.getWorld(dimensionIn).getDefaultTeleporter()); ++ } ++ ++ // TODO: Remove (1.13) ++ public void transferPlayerToDimension(EntityPlayerMP player, int dimensionIn, net.minecraft.world.Teleporter teleporter) { ++ transferPlayerToDimension(player, dimensionIn, (net.minecraftforge.common.util.ITeleporter) teleporter); ++ } ++ ++ public void transferPlayerToDimension(EntityPlayerMP player, int dimensionIn, net.minecraftforge.common.util.ITeleporter teleporter) { + int i = player.dimension; + WorldServer worldserver = this.server.getWorld(player.dimension); + player.dimension = dimensionIn; + WorldServer worldserver1 = this.server.getWorld(player.dimension); + player.connection +- .sendPacket( +- new SPacketRespawn( +- player.dimension, +- player.world.getDifficulty(), +- player.world.getWorldInfo().getTerrainType(), +- player.interactionManager.getGameType() +- ) +- ); ++ .sendPacket( ++ new SPacketRespawn( ++ player.dimension, ++ worldserver1.getDifficulty(), ++ worldserver1.getWorldInfo().getTerrainType(), ++ player.interactionManager.getGameType() ++ ) ++ ); // Forge: Use new dimensions information + this.updatePermissionLevel(player); + worldserver.removeEntityDangerously(player); + player.isDead = false; +- this.transferEntityToWorld(player, i, worldserver, worldserver1); ++ this.transferEntityToWorld(player, i, worldserver, worldserver1, teleporter); + this.preparePlayer(player, worldserver); + player.connection + .setPlayerLocation( +@@ -556,30 +602,47 @@ + for (PotionEffect potioneffect : player.getActivePotionEffects()) { + player.connection.sendPacket(new SPacketEntityEffect(player.getEntityId(), potioneffect)); + } ++ // Fix MC-88179: on non-death SPacketRespawn, also resend attributes ++ net.minecraft.entity.ai.attributes.AttributeMap attributemap = (net.minecraft.entity.ai.attributes.AttributeMap) player.getAttributeMap(); ++ java.util.Collection watchedAttribs = attributemap.getWatchedAttributes(); ++ if (!watchedAttribs.isEmpty()) player.connection.sendPacket(new net.minecraft.network.play.server.SPacketEntityProperties(player.getEntityId(), watchedAttribs)); ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().firePlayerChangedDimensionEvent(player, i, dimensionIn); + } + + /** Transfers an entity from a world to another world. */ + public void transferEntityToWorld(Entity entityIn, int lastDimension, WorldServer oldWorldIn, WorldServer toWorldIn) { +- double d0 = entityIn.posX; +- double d1 = entityIn.posZ; ++ transferEntityToWorld(entityIn, lastDimension, oldWorldIn, toWorldIn, toWorldIn.getDefaultTeleporter()); ++ } ++ ++ // TODO: Remove (1.13) ++ public void transferEntityToWorld(Entity entityIn, int lastDimension, WorldServer oldWorldIn, WorldServer toWorldIn, net.minecraft.world.Teleporter teleporter) { ++ transferEntityToWorld(entityIn, lastDimension, oldWorldIn, toWorldIn, (net.minecraftforge.common.util.ITeleporter) teleporter); ++ } ++ ++ public void transferEntityToWorld(Entity entityIn, int lastDimension, WorldServer oldWorldIn, WorldServer toWorldIn, net.minecraftforge.common.util.ITeleporter teleporter) { ++ double moveFactor = oldWorldIn.provider.getMovementFactor() / toWorldIn.provider.getMovementFactor(); ++ double d0 = MathHelper.clamp(entityIn.posX * moveFactor, toWorldIn.getWorldBorder().minX() + 16.0, toWorldIn.getWorldBorder().maxX() - 16.0); ++ double d1 = MathHelper.clamp(entityIn.posZ * moveFactor, toWorldIn.getWorldBorder().minZ() + 16.0, toWorldIn.getWorldBorder().maxZ() - 16.0); + double d2 = 8.0; + float f = entityIn.rotationYaw; + oldWorldIn.profiler.startSection("moving"); +- if (entityIn.dimension == -1) { ++ ++ if (false && entityIn.dimension == -1) { + d0 = MathHelper.clamp(d0 / 8.0, toWorldIn.getWorldBorder().minX() + 16.0, toWorldIn.getWorldBorder().maxX() - 16.0); + d1 = MathHelper.clamp(d1 / 8.0, toWorldIn.getWorldBorder().minZ() + 16.0, toWorldIn.getWorldBorder().maxZ() - 16.0); + entityIn.setLocationAndAngles(d0, entityIn.posY, d1, entityIn.rotationYaw, entityIn.rotationPitch); + if (entityIn.isEntityAlive()) { + oldWorldIn.updateEntityWithOptionalForce(entityIn, false); + } +- } else if (entityIn.dimension == 0) { ++ } else if (false && entityIn.dimension == 0) { + d0 = MathHelper.clamp(d0 * 8.0, toWorldIn.getWorldBorder().minX() + 16.0, toWorldIn.getWorldBorder().maxX() - 16.0); + d1 = MathHelper.clamp(d1 * 8.0, toWorldIn.getWorldBorder().minZ() + 16.0, toWorldIn.getWorldBorder().maxZ() - 16.0); + entityIn.setLocationAndAngles(d0, entityIn.posY, d1, entityIn.rotationYaw, entityIn.rotationPitch); + if (entityIn.isEntityAlive()) { + oldWorldIn.updateEntityWithOptionalForce(entityIn, false); + } +- } else { ++ } ++ if (entityIn.dimension == 1 && teleporter.isVanilla()) { + BlockPos blockpos; + if (lastDimension == 1) { + blockpos = toWorldIn.getSpawnPoint(); +@@ -597,13 +660,15 @@ + } + + oldWorldIn.profiler.endSection(); +- if (lastDimension != 1) { ++ ++ if (lastDimension != 1 || !teleporter.isVanilla()) { + oldWorldIn.profiler.startSection("placing"); + d0 = MathHelper.clamp((int)d0, -29999872, 29999872); + d1 = MathHelper.clamp((int)d1, -29999872, 29999872); + if (entityIn.isEntityAlive()) { + entityIn.setLocationAndAngles(d0, entityIn.posY, d1, entityIn.rotationYaw, entityIn.rotationPitch); +- toWorldIn.getDefaultTeleporter().placeInPortal(entityIn, f); ++ oldWorldIn.updateEntityWithOptionalForce(entityIn, false); ++ teleporter.placeEntity(toWorldIn, entityIn, f); + toWorldIn.spawnEntity(entityIn); + toWorldIn.updateEntityWithOptionalForce(entityIn, false); + } diff --git a/module/minecraft/patches/net/minecraft/server/network/NetHandlerHandshakeTCP.java.patch b/module/minecraft/patches/net/minecraft/server/network/NetHandlerHandshakeTCP.java.patch new file mode 100644 index 000000000..49c4b3340 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/server/network/NetHandlerHandshakeTCP.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/server/network/NetHandlerHandshakeTCP.java ++++ modified/net/minecraft/server/network/NetHandlerHandshakeTCP.java +@@ -21,6 +21,8 @@ + /** There are two recognized intentions for initiating a handshake: logging in and acquiring server status. The NetworkManager's protocol will be reconfigured according to the specified intention, although a login-intention must pass a versioncheck or receive a disconnect otherwise */ + @Override + public void processHandshake(C00Handshake packetIn) { ++ if (!net.minecraftforge.fml.common.FMLCommonHandler.instance().handleServerHandshake(packetIn, this.networkManager)) return; ++ + switch (packetIn.getRequestedState()) { + case LOGIN: + this.networkManager.setConnectionState(EnumConnectionState.LOGIN); diff --git a/module/minecraft/patches/net/minecraft/server/network/NetHandlerLoginServer.java.patch b/module/minecraft/patches/net/minecraft/server/network/NetHandlerLoginServer.java.patch new file mode 100644 index 000000000..20fabe25a --- /dev/null +++ b/module/minecraft/patches/net/minecraft/server/network/NetHandlerLoginServer.java.patch @@ -0,0 +1,29 @@ +--- original/net/minecraft/server/network/NetHandlerLoginServer.java ++++ modified/net/minecraft/server/network/NetHandlerLoginServer.java +@@ -64,7 +64,7 @@ + EntityPlayerMP entityplayermp = this.server.getPlayerList().getPlayerByUUID(this.loginGameProfile.getId()); + if (entityplayermp == null) { + this.currentLoginState = NetHandlerLoginServer.LoginState.READY_TO_ACCEPT; +- this.server.getPlayerList().initializeConnectionToPlayer(this.networkManager, this.player); ++ net.minecraftforge.fml.common.network.internal.FMLNetworkHandler.fmlServerHandshake(this.server.getPlayerList(), this.networkManager, this.player); + this.player = null; + } + } +@@ -108,7 +108,7 @@ + this.currentLoginState = NetHandlerLoginServer.LoginState.DELAY_ACCEPT; + this.player = this.server.getPlayerList().createPlayerForUser(this.loginGameProfile); + } else { +- this.server.getPlayerList().initializeConnectionToPlayer(this.networkManager, this.server.getPlayerList().createPlayerForUser(this.loginGameProfile)); ++ net.minecraftforge.fml.common.network.internal.FMLNetworkHandler.fmlServerHandshake(this.server.getPlayerList(), this.networkManager, this.server.getPlayerList().createPlayerForUser(this.loginGameProfile)); + } + } + } +@@ -148,7 +148,7 @@ + this.secretKey = packetIn.getSecretKey(privatekey); + this.currentLoginState = NetHandlerLoginServer.LoginState.AUTHENTICATING; + this.networkManager.enableEncryption(this.secretKey); +- (new Thread("User Authenticator #" + AUTHENTICATOR_THREAD_ID.incrementAndGet()) { ++ (new Thread(net.minecraftforge.fml.common.thread.SidedThreadGroups.SERVER, "User Authenticator #" + AUTHENTICATOR_THREAD_ID.incrementAndGet()) { + @Override + public void run() { + GameProfile gameprofile = NetHandlerLoginServer.this.loginGameProfile; diff --git a/module/minecraft/patches/net/minecraft/stats/RecipeBook.java.patch b/module/minecraft/patches/net/minecraft/stats/RecipeBook.java.patch new file mode 100644 index 000000000..272b922cc --- /dev/null +++ b/module/minecraft/patches/net/minecraft/stats/RecipeBook.java.patch @@ -0,0 +1,19 @@ +--- original/net/minecraft/stats/RecipeBook.java ++++ modified/net/minecraft/stats/RecipeBook.java +@@ -37,8 +37,15 @@ + this.newRecipes.clear(i); + } + ++ @Deprecated //DO NOT USE + protected static int getRecipeId(@Nullable IRecipe recipe) { +- return CraftingManager.REGISTRY.getIDForObject(recipe); ++ int ret = CraftingManager.REGISTRY.getIDForObject(recipe); ++ if (ret == -1) { ++ ret = ((net.minecraftforge.registries.ForgeRegistry)net.minecraftforge.fml.common.registry.ForgeRegistries.RECIPES).getID(recipe.getRegistryName()); ++ if (ret == -1) ++ throw new IllegalArgumentException(String.format("Attempted to get the ID for a unknown recipe: %s Name: %s", recipe, recipe.getRegistryName())); ++ } ++ return ret; + } + + @SideOnly(Side.CLIENT) diff --git a/module/minecraft/patches/net/minecraft/stats/RecipeBookServer.java.patch b/module/minecraft/patches/net/minecraft/stats/RecipeBookServer.java.patch new file mode 100644 index 000000000..ec2b55b60 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/stats/RecipeBookServer.java.patch @@ -0,0 +1,23 @@ +--- original/net/minecraft/stats/RecipeBookServer.java ++++ modified/net/minecraft/stats/RecipeBookServer.java +@@ -47,8 +47,7 @@ + } + + private void sendPacket(SPacketRecipeBook.State state, EntityPlayerMP player, List recipesIn) { +- player.connection +- .sendPacket(new SPacketRecipeBook(state, recipesIn, Collections.emptyList(), this.isGuiOpen, this.isFilteringCraftable)); ++ net.minecraftforge.common.ForgeHooks.sendRecipeBook(player.connection, state, recipesIn, Collections.emptyList(), this.isGuiOpen, this.isFilteringCraftable); + } + + public NBTTagCompound write() { +@@ -121,9 +120,6 @@ + } + + public void init(EntityPlayerMP player) { +- player.connection +- .sendPacket( +- new SPacketRecipeBook(SPacketRecipeBook.State.INIT, this.getRecipes(), this.getDisplayedRecipes(), this.isGuiOpen, this.isFilteringCraftable) +- ); ++ net.minecraftforge.common.ForgeHooks.sendRecipeBook(player.connection, SPacketRecipeBook.State.INIT, this.getRecipes(), this.getDisplayedRecipes(), this.isGuiOpen, this.isFilteringCraftable); + } + } diff --git a/module/minecraft/patches/net/minecraft/stats/StatList.java.patch b/module/minecraft/patches/net/minecraft/stats/StatList.java.patch new file mode 100644 index 000000000..fcc311f8e --- /dev/null +++ b/module/minecraft/patches/net/minecraft/stats/StatList.java.patch @@ -0,0 +1,135 @@ +--- original/net/minecraft/stats/StatList.java ++++ modified/net/minecraft/stats/StatList.java +@@ -205,7 +205,7 @@ + } + } + +- replaceAllSimilarBlocks(CRAFTS_STATS); ++ replaceAllSimilarBlocks(CRAFTS_STATS, true); + } + + private static void initMiningStats() { +@@ -224,7 +224,7 @@ + } + } + +- replaceAllSimilarBlocks(BLOCKS_STATS); ++ replaceAllSimilarBlocks(BLOCKS_STATS, false); + } + + private static void initStats() { +@@ -244,7 +244,7 @@ + } + } + +- replaceAllSimilarBlocks(OBJECT_USE_STATS); ++ replaceAllSimilarBlocks(OBJECT_USE_STATS, true); + } + + private static void initItemDepleteStats() { +@@ -261,7 +261,7 @@ + } + } + +- replaceAllSimilarBlocks(OBJECT_BREAK_STATS); ++ replaceAllSimilarBlocks(OBJECT_BREAK_STATS, true); + } + + private static void initPickedUpAndDroppedStats() { +@@ -280,7 +280,7 @@ + } + } + +- replaceAllSimilarBlocks(OBJECT_BREAK_STATS); ++ replaceAllSimilarBlocks(OBJECT_BREAK_STATS, true); + } + + private static String getItemName(Item itemIn) { +@@ -288,28 +288,34 @@ + return resourcelocation != null ? resourcelocation.toString().replace(':', '.') : null; + } + +- /** Forces all dual blocks to count for each other on the stats list */ +- private static void replaceAllSimilarBlocks(StatBase[] stat) { +- mergeStatBases(stat, Blocks.WATER, Blocks.FLOWING_WATER); +- mergeStatBases(stat, Blocks.LAVA, Blocks.FLOWING_LAVA); +- mergeStatBases(stat, Blocks.LIT_PUMPKIN, Blocks.PUMPKIN); +- mergeStatBases(stat, Blocks.LIT_FURNACE, Blocks.FURNACE); +- mergeStatBases(stat, Blocks.LIT_REDSTONE_ORE, Blocks.REDSTONE_ORE); +- mergeStatBases(stat, Blocks.POWERED_REPEATER, Blocks.UNPOWERED_REPEATER); +- mergeStatBases(stat, Blocks.POWERED_COMPARATOR, Blocks.UNPOWERED_COMPARATOR); +- mergeStatBases(stat, Blocks.REDSTONE_TORCH, Blocks.UNLIT_REDSTONE_TORCH); +- mergeStatBases(stat, Blocks.LIT_REDSTONE_LAMP, Blocks.REDSTONE_LAMP); +- mergeStatBases(stat, Blocks.DOUBLE_STONE_SLAB, Blocks.STONE_SLAB); +- mergeStatBases(stat, Blocks.DOUBLE_WOODEN_SLAB, Blocks.WOODEN_SLAB); +- mergeStatBases(stat, Blocks.DOUBLE_STONE_SLAB2, Blocks.STONE_SLAB2); +- mergeStatBases(stat, Blocks.GRASS, Blocks.DIRT); +- mergeStatBases(stat, Blocks.FARMLAND, Blocks.DIRT); ++ private static void replaceAllSimilarBlocks(StatBase[] stat, boolean useItemIds) { ++ mergeStatBases(stat, Blocks.WATER, Blocks.FLOWING_WATER, useItemIds); ++ mergeStatBases(stat, Blocks.LAVA, Blocks.FLOWING_LAVA, useItemIds); ++ mergeStatBases(stat, Blocks.LIT_PUMPKIN, Blocks.PUMPKIN, useItemIds); ++ mergeStatBases(stat, Blocks.LIT_FURNACE, Blocks.FURNACE, useItemIds); ++ mergeStatBases(stat, Blocks.LIT_REDSTONE_ORE, Blocks.REDSTONE_ORE, useItemIds); ++ mergeStatBases(stat, Blocks.POWERED_REPEATER, Blocks.UNPOWERED_REPEATER, useItemIds); ++ mergeStatBases(stat, Blocks.POWERED_COMPARATOR, Blocks.UNPOWERED_COMPARATOR, useItemIds); ++ mergeStatBases(stat, Blocks.REDSTONE_TORCH, Blocks.UNLIT_REDSTONE_TORCH, useItemIds); ++ mergeStatBases(stat, Blocks.LIT_REDSTONE_LAMP, Blocks.REDSTONE_LAMP, useItemIds); ++ mergeStatBases(stat, Blocks.DOUBLE_STONE_SLAB, Blocks.STONE_SLAB, useItemIds); ++ mergeStatBases(stat, Blocks.DOUBLE_WOODEN_SLAB, Blocks.WOODEN_SLAB, useItemIds); ++ mergeStatBases(stat, Blocks.DOUBLE_STONE_SLAB2, Blocks.STONE_SLAB2, useItemIds); ++ mergeStatBases(stat, Blocks.GRASS, Blocks.DIRT, useItemIds); ++ mergeStatBases(stat, Blocks.FARMLAND, Blocks.DIRT, useItemIds); + } + +- /** Merge {@link StatBase} object references for similar blocks */ +- private static void mergeStatBases(StatBase[] statBaseIn, Block block1, Block block2) { +- int i = Block.getIdFromBlock(block1); +- int j = Block.getIdFromBlock(block2); ++ private static void mergeStatBases(StatBase[] statBaseIn, Block block1, Block block2, boolean useItemIds) { ++ int i; ++ int j; ++ if (useItemIds) { ++ i = Item.getIdFromItem(Item.getItemFromBlock(block1)); ++ j = Item.getIdFromItem(Item.getItemFromBlock(block2)); ++ } else { ++ i = Block.getIdFromBlock(block1); ++ j = Block.getIdFromBlock(block2); ++ } ++ + if (statBaseIn[i] != null && statBaseIn[j] == null) { + statBaseIn[j] = statBaseIn[i]; + } else { +@@ -342,4 +348,32 @@ + public static StatBase getOneShotStat(String statName) { + return ID_TO_STAT_MAP.get(statName); + } ++ ++ @Deprecated //MODDER DO NOT CALL THIS ITS JUST A EVENT CALLBACK FOR FORGE ++ public static void reinit() { ++ ID_TO_STAT_MAP.clear(); ++ BASIC_STATS.clear(); ++ USE_ITEM_STATS.clear(); ++ MINE_BLOCK_STATS.clear(); ++ ++ for (StatBase[] sb : new StatBase[][]{BLOCKS_STATS, CRAFTS_STATS, OBJECT_USE_STATS, OBJECT_BREAK_STATS, OBJECTS_PICKED_UP_STATS, OBJECTS_DROPPED_STATS}) { ++ for (int x = 0; x < sb.length; x++) { ++ if (sb[x] != null) { ++ ALL_STATS.remove(sb[x]); ++ sb[x] = null; ++ } ++ } ++ } ++ List unknown = Lists.newArrayList(ALL_STATS); ++ ALL_STATS.clear(); ++ ++ for (StatBase b : unknown) ++ b.registerStat(); ++ ++ initMiningStats(); ++ initStats(); ++ initItemDepleteStats(); ++ initCraftableStats(); ++ initPickedUpAndDroppedStats(); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/stats/StatisticsManagerServer.java.patch b/module/minecraft/patches/net/minecraft/stats/StatisticsManagerServer.java.patch new file mode 100644 index 000000000..693a58f80 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/stats/StatisticsManagerServer.java.patch @@ -0,0 +1,12 @@ +--- original/net/minecraft/stats/StatisticsManagerServer.java ++++ modified/net/minecraft/stats/StatisticsManagerServer.java +@@ -69,7 +69,8 @@ + } + + public Map parseJson(String p_150881_1_) { +- JsonElement jsonelement = new JsonParser().parse(p_150881_1_); ++ JsonElement jsonelement = JsonParser.parseString(p_150881_1_); ++ + if (!jsonelement.isJsonObject()) { + return Maps.newHashMap(); + } diff --git a/module/minecraft/patches/net/minecraft/tileentity/MobSpawnerBaseLogic.java.patch b/module/minecraft/patches/net/minecraft/tileentity/MobSpawnerBaseLogic.java.patch new file mode 100644 index 000000000..580955f3e --- /dev/null +++ b/module/minecraft/patches/net/minecraft/tileentity/MobSpawnerBaseLogic.java.patch @@ -0,0 +1,26 @@ +--- original/net/minecraft/tileentity/MobSpawnerBaseLogic.java ++++ modified/net/minecraft/tileentity/MobSpawnerBaseLogic.java +@@ -125,10 +125,12 @@ + + EntityLiving entityliving = entity instanceof EntityLiving ? (EntityLiving)entity : null; + entity.setLocationAndAngles(entity.posX, entity.posY, entity.posZ, world.rand.nextFloat() * 360.0F, 0.0F); +- if (entityliving == null || entityliving.getCanSpawnHere() && entityliving.isNotColliding()) { ++ ++ if (entityliving == null || net.minecraftforge.event.ForgeEventFactory.canEntitySpawnSpawner(entityliving, getSpawnerWorld(), (float)entity.posX, (float)entity.posY, (float)entity.posZ, this)) { + if (this.spawnData.getNbt().getSize() == 1 +- && this.spawnData.getNbt().hasKey("id", 8) +- && entity instanceof EntityLiving) { ++ && this.spawnData.getNbt().hasKey("id", 8) ++ && entity instanceof EntityLiving) { ++ if (!net.minecraftforge.event.ForgeEventFactory.doSpecialSpawn(entityliving, this.getSpawnerWorld(), (float)entity.posX, (float)entity.posY, (float)entity.posZ, this)) + ((EntityLiving)entity).onInitialSpawn(world.getDifficultyForLocation(new BlockPos(entity)), null); + } + +@@ -270,4 +272,7 @@ + public double getPrevMobRotation() { + return this.prevMobRotation; + } ++ ++ /* ======================================== FORGE START =====================================*/ ++ @Nullable public Entity getSpawnerEntity() { return null; } + } diff --git a/module/minecraft/patches/net/minecraft/tileentity/TileEntity.java.patch b/module/minecraft/patches/net/minecraft/tileentity/TileEntity.java.patch new file mode 100644 index 000000000..ce7678d3c --- /dev/null +++ b/module/minecraft/patches/net/minecraft/tileentity/TileEntity.java.patch @@ -0,0 +1,254 @@ +--- original/net/minecraft/tileentity/TileEntity.java ++++ modified/net/minecraft/tileentity/TileEntity.java +@@ -21,7 +21,7 @@ + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + +-public abstract class TileEntity { ++public abstract class TileEntity implements net.minecraftforge.common.capabilities.ICapabilitySerializable { + private static final Logger LOGGER = LogManager.getLogger(); + private static final RegistryNamespaced> REGISTRY = new RegistryNamespaced<>(); + /** the instance of the world the tile entity is in. */ +@@ -58,6 +58,8 @@ + + public void readFromNBT(NBTTagCompound compound) { + this.pos = new BlockPos(compound.getInteger("x"), compound.getInteger("y"), compound.getInteger("z")); ++ if (compound.hasKey("ForgeData")) this.customTileData = compound.getCompoundTag("ForgeData"); ++ if (this.capabilities != null && compound.hasKey("ForgeCaps")) this.capabilities.deserializeNBT(compound.getCompoundTag("ForgeCaps")); + } + + public NBTTagCompound writeToNBT(NBTTagCompound compound) { +@@ -74,6 +76,8 @@ + compound.setInteger("x", this.pos.getX()); + compound.setInteger("y", this.pos.getY()); + compound.setInteger("z", this.pos.getZ()); ++ if (this.customTileData != null) compound.setTag("ForgeData", this.customTileData); ++ if (this.capabilities != null) compound.setTag("ForgeCaps", this.capabilities.serializeNBT()); + return compound; + } + +@@ -81,14 +85,17 @@ + public static TileEntity create(World worldIn, NBTTagCompound compound) { + TileEntity tileentity = null; + String s = compound.getString("id"); ++ Class oclass = null; + + try { +- Class oclass = REGISTRY.getObject(new ResourceLocation(s)); ++ oclass = REGISTRY.getObject(new ResourceLocation(s)); + if (oclass != null) { +- tileentity = oclass.newInstance(); ++ tileentity = oclass.getConstructor().newInstance(); + } + } catch (Throwable throwable1) { + LOGGER.error("Failed to create block entity {}", s, throwable1); ++ net.minecraftforge.fml.common.FMLLog.log.error("A TileEntity {}({}) has thrown an exception during loading, its state cannot be restored. Report this to the mod author", ++ s, oclass == null ? null : oclass.getName(), throwable1); + } + + if (tileentity != null) { +@@ -97,6 +104,8 @@ + tileentity.readFromNBT(compound); + } catch (Throwable throwable) { + LOGGER.error("Failed to load data for block entity {}", s, throwable); ++ net.minecraftforge.fml.common.FMLLog.log.error("A TileEntity {}({}) has thrown an exception during loading, its state cannot be restored. Report this to the mod author", ++ s, oclass.getName(), throwable); + tileentity = null; + } + } else { +@@ -130,8 +139,6 @@ + } + } + +- /** Returns the square of the distance between this entity and the passed in coordinates. */ +- @SideOnly(Side.CLIENT) + public double getDistanceSq(double x, double y, double z) { + double d0 = this.pos.getX() + 0.5 - x; + double d1 = this.pos.getY() + 0.5 - y; +@@ -213,7 +220,7 @@ + + try { + return String.format( +- "ID #%d (%s // %s)", i, Block.getBlockById(i).getTranslationKey(), Block.getBlockById(i).getClass().getCanonicalName() ++ "ID #%d (%s // %s// %s)", i, Block.getBlockById(i).getTranslationKey(), Block.getBlockById(i).getClass().getName(), Block.getBlockById(i).getRegistryName() + ); + } catch (Throwable throwable) { + return "ID #" + i; +@@ -267,6 +274,177 @@ + public void mirror(Mirror mirrorIn) { + } + ++ // -- BEGIN FORGE PATCHES -- ++ /** ++ * Called when you receive a TileEntityData packet for the location this ++ * TileEntity is currently in. On the client, the NetworkManager will always ++ * be the remote server. On the server, it will be whomever is responsible for ++ * sending the packet. ++ * ++ * @param net The NetworkManager the packet originated from ++ * @param pkt The data packet ++ */ ++ public void onDataPacket(net.minecraft.network.NetworkManager net, net.minecraft.network.play.server.SPacketUpdateTileEntity pkt) { ++ } ++ ++ /** ++ * Called when the chunk's TE update tag, gotten from {@link #getUpdateTag()}, is received on the client. ++ *

++ * Used to handle this tag in a special way. By default this simply calls {@link #readFromNBT(NBTTagCompound)}. ++ * ++ * @param tag The {@link NBTTagCompound} sent from {@link #getUpdateTag()} ++ */ ++ public void handleUpdateTag(NBTTagCompound tag) { ++ this.readFromNBT(tag); ++ } ++ ++ /** ++ * Called when the chunk this TileEntity is on is Unloaded. ++ */ ++ public void onChunkUnload() { ++ } ++ ++ private boolean isVanilla = getClass().getName().startsWith("net.minecraft."); ++ /** ++ * Called from Chunk.setBlockIDWithMetadata and Chunk.fillChunk, determines if this tile entity should be re-created when the ID, or Metadata changes. ++ * Use with caution as this will leave straggler TileEntities, or create conflicts with other TileEntities if not used properly. ++ * ++ * @param world Current world ++ * @param pos Tile's world position ++ * @param oldState The old ID of the block ++ * @param newState The new ID of the block (May be the same) ++ * @return true forcing the invalidation of the existing TE, false not to invalidate the existing TE ++ */ ++ public boolean shouldRefresh(World world, BlockPos pos, IBlockState oldState, IBlockState newSate) { ++ return isVanilla ? (oldState.getBlock() != newSate.getBlock()) : oldState != newSate; ++ } ++ ++ public boolean shouldRenderInPass(int pass) { ++ return pass == 0; ++ } ++ ++ /** ++ * Sometimes default render bounding box: infinite in scope. Used to control rendering on {@link TileEntitySpecialRenderer}. ++ */ ++ public static final net.minecraft.util.math.AxisAlignedBB INFINITE_EXTENT_AABB = new net.minecraft.util.math.AxisAlignedBB(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY); ++ /** ++ * Return an {@link AxisAlignedBB} that controls the visible scope of a {@link TileEntitySpecialRenderer} associated with this {@link TileEntity} ++ * Defaults to the collision bounding box {@link Block#getCollisionBoundingBoxFromPool(World, int, int, int)} associated with the block ++ * at this location. ++ * ++ * @return an appropriately size {@link AxisAlignedBB} for the {@link TileEntity} ++ */ ++ @SideOnly(Side.CLIENT) ++ public net.minecraft.util.math.AxisAlignedBB getRenderBoundingBox() { ++ net.minecraft.util.math.AxisAlignedBB bb = INFINITE_EXTENT_AABB; ++ Block type = getBlockType(); ++ BlockPos pos = getPos(); ++ if (type == Blocks.ENCHANTING_TABLE) { ++ bb = new net.minecraft.util.math.AxisAlignedBB(pos, pos.add(1, 1, 1)); ++ } else if (type == Blocks.CHEST || type == Blocks.TRAPPED_CHEST) { ++ bb = new net.minecraft.util.math.AxisAlignedBB(pos.add(-1, 0, -1), pos.add(2, 2, 2)); ++ } else if (type == Blocks.STRUCTURE_BLOCK) { ++ bb = INFINITE_EXTENT_AABB; ++ } else if (type != null && type != Blocks.BEACON) { ++ net.minecraft.util.math.AxisAlignedBB cbb = null; ++ try { ++ cbb = world.getBlockState(getPos()).getCollisionBoundingBox(world, pos).offset(pos); ++ } catch (Exception e) { ++ // We have to capture any exceptions that may occur here because BUKKIT servers like to send ++ // the tile entity data BEFORE the chunk data, you know, the OPPOSITE of what vanilla does! ++ // So we can not GARENTEE that the world state is the real state for the block... ++ // So, once again in the long line of US having to accommodate BUKKIT breaking things, ++ // here it is, assume that the TE is only 1 cubic block. Problem with this is that it may ++ // cause the TileEntity renderer to error further down the line! But alas, nothing we can do. ++ cbb = new net.minecraft.util.math.AxisAlignedBB(getPos().add(-1, 0, -1), getPos().add(1, 1, 1)); ++ } ++ if (cbb != null) bb = cbb; ++ } ++ return bb; ++ } ++ ++ /** ++ * Checks if this tile entity knows how to render its 'breaking' overlay effect. ++ * If this returns true, The TileEntitySpecialRenderer will be called again with break progress set. ++ * @return True to re-render tile with breaking effect. ++ */ ++ public boolean canRenderBreaking() { ++ Block block = this.getBlockType(); ++ return (block instanceof net.minecraft.block.BlockChest || ++ block instanceof net.minecraft.block.BlockEnderChest || ++ block instanceof net.minecraft.block.BlockSign || ++ block instanceof net.minecraft.block.BlockSkull); ++ } ++ ++ private NBTTagCompound customTileData; ++ ++ /** ++ * Gets a {@link NBTTagCompound} that can be used to store custom data for this tile entity. ++ * It will be written, and read from disc, so it persists over world saves. ++ * ++ * @return A compound tag for custom data ++ */ ++ public NBTTagCompound getTileData() { ++ if (this.customTileData == null) { ++ this.customTileData = new NBTTagCompound(); ++ } ++ return this.customTileData; ++ } ++ ++ /** ++ * Determines if the player can overwrite the NBT data of this tile entity while they place it using a ItemStack. ++ * Added as a fix for MC-75630 - Exploit with signs and command blocks ++ * @return True to prevent NBT copy, false to allow. ++ */ ++ public boolean restrictNBTCopy() { ++ return this instanceof TileEntityCommandBlock || ++ this instanceof TileEntityMobSpawner || ++ this instanceof TileEntitySign; ++ } ++ ++ ++ /** ++ * Called when this is first added to the world (by {@link World#addTileEntity(TileEntity)}). ++ * Override instead of adding {@code if (firstTick)} stuff in update. ++ */ ++ public void onLoad() { ++ // NOOP ++ } ++ ++ /** ++ * If the TileEntitySpecialRenderer associated with this TileEntity can be batched in with another renderers, and won't access the GL state. ++ * If TileEntity returns true, then TESR should have the same functionality as (and probably extend) the FastTESR class. ++ */ ++ public boolean hasFastRenderer() { ++ return false; ++ } ++ ++ private net.minecraftforge.common.capabilities.CapabilityDispatcher capabilities; ++ public TileEntity() { ++ capabilities = net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(this); ++ } ++ ++ @Override ++ public boolean hasCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable net.minecraft.util.EnumFacing facing) { ++ return capabilities == null ? false : capabilities.hasCapability(capability, facing); ++ } ++ ++ @Override ++ @Nullable ++ public T getCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable net.minecraft.util.EnumFacing facing) { ++ return capabilities == null ? null : capabilities.getCapability(capability, facing); ++ } ++ ++ public void deserializeNBT(NBTTagCompound nbt) { ++ this.readFromNBT(nbt); ++ } ++ ++ public NBTTagCompound serializeNBT() { ++ NBTTagCompound ret = new NBTTagCompound(); ++ this.writeToNBT(ret); ++ return ret; ++ } ++ + static { + register("furnace", TileEntityFurnace.class); + register("chest", TileEntityChest.class); diff --git a/module/minecraft/patches/net/minecraft/tileentity/TileEntityBeacon.java.patch b/module/minecraft/patches/net/minecraft/tileentity/TileEntityBeacon.java.patch new file mode 100644 index 000000000..92150aabc --- /dev/null +++ b/module/minecraft/patches/net/minecraft/tileentity/TileEntityBeacon.java.patch @@ -0,0 +1,50 @@ +--- original/net/minecraft/tileentity/TileEntityBeacon.java ++++ modified/net/minecraft/tileentity/TileEntityBeacon.java +@@ -127,16 +127,22 @@ + afloat = iblockstate.getValue(BlockStainedGlass.COLOR).getColorComponentValues(); + } else { + if (iblockstate.getBlock() != Blocks.STAINED_GLASS_PANE) { +- if (iblockstate.getLightOpacity() >= 15 && iblockstate.getBlock() != Blocks.BEDROCK) { ++ if (iblockstate.getLightOpacity(world, blockpos$mutableblockpos) >= 15 && iblockstate.getBlock() != Blocks.BEDROCK) { + this.isComplete = false; + this.beamSegments.clear(); + break; + } + ++ float[] customColor = iblockstate.getBlock().getBeaconColorMultiplier(iblockstate, this.world, blockpos$mutableblockpos, getPos()); ++ if (customColor != null) ++ afloat = customColor; ++ else { + tileentitybeacon$beamsegment.incrementHeight(); + continue; ++ } + } + ++ else + afloat = iblockstate.getValue(BlockStainedGlassPane.COLOR).getColorComponentValues(); + } + +@@ -170,10 +176,7 @@ + for (int j1 = i - l1; j1 <= i + l1 && flag1; j1++) { + for (int k1 = k - l1; k1 <= k + l1; k1++) { + Block block = this.world.getBlockState(new BlockPos(j1, i2, k1)).getBlock(); +- if (block != Blocks.EMERALD_BLOCK +- && block != Blocks.GOLD_BLOCK +- && block != Blocks.DIAMOND_BLOCK +- && block != Blocks.IRON_BLOCK) { ++ if (!block.isBeaconBase(this.world, new BlockPos(j1, i2, k1), getPos())) { + flag1 = false; + break; + } +@@ -392,10 +395,7 @@ + /** Returns true if automation is allowed to insert the given stack (ignoring stack size) into the given slot. For guis use Slot.isItemValid */ + @Override + public boolean isItemValidForSlot(int index, ItemStack stack) { +- return stack.getItem() == Items.EMERALD +- || stack.getItem() == Items.DIAMOND +- || stack.getItem() == Items.GOLD_INGOT +- || stack.getItem() == Items.IRON_INGOT; ++ return stack.getItem() != null && stack.getItem().isBeaconPayment(stack); + } + + @Override diff --git a/module/minecraft/patches/net/minecraft/tileentity/TileEntityBrewingStand.java.patch b/module/minecraft/patches/net/minecraft/tileentity/TileEntityBrewingStand.java.patch new file mode 100644 index 000000000..2ceb79800 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/tileentity/TileEntityBrewingStand.java.patch @@ -0,0 +1,85 @@ +--- original/net/minecraft/tileentity/TileEntityBrewingStand.java ++++ modified/net/minecraft/tileentity/TileEntityBrewingStand.java +@@ -160,6 +160,7 @@ + } + + private boolean canBrew() { ++ if (1 == 1) return net.minecraftforge.common.brewing.BrewingRecipeRegistry.canBrew(brewingItemStacks, brewingItemStacks.get(3), OUTPUT_SLOTS); // divert to VanillaBrewingRegistry + ItemStack itemstack = this.brewingItemStacks.get(3); + if (itemstack.isEmpty()) { + return false; +@@ -180,16 +181,17 @@ + } + + private void brewPotions() { ++ if (net.minecraftforge.event.ForgeEventFactory.onPotionAttemptBrew(brewingItemStacks)) return; + ItemStack itemstack = this.brewingItemStacks.get(3); + +- for (int i = 0; i < 3; i++) { +- this.brewingItemStacks.set(i, PotionHelper.doReaction(itemstack, this.brewingItemStacks.get(i))); +- } ++ net.minecraftforge.common.brewing.BrewingRecipeRegistry.brewPotions(brewingItemStacks, brewingItemStacks.get(3), OUTPUT_SLOTS); + + itemstack.shrink(1); + BlockPos blockpos = this.getPos(); +- if (itemstack.getItem().hasContainerItem()) { +- ItemStack itemstack1 = new ItemStack(itemstack.getItem().getContainerItem()); ++ ++ if (itemstack.getItem().hasContainerItem(itemstack)) { ++ ItemStack itemstack1 = itemstack.getItem().getContainerItem(itemstack); ++ + if (itemstack.isEmpty()) { + itemstack = itemstack1; + } else { +@@ -199,6 +201,7 @@ + + this.brewingItemStacks.set(3, itemstack); + this.world.playEvent(1035, blockpos, 0); ++ net.minecraftforge.event.ForgeEventFactory.onPotionBrewed(brewingItemStacks); + } + + public static void registerFixesBrewingStand(DataFixer fixer) { +@@ -288,14 +291,13 @@ + @Override + public boolean isItemValidForSlot(int index, ItemStack stack) { + if (index == 3) { +- return PotionHelper.isReagent(stack); ++ return net.minecraftforge.common.brewing.BrewingRecipeRegistry.isValidIngredient(stack); + } + + Item item = stack.getItem(); + return index == 4 + ? item == Items.BLAZE_POWDER +- : (item == Items.POTIONITEM || item == Items.SPLASH_POTION || item == Items.LINGERING_POTION || item == Items.GLASS_BOTTLE) +- && this.getStackInSlot(index).isEmpty(); ++ : net.minecraftforge.common.brewing.BrewingRecipeRegistry.isValidInput(stack) && this.getStackInSlot(index).isEmpty(); + } + + @Override +@@ -352,7 +354,26 @@ + } + } + ++ net.minecraftforge.items.IItemHandler handlerInput = new net.minecraftforge.items.wrapper.SidedInvWrapper(this, net.minecraft.util.EnumFacing.UP); ++ net.minecraftforge.items.IItemHandler handlerOutput = new net.minecraftforge.items.wrapper.SidedInvWrapper(this, net.minecraft.util.EnumFacing.DOWN); ++ net.minecraftforge.items.IItemHandler handlerSides = new net.minecraftforge.items.wrapper.SidedInvWrapper(this, net.minecraft.util.EnumFacing.NORTH); ++ ++ @SuppressWarnings("unchecked") + @Override ++ @javax.annotation.Nullable ++ public T getCapability(net.minecraftforge.common.capabilities.Capability capability, @javax.annotation.Nullable net.minecraft.util.EnumFacing facing) { ++ if (facing != null && capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { ++ if (facing == EnumFacing.UP) ++ return (T) handlerInput; ++ else if (facing == EnumFacing.DOWN) ++ return (T) handlerOutput; ++ else ++ return (T) handlerSides; ++ } ++ return super.getCapability(capability, facing); ++ } ++ ++ @Override + public int getFieldCount() { + return 2; + } diff --git a/module/minecraft/patches/net/minecraft/tileentity/TileEntityChest.java.patch b/module/minecraft/patches/net/minecraft/tileentity/TileEntityChest.java.patch new file mode 100644 index 000000000..44aa12c58 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/tileentity/TileEntityChest.java.patch @@ -0,0 +1,46 @@ +--- original/net/minecraft/tileentity/TileEntityChest.java ++++ modified/net/minecraft/tileentity/TileEntityChest.java +@@ -130,6 +130,7 @@ + public void updateContainingBlockInfo() { + super.updateContainingBlockInfo(); + this.adjacentChestChecked = false; ++ doubleChestHandler = null; + } + + private void setNeighbor(TileEntityChest chestTe, EnumFacing side) { +@@ -163,6 +164,7 @@ + /** Performs the check for adjacent chests to determine if this chest is double or not. */ + public void checkForAdjacentChests() { + if (!this.adjacentChestChecked) { ++ if (this.world == null || !this.world.isAreaLoaded(this.pos, 1)) return; // Forge: prevent loading unloaded chunks when checking neighbors + this.adjacentChestChecked = true; + this.adjacentChestXNeg = this.getAdjacentChest(EnumFacing.WEST); + this.adjacentChestXPos = this.getAdjacentChest(EnumFacing.EAST); +@@ -319,8 +321,26 @@ + } + } + +- /** invalidates a tile entity */ ++ public net.minecraftforge.items.VanillaDoubleChestItemHandler doubleChestHandler; ++ ++ @SuppressWarnings("unchecked") + @Override ++ @Nullable ++ public T getCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable net.minecraft.util.EnumFacing facing) { ++ if (capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { ++ if(doubleChestHandler == null || doubleChestHandler.needsRefresh()) ++ doubleChestHandler = net.minecraftforge.items.VanillaDoubleChestItemHandler.get(this); ++ if (doubleChestHandler != null && doubleChestHandler != net.minecraftforge.items.VanillaDoubleChestItemHandler.NO_ADJACENT_CHESTS_INSTANCE) ++ return (T) doubleChestHandler; ++ } ++ return super.getCapability(capability, facing); ++ } ++ ++ public net.minecraftforge.items.IItemHandler getSingleChestHandler() { ++ return super.getCapability(net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null); ++ } ++ ++ @Override + public void invalidate() { + super.invalidate(); + this.updateContainingBlockInfo(); diff --git a/module/minecraft/patches/net/minecraft/tileentity/TileEntityFurnace.java.patch b/module/minecraft/patches/net/minecraft/tileentity/TileEntityFurnace.java.patch new file mode 100644 index 000000000..24044ef4e --- /dev/null +++ b/module/minecraft/patches/net/minecraft/tileentity/TileEntityFurnace.java.patch @@ -0,0 +1,94 @@ +--- original/net/minecraft/tileentity/TileEntityFurnace.java ++++ modified/net/minecraft/tileentity/TileEntityFurnace.java +@@ -146,9 +146,9 @@ + super.readFromNBT(compound); + this.furnaceItemStacks = NonNullList.withSize(this.getSizeInventory(), ItemStack.EMPTY); + ItemStackHelper.loadAllItems(compound, this.furnaceItemStacks); +- this.furnaceBurnTime = compound.getShort("BurnTime"); +- this.cookTime = compound.getShort("CookTime"); +- this.totalCookTime = compound.getShort("CookTimeTotal"); ++ this.furnaceBurnTime = compound.getInteger("BurnTime"); ++ this.cookTime = compound.getInteger("CookTime"); ++ this.totalCookTime = compound.getInteger("CookTimeTotal"); + this.currentItemBurnTime = getItemBurnTime(this.furnaceItemStacks.get(1)); + if (compound.hasKey("CustomName", 8)) { + this.furnaceCustomName = compound.getString("CustomName"); +@@ -158,9 +158,9 @@ + @Override + public NBTTagCompound writeToNBT(NBTTagCompound compound) { + super.writeToNBT(compound); +- compound.setShort("BurnTime", (short)this.furnaceBurnTime); +- compound.setShort("CookTime", (short)this.cookTime); +- compound.setShort("CookTimeTotal", (short)this.totalCookTime); ++ compound.setInteger("BurnTime", (short)this.furnaceBurnTime); ++ compound.setInteger("CookTime", (short)this.cookTime); ++ compound.setInteger("CookTimeTotal", (short)this.totalCookTime); + ItemStackHelper.saveAllItems(compound, this.furnaceItemStacks); + if (this.hasCustomName()) { + compound.setString("CustomName", this.furnaceCustomName); +@@ -206,8 +206,8 @@ + Item item = itemstack.getItem(); + itemstack.shrink(1); + if (itemstack.isEmpty()) { +- Item item1 = item.getContainerItem(); +- this.furnaceItemStacks.set(1, item1 == null ? ItemStack.EMPTY : new ItemStack(item1)); ++ ItemStack item1 = item.getContainerItem(itemstack); ++ this.furnaceItemStacks.set(1, item1); + } + } + } +@@ -257,10 +257,10 @@ + return true; + } else if (!itemstack1.isItemEqual(itemstack)) { + return false; ++ } else if (itemstack1.getCount() + itemstack.getCount() <= this.getInventoryStackLimit() && itemstack1.getCount() + itemstack.getCount() <= itemstack1.getMaxStackSize()) { // Forge fix: make furnace respect stack sizes in furnace recipes ++ return true; + } else { +- return itemstack1.getCount() < this.getInventoryStackLimit() && itemstack1.getCount() < itemstack1.getMaxStackSize() +- ? true +- : itemstack1.getCount() < itemstack.getMaxStackSize(); ++ return itemstack1.getCount() + itemstack.getCount() <= itemstack.getMaxStackSize(); // Forge fix: make furnace respect stack sizes in furnace recipes + } + } + } +@@ -275,7 +275,7 @@ + if (itemstack2.isEmpty()) { + this.furnaceItemStacks.set(2, itemstack1.copy()); + } else if (itemstack2.getItem() == itemstack1.getItem()) { +- itemstack2.grow(1); ++ itemstack2.grow(itemstack1.getCount()); + } + + if (itemstack.getItem() == Item.getItemFromBlock(Blocks.SPONGE) +@@ -294,6 +294,8 @@ + if (stack.isEmpty()) { + return 0; + } else { ++ int burnTime = net.minecraftforge.event.ForgeEventFactory.getItemBurnTime(stack); ++ if (burnTime >= 0) return burnTime; + Item item = stack.getItem(); + if (item == Item.getItemFromBlock(Blocks.WOODEN_SLAB)) { + return 150; +@@ -457,4 +459,22 @@ + public void clear() { + this.furnaceItemStacks.clear(); + } ++ ++ net.minecraftforge.items.IItemHandler handlerTop = new net.minecraftforge.items.wrapper.SidedInvWrapper(this, net.minecraft.util.EnumFacing.UP); ++ net.minecraftforge.items.IItemHandler handlerBottom = new net.minecraftforge.items.wrapper.SidedInvWrapper(this, net.minecraft.util.EnumFacing.DOWN); ++ net.minecraftforge.items.IItemHandler handlerSide = new net.minecraftforge.items.wrapper.SidedInvWrapper(this, net.minecraft.util.EnumFacing.WEST); ++ ++ @SuppressWarnings("unchecked") ++ @Override ++ @javax.annotation.Nullable ++ public T getCapability(net.minecraftforge.common.capabilities.Capability capability, @javax.annotation.Nullable net.minecraft.util.EnumFacing facing) { ++ if (facing != null && capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) ++ if (facing == EnumFacing.DOWN) ++ return (T) handlerBottom; ++ else if (facing == EnumFacing.UP) ++ return (T) handlerTop; ++ else ++ return (T) handlerSide; ++ return super.getCapability(capability, facing); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/tileentity/TileEntityHopper.java.patch b/module/minecraft/patches/net/minecraft/tileentity/TileEntityHopper.java.patch new file mode 100644 index 000000000..ad4686a52 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/tileentity/TileEntityHopper.java.patch @@ -0,0 +1,62 @@ +--- original/net/minecraft/tileentity/TileEntityHopper.java ++++ modified/net/minecraft/tileentity/TileEntityHopper.java +@@ -77,7 +77,8 @@ + @Override + public ItemStack decrStackSize(int index, int count) { + this.fillWithLoot(null); +- return ItemStackHelper.getAndSplit(this.getItems(), index, count); ++ ItemStack itemstack = ItemStackHelper.getAndSplit(this.getItems(), index, count); ++ return itemstack; + } + + /** Sets the given item stack to the specified slot in the inventory (can be crafting or armor sections). */ +@@ -180,6 +181,7 @@ + } + + private boolean transferItemsOut() { ++ if (net.minecraftforge.items.VanillaInventoryCodeHooks.insertHook(this)) { return true; } + IInventory iinventory = this.getInventoryForHopperTransfer(); + if (iinventory == null) { + return false; +@@ -263,6 +265,8 @@ + * @return whether any items were successfully added to the hopper + */ + public static boolean pullItems(IHopper hopper) { ++ Boolean ret = net.minecraftforge.items.VanillaInventoryCodeHooks.extractHook(hopper); ++ if (ret != null) return ret; + IInventory iinventory = getSourceInventory(hopper); + if (iinventory != null) { + EnumFacing enumfacing = EnumFacing.DOWN; +@@ -337,7 +341,11 @@ + return flag; + } + +- /** Attempts to place the passed stack in the inventory, using as many slots as required. Returns leftover items */ ++ ++ protected net.minecraftforge.items.IItemHandler createUnSidedHandler() { ++ return new net.minecraftforge.items.VanillaHopperItemHandler(this); ++ } ++ + public static ItemStack putStackInInventoryAllSlots(IInventory source, IInventory destination, ItemStack stack, @Nullable EnumFacing direction) { + if (destination instanceof ISidedInventory && direction != null) { + ISidedInventory isidedinventory = (ISidedInventory)destination; +@@ -441,8 +449,10 @@ + int j = MathHelper.floor(y); + int k = MathHelper.floor(z); + BlockPos blockpos = new BlockPos(i, j, k); +- Block block = worldIn.getBlockState(blockpos).getBlock(); +- if (block.hasTileEntity()) { ++ net.minecraft.block.state.IBlockState state = worldIn.getBlockState(blockpos); ++ Block block = state.getBlock(); ++ ++ if (block.hasTileEntity(state)) { + TileEntity tileentity = worldIn.getTileEntity(blockpos); + if (tileentity instanceof IInventory) { + iinventory = (IInventory)tileentity; +@@ -521,4 +531,6 @@ + protected NonNullList getItems() { + return this.inventory; + } ++ ++ public long getLastUpdateTime() { return tickedGameTime; } // Forge + } diff --git a/module/minecraft/patches/net/minecraft/tileentity/TileEntityLockable.java.patch b/module/minecraft/patches/net/minecraft/tileentity/TileEntityLockable.java.patch new file mode 100644 index 000000000..5a86dca44 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/tileentity/TileEntityLockable.java.patch @@ -0,0 +1,27 @@ +--- original/net/minecraft/tileentity/TileEntityLockable.java ++++ modified/net/minecraft/tileentity/TileEntityLockable.java +@@ -57,4 +57,24 @@ + public ITextComponent getDisplayName() { + return this.hasCustomName() ? new TextComponentString(this.getName()) : new TextComponentTranslation(this.getName()); + } ++ ++ private net.minecraftforge.items.IItemHandler itemHandler; ++ ++ protected net.minecraftforge.items.IItemHandler createUnSidedHandler() { ++ return new net.minecraftforge.items.wrapper.InvWrapper(this); ++ } ++ ++ @SuppressWarnings("unchecked") ++ @Override ++ @javax.annotation.Nullable ++ public T getCapability(net.minecraftforge.common.capabilities.Capability capability, @javax.annotation.Nullable net.minecraft.util.EnumFacing facing) { ++ if (capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) ++ return (T) (itemHandler == null ? (itemHandler = createUnSidedHandler()) : itemHandler); ++ return super.getCapability(capability, facing); ++ } ++ ++ @Override ++ public boolean hasCapability(net.minecraftforge.common.capabilities.Capability capability, @javax.annotation.Nullable net.minecraft.util.EnumFacing facing) { ++ return capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY || super.hasCapability(capability, facing); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/tileentity/TileEntityLockableLoot.java.patch b/module/minecraft/patches/net/minecraft/tileentity/TileEntityLockableLoot.java.patch new file mode 100644 index 000000000..7e7c6a209 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/tileentity/TileEntityLockableLoot.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/tileentity/TileEntityLockableLoot.java ++++ modified/net/minecraft/tileentity/TileEntityLockableLoot.java +@@ -54,7 +54,7 @@ + + LootContext.Builder lootcontext$builder = new LootContext.Builder((WorldServer)this.world); + if (player != null) { +- lootcontext$builder.withLuck(player.getLuck()); ++ lootcontext$builder.withLuck(player.getLuck()).withPlayer(player); // Forge: add player to LootContext + } + + loottable.fillInventory(this, random, lootcontext$builder.build()); diff --git a/module/minecraft/patches/net/minecraft/tileentity/TileEntityNote.java.patch b/module/minecraft/patches/net/minecraft/tileentity/TileEntityNote.java.patch new file mode 100644 index 000000000..a8ab4067c --- /dev/null +++ b/module/minecraft/patches/net/minecraft/tileentity/TileEntityNote.java.patch @@ -0,0 +1,12 @@ +--- original/net/minecraft/tileentity/TileEntityNote.java ++++ modified/net/minecraft/tileentity/TileEntityNote.java +@@ -33,7 +33,9 @@ + + /** change pitch by -> (currentPitch + 1) % 25 */ + public void changePitch() { ++ byte old = note; + this.note = (byte)((this.note + 1) % 25); ++ if (!net.minecraftforge.common.ForgeHooks.onNoteChange(this, old)) return; + this.markDirty(); + } + diff --git a/module/minecraft/patches/net/minecraft/tileentity/TileEntityPiston.java.patch b/module/minecraft/patches/net/minecraft/tileentity/TileEntityPiston.java.patch new file mode 100644 index 000000000..12c348627 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/tileentity/TileEntityPiston.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/tileentity/TileEntityPiston.java ++++ modified/net/minecraft/tileentity/TileEntityPiston.java +@@ -143,7 +143,7 @@ + AxisAlignedBB axisalignedbb = this.moveByPositionAndProgress(this.getMinMaxPiecesAABB(list)); + List list1 = this.world.getEntitiesWithinAABBExcludingEntity(null, this.getMovementArea(axisalignedbb, enumfacing, d0).union(axisalignedbb)); + if (!list1.isEmpty()) { +- boolean flag = this.pistonState.getBlock() == Blocks.SLIME_BLOCK; ++ boolean flag = this.pistonState.getBlock().isStickyBlock(this.pistonState); + + for (int i = 0; i < list1.size(); i++) { + Entity entity = list1.get(i); diff --git a/module/minecraft/patches/net/minecraft/tileentity/TileEntityShulkerBox.java.patch b/module/minecraft/patches/net/minecraft/tileentity/TileEntityShulkerBox.java.patch new file mode 100644 index 000000000..40fe9a5f2 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/tileentity/TileEntityShulkerBox.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/tileentity/TileEntityShulkerBox.java ++++ modified/net/minecraft/tileentity/TileEntityShulkerBox.java +@@ -393,4 +393,8 @@ + OPENED, + CLOSING; + } ++ ++ protected net.minecraftforge.items.IItemHandler createUnSidedHandler() { ++ return new net.minecraftforge.items.wrapper.SidedInvWrapper(this, EnumFacing.UP); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/tileentity/TileEntitySign.java.patch b/module/minecraft/patches/net/minecraft/tileentity/TileEntitySign.java.patch new file mode 100644 index 000000000..6323633f1 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/tileentity/TileEntitySign.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/tileentity/TileEntitySign.java ++++ modified/net/minecraft/tileentity/TileEntitySign.java +@@ -76,7 +76,7 @@ + /** Returns {@code true} if the CommandSender is allowed to execute the command, {@code false} if not */ + @Override + public boolean canUseCommand(int permLevel, String commandName) { +- return true; ++ return permLevel <= 2; //Forge: Fixes MC-75630 - Exploit with signs and command blocks + } + + /** Get the position in the world. {@code null} is not allowed! If you are not an entity in the world, return the coordinates 0, 0, 0 */ diff --git a/module/minecraft/patches/net/minecraft/util/ActionResult.java.patch b/module/minecraft/patches/net/minecraft/util/ActionResult.java.patch new file mode 100644 index 000000000..dc0e04cf2 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/util/ActionResult.java.patch @@ -0,0 +1,12 @@ +--- original/net/minecraft/util/ActionResult.java ++++ modified/net/minecraft/util/ActionResult.java +@@ -16,4 +16,9 @@ + public T getResult() { + return this.result; + } ++ ++ //Just a generic helper function to make typecasing easier... ++ public static ActionResult newResult(EnumActionResult result, T value) { ++ return new ActionResult(result, value); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/util/BlockRenderLayer.java.patch b/module/minecraft/patches/net/minecraft/util/BlockRenderLayer.java.patch new file mode 100644 index 000000000..4a82974e8 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/util/BlockRenderLayer.java.patch @@ -0,0 +1,12 @@ +--- original/net/minecraft/util/BlockRenderLayer.java ++++ modified/net/minecraft/util/BlockRenderLayer.java +@@ -1,9 +1,5 @@ + package net.minecraft.util; + +-import net.minecraftforge.fml.relauncher.Side; +-import net.minecraftforge.fml.relauncher.SideOnly; +- +-@SideOnly(Side.CLIENT) + public enum BlockRenderLayer { + SOLID("Solid"), + CUTOUT_MIPPED("Mipped Cutout"), diff --git a/module/minecraft/patches/net/minecraft/util/ChatAllowedCharacters.java.patch b/module/minecraft/patches/net/minecraft/util/ChatAllowedCharacters.java.patch new file mode 100644 index 000000000..296573543 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/util/ChatAllowedCharacters.java.patch @@ -0,0 +1,10 @@ +--- original/net/minecraft/util/ChatAllowedCharacters.java ++++ modified/net/minecraft/util/ChatAllowedCharacters.java +@@ -33,6 +33,7 @@ + } + + static { ++ if (System.getProperty("io.netty.leakDetection.level") == null) // Forge: allow level to be manually specified + ResourceLeakDetector.setLevel(NETTY_LEAK_DETECTION); + } + } diff --git a/module/minecraft/patches/net/minecraft/util/ClassInheritanceMultiMap.java.patch b/module/minecraft/patches/net/minecraft/util/ClassInheritanceMultiMap.java.patch new file mode 100644 index 000000000..1de224724 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/util/ClassInheritanceMultiMap.java.patch @@ -0,0 +1,12 @@ +--- original/net/minecraft/util/ClassInheritanceMultiMap.java ++++ modified/net/minecraft/util/ClassInheritanceMultiMap.java +@@ -12,7 +12,8 @@ + import java.util.Set; + + public class ClassInheritanceMultiMap extends AbstractSet { +- private static final Set> ALL_KNOWN = Sets.newHashSet(); ++ // Forge: Use concurrent collection to allow creating chunks from multiple threads safely ++ private static final Set> ALL_KNOWN = java.util.Collections.newSetFromMap(new java.util.concurrent.ConcurrentHashMap<>()); + private final Map, List> map = Maps.newHashMap(); + private final Set> knownKeys = Sets.newIdentityHashSet(); + private final Class baseClass; diff --git a/module/minecraft/patches/net/minecraft/util/EnumFacing.java.patch b/module/minecraft/patches/net/minecraft/util/EnumFacing.java.patch new file mode 100644 index 000000000..0165be7c1 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/util/EnumFacing.java.patch @@ -0,0 +1,71 @@ +--- original/net/minecraft/util/EnumFacing.java ++++ modified/net/minecraft/util/EnumFacing.java +@@ -12,8 +12,6 @@ + import net.minecraft.util.math.BlockPos; + import net.minecraft.util.math.MathHelper; + import net.minecraft.util.math.Vec3i; +-import net.minecraftforge.fml.relauncher.Side; +-import net.minecraftforge.fml.relauncher.SideOnly; + + public enum EnumFacing implements IStringSerializable { + DOWN(0, 1, -1, "down", EnumFacing.AxisDirection.NEGATIVE, EnumFacing.Axis.Y, new Vec3i(0, -1, 0)), +@@ -78,8 +76,6 @@ + return byIndex(this.opposite); + } + +- /** Rotate this Facing around the given axis clockwise. If this facing cannot be rotated around the given axis, returns this facing without rotating. */ +- @SideOnly(Side.CLIENT) + public EnumFacing rotateAround(EnumFacing.Axis axis) { + switch (axis) { + case X: +@@ -121,8 +117,6 @@ + } + } + +- /** Rotate this Facing around the X axis (NORTH => DOWN => SOUTH => UP => NORTH) */ +- @SideOnly(Side.CLIENT) + private EnumFacing rotateX() { + switch (this) { + case NORTH: +@@ -140,8 +134,6 @@ + } + } + +- /** Rotate this Facing around the Z axis (EAST => DOWN => WEST => UP => EAST) */ +- @SideOnly(Side.CLIENT) + private EnumFacing rotateZ() { + switch (this) { + case EAST: +@@ -200,7 +192,6 @@ + + /** Get the facing specified by the given name */ + @Nullable +- @SideOnly(Side.CLIENT) + public static EnumFacing byName(String name) { + return name == null ? null : NAME_LOOKUP.get(name.toLowerCase(Locale.ROOT)); + } +@@ -230,7 +221,6 @@ + return values()[rand.nextInt(values().length)]; + } + +- @SideOnly(Side.CLIENT) + public static EnumFacing getFacingFromVector(float x, float y, float z) { + EnumFacing enumfacing = NORTH; + float f = Float.MIN_VALUE; +@@ -284,8 +274,6 @@ + return placer.getHorizontalFacing().getOpposite(); + } + +- /** Get a normalized Vector that points in the direction of this Facing. */ +- @SideOnly(Side.CLIENT) + public Vec3i getDirectionVec() { + return this.directionVec; + } +@@ -317,7 +305,6 @@ + + /** Get the axis specified by the given name */ + @Nullable +- @SideOnly(Side.CLIENT) + public static EnumFacing.Axis byName(String name) { + return name == null ? null : NAME_LOOKUP.get(name.toLowerCase(Locale.ROOT)); + } diff --git a/module/minecraft/patches/net/minecraft/util/IntIdentityHashBiMap.java.patch b/module/minecraft/patches/net/minecraft/util/IntIdentityHashBiMap.java.patch new file mode 100644 index 000000000..93345fe4c --- /dev/null +++ b/module/minecraft/patches/net/minecraft/util/IntIdentityHashBiMap.java.patch @@ -0,0 +1,10 @@ +--- original/net/minecraft/util/IntIdentityHashBiMap.java ++++ modified/net/minecraft/util/IntIdentityHashBiMap.java +@@ -141,7 +141,6 @@ + return Iterators.filter(Iterators.forArray(this.byId), Predicates.notNull()); + } + +- @SideOnly(Side.CLIENT) + public void clear() { + Arrays.fill(this.values, null); + Arrays.fill(this.byId, null); diff --git a/module/minecraft/patches/net/minecraft/util/MouseHelper.java.patch b/module/minecraft/patches/net/minecraft/util/MouseHelper.java.patch new file mode 100644 index 000000000..0cbcaed8f --- /dev/null +++ b/module/minecraft/patches/net/minecraft/util/MouseHelper.java.patch @@ -0,0 +1,10 @@ +--- original/net/minecraft/util/MouseHelper.java ++++ modified/net/minecraft/util/MouseHelper.java +@@ -14,6 +14,7 @@ + + /** Grabs the mouse cursor it doesn't move and isn't seen. */ + public void grabMouseCursor() { ++ if (Boolean.parseBoolean(System.getProperty("fml.noGrab","false"))) return; + Mouse.setGrabbed(true); + this.deltaX = 0; + this.deltaY = 0; diff --git a/module/minecraft/patches/net/minecraft/util/ScreenShotHelper.java.patch b/module/minecraft/patches/net/minecraft/util/ScreenShotHelper.java.patch new file mode 100644 index 000000000..a2a44227a --- /dev/null +++ b/module/minecraft/patches/net/minecraft/util/ScreenShotHelper.java.patch @@ -0,0 +1,17 @@ +--- original/net/minecraft/util/ScreenShotHelper.java ++++ modified/net/minecraft/util/ScreenShotHelper.java +@@ -56,10 +56,14 @@ + file2 = new File(file1, screenshotName); + } + ++ file2 = file2.getCanonicalFile(); // FORGE: Fix errors on Windows with paths that include \.\ ++ net.minecraftforge.client.event.ScreenshotEvent event = net.minecraftforge.client.ForgeHooksClient.onScreenshot(bufferedimage, file2); ++ if (event.isCanceled()) return event.getCancelMessage(); else file2 = event.getScreenshotFile(); + ImageIO.write(bufferedimage, "png", file2); + ITextComponent itextcomponent = new TextComponentString(file2.getName()); + itextcomponent.getStyle().setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_FILE, file2.getAbsolutePath())); + itextcomponent.getStyle().setUnderlined(true); ++ if (event.getResultMessage() != null) return event.getResultMessage(); + return new TextComponentTranslation("screenshot.success", itextcomponent); + } catch (Exception exception) { + LOGGER.warn("Couldn't save screenshot", exception); diff --git a/module/minecraft/patches/net/minecraft/util/ServerRecipeBookHelper.java.patch b/module/minecraft/patches/net/minecraft/util/ServerRecipeBookHelper.java.patch new file mode 100644 index 000000000..1024d7d02 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/util/ServerRecipeBookHelper.java.patch @@ -0,0 +1,28 @@ +--- original/net/minecraft/util/ServerRecipeBookHelper.java ++++ modified/net/minecraft/util/ServerRecipeBookHelper.java +@@ -46,6 +46,9 @@ + } else if (container instanceof ContainerPlayer) { + this.field_194335_f = ((ContainerPlayer)container).craftResult; + this.field_194336_g = ((ContainerPlayer)container).craftMatrix; ++ } else if (container instanceof net.minecraftforge.common.crafting.IRecipeContainer) { ++ this.field_194335_f = ((net.minecraftforge.common.crafting.IRecipeContainer)container).getCraftResult(); ++ this.field_194336_g = ((net.minecraftforge.common.crafting.IRecipeContainer)container).getCraftMatrix(); + } + + if (this.field_194335_f != null && this.field_194336_g != null) { +@@ -153,10 +156,11 @@ + private void func_194323_a(int p_194323_1_, IntList p_194323_2_) { + int i = this.field_194336_g.getWidth(); + int j = this.field_194336_g.getHeight(); +- if (this.field_194333_d instanceof ShapedRecipes) { +- ShapedRecipes shapedrecipes = (ShapedRecipes)this.field_194333_d; +- i = shapedrecipes.getWidth(); +- j = shapedrecipes.getHeight(); ++ ++ if (this.field_194333_d instanceof net.minecraftforge.common.crafting.IShapedRecipe) { ++ net.minecraftforge.common.crafting.IShapedRecipe shapedrecipes = (net.minecraftforge.common.crafting.IShapedRecipe)this.field_194333_d; ++ i = shapedrecipes.getRecipeWidth(); ++ j = shapedrecipes.getRecipeHeight(); + } + + int j1 = 1; diff --git a/module/minecraft/patches/net/minecraft/util/Session.java.patch b/module/minecraft/patches/net/minecraft/util/Session.java.patch new file mode 100644 index 000000000..b3a9b6319 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/util/Session.java.patch @@ -0,0 +1,54 @@ +--- original/net/minecraft/util/Session.java ++++ modified/net/minecraft/util/Session.java +@@ -16,8 +16,23 @@ + private final String playerID; + private final String token; + private final Session.Type sessionType; ++ /** Forge: Cache of the local session's GameProfile properties. */ ++ private com.mojang.authlib.properties.PropertyMap properties; + + public Session(String usernameIn, String playerIDIn, String tokenIn, String sessionTypeIn) { ++ if (usernameIn == null || usernameIn.isEmpty()) { ++ usernameIn = "MissingName"; ++ playerIDIn = tokenIn = "NotValid"; ++ org.apache.logging.log4j.Logger logger = net.minecraftforge.fml.common.FMLLog.log; ++ logger.log(org.apache.logging.log4j.Level.WARN, "========================================================="); ++ logger.log(org.apache.logging.log4j.Level.WARN, "WARNING!! the username was not set for this session, typically"); ++ logger.log(org.apache.logging.log4j.Level.WARN, "this means you installed Forge incorrectly. We have set your"); ++ logger.log(org.apache.logging.log4j.Level.WARN, "name to \"MissingName\" and your session to nothing. Please"); ++ logger.log(org.apache.logging.log4j.Level.WARN, "check your installation and post a console log from the launcher"); ++ logger.log(org.apache.logging.log4j.Level.WARN, "when asking for help!"); ++ logger.log(org.apache.logging.log4j.Level.WARN, "========================================================="); ++ } ++ + this.username = usernameIn; + this.playerID = playerIDIn; + this.token = tokenIn; +@@ -43,12 +58,25 @@ + public GameProfile getProfile() { + try { + UUID uuid = UUIDTypeAdapter.fromString(this.getPlayerID()); +- return new GameProfile(uuid, this.getUsername()); ++ GameProfile ret = new GameProfile(uuid, this.getUsername()); //Forge: Adds cached GameProfile properties to returned GameProfile. ++ if (properties != null) ret.getProperties().putAll(properties); // Helps to cut down on calls to the session service, ++ return ret; // which helps to fix MC-52974. + } catch (IllegalArgumentException illegalargumentexception) { +- return new GameProfile(null, this.getUsername()); ++ return new GameProfile(net.minecraft.entity.player.EntityPlayer.getUUID(new GameProfile((UUID)null, this.getUsername())), this.getUsername()); + } + } + ++ /* ======================================== FORGE START ===================================== */ ++ //For internal use only. Modders should never need to use this. ++ public void setProperties(com.mojang.authlib.properties.PropertyMap properties) { ++ if(this.properties == null) this.properties = properties; ++ } ++ ++ public boolean hasCachedProperties() { ++ return properties != null; ++ } ++ /* ========================================= FORGE END ====================================== */ ++ + @SideOnly(Side.CLIENT) + public enum Type { + LEGACY("legacy"), diff --git a/module/minecraft/patches/net/minecraft/util/SoundEvent.java.patch b/module/minecraft/patches/net/minecraft/util/SoundEvent.java.patch new file mode 100644 index 000000000..2b306da0d --- /dev/null +++ b/module/minecraft/patches/net/minecraft/util/SoundEvent.java.patch @@ -0,0 +1,13 @@ +--- original/net/minecraft/util/SoundEvent.java ++++ modified/net/minecraft/util/SoundEvent.java +@@ -4,8 +4,8 @@ + import net.minecraftforge.fml.relauncher.Side; + import net.minecraftforge.fml.relauncher.SideOnly; + +-public class SoundEvent { +- public static final RegistryNamespaced REGISTRY = new RegistryNamespaced<>(); ++public class SoundEvent extends net.minecraftforge.registries.IForgeRegistryEntry.Impl { ++ public static final RegistryNamespaced REGISTRY = net.minecraftforge.registries.GameData.getWrapper(SoundEvent.class); + private final ResourceLocation soundName; + private static int soundEventId; + diff --git a/module/minecraft/patches/net/minecraft/util/TabCompleter.java.patch b/module/minecraft/patches/net/minecraft/util/TabCompleter.java.patch new file mode 100644 index 000000000..f08e2e320 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/util/TabCompleter.java.patch @@ -0,0 +1,37 @@ +--- original/net/minecraft/util/TabCompleter.java ++++ modified/net/minecraft/util/TabCompleter.java +@@ -48,11 +48,12 @@ + this.textField.deleteFromCursor(i - this.textField.getCursorPosition()); + } + +- this.textField.writeText(this.completions.get(this.completionIdx++)); ++ this.textField.writeText(net.minecraft.util.text.TextFormatting.getTextWithoutFormattingCodes(this.completions.get(this.completionIdx++))); + } + + private void requestCompletions(String prefix) { + if (prefix.length() >= 1) { ++ net.minecraftforge.client.ClientCommandHandler.instance.autoComplete(prefix); + Minecraft.getMinecraft().player.connection.sendPacket(new CPacketTabComplete(prefix, this.getTargetBlockPos(), this.hasTargetBlock)); + this.requestedCompletions = true; + } +@@ -67,6 +68,11 @@ + this.didComplete = false; + this.completions.clear(); + ++ String[] complete = net.minecraftforge.client.ClientCommandHandler.instance.latestAutoComplete; ++ if (complete != null) { ++ newCompl = com.google.common.collect.ObjectArrays.concat(complete, newCompl, String.class); ++ } ++ + for (String s : newCompl) { + if (!s.isEmpty()) { + this.completions.add(s); +@@ -75,6 +81,8 @@ + + String s1 = this.textField.getText().substring(this.textField.getNthWordFromPosWS(-1, this.textField.getCursorPosition(), false)); + String s2 = org.apache.commons.lang3.StringUtils.getCommonPrefix(newCompl); ++ s2 = net.minecraft.util.text.TextFormatting.getTextWithoutFormattingCodes(s2); ++ + if (!s2.isEmpty() && !s1.equalsIgnoreCase(s2)) { + this.textField.deleteFromCursor(0); + this.textField diff --git a/module/minecraft/patches/net/minecraft/util/datafix/DataFixesManager.java.patch b/module/minecraft/patches/net/minecraft/util/datafix/DataFixesManager.java.patch new file mode 100644 index 000000000..d1ed49b72 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/util/datafix/DataFixesManager.java.patch @@ -0,0 +1,10 @@ +--- original/net/minecraft/util/datafix/DataFixesManager.java ++++ modified/net/minecraft/util/datafix/DataFixesManager.java +@@ -162,6 +162,7 @@ + + public static DataFixer createFixer() { + DataFixer datafixer = new DataFixer(1343); ++ datafixer = new net.minecraftforge.common.util.CompoundDataFixer(datafixer); + WorldInfo.registerFixes(datafixer); + EntityPlayerMP.registerFixesPlayerMP(datafixer); + EntityPlayer.registerFixesPlayer(datafixer); diff --git a/module/minecraft/patches/net/minecraft/util/math/ChunkPos.java.patch b/module/minecraft/patches/net/minecraft/util/math/ChunkPos.java.patch new file mode 100644 index 000000000..31c5f895e --- /dev/null +++ b/module/minecraft/patches/net/minecraft/util/math/ChunkPos.java.patch @@ -0,0 +1,17 @@ +--- original/net/minecraft/util/math/ChunkPos.java ++++ modified/net/minecraft/util/math/ChunkPos.java +@@ -23,6 +23,14 @@ + return x & 4294967295L | (z & 4294967295L) << 32; + } + ++ public static int getX(long key) { ++ return (int) (key & 0xFFFFFFFFL); ++ } ++ ++ public static int getZ(long key) { ++ return (int) ((key >>> 32) & 0xFFFFFFFFL); ++ } ++ + @Override + public int hashCode() { + int i = 1664525 * this.x + 1013904223; diff --git a/module/minecraft/patches/net/minecraft/util/math/RayTraceResult.java.patch b/module/minecraft/patches/net/minecraft/util/math/RayTraceResult.java.patch new file mode 100644 index 000000000..747bdf23d --- /dev/null +++ b/module/minecraft/patches/net/minecraft/util/math/RayTraceResult.java.patch @@ -0,0 +1,15 @@ +--- original/net/minecraft/util/math/RayTraceResult.java ++++ modified/net/minecraft/util/math/RayTraceResult.java +@@ -4,6 +4,12 @@ + import net.minecraft.util.EnumFacing; + + public class RayTraceResult { ++ /** Used to determine what sub-segment is hit */ ++ public int subHit = -1; ++ ++ /** Used to add extra hit info */ ++ public Object hitInfo = null; ++ + private BlockPos blockPos; + /** The type of hit that occured, see {@link RayTraceResult#Type} for possibilities. */ + public RayTraceResult.Type typeOfHit; diff --git a/module/minecraft/patches/net/minecraft/util/math/Vec2f.java.patch b/module/minecraft/patches/net/minecraft/util/math/Vec2f.java.patch new file mode 100644 index 000000000..805dd8d97 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/util/math/Vec2f.java.patch @@ -0,0 +1,12 @@ +--- original/net/minecraft/util/math/Vec2f.java ++++ modified/net/minecraft/util/math/Vec2f.java +@@ -1,9 +1,5 @@ + package net.minecraft.util.math; + +-import net.minecraftforge.fml.relauncher.Side; +-import net.minecraftforge.fml.relauncher.SideOnly; +- +-@SideOnly(Side.CLIENT) + public class Vec2f { + /** An immutable vector with {@code 0.0F} as the x and y components. */ + public static final Vec2f ZERO = new Vec2f(0.0F, 0.0F); diff --git a/module/minecraft/patches/net/minecraft/util/math/Vec3d.java.patch b/module/minecraft/patches/net/minecraft/util/math/Vec3d.java.patch new file mode 100644 index 000000000..2288ffa1c --- /dev/null +++ b/module/minecraft/patches/net/minecraft/util/math/Vec3d.java.patch @@ -0,0 +1,44 @@ +--- original/net/minecraft/util/math/Vec3d.java ++++ modified/net/minecraft/util/math/Vec3d.java +@@ -1,9 +1,6 @@ + package net.minecraft.util.math; + + import javax.annotation.Nullable; +-import net.minecraftforge.fml.relauncher.Side; +-import net.minecraftforge.fml.relauncher.SideOnly; +- + public class Vec3d { + public static final Vec3d ZERO = new Vec3d(0.0, 0.0, 0.0); + /** X coordinate of Vec3D */ +@@ -54,8 +51,6 @@ + return this.x * vec.x + this.y * vec.y + this.z * vec.z; + } + +- /** Returns a new vector with the result of this vector x the specified vector. */ +- @SideOnly(Side.CLIENT) + public Vec3d crossProduct(Vec3d vec) { + return new Vec3d( + this.y * vec.z - this.z * vec.y, +@@ -115,7 +110,6 @@ + ); + } + +- @SideOnly(Side.CLIENT) + public double lengthSquared() { + return this.x * this.x + this.y * this.y + this.z * this.z; + } +@@ -211,14 +205,10 @@ + return new Vec3d(d0, d1, d2); + } + +- /** returns a Vec3d from given pitch and yaw degrees as Vec2f */ +- @SideOnly(Side.CLIENT) + public static Vec3d fromPitchYaw(Vec2f p_189984_0_) { + return fromPitchYaw(p_189984_0_.x, p_189984_0_.y); + } + +- /** returns a Vec3d from given pitch and yaw degrees */ +- @SideOnly(Side.CLIENT) + public static Vec3d fromPitchYaw(float p_189986_0_, float p_189986_1_) { + float f = MathHelper.cos(-p_189986_1_ * (float) (Math.PI / 180.0) - (float) Math.PI); + float f1 = MathHelper.sin(-p_189986_1_ * (float) (Math.PI / 180.0) - (float) Math.PI); diff --git a/module/minecraft/patches/net/minecraft/util/text/ITextComponent.java.patch b/module/minecraft/patches/net/minecraft/util/text/ITextComponent.java.patch new file mode 100644 index 000000000..126ccf39e --- /dev/null +++ b/module/minecraft/patches/net/minecraft/util/text/ITextComponent.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/util/text/ITextComponent.java ++++ modified/net/minecraft/util/text/ITextComponent.java +@@ -53,8 +53,6 @@ + /** Gets the text of this component and all sibling components, without any formatting codes. */ + String getUnformattedText(); + +- /** Gets the text of this component and all sibling components, with formatting codes added for rendering. */ +- @SideOnly(Side.CLIENT) + String getFormattedText(); + + /** Gets the sibling components of this one. */ diff --git a/module/minecraft/patches/net/minecraft/util/text/Style.java.patch b/module/minecraft/patches/net/minecraft/util/text/Style.java.patch new file mode 100644 index 000000000..ebf969de5 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/util/text/Style.java.patch @@ -0,0 +1,29 @@ +--- original/net/minecraft/util/text/Style.java ++++ modified/net/minecraft/util/text/Style.java +@@ -157,13 +157,6 @@ + public Style createDeepCopy() { + return this; + } +- +- /** +- * Gets the equivilent text formatting code(s) for this style, including all needed section sign characters. +- * +- * @return A formatted string that can be combined with text to produce this style. +- */ +- @SideOnly(Side.CLIENT) + @Override + public String getFormattingCode() { + return ""; +@@ -292,12 +285,6 @@ + return this; + } + +- /** +- * Gets the equivilent text formatting code(s) for this style, including all needed section sign characters. +- * +- * @return A formatted string that can be combined with text to produce this style. +- */ +- @SideOnly(Side.CLIENT) + public String getFormattingCode() { + if (this.isEmpty()) { + return this.parentStyle != null ? this.parentStyle.getFormattingCode() : ""; diff --git a/module/minecraft/patches/net/minecraft/util/text/TextComponentBase.java.patch b/module/minecraft/patches/net/minecraft/util/text/TextComponentBase.java.patch new file mode 100644 index 000000000..f05069a32 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/util/text/TextComponentBase.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/util/text/TextComponentBase.java ++++ modified/net/minecraft/util/text/TextComponentBase.java +@@ -91,8 +91,6 @@ + return stringbuilder.toString(); + } + +- /** Gets the text of this component and all sibling components, with formatting codes added for rendering. */ +- @SideOnly(Side.CLIENT) + @Override + public final String getFormattedText() { + StringBuilder stringbuilder = new StringBuilder(); diff --git a/module/minecraft/patches/net/minecraft/util/text/translation/LanguageMap.java.patch b/module/minecraft/patches/net/minecraft/util/text/translation/LanguageMap.java.patch new file mode 100644 index 000000000..e91e779a8 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/util/text/translation/LanguageMap.java.patch @@ -0,0 +1,51 @@ +--- original/net/minecraft/util/text/translation/LanguageMap.java ++++ modified/net/minecraft/util/text/translation/LanguageMap.java +@@ -25,23 +25,44 @@ + private long lastUpdateTimeInMilliseconds; + + public LanguageMap() { +- try { + InputStream inputstream = LanguageMap.class.getResourceAsStream("/assets/minecraft/lang/en_us.lang"); ++ try { ++ inject(this, inputstream); ++ } finally { ++ IOUtils.closeQuietly(inputstream); // Forge: close stream after use (MC-153470) ++ } ++ } + ++ public static void inject(InputStream inputstream) { ++ inject(instance, inputstream); ++ } ++ ++ private static void inject(LanguageMap inst, InputStream inputstream) { ++ Map map = parseLangFile(inputstream); ++ inst.languageList.putAll(map); ++ inst.lastUpdateTimeInMilliseconds = System.currentTimeMillis(); ++ } ++ ++ public static Map parseLangFile(InputStream inputstream) { ++ Map table = Maps.newHashMap(); ++ try { ++ inputstream = net.minecraftforge.fml.common.FMLCommonHandler.instance().loadLanguage(table, inputstream); ++ if (inputstream == null) return table; ++ + for (String s : IOUtils.readLines(inputstream, StandardCharsets.UTF_8)) { + if (!s.isEmpty() && s.charAt(0) != '#') { + String[] astring = Iterables.toArray(EQUAL_SIGN_SPLITTER.split(s), String.class); + if (astring != null && astring.length == 2) { + String s1 = astring[0]; + String s2 = NUMERIC_VARIABLE_PATTERN.matcher(astring[1]).replaceAll("%$1s"); +- this.languageList.put(s1, s2); ++ table.put(s1, s2); + } + } + } + +- this.lastUpdateTimeInMilliseconds = System.currentTimeMillis(); + } catch (IOException ioexception) { +- } ++ } catch (Exception ex) {} ++ return table; + } + + /** Return the StringTranslate singleton instance */ diff --git a/module/minecraft/patches/net/minecraft/village/Village.java.patch b/module/minecraft/patches/net/minecraft/village/Village.java.patch new file mode 100644 index 000000000..d45a02004 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/village/Village.java.patch @@ -0,0 +1,187 @@ +--- original/net/minecraft/village/Village.java ++++ modified/net/minecraft/village/Village.java +@@ -26,7 +26,7 @@ + import net.minecraft.util.math.Vec3d; + import net.minecraft.world.World; + +-public class Village { ++public class Village implements net.minecraftforge.common.capabilities.ICapabilitySerializable { + private World world; + /** list of VillageDoorInfo objects */ + private final List villageDoorInfoList = Lists.newArrayList(); +@@ -40,16 +40,17 @@ + private int numVillagers; + /** Timestamp of tick count when villager last bred */ + private int noBreedTicks; +- /** List of player reputations with this village */ +- private final Map playerReputation = Maps.newHashMap(); ++ private final Map playerReputation = Maps.newHashMap(); + private final List villageAgressors = Lists.newArrayList(); + private int numIronGolems; + + public Village() { ++ this.capabilities = net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(this); + } + + public Village(World worldIn) { + this.world = worldIn; ++ this.capabilities = net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(this); + } + + public void setWorld(World worldIn) { +@@ -302,9 +303,10 @@ + double d0 = Double.MAX_VALUE; + EntityPlayer entityplayer = null; + +- for (String s : this.playerReputation.keySet()) { ++ for (UUID s : this.playerReputation.keySet()) { + if (this.isPlayerReputationTooLow(s)) { +- EntityPlayer entityplayer1 = this.world.getPlayerEntityByName(s); ++ EntityPlayer entityplayer1 = this.world.getPlayerEntityByUUID(s); ++ + if (entityplayer1 != null) { + double d1 = entityplayer1.getDistanceSq(villageDefender); + if (!(d1 > d0)) { +@@ -340,6 +342,7 @@ + villagedoorinfo.resetDoorOpeningRestrictionCounter(); + } + ++ if (world.isBlockLoaded(villagedoorinfo.getDoorBlockPos())) // Forge: check that the door block is loaded to avoid loading chunks + if (!this.isWoodDoor(villagedoorinfo.getDoorBlockPos()) || Math.abs(this.tickCounter - villagedoorinfo.getLastActivityTimestamp()) > 1200) { + this.centerHelper = this.centerHelper.subtract(villagedoorinfo.getDoorBlockPos()); + flag = true; +@@ -378,25 +381,44 @@ + } + } + +- /** Return the village reputation for a player */ ++ @Deprecated //Hasn't worked since 1.9, use UUID version below. + public int getPlayerReputation(String playerName) { ++ return this.getPlayerReputation(findUUID(playerName)); ++ } ++ ++ public int getPlayerReputation(UUID playerName) { + Integer integer = this.playerReputation.get(playerName); + return integer == null ? 0 : integer; + } + +- /** Modify a players reputation in the village. Use positive values to increase reputation and negative values to decrease.
Note that a players reputation is clamped between -30 and 10 */ ++ private UUID findUUID(String name) { ++ if (this.world == null || this.world.getMinecraftServer() == null) ++ return EntityPlayer.getOfflineUUID(name); ++ GameProfile profile = this.world.getMinecraftServer().getPlayerProfileCache().getGameProfileForUsername(name); ++ return profile == null ? EntityPlayer.getOfflineUUID(name) : profile.getId(); ++ } ++ ++ @Deprecated //Hasn't worked since 1.9, use UUID version below. + public int modifyPlayerReputation(String playerName, int reputation) { ++ return this.modifyPlayerReputation(findUUID(playerName), reputation); ++ } ++ ++ public int modifyPlayerReputation(UUID playerName, int reputation) { + int i = this.getPlayerReputation(playerName); + int j = MathHelper.clamp(i + reputation, -30, 10); + this.playerReputation.put(playerName, j); + return j; + } + +- /** Return whether this player has a too low reputation with this village. */ ++ @Deprecated //Hasn't worked since 1.9, use UUID version below. + public boolean isPlayerReputationTooLow(String playerName) { +- return this.getPlayerReputation(playerName) <= -15; ++ return this.isPlayerReputationTooLow(findUUID(playerName)); + } + ++ public boolean isPlayerReputationTooLow(UUID uuid) { ++ return this.getPlayerReputation(uuid) <= -15; ++ } ++ + /** Read this village's data from NBT. */ + public void readVillageDataFromNBT(NBTTagCompound compound) { + this.numVillagers = compound.getInteger("PopSize"); +@@ -424,16 +446,15 @@ + + for (int j = 0; j < nbttaglist1.tagCount(); j++) { + NBTTagCompound nbttagcompound1 = nbttaglist1.getCompoundTagAt(j); +- if (nbttagcompound1.hasKey("UUID") && this.world != null && this.world.getMinecraftServer() != null) { +- PlayerProfileCache playerprofilecache = this.world.getMinecraftServer().getPlayerProfileCache(); +- GameProfile gameprofile = playerprofilecache.getProfileByUUID(UUID.fromString(nbttagcompound1.getString("UUID"))); +- if (gameprofile != null) { +- this.playerReputation.put(gameprofile.getName(), nbttagcompound1.getInteger("S")); +- } ++ ++ if (nbttagcompound1.hasKey("UUID")) { ++ this.playerReputation.put(UUID.fromString(nbttagcompound1.getString("UUID")), nbttagcompound1.getInteger("S")); + } else { +- this.playerReputation.put(nbttagcompound1.getString("Name"), nbttagcompound1.getInteger("S")); ++ //World is never set here, so this will always be offline UUIDs, sadly there is no way to convert this. ++ this.playerReputation.put(findUUID(nbttagcompound1.getString("Name")), nbttagcompound1.getInteger("S")); + } + } ++ if (this.capabilities != null && compound.hasKey("ForgeCaps")) this.capabilities.deserializeNBT(compound.getCompoundTag("ForgeCaps")); + } + + /** Write this village's data to NBT. */ +@@ -466,14 +487,12 @@ + compound.setTag("Doors", nbttaglist); + NBTTagList nbttaglist1 = new NBTTagList(); + +- for (String s : this.playerReputation.keySet()) { ++ for (UUID s : this.playerReputation.keySet()) { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); +- PlayerProfileCache playerprofilecache = this.world.getMinecraftServer().getPlayerProfileCache(); + + try { +- GameProfile gameprofile = playerprofilecache.getGameProfileForUsername(s); +- if (gameprofile != null) { +- nbttagcompound1.setString("UUID", gameprofile.getId().toString()); ++ { ++ nbttagcompound1.setString("UUID", s.toString()); + nbttagcompound1.setInteger("S", this.playerReputation.get(s)); + nbttaglist1.appendTag(nbttagcompound1); + } +@@ -482,6 +501,7 @@ + } + + compound.setTag("Players", nbttaglist1); ++ if (this.capabilities != null) compound.setTag("ForgeCaps", this.capabilities.serializeNBT()); + } + + /** Prevent villager breeding for a fixed interval of time */ +@@ -495,7 +515,7 @@ + } + + public void setDefaultPlayerReputation(int defaultReputation) { +- for (String s : this.playerReputation.keySet()) { ++ for (UUID s : this.playerReputation.keySet()) { + this.modifyPlayerReputation(s, defaultReputation); + } + } +@@ -509,4 +529,27 @@ + this.agressionTime = agressionTimeIn; + } + } ++ ++ /* ======================================== FORGE START =====================================*/ ++ private net.minecraftforge.common.capabilities.CapabilityDispatcher capabilities; ++ public boolean hasCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable net.minecraft.util.EnumFacing facing) { ++ return capabilities == null ? false : capabilities.hasCapability(capability, facing); ++ } ++ ++ @Nullable ++ public T getCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable net.minecraft.util.EnumFacing facing) { ++ return capabilities == null ? null : capabilities.getCapability(capability, facing); ++ } ++ ++ public void deserializeNBT(NBTTagCompound nbt) { ++ this.readVillageDataFromNBT(nbt);; ++ } ++ ++ public NBTTagCompound serializeNBT() { ++ NBTTagCompound ret = new NBTTagCompound(); ++ this.writeVillageDataToNBT(ret); ++ return ret; ++ } ++ ++ /* ========================================= FORGE END ======================================*/ + } diff --git a/module/minecraft/patches/net/minecraft/village/VillageCollection.java.patch b/module/minecraft/patches/net/minecraft/village/VillageCollection.java.patch new file mode 100644 index 000000000..a5762376b --- /dev/null +++ b/module/minecraft/patches/net/minecraft/village/VillageCollection.java.patch @@ -0,0 +1,10 @@ +--- original/net/minecraft/village/VillageCollection.java ++++ modified/net/minecraft/village/VillageCollection.java +@@ -124,6 +124,7 @@ + } + + private void addDoorsAround(BlockPos central) { ++ if (!this.world.isAreaLoaded(central, 16)) return; // Forge: prevent loading unloaded chunks when checking for doors + int i = 16; + int j = 4; + int k = 16; diff --git a/module/minecraft/patches/net/minecraft/village/VillageSiege.java.patch b/module/minecraft/patches/net/minecraft/village/VillageSiege.java.patch new file mode 100644 index 000000000..8c03cb4ae --- /dev/null +++ b/module/minecraft/patches/net/minecraft/village/VillageSiege.java.patch @@ -0,0 +1,10 @@ +--- original/net/minecraft/village/VillageSiege.java ++++ modified/net/minecraft/village/VillageSiege.java +@@ -106,6 +106,7 @@ + + Vec3d vec3d = this.findRandomSpawnPos(new BlockPos(this.spawnX, this.spawnY, this.spawnZ)); + if (vec3d != null) { ++ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.village.VillageSiegeEvent(this, world, entityplayer, village, vec3d))) return false; + this.nextSpawnTime = 0; + this.siegeCount = 20; + return true; diff --git a/module/minecraft/patches/net/minecraft/world/BossInfo.java.patch b/module/minecraft/patches/net/minecraft/world/BossInfo.java.patch new file mode 100644 index 000000000..9dd9f52f6 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/BossInfo.java.patch @@ -0,0 +1,27 @@ +--- original/net/minecraft/world/BossInfo.java ++++ modified/net/minecraft/world/BossInfo.java +@@ -2,8 +2,6 @@ + + import java.util.UUID; + import net.minecraft.util.text.ITextComponent; +-import net.minecraftforge.fml.relauncher.Side; +-import net.minecraftforge.fml.relauncher.SideOnly; + + public abstract class BossInfo { + private final UUID uniqueId; +@@ -47,7 +45,6 @@ + return this.color; + } + +- @SideOnly(Side.CLIENT) + public void setColor(BossInfo.Color colorIn) { + this.color = colorIn; + } +@@ -56,7 +53,6 @@ + return this.overlay; + } + +- @SideOnly(Side.CLIENT) + public void setOverlay(BossInfo.Overlay overlayIn) { + this.overlay = overlayIn; + } diff --git a/module/minecraft/patches/net/minecraft/world/BossInfoServer.java.patch b/module/minecraft/patches/net/minecraft/world/BossInfoServer.java.patch new file mode 100644 index 000000000..af5ac3bfc --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/BossInfoServer.java.patch @@ -0,0 +1,27 @@ +--- original/net/minecraft/world/BossInfoServer.java ++++ modified/net/minecraft/world/BossInfoServer.java +@@ -9,8 +9,6 @@ + import net.minecraft.network.play.server.SPacketUpdateBossInfo; + import net.minecraft.util.math.MathHelper; + import net.minecraft.util.text.ITextComponent; +-import net.minecraftforge.fml.relauncher.Side; +-import net.minecraftforge.fml.relauncher.SideOnly; + + public class BossInfoServer extends BossInfo { + private final Set players = Sets.newHashSet(); +@@ -29,7 +27,6 @@ + } + } + +- @SideOnly(Side.CLIENT) + @Override + public void setColor(BossInfo.Color colorIn) { + if (colorIn != this.color) { +@@ -38,7 +35,6 @@ + } + } + +- @SideOnly(Side.CLIENT) + @Override + public void setOverlay(BossInfo.Overlay overlayIn) { + if (overlayIn != this.overlay) { diff --git a/module/minecraft/patches/net/minecraft/world/ChunkCache.java.patch b/module/minecraft/patches/net/minecraft/world/ChunkCache.java.patch new file mode 100644 index 000000000..e26191d63 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/ChunkCache.java.patch @@ -0,0 +1,72 @@ +--- original/net/minecraft/world/ChunkCache.java ++++ modified/net/minecraft/world/ChunkCache.java +@@ -55,13 +55,14 @@ + @Nullable + @Override + public TileEntity getTileEntity(BlockPos pos) { +- return this.getTileEntity(pos, Chunk.EnumCreateEntityType.IMMEDIATE); ++ return this.getTileEntity(pos, Chunk.EnumCreateEntityType.CHECK); // Forge: don't modify world from other threads + } + + @Nullable + public TileEntity getTileEntity(BlockPos pos, Chunk.EnumCreateEntityType createType) { + int i = (pos.getX() >> 4) - this.chunkX; + int j = (pos.getZ() >> 4) - this.chunkZ; ++ if (!withinBounds(i, j)) return null; + return this.chunkArray[i][j].getTileEntity(pos, createType); + } + +@@ -98,6 +99,7 @@ + public Biome getBiome(BlockPos pos) { + int i = (pos.getX() >> 4) - this.chunkX; + int j = (pos.getZ() >> 4) - this.chunkZ; ++ if (!withinBounds(i, j)) return net.minecraft.init.Biomes.PLAINS; + return this.chunkArray[i][j].getBiome(pos, this.world.getBiomeProvider()); + } + +@@ -126,6 +128,7 @@ + } else { + int i = (pos.getX() >> 4) - this.chunkX; + int j = (pos.getZ() >> 4) - this.chunkZ; ++ if (!withinBounds(i, j)) return type.defaultLightValue; + return this.chunkArray[i][j].getLightFor(type, pos); + } + } else { +@@ -136,7 +139,8 @@ + /** Checks to see if an air block exists at the provided location. Note that this only checks to see if the blocks material is set to air, meaning it is possible for non-vanilla blocks to still pass this check. */ + @Override + public boolean isAirBlock(BlockPos pos) { +- return this.getBlockState(pos).getMaterial() == Material.AIR; ++ IBlockState state = this.getBlockState(pos); ++ return state.getBlock().isAir(state, this, pos); + } + + @SideOnly(Side.CLIENT) +@@ -144,6 +148,7 @@ + if (pos.getY() >= 0 && pos.getY() < 256) { + int i = (pos.getX() >> 4) - this.chunkX; + int j = (pos.getZ() >> 4) - this.chunkZ; ++ if (!withinBounds(i, j)) return type.defaultLightValue; + return this.chunkArray[i][j].getLightFor(type, pos); + } else { + return type.defaultLightValue; +@@ -160,4 +165,19 @@ + public WorldType getWorldType() { + return this.world.getWorldType(); + } ++ ++ @Override ++ public boolean isSideSolid(BlockPos pos, EnumFacing side, boolean _default) { ++ int x = (pos.getX() >> 4) - this.chunkX; ++ int z = (pos.getZ() >> 4) - this.chunkZ; ++ if (pos.getY() < 0 || pos.getY() >= 256) return _default; ++ if (!withinBounds(x, z)) return _default; ++ ++ IBlockState state = getBlockState(pos); ++ return state.getBlock().isSideSolid(state, this, pos, side); ++ } ++ ++ private boolean withinBounds(int x, int z) { ++ return x >= 0 && x < chunkArray.length && z >= 0 && z < chunkArray[x].length && chunkArray[x][z] != null; ++ } + } diff --git a/module/minecraft/patches/net/minecraft/world/DimensionType.java.patch b/module/minecraft/patches/net/minecraft/world/DimensionType.java.patch new file mode 100644 index 000000000..489c00cf2 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/DimensionType.java.patch @@ -0,0 +1,37 @@ +--- original/net/minecraft/world/DimensionType.java ++++ modified/net/minecraft/world/DimensionType.java +@@ -12,12 +12,14 @@ + private final String name; + private final String suffix; + private final Class clazz; ++ private boolean shouldLoadSpawn = false; + + DimensionType(int idIn, String nameIn, String suffixIn, Class clazzIn) { + this.id = idIn; + this.name = nameIn; + this.suffix = suffixIn; + this.clazz = clazzIn; ++ this.shouldLoadSpawn = idIn == 0; + } + + public int getId() { +@@ -57,6 +59,19 @@ + throw new IllegalArgumentException("Invalid dimension id " + id); + } + ++ public boolean shouldLoadSpawn(){ return this.shouldLoadSpawn; } ++ public DimensionType setLoadSpawn(boolean value) { this.shouldLoadSpawn = value; return this; } ++ ++ private static Class[] ENUM_ARGS = {int.class, String.class, String.class, Class.class}; ++ static { net.minecraftforge.common.util.EnumHelper.testEnum(DimensionType.class, ENUM_ARGS); } ++ public static DimensionType register(String name, String suffix, int id, Class provider, boolean keepLoaded) { ++ String enum_name = name.replace(" ", "_").toLowerCase(); ++ DimensionType ret = net.minecraftforge.common.util.EnumHelper.addEnum(DimensionType.class, enum_name, ENUM_ARGS, ++ id, name, suffix, provider); ++ return ret.setLoadSpawn(keepLoaded); ++ } ++ //TODO: Unregister? There is no way to really delete a enum value... ++ + public static DimensionType byName(String nameIn) { + for (DimensionType dimensiontype : values()) { + if (dimensiontype.getName().equals(nameIn)) { diff --git a/module/minecraft/patches/net/minecraft/world/Explosion.java.patch b/module/minecraft/patches/net/minecraft/world/Explosion.java.patch new file mode 100644 index 000000000..78638cb9c --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/Explosion.java.patch @@ -0,0 +1,54 @@ +--- original/net/minecraft/world/Explosion.java ++++ modified/net/minecraft/world/Explosion.java +@@ -44,6 +44,7 @@ + private final List affectedBlockPositions = Lists.newArrayList(); + /** Maps players to the knockback vector applied by the explosion, to send to the client */ + private final Map playerKnockbackMap = Maps.newHashMap(); ++ private final Vec3d position; + + @SideOnly(Side.CLIENT) + public Explosion( +@@ -86,6 +87,7 @@ + this.z = z; + this.causesFire = causesFire; + this.damagesTerrain = damagesTerrain; ++ position = new Vec3d(this.x, this.y, this.z); + } + + /** Does the first part of the explosion (destroy blocks) */ +@@ -115,8 +117,8 @@ + IBlockState iblockstate = this.world.getBlockState(blockpos); + if (iblockstate.getMaterial() != Material.AIR) { + float f2 = this.exploder != null +- ? this.exploder.getExplosionResistance(this, this.world, blockpos, iblockstate) +- : iblockstate.getBlock().getExplosionResistance(null); ++ ? this.exploder.getExplosionResistance(this, this.world, blockpos, iblockstate) ++ : iblockstate.getBlock().getExplosionResistance(world, blockpos, null, this); + f -= (f2 + 0.3F) * 0.3F; + } + +@@ -144,6 +146,7 @@ + int j2 = MathHelper.floor(this.z - f3 - 1.0); + int j1 = MathHelper.floor(this.z + f3 + 1.0); + List list = this.world.getEntitiesWithinAABBExcludingEntity(this.exploder, new AxisAlignedBB(k1, i2, j2, l1, i1, j1)); ++ net.minecraftforge.event.ForgeEventFactory.onExplosionDetonate(this.world, this, list, f3); + Vec3d vec3d = new Vec3d(this.x, this.y, this.z); + + for (int k2 = 0; k2 < list.size(); k2++) { +@@ -239,8 +242,7 @@ + block.dropBlockAsItemWithChance(this.world, blockpos, this.world.getBlockState(blockpos), 1.0F / this.size, 0); + } + +- this.world.setBlockState(blockpos, Blocks.AIR.getDefaultState(), 3); +- block.onExplosionDestroy(this.world, blockpos, this); ++ block.onBlockExploded(this.world, blockpos, this); + } + } + } +@@ -279,4 +281,6 @@ + public List getAffectedBlockPositions() { + return this.affectedBlockPositions; + } ++ ++ public Vec3d getPosition(){ return this.position; } + } diff --git a/module/minecraft/patches/net/minecraft/world/IBlockAccess.java.patch b/module/minecraft/patches/net/minecraft/world/IBlockAccess.java.patch new file mode 100644 index 000000000..9d9a7b62b --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/IBlockAccess.java.patch @@ -0,0 +1,17 @@ +--- original/net/minecraft/world/IBlockAccess.java ++++ modified/net/minecraft/world/IBlockAccess.java +@@ -28,4 +28,14 @@ + + @SideOnly(Side.CLIENT) + WorldType getWorldType(); ++ ++ /** ++ * FORGE: isSideSolid, pulled up from {@link World} ++ * ++ * @param pos Position ++ * @param side Side ++ * @param _default default return value ++ * @return if the block is solid on the side ++ */ ++ boolean isSideSolid(BlockPos pos, EnumFacing side, boolean _default); + } diff --git a/module/minecraft/patches/net/minecraft/world/ServerWorldEventHandler.java.patch b/module/minecraft/patches/net/minecraft/world/ServerWorldEventHandler.java.patch new file mode 100644 index 000000000..368e1f2a8 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/ServerWorldEventHandler.java.patch @@ -0,0 +1,56 @@ +--- original/net/minecraft/world/ServerWorldEventHandler.java ++++ modified/net/minecraft/world/ServerWorldEventHandler.java +@@ -84,16 +84,16 @@ + float pitch + ) { + this.server +- .getPlayerList() +- .sendToAllNearExcept( +- player, +- x, +- y, +- z, +- volume > 1.0F ? 16.0F * volume : 16.0, +- this.world.provider.getDimensionType().getId(), +- new SPacketSoundEffect(soundIn, category, x, y, z, volume, pitch) +- ); ++ .getPlayerList() ++ .sendToAllNearExcept( ++ player, ++ x, ++ y, ++ z, ++ volume > 1.0F ? 16.0F * volume : 16.0, ++ this.world.provider.getDimension(), ++ new SPacketSoundEffect(soundIn, category, x, y, z, volume, pitch) ++ ); + } + + /** On the client, re-renders all blocks in this range, inclusive. On the server, does nothing. */ +@@ -117,16 +117,16 @@ + @Override + public void playEvent(EntityPlayer player, int type, BlockPos blockPosIn, int data) { + this.server +- .getPlayerList() +- .sendToAllNearExcept( +- player, +- blockPosIn.getX(), +- blockPosIn.getY(), +- blockPosIn.getZ(), +- 64.0, +- this.world.provider.getDimensionType().getId(), +- new SPacketEffect(type, blockPosIn, data, false) +- ); ++ .getPlayerList() ++ .sendToAllNearExcept( ++ player, ++ blockPosIn.getX(), ++ blockPosIn.getY(), ++ blockPosIn.getZ(), ++ 64.0, ++ this.world.provider.getDimension(), ++ new SPacketEffect(type, blockPosIn, data, false) ++ ); + } + + @Override diff --git a/module/minecraft/patches/net/minecraft/world/Teleporter.java.patch b/module/minecraft/patches/net/minecraft/world/Teleporter.java.patch new file mode 100644 index 000000000..5856f5762 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/Teleporter.java.patch @@ -0,0 +1,24 @@ +--- original/net/minecraft/world/Teleporter.java ++++ modified/net/minecraft/world/Teleporter.java +@@ -15,7 +15,7 @@ + import net.minecraft.util.math.ChunkPos; + import net.minecraft.util.math.MathHelper; + +-public class Teleporter { ++public class Teleporter implements net.minecraftforge.common.util.ITeleporter { + protected final WorldServer world; + /** A private Random() function in Teleporter */ + protected final Random random; +@@ -365,4 +365,12 @@ + this.lastUpdateTime = lastUpdate; + } + } ++ ++ @Override ++ public void placeEntity(World world, Entity entity, float yaw) { ++ if (entity instanceof EntityPlayerMP) ++ placeInPortal(entity, yaw); ++ else ++ placeInExistingPortal(entity, yaw); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/world/World.java.patch b/module/minecraft/patches/net/minecraft/world/World.java.patch new file mode 100644 index 000000000..d056cc090 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/World.java.patch @@ -0,0 +1,1479 @@ +--- original/net/minecraft/world/World.java ++++ modified/net/minecraft/world/World.java +@@ -62,7 +62,14 @@ + import net.minecraftforge.fml.relauncher.Side; + import net.minecraftforge.fml.relauncher.SideOnly; + +-public abstract class World implements IBlockAccess { ++public abstract class World implements IBlockAccess, net.minecraftforge.common.capabilities.ICapabilityProvider { ++ /** ++ * Used in the getEntitiesWithinAABB functions to expand the search area for entities. ++ * Modders should change this variable to a higher value if it is less then the radius ++ * of one of there entities. ++ */ ++ public static double MAX_ENTITY_RADIUS = 2.0D; ++ + private int seaLevel = 63; + /** boolean; if true updates scheduled by scheduleBlockUpdate happen immediately */ + protected boolean scheduledUpdatesAreImmediate; +@@ -127,6 +134,12 @@ + /** is a temporary list of blocks and light values used when updating light levels. Holds up to 32x32x32 blocks (the maximum influence of a light source.) Every element is a packed bit value: 0000000000LLLLzzzzzzyyyyyyxxxxxx. The 4-bit L is a light level used when darkening blocks. 6-bit numbers x, y and z represent the block's offset from the original block, plus 32 (i.e. value of 31 would mean a -1 offset */ + int[] lightUpdateBlockList = new int[32768]; + ++ public boolean restoringBlockSnapshots = false; ++ public boolean captureBlockSnapshots = false; ++ public java.util.ArrayList capturedBlockSnapshots = new java.util.ArrayList(); ++ private net.minecraftforge.common.capabilities.CapabilityDispatcher capabilities; ++ private net.minecraftforge.common.util.WorldCapabilityData capabilityData; ++ + protected World(ISaveHandler saveHandlerIn, WorldInfo info, WorldProvider providerIn, Profiler profilerIn, boolean client) { + this.saveHandler = saveHandlerIn; + this.profiler = profilerIn; +@@ -134,6 +147,7 @@ + this.provider = providerIn; + this.isRemote = client; + this.worldBorder = providerIn.createWorldBorder(); ++ perWorldStorage = new MapStorage(null); + } + + public World init() { +@@ -142,6 +156,10 @@ + + @Override + public Biome getBiome(final BlockPos pos) { ++ return this.provider.getBiomeForCoords(pos); ++ } ++ ++ public Biome getBiomeForCoordsBody(final BlockPos pos) { + if (this.isBlockLoaded(pos)) { + Chunk chunk = this.getChunk(pos); + +@@ -210,7 +228,7 @@ + /** Checks to see if an air block exists at the provided location. Note that this only checks to see if the blocks material is set to air, meaning it is possible for non-vanilla blocks to still pass this check. */ + @Override + public boolean isAirBlock(BlockPos pos) { +- return this.getBlockState(pos).getMaterial() == Material.AIR; ++ return this.getBlockState(pos).getBlock().isAir(this.getBlockState(pos), this, pos); + } + + public boolean isBlockLoaded(BlockPos pos) { +@@ -344,6 +362,27 @@ + return true; + } + ++ // Split off from original setBlockState(BlockPos, IBlockState, int) method in order to directly send client and physic updates ++ public void markAndNotifyBlock(BlockPos pos, @Nullable Chunk chunk, IBlockState iblockstate, IBlockState newState, int flags) { ++ Block block = newState.getBlock(); { ++ { ++ if ((flags & 2) != 0 && (!this.isRemote || (flags & 4) == 0) && (chunk == null || chunk.isPopulated())) { ++ this.notifyBlockUpdate(pos, iblockstate, newState, flags); ++ } ++ ++ if (!this.isRemote && (flags & 1) != 0) { ++ this.notifyNeighborsRespectDebug(pos, iblockstate.getBlock(), true); ++ ++ if (newState.hasComparatorInputOverride()) { ++ this.updateComparatorOutputLevel(pos, block); ++ } ++ } else if (!this.isRemote && (flags & 16) == 0) { ++ this.updateObservingBlocksAt(pos, block); ++ } ++ } ++ } ++ } ++ + public boolean setBlockToAir(BlockPos pos) { + return this.setBlockState(pos, Blocks.AIR.getDefaultState(), 3); + } +@@ -352,7 +391,8 @@ + public boolean destroyBlock(BlockPos pos, boolean dropBlock) { + IBlockState iblockstate = this.getBlockState(pos); + Block block = iblockstate.getBlock(); +- if (iblockstate.getMaterial() == Material.AIR) { ++ ++ if (block.isAir(iblockstate, this, pos)) { + return false; + } + +@@ -431,6 +471,9 @@ + } + + public void notifyNeighborsOfStateChange(BlockPos pos, Block blockType, boolean updateObservers) { ++ if(net.minecraftforge.event.ForgeEventFactory.onNeighborNotify(this, pos, this.getBlockState(pos), java.util.EnumSet.allOf(EnumFacing.class), updateObservers).isCanceled()) ++ return; ++ + this.neighborChanged(pos.west(), blockType, pos); + this.neighborChanged(pos.east(), blockType, pos); + this.neighborChanged(pos.down(), blockType, pos); +@@ -443,6 +486,11 @@ + } + + public void notifyNeighborsOfStateExcept(BlockPos pos, Block blockType, EnumFacing skipSide) { ++ java.util.EnumSet directions = java.util.EnumSet.allOf(EnumFacing.class); ++ directions.remove(skipSide); ++ if(net.minecraftforge.event.ForgeEventFactory.onNeighborNotify(this, pos, this.getBlockState(pos), directions, false).isCanceled()) ++ return; ++ + if (skipSide != EnumFacing.WEST) { + this.neighborChanged(pos.west(), blockType, pos); + } +@@ -480,19 +528,16 @@ + crashreportcategory.addDetail( + "Source block type", + new ICrashReportDetail() { +- public String call() throws Exception { +- try { +- return String.format( +- "ID #%d (%s // %s)", +- Block.getIdFromBlock(blockIn), +- blockIn.getTranslationKey(), +- blockIn.getClass().getCanonicalName() +- ); +- } catch (Throwable throwable1) { +- return "ID #" + Block.getIdFromBlock(blockIn); +- } ++ public String call() throws Exception { ++ try { ++ return String.format( ++ "ID #%d (%s // %s // %s)", Block.getIdFromBlock(blockIn), blockIn.getTranslationKey(), blockIn.getClass().getName(), blockIn.getRegistryName() ++ ); ++ } catch (Throwable throwable1) { ++ return "ID #" + Block.getIdFromBlock(blockIn); + } + } ++ } + ); + CrashReportCategory.addBlockInfo(crashreportcategory, pos, iblockstate); + throw new ReportedException(crashreport); +@@ -503,28 +548,26 @@ + public void observedNeighborChanged(BlockPos pos, final Block changedBlock, BlockPos changedBlockPos) { + if (!this.isRemote) { + IBlockState iblockstate = this.getBlockState(pos); +- if (iblockstate.getBlock() == Blocks.OBSERVER) { ++ ++ if (true) { + try { +- ((BlockObserver)iblockstate.getBlock()).observedNeighborChanged(iblockstate, this, pos, changedBlock, changedBlockPos); ++ iblockstate.getBlock().observedNeighborChange(iblockstate, this, pos, changedBlock, changedBlockPos); + } catch (Throwable throwable) { + CrashReport crashreport = CrashReport.makeCrashReport(throwable, "Exception while updating neighbours"); + CrashReportCategory crashreportcategory = crashreport.makeCategory("Block being updated"); + crashreportcategory.addDetail( + "Source block type", + new ICrashReportDetail() { +- public String call() throws Exception { +- try { +- return String.format( +- "ID #%d (%s // %s)", +- Block.getIdFromBlock(changedBlock), +- changedBlock.getTranslationKey(), +- changedBlock.getClass().getCanonicalName() +- ); +- } catch (Throwable throwable1) { +- return "ID #" + Block.getIdFromBlock(changedBlock); +- } ++ public String call() throws Exception { ++ try { ++ return String.format( ++ "ID #%d (%s // %s // %s)", Block.getIdFromBlock(changedBlock), changedBlock.getTranslationKey(), changedBlock.getClass().getName(), changedBlock.getRegistryName() ++ ); ++ } catch (Throwable throwable1) { ++ return "ID #" + Block.getIdFromBlock(changedBlock); + } + } ++ } + ); + CrashReportCategory.addBlockInfo(crashreportcategory, pos, iblockstate); + throw new ReportedException(crashreport); +@@ -544,21 +587,23 @@ + public boolean canBlockSeeSky(BlockPos pos) { + if (pos.getY() >= this.getSeaLevel()) { + return this.canSeeSky(pos); +- } ++ } else { ++ BlockPos blockpos = new BlockPos(pos.getX(), this.getSeaLevel(), pos.getZ()); + +- BlockPos blockpos = new BlockPos(pos.getX(), this.getSeaLevel(), pos.getZ()); +- if (!this.canSeeSky(blockpos)) { +- return false; +- } +- +- for (BlockPos blockpos1 = blockpos.down(); blockpos1.getY() > pos.getY(); blockpos1 = blockpos1.down()) { +- IBlockState iblockstate = this.getBlockState(blockpos1); +- if (iblockstate.getLightOpacity() > 0 && !iblockstate.getMaterial().isLiquid()) { ++ if (!this.canSeeSky(blockpos)) { + return false; ++ } else { ++ for (BlockPos blockpos1 = blockpos.down(); blockpos1.getY() > pos.getY(); blockpos1 = blockpos1.down()) { ++ IBlockState iblockstate = this.getBlockState(blockpos1); ++ ++ if (iblockstate.getBlock().getLightOpacity(iblockstate, this, blockpos) > 0 && !iblockstate.getMaterial().isLiquid()) { ++ return false; ++ } ++ } ++ ++ return true; + } + } +- +- return true; + } + + public int getLight(BlockPos pos) { +@@ -768,7 +813,7 @@ + + /** Checks whether its daytime by seeing if the light subtracted from the skylight is less than 4 */ + public boolean isDaytime() { +- return this.skylightSubtracted < 4; ++ return this.provider.isDaytime(); + } + + /** ray traces all blocks, including non-collideable ones */ +@@ -942,6 +987,13 @@ + float volume, + float pitch + ) { ++ net.minecraftforge.event.entity.PlaySoundAtEntityEvent event = net.minecraftforge.event.ForgeEventFactory.onPlaySoundAtEntity(player, soundIn, category, volume, pitch); ++ if (event.isCanceled() || event.getSound() == null) return; ++ soundIn = event.getSound(); ++ category = event.getCategory(); ++ volume = event.getVolume(); ++ pitch = event.getPitch(); ++ + for (int i = 0; i < this.eventListeners.size(); i++) { + this.eventListeners.get(i).playSoundToAllNearExcept(player, soundIn, category, x, y, z, volume, pitch); + } +@@ -1051,12 +1103,18 @@ + + /** adds a lightning bolt to the list of lightning bolts in this world. */ + public boolean addWeatherEffect(Entity entityIn) { ++ if(net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.EntityJoinWorldEvent(entityIn, this))) ++ return false; ++ + this.weatherEffects.add(entityIn); + return true; + } + + /** Called when an entity is spawned in the world. This includes players. */ + public boolean spawnEntity(Entity entityIn) { ++ // do not drop any items while restoring blocksnapshots. Prevents dupes ++ if (!this.isRemote && (entityIn == null || (entityIn instanceof net.minecraft.entity.item.EntityItem && this.restoringBlockSnapshots))) return false; ++ + int i = MathHelper.floor(entityIn.posX / 16.0); + int j = MathHelper.floor(entityIn.posZ / 16.0); + boolean flag = entityIn.forceSpawn; +@@ -1068,6 +1126,8 @@ + return false; + } + ++ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.EntityJoinWorldEvent(entityIn, this)) && !flag) return false; ++ + if (entityIn instanceof EntityPlayer) { + EntityPlayer entityplayer = (EntityPlayer)entityIn; + this.playerEntities.add(entityplayer); +@@ -1084,12 +1144,14 @@ + for (int i = 0; i < this.eventListeners.size(); i++) { + this.eventListeners.get(i).onEntityAdded(entityIn); + } ++ entityIn.onAddedToWorld(); + } + + public void onEntityRemoved(Entity entityIn) { + for (int i = 0; i < this.eventListeners.size(); i++) { + this.eventListeners.get(i).onEntityRemoved(entityIn); + } ++ entityIn.onRemovedFromWorld(); + } + + /** Schedule the entity for removal during the next tick. Marks the entity dead in anticipation. */ +@@ -1134,8 +1196,6 @@ + this.eventListeners.add(listener); + } + +- /** Remove a world event listener */ +- @SideOnly(Side.CLIENT) + public void removeEventListener(IWorldEventListener listener) { + this.eventListeners.remove(listener); + } +@@ -1162,6 +1222,7 @@ + IBlockState iblockstate = Blocks.STONE.getDefaultState(); + BlockPos.PooledMutableBlockPos blockpos$pooledmutableblockpos = BlockPos.PooledMutableBlockPos.retain(); + ++ if (p_191504_3_ && !net.minecraftforge.event.ForgeEventFactory.gatherCollisionBoxes(this, entityIn, aabb, outList)) return true; + try { + for (int k1 = i; k1 < j; k1++) { + for (int l1 = i1; l1 < j1; l1++) { +@@ -1187,7 +1248,8 @@ + } + + iblockstate1.addCollisionBoxToList(this, blockpos$pooledmutableblockpos, aabb, outList, entityIn, false); +- if (p_191504_3_ && !outList.isEmpty()) { ++ ++ if (p_191504_3_ && !net.minecraftforge.event.ForgeEventFactory.gatherCollisionBoxes(this, entityIn, aabb, outList)) { + return true; + } + } +@@ -1224,7 +1286,7 @@ + } + } + } +- ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.GetCollisionBoxesEvent(this, entityIn, aabb, list)); + return list; + } + +@@ -1255,19 +1317,36 @@ + + /** Returns the amount of skylight subtracted for the current time */ + public int calculateSkylightSubtracted(float partialTicks) { ++ float f = provider.getSunBrightnessFactor(partialTicks); ++ f = 1 - f; ++ return (int)(f * 11); ++ } ++ ++ /** ++ * The current sun brightness factor for this dimension. ++ * 0.0f means no light at all, and 1.0f means maximum sunlight. ++ * Highly recommended for sunlight detection like solar panel. ++ * ++ * @return The current brightness factor ++ * */ ++ public float getSunBrightnessFactor(float partialTicks) { + float f = this.getCelestialAngle(partialTicks); + float f1 = 1.0F - (MathHelper.cos(f * (float) (Math.PI * 2)) * 2.0F + 0.5F); + f1 = MathHelper.clamp(f1, 0.0F, 1.0F); + f1 = 1.0F - f1; + f1 = (float)(f1 * (1.0 - this.getRainStrength(partialTicks) * 5.0F / 16.0)); + f1 = (float)(f1 * (1.0 - this.getThunderStrength(partialTicks) * 5.0F / 16.0)); +- f1 = 1.0F - f1; +- return (int)(f1 * 11.0F); ++ return f1; + } + + /** Returns the sun brightness - checks time of day, rain and thunder */ + @SideOnly(Side.CLIENT) + public float getSunBrightness(float partialTicks) { ++ return this.provider.getSunBrightness(partialTicks); ++ } ++ ++ @SideOnly(Side.CLIENT) ++ public float getSunBrightnessBody(float partialTicks) { + float f = this.getCelestialAngle(partialTicks); + float f1 = 1.0F - (MathHelper.cos(f * (float) (Math.PI * 2)) * 2.0F + 0.2F); + f1 = MathHelper.clamp(f1, 0.0F, 1.0F); +@@ -1280,6 +1359,11 @@ + /** Calculates the color for the skybox */ + @SideOnly(Side.CLIENT) + public Vec3d getSkyColor(Entity entityIn, float partialTicks) { ++ return this.provider.getSkyColor(entityIn, partialTicks); ++ } ++ ++ @SideOnly(Side.CLIENT) ++ public Vec3d getSkyColorBody(Entity entityIn, float partialTicks) { + float f = this.getCelestialAngle(partialTicks); + float f1 = MathHelper.cos(f * (float) (Math.PI * 2)) * 2.0F + 0.5F; + f1 = MathHelper.clamp(f1, 0.0F, 1.0F); +@@ -1287,9 +1371,7 @@ + int j = MathHelper.floor(entityIn.posY); + int k = MathHelper.floor(entityIn.posZ); + BlockPos blockpos = new BlockPos(i, j, k); +- Biome biome = this.getBiome(blockpos); +- float f2 = biome.getTemperature(blockpos); +- int l = biome.getSkyColorByTemp(f2); ++ int l = net.minecraftforge.client.ForgeHooksClient.getSkyBlendColour(this, blockpos); + float f3 = (l >> 16 & 0xFF) / 255.0F; + float f4 = (l >> 8 & 0xFF) / 255.0F; + float f5 = (l & 0xFF) / 255.0F; +@@ -1331,19 +1413,23 @@ + + /** calls calculateCelestialAngle */ + public float getCelestialAngle(float partialTicks) { +- return this.provider.calculateCelestialAngle(this.worldInfo.getWorldTime(), partialTicks); ++ return this.provider.calculateCelestialAngle(this.getWorldTime(), partialTicks); + } + + @SideOnly(Side.CLIENT) + public int getMoonPhase() { +- return this.provider.getMoonPhase(this.worldInfo.getWorldTime()); ++ return this.provider.getMoonPhase(this.getWorldTime()); + } + + /** gets the current fullness of the moon expressed as a float between 1.0 and 0.0, in steps of .25 */ + public float getCurrentMoonPhaseFactor() { +- return WorldProvider.MOON_PHASE_FACTORS[this.provider.getMoonPhase(this.worldInfo.getWorldTime())]; ++ return provider.getCurrentMoonPhaseFactor(); + } + ++ public float getCurrentMoonPhaseFactorBody() { ++ return WorldProvider.MOON_PHASE_FACTORS[this.provider.getMoonPhase(this.getWorldTime())]; ++ } ++ + /** Return getCelestialAngle()*2*PI */ + public float getCelestialAngleRadians(float partialTicks) { + float f = this.getCelestialAngle(partialTicks); +@@ -1352,6 +1438,11 @@ + + @SideOnly(Side.CLIENT) + public Vec3d getCloudColour(float partialTicks) { ++ return this.provider.getCloudColor(partialTicks); ++ } ++ ++ @SideOnly(Side.CLIENT) ++ public Vec3d getCloudColorBody(float partialTicks) { + float f = this.getCelestialAngle(partialTicks); + float f1 = MathHelper.cos(f * (float) (Math.PI * 2)) * 2.0F + 0.5F; + f1 = MathHelper.clamp(f1, 0.0F, 1.0F); +@@ -1400,8 +1491,9 @@ + + while (blockpos.getY() >= 0) { + BlockPos blockpos1 = blockpos.down(); +- Material material = chunk.getBlockState(blockpos1).getMaterial(); +- if (material.blocksMovement() && material != Material.LEAVES) { ++ IBlockState state = chunk.getBlockState(blockpos1); ++ ++ if (state.getMaterial().blocksMovement() && !state.getBlock().isLeaves(state, this, blockpos1) && !state.getBlock().isFoliage(this, blockpos1)) { + break; + } + +@@ -1414,6 +1506,11 @@ + /** How bright are stars in the sky */ + @SideOnly(Side.CLIENT) + public float getStarBrightness(float partialTicks) { ++ return this.provider.getStarBrightness(partialTicks); ++ } ++ ++ @SideOnly(Side.CLIENT) ++ public float getStarBrightnessBody(float partialTicks) { + float f = this.getCelestialAngle(partialTicks); + float f1 = 1.0F - (MathHelper.cos(f * (float) (Math.PI * 2)) * 2.0F + 0.25F); + f1 = MathHelper.clamp(f1, 0.0F, 1.0F); +@@ -1444,17 +1541,23 @@ + Entity entity = this.weatherEffects.get(i); + + try { ++ if(entity.updateBlocked) continue; + entity.ticksExisted++; + entity.onUpdate(); + } catch (Throwable throwable2) { + CrashReport crashreport = CrashReport.makeCrashReport(throwable2, "Ticking entity"); + CrashReportCategory crashreportcategory = crashreport.makeCategory("Entity being ticked"); ++ + if (entity == null) { + crashreportcategory.addCrashSection("Entity", "~~NULL~~"); + } else { + entity.addEntityCrashInfo(crashreportcategory); + } + ++ if (net.minecraftforge.common.ForgeModContainer.removeErroringEntities) { ++ net.minecraftforge.fml.common.FMLLog.log.fatal("{}", crashreport.getCompleteReport()); ++ removeEntity(entity); ++ } else + throw new ReportedException(crashreport); + } + +@@ -1470,6 +1573,7 @@ + Entity entity1 = this.unloadedEntityList.get(k); + int j = entity1.chunkCoordX; + int k1 = entity1.chunkCoordZ; ++ + if (entity1.addedToChunk && this.isChunkLoaded(j, k1, true)) { + this.getChunk(j, k1).removeEntity(entity1); + } +@@ -1486,6 +1590,7 @@ + for (int i1 = 0; i1 < this.loadedEntityList.size(); i1++) { + Entity entity2 = this.loadedEntityList.get(i1); + Entity entity3 = entity2.getRidingEntity(); ++ + if (entity3 != null) { + if (!entity3.isDead && entity3.isPassenger(entity2)) { + continue; +@@ -1495,22 +1600,31 @@ + } + + this.profiler.startSection("tick"); ++ + if (!entity2.isDead && !(entity2 instanceof EntityPlayerMP)) { + try { ++ net.minecraftforge.server.timings.TimeTracker.ENTITY_UPDATE.trackStart(entity2); + this.updateEntity(entity2); ++ net.minecraftforge.server.timings.TimeTracker.ENTITY_UPDATE.trackEnd(entity2); + } catch (Throwable throwable1) { + CrashReport crashreport1 = CrashReport.makeCrashReport(throwable1, "Ticking entity"); + CrashReportCategory crashreportcategory1 = crashreport1.makeCategory("Entity being ticked"); + entity2.addEntityCrashInfo(crashreportcategory1); ++ if (net.minecraftforge.common.ForgeModContainer.removeErroringEntities) { ++ net.minecraftforge.fml.common.FMLLog.log.fatal("{}", crashreport1.getCompleteReport()); ++ removeEntity(entity2); ++ } else + throw new ReportedException(crashreport1); + } + } + + this.profiler.endSection(); + this.profiler.startSection("remove"); ++ + if (entity2.isDead) { + int l1 = entity2.chunkCoordX; + int i2 = entity2.chunkCoordZ; ++ + if (entity2.addedToChunk && this.isChunkLoaded(l1, i2, true)) { + this.getChunk(l1, i2).removeEntity(entity2); + } +@@ -1523,28 +1637,46 @@ + } + + this.profiler.endStartSection("blockEntities"); ++ ++ this.processingLoadedTiles = true; //FML Move above remove to prevent CMEs ++ + if (!this.tileEntitiesToBeRemoved.isEmpty()) { +- this.tickableTileEntities.removeAll(this.tileEntitiesToBeRemoved); +- this.loadedTileEntityList.removeAll(this.tileEntitiesToBeRemoved); ++ for (Object tile : tileEntitiesToBeRemoved) { ++ ((TileEntity)tile).onChunkUnload(); ++ } ++ ++ // forge: faster "contains" makes this removal much more efficient ++ java.util.Set remove = java.util.Collections.newSetFromMap(new java.util.IdentityHashMap<>()); ++ remove.addAll(tileEntitiesToBeRemoved); ++ this.tickableTileEntities.removeAll(remove); ++ this.loadedTileEntityList.removeAll(remove); + this.tileEntitiesToBeRemoved.clear(); + } + +- this.processingLoadedTiles = true; + Iterator iterator = this.tickableTileEntities.iterator(); + + while (iterator.hasNext()) { + TileEntity tileentity = iterator.next(); ++ + if (!tileentity.isInvalid() && tileentity.hasWorld()) { + BlockPos blockpos = tileentity.getPos(); +- if (this.isBlockLoaded(blockpos) && this.worldBorder.contains(blockpos)) { ++ ++ if (this.isBlockLoaded(blockpos, false) && this.worldBorder.contains(blockpos)) { //Forge: Fix TE's getting an extra tick on the client side.... + try { +- this.profiler.func_194340_a(() -> String.valueOf(TileEntity.getKey((Class)tileentity.getClass()))); ++ this.profiler.func_194340_a(() -> String.valueOf(TileEntity.getKey(tileentity.getClass()))); ++ net.minecraftforge.server.timings.TimeTracker.TILE_ENTITY_UPDATE.trackStart(tileentity); + ((ITickable)tileentity).update(); ++ net.minecraftforge.server.timings.TimeTracker.TILE_ENTITY_UPDATE.trackEnd(tileentity); + this.profiler.endSection(); + } catch (Throwable throwable) { + CrashReport crashreport2 = CrashReport.makeCrashReport(throwable, "Ticking block entity"); + CrashReportCategory crashreportcategory2 = crashreport2.makeCategory("Block entity being ticked"); + tileentity.addInfoToCrashReport(crashreportcategory2); ++ if (net.minecraftforge.common.ForgeModContainer.removeErroringTileEntities) { ++ net.minecraftforge.fml.common.FMLLog.log.fatal("{}", crashreport2.getCompleteReport()); ++ tileentity.invalidate(); ++ this.removeTileEntity(tileentity.getPos()); ++ } else + throw new ReportedException(crashreport2); + } + } +@@ -1553,17 +1685,23 @@ + if (tileentity.isInvalid()) { + iterator.remove(); + this.loadedTileEntityList.remove(tileentity); ++ + if (this.isBlockLoaded(tileentity.getPos())) { +- this.getChunk(tileentity.getPos()).removeTileEntity(tileentity.getPos()); ++ //Forge: Bugfix: If we set the tile entity it immediately sets it in the chunk, so we could be desyned ++ Chunk chunk = this.getChunk(tileentity.getPos()); ++ if (chunk.getTileEntity(tileentity.getPos(), net.minecraft.world.chunk.Chunk.EnumCreateEntityType.CHECK) == tileentity) ++ chunk.removeTileEntity(tileentity.getPos()); + } + } + } + + this.processingLoadedTiles = false; + this.profiler.endStartSection("pendingBlockEntities"); ++ + if (!this.addedTileEntityList.isEmpty()) { + for (int j1 = 0; j1 < this.addedTileEntityList.size(); j1++) { + TileEntity tileentity1 = this.addedTileEntityList.get(j1); ++ + if (!tileentity1.isInvalid()) { + if (!this.loadedTileEntityList.contains(tileentity1)) { + this.addTileEntity(tileentity1); +@@ -1589,10 +1727,16 @@ + } + + public boolean addTileEntity(TileEntity tile) { ++ // Forge - set the world early as vanilla doesn't set it until next tick ++ if (tile.getWorld() != this) tile.setWorld(this); ++ // Forge: wait to add new TE if we're currently processing existing ones ++ if (processingLoadedTiles) return addedTileEntityList.add(tile); ++ + boolean flag = this.loadedTileEntityList.add(tile); + if (flag && tile instanceof ITickable) { + this.tickableTileEntities.add(tile); + } ++ tile.onLoad(); + + if (this.isRemote) { + BlockPos blockpos = tile.getPos(); +@@ -1605,6 +1749,10 @@ + + public void addTileEntities(Collection tileEntityCollection) { + if (this.processingLoadedTiles) { ++ for (TileEntity te : tileEntityCollection) { ++ if (te.getWorld() != this) // Forge - set the world early as vanilla doesn't set it until next tick ++ te.setWorld(this); ++ } + this.addedTileEntityList.addAll(tileEntityCollection); + } else { + for (TileEntity tileentity : tileEntityCollection) { +@@ -1623,8 +1771,13 @@ + if (!(entityIn instanceof EntityPlayer)) { + int i = MathHelper.floor(entityIn.posX); + int j = MathHelper.floor(entityIn.posZ); +- int k = 32; +- if (forceUpdate && !this.isAreaLoaded(i - 32, 0, j - 32, i + 32, 0, j + 32, true)) { ++ ++ boolean isForced = !this.isRemote && getPersistentChunks().containsKey(new net.minecraft.util.math.ChunkPos(i >> 4, j >> 4)); ++ int range = isForced ? 0 : 32; ++ boolean canUpdate = !forceUpdate || this.isAreaLoaded(i - range, 0, j - range, i + range, 0, j + range, true); ++ if (!canUpdate) canUpdate = net.minecraftforge.event.ForgeEventFactory.canEntityUpdate(entityIn); ++ ++ if (!canUpdate) { + return; + } + } +@@ -1639,6 +1792,7 @@ + if (entityIn.isRiding()) { + entityIn.updateRidden(); + } else { ++ if(!entityIn.updateBlocked) + entityIn.onUpdate(); + } + } +@@ -1702,7 +1856,8 @@ + + for (int i = 0; i < list.size(); i++) { + Entity entity = list.get(i); +- if (!entity.isDead && entity.preventEntitySpawning && entity != entityIn && (entityIn == null || entity.isRidingSameEntity(entityIn))) { ++ ++ if (!entity.isDead && entity.preventEntitySpawning && entity != entityIn && (entityIn == null || !entity.isRidingSameEntity(entityIn))) { // Forge: fix MC-103516 + return false; + } + } +@@ -1750,6 +1905,13 @@ + for (int l1 = k; l1 < l; l1++) { + for (int i2 = i1; i2 < j1; i2++) { + IBlockState iblockstate = this.getBlockState(blockpos$pooledmutableblockpos.setPos(k1, l1, i2)); ++ ++ Boolean result = iblockstate.getBlock().isAABBInsideLiquid(this, blockpos$pooledmutableblockpos, bb); ++ if (result != null) { ++ if (!result) continue; ++ blockpos$pooledmutableblockpos.release(); ++ return true; ++ } + if (iblockstate.getMaterial().isLiquid()) { + blockpos$pooledmutableblockpos.release(); + return true; +@@ -1779,6 +1941,9 @@ + if (block == Blocks.FIRE || block == Blocks.FLOWING_LAVA || block == Blocks.LAVA) { + blockpos$pooledmutableblockpos.release(); + return true; ++ } else if (block.isBurning(this, new BlockPos(k1, l1, i2))) { ++ blockpos$pooledmutableblockpos.release(); ++ return true; + } + } + } +@@ -1798,41 +1963,53 @@ + int l = MathHelper.ceil(bb.maxY); + int i1 = MathHelper.floor(bb.minZ); + int j1 = MathHelper.ceil(bb.maxZ); ++ + if (!this.isAreaLoaded(i, k, i1, j, l, j1, true)) { + return false; +- } ++ } else { ++ boolean flag = false; ++ Vec3d vec3d = Vec3d.ZERO; ++ BlockPos.PooledMutableBlockPos blockpos$pooledmutableblockpos = BlockPos.PooledMutableBlockPos.retain(); + +- boolean flag = false; +- Vec3d vec3d = Vec3d.ZERO; +- BlockPos.PooledMutableBlockPos blockpos$pooledmutableblockpos = BlockPos.PooledMutableBlockPos.retain(); ++ for (int k1 = i; k1 < j; k1++) { ++ for (int l1 = k; l1 < l; l1++) { ++ for (int i2 = i1; i2 < j1; i2++) { ++ blockpos$pooledmutableblockpos.setPos(k1, l1, i2); ++ IBlockState iblockstate = this.getBlockState(blockpos$pooledmutableblockpos); ++ Block block = iblockstate.getBlock(); + +- for (int k1 = i; k1 < j; k1++) { +- for (int l1 = k; l1 < l; l1++) { +- for (int i2 = i1; i2 < j1; i2++) { +- blockpos$pooledmutableblockpos.setPos(k1, l1, i2); +- IBlockState iblockstate = this.getBlockState(blockpos$pooledmutableblockpos); +- Block block = iblockstate.getBlock(); +- if (iblockstate.getMaterial() == materialIn) { +- double d0 = l1 + 1 - BlockLiquid.getLiquidHeightPercent(iblockstate.getValue(BlockLiquid.LEVEL)); +- if (l >= d0) { ++ Boolean result = block.isEntityInsideMaterial(this, blockpos$pooledmutableblockpos, iblockstate, entityIn, (double)l, materialIn, false); ++ if (result != null && result == true) { ++ // Forge: When requested call blocks modifyAcceleration method, and more importantly cause this method to return true, which results in an entity being "inWater" + flag = true; + vec3d = block.modifyAcceleration(this, blockpos$pooledmutableblockpos, entityIn, vec3d); ++ continue; ++ } else if (result != null && result == false) continue; ++ ++ if (iblockstate.getMaterial() == materialIn) { ++ double d0 = l1 + 1 - BlockLiquid.getLiquidHeightPercent(iblockstate.getValue(BlockLiquid.LEVEL)); ++ ++ if (l >= d0) { ++ flag = true; ++ vec3d = block.modifyAcceleration(this, blockpos$pooledmutableblockpos, entityIn, vec3d); ++ } + } + } + } + } +- } + +- blockpos$pooledmutableblockpos.release(); +- if (vec3d.length() > 0.0 && entityIn.isPushedByWater()) { +- vec3d = vec3d.normalize(); +- double d1 = 0.014; +- entityIn.motionX = entityIn.motionX + vec3d.x * 0.014; +- entityIn.motionY = entityIn.motionY + vec3d.y * 0.014; +- entityIn.motionZ = entityIn.motionZ + vec3d.z * 0.014; +- } ++ blockpos$pooledmutableblockpos.release(); + +- return flag; ++ if (vec3d.length() > 0.0 && entityIn.isPushedByWater()) { ++ vec3d = vec3d.normalize(); ++ double d1 = 0.014; ++ entityIn.motionX = entityIn.motionX + vec3d.x * 0.014; ++ entityIn.motionY = entityIn.motionY + vec3d.y * 0.014; ++ entityIn.motionZ = entityIn.motionZ + vec3d.z * 0.014; ++ } ++ ++ return flag; ++ } + } + + /** Returns true if the given bounding box contains the given material */ +@@ -1848,10 +2025,17 @@ + for (int k1 = i; k1 < j; k1++) { + for (int l1 = k; l1 < l; l1++) { + for (int i2 = i1; i2 < j1; i2++) { +- if (this.getBlockState(blockpos$pooledmutableblockpos.setPos(k1, l1, i2)).getMaterial() == materialIn) { ++ IBlockState iblockstate1 = this.getBlockState(blockpos$pooledmutableblockpos.setPos(k1, l1, i2)); ++ Boolean result = iblockstate1.getBlock().isAABBInsideMaterial(this, blockpos$pooledmutableblockpos, bb, materialIn); ++ if (result != null) { ++ if (!result) continue; + blockpos$pooledmutableblockpos.release(); + return true; + } ++ if (iblockstate1.getMaterial() == materialIn) { ++ blockpos$pooledmutableblockpos.release(); ++ return true; ++ } + } + } + } +@@ -1870,6 +2054,7 @@ + @Nullable Entity entityIn, double x, double y, double z, float strength, boolean causesFire, boolean damagesTerrain + ) { + Explosion explosion = new Explosion(this, entityIn, x, y, z, strength, causesFire, damagesTerrain); ++ if (net.minecraftforge.event.ForgeEventFactory.onExplosionStart(this, explosion)) return explosion; + explosion.doExplosionA(); + explosion.doExplosionB(true); + return explosion; +@@ -1967,23 +2152,29 @@ + } + + public void setTileEntity(BlockPos pos, @Nullable TileEntity tileEntityIn) { ++ pos = pos.toImmutable(); // Forge - prevent mutable BlockPos leaks + if (!this.isOutsideBuildHeight(pos)) { + if (tileEntityIn != null && !tileEntityIn.isInvalid()) { + if (this.processingLoadedTiles) { + tileEntityIn.setPos(pos); ++ if (tileEntityIn.getWorld() != this) ++ tileEntityIn.setWorld(this); // Forge - set the world early as vanilla doesn't set it until next tick + Iterator iterator = this.addedTileEntityList.iterator(); ++ List toInvalidate = Lists.newArrayList(); + + while (iterator.hasNext()) { + TileEntity tileentity = iterator.next(); + if (tileentity.getPos().equals(pos)) { +- tileentity.invalidate(); ++ toInvalidate.add(tileentity); // Forge - don't call invalidate while iterating + iterator.remove(); + } + } + ++ toInvalidate.forEach(TileEntity::invalidate); + this.addedTileEntityList.add(tileEntityIn); + } else { +- this.getChunk(pos).addTileEntity(pos, tileEntityIn); ++ Chunk chunk = this.getChunk(pos); ++ if (chunk != null) chunk.addTileEntity(pos, tileEntityIn); + this.addTileEntity(tileEntityIn); + } + } +@@ -1995,6 +2186,8 @@ + if (tileentity != null && this.processingLoadedTiles) { + tileentity.invalidate(); + this.addedTileEntityList.remove(tileentity); ++ if (!(tileentity instanceof ITickable)) //Forge: If they are not tickable they wont be removed in the update loop. ++ this.loadedTileEntityList.remove(tileentity); + } else { + if (tileentity != null) { + this.addedTileEntityList.remove(tileentity); +@@ -2004,6 +2197,7 @@ + + this.getChunk(pos).removeTileEntity(pos); + } ++ this.updateComparatorOutputLevel(pos, getBlockState(pos).getBlock()); //Notify neighbors of changes + } + + /** Adds the specified TileEntity to the pending removal list. */ +@@ -2024,7 +2218,7 @@ + Chunk chunk = this.chunkProvider.getLoadedChunk(pos.getX() >> 4, pos.getZ() >> 4); + if (chunk != null && !chunk.isEmpty()) { + IBlockState iblockstate = this.getBlockState(pos); +- return iblockstate.getMaterial().isOpaque() && iblockstate.isFullCube(); ++ return iblockstate.getBlock().isNormalCube(iblockstate, this, pos); + } else { + return _default; + } +@@ -2043,6 +2237,7 @@ + public void setAllowedSpawnTypes(boolean hostile, boolean peaceful) { + this.spawnHostileMobs = hostile; + this.spawnPeacefulMobs = peaceful; ++ this.provider.setAllowedSpawnTypes(hostile, peaceful); + } + + /** Runs a single tick for the world */ +@@ -2052,6 +2247,10 @@ + + /** Called from World constructor to set rainingStrength and thunderingStrength */ + protected void calculateInitialWeather() { ++ this.provider.calculateInitialWeather(); ++ } ++ ++ public void calculateInitialWeatherBody() { + if (this.worldInfo.isRaining()) { + this.rainingStrength = 1.0F; + if (this.worldInfo.isThundering()) { +@@ -2062,6 +2261,10 @@ + + /** Updates all weather states. */ + protected void updateWeather() { ++ this.provider.updateWeather(); ++ } ++ ++ public void updateWeatherBody() { + if (this.provider.hasSkyLight()) { + if (!this.isRemote) { + boolean flag = this.getGameRules().getBoolean("doWeatherCycle"); +@@ -2146,6 +2349,10 @@ + + /** Checks to see if a given block is both water and cold enough to freeze. */ + public boolean canBlockFreeze(BlockPos pos, boolean noWaterAdj) { ++ return this.provider.canBlockFreeze(pos, noWaterAdj); ++ } ++ ++ public boolean canBlockFreezeBody(BlockPos pos, boolean noWaterAdj) { + Biome biome = this.getBiome(pos); + float f = biome.getTemperature(pos); + if (f >= 0.15F) { +@@ -2179,6 +2386,10 @@ + + /** Checks to see if a given block can accumulate snow from it snowing */ + public boolean canSnowAt(BlockPos pos, boolean checkLight) { ++ return this.provider.canSnowAt(pos, checkLight); ++ } ++ ++ public boolean canSnowAtBody(BlockPos pos, boolean checkLight) { + Biome biome = this.getBiome(pos); + float f = biome.getTemperature(pos); + if (f >= 0.15F) { +@@ -2191,7 +2402,7 @@ + + if (pos.getY() >= 0 && pos.getY() < 256 && this.getLightFor(EnumSkyBlock.BLOCK, pos) < 10) { + IBlockState iblockstate = this.getBlockState(pos); +- if (iblockstate.getMaterial() == Material.AIR && Blocks.SNOW_LAYER.canPlaceBlockAt(this, pos)) { ++ if (iblockstate.getBlock().isAir(iblockstate, this, pos) && Blocks.SNOW_LAYER.canPlaceBlockAt(this, pos)) { + return true; + } + } +@@ -2212,153 +2423,163 @@ + private int getRawLight(BlockPos pos, EnumSkyBlock lightType) { + if (lightType == EnumSkyBlock.SKY && this.canSeeSky(pos)) { + return 15; +- } ++ } else { ++ IBlockState iblockstate = this.getBlockState(pos); ++ int i = lightType == EnumSkyBlock.SKY ? 0 : iblockstate.getBlock().getLightValue(iblockstate, this, pos); ++ int j = iblockstate.getBlock().getLightOpacity(iblockstate, this, pos); + +- IBlockState iblockstate = this.getBlockState(pos); +- int i = lightType == EnumSkyBlock.SKY ? 0 : iblockstate.getLightValue(); +- int j = iblockstate.getLightOpacity(); +- if (j >= 15 && iblockstate.getLightValue() > 0) { +- j = 1; +- } ++ if (false) { // Forge: fix MC-119932 ++ j = 1; ++ } + +- if (j < 1) { +- j = 1; +- } ++ if (j < 1) { ++ j = 1; ++ } + +- if (j >= 15) { +- return 0; +- } ++ if (j >= 15) { ++ return i; // Forge: fix MC-119932 ++ } else if (i >= 14) { ++ return i; ++ } else { ++ BlockPos.PooledMutableBlockPos blockpos$pooledmutableblockpos = BlockPos.PooledMutableBlockPos.retain(); + +- if (i >= 14) { +- return i; +- } ++ try { ++ for (EnumFacing enumfacing : EnumFacing.values()) { ++ blockpos$pooledmutableblockpos.setPos(pos).move(enumfacing); ++ int k = this.getLightFor(lightType, blockpos$pooledmutableblockpos) - j; + +- BlockPos.PooledMutableBlockPos blockpos$pooledmutableblockpos = BlockPos.PooledMutableBlockPos.retain(); ++ if (k > i) { ++ i = k; ++ } + +- try { +- for (EnumFacing enumfacing : EnumFacing.values()) { +- blockpos$pooledmutableblockpos.setPos(pos).move(enumfacing); +- int k = this.getLightFor(lightType, blockpos$pooledmutableblockpos) - j; +- if (k > i) { +- i = k; +- } ++ if (i >= 14) { ++ return i; ++ } ++ } + +- if (i >= 14) { + return i; ++ } finally { ++ blockpos$pooledmutableblockpos.release(); + } + } +- } finally { +- blockpos$pooledmutableblockpos.release(); + } +- +- return i; + } + + public boolean checkLightFor(EnumSkyBlock lightType, BlockPos pos) { +- if (!this.isAreaLoaded(pos, 17, false)) { ++ if (!this.isAreaLoaded(pos, 16, false)) { + return false; +- } ++ } else { ++ int updateRange = this.isAreaLoaded(pos, 18, false) ? 17 : 15; ++ int i = 0; ++ int j = 0; ++ this.profiler.startSection("getBrightness"); ++ int k = this.getLightFor(lightType, pos); ++ int l = this.getRawLight(pos, lightType); ++ int i1 = pos.getX(); ++ int j1 = pos.getY(); ++ int k1 = pos.getZ(); + +- int i = 0; +- int j = 0; +- this.profiler.startSection("getBrightness"); +- int k = this.getLightFor(lightType, pos); +- int l = this.getRawLight(pos, lightType); +- int i1 = pos.getX(); +- int j1 = pos.getY(); +- int k1 = pos.getZ(); +- if (l > k) { +- this.lightUpdateBlockList[j++] = 133152; +- } else if (l < k) { +- this.lightUpdateBlockList[j++] = 133152 | k << 18; ++ if (l > k) { ++ this.lightUpdateBlockList[j++] = 133152; ++ } else if (l < k) { ++ this.lightUpdateBlockList[j++] = 133152 | k << 18; + +- while (i < j) { +- int l1 = this.lightUpdateBlockList[i++]; +- int i2 = (l1 & 63) - 32 + i1; +- int j2 = (l1 >> 6 & 63) - 32 + j1; +- int k2 = (l1 >> 12 & 63) - 32 + k1; +- int l2 = l1 >> 18 & 15; +- BlockPos blockpos = new BlockPos(i2, j2, k2); +- int i3 = this.getLightFor(lightType, blockpos); +- if (i3 == l2) { +- this.setLightFor(lightType, blockpos, 0); +- if (l2 > 0) { +- int j3 = MathHelper.abs(i2 - i1); +- int k3 = MathHelper.abs(j2 - j1); +- int l3 = MathHelper.abs(k2 - k1); +- if (j3 + k3 + l3 < 17) { +- BlockPos.PooledMutableBlockPos blockpos$pooledmutableblockpos = BlockPos.PooledMutableBlockPos.retain(); ++ while (i < j) { ++ int l1 = this.lightUpdateBlockList[i++]; ++ int i2 = (l1 & 63) - 32 + i1; ++ int j2 = (l1 >> 6 & 63) - 32 + j1; ++ int k2 = (l1 >> 12 & 63) - 32 + k1; ++ int l2 = l1 >> 18 & 15; ++ BlockPos blockpos = new BlockPos(i2, j2, k2); ++ int i3 = this.getLightFor(lightType, blockpos); + +- for (EnumFacing enumfacing : EnumFacing.values()) { +- int i4 = i2 + enumfacing.getXOffset(); +- int j4 = j2 + enumfacing.getYOffset(); +- int k4 = k2 + enumfacing.getZOffset(); +- blockpos$pooledmutableblockpos.setPos(i4, j4, k4); +- int l4 = Math.max(1, this.getBlockState(blockpos$pooledmutableblockpos).getLightOpacity()); +- i3 = this.getLightFor(lightType, blockpos$pooledmutableblockpos); +- if (i3 == l2 - l4 && j < this.lightUpdateBlockList.length) { +- this.lightUpdateBlockList[j++] = i4 - i1 + 32 | j4 - j1 + 32 << 6 | k4 - k1 + 32 << 12 | l2 - l4 << 18; ++ if (i3 == l2) { ++ this.setLightFor(lightType, blockpos, 0); ++ ++ if (l2 > 0) { ++ int j3 = MathHelper.abs(i2 - i1); ++ int k3 = MathHelper.abs(j2 - j1); ++ int l3 = MathHelper.abs(k2 - k1); ++ ++ if (j3 + k3 + l3 < updateRange) { ++ BlockPos.PooledMutableBlockPos blockpos$pooledmutableblockpos = BlockPos.PooledMutableBlockPos.retain(); ++ ++ for (EnumFacing enumfacing : EnumFacing.values()) { ++ int i4 = i2 + enumfacing.getXOffset(); ++ int j4 = j2 + enumfacing.getYOffset(); ++ int k4 = k2 + enumfacing.getZOffset(); ++ blockpos$pooledmutableblockpos.setPos(i4, j4, k4); ++ IBlockState bs = this.getBlockState(blockpos$pooledmutableblockpos); ++ int l4 = Math.max(1, bs.getBlock().getLightOpacity(bs, this, blockpos$pooledmutableblockpos)); ++ i3 = this.getLightFor(lightType, blockpos$pooledmutableblockpos); ++ ++ if (i3 == l2 - l4 && j < this.lightUpdateBlockList.length) { ++ this.lightUpdateBlockList[j++] = i4 - i1 + 32 | j4 - j1 + 32 << 6 | k4 - k1 + 32 << 12 | l2 - l4 << 18; ++ } + } +- } + +- blockpos$pooledmutableblockpos.release(); ++ blockpos$pooledmutableblockpos.release(); ++ } + } + } + } ++ ++ i = 0; + } + +- i = 0; +- } ++ this.profiler.endSection(); ++ this.profiler.startSection("checkedPosition < toCheckCount"); + +- this.profiler.endSection(); +- this.profiler.startSection("checkedPosition < toCheckCount"); ++ while (i < j) { ++ int j7 = this.lightUpdateBlockList[i++]; ++ int k7 = (j7 & 63) - 32 + i1; ++ int l7 = (j7 >> 6 & 63) - 32 + j1; ++ int i8 = (j7 >> 12 & 63) - 32 + k1; ++ BlockPos blockpos2 = new BlockPos(k7, l7, i8); ++ int j8 = this.getLightFor(lightType, blockpos2); ++ int k8 = this.getRawLight(blockpos2, lightType); + +- while (i < j) { +- int i5 = this.lightUpdateBlockList[i++]; +- int j5 = (i5 & 63) - 32 + i1; +- int k5 = (i5 >> 6 & 63) - 32 + j1; +- int l5 = (i5 >> 12 & 63) - 32 + k1; +- BlockPos blockpos1 = new BlockPos(j5, k5, l5); +- int i6 = this.getLightFor(lightType, blockpos1); +- int j6 = this.getRawLight(blockpos1, lightType); +- if (j6 != i6) { +- this.setLightFor(lightType, blockpos1, j6); +- if (j6 > i6) { +- int k6 = Math.abs(j5 - i1); +- int l6 = Math.abs(k5 - j1); +- int i7 = Math.abs(l5 - k1); +- boolean flag = j < this.lightUpdateBlockList.length - 6; +- if (k6 + l6 + i7 < 17 && flag) { +- if (this.getLightFor(lightType, blockpos1.west()) < j6) { +- this.lightUpdateBlockList[j++] = j5 - 1 - i1 + 32 + (k5 - j1 + 32 << 6) + (l5 - k1 + 32 << 12); +- } ++ if (k8 != j8) { ++ this.setLightFor(lightType, blockpos2, k8); + +- if (this.getLightFor(lightType, blockpos1.east()) < j6) { +- this.lightUpdateBlockList[j++] = j5 + 1 - i1 + 32 + (k5 - j1 + 32 << 6) + (l5 - k1 + 32 << 12); +- } ++ if (k8 > j8) { ++ int l8 = Math.abs(k7 - i1); ++ int i9 = Math.abs(l7 - j1); ++ int j9 = Math.abs(i8 - k1); ++ boolean flag = j < this.lightUpdateBlockList.length - 6; + +- if (this.getLightFor(lightType, blockpos1.down()) < j6) { +- this.lightUpdateBlockList[j++] = j5 - i1 + 32 + (k5 - 1 - j1 + 32 << 6) + (l5 - k1 + 32 << 12); +- } ++ if (l8 + i9 + j9 < updateRange && flag) { ++ if (this.getLightFor(lightType, blockpos2.west()) < k8) { ++ this.lightUpdateBlockList[j++] = k7 - 1 - i1 + 32 + (l7 - j1 + 32 << 6) + (i8 - k1 + 32 << 12); ++ } + +- if (this.getLightFor(lightType, blockpos1.up()) < j6) { +- this.lightUpdateBlockList[j++] = j5 - i1 + 32 + (k5 + 1 - j1 + 32 << 6) + (l5 - k1 + 32 << 12); +- } ++ if (this.getLightFor(lightType, blockpos2.east()) < k8) { ++ this.lightUpdateBlockList[j++] = k7 + 1 - i1 + 32 + (l7 - j1 + 32 << 6) + (i8 - k1 + 32 << 12); ++ } + +- if (this.getLightFor(lightType, blockpos1.north()) < j6) { +- this.lightUpdateBlockList[j++] = j5 - i1 + 32 + (k5 - j1 + 32 << 6) + (l5 - 1 - k1 + 32 << 12); +- } ++ if (this.getLightFor(lightType, blockpos2.down()) < k8) { ++ this.lightUpdateBlockList[j++] = k7 - i1 + 32 + (l7 - 1 - j1 + 32 << 6) + (i8 - k1 + 32 << 12); ++ } + +- if (this.getLightFor(lightType, blockpos1.south()) < j6) { +- this.lightUpdateBlockList[j++] = j5 - i1 + 32 + (k5 - j1 + 32 << 6) + (l5 + 1 - k1 + 32 << 12); ++ if (this.getLightFor(lightType, blockpos2.up()) < k8) { ++ this.lightUpdateBlockList[j++] = k7 - i1 + 32 + (l7 + 1 - j1 + 32 << 6) + (i8 - k1 + 32 << 12); ++ } ++ ++ if (this.getLightFor(lightType, blockpos2.north()) < k8) { ++ this.lightUpdateBlockList[j++] = k7 - i1 + 32 + (l7 - j1 + 32 << 6) + (i8 - 1 - k1 + 32 << 12); ++ } ++ ++ if (this.getLightFor(lightType, blockpos2.south()) < k8) { ++ this.lightUpdateBlockList[j++] = k7 - i1 + 32 + (l7 - j1 + 32 << 6) + (i8 + 1 - k1 + 32 << 12); ++ } + } + } + } + } +- } + +- this.profiler.endSection(); +- return true; ++ this.profiler.endSection(); ++ return true; ++ } + } + + /** Runs through the list of updates to run and ticks them */ +@@ -2384,10 +2605,10 @@ + /** Gets all entities within the specified AABB excluding the one passed into it. */ + public List getEntitiesInAABBexcluding(@Nullable Entity entityIn, AxisAlignedBB boundingBox, @Nullable Predicate predicate) { + List list = Lists.newArrayList(); +- int i = MathHelper.floor((boundingBox.minX - 2.0) / 16.0); +- int j = MathHelper.floor((boundingBox.maxX + 2.0) / 16.0); +- int k = MathHelper.floor((boundingBox.minZ - 2.0) / 16.0); +- int l = MathHelper.floor((boundingBox.maxZ + 2.0) / 16.0); ++ int i = MathHelper.floor((boundingBox.minX - MAX_ENTITY_RADIUS) / 16.0); ++ int j = MathHelper.floor((boundingBox.maxX + MAX_ENTITY_RADIUS) / 16.0); ++ int k = MathHelper.floor((boundingBox.minZ - MAX_ENTITY_RADIUS) / 16.0); ++ int l = MathHelper.floor((boundingBox.maxZ + MAX_ENTITY_RADIUS) / 16.0); + + for (int i1 = i; i1 <= j; i1++) { + for (int j1 = k; j1 <= l; j1++) { +@@ -2430,10 +2651,10 @@ + } + + public List getEntitiesWithinAABB(Class clazz, AxisAlignedBB aabb, @Nullable Predicate filter) { +- int i = MathHelper.floor((aabb.minX - 2.0) / 16.0); +- int j = MathHelper.ceil((aabb.maxX + 2.0) / 16.0); +- int k = MathHelper.floor((aabb.minZ - 2.0) / 16.0); +- int l = MathHelper.ceil((aabb.maxZ + 2.0) / 16.0); ++ int i = MathHelper.floor((aabb.minX - MAX_ENTITY_RADIUS) / 16.0); ++ int j = MathHelper.ceil((aabb.maxX + MAX_ENTITY_RADIUS) / 16.0); ++ int k = MathHelper.floor((aabb.minZ - MAX_ENTITY_RADIUS) / 16.0); ++ int l = MathHelper.ceil((aabb.maxZ + MAX_ENTITY_RADIUS) / 16.0); + List list = Lists.newArrayList(); + + for (int i1 = i; i1 < j; i1++) { +@@ -2499,10 +2720,11 @@ + } + + public void loadEntities(Collection entityCollection) { +- this.loadedEntityList.addAll(entityCollection); +- + for (Entity entity : entityCollection) { +- this.onEntityAdded(entity); ++ if (!net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.EntityJoinWorldEvent(entity, this))) { ++ loadedEntityList.add(entity); ++ this.onEntityAdded(entity); ++ } + } + } + +@@ -2514,7 +2736,9 @@ + public boolean mayPlace(Block blockIn, BlockPos pos, boolean skipCollisionCheck, EnumFacing sidePlacedOn, @Nullable Entity placer) { + IBlockState iblockstate = this.getBlockState(pos); + AxisAlignedBB axisalignedbb = skipCollisionCheck ? null : blockIn.getDefaultState().getCollisionBoundingBox(this, pos); +- if (axisalignedbb != Block.NULL_AABB && !this.checkNoEntityCollision(axisalignedbb.offset(pos), placer)) { ++ ++ if (!((placer instanceof EntityPlayer) || !net.minecraftforge.event.ForgeEventFactory.onBlockPlace(placer, new net.minecraftforge.common.util.BlockSnapshot(this, pos, blockIn.getDefaultState()), sidePlacedOn).isCanceled())) return false; ++ if (axisalignedbb != Block.NULL_AABB && !this.checkNoEntityCollision(axisalignedbb.offset(pos))) { // Forge: Remove second parameter, we patch placer to be non-null, passing it here skips collision checks for the placer + return false; + } else { + return iblockstate.getMaterial() == Material.CIRCUITS && blockIn == Blocks.ANVIL +@@ -2580,7 +2804,7 @@ + + public int getRedstonePower(BlockPos pos, EnumFacing facing) { + IBlockState iblockstate = this.getBlockState(pos); +- return iblockstate.isNormalCube() ? this.getStrongPower(pos) : iblockstate.getWeakPower(this, pos, facing); ++ return iblockstate.getBlock().shouldCheckWeakPower(iblockstate, this, pos, facing) ? this.getStrongPower(pos) : iblockstate.getWeakPower(this, pos, facing); + } + + public boolean isBlockPowered(BlockPos pos) { +@@ -2717,6 +2941,8 @@ + d2 *= MoreObjects.firstNonNull(playerToDouble.apply(entityplayer1), 1.0); + } + ++ d2 = net.minecraftforge.common.ForgeHooks.getPlayerVisibilityDistance(entityplayer1, d2, maxYDistance); ++ + if ((maxYDistance < 0.0 || Math.abs(entityplayer1.posY - posY) < maxYDistance * maxYDistance) + && (maxXZDistance < 0.0 || d1 < d2 * d2) + && (d0 == -1.0 || d1 < d0)) { +@@ -2771,7 +2997,7 @@ + + /** gets the random world seed */ + public long getSeed() { +- return this.worldInfo.getSeed(); ++ return this.provider.getSeed(); + } + + public long getTotalWorldTime() { +@@ -2779,17 +3005,18 @@ + } + + public long getWorldTime() { +- return this.worldInfo.getWorldTime(); ++ return this.provider.getWorldTime(); + } + + /** Sets the world time. */ + public void setWorldTime(long time) { +- this.worldInfo.setWorldTime(time); ++ this.provider.setWorldTime(time); + } + + /** Gets the spawn point in the world */ + public BlockPos getSpawnPoint() { +- BlockPos blockpos = new BlockPos(this.worldInfo.getSpawnX(), this.worldInfo.getSpawnY(), this.worldInfo.getSpawnZ()); ++ BlockPos blockpos = this.provider.getSpawnPoint(); ++ + if (!this.getWorldBorder().contains(blockpos)) { + blockpos = this.getHeight(new BlockPos(this.getWorldBorder().getCenterX(), 0.0, this.getWorldBorder().getCenterZ())); + } +@@ -2798,7 +3025,7 @@ + } + + public void setSpawnPoint(BlockPos pos) { +- this.worldInfo.setSpawn(pos); ++ this.provider.setSpawnPoint(pos); + } + + /** spwans an entity and loads surrounding chunks */ +@@ -2815,11 +3042,16 @@ + } + + if (!this.loadedEntityList.contains(entityIn)) { ++ if (!net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.EntityJoinWorldEvent(entityIn, this))) + this.loadedEntityList.add(entityIn); + } + } + + public boolean isBlockModifiable(EntityPlayer player, BlockPos pos) { ++ return this.provider.canMineBlock(player, pos); ++ } ++ ++ public boolean canMineBlockBody(EntityPlayer player, BlockPos pos) { + return true; + } + +@@ -2907,8 +3139,7 @@ + } + + public boolean isBlockinHighHumidity(BlockPos pos) { +- Biome biome = this.getBiome(pos); +- return biome.isHighHumidity(); ++ return this.provider.isBlockHighHumidity(pos); + } + + @Nullable +@@ -2960,12 +3191,12 @@ + + /** Returns maximum world height. */ + public int getHeight() { +- return 256; ++ return this.provider.getHeight(); + } + + /** Returns current world height. */ + public int getActualHeight() { +- return this.provider.isNether() ? 128 : 256; ++ return this.provider.getActualHeight(); + } + + /** puts the World Random seed to a specific state dependant on the inputs */ +@@ -2978,7 +3209,7 @@ + /** Returns horizon height for use in rendering the sky. */ + @SideOnly(Side.CLIENT) + public double getHorizon() { +- return this.worldInfo.getTerrainType() == WorldType.FLAT ? 0.0 : 63.0; ++ return provider.getHorizon(); + } + + /** Adds some basic stats of the world to the given crash report. */ +@@ -3032,17 +3263,18 @@ + } + + public void updateComparatorOutputLevel(BlockPos pos, Block blockIn) { +- for (EnumFacing enumfacing : EnumFacing.Plane.HORIZONTAL) { ++ for (EnumFacing enumfacing : EnumFacing.VALUES) { + BlockPos blockpos = pos.offset(enumfacing); + if (this.isBlockLoaded(blockpos)) { + IBlockState iblockstate = this.getBlockState(blockpos); +- if (Blocks.UNPOWERED_COMPARATOR.isSameDiode(iblockstate)) { +- iblockstate.neighborChanged(this, blockpos, blockIn, pos); +- } else if (iblockstate.isNormalCube()) { ++ ++ iblockstate.getBlock().onNeighborChange(this, blockpos, pos); ++ if (iblockstate.getBlock().isNormalCube(iblockstate, this, blockpos)) { + blockpos = blockpos.offset(enumfacing); + iblockstate = this.getBlockState(blockpos); +- if (Blocks.UNPOWERED_COMPARATOR.isSameDiode(iblockstate)) { +- iblockstate.neighborChanged(this, blockpos, blockIn, pos); ++ ++ if (iblockstate.getBlock().getWeakChanges(this, blockpos)) { ++ iblockstate.getBlock().onNeighborChange(this, blockpos, pos); + } + } + } +@@ -3098,6 +3330,107 @@ + return i >= -128 && i <= 128 && j >= -128 && j <= 128; + } + ++ /* ======================================== FORGE START =====================================*/ ++ /** ++ * Determine if the given block is considered solid on the ++ * specified side. Used by placement logic. ++ * ++ * @param pos Block Position ++ * @param side The Side in question ++ * @return True if the side is solid ++ */ ++ public boolean isSideSolid(BlockPos pos, EnumFacing side) { ++ return isSideSolid(pos, side, false); ++ } ++ ++ /** ++ * Determine if the given block is considered solid on the ++ * specified side. Used by placement logic. ++ * ++ * @param pos Block Position ++ * @param side The Side in question ++ * @param _default The default to return if the block doesn't exist. ++ * @return True if the side is solid ++ */ ++ @Override ++ public boolean isSideSolid(BlockPos pos, EnumFacing side, boolean _default) { ++ if (!this.isValid(pos)) return _default; ++ ++ Chunk chunk = getChunk(pos); ++ if (chunk == null || chunk.isEmpty()) return _default; ++ return getBlockState(pos).isSideSolid(this, pos, side); ++ } ++ ++ /** ++ * Get the persistent chunks for this world ++ * ++ * @return ++ */ ++ public com.google.common.collect.ImmutableSetMultimap getPersistentChunks() { ++ return net.minecraftforge.common.ForgeChunkManager.getPersistentChunksFor(this); ++ } ++ ++ public Iterator getPersistentChunkIterable(Iterator chunkIterator) { ++ return net.minecraftforge.common.ForgeChunkManager.getPersistentChunksIterableFor(this, chunkIterator); ++ } ++ /** ++ * Readded as it was removed, very useful helper function ++ * ++ * @param pos Block position ++ * @return The blocks light opacity ++ */ ++ public int getBlockLightOpacity(BlockPos pos) { ++ if (!this.isValid(pos)) return 0; ++ return getChunk(pos).getBlockLightOpacity(pos); ++ } ++ ++ /** ++ * Returns a count of entities that classify themselves as the specified creature type. ++ */ ++ public int countEntities(net.minecraft.entity.EnumCreatureType type, boolean forSpawnCount) { ++ int count = 0; ++ for (int x = 0; x < loadedEntityList.size(); x++) { ++ if (((Entity)loadedEntityList.get(x)).isCreatureType(type, forSpawnCount)) { ++ count++; ++ } ++ } ++ return count; ++ } ++ ++ @Deprecated // remove in 1.13 ++ public void markTileEntitiesInChunkForRemoval(Chunk chunk) { ++ for (TileEntity tileentity : chunk.getTileEntityMap().values()) { ++ markTileEntityForRemoval(tileentity); ++ } ++ } ++ ++ protected void initCapabilities() { ++ net.minecraftforge.common.capabilities.ICapabilityProvider parent = provider.initCapabilities(); ++ capabilities = net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(this, parent); ++ net.minecraftforge.common.util.WorldCapabilityData data = (net.minecraftforge.common.util.WorldCapabilityData)perWorldStorage.getOrLoadData(net.minecraftforge.common.util.WorldCapabilityData.class, net.minecraftforge.common.util.WorldCapabilityData.ID); ++ if (data == null) { ++ capabilityData = new net.minecraftforge.common.util.WorldCapabilityData(capabilities); ++ perWorldStorage.setData(capabilityData.mapName, capabilityData); ++ } else { ++ capabilityData = data; ++ capabilityData.setCapabilities(provider, capabilities); ++ } ++ } ++ @Override ++ public boolean hasCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable EnumFacing facing) { ++ return capabilities == null ? false : capabilities.hasCapability(capability, facing); ++ } ++ @Override ++ @Nullable ++ public T getCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable EnumFacing facing) { ++ return capabilities == null ? null : capabilities.getCapability(capability, facing); ++ } ++ ++ protected MapStorage perWorldStorage; //Moved to a getter to simulate final without being final so we can load in subclasses. ++ public MapStorage getPerWorldStorage() { ++ return perWorldStorage; ++ } ++ + public void sendPacketToServer(Packet packetIn) { + throw new UnsupportedOperationException("Can't send packets to server unless you're on the client."); + } diff --git a/module/minecraft/patches/net/minecraft/world/WorldEntitySpawner.java.patch b/module/minecraft/patches/net/minecraft/world/WorldEntitySpawner.java.patch new file mode 100644 index 000000000..bf04535f0 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/WorldEntitySpawner.java.patch @@ -0,0 +1,101 @@ +--- original/net/minecraft/world/WorldEntitySpawner.java ++++ modified/net/minecraft/world/WorldEntitySpawner.java +@@ -68,13 +68,15 @@ + if ((!enumcreaturetype.getPeacefulCreature() || spawnPeacefulMobs) + && (enumcreaturetype.getPeacefulCreature() || spawnHostileMobs) + && (!enumcreaturetype.getAnimal() || spawnOnSetTickRate)) { +- int k4 = worldServerIn.countEntities(enumcreaturetype.getCreatureClass()); ++ int k4 = worldServerIn.countEntities(enumcreaturetype, true); + int l4 = enumcreaturetype.getMaxNumberOfCreature() * i / MOB_COUNT_DIV; + if (k4 <= l4) { ++ java.util.ArrayList shuffled = com.google.common.collect.Lists.newArrayList(this.eligibleChunksForSpawning); ++ java.util.Collections.shuffle(shuffled); + BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos(); + + label134: +- for (ChunkPos chunkpos1 : this.eligibleChunksForSpawning) { ++ for (ChunkPos chunkpos1 : shuffled) { + BlockPos blockpos = getRandomChunkPosition(worldServerIn, chunkpos1.x, chunkpos1.z); + int k1 = blockpos.getX(); + int l1 = blockpos.getY(); +@@ -133,7 +135,7 @@ + entityliving.setDead(); + } + +- if (j2 >= entityliving.getMaxSpawnedInChunk()) { ++ if (j2 >= net.minecraftforge.event.ForgeEventFactory.getMaxSpawnPackSize(entityliving)) { + continue label134; + } + } +@@ -166,31 +168,42 @@ + return false; + } else if (state.canProvidePower()) { + return false; ++ } else if (state.getMaterial().isLiquid()) { ++ return false; + } else { +- return state.getMaterial().isLiquid() ? false : !BlockRailBase.isRailBlock(state); ++ return !BlockRailBase.isRailBlock(state); + } + } + + public static boolean canCreatureTypeSpawnAtLocation(EntityLiving.SpawnPlacementType spawnPlacementTypeIn, World worldIn, BlockPos pos) { + if (!worldIn.getWorldBorder().contains(pos)) { + return false; ++ } else { ++ return spawnPlacementTypeIn.canSpawnAt(worldIn, pos); + } ++ } + +- IBlockState iblockstate = worldIn.getBlockState(pos); +- if (spawnPlacementTypeIn == EntityLiving.SpawnPlacementType.IN_WATER) { +- return iblockstate.getMaterial() == Material.WATER +- && worldIn.getBlockState(pos.down()).getMaterial() == Material.WATER +- && !worldIn.getBlockState(pos.up()).isNormalCube(); +- } ++ public static boolean canCreatureTypeSpawnBody(EntityLiving.SpawnPlacementType spawnPlacementTypeIn, World worldIn, BlockPos pos) { ++ { ++ IBlockState iblockstate = worldIn.getBlockState(pos); + +- BlockPos blockpos = pos.down(); +- if (!worldIn.getBlockState(blockpos).isTopSolid()) { +- return false; +- } ++ if (spawnPlacementTypeIn == EntityLiving.SpawnPlacementType.IN_WATER) { ++ return iblockstate.getMaterial() == Material.WATER ++ && worldIn.getBlockState(pos.down()).getMaterial() == Material.WATER ++ && !worldIn.getBlockState(pos.up()).isNormalCube(); ++ } else { ++ BlockPos blockpos = pos.down(); ++ IBlockState state = worldIn.getBlockState(blockpos); + +- Block block = worldIn.getBlockState(blockpos).getBlock(); +- boolean flag = block != Blocks.BEDROCK && block != Blocks.BARRIER; +- return flag && isValidEmptySpawnBlock(iblockstate) && isValidEmptySpawnBlock(worldIn.getBlockState(pos.up())); ++ if (!state.getBlock().canCreatureSpawn(state, worldIn, blockpos, spawnPlacementTypeIn)) { ++ return false; ++ } else { ++ Block block = worldIn.getBlockState(blockpos).getBlock(); ++ boolean flag = block != Blocks.BEDROCK && block != Blocks.BARRIER; ++ return flag && isValidEmptySpawnBlock(iblockstate) && isValidEmptySpawnBlock(worldIn.getBlockState(pos.up())); ++ } ++ } ++ } + } + + /** +@@ -221,12 +234,13 @@ + if (canCreatureTypeSpawnAtLocation(EntityLiving.SpawnPlacementType.ON_GROUND, worldIn, blockpos)) { + EntityLiving entityliving; + try { +- entityliving = biome$spawnlistentry.entityClass.getConstructor(World.class).newInstance(worldIn); ++ entityliving = biome$spawnlistentry.newInstance(worldIn); + } catch (Exception exception) { + exception.printStackTrace(); + continue; + } + ++ if (net.minecraftforge.event.ForgeEventFactory.canEntitySpawn(entityliving, worldIn, j + 0.5f, (float) blockpos.getY(), k +0.5f, false) == net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) continue; + entityliving.setLocationAndAngles(j + 0.5F, blockpos.getY(), k + 0.5F, randomIn.nextFloat() * 360.0F, 0.0F); + worldIn.spawnEntity(entityliving); + ientitylivingdata = entityliving.onInitialSpawn(worldIn.getDifficultyForLocation(new BlockPos(entityliving)), ientitylivingdata); diff --git a/module/minecraft/patches/net/minecraft/world/WorldProvider.java.patch b/module/minecraft/patches/net/minecraft/world/WorldProvider.java.patch new file mode 100644 index 000000000..b72032b93 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/WorldProvider.java.patch @@ -0,0 +1,391 @@ +--- original/net/minecraft/world/WorldProvider.java ++++ modified/net/minecraft/world/WorldProvider.java +@@ -67,33 +67,11 @@ + */ + protected void init() { + this.hasSkyLight = true; +- WorldType worldtype = this.world.getWorldInfo().getTerrainType(); +- if (worldtype == WorldType.FLAT) { +- FlatGeneratorInfo flatgeneratorinfo = FlatGeneratorInfo.createFlatGeneratorFromString(this.world.getWorldInfo().getGeneratorOptions()); +- this.biomeProvider = new BiomeProviderSingle(Biome.getBiome(flatgeneratorinfo.getBiome(), Biomes.DEFAULT)); +- } else if (worldtype == WorldType.DEBUG_ALL_BLOCK_STATES) { +- this.biomeProvider = new BiomeProviderSingle(Biomes.PLAINS); +- } else { +- this.biomeProvider = new BiomeProvider(this.world.getWorldInfo()); +- } ++ this.biomeProvider = this.terrainType.getBiomeProvider(world); + } + + public IChunkGenerator createChunkGenerator() { +- if (this.terrainType == WorldType.FLAT) { +- return new ChunkGeneratorFlat( +- this.world, this.world.getSeed(), this.world.getWorldInfo().isMapFeaturesEnabled(), this.generatorSettings +- ); +- } else if (this.terrainType == WorldType.DEBUG_ALL_BLOCK_STATES) { +- return new ChunkGeneratorDebug(this.world); +- } else { +- return this.terrainType == WorldType.CUSTOMIZED +- ? new ChunkGeneratorOverworld( +- this.world, this.world.getSeed(), this.world.getWorldInfo().isMapFeaturesEnabled(), this.generatorSettings +- ) +- : new ChunkGeneratorOverworld( +- this.world, this.world.getSeed(), this.world.getWorldInfo().isMapFeaturesEnabled(), this.generatorSettings +- ); +- } ++ return this.terrainType.getChunkGenerator(world, generatorSettings); + } + + /** Will check if the x, z position specified is alright to be set as the map spawn point */ +@@ -173,7 +151,7 @@ + /** the y level at which clouds are rendered. */ + @SideOnly(Side.CLIENT) + public float getCloudHeight() { +- return 128.0F; ++ return this.terrainType.getCloudHeight(); + } + + @SideOnly(Side.CLIENT) +@@ -187,13 +165,13 @@ + } + + public int getAverageGroundLevel() { +- return this.terrainType == WorldType.FLAT ? 4 : this.world.getSeaLevel() + 1; ++ return this.terrainType.getMinimumSpawnHeight(this.world); + } + + /** Returns a double value representing the Y value relative to the top of the map at which void fog is at its maximum. The default factor of 0.03125 relative to 256, for example, means the void fog will be at its maximum at (256*0.03125), or 8. */ + @SideOnly(Side.CLIENT) + public double getVoidFogYFactor() { +- return this.terrainType == WorldType.FLAT ? 1.0 : 0.03125; ++ return this.terrainType.voidFadeMagnitude(); + } + + /** Returns true if the given X,Z coordinate should show environmental fog. */ +@@ -226,7 +204,326 @@ + return new WorldBorder(); + } + +- /** Called when a Player is added to the provider's world. */ ++ /*======================================= Forge Start =========================================*/ ++ private net.minecraftforge.client.IRenderHandler skyRenderer = null; ++ private net.minecraftforge.client.IRenderHandler cloudRenderer = null; ++ private net.minecraftforge.client.IRenderHandler weatherRenderer = null; ++ private int dimensionId; ++ ++ /** ++ * Sets the providers current dimension ID, used in default getSaveFolder() ++ * Added to allow default providers to be registered for multiple dimensions. ++ * This is to denote the exact dimension ID opposed to the 'type' in WorldType ++ * ++ * @param dim Dimension ID ++ */ ++ public void setDimension(int dim) { ++ this.dimensionId = dim; ++ } ++ public int getDimension() { ++ return this.dimensionId; ++ } ++ ++ /** ++ * Returns the sub-folder of the world folder that this WorldProvider saves to. ++ * EXA: DIM1, DIM-1 ++ * @return The sub-folder name to save this world's chunks to. ++ */ ++ @Nullable ++ public String getSaveFolder() { ++ return (dimensionId == 0 ? null : "DIM" + dimensionId); ++ } ++ ++ /** ++ * The dimension's movement factor. ++ * Whenever a player or entity changes dimension from world A to world B, their coordinates are multiplied by ++ * worldA.provider.getMovementFactor() / worldB.provider.getMovementFactor() ++ * Example: Overworld factor is 1, nether factor is 8. Traveling from overworld to nether multiplies coordinates by 1/8. ++ * @return The movement factor ++ */ ++ public double getMovementFactor() { ++ if (this instanceof WorldProviderHell) { ++ return 8.0; ++ } ++ return 1.0; ++ } ++ ++ /** ++ * If this method returns true, then chunks received by the client will ++ * have {@link net.minecraft.world.chunk.Chunk#resetRelightChecks} called ++ * on them, queuing lighting checks for all air blocks in the chunk (and ++ * any adjacent light-emitting blocks). ++ * ++ * Returning true here is recommended if the chunk generator used also ++ * does this for newly generated chunks. ++ * ++ * @return true if lighting checks should be performed ++ */ ++ public boolean shouldClientCheckLighting() { ++ return !(this instanceof WorldProviderSurface); ++ } ++ ++ @Nullable ++ @SideOnly(Side.CLIENT) ++ public net.minecraftforge.client.IRenderHandler getSkyRenderer() { ++ return this.skyRenderer; ++ } ++ ++ @SideOnly(Side.CLIENT) ++ public void setSkyRenderer(net.minecraftforge.client.IRenderHandler skyRenderer) { ++ this.skyRenderer = skyRenderer; ++ } ++ ++ @Nullable ++ @SideOnly(Side.CLIENT) ++ public net.minecraftforge.client.IRenderHandler getCloudRenderer() { ++ return cloudRenderer; ++ } ++ ++ @SideOnly(Side.CLIENT) ++ public void setCloudRenderer(net.minecraftforge.client.IRenderHandler renderer) { ++ cloudRenderer = renderer; ++ } ++ ++ @Nullable ++ @SideOnly(Side.CLIENT) ++ public net.minecraftforge.client.IRenderHandler getWeatherRenderer() { ++ return weatherRenderer; ++ } ++ ++ @SideOnly(Side.CLIENT) ++ public void setWeatherRenderer(net.minecraftforge.client.IRenderHandler renderer) { ++ weatherRenderer = renderer; ++ } ++ ++ /** ++ * Allows for manipulating the coloring of the lightmap texture. ++ * Will be called for each 16*16 combination of sky/block light values. ++ * ++ * @param partialTicks Progress between ticks. ++ * @param sunBrightness Current sun brightness. ++ * @param skyLight Sky light brightness factor. ++ * @param blockLight Block light brightness factor. ++ * @param colors The color values that will be used: [r, g, b]. ++ * ++ * @see net.minecraft.client.renderer.EntityRenderer#updateLightmap(float) ++ */ ++ public void getLightmapColors(float partialTicks, float sunBrightness, float skyLight, float blockLight, float[] colors) {} ++ ++ public BlockPos getRandomizedSpawnPoint() { ++ BlockPos ret = this.world.getSpawnPoint(); ++ ++ boolean isAdventure = world.getWorldInfo().getGameType() == GameType.ADVENTURE; ++ int spawnFuzz = this.world instanceof WorldServer ? terrainType.getSpawnFuzz((WorldServer)this.world, this.world.getMinecraftServer()) : 1; ++ int border = MathHelper.floor(world.getWorldBorder().getClosestDistance(ret.getX(), ret.getZ())); ++ if (border < spawnFuzz) spawnFuzz = border; ++ ++ if (!isNether() && !isAdventure && spawnFuzz != 0) { ++ if (spawnFuzz < 2) spawnFuzz = 2; ++ int spawnFuzzHalf = spawnFuzz / 2; ++ ret = world.getTopSolidOrLiquidBlock(ret.add(spawnFuzzHalf - world.rand.nextInt(spawnFuzz), 0, spawnFuzzHalf - world.rand.nextInt(spawnFuzz))); ++ } ++ ++ return ret; ++ } ++ /** ++ * Determine if the cursor on the map should 'spin' when rendered, like it does for the player in the nether. ++ * ++ * @param entity The entity holding the map, playername, or frame-ENTITYID ++ * @param x X Position ++ * @param z Z Position ++ * @param rotation the regular rotation of the marker ++ * @return True to 'spin' the cursor ++ */ ++ public boolean shouldMapSpin(String entity, double x, double z, double rotation) { ++ return dimensionId < 0; ++ } ++ ++ /** ++ * Determines the dimension the player will be respawned in, typically this brings them back to the overworld. ++ * ++ * @param player The player that is respawning ++ * @return The dimension to respawn the player in ++ */ ++ public int getRespawnDimension(net.minecraft.entity.player.EntityPlayerMP player) { ++ return player.getSpawnDimension(); ++ } ++ ++ /** ++ * Called from {@link World#initCapabilities()}, to gather capabilities for this world. ++ * It's safe to access world here since this is called after world is registered. ++ * ++ * On server, called directly after mapStorage and world data such as Scoreboard and VillageCollection are initialized. ++ * On client, called when world is constructed, just before world load event is called. ++ * Note that this method is always called before the world load event. ++ * @return initial holder for capabilities on the world ++ */ ++ @Nullable ++ public net.minecraftforge.common.capabilities.ICapabilityProvider initCapabilities() { ++ return null; ++ } ++ ++ /** ++ * Called on the client to get the music type to play when in this world type. ++ * At the time of calling, the client player and world are guaranteed to be non-null ++ * @return null to use vanilla logic, otherwise a MusicType to play in this world ++ */ ++ @Nullable ++ @SideOnly(Side.CLIENT) ++ public net.minecraft.client.audio.MusicTicker.MusicType getMusicType() { ++ return null; ++ } ++ ++ /** ++ * Determines if the player can sleep in this world (or if the bed should explode for example). ++ * ++ * @param player The player that is attempting to sleep ++ * @param pos The location where the player tries to sleep at (the position of the clicked on bed for example) ++ * @return the result of a player trying to sleep at the given location ++ */ ++ public WorldSleepResult canSleepAt(net.minecraft.entity.player.EntityPlayer player, BlockPos pos) { ++ return (this.canRespawnHere() && this.world.getBiome(pos) != net.minecraft.init.Biomes.HELL) ? WorldSleepResult.ALLOW : WorldSleepResult.BED_EXPLODES; ++ } ++ ++ public static enum WorldSleepResult { ++ ALLOW, ++ DENY, ++ BED_EXPLODES; ++ } ++ ++ /*======================================= Start Moved From World =========================================*/ ++ ++ public Biome getBiomeForCoords(BlockPos pos) { ++ return world.getBiomeForCoordsBody(pos); ++ } ++ ++ public boolean isDaytime() { ++ return world.getSkylightSubtracted() < 4; ++ } ++ ++ /** ++ * The current sun brightness factor for this dimension. ++ * 0.0f means no light at all, and 1.0f means maximum sunlight. ++ * This will be used for the "calculateSkylightSubtracted" ++ * which is for Sky light value calculation. ++ * ++ * @return The current brightness factor ++ * */ ++ public float getSunBrightnessFactor(float par1) { ++ return world.getSunBrightnessFactor(par1); ++ } ++ ++ /** ++ * Calculates the current moon phase factor. ++ * This factor is effective for slimes. ++ * (This method do not affect the moon rendering) ++ * */ ++ public float getCurrentMoonPhaseFactor() { ++ return world.getCurrentMoonPhaseFactorBody(); ++ } ++ ++ @SideOnly(Side.CLIENT) ++ public Vec3d getSkyColor(net.minecraft.entity.Entity cameraEntity, float partialTicks) { ++ return world.getSkyColorBody(cameraEntity, partialTicks); ++ } ++ ++ @SideOnly(Side.CLIENT) ++ public Vec3d getCloudColor(float partialTicks) { ++ return world.getCloudColorBody(partialTicks); ++ } ++ ++ /** ++ * Gets the Sun Brightness for rendering sky. ++ * */ ++ @SideOnly(Side.CLIENT) ++ public float getSunBrightness(float par1) { ++ return world.getSunBrightnessBody(par1); ++ } ++ ++ /** ++ * Gets the Star Brightness for rendering sky. ++ * */ ++ @SideOnly(Side.CLIENT) ++ public float getStarBrightness(float par1) { ++ return world.getStarBrightnessBody(par1); ++ } ++ ++ public void setAllowedSpawnTypes(boolean allowHostile, boolean allowPeaceful) { ++ world.spawnHostileMobs = allowHostile; ++ world.spawnPeacefulMobs = allowPeaceful; ++ } ++ ++ public void calculateInitialWeather() { ++ world.calculateInitialWeatherBody(); ++ } ++ ++ public void updateWeather() { ++ world.updateWeatherBody(); ++ } ++ ++ public boolean canBlockFreeze(BlockPos pos, boolean byWater) { ++ return world.canBlockFreezeBody(pos, byWater); ++ } ++ ++ public boolean canSnowAt(BlockPos pos, boolean checkLight) { ++ return world.canSnowAtBody(pos, checkLight); ++ } ++ public void setWorldTime(long time) { ++ world.worldInfo.setWorldTime(time); ++ } ++ ++ public long getSeed() { ++ return world.worldInfo.getSeed(); ++ } ++ ++ public long getWorldTime() { ++ return world.worldInfo.getWorldTime(); ++ } ++ ++ public BlockPos getSpawnPoint() { ++ net.minecraft.world.storage.WorldInfo info = world.worldInfo; ++ return new BlockPos(info.getSpawnX(), info.getSpawnY(), info.getSpawnZ()); ++ } ++ ++ public void setSpawnPoint(BlockPos pos) { ++ world.worldInfo.setSpawn(pos); ++ } ++ ++ public boolean canMineBlock(net.minecraft.entity.player.EntityPlayer player, BlockPos pos) { ++ return world.canMineBlockBody(player, pos); ++ } ++ ++ public boolean isBlockHighHumidity(BlockPos pos) { ++ return world.getBiome(pos).isHighHumidity(); ++ } ++ ++ public int getHeight() { ++ return 256; ++ } ++ ++ public int getActualHeight() { ++ return nether ? 128 : 256; ++ } ++ ++ public double getHorizon() { ++ return world.worldInfo.getTerrainType().getHorizon(world); ++ } ++ ++ public void resetRainAndThunder() { ++ world.worldInfo.setRainTime(0); ++ world.worldInfo.setRaining(false); ++ world.worldInfo.setThunderTime(0); ++ world.worldInfo.setThundering(false); ++ } ++ ++ public boolean canDoLightning(net.minecraft.world.chunk.Chunk chunk) { ++ return true; ++ } ++ ++ public boolean canDoRainSnowIce(net.minecraft.world.chunk.Chunk chunk) { ++ return true; ++ } ++ + public void onPlayerAdded(EntityPlayerMP player) { + } + diff --git a/module/minecraft/patches/net/minecraft/world/WorldProviderEnd.java.patch b/module/minecraft/patches/net/minecraft/world/WorldProviderEnd.java.patch new file mode 100644 index 000000000..543c9dde6 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/WorldProviderEnd.java.patch @@ -0,0 +1,39 @@ +--- original/net/minecraft/world/WorldProviderEnd.java ++++ modified/net/minecraft/world/WorldProviderEnd.java +@@ -24,7 +24,7 @@ + @Override + public void init() { + this.biomeProvider = new BiomeProviderSingle(Biomes.SKY); +- NBTTagCompound nbttagcompound = this.world.getWorldInfo().getDimensionData(DimensionType.THE_END); ++ NBTTagCompound nbttagcompound = this.world.getWorldInfo().getDimensionData(this.world.provider.getDimension()); + this.dragonFightManager = this.world instanceof WorldServer + ? new DragonFightManager((WorldServer)this.world, nbttagcompound.getCompoundTag("DragonFight")) + : null; +@@ -128,7 +128,7 @@ + nbttagcompound.setTag("DragonFight", this.dragonFightManager.getCompound()); + } + +- this.world.getWorldInfo().setDimensionData(DimensionType.THE_END, nbttagcompound); ++ this.world.getWorldInfo().setDimensionData(this.world.provider.getDimension(), nbttagcompound); + } + + /** Called when the world is updating entities. Only used in WorldProviderEnd to update the DragonFightManager in Vanilla. */ +@@ -143,4 +143,18 @@ + public DragonFightManager getDragonFightManager() { + return this.dragonFightManager; + } ++ ++ @Override ++ public void onPlayerAdded(net.minecraft.entity.player.EntityPlayerMP player) { ++ if (this.dragonFightManager != null) { ++ this.dragonFightManager.addPlayer(player); ++ } ++ } ++ ++ @Override ++ public void onPlayerRemoved(net.minecraft.entity.player.EntityPlayerMP player) { ++ if (this.dragonFightManager != null) { ++ this.dragonFightManager.removePlayer(player); ++ } ++ } + } diff --git a/module/minecraft/patches/net/minecraft/world/WorldProviderSurface.java.patch b/module/minecraft/patches/net/minecraft/world/WorldProviderSurface.java.patch new file mode 100644 index 000000000..c64b866ba --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/WorldProviderSurface.java.patch @@ -0,0 +1,10 @@ +--- original/net/minecraft/world/WorldProviderSurface.java ++++ modified/net/minecraft/world/WorldProviderSurface.java +@@ -9,6 +9,6 @@ + /** Called to determine if the chunk at the given chunk coordinates within the provider's world can be dropped. Used in WorldProviderSurface to prevent spawn chunks from being unloaded. */ + @Override + public boolean canDropChunk(int x, int z) { +- return !this.world.isSpawnChunk(x, z); ++ return !this.world.isSpawnChunk(x, z) || !this.world.provider.getDimensionType().shouldLoadSpawn(); + } + } diff --git a/module/minecraft/patches/net/minecraft/world/WorldServer.java.patch b/module/minecraft/patches/net/minecraft/world/WorldServer.java.patch new file mode 100644 index 000000000..b11680bd8 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/WorldServer.java.patch @@ -0,0 +1,339 @@ +--- original/net/minecraft/world/WorldServer.java ++++ modified/net/minecraft/world/WorldServer.java +@@ -107,27 +107,37 @@ + private int blockEventCacheIndex; + private final List pendingTickListEntriesThisTick = Lists.newArrayList(); + ++ /** Stores the recently processed (lighting) chunks */ ++ protected Set doneChunks = new java.util.HashSet<>(); ++ public List customTeleporters = new ArrayList<>(); ++ + public WorldServer(MinecraftServer server, ISaveHandler saveHandlerIn, WorldInfo info, int dimensionId, Profiler profilerIn) { +- super(saveHandlerIn, info, DimensionType.getById(dimensionId).createDimension(), profilerIn, false); ++ super(saveHandlerIn, info, net.minecraftforge.common.DimensionManager.createProviderFor(dimensionId), profilerIn, false); + this.server = server; + this.entityTracker = new EntityTracker(this); + this.playerChunkMap = new PlayerChunkMap(this); ++ // Guarantee the dimension ID was not reset by the provider ++ int providerDim = this.provider.getDimension(); + this.provider.setWorld(this); ++ this.provider.setDimension(providerDim); + this.chunkProvider = this.createChunkProvider(); ++ perWorldStorage = new MapStorage(new net.minecraftforge.common.WorldSpecificSaveHandler(this, saveHandlerIn)); + this.worldTeleporter = new Teleporter(this); + this.calculateInitialSkylight(); + this.calculateInitialWeather(); + this.getWorldBorder().setSize(server.getMaxWorldSize()); ++ net.minecraftforge.common.DimensionManager.setWorld(dimensionId, this, server); + } + + @Override + public World init() { + this.mapStorage = new MapStorage(this.saveHandler); + String s = VillageCollection.fileNameForProvider(this.provider); +- VillageCollection villagecollection = (VillageCollection)this.mapStorage.getOrLoadData(VillageCollection.class, s); ++ VillageCollection villagecollection = (VillageCollection)this.perWorldStorage.getOrLoadData(VillageCollection.class, s); ++ + if (villagecollection == null) { + this.villageCollection = new VillageCollection(this); +- this.mapStorage.setData(s, this.villageCollection); ++ this.perWorldStorage.setData(s, this.villageCollection); + } else { + this.villageCollection = villagecollection; + this.villageCollection.setWorldsForAll(this); +@@ -156,6 +166,7 @@ + this.getWorldBorder().setTransition(this.worldInfo.getBorderSize()); + } + ++ this.initCapabilities(); + return this; + } + +@@ -170,8 +181,8 @@ + this.provider.getBiomeProvider().cleanupCache(); + if (this.areAllPlayersAsleep()) { + if (this.getGameRules().getBoolean("doDaylightCycle")) { +- long i = this.worldInfo.getWorldTime() + 24000L; +- this.worldInfo.setWorldTime(i - i % 24000L); ++ long i = this.getWorldTime() + 24000L; ++ this.setWorldTime(i - i % 24000L); + } + + this.wakeAllPlayers(); +@@ -191,7 +202,7 @@ + + this.worldInfo.setWorldTotalTime(this.worldInfo.getWorldTotalTime() + 1L); + if (this.getGameRules().getBoolean("doDaylightCycle")) { +- this.worldInfo.setWorldTime(this.worldInfo.getWorldTime() + 1L); ++ this.setWorldTime(this.getWorldTime() + 1L); + } + + this.profiler.endStartSection("tickPending"); +@@ -205,6 +216,9 @@ + this.villageSiege.tick(); + this.profiler.endStartSection("portalForcer"); + this.worldTeleporter.removeStalePortalLocations(this.getTotalWorldTime()); ++ for (Teleporter tele : customTeleporters) { ++ tele.removeStalePortalLocations(getTotalWorldTime()); ++ } + this.profiler.endSection(); + this.sendQueuedBlockEvents(); + } +@@ -212,11 +226,13 @@ + @Nullable + public Biome.SpawnListEntry getSpawnListEntryForTypeAt(EnumCreatureType creatureType, BlockPos pos) { + List list = this.getChunkProvider().getPossibleCreatures(creatureType, pos); ++ list = net.minecraftforge.event.ForgeEventFactory.getPotentialSpawns(this, creatureType, pos, list); + return list != null && !list.isEmpty() ? WeightedRandom.getRandomItem(this.rand, list) : null; + } + + public boolean canCreatureTypeSpawnHere(EnumCreatureType creatureType, Biome.SpawnListEntry spawnListEntry, BlockPos pos) { + List list = this.getChunkProvider().getPossibleCreatures(creatureType, pos); ++ list = net.minecraftforge.event.ForgeEventFactory.getPotentialSpawns(this, creatureType, pos, list); + return list != null && !list.isEmpty() ? list.contains(spawnListEntry) : false; + } + +@@ -254,10 +270,7 @@ + + /** Clears the current rain and thunder weather states. */ + private void resetRainAndThunder() { +- this.worldInfo.setRainTime(0); +- this.worldInfo.setRaining(false); +- this.worldInfo.setThunderTime(0); +- this.worldInfo.setThundering(false); ++ this.provider.resetRainAndThunder(); + } + + /** Checks if all players in this world are sleeping. */ +@@ -333,7 +346,7 @@ + boolean flag1 = this.isThundering(); + this.profiler.startSection("pollingChunks"); + +- for (Iterator iterator = this.playerChunkMap.getChunkIterator(); iterator.hasNext(); this.profiler.endSection()) { ++ for (Iterator iterator = getPersistentChunkIterable(this.playerChunkMap.getChunkIterator()); iterator.hasNext(); this.profiler.endSection()) { + this.profiler.startSection("getChunk"); + Chunk chunk = iterator.next(); + int j = chunk.x * 16; +@@ -343,7 +356,8 @@ + this.profiler.endStartSection("tickChunk"); + chunk.onTick(false); + this.profiler.endStartSection("thunder"); +- if (flag && flag1 && this.rand.nextInt(100000) == 0) { ++ ++ if (this.provider.canDoLightning(chunk) && flag && flag1 && this.rand.nextInt(100000) == 0) { + this.updateLCG = this.updateLCG * 3 + 1013904223; + int l = this.updateLCG >> 2; + BlockPos blockpos = this.adjustPosToNearbyEntity(new BlockPos(j + (l & 15), 0, k + (l >> 8 & 15))); +@@ -365,11 +379,14 @@ + } + + this.profiler.endStartSection("iceandsnow"); +- if (this.rand.nextInt(16) == 0) { ++ ++ if (this.provider.canDoRainSnowIce(chunk) && this.rand.nextInt(16) == 0) { + this.updateLCG = this.updateLCG * 3 + 1013904223; + int j2 = this.updateLCG >> 2; + BlockPos blockpos1 = this.getPrecipitationHeight(new BlockPos(j + (j2 & 15), 0, k + (j2 >> 8 & 15))); + BlockPos blockpos2 = blockpos1.down(); ++ ++ if (this.isAreaLoaded(blockpos2, 1)) // Forge: check area to avoid loading neighbors in unloaded chunks + if (this.canBlockFreezeNoWater(blockpos2)) { + this.setBlockState(blockpos2, Blocks.ICE.getDefaultState()); + } +@@ -456,7 +473,10 @@ + Material material = blockIn.getDefaultState().getMaterial(); + if (this.scheduledUpdatesAreImmediate && material != Material.AIR) { + if (blockIn.requiresUpdates()) { +- if (this.isAreaLoaded(pos.add(-8, -8, -8), pos.add(8, 8, 8))) { ++ //Keeping here as a note for future when it may be restored. ++ boolean isForced = getPersistentChunks().containsKey(new ChunkPos(pos)); ++ int range = isForced ? 0 : 8; ++ if (this.isAreaLoaded(pos.add(-range, -range, -range), pos.add(range, range, range))) { + IBlockState iblockstate = this.getBlockState(pos); + if (iblockstate.getMaterial() != Material.AIR && iblockstate.getBlock() == blockIn) { + iblockstate.getBlock().updateTick(this, pos, iblockstate, this.rand); +@@ -486,6 +506,7 @@ + /** Called by CommandClone and AnvilChunkLoader to force a block update. */ + @Override + public void scheduleBlockUpdate(BlockPos pos, Block blockIn, int delay, int priority) { ++ if (blockIn == null) return; //Forge: Prevent null blocks from ticking, can happen if blocks are removed in old worlds. TODO: Fix real issue causing block to be null. + NextTickListEntry nextticklistentry = new NextTickListEntry(pos, blockIn); + nextticklistentry.setPriority(priority); + Material material = blockIn.getDefaultState().getMaterial(); +@@ -502,7 +523,7 @@ + /** Updates (and cleans up) entities and tile entities */ + @Override + public void updateEntities() { +- if (this.playerEntities.isEmpty()) { ++ if (this.playerEntities.isEmpty() && getPersistentChunks().isEmpty()) { + if (this.updateEntityTick++ >= 300) { + return; + } +@@ -600,6 +621,9 @@ + while (iterator.hasNext()) { + NextTickListEntry nextticklistentry1 = iterator.next(); + iterator.remove(); ++ //Keeping here as a note for future when it may be restored. ++ //boolean isForced = getPersistentChunks().containsKey(new ChunkPos(nextticklistentry.xCoord >> 4, nextticklistentry.zCoord >> 4)); ++ //byte b0 = isForced ? 0 : 8; + int k = 0; + if (this.isAreaLoaded(nextticklistentry1.position.add(0, 0, 0), nextticklistentry1.position.add(0, 0, 0))) { + IBlockState iblockstate = this.getBlockState(nextticklistentry1.position); +@@ -706,6 +730,9 @@ + + @Override + public boolean isBlockModifiable(EntityPlayer player, BlockPos pos) { ++ return super.isBlockModifiable(player, pos); ++ } ++ public boolean canMineBlockBody(EntityPlayer player, BlockPos pos) { + return !this.server.isBlockProtected(this, pos, player) && this.getWorldBorder().contains(pos); + } + +@@ -755,6 +782,7 @@ + } else if (this.worldInfo.getTerrainType() == WorldType.DEBUG_ALL_BLOCK_STATES) { + this.worldInfo.setSpawn(BlockPos.ORIGIN.up()); + } else { ++ if (net.minecraftforge.event.ForgeEventFactory.onCreateWorldSpawn(this, settings)) return; + this.findingSpawnPoint = true; + BiomeProvider biomeprovider = this.provider.getBiomeProvider(); + List list = biomeprovider.getBiomesToSpawnIn(); +@@ -822,6 +850,7 @@ + } + + chunkproviderserver.saveChunks(all); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.WorldEvent.Save(this)); + + for (Chunk chunk : Lists.newArrayList(chunkproviderserver.getLoadedChunks())) { + if (chunk != null && !this.playerChunkMap.contains(chunk.x, chunk.z)) { +@@ -860,6 +889,7 @@ + this.worldInfo.setBorderLerpTime(this.getWorldBorder().getTimeUntilTarget()); + this.saveHandler.saveWorldInfoWithPlayer(this.worldInfo, this.server.getPlayerList().getHostPlayerData()); + this.mapStorage.saveAllData(); ++ this.perWorldStorage.saveAllData(); + } + + /** Called when an entity is spawned in the world. This includes players. */ +@@ -871,7 +901,7 @@ + @Override + public void loadEntities(Collection entityCollection) { + for (Entity entity : Lists.newArrayList(entityCollection)) { +- if (this.canAddEntity(entity)) { ++ if (this.canAddEntity(entity) && !net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.EntityJoinWorldEvent(entity, this))) { + this.loadedEntityList.add(entity); + this.onEntityAdded(entity); + } +@@ -935,16 +965,16 @@ + public boolean addWeatherEffect(Entity entityIn) { + if (super.addWeatherEffect(entityIn)) { + this.server +- .getPlayerList() +- .sendToAllNearExcept( +- null, +- entityIn.posX, +- entityIn.posY, +- entityIn.posZ, +- 512.0, +- this.provider.getDimensionType().getId(), +- new SPacketSpawnGlobalEntity(entityIn) +- ); ++ .getPlayerList() ++ .sendToAllNearExcept( ++ null, ++ entityIn.posX, ++ entityIn.posY, ++ entityIn.posZ, ++ 512.0, ++ this.provider.getDimension(), ++ new SPacketSpawnGlobalEntity(entityIn) ++ ); + return true; + } else { + return false; +@@ -968,6 +998,7 @@ + @Nullable Entity entityIn, double x, double y, double z, float strength, boolean causesFire, boolean damagesTerrain + ) { + Explosion explosion = new Explosion(this, entityIn, x, y, z, strength, causesFire, damagesTerrain); ++ if (net.minecraftforge.event.ForgeEventFactory.onExplosionStart(this, explosion)) return explosion; + explosion.doExplosionA(); + explosion.doExplosionB(false); + if (!damagesTerrain) { +@@ -1010,18 +1041,18 @@ + for (BlockEventData blockeventdata : this.blockEventQueue[i]) { + if (this.fireBlockEvent(blockeventdata)) { + this.server +- .getPlayerList() +- .sendToAllNearExcept( +- null, +- blockeventdata.getPosition().getX(), +- blockeventdata.getPosition().getY(), +- blockeventdata.getPosition().getZ(), +- 64.0, +- this.provider.getDimensionType().getId(), +- new SPacketBlockAction( +- blockeventdata.getPosition(), blockeventdata.getBlock(), blockeventdata.getEventID(), blockeventdata.getEventParameter() +- ) +- ); ++ .getPlayerList() ++ .sendToAllNearExcept( ++ null, ++ blockeventdata.getPosition().getX(), ++ blockeventdata.getPosition().getY(), ++ blockeventdata.getPosition().getZ(), ++ 64.0, ++ this.provider.getDimension(), ++ new SPacketBlockAction( ++ blockeventdata.getPosition(), blockeventdata.getBlock(), blockeventdata.getEventID(), blockeventdata.getEventParameter() ++ ) ++ ); + } + } + +@@ -1048,25 +1079,29 @@ + super.updateWeather(); + if (this.prevRainingStrength != this.rainingStrength) { + this.server +- .getPlayerList() +- .sendPacketToAllPlayersInDimension(new SPacketChangeGameState(7, this.rainingStrength), this.provider.getDimensionType().getId()); ++ .getPlayerList() ++ .sendPacketToAllPlayersInDimension(new SPacketChangeGameState(7, this.rainingStrength), this.provider.getDimension()); + } + + if (this.prevThunderingStrength != this.thunderingStrength) { + this.server +- .getPlayerList() +- .sendPacketToAllPlayersInDimension(new SPacketChangeGameState(8, this.thunderingStrength), this.provider.getDimensionType().getId()); ++ .getPlayerList() ++ .sendPacketToAllPlayersInDimension(new SPacketChangeGameState(8, this.thunderingStrength), this.provider.getDimension()); + } + ++ /* The function in use here has been replaced in order to only send the weather info to players in the correct dimension, ++ * rather than to all players on the server. This is what causes the client-side rain, as the ++ * client believes that it has started raining locally, rather than in another dimension. ++ */ + if (flag != this.isRaining()) { + if (flag) { +- this.server.getPlayerList().sendPacketToAllPlayers(new SPacketChangeGameState(2, 0.0F)); ++ this.server.getPlayerList().sendPacketToAllPlayersInDimension(new SPacketChangeGameState(2, 0.0F), this.provider.getDimension()); + } else { +- this.server.getPlayerList().sendPacketToAllPlayers(new SPacketChangeGameState(1, 0.0F)); ++ this.server.getPlayerList().sendPacketToAllPlayersInDimension(new SPacketChangeGameState(1, 0.0F), this.provider.getDimension()); + } + +- this.server.getPlayerList().sendPacketToAllPlayers(new SPacketChangeGameState(7, this.rainingStrength)); +- this.server.getPlayerList().sendPacketToAllPlayers(new SPacketChangeGameState(8, this.thunderingStrength)); ++ this.server.getPlayerList().sendPacketToAllPlayersInDimension(new SPacketChangeGameState(7, this.rainingStrength), this.provider.getDimension()); ++ this.server.getPlayerList().sendPacketToAllPlayersInDimension(new SPacketChangeGameState(8, this.thunderingStrength), this.provider.getDimension()); + } + } + +@@ -1215,6 +1250,10 @@ + return this.functionManager; + } + ++ public java.io.File getChunkSaveLocation() { ++ return ((net.minecraft.world.chunk.storage.AnvilChunkLoader)getChunkProvider().chunkLoader).chunkSaveLocation; ++ } ++ + static class ServerBlockEventList extends ArrayList { + private ServerBlockEventList() { + } diff --git a/module/minecraft/patches/net/minecraft/world/WorldServerMulti.java.patch b/module/minecraft/patches/net/minecraft/world/WorldServerMulti.java.patch new file mode 100644 index 000000000..c9fba38aa --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/WorldServerMulti.java.patch @@ -0,0 +1,63 @@ +--- original/net/minecraft/world/WorldServerMulti.java ++++ modified/net/minecraft/world/WorldServerMulti.java +@@ -10,11 +10,12 @@ + + public class WorldServerMulti extends WorldServer { + private final WorldServer delegate; ++ private IBorderListener borderListener; + + public WorldServerMulti(MinecraftServer server, ISaveHandler saveHandlerIn, int dimensionId, WorldServer delegate, Profiler profilerIn) { + super(server, saveHandlerIn, new DerivedWorldInfo(delegate.getWorldInfo()), dimensionId, profilerIn); + this.delegate = delegate; +- delegate.getWorldBorder().addListener(new IBorderListener() { ++ this.borderListener = new IBorderListener() { + @Override + public void onSizeChanged(WorldBorder border, double newSize) { + WorldServerMulti.this.getWorldBorder().setTransition(newSize); +@@ -49,12 +50,14 @@ + public void onDamageBufferChanged(WorldBorder border, double newSize) { + WorldServerMulti.this.getWorldBorder().setDamageBuffer(newSize); + } +- }); ++ }; ++ this.delegate.getWorldBorder().addListener(this.borderListener); + } + + /** Saves the chunks to disk. */ + @Override + protected void saveLevel() throws MinecraftException { ++ this.perWorldStorage.saveAllData(); + } + + @Override +@@ -64,19 +67,27 @@ + this.lootTable = this.delegate.getLootTableManager(); + this.advancementManager = this.delegate.getAdvancementManager(); + String s = VillageCollection.fileNameForProvider(this.provider); +- VillageCollection villagecollection = (VillageCollection)this.mapStorage.getOrLoadData(VillageCollection.class, s); ++ VillageCollection villagecollection = (VillageCollection)this.perWorldStorage.getOrLoadData(VillageCollection.class, s); ++ + if (villagecollection == null) { + this.villageCollection = new VillageCollection(this); +- this.mapStorage.setData(s, this.villageCollection); ++ this.perWorldStorage.setData(s, this.villageCollection); + } else { + this.villageCollection = villagecollection; + this.villageCollection.setWorldsForAll(this); + } + ++ this.initCapabilities(); + return this; + } + +- /** Called during saving of a world to give children worlds a chance to save additional data. Only used to save WorldProviderEnd's data in Vanilla. */ ++ ++ @Override ++ public void flush() { ++ super.flush(); ++ this.delegate.getWorldBorder().removeListener(this.borderListener); // Unlink ourselves, to prevent world leak. ++ } ++ + public void saveAdditionalData() { + this.provider.onWorldSave(); + } diff --git a/module/minecraft/patches/net/minecraft/world/WorldType.java.patch b/module/minecraft/patches/net/minecraft/world/WorldType.java.patch new file mode 100644 index 000000000..9a4fb86b5 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/WorldType.java.patch @@ -0,0 +1,133 @@ +--- original/net/minecraft/world/WorldType.java ++++ modified/net/minecraft/world/WorldType.java +@@ -34,6 +34,7 @@ + } + + private WorldType(int id, String name, int version) { ++ if (name.length() > 16 && DEBUG_ALL_BLOCK_STATES != null) throw new IllegalArgumentException("World type names must not be longer then 16: " + name); + this.name = name; + this.version = version; + this.canBeCreated = true; +@@ -114,4 +115,122 @@ + this.hasInfoNotice = true; + return this; + } ++ ++ public net.minecraft.world.biome.BiomeProvider getBiomeProvider(World world) { ++ if (this == FLAT) { ++ net.minecraft.world.gen.FlatGeneratorInfo flatgeneratorinfo = net.minecraft.world.gen.FlatGeneratorInfo.createFlatGeneratorFromString(world.getWorldInfo().getGeneratorOptions()); ++ return new net.minecraft.world.biome.BiomeProviderSingle(net.minecraft.world.biome.Biome.getBiome(flatgeneratorinfo.getBiome(), net.minecraft.init.Biomes.DEFAULT)); ++ } else if (this == DEBUG_ALL_BLOCK_STATES) { ++ return new net.minecraft.world.biome.BiomeProviderSingle(net.minecraft.init.Biomes.PLAINS); ++ } else { ++ return new net.minecraft.world.biome.BiomeProvider(world.getWorldInfo()); ++ } ++ } ++ ++ public net.minecraft.world.gen.IChunkGenerator getChunkGenerator(World world, String generatorOptions) { ++ if (this == FLAT) return new net.minecraft.world.gen.ChunkGeneratorFlat(world, world.getSeed(), world.getWorldInfo().isMapFeaturesEnabled(), generatorOptions); ++ if (this == DEBUG_ALL_BLOCK_STATES) return new net.minecraft.world.gen.ChunkGeneratorDebug(world); ++ if (this == CUSTOMIZED) return new net.minecraft.world.gen.ChunkGeneratorOverworld(world, world.getSeed(), world.getWorldInfo().isMapFeaturesEnabled(), generatorOptions); ++ return new net.minecraft.world.gen.ChunkGeneratorOverworld(world, world.getSeed(), world.getWorldInfo().isMapFeaturesEnabled(), generatorOptions); ++ } ++ ++ public int getMinimumSpawnHeight(World world) { ++ return this == FLAT ? 4 : world.getSeaLevel() + 1; ++ } ++ ++ public double getHorizon(World world) { ++ return this == FLAT ? 0.0D : 63.0D; ++ } ++ ++ public double voidFadeMagnitude() { ++ return this == FLAT ? 1.0D : 0.03125D; ++ } ++ ++ public boolean handleSlimeSpawnReduction(java.util.Random random, World world) { ++ return this == FLAT ? random.nextInt(4) != 1 : false; ++ } ++ ++ /*=================================================== FORGE START ======================================*/ ++ private static int getNextID() { ++ for (int x = 0; x < WORLD_TYPES.length; x++) { ++ if (WORLD_TYPES[x] == null) { ++ return x; ++ } ++ } ++ ++ int oldLen = WORLD_TYPES.length; ++ WORLD_TYPES = java.util.Arrays.copyOf(WORLD_TYPES, oldLen + 16); ++ return oldLen; ++ } ++ ++ /** ++ * Creates a new world type, the ID is hidden and should not be referenced by modders. ++ * It will automatically expand the underlying workdType array if there are no IDs left. ++ * @param name ++ */ ++ public WorldType(String name) { ++ this(getNextID(), name); ++ } ++ ++ /** ++ * Called when 'Create New World' button is pressed before starting game ++ */ ++ public void onGUICreateWorldPress() { } ++ ++ /** ++ * Gets the spawn fuzz for players who join the world. ++ * Useful for void world types. ++ * @return Fuzz for entity initial spawn in blocks. ++ */ ++ public int getSpawnFuzz(WorldServer world, net.minecraft.server.MinecraftServer server) { ++ return Math.max(0, server.getSpawnRadius(world)); ++ } ++ ++ /** ++ * Called when the 'Customize' button is pressed on world creation GUI ++ * @param mc The Minecraft instance ++ * @param guiCreateWorld the createworld GUI ++ */ ++ @SideOnly(Side.CLIENT) ++ public void onCustomizeButton(net.minecraft.client.Minecraft mc, net.minecraft.client.gui.GuiCreateWorld guiCreateWorld) { ++ if (this == WorldType.FLAT) { ++ mc.displayGuiScreen(new net.minecraft.client.gui.GuiCreateFlatWorld(guiCreateWorld, guiCreateWorld.chunkProviderSettingsJson)); ++ } else if (this == WorldType.CUSTOMIZED) { ++ mc.displayGuiScreen(new net.minecraft.client.gui.GuiCustomizeWorldScreen(guiCreateWorld, guiCreateWorld.chunkProviderSettingsJson)); ++ } ++ } ++ ++ /** ++ * Should world creation GUI show 'Customize' button for this world type? ++ * @return if this world type has customization parameters ++ */ ++ public boolean isCustomizable() { ++ return this == FLAT || this == WorldType.CUSTOMIZED; ++ } ++ ++ ++ /** ++ * Get the height to render the clouds for this world type ++ * @return The height to render clouds at ++ */ ++ public float getCloudHeight() { ++ return 128.0F; ++ } ++ ++ /** ++ * Creates the GenLayerBiome used for generating the world with the specified ChunkProviderSettings JSON String ++ * *IF AND ONLY IF* this WorldType == WorldType.CUSTOMIZED. ++ * ++ * ++ * @param worldSeed The world seed ++ * @param parentLayer The parent layer to feed into any layer you return ++ * @param chunkSettings The ChunkGeneratorSettings constructed from the custom JSON ++ * @return A GenLayer that will return ints representing the Biomes to be generated, see GenLayerBiome ++ */ ++ public net.minecraft.world.gen.layer.GenLayer getBiomeLayer(long worldSeed, net.minecraft.world.gen.layer.GenLayer parentLayer, net.minecraft.world.gen.ChunkGeneratorSettings chunkSettings) { ++ net.minecraft.world.gen.layer.GenLayer ret = new net.minecraft.world.gen.layer.GenLayerBiome(200L, parentLayer, this, chunkSettings); ++ ret = net.minecraft.world.gen.layer.GenLayerZoom.magnify(1000L, ret, 2); ++ ret = new net.minecraft.world.gen.layer.GenLayerBiomeEdge(1000L, ret); ++ return ret; ++ } + } diff --git a/module/minecraft/patches/net/minecraft/world/biome/Biome.java.patch b/module/minecraft/patches/net/minecraft/world/biome/Biome.java.patch new file mode 100644 index 000000000..44e9b696f --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/biome/Biome.java.patch @@ -0,0 +1,168 @@ +--- original/net/minecraft/world/biome/Biome.java ++++ modified/net/minecraft/world/biome/Biome.java +@@ -50,7 +50,7 @@ + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + +-public abstract class Biome { ++public abstract class Biome extends net.minecraftforge.registries.IForgeRegistryEntry.Impl { + private static final Logger LOGGER = LogManager.getLogger(); + protected static final IBlockState STONE = Blocks.STONE.getDefaultState(); + protected static final IBlockState AIR = Blocks.AIR.getDefaultState(); +@@ -70,7 +70,7 @@ + protected static final WorldGenBigTree BIG_TREE_FEATURE = new WorldGenBigTree(false); + /** The swamp tree generator. */ + protected static final WorldGenSwamp SWAMP_FEATURE = new WorldGenSwamp(); +- public static final RegistryNamespaced REGISTRY = new RegistryNamespaced<>(); ++ public static final RegistryNamespaced REGISTRY = net.minecraftforge.registries.GameData.getWrapper(Biome.class); + private final String biomeName; + /** The base height of this biome. Default 0.1. */ + private final float baseHeight; +@@ -102,6 +102,8 @@ + /** Holds the classes of any aquatic creature that can be spawned in the water of the biome. */ + protected List spawnableWaterCreatureList = Lists.newArrayList(); + protected List spawnableCaveCreatureList = Lists.newArrayList(); ++ // Forge: Stores the spawnable lists for non-vanilla EnumCreatureTypes. Can't be an EnumMap as that doesn't handle new enum values being added after it's created. ++ protected java.util.Map> modSpawnableLists = com.google.common.collect.Maps.newHashMap(); + + public static int getIdForBiome(Biome biome) { + return REGISTRY.getIDForObject(biome); +@@ -142,11 +144,12 @@ + this.spawnableMonsterList.add(new Biome.SpawnListEntry(EntityWitch.class, 5, 1, 1)); + this.spawnableWaterCreatureList.add(new Biome.SpawnListEntry(EntitySquid.class, 10, 4, 4)); + this.spawnableCaveCreatureList.add(new Biome.SpawnListEntry(EntityBat.class, 10, 8, 8)); ++ this.addDefaultFlowers(); + } + + /** Allocate a new BiomeDecorator for this BiomeGenBase */ + public BiomeDecorator createBiomeDecorator() { +- return new BiomeDecorator(); ++ return getModdedBiomeDecorator(new BiomeDecorator()); + } + + public boolean isMutation() { +@@ -186,7 +189,9 @@ + case AMBIENT: + return this.spawnableCaveCreatureList; + default: +- return Collections.emptyList(); ++ // Forge: Return a non-empty list for non-vanilla EnumCreatureTypes ++ if (!this.modSpawnableLists.containsKey(creatureType)) this.modSpawnableLists.put(creatureType, Lists.newArrayList()); ++ return this.modSpawnableLists.get(creatureType); + } + } + +@@ -228,14 +233,14 @@ + public int getGrassColorAtPos(BlockPos pos) { + double d0 = MathHelper.clamp(this.getTemperature(pos), 0.0F, 1.0F); + double d1 = MathHelper.clamp(this.getRainfall(), 0.0F, 1.0F); +- return ColorizerGrass.getGrassColor(d0, d1); ++ return getModdedBiomeGrassColor(ColorizerGrass.getGrassColor(d0, d1)); + } + + @SideOnly(Side.CLIENT) + public int getFoliageColorAtPos(BlockPos pos) { + double d0 = MathHelper.clamp(this.getTemperature(pos), 0.0F, 1.0F); + double d1 = MathHelper.clamp(this.getRainfall(), 0.0F, 1.0F); +- return ColorizerFoliage.getFoliageColor(d0, d1); ++ return getModdedBiomeFoliageColor(ColorizerFoliage.getFoliageColor(d0, d1)); + } + + public void genTerrainBlocks(World worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) { +@@ -361,14 +366,81 @@ + + @SideOnly(Side.CLIENT) + public final int getWaterColor() { +- return this.waterColor; ++ return getWaterColorMultiplier(); + } + + public final boolean isSnowyBiome() { + return this.enableSnow; + } + +- /** Registers all of the vanilla biomes. */ ++ /* ========================================= FORGE START ======================================*/ ++ protected List flowers = new java.util.ArrayList(); ++ ++ public BiomeDecorator getModdedBiomeDecorator(BiomeDecorator original) { ++ return new net.minecraftforge.event.terraingen.DeferredBiomeDecorator(original); ++ } ++ ++ public int getWaterColorMultiplier() { ++ net.minecraftforge.event.terraingen.BiomeEvent.GetWaterColor event = new net.minecraftforge.event.terraingen.BiomeEvent.GetWaterColor(this, waterColor); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event); ++ return event.getNewColor(); ++ } ++ ++ public int getModdedBiomeGrassColor(int original) { ++ net.minecraftforge.event.terraingen.BiomeEvent.GetGrassColor event = new net.minecraftforge.event.terraingen.BiomeEvent.GetGrassColor(this, original); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event); ++ return event.getNewColor(); ++ } ++ ++ public int getModdedBiomeFoliageColor(int original) { ++ net.minecraftforge.event.terraingen.BiomeEvent.GetFoliageColor event = new net.minecraftforge.event.terraingen.BiomeEvent.GetFoliageColor(this, original); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event); ++ return event.getNewColor(); ++ } ++ ++ /** ++ * Weighted random holder class used to hold possible flowers ++ * that can spawn in this biome when bonemeal is used on grass. ++ */ ++ public static class FlowerEntry extends WeightedRandom.Item { ++ public final net.minecraft.block.state.IBlockState state; ++ public FlowerEntry(net.minecraft.block.state.IBlockState state, int weight) { ++ super(weight); ++ this.state = state; ++ } ++ } ++ ++ /** ++ * Adds the default flowers, as of 1.7, it is 2 yellow, and 1 red. I chose 10 to allow some wiggle room in the numbers. ++ */ ++ public void addDefaultFlowers() { ++ addFlower(Blocks.YELLOW_FLOWER.getDefaultState().withProperty(Blocks.YELLOW_FLOWER.getTypeProperty(), BlockFlower.EnumFlowerType.DANDELION), 20); ++ addFlower(Blocks.RED_FLOWER.getDefaultState().withProperty(Blocks.RED_FLOWER.getTypeProperty(), BlockFlower.EnumFlowerType.POPPY), 10); ++ } ++ ++ /** Register a new plant to be planted when bonemeal is used on grass. ++ * @param state The block to place. ++ * @param weight The weight of the plant, where red flowers are ++ * 10 and yellow flowers are 20. ++ */ ++ public void addFlower(IBlockState state, int weight) { ++ this.flowers.add(new FlowerEntry(state, weight)); ++ } ++ ++ public void plantFlower(World world, Random rand, BlockPos pos) { ++ if (flowers.isEmpty()) return; ++ FlowerEntry flower = (FlowerEntry)WeightedRandom.getRandomItem(rand, flowers); ++ if (flower == null || flower.state == null || ++ (flower.state.getBlock() instanceof net.minecraft.block.BlockBush && ++ !((net.minecraft.block.BlockBush)flower.state.getBlock()).canBlockStay(world, pos, flower.state))) { ++ return; ++ } ++ ++ world.setBlockState(pos, flower.state, 3); ++ } ++ ++ /* ========================================= FORGE END ======================================*/ ++ + public static void registerBiomes() { + registerBiome(0, "ocean", new BiomeOcean(new Biome.BiomeProperties("Ocean").setBaseHeight(-1.0F).setHeightVariation(0.1F))); + registerBiome( +@@ -934,6 +1006,12 @@ + public String toString() { + return this.entityClass.getSimpleName() + "*(" + this.minGroupCount + "-" + this.maxGroupCount + "):" + this.itemWeight; + } ++ ++ public EntityLiving newInstance(World world) throws Exception { ++ net.minecraftforge.fml.common.registry.EntityEntry entry = net.minecraftforge.fml.common.registry.EntityRegistry.getEntry(this.entityClass); ++ if (entry != null) return (EntityLiving) entry.newInstance(world); ++ return this.entityClass.getConstructor(World.class).newInstance(world); ++ } + } + + public enum TempCategory { diff --git a/module/minecraft/patches/net/minecraft/world/biome/BiomeDecorator.java.patch b/module/minecraft/patches/net/minecraft/world/biome/BiomeDecorator.java.patch new file mode 100644 index 000000000..9d60aad98 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/biome/BiomeDecorator.java.patch @@ -0,0 +1,227 @@ +--- original/net/minecraft/world/biome/BiomeDecorator.java ++++ modified/net/minecraft/world/biome/BiomeDecorator.java +@@ -117,20 +117,25 @@ + } + + protected void genDecorations(Biome biomeIn, World worldIn, Random random) { ++ net.minecraft.util.math.ChunkPos forgeChunkPos = new net.minecraft.util.math.ChunkPos(chunkPos); // actual ChunkPos instead of BlockPos, used for events ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.terraingen.DecorateBiomeEvent.Pre(worldIn, random, forgeChunkPos)); + this.generateOres(worldIn, random); + ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.SAND)) + for (int i = 0; i < this.sandPatchesPerChunk; i++) { + int j = random.nextInt(16) + 8; + int k = random.nextInt(16) + 8; + this.sandGen.generate(worldIn, random, worldIn.getTopSolidOrLiquidBlock(this.chunkPos.add(j, 0, k))); + } + ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.CLAY)) + for (int i1 = 0; i1 < this.clayPerChunk; i1++) { + int l1 = random.nextInt(16) + 8; + int i6 = random.nextInt(16) + 8; + this.clayGen.generate(worldIn, random, worldIn.getTopSolidOrLiquidBlock(this.chunkPos.add(l1, 0, i6))); + } + ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.SAND_PASS2)) + for (int j1 = 0; j1 < this.gravelPatchesPerChunk; j1++) { + int i2 = random.nextInt(16) + 8; + int j6 = random.nextInt(16) + 8; +@@ -142,6 +147,7 @@ + k1++; + } + ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.TREE)) + for (int j2 = 0; j2 < k1; j2++) { + int k6 = random.nextInt(16) + 8; + int l = random.nextInt(16) + 8; +@@ -153,12 +159,14 @@ + } + } + ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.BIG_SHROOM)) + for (int k2 = 0; k2 < this.bigMushroomsPerChunk; k2++) { + int l6 = random.nextInt(16) + 8; + int k10 = random.nextInt(16) + 8; + this.bigMushroomGen.generate(worldIn, random, worldIn.getHeight(this.chunkPos.add(l6, 0, k10))); + } + ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.FLOWERS)) + for (int l2 = 0; l2 < this.flowersPerChunk; l2++) { + int i7 = random.nextInt(16) + 8; + int l10 = random.nextInt(16) + 8; +@@ -175,6 +183,7 @@ + } + } + ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.GRASS)) + for (int i3 = 0; i3 < this.grassPerChunk; i3++) { + int j7 = random.nextInt(16) + 8; + int i11 = random.nextInt(16) + 8; +@@ -185,6 +194,7 @@ + } + } + ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.DEAD_BUSH)) + for (int j3 = 0; j3 < this.deadBushPerChunk; j3++) { + int k7 = random.nextInt(16) + 8; + int j11 = random.nextInt(16) + 8; +@@ -195,6 +205,7 @@ + } + } + ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.LILYPAD)) + for (int k3 = 0; k3 < this.waterlilyPerChunk; k3++) { + int l7 = random.nextInt(16) + 8; + int k11 = random.nextInt(16) + 8; +@@ -216,6 +227,7 @@ + } + } + ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.SHROOM)) { + for (int l3 = 0; l3 < this.mushroomsPerChunk; l3++) { + if (random.nextInt(4) == 0) { + int i8 = random.nextInt(16) + 8; +@@ -256,6 +268,8 @@ + } + } + ++ } // End of Mushroom generation ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.REED)) { + for (int k4 = 0; k4 < this.reedsPerChunk; k4++) { + int i9 = random.nextInt(16) + 8; + int l12 = random.nextInt(16) + 8; +@@ -276,6 +290,8 @@ + } + } + ++ } // End of Reed generation ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.PUMPKIN)) + if (random.nextInt(32) == 0) { + int i5 = random.nextInt(16) + 8; + int k9 = random.nextInt(16) + 8; +@@ -286,6 +302,7 @@ + } + } + ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.CACTUS)) + for (int j5 = 0; j5 < this.cactiPerChunk; j5++) { + int l9 = random.nextInt(16) + 8; + int k13 = random.nextInt(16) + 8; +@@ -297,6 +314,7 @@ + } + + if (this.generateFalls) { ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.LAKE_WATER)) + for (int k5 = 0; k5 < 50; k5++) { + int i10 = random.nextInt(16) + 8; + int l13 = random.nextInt(16) + 8; +@@ -308,6 +326,7 @@ + } + } + ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.LAKE_LAVA)) + for (int l5 = 0; l5 < 20; l5++) { + int j10 = random.nextInt(16) + 8; + int i14 = random.nextInt(16) + 8; +@@ -316,10 +335,13 @@ + new WorldGenLiquids(Blocks.FLOWING_LAVA).generate(worldIn, random, blockpos3); + } + } ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.terraingen.DecorateBiomeEvent.Post(worldIn, random, forgeChunkPos)); + } + + /** Generates ores in the current chunk */ + protected void generateOres(World worldIn, Random random) { ++ net.minecraftforge.common.MinecraftForge.ORE_GEN_BUS.post(new net.minecraftforge.event.terraingen.OreGenEvent.Pre(worldIn, random, chunkPos)); ++ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, dirtGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.DIRT)) + this.genStandardOre1( + worldIn, + random, +@@ -328,6 +350,7 @@ + this.chunkProviderSettings.dirtMinHeight, + this.chunkProviderSettings.dirtMaxHeight + ); ++ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, gravelOreGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.GRAVEL)) + this.genStandardOre1( + worldIn, + random, +@@ -336,6 +359,7 @@ + this.chunkProviderSettings.gravelMinHeight, + this.chunkProviderSettings.gravelMaxHeight + ); ++ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, dioriteGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.DIORITE)) + this.genStandardOre1( + worldIn, + random, +@@ -344,6 +368,7 @@ + this.chunkProviderSettings.dioriteMinHeight, + this.chunkProviderSettings.dioriteMaxHeight + ); ++ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, graniteGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.GRANITE)) + this.genStandardOre1( + worldIn, + random, +@@ -352,6 +377,7 @@ + this.chunkProviderSettings.graniteMinHeight, + this.chunkProviderSettings.graniteMaxHeight + ); ++ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, andesiteGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.ANDESITE)) + this.genStandardOre1( + worldIn, + random, +@@ -360,6 +386,7 @@ + this.chunkProviderSettings.andesiteMinHeight, + this.chunkProviderSettings.andesiteMaxHeight + ); ++ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, coalGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.COAL)) + this.genStandardOre1( + worldIn, + random, +@@ -368,6 +395,7 @@ + this.chunkProviderSettings.coalMinHeight, + this.chunkProviderSettings.coalMaxHeight + ); ++ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, ironGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.IRON)) + this.genStandardOre1( + worldIn, + random, +@@ -376,6 +404,7 @@ + this.chunkProviderSettings.ironMinHeight, + this.chunkProviderSettings.ironMaxHeight + ); ++ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, goldGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.GOLD)) + this.genStandardOre1( + worldIn, + random, +@@ -384,6 +413,7 @@ + this.chunkProviderSettings.goldMinHeight, + this.chunkProviderSettings.goldMaxHeight + ); ++ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, redstoneGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.REDSTONE)) + this.genStandardOre1( + worldIn, + random, +@@ -392,6 +422,7 @@ + this.chunkProviderSettings.redstoneMinHeight, + this.chunkProviderSettings.redstoneMaxHeight + ); ++ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, diamondGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.DIAMOND)) + this.genStandardOre1( + worldIn, + random, +@@ -400,6 +431,7 @@ + this.chunkProviderSettings.diamondMinHeight, + this.chunkProviderSettings.diamondMaxHeight + ); ++ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, lapisGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.LAPIS)) + this.genStandardOre2( + worldIn, + random, +@@ -408,6 +440,7 @@ + this.chunkProviderSettings.lapisCenterHeight, + this.chunkProviderSettings.lapisSpread + ); ++ net.minecraftforge.common.MinecraftForge.ORE_GEN_BUS.post(new net.minecraftforge.event.terraingen.OreGenEvent.Post(worldIn, random, chunkPos)); + } + + /** diff --git a/module/minecraft/patches/net/minecraft/world/biome/BiomeDesert.java.patch b/module/minecraft/patches/net/minecraft/world/biome/BiomeDesert.java.patch new file mode 100644 index 000000000..755319e3a --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/biome/BiomeDesert.java.patch @@ -0,0 +1,19 @@ +--- original/net/minecraft/world/biome/BiomeDesert.java ++++ modified/net/minecraft/world/biome/BiomeDesert.java +@@ -41,6 +41,8 @@ + @Override + public void decorate(World worldIn, Random rand, BlockPos pos) { + super.decorate(worldIn, rand, pos); ++ ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.DESERT_WELL)) + if (rand.nextInt(1000) == 0) { + int i = rand.nextInt(16) + 8; + int j = rand.nextInt(16) + 8; +@@ -48,6 +50,7 @@ + new WorldGenDesertWells().generate(worldIn, rand, blockpos); + } + ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.FOSSIL)) + if (rand.nextInt(64) == 0) { + new WorldGenFossils().generate(worldIn, rand, pos); + } diff --git a/module/minecraft/patches/net/minecraft/world/biome/BiomeForest.java.patch b/module/minecraft/patches/net/minecraft/world/biome/BiomeForest.java.patch new file mode 100644 index 000000000..b127da3c6 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/biome/BiomeForest.java.patch @@ -0,0 +1,48 @@ +--- original/net/minecraft/world/biome/BiomeForest.java ++++ modified/net/minecraft/world/biome/BiomeForest.java +@@ -40,6 +40,15 @@ + if (this.type == BiomeForest.Type.ROOFED) { + this.decorator.treesPerChunk = -999; + } ++ ++ if (this.type == BiomeForest.Type.FLOWER) { //Needs to be done here so we have access to this.type ++ this.flowers.clear(); ++ for (BlockFlower.EnumFlowerType type : BlockFlower.EnumFlowerType.values()) { ++ if (type.getBlockType() == BlockFlower.EnumFlowerColor.YELLOW) continue; ++ if (type == BlockFlower.EnumFlowerType.BLUE_ORCHID) type = BlockFlower.EnumFlowerType.POPPY; ++ addFlower(net.minecraft.init.Blocks.RED_FLOWER.getDefaultState().withProperty(net.minecraft.init.Blocks.RED_FLOWER.getTypeProperty(), type), 10); ++ } ++ } + } + + @Override +@@ -72,12 +81,15 @@ + this.addMushrooms(worldIn, rand, pos); + } + ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.FLOWERS)) ++ { // no tab for patch + int i = rand.nextInt(5) - 3; + if (this.type == BiomeForest.Type.FLOWER) { + i += 2; + } + + this.addDoublePlants(worldIn, rand, pos, i); ++ } + super.decorate(worldIn, rand, pos); + } + +@@ -87,10 +99,11 @@ + int k = i * 4 + 1 + 8 + p_185379_2_.nextInt(3); + int l = j * 4 + 1 + 8 + p_185379_2_.nextInt(3); + BlockPos blockpos = p_185379_1_.getHeight(p_185379_3_.add(k, 0, l)); +- if (p_185379_2_.nextInt(20) == 0) { ++ ++ if (p_185379_2_.nextInt(20) == 0 && net.minecraftforge.event.terraingen.TerrainGen.decorate(p_185379_1_, p_185379_2_, new net.minecraft.util.math.ChunkPos(p_185379_3_), blockpos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.BIG_SHROOM)) { + WorldGenBigMushroom worldgenbigmushroom = new WorldGenBigMushroom(); + worldgenbigmushroom.generate(p_185379_1_, p_185379_2_, blockpos); +- } else { ++ } else if (net.minecraftforge.event.terraingen.TerrainGen.decorate(p_185379_1_, p_185379_2_, new net.minecraft.util.math.ChunkPos(p_185379_3_), blockpos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.TREE)) { + WorldGenAbstractTree worldgenabstracttree = this.getRandomTreeFeature(p_185379_2_); + worldgenabstracttree.setDecorationDefaults(); + if (worldgenabstracttree.generate(p_185379_1_, p_185379_2_, blockpos)) { diff --git a/module/minecraft/patches/net/minecraft/world/biome/BiomeHills.java.patch b/module/minecraft/patches/net/minecraft/world/biome/BiomeHills.java.patch new file mode 100644 index 000000000..e7ac312e5 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/biome/BiomeHills.java.patch @@ -0,0 +1,55 @@ +--- original/net/minecraft/world/biome/BiomeHills.java ++++ modified/net/minecraft/world/biome/BiomeHills.java +@@ -37,24 +37,20 @@ + @Override + public void decorate(World worldIn, Random rand, BlockPos pos) { + super.decorate(worldIn, rand, pos); +- int i = 3 + rand.nextInt(6); + +- for (int j = 0; j < i; j++) { +- int k = rand.nextInt(16); +- int l = rand.nextInt(28) + 4; +- int i1 = rand.nextInt(16); +- BlockPos blockpos = pos.add(k, l, i1); +- if (worldIn.getBlockState(blockpos).getBlock() == Blocks.STONE) { +- worldIn.setBlockState(blockpos, Blocks.EMERALD_ORE.getDefaultState(), 2); +- } +- } ++ net.minecraftforge.common.MinecraftForge.ORE_GEN_BUS.post(new net.minecraftforge.event.terraingen.OreGenEvent.Pre(worldIn, rand, pos)); ++ WorldGenerator emeralds = new EmeraldGenerator(); ++ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, rand, emeralds, pos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.EMERALD)) ++ emeralds.generate(worldIn, rand, pos); + + for (int j1 = 0; j1 < 7; j1++) { + int k1 = rand.nextInt(16); + int l1 = rand.nextInt(64); + int i2 = rand.nextInt(16); ++ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, rand, silverfishSpawner, pos.add(j1, k1, l1), net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.SILVERFISH)) + this.silverfishSpawner.generate(worldIn, rand, pos.add(k1, l1, i2)); + } ++ net.minecraftforge.common.MinecraftForge.ORE_GEN_BUS.post(new net.minecraftforge.event.terraingen.OreGenEvent.Post(worldIn, rand, pos)); + } + + @Override +@@ -77,4 +73,21 @@ + EXTRA_TREES, + MUTATED; + } ++ ++ private static class EmeraldGenerator extends WorldGenerator { ++ @Override ++ public boolean generate(World worldIn, Random rand, BlockPos pos) { ++ int count = 3 + rand.nextInt(6); ++ for (int i = 0; i < count; i++) { ++ int offset = net.minecraftforge.common.ForgeModContainer.fixVanillaCascading ? 8 : 0; // MC-114332 ++ BlockPos blockpos = pos.add(rand.nextInt(16) + offset, rand.nextInt(28) + 4, rand.nextInt(16) + offset); ++ ++ net.minecraft.block.state.IBlockState state = worldIn.getBlockState(blockpos); ++ if (state.getBlock().isReplaceableOreGen(state, worldIn, blockpos, net.minecraft.block.state.pattern.BlockMatcher.forBlock(Blocks.STONE))) { ++ worldIn.setBlockState(blockpos, Blocks.EMERALD_ORE.getDefaultState(), 16 | 2); ++ } ++ } ++ return true; ++ } ++ } + } diff --git a/module/minecraft/patches/net/minecraft/world/biome/BiomeJungle.java.patch b/module/minecraft/patches/net/minecraft/world/biome/BiomeJungle.java.patch new file mode 100644 index 000000000..6eac7d831 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/biome/BiomeJungle.java.patch @@ -0,0 +1,19 @@ +--- original/net/minecraft/world/biome/BiomeJungle.java ++++ modified/net/minecraft/world/biome/BiomeJungle.java +@@ -80,10 +80,14 @@ + super.decorate(worldIn, rand, pos); + int i = rand.nextInt(16) + 8; + int j = rand.nextInt(16) + 8; +- int k = rand.nextInt(worldIn.getHeight(pos.add(i, 0, j)).getY() * 2); +- new WorldGenMelon().generate(worldIn, rand, pos.add(i, k, j)); ++ int height = worldIn.getHeight(pos.add(i, 0, j)).getY() * 2; // could == 0, which crashes nextInt ++ if (height < 1) height = 1; ++ int k = rand.nextInt(height); ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), pos.add(i, k, j), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.PUMPKIN)) ++ (new WorldGenMelon()).generate(worldIn, rand, pos.add(i, k, j)); + WorldGenVines worldgenvines = new WorldGenVines(); + ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.GRASS)) + for (int j1 = 0; j1 < 50; j1++) { + k = rand.nextInt(16) + 8; + int l = 128; diff --git a/module/minecraft/patches/net/minecraft/world/biome/BiomeMesa.java.patch b/module/minecraft/patches/net/minecraft/world/biome/BiomeMesa.java.patch new file mode 100644 index 000000000..f94798324 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/biome/BiomeMesa.java.patch @@ -0,0 +1,26 @@ +--- original/net/minecraft/world/biome/BiomeMesa.java ++++ modified/net/minecraft/world/biome/BiomeMesa.java +@@ -68,13 +68,13 @@ + @SideOnly(Side.CLIENT) + @Override + public int getFoliageColorAtPos(BlockPos pos) { +- return 10387789; ++ return getModdedBiomeFoliageColor(10387789); + } + + @SideOnly(Side.CLIENT) + @Override + public int getGrassColorAtPos(BlockPos pos) { +- return 9470285; ++ return getModdedBiomeGrassColor(9470285); + } + + @Override +@@ -266,6 +266,7 @@ + @Override + protected void generateOres(World worldIn, Random random) { + super.generateOres(worldIn, random); ++ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, goldGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.GOLD)) + this.genStandardOre1(worldIn, random, 20, this.goldGen, 32, 80); + } + } diff --git a/module/minecraft/patches/net/minecraft/world/biome/BiomePlains.java.patch b/module/minecraft/patches/net/minecraft/world/biome/BiomePlains.java.patch new file mode 100644 index 000000000..84286d2e9 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/biome/BiomePlains.java.patch @@ -0,0 +1,39 @@ +--- original/net/minecraft/world/biome/BiomePlains.java ++++ modified/net/minecraft/world/biome/BiomePlains.java +@@ -62,6 +62,7 @@ + this.decorator.grassPerChunk = 10; + DOUBLE_PLANT_GENERATOR.setPlantType(BlockDoublePlant.EnumPlantType.GRASS); + ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.GRASS)) + for (int i = 0; i < 7; i++) { + int j = rand.nextInt(16) + 8; + int k = rand.nextInt(16) + 8; +@@ -70,7 +71,7 @@ + } + } + +- if (this.sunflowers) { ++ if (this.sunflowers && net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.FLOWERS)) { + DOUBLE_PLANT_GENERATOR.setPlantType(BlockDoublePlant.EnumPlantType.SUNFLOWER); + + for (int i1 = 0; i1 < 10; i1++) { +@@ -85,6 +86,19 @@ + } + + @Override ++ public void addDefaultFlowers() { ++ BlockFlower red = net.minecraft.init.Blocks.RED_FLOWER; ++ BlockFlower yel = net.minecraft.init.Blocks.YELLOW_FLOWER; ++ addFlower(red.getDefaultState().withProperty(red.getTypeProperty(), BlockFlower.EnumFlowerType.ORANGE_TULIP), 3); ++ addFlower(red.getDefaultState().withProperty(red.getTypeProperty(), BlockFlower.EnumFlowerType.RED_TULIP), 3); ++ addFlower(red.getDefaultState().withProperty(red.getTypeProperty(), BlockFlower.EnumFlowerType.PINK_TULIP), 3); ++ addFlower(red.getDefaultState().withProperty(red.getTypeProperty(), BlockFlower.EnumFlowerType.WHITE_TULIP), 3); ++ addFlower(red.getDefaultState().withProperty(red.getTypeProperty(), BlockFlower.EnumFlowerType.POPPY), 20); ++ addFlower(red.getDefaultState().withProperty(red.getTypeProperty(), BlockFlower.EnumFlowerType.HOUSTONIA), 20); ++ addFlower(red.getDefaultState().withProperty(red.getTypeProperty(), BlockFlower.EnumFlowerType.OXEYE_DAISY), 20); ++ addFlower(yel.getDefaultState().withProperty(yel.getTypeProperty(), BlockFlower.EnumFlowerType.DANDELION), 30); ++ } ++ + public WorldGenAbstractTree getRandomTreeFeature(Random rand) { + return rand.nextInt(3) == 0 ? BIG_TREE_FEATURE : TREE_FEATURE; + } diff --git a/module/minecraft/patches/net/minecraft/world/biome/BiomeProvider.java.patch b/module/minecraft/patches/net/minecraft/world/biome/BiomeProvider.java.patch new file mode 100644 index 000000000..bf54db800 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/biome/BiomeProvider.java.patch @@ -0,0 +1,33 @@ +--- original/net/minecraft/world/biome/BiomeProvider.java ++++ modified/net/minecraft/world/biome/BiomeProvider.java +@@ -23,7 +23,8 @@ + /** The biome list. */ + private final BiomeCache biomeCache = new BiomeCache(this); + /** A list of biomes that the player can spawn in. */ +- private final List biomesToSpawnIn = Lists.newArrayList( ++ private final List biomesToSpawnIn = Lists.newArrayList(allowedBiomes); ++ public static List allowedBiomes = Lists.newArrayList( + Biomes.FOREST, + Biomes.PLAINS, + Biomes.TAIGA, +@@ -43,6 +44,7 @@ + } + + GenLayer[] agenlayer = GenLayer.initializeAllBiomeGenerators(seed, worldTypeIn, this.settings); ++ agenlayer = getModdedBiomeGenerators(worldTypeIn, seed, agenlayer); + this.genBiomes = agenlayer[0]; + this.biomeIndexLayer = agenlayer[1]; + } +@@ -186,6 +188,12 @@ + public void cleanupCache() { + this.biomeCache.cleanupCache(); + } ++ public GenLayer[] getModdedBiomeGenerators(WorldType worldType, long seed, GenLayer[] original) ++ { ++ net.minecraftforge.event.terraingen.WorldTypeEvent.InitBiomeGens event = new net.minecraftforge.event.terraingen.WorldTypeEvent.InitBiomeGens(worldType, seed, original); ++ net.minecraftforge.common.MinecraftForge.TERRAIN_GEN_BUS.post(event); ++ return event.getNewBiomeGens(); ++ } + + public boolean isFixedBiome() { + return this.settings != null && this.settings.fixedBiome >= 0; diff --git a/module/minecraft/patches/net/minecraft/world/biome/BiomeSavanna.java.patch b/module/minecraft/patches/net/minecraft/world/biome/BiomeSavanna.java.patch new file mode 100644 index 000000000..46ba3c979 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/biome/BiomeSavanna.java.patch @@ -0,0 +1,10 @@ +--- original/net/minecraft/world/biome/BiomeSavanna.java ++++ modified/net/minecraft/world/biome/BiomeSavanna.java +@@ -35,6 +35,7 @@ + public void decorate(World worldIn, Random rand, BlockPos pos) { + DOUBLE_PLANT_GENERATOR.setPlantType(BlockDoublePlant.EnumPlantType.GRASS); + ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.GRASS)) + for (int i = 0; i < 7; i++) { + int j = rand.nextInt(16) + 8; + int k = rand.nextInt(16) + 8; diff --git a/module/minecraft/patches/net/minecraft/world/biome/BiomeSnow.java.patch b/module/minecraft/patches/net/minecraft/world/biome/BiomeSnow.java.patch new file mode 100644 index 000000000..9dc092e8b --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/biome/BiomeSnow.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/world/biome/BiomeSnow.java ++++ modified/net/minecraft/world/biome/BiomeSnow.java +@@ -50,7 +50,7 @@ + + @Override + public void decorate(World worldIn, Random rand, BlockPos pos) { +- if (this.superIcy) { ++ if (this.superIcy && net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.ICE)) { + for (int i = 0; i < 3; i++) { + int j = rand.nextInt(16) + 8; + int k = rand.nextInt(16) + 8; diff --git a/module/minecraft/patches/net/minecraft/world/biome/BiomeSwamp.java.patch b/module/minecraft/patches/net/minecraft/world/biome/BiomeSwamp.java.patch new file mode 100644 index 000000000..6143841c5 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/biome/BiomeSwamp.java.patch @@ -0,0 +1,34 @@ +--- original/net/minecraft/world/biome/BiomeSwamp.java ++++ modified/net/minecraft/world/biome/BiomeSwamp.java +@@ -41,13 +41,13 @@ + @Override + public int getGrassColorAtPos(BlockPos pos) { + double d0 = GRASS_COLOR_NOISE.getValue(pos.getX() * 0.0225, pos.getZ() * 0.0225); +- return d0 < -0.1 ? 5011004 : 6975545; ++ return getModdedBiomeGrassColor(d0 < -0.1 ? 5011004 : 6975545); + } + + @SideOnly(Side.CLIENT) + @Override + public int getFoliageColorAtPos(BlockPos pos) { +- return 6975545; ++ return getModdedBiomeFoliageColor(6975545); + } + + @Override +@@ -81,8 +81,15 @@ + @Override + public void decorate(World worldIn, Random rand, BlockPos pos) { + super.decorate(worldIn, rand, pos); ++ ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.FOSSIL)) + if (rand.nextInt(64) == 0) { + new WorldGenFossils().generate(worldIn, rand, pos); + } + } ++ ++ @Override ++ public void addDefaultFlowers() { ++ addFlower(Blocks.RED_FLOWER.getDefaultState().withProperty(Blocks.RED_FLOWER.getTypeProperty(), BlockFlower.EnumFlowerType.BLUE_ORCHID), 10); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/world/biome/BiomeTaiga.java.patch b/module/minecraft/patches/net/minecraft/world/biome/BiomeTaiga.java.patch new file mode 100644 index 000000000..720c18395 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/biome/BiomeTaiga.java.patch @@ -0,0 +1,19 @@ +--- original/net/minecraft/world/biome/BiomeTaiga.java ++++ modified/net/minecraft/world/biome/BiomeTaiga.java +@@ -59,7 +59,7 @@ + + @Override + public void decorate(World worldIn, Random rand, BlockPos pos) { +- if (this.type == BiomeTaiga.Type.MEGA || this.type == BiomeTaiga.Type.MEGA_SPRUCE) { ++ if ((this.type == BiomeTaiga.Type.MEGA || this.type == BiomeTaiga.Type.MEGA_SPRUCE) && net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.ROCK)) { + int i = rand.nextInt(3); + + for (int j = 0; j < i; j++) { +@@ -72,6 +72,7 @@ + + DOUBLE_PLANT_GENERATOR.setPlantType(BlockDoublePlant.EnumPlantType.FERN); + ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.FLOWERS)) + for (int i1 = 0; i1 < 7; i1++) { + int j1 = rand.nextInt(16) + 8; + int k1 = rand.nextInt(16) + 8; diff --git a/module/minecraft/patches/net/minecraft/world/border/WorldBorder.java.patch b/module/minecraft/patches/net/minecraft/world/border/WorldBorder.java.patch new file mode 100644 index 000000000..7fe5002d2 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/border/WorldBorder.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/world/border/WorldBorder.java ++++ modified/net/minecraft/world/border/WorldBorder.java +@@ -232,4 +232,8 @@ + iborderlistener.onWarningDistanceChanged(this, warningDistance); + } + } ++ ++ public void removeListener(IBorderListener listener) { ++ this.listeners.remove(listener); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/world/chunk/BlockStateContainer.java.patch b/module/minecraft/patches/net/minecraft/world/chunk/BlockStateContainer.java.patch new file mode 100644 index 000000000..5491013c7 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/chunk/BlockStateContainer.java.patch @@ -0,0 +1,38 @@ +--- original/net/minecraft/world/chunk/BlockStateContainer.java ++++ modified/net/minecraft/world/chunk/BlockStateContainer.java +@@ -26,6 +26,9 @@ + } + + private void setBits(int bitsIn) { ++ setBits(bitsIn, false); ++ } ++ private void setBits(int bitsIn, boolean forceBits) { + if (bitsIn != this.bits) { + this.bits = bitsIn; + if (this.bits <= 4) { +@@ -36,6 +39,8 @@ + } else { + this.palette = REGISTRY_BASED_PALETTE; + this.bits = MathHelper.log2DeBruijn(Block.BLOCK_STATE_IDS.size()); ++ if (forceBits) ++ this.bits = bitsIn; + } + + this.palette.idFor(AIR_BLOCK_STATE); +@@ -81,11 +86,15 @@ + public void read(PacketBuffer buf) { + int i = buf.readByte(); + if (this.bits != i) { +- this.setBits(i); ++ this.setBits(i, true); //Forge, Force bit density to fix network issues, resize below if needed. + } + + this.palette.read(buf); + buf.readLongArray(this.storage.getBackingLongArray()); ++ ++ int regSize = MathHelper.log2DeBruijn(Block.BLOCK_STATE_IDS.size()); ++ if (this.palette == REGISTRY_BASED_PALETTE && this.bits != regSize) // Resize bits to fit registry. ++ this.onResize(regSize, AIR_BLOCK_STATE); + } + + public void write(PacketBuffer buf) { diff --git a/module/minecraft/patches/net/minecraft/world/chunk/Chunk.java.patch b/module/minecraft/patches/net/minecraft/world/chunk/Chunk.java.patch new file mode 100644 index 000000000..fe2fd7b0a --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/chunk/Chunk.java.patch @@ -0,0 +1,464 @@ +--- original/net/minecraft/world/chunk/Chunk.java ++++ modified/net/minecraft/world/chunk/Chunk.java +@@ -41,7 +41,7 @@ + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + +-public class Chunk { ++public class Chunk implements net.minecraftforge.common.capabilities.ICapabilityProvider { + private static final Logger LOGGER = LogManager.getLogger(); + public static final ExtendedBlockStorage NULL_BLOCK_STORAGE = null; + /** Used to store block IDs, block MSBs, Sky-light maps, Block-light maps, and metadata. Each entry corresponds to a logical segment of 16x16x16 blocks, stacked vertically. */ +@@ -99,6 +99,7 @@ + + Arrays.fill(this.precipitationHeightMap, -999); + Arrays.fill(this.blockBiomeArray, (byte)-1); ++ capabilities = net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(this); + } + + public Chunk(World worldIn, ChunkPrimer primer, int x, int z) { +@@ -171,7 +172,8 @@ + + for (int l = i + 16; l > 0; l--) { + IBlockState iblockstate = this.getBlockState(j, l - 1, k); +- if (iblockstate.getLightOpacity() != 0) { ++ ++ if (this.getBlockLightOpacity(j, l - 1, k) != 0) { + this.heightMap[k << 4 | j] = l; + if (l < this.heightMapMinimum) { + this.heightMapMinimum = l; +@@ -378,11 +380,12 @@ + } + + public int getBlockLightOpacity(BlockPos pos) { +- return this.getBlockState(pos).getLightOpacity(); ++ return this.getBlockState(pos).getLightOpacity(this.world, pos); + } + + private int getBlockLightOpacity(int x, int y, int z) { +- return this.getBlockState(x, y, z).getLightOpacity(); ++ IBlockState state = this.getBlockState(x, y, z); //Forge: Can sometimes be called before we are added to the global world list. So use the less accurate one during that. It'll be recalculated later ++ return !loaded ? state.getLightOpacity() : state.getLightOpacity(world, new BlockPos(this.x << 4 | x & 15, y, this.z << 4 | z & 15)); + } + + public IBlockState getBlockState(BlockPos pos) { +@@ -430,86 +433,91 @@ + int j = pos.getY(); + int k = pos.getZ() & 15; + int l = k << 4 | i; ++ + if (j >= this.precipitationHeightMap[l] - 1) { + this.precipitationHeightMap[l] = -999; + } + + int i1 = this.heightMap[l]; + IBlockState iblockstate = this.getBlockState(pos); ++ + if (iblockstate == state) { + return null; +- } ++ } else { ++ Block block = state.getBlock(); ++ Block block1 = iblockstate.getBlock(); ++ int k1 = iblockstate.getLightOpacity(this.world, pos); // Relocate old light value lookup here, so that it is called before TE is removed. ++ ExtendedBlockStorage extendedblockstorage = this.storageArrays[j >> 4]; ++ boolean flag = false; + +- Block block = state.getBlock(); +- Block block1 = iblockstate.getBlock(); +- ExtendedBlockStorage extendedblockstorage = this.storageArrays[j >> 4]; +- boolean flag = false; +- if (extendedblockstorage == NULL_BLOCK_STORAGE) { +- if (block == Blocks.AIR) { +- return null; ++ if (extendedblockstorage == NULL_BLOCK_STORAGE) { ++ if (block == Blocks.AIR) { ++ return null; ++ } ++ ++ extendedblockstorage = new ExtendedBlockStorage(j >> 4 << 4, this.world.provider.hasSkyLight()); ++ this.storageArrays[j >> 4] = extendedblockstorage; ++ flag = j >= i1; + } + +- extendedblockstorage = new ExtendedBlockStorage(j >> 4 << 4, this.world.provider.hasSkyLight()); +- this.storageArrays[j >> 4] = extendedblockstorage; +- flag = j >= i1; +- } ++ extendedblockstorage.set(i, j & 15, k, state); + +- extendedblockstorage.set(i, j & 15, k, state); +- if (block1 != block) { +- if (!this.world.isRemote) { +- block1.breakBlock(this.world, pos, iblockstate); +- } else if (block1 instanceof ITileEntityProvider) { +- this.world.removeTileEntity(pos); ++ { //if (block1 != block) ++ if (!this.world.isRemote) { ++ if (block1 != block) //Only fire block breaks when the block changes. ++ block1.breakBlock(this.world, pos, iblockstate); ++ TileEntity te = this.getTileEntity(pos, Chunk.EnumCreateEntityType.CHECK); ++ if (te != null && te.shouldRefresh(this.world, pos, iblockstate, state)) this.world.removeTileEntity(pos); ++ } else if (block1.hasTileEntity(iblockstate)) { ++ TileEntity te = this.getTileEntity(pos, Chunk.EnumCreateEntityType.CHECK); ++ if (te != null && te.shouldRefresh(this.world, pos, iblockstate, state)) ++ this.world.removeTileEntity(pos); ++ } + } +- } + +- if (extendedblockstorage.get(i, j & 15, k).getBlock() != block) { +- return null; +- } ++ if (extendedblockstorage.get(i, j & 15, k).getBlock() != block) { ++ return null; ++ } else { ++ if (flag) { ++ this.generateSkylightMap(); ++ } else { ++ int j1 = state.getLightOpacity(this.world, pos); + +- if (flag) { +- this.generateSkylightMap(); +- } else { +- int j1 = state.getLightOpacity(); +- int k1 = iblockstate.getLightOpacity(); +- if (j1 > 0) { +- if (j >= i1) { +- this.relightBlock(i, j + 1, k); ++ if (j1 > 0) { ++ if (j >= i1) { ++ this.relightBlock(i, j + 1, k); ++ } ++ } else if (j == i1 - 1) { ++ this.relightBlock(i, j, k); ++ } ++ ++ if (j1 != k1 && (j1 < k1 || this.getLightFor(EnumSkyBlock.SKY, pos) > 0 || this.getLightFor(EnumSkyBlock.BLOCK, pos) > 0)) { ++ this.propagateSkylightOcclusion(i, k); ++ } + } +- } else if (j == i1 - 1) { +- this.relightBlock(i, j, k); +- } + +- if (j1 != k1 && (j1 < k1 || this.getLightFor(EnumSkyBlock.SKY, pos) > 0 || this.getLightFor(EnumSkyBlock.BLOCK, pos) > 0)) { +- this.propagateSkylightOcclusion(i, k); +- } +- } ++ // If capturing blocks, only run block physics for TE's. Non-TE's are handled in ForgeHooks.onPlaceItemIntoWorld ++ if (!this.world.isRemote && block1 != block && (!this.world.captureBlockSnapshots || block.hasTileEntity(state))) { ++ block.onBlockAdded(this.world, pos, state); ++ } + +- if (block1 instanceof ITileEntityProvider) { +- TileEntity tileentity = this.getTileEntity(pos, Chunk.EnumCreateEntityType.CHECK); +- if (tileentity != null) { +- tileentity.updateContainingBlockInfo(); +- } +- } ++ if (block.hasTileEntity(state)) { ++ TileEntity tileentity1 = this.getTileEntity(pos, Chunk.EnumCreateEntityType.CHECK); + +- if (!this.world.isRemote && block1 != block) { +- block.onBlockAdded(this.world, pos, state); +- } ++ if (tileentity1 == null) { ++ tileentity1 = block.createTileEntity(this.world, state); ++ this.world.setTileEntity(pos, tileentity1); ++ } + +- if (block instanceof ITileEntityProvider) { +- TileEntity tileentity1 = this.getTileEntity(pos, Chunk.EnumCreateEntityType.CHECK); +- if (tileentity1 == null) { +- tileentity1 = ((ITileEntityProvider)block).createNewTileEntity(this.world, block.getMetaFromState(state)); +- this.world.setTileEntity(pos, tileentity1); +- } ++ if (tileentity1 != null) { ++ tileentity1.updateContainingBlockInfo(); ++ } ++ } + +- if (tileentity1 != null) { +- tileentity1.updateContainingBlockInfo(); ++ this.dirty = true; ++ return iblockstate; + } + } +- +- this.dirty = true; +- return iblockstate; + } + + public int getLightFor(EnumSkyBlock type, BlockPos pos) { +@@ -587,11 +595,13 @@ + k = this.entityLists.length - 1; + } + ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.EntityEvent.EnteringChunk(entityIn, this.x, this.z, entityIn.chunkCoordX, entityIn.chunkCoordZ)); + entityIn.addedToChunk = true; + entityIn.chunkCoordX = this.x; + entityIn.chunkCoordY = k; + entityIn.chunkCoordZ = this.z; + this.entityLists[k].add(entityIn); ++ this.markDirty(); // Forge - ensure chunks are marked to save after an entity add + } + + /** removes entity using its y chunk coordinate as its index */ +@@ -610,6 +620,7 @@ + } + + this.entityLists[index].remove(entityIn); ++ this.markDirty(); // Forge - ensure chunks are marked to save after entity removals + } + + public boolean canSeeSky(BlockPos pos) { +@@ -623,24 +634,27 @@ + private TileEntity createNewTileEntity(BlockPos pos) { + IBlockState iblockstate = this.getBlockState(pos); + Block block = iblockstate.getBlock(); +- return !block.hasTileEntity() +- ? null +- : ((ITileEntityProvider)block).createNewTileEntity(this.world, iblockstate.getBlock().getMetaFromState(iblockstate)); ++ return !block.hasTileEntity(iblockstate) ++ ? null ++ : block.createTileEntity(this.world, iblockstate); + } + + @Nullable + public TileEntity getTileEntity(BlockPos pos, Chunk.EnumCreateEntityType creationMode) { + TileEntity tileentity = this.tileEntities.get(pos); ++ ++ if (tileentity != null && tileentity.isInvalid()) { ++ tileEntities.remove(pos); ++ tileentity = null; ++ } ++ + if (tileentity == null) { + if (creationMode == Chunk.EnumCreateEntityType.IMMEDIATE) { + tileentity = this.createNewTileEntity(pos); + this.world.setTileEntity(pos, tileentity); + } else if (creationMode == Chunk.EnumCreateEntityType.QUEUED) { +- this.tileEntityPosQueue.add(pos); ++ this.tileEntityPosQueue.add(pos.toImmutable()); + } +- } else if (tileentity.isInvalid()) { +- this.tileEntities.remove(pos); +- return null; + } + + return tileentity; +@@ -654,9 +668,11 @@ + } + + public void addTileEntity(BlockPos pos, TileEntity tileEntityIn) { ++ if (tileEntityIn.getWorld() != this.world) //Forge don't call unless it's changed, could screw up bad mods. + tileEntityIn.setWorld(this.world); + tileEntityIn.setPos(pos); +- if (this.getBlockState(pos).getBlock() instanceof ITileEntityProvider) { ++ ++ if (this.getBlockState(pos).getBlock().hasTileEntity(this.getBlockState(pos))) { + if (this.tileEntities.containsKey(pos)) { + this.tileEntities.get(pos).invalidate(); + } +@@ -681,12 +697,14 @@ + this.world.addTileEntities(this.tileEntities.values()); + + for (ClassInheritanceMultiMap classinheritancemultimap : this.entityLists) { +- this.world.loadEntities(classinheritancemultimap); ++ this.world.loadEntities(com.google.common.collect.ImmutableList.copyOf(classinheritancemultimap)); + } ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.ChunkEvent.Load(this)); + } + + /** Called when this Chunk is unloaded by the ChunkProvider */ + public void onUnload() { ++ java.util.Arrays.stream(entityLists).forEach(multimap -> com.google.common.collect.Lists.newArrayList(multimap.getByClass(net.minecraft.entity.player.EntityPlayer.class)).forEach(player -> world.updateEntityWithOptionalForce(player, false))); // FORGE - Fix for MC-92916 + this.loaded = false; + + for (TileEntity tileentity : this.tileEntities.values()) { +@@ -696,6 +714,7 @@ + for (ClassInheritanceMultiMap classinheritancemultimap : this.entityLists) { + this.world.unloadEntities(classinheritancemultimap); + } ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.ChunkEvent.Unload(this)); + } + + /** Sets the isModified flag for this Chunk */ +@@ -705,8 +724,8 @@ + + /** Fills the given list of all entities that intersect within the given bounding box that aren't the passed entity. */ + public void getEntitiesWithinAABBForEntity(@Nullable Entity entityIn, AxisAlignedBB aabb, List listToFill, Predicate filter) { +- int i = MathHelper.floor((aabb.minY - 2.0) / 16.0); +- int j = MathHelper.floor((aabb.maxY + 2.0) / 16.0); ++ int i = MathHelper.floor((aabb.minY - World.MAX_ENTITY_RADIUS) / 16.0); ++ int j = MathHelper.floor((aabb.maxY + World.MAX_ENTITY_RADIUS) / 16.0); + i = MathHelper.clamp(i, 0, this.entityLists.length - 1); + j = MathHelper.clamp(j, 0, this.entityLists.length - 1); + +@@ -739,8 +758,8 @@ + public void getEntitiesOfTypeWithinAABB( + Class entityClass, AxisAlignedBB aabb, List listToFill, Predicate filter + ) { +- int i = MathHelper.floor((aabb.minY - 2.0) / 16.0); +- int j = MathHelper.floor((aabb.maxY + 2.0) / 16.0); ++ int i = MathHelper.floor((aabb.minY - World.MAX_ENTITY_RADIUS) / 16.0); ++ int j = MathHelper.floor((aabb.maxY + World.MAX_ENTITY_RADIUS) / 16.0); + i = MathHelper.clamp(i, 0, this.entityLists.length - 1); + j = MathHelper.clamp(j, 0, this.entityLists.length - 1); + +@@ -807,6 +826,9 @@ + } + + protected void populate(IChunkGenerator generator) { ++ if (populating != null && net.minecraftforge.common.ForgeModContainer.logCascadingWorldGeneration) logCascadingWorldGeneration(); ++ ChunkPos prev = populating; ++ populating = this.getPos(); + if (this.isTerrainPopulated()) { + if (generator.generateStructures(this, this.x, this.z)) { + this.markDirty(); +@@ -814,8 +836,10 @@ + } else { + this.checkLight(); + generator.populate(this.x, this.z); ++ net.minecraftforge.fml.common.registry.GameRegistry.generateWorld(this.x, this.z, this.world, generator, this.world.getChunkProvider()); + this.markDirty(); + } ++ populating = prev; + } + + public BlockPos getPrecipitationHeight(BlockPos pos) { +@@ -856,7 +880,8 @@ + + while (!this.tileEntityPosQueue.isEmpty()) { + BlockPos blockpos = this.tileEntityPosQueue.poll(); +- if (this.getTileEntity(blockpos, Chunk.EnumCreateEntityType.CHECK) == null && this.getBlockState(blockpos).getBlock().hasTileEntity()) { ++ ++ if (this.getTileEntity(blockpos, Chunk.EnumCreateEntityType.CHECK) == null && this.getBlockState(blockpos).getBlock().hasTileEntity(this.getBlockState(blockpos))) { + TileEntity tileentity = this.createNewTileEntity(blockpos); + this.world.setTileEntity(blockpos, tileentity); + this.world.markBlockRangeForRenderUpdate(blockpos, blockpos); +@@ -912,6 +937,12 @@ + */ + @SideOnly(Side.CLIENT) + public void read(PacketBuffer buf, int availableSections, boolean groundUpContinuous) { ++ for(TileEntity tileEntity : tileEntities.values()) { ++ tileEntity.updateContainingBlockInfo(); ++ tileEntity.getBlockMetadata(); ++ tileEntity.getBlockType(); ++ } ++ + boolean flag = this.world.provider.hasSkyLight(); + + for (int i = 0; i < this.storageArrays.length; i++) { +@@ -948,9 +979,15 @@ + this.isTerrainPopulated = true; + this.generateHeightMap(); + ++ List invalidList = new java.util.ArrayList<>(); ++ + for (TileEntity tileentity : this.tileEntities.values()) { ++ if (tileentity.shouldRefresh(this.world, tileentity.getPos(), tileentity.getBlockType().getStateFromMeta(tileentity.getBlockMetadata()), getBlockState(tileentity.getPos()))) ++ invalidList.add(tileentity); + tileentity.updateContainingBlockInfo(); + } ++ ++ for (TileEntity te : invalidList) te.invalidate(); + } + + public Biome getBiome(BlockPos pos, BiomeProvider provider) { +@@ -958,7 +995,12 @@ + int j = pos.getZ() & 15; + int k = this.blockBiomeArray[j << 4 | i] & 255; + if (k == 255) { +- Biome biome = provider.getBiome(pos, Biomes.PLAINS); ++ // Forge: checking for client ensures that biomes are only generated on integrated server ++ // in singleplayer. Generating biomes on the client may corrupt the biome ID arrays on ++ // the server while they are being generated because IntCache can't be thread safe, ++ // so client and server may end up filling the same array. ++ // This is not necessary in 1.13 and newer versions. ++ Biome biome = world.isRemote ? Biomes.PLAINS : provider.getBiome(pos, Biomes.PLAINS); + k = Biome.getIdForBiome(biome); + this.blockBiomeArray[j << 4 | i] = (byte)(k & 0xFF); + } +@@ -1005,10 +1047,11 @@ + BlockPos blockpos1 = blockpos.add(k, (j << 4) + i1, l); + boolean flag = i1 == 0 || i1 == 15 || k == 0 || k == 15 || l == 0 || l == 15; + if (this.storageArrays[j] == NULL_BLOCK_STORAGE && flag +- || this.storageArrays[j] != NULL_BLOCK_STORAGE && this.storageArrays[j].get(k, i1, l).getMaterial() == Material.AIR) { ++ || this.storageArrays[j] != NULL_BLOCK_STORAGE && this.storageArrays[j].get(k, i1, l).getBlock().isAir(this.storageArrays[j].get(k, i1, l), this.world, blockpos1)) { + for (EnumFacing enumfacing : EnumFacing.values()) { + BlockPos blockpos2 = blockpos1.offset(enumfacing); +- if (this.world.getBlockState(blockpos2).getLightValue() > 0) { ++ ++ if (this.world.getBlockState(blockpos2).getLightValue(this.world, blockpos2) > 0) { + this.world.checkLight(blockpos2); + } + } +@@ -1104,7 +1147,8 @@ + + for (int l = blockpos$mutableblockpos.getY(); l > 0; l--) { + blockpos$mutableblockpos.setPos(blockpos$mutableblockpos.getX(), l, blockpos$mutableblockpos.getZ()); +- if (this.getBlockState(blockpos$mutableblockpos).getLightValue() > 0) { ++ ++ if (this.getBlockState(blockpos$mutableblockpos).getLightValue(this.world, blockpos$mutableblockpos) > 0) { + this.world.checkLight(blockpos$mutableblockpos); + } + } +@@ -1134,6 +1178,7 @@ + LOGGER.warn("Could not set level chunk heightmap, array length is {} instead of {}", newHeightMap.length, this.heightMap.length); + } else { + System.arraycopy(newHeightMap, 0, this.heightMap, 0, this.heightMap.length); ++ this.heightMapMinimum = com.google.common.primitives.Ints.min(this.heightMap); // Forge: fix MC-117412 + } + } + +@@ -1190,4 +1235,48 @@ + QUEUED, + CHECK; + } ++ ++ /* ======================================== FORGE START =====================================*/ ++ /** ++ * Removes the tile entity at the specified position, only if it's ++ * marked as invalid. ++ */ ++ public void removeInvalidTileEntity(BlockPos pos) { ++ if (loaded) { ++ TileEntity entity = (TileEntity)tileEntities.get(pos); ++ if (entity != null && entity.isInvalid()) { ++ tileEntities.remove(pos); ++ } ++ } ++ } ++ ++ private static ChunkPos populating = null; // keep track of cascading chunk generation during chunk population ++ ++ private void logCascadingWorldGeneration() { ++ net.minecraftforge.fml.common.ModContainer activeModContainer = net.minecraftforge.fml.common.Loader.instance().activeModContainer(); ++ String format = "{} loaded a new chunk {} in dimension {} ({}) while populating chunk {}, causing cascading worldgen lag."; ++ ++ if (activeModContainer == null) { // vanilla minecraft has problems too (MC-114332), log it at a quieter level. ++ net.minecraftforge.fml.common.FMLLog.log.debug(format, "Minecraft", this.getPos(), this.world.provider.getDimension(), this.world.provider.getDimensionType().getName(), populating); ++ net.minecraftforge.fml.common.FMLLog.log.debug("Consider setting 'fixVanillaCascading' to 'true' in the Forge config to fix many cases where this occurs in the base game."); ++ } else { ++ net.minecraftforge.fml.common.FMLLog.log.warn(format, activeModContainer.getName(), this.getPos(), this.world.provider.getDimension(), this.world.provider.getDimensionType().getName(), populating); ++ net.minecraftforge.fml.common.FMLLog.log.warn("Please report this to the mod's issue tracker. This log can be disabled in the Forge config."); ++ } ++ } ++ ++ private final net.minecraftforge.common.capabilities.CapabilityDispatcher capabilities; ++ @Nullable ++ public net.minecraftforge.common.capabilities.CapabilityDispatcher getCapabilities() { ++ return capabilities; ++ } ++ @Override ++ public boolean hasCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable EnumFacing facing) { ++ return capabilities == null ? false : capabilities.hasCapability(capability, facing); ++ } ++ @Override ++ @Nullable ++ public T getCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable EnumFacing facing) { ++ return capabilities == null ? null : capabilities.getCapability(capability, facing); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/world/chunk/storage/AnvilChunkLoader.java.patch b/module/minecraft/patches/net/minecraft/world/chunk/storage/AnvilChunkLoader.java.patch new file mode 100644 index 000000000..143abf219 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/chunk/storage/AnvilChunkLoader.java.patch @@ -0,0 +1,217 @@ +--- original/net/minecraft/world/chunk/storage/AnvilChunkLoader.java ++++ modified/net/minecraft/world/chunk/storage/AnvilChunkLoader.java +@@ -50,10 +50,28 @@ + this.fixer = dataFixerIn; + } + +- /** Loads the specified(XZ) chunk into the specified world. */ ++ @Deprecated // TODO: remove (1.13) ++ public boolean chunkExists(World world, int x, int z) { ++ return isChunkGeneratedAt(x, z); ++ } ++ + @Nullable + @Override + public Chunk loadChunk(World worldIn, int x, int z) throws IOException { ++ Object[] data = this.loadChunk__Async(worldIn, x, z); ++ ++ if (data != null) { ++ Chunk chunk = (Chunk) data[0]; ++ NBTTagCompound nbttagcompound = (NBTTagCompound) data[1]; ++ this.loadEntities(worldIn, nbttagcompound.getCompoundTag("Level"), chunk); ++ return chunk; ++ } ++ ++ return null; ++ } ++ ++ @Nullable ++ public Object[] loadChunk__Async(World worldIn, int x, int z) throws IOException { + ChunkPos chunkpos = new ChunkPos(x, z); + NBTTagCompound nbttagcompound = this.chunksToSave.get(chunkpos); + if (nbttagcompound == null) { +@@ -63,9 +81,10 @@ + } + + nbttagcompound = this.fixer.process(FixTypes.CHUNK, CompressedStreamTools.read(datainputstream)); ++ datainputstream.close(); // Forge: close stream after use + } + +- return this.checkedReadChunkFromNBT(worldIn, x, z, nbttagcompound); ++ return this.checkedReadChunkFromNBT__Async(worldIn, x, z, nbttagcompound); + } + + @Override +@@ -78,34 +97,59 @@ + /** Wraps readChunkFromNBT. Checks the coordinates and several NBT tags. */ + @Nullable + protected Chunk checkedReadChunkFromNBT(World worldIn, int x, int z, NBTTagCompound compound) { ++ Object[] data = this.checkedReadChunkFromNBT__Async(worldIn, x, z, compound); ++ return data != null ? (Chunk)data[0] : null; ++ } ++ ++ @Nullable ++ protected Object[] checkedReadChunkFromNBT__Async(World worldIn, int x, int z, NBTTagCompound compound) { + if (!compound.hasKey("Level", 10)) { + LOGGER.error("Chunk file at {},{} is missing level data, skipping", x, z); + return null; +- } ++ } else { ++ NBTTagCompound nbttagcompound = compound.getCompoundTag("Level"); + +- NBTTagCompound nbttagcompound = compound.getCompoundTag("Level"); +- if (!nbttagcompound.hasKey("Sections", 9)) { +- LOGGER.error("Chunk file at {},{} is missing block data, skipping", x, z); +- return null; +- } ++ if (!nbttagcompound.hasKey("Sections", 9)) { ++ LOGGER.error("Chunk file at {},{} is missing block data, skipping", x, z); ++ return null; ++ } else { ++ Chunk chunk = this.readChunkFromNBT(worldIn, nbttagcompound); + +- Chunk chunk = this.readChunkFromNBT(worldIn, nbttagcompound); +- if (!chunk.isAtLocation(x, z)) { +- LOGGER.error( +- "Chunk file at {},{} is in the wrong location; relocating. (Expected {}, {}, got {}, {})", +- x, +- z, +- x, +- z, +- chunk.x, +- chunk.z +- ); +- nbttagcompound.setInteger("xPos", x); +- nbttagcompound.setInteger("zPos", z); +- chunk = this.readChunkFromNBT(worldIn, nbttagcompound); +- } ++ if (!chunk.isAtLocation(x, z)) { ++ LOGGER.error( ++ "Chunk file at {},{} is in the wrong location; relocating. (Expected {}, {}, got {}, {})", ++ x, ++ z, ++ x, ++ z, ++ chunk.x, ++ chunk.z ++ ); ++ nbttagcompound.setInteger("xPos", x); ++ nbttagcompound.setInteger("zPos", z); + +- return chunk; ++ // Have to move tile entities since we don't load them at this stage ++ NBTTagList _tileEntities = nbttagcompound.getTagList("TileEntities", 10); ++ ++ if (_tileEntities != null) { ++ for (int te = 0; te < _tileEntities.tagCount(); te++) { ++ NBTTagCompound _nbt = (NBTTagCompound) _tileEntities.getCompoundTagAt(te); ++ _nbt.setInteger("x", x * 16 + (_nbt.getInteger("x") - chunk.x * 16)); ++ _nbt.setInteger("z", z * 16 + (_nbt.getInteger("z") - chunk.z * 16)); ++ } ++ } ++ ++ chunk = this.readChunkFromNBT(worldIn, nbttagcompound); ++ } ++ ++ Object[] data = new Object[2]; ++ data[0] = chunk; ++ data[1] = compound; ++ // event is fired in ChunkIOProvider.callStage2 since it must be fired after TE's load. ++ // MinecraftForge.EVENT_BUS.post(new ChunkDataEvent.Load(chunk, par4NBTTagCompound)); ++ return data; ++ } ++ } + } + + @Override +@@ -117,7 +161,10 @@ + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + nbttagcompound.setTag("Level", nbttagcompound1); + nbttagcompound.setInteger("DataVersion", 1343); ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().getDataFixer().writeVersionData(nbttagcompound); + this.writeChunkToNBT(chunkIn, worldIn, nbttagcompound1); ++ net.minecraftforge.common.ForgeChunkManager.storeChunkNBT(chunkIn, nbttagcompound1); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.ChunkDataEvent.Save(chunkIn, nbttagcompound)); + this.addChunkToPending(chunkIn.getPos(), nbttagcompound); + } catch (Exception exception) { + LOGGER.error("Failed to save chunk", exception); +@@ -275,10 +322,16 @@ + for (int i = 0; i < chunkIn.getEntityLists().length; i++) { + for (Entity entity : chunkIn.getEntityLists()[i]) { + NBTTagCompound nbttagcompound2 = new NBTTagCompound(); ++ ++ try { + if (entity.writeToNBTOptional(nbttagcompound2)) { + chunkIn.setHasEntities(true); + nbttaglist1.appendTag(nbttagcompound2); + } ++ } catch (Exception e) { ++ net.minecraftforge.fml.common.FMLLog.log.error("An Entity type {} has thrown an exception trying to write state. It will not persist. Report this to the mod author", ++ entity.getClass().getName(), e); ++ } + } + } + +@@ -286,8 +339,13 @@ + NBTTagList nbttaglist2 = new NBTTagList(); + + for (TileEntity tileentity : chunkIn.getTileEntityMap().values()) { ++ try { + NBTTagCompound nbttagcompound3 = tileentity.writeToNBT(new NBTTagCompound()); + nbttaglist2.appendTag(nbttagcompound3); ++ } catch (Exception e) { ++ net.minecraftforge.fml.common.FMLLog.log.error("A TileEntity type {} has throw an exception trying to write state. It will not persist. Report this to the mod author", ++ tileentity.getClass().getName(), e); ++ } + } + + compound.setTag("TileEntities", nbttaglist2); +@@ -310,6 +368,14 @@ + + compound.setTag("TileTicks", nbttaglist3); + } ++ ++ if (chunkIn.getCapabilities() != null) { ++ try { ++ compound.setTag("ForgeCaps", chunkIn.getCapabilities().serializeNBT()); ++ } catch (Exception exception) { ++ net.minecraftforge.fml.common.FMLLog.log.error("A capability provider has thrown an exception trying to write state. It will not persist. Report this to the mod author", exception); ++ } ++ } + } + + /** Reads the data stored in the passed NBTTagCompound and creates a Chunk with that data in the passed World. Returns the created Chunk. */ +@@ -348,6 +414,15 @@ + chunk.setBiomeArray(compound.getByteArray("Biomes")); + } + ++ if (chunk.getCapabilities() != null && compound.hasKey("ForgeCaps")) { ++ chunk.getCapabilities().deserializeNBT(compound.getCompoundTag("ForgeCaps")); ++ } ++ ++ // End this method here and split off entity loading to another method ++ return chunk; ++ } ++ ++ public void loadEntities(World worldIn, NBTTagCompound compound, Chunk chunk) { + NBTTagList nbttaglist1 = compound.getTagList("Entities", 10); + + for (int j1 = 0; j1 < nbttaglist1.tagCount(); j1++) { +@@ -386,8 +461,6 @@ + ); + } + } +- +- return chunk; + } + + @Nullable +@@ -481,4 +554,8 @@ + + return entity; + } ++ ++ public int getPendingSaveCount() { ++ return this.chunksToSave.size(); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/world/chunk/storage/AnvilSaveHandler.java.patch b/module/minecraft/patches/net/minecraft/world/chunk/storage/AnvilSaveHandler.java.patch new file mode 100644 index 000000000..2dd54c148 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/chunk/storage/AnvilSaveHandler.java.patch @@ -0,0 +1,20 @@ +--- original/net/minecraft/world/chunk/storage/AnvilSaveHandler.java ++++ modified/net/minecraft/world/chunk/storage/AnvilSaveHandler.java +@@ -20,14 +20,11 @@ + @Override + public IChunkLoader getChunkLoader(WorldProvider provider) { + File file1 = this.getWorldDirectory(); +- if (provider instanceof WorldProviderHell) { +- File file3 = new File(file1, "DIM-1"); ++ ++ if (provider.getSaveFolder() != null) { ++ File file3 = new File(file1, provider.getSaveFolder()); + file3.mkdirs(); + return new AnvilChunkLoader(file3, this.dataFixer); +- } else if (provider instanceof WorldProviderEnd) { +- File file2 = new File(file1, "DIM1"); +- file2.mkdirs(); +- return new AnvilChunkLoader(file2, this.dataFixer); + } else { + return new AnvilChunkLoader(file1, this.dataFixer); + } diff --git a/module/minecraft/patches/net/minecraft/world/chunk/storage/ExtendedBlockStorage.java.patch b/module/minecraft/patches/net/minecraft/world/chunk/storage/ExtendedBlockStorage.java.patch new file mode 100644 index 000000000..e85543cfc --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/chunk/storage/ExtendedBlockStorage.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/world/chunk/storage/ExtendedBlockStorage.java ++++ modified/net/minecraft/world/chunk/storage/ExtendedBlockStorage.java +@@ -37,6 +37,8 @@ + } + + public void set(int x, int y, int z, IBlockState state) { ++ if (state instanceof net.minecraftforge.common.property.IExtendedBlockState) ++ state = ((net.minecraftforge.common.property.IExtendedBlockState) state).getClean(); + IBlockState iblockstate = this.get(x, y, z); + Block block = iblockstate.getBlock(); + Block block1 = state.getBlock(); diff --git a/module/minecraft/patches/net/minecraft/world/chunk/storage/RegionFile.java.patch b/module/minecraft/patches/net/minecraft/world/chunk/storage/RegionFile.java.patch new file mode 100644 index 000000000..828bf346f --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/chunk/storage/RegionFile.java.patch @@ -0,0 +1,107 @@ +--- original/net/minecraft/world/chunk/storage/RegionFile.java ++++ modified/net/minecraft/world/chunk/storage/RegionFile.java +@@ -18,6 +18,9 @@ + import net.minecraft.server.MinecraftServer; + + public class RegionFile { ++ // Minecraft is limited to 256 sections per chunk. So 1MB. This can easily be override. ++ // So we extend this to use the REAL size when the count is maxed by seeking to that section and reading the length. ++ private static final boolean FORGE_ENABLE_EXTENDED_SAVE = Boolean.parseBoolean(System.getProperty("forge.enableExtendedSave", "true")); + private static final byte[] EMPTY_SECTOR = new byte[4096]; + private final File fileName; + private RandomAccessFile dataFile; +@@ -64,11 +67,22 @@ + for (int j1 = 0; j1 < 1024; j1++) { + int k = this.dataFile.readInt(); + this.offsets[j1] = k; +- if (k != 0 && (k >> 8) + (k & 0xFF) <= this.sectorFree.size()) { +- for (int l = 0; l < (k & 0xFF); l++) { +- this.sectorFree.set((k >> 8) + l, false); ++ ++ int length = k & 255; ++ if (length == 255) { ++ if ((k >> 8) <= this.sectorFree.size()) ++ { // We're maxed out, so we need to read the proper length from the section ++ this.dataFile.seek((k >> 8) * 4096); ++ length = (this.dataFile.readInt() + 4)/ 4096 + 1; ++ this.dataFile.seek(j1 * 4 + 4); //Go back to where we were + } + } ++ if (k != 0 && (k >> 8) + length <= this.sectorFree.size()) { ++ for (int l = 0; l < length; l++) { ++ this.sectorFree.set((k >> 8) + l, false); ++ } ++ } else if (length > 0) ++ net.minecraftforge.fml.common.FMLLog.log.warn("Invalid chunk: ({}, {}) Offset: {} Length: {} runs off end file. {}", j1 % 32, (int)(j1 / 32), k >> 8, length, fileNameIn); + } + + for (int k1 = 0; k1 < 1024; k1++) { +@@ -80,7 +94,11 @@ + } + } + +- /** Returns an uncompressed chunk stream from the region file. */ ++ @Deprecated // TODO: remove (1.13) ++ public synchronized boolean chunkExists(int x, int z) { ++ return isChunkSaved(x, z); ++ } ++ + @Nullable + public synchronized DataInputStream getChunkDataInputStream(int x, int z) { + if (this.outOfBounds(x, z)) { +@@ -94,14 +112,21 @@ + } else { + int j = i >> 8; + int k = i & 0xFF; ++ if (k == 255) { ++ this.dataFile.seek(j * 4096); ++ k = (this.dataFile.readInt() + 4) / 4096 + 1; ++ } ++ + if (j + k > this.sectorFree.size()) { + return null; + } else { + this.dataFile.seek(j * 4096); + int l = this.dataFile.readInt(); + if (l > 4096 * k) { ++ net.minecraftforge.fml.common.FMLLog.log.warn("Invalid chunk: ({}, {}) Offset: {} Invalid Size: {}>{} {}", x, z, j, l, k * 4096, fileName); + return null; + } else if (l <= 0) { ++ net.minecraftforge.fml.common.FMLLog.log.warn("Invalid chunk: ({}, {}) Offset: {} Invalid Size: {} {}", x, z, j, l, fileName); + return null; + } else { + byte b0 = this.dataFile.readByte(); +@@ -138,9 +163,14 @@ + int i = this.getOffset(x, z); + int j = i >> 8; + int k = i & 0xFF; ++ if (k == 255) { ++ this.dataFile.seek(j * 4096); ++ k = (this.dataFile.readInt() + 4) / 4096 + 1; ++ } + int l = (length + 5) / 4096 + 1; + if (l >= 256) { +- return; ++ if (!FORGE_ENABLE_EXTENDED_SAVE) return; ++ net.minecraftforge.fml.common.FMLLog.log.warn("Large Chunk Detected: ({}, {}) Size: {} {}", x, z, l, fileName); + } + + if (j != 0 && k == l) { +@@ -173,7 +203,7 @@ + + if (j1 >= l) { + j = l1; +- this.setOffset(x, z, j << 8 | l); ++ this.setOffset(x, z, j << 8 | (l > 255 ? 255 : l)); + + for (int j2 = 0; j2 < l; j2++) { + this.sectorFree.set(j + j2, false); +@@ -191,7 +221,7 @@ + + this.sizeDelta += 4096 * l; + this.write(j, data, length); +- this.setOffset(x, z, j << 8 | l); ++ this.setOffset(x, z, j << 8 | (l > 255 ? 255 : l)); + } + } + diff --git a/module/minecraft/patches/net/minecraft/world/end/DragonFightManager.java.patch b/module/minecraft/patches/net/minecraft/world/end/DragonFightManager.java.patch new file mode 100644 index 000000000..b7403f58a --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/end/DragonFightManager.java.patch @@ -0,0 +1,33 @@ +--- original/net/minecraft/world/end/DragonFightManager.java ++++ modified/net/minecraft/world/end/DragonFightManager.java +@@ -82,6 +82,8 @@ + + this.dragonKilled = compound.getBoolean("DragonKilled"); + this.previouslyKilled = compound.getBoolean("PreviouslyKilled"); ++ this.scanForLegacyFight = !compound.getBoolean("LegacyScanPerformed"); // Forge: fix MC-105080 ++ + if (compound.getBoolean("IsRespawning")) { + this.respawnState = DragonSpawnManager.START; + } +@@ -123,6 +125,8 @@ + + nbttagcompound.setBoolean("DragonKilled", this.dragonKilled); + nbttagcompound.setBoolean("PreviouslyKilled", this.previouslyKilled); ++ nbttagcompound.setBoolean("LegacyScanPerformed", !this.scanForLegacyFight); // Forge: fix MC-105080 ++ + if (this.exitPortalLocation != null) { + nbttagcompound.setTag("ExitPortalLocation", NBTUtil.createPosTag(this.exitPortalLocation)); + } +@@ -481,4 +485,12 @@ + } + } + } ++ ++ public void addPlayer(EntityPlayerMP player) { ++ this.bossInfo.addPlayer(player); ++ } ++ ++ public void removePlayer(EntityPlayerMP player) { ++ this.bossInfo.removePlayer(player); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/world/gen/ChunkGeneratorEnd.java.patch b/module/minecraft/patches/net/minecraft/world/gen/ChunkGeneratorEnd.java.patch new file mode 100644 index 000000000..39d268a37 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/ChunkGeneratorEnd.java.patch @@ -0,0 +1,73 @@ +--- original/net/minecraft/world/gen/ChunkGeneratorEnd.java ++++ modified/net/minecraft/world/gen/ChunkGeneratorEnd.java +@@ -48,6 +48,9 @@ + double[] ar; + double[] br; + private final WorldGenEndIsland endIslands = new WorldGenEndIsland(); ++ // temporary variables used during event handling ++ private int chunkX = 0; ++ private int chunkZ = 0; + + public ChunkGeneratorEnd(World p_i47241_1_, boolean p_i47241_2_, long p_i47241_3_, BlockPos p_i47241_5_) { + this.world = p_i47241_1_; +@@ -60,6 +63,17 @@ + this.noiseGen5 = new NoiseGeneratorOctaves(this.rand, 10); + this.noiseGen6 = new NoiseGeneratorOctaves(this.rand, 16); + this.islandNoise = new NoiseGeneratorSimplex(this.rand); ++ ++ net.minecraftforge.event.terraingen.InitNoiseGensEvent.ContextEnd ctx = ++ new net.minecraftforge.event.terraingen.InitNoiseGensEvent.ContextEnd(lperlinNoise1, lperlinNoise2, perlinNoise1, noiseGen5, noiseGen6, islandNoise); ++ ctx = net.minecraftforge.event.terraingen.TerrainGen.getModdedNoiseGenerators(p_i47241_1_, this.rand, ctx); ++ this.lperlinNoise1 = ctx.getLPerlin1(); ++ this.lperlinNoise2 = ctx.getLPerlin2(); ++ this.perlinNoise1 = ctx.getPerlin(); ++ this.noiseGen5 = ctx.getDepth(); ++ this.noiseGen6 = ctx.getScale(); ++ this.islandNoise = ctx.getIsland(); ++ this.endCityGen = (MapGenEndCity) net.minecraftforge.event.terraingen.TerrainGen.getModdedMapGen(this.endCityGen, net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.END_CITY); + } + + /** Generates a bare-bones chunk of nothing but stone or ocean blocks, formed, but featureless. */ +@@ -123,6 +137,7 @@ + } + + public void buildSurfaces(ChunkPrimer primer) { ++ if (!net.minecraftforge.event.ForgeEventFactory.onReplaceBiomeBlocks(this, this.chunkX, this.chunkZ, primer, this.world)) return; + for (int i = 0; i < 16; i++) { + for (int j = 0; j < 16; j++) { + int k = 1; +@@ -155,6 +170,7 @@ + /** Generates the chunk at the specified position, from scratch */ + @Override + public Chunk generateChunk(int x, int z) { ++ this.chunkX = x; this.chunkZ = z; + this.rand.setSeed(x * 341873128712L + z * 132897987541L); + ChunkPrimer chunkprimer = new ChunkPrimer(); + this.biomesForGeneration = this.world.getBiomeProvider().getBiomes(this.biomesForGeneration, x * 16, z * 16, 16, 16); +@@ -219,6 +235,10 @@ + } + + private double[] getHeights(double[] p_185963_1_, int p_185963_2_, int p_185963_3_, int p_185963_4_, int p_185963_5_, int p_185963_6_, int p_185963_7_) { ++ net.minecraftforge.event.terraingen.ChunkGeneratorEvent.InitNoiseField event = new net.minecraftforge.event.terraingen.ChunkGeneratorEvent.InitNoiseField(this, p_185963_1_, p_185963_2_, p_185963_3_, p_185963_4_, p_185963_5_, p_185963_6_, p_185963_7_); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event); ++ if (event.getResult() == net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) return event.getNoisefield(); ++ + if (p_185963_1_ == null) { + p_185963_1_ = new double[p_185963_5_ * p_185963_6_ * p_185963_7_]; + } +@@ -288,6 +308,7 @@ + @Override + public void populate(int x, int z) { + BlockFalling.fallInstantly = true; ++ net.minecraftforge.event.ForgeEventFactory.onChunkPopulate(true, this, this.world, this.rand, x, z, false); + BlockPos blockpos = new BlockPos(x * 16, 0, z * 16); + if (this.mapFeaturesEnabled) { + this.endCityGen.generateStructure(this.world, this.rand, new ChunkPos(x, z)); +@@ -348,6 +369,7 @@ + } + } + ++ net.minecraftforge.event.ForgeEventFactory.onChunkPopulate(false, this, this.world, this.rand, x, z, false); + BlockFalling.fallInstantly = false; + } + diff --git a/module/minecraft/patches/net/minecraft/world/gen/ChunkGeneratorFlat.java.patch b/module/minecraft/patches/net/minecraft/world/gen/ChunkGeneratorFlat.java.patch new file mode 100644 index 000000000..dca0a53e4 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/ChunkGeneratorFlat.java.patch @@ -0,0 +1,29 @@ +--- original/net/minecraft/world/gen/ChunkGeneratorFlat.java ++++ modified/net/minecraft/world/gen/ChunkGeneratorFlat.java +@@ -143,6 +143,7 @@ + */ + @Override + public void populate(int x, int z) { ++ net.minecraft.block.BlockFalling.fallInstantly = true; + int i = x * 16; + int j = z * 16; + BlockPos blockpos = new BlockPos(i, 0, j); +@@ -154,6 +155,8 @@ + this.random.setSeed(x * k + z * l ^ this.world.getSeed()); + ChunkPos chunkpos = new ChunkPos(x, z); + ++ net.minecraftforge.event.ForgeEventFactory.onChunkPopulate(true, this, this.world, this.random, x, z, flag); ++ + for (MapGenStructure mapgenstructure : this.structureGenerators.values()) { + boolean flag1 = mapgenstructure.generateStructure(this.world, this.random, chunkpos); + if (mapgenstructure instanceof MapGenVillage) { +@@ -193,6 +196,9 @@ + if (this.hasDecoration) { + biome.decorate(this.world, this.random, blockpos); + } ++ ++ net.minecraftforge.event.ForgeEventFactory.onChunkPopulate(false, this, this.world, this.random, x, z, flag); ++ net.minecraft.block.BlockFalling.fallInstantly = false; + } + + /** Called to generate additional structures after initial worldgen, used by ocean monuments */ diff --git a/module/minecraft/patches/net/minecraft/world/gen/ChunkGeneratorHell.java.patch b/module/minecraft/patches/net/minecraft/world/gen/ChunkGeneratorHell.java.patch new file mode 100644 index 000000000..88940ec7f --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/ChunkGeneratorHell.java.patch @@ -0,0 +1,130 @@ +--- original/net/minecraft/world/gen/ChunkGeneratorHell.java ++++ modified/net/minecraft/world/gen/ChunkGeneratorHell.java +@@ -82,6 +82,19 @@ + this.scaleNoise = new NoiseGeneratorOctaves(this.rand, 10); + this.depthNoise = new NoiseGeneratorOctaves(this.rand, 16); + worldIn.setSeaLevel(63); ++ ++ net.minecraftforge.event.terraingen.InitNoiseGensEvent.ContextHell ctx = ++ new net.minecraftforge.event.terraingen.InitNoiseGensEvent.ContextHell(lperlinNoise1, lperlinNoise2, perlinNoise1, slowsandGravelNoiseGen, netherrackExculsivityNoiseGen, scaleNoise, depthNoise); ++ ctx = net.minecraftforge.event.terraingen.TerrainGen.getModdedNoiseGenerators(worldIn, this.rand, ctx); ++ this.lperlinNoise1 = ctx.getLPerlin1(); ++ this.lperlinNoise2 = ctx.getLPerlin2(); ++ this.perlinNoise1 = ctx.getPerlin(); ++ this.slowsandGravelNoiseGen = ctx.getPerlin2(); ++ this.netherrackExculsivityNoiseGen = ctx.getPerlin3(); ++ this.scaleNoise = ctx.getScale(); ++ this.depthNoise = ctx.getDepth(); ++ this.genNetherBridge = (MapGenNetherBridge)net.minecraftforge.event.terraingen.TerrainGen.getModdedMapGen(genNetherBridge, net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.NETHER_BRIDGE); ++ this.genNetherCaves = net.minecraftforge.event.terraingen.TerrainGen.getModdedMapGen(genNetherCaves, net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.NETHER_CAVE); + } + + public void prepareHeights(int p_185936_1_, int p_185936_2_, ChunkPrimer primer) { +@@ -149,6 +162,7 @@ + } + + public void buildSurfaces(int p_185937_1_, int p_185937_2_, ChunkPrimer primer) { ++ if (!net.minecraftforge.event.ForgeEventFactory.onReplaceBiomeBlocks(this, p_185937_1_, p_185937_2_, primer, this.world)) return; + int i = this.world.getSeaLevel() + 1; + double d0 = 0.03125; + this.slowsandNoise = this.slowsandGravelNoiseGen.generateNoiseOctaves(this.slowsandNoise, p_185937_1_ * 16, p_185937_2_ * 16, 0, 16, 16, 1, 0.03125, 0.03125, 1.0); +@@ -240,6 +254,10 @@ + p_185938_1_ = new double[p_185938_5_ * p_185938_6_ * p_185938_7_]; + } + ++ net.minecraftforge.event.terraingen.ChunkGeneratorEvent.InitNoiseField event = new net.minecraftforge.event.terraingen.ChunkGeneratorEvent.InitNoiseField(this, p_185938_1_, p_185938_2_, p_185938_3_, p_185938_4_, p_185938_5_, p_185938_6_, p_185938_7_); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event); ++ if (event.getResult() == net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) return event.getNoisefield(); ++ + double d0 = 684.412; + double d1 = 2053.236; + this.noiseData4 = this.scaleNoise +@@ -327,6 +345,7 @@ + @Override + public void populate(int x, int z) { + BlockFalling.fallInstantly = true; ++ net.minecraftforge.event.ForgeEventFactory.onChunkPopulate(true, this, this.world, this.rand, x, z, false); + int i = x * 16; + int j = z * 16; + BlockPos blockpos = new BlockPos(i, 0, j); +@@ -334,6 +353,7 @@ + ChunkPos chunkpos = new ChunkPos(x, z); + this.genNetherBridge.generateStructure(this.world, this.rand, chunkpos); + ++ if (net.minecraftforge.event.terraingen.TerrainGen.populate(this, this.world, this.rand, x, z, false, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.NETHER_LAVA)) + for (int k = 0; k < 8; k++) { + this.hellSpringGen + .generate( +@@ -343,6 +363,7 @@ + ); + } + ++ if (net.minecraftforge.event.terraingen.TerrainGen.populate(this, this.world, this.rand, x, z, false, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.FIRE)) + for (int i1 = 0; i1 < this.rand.nextInt(this.rand.nextInt(10) + 1) + 1; i1++) { + this.fireFeature + .generate( +@@ -352,6 +373,7 @@ + ); + } + ++ if (net.minecraftforge.event.terraingen.TerrainGen.populate(this, this.world, this.rand, x, z, false, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.GLOWSTONE)) { + for (int j1 = 0; j1 < this.rand.nextInt(this.rand.nextInt(10) + 1); j1++) { + this.lightGemGen + .generate( +@@ -370,6 +392,12 @@ + ); + } + ++ }//Forge: End doGLowstone ++ ++ net.minecraftforge.event.ForgeEventFactory.onChunkPopulate(false, this, this.world, this.rand, x, z, false); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.terraingen.DecorateBiomeEvent.Pre(this.world, this.rand, chunkpos)); ++ ++ if (net.minecraftforge.event.terraingen.TerrainGen.decorate(this.world, this.rand, chunkpos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.SHROOM)) { + if (this.rand.nextBoolean()) { + this.brownMushroomFeature + .generate( +@@ -388,6 +416,8 @@ + ); + } + ++ } ++ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(this.world, this.rand, quartzGen, blockpos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.QUARTZ)) + for (int l1 = 0; l1 < 16; l1++) { + this.quartzGen + .generate( +@@ -399,6 +429,7 @@ + + int i2 = this.world.getSeaLevel() / 2 + 1; + ++ if (net.minecraftforge.event.terraingen.TerrainGen.populate(this, this.world, this.rand, x, z, false, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.NETHER_MAGMA)) + for (int l = 0; l < 4; l++) { + this.magmaGen + .generate( +@@ -408,16 +439,21 @@ + ); + } + ++ if (net.minecraftforge.event.terraingen.TerrainGen.populate(this, this.world, this.rand, x, z, false, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.NETHER_LAVA2)) + for (int j2 = 0; j2 < 16; j2++) { ++ int offset = net.minecraftforge.common.ForgeModContainer.fixVanillaCascading ? 8 : 0; // MC-117810 + this.lavaTrapGen +- .generate( +- this.world, +- this.rand, +- blockpos.add(this.rand.nextInt(16), this.rand.nextInt(108) + 10, this.rand.nextInt(16)) +- ); ++ .generate( ++ this.world, ++ this.rand, ++ blockpos.add(this.rand.nextInt(16) + offset, this.rand.nextInt(108) + 10, this.rand.nextInt(16) + offset) ++ ); + } + + biome.decorate(this.world, this.rand, new BlockPos(i, 0, j)); ++ ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.terraingen.DecorateBiomeEvent.Post(this.world, this.rand, blockpos)); ++ + BlockFalling.fallInstantly = false; + } + diff --git a/module/minecraft/patches/net/minecraft/world/gen/ChunkGeneratorOverworld.java.patch b/module/minecraft/patches/net/minecraft/world/gen/ChunkGeneratorOverworld.java.patch new file mode 100644 index 000000000..4bfaa01c5 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/ChunkGeneratorOverworld.java.patch @@ -0,0 +1,113 @@ +--- original/net/minecraft/world/gen/ChunkGeneratorOverworld.java ++++ modified/net/minecraft/world/gen/ChunkGeneratorOverworld.java +@@ -59,6 +59,16 @@ + double[] depthRegion; + + public ChunkGeneratorOverworld(World worldIn, long seed, boolean mapFeaturesEnabledIn, String generatorOptions) { ++ { ++ caveGenerator = net.minecraftforge.event.terraingen.TerrainGen.getModdedMapGen(caveGenerator, net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.CAVE); ++ strongholdGenerator = (MapGenStronghold)net.minecraftforge.event.terraingen.TerrainGen.getModdedMapGen(strongholdGenerator, net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.STRONGHOLD); ++ villageGenerator = (MapGenVillage)net.minecraftforge.event.terraingen.TerrainGen.getModdedMapGen(villageGenerator, net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.VILLAGE); ++ mineshaftGenerator = (MapGenMineshaft)net.minecraftforge.event.terraingen.TerrainGen.getModdedMapGen(mineshaftGenerator, net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.MINESHAFT); ++ scatteredFeatureGenerator = (MapGenScatteredFeature)net.minecraftforge.event.terraingen.TerrainGen.getModdedMapGen(scatteredFeatureGenerator, net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.SCATTERED_FEATURE); ++ ravineGenerator = net.minecraftforge.event.terraingen.TerrainGen.getModdedMapGen(ravineGenerator, net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.RAVINE); ++ oceanMonumentGenerator = (StructureOceanMonument)net.minecraftforge.event.terraingen.TerrainGen.getModdedMapGen(oceanMonumentGenerator, net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.OCEAN_MONUMENT); ++ woodlandMansionGenerator = (WoodlandMansion)net.minecraftforge.event.terraingen.TerrainGen.getModdedMapGen(woodlandMansionGenerator, net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.WOODLAND_MANSION); ++ } + this.world = worldIn; + this.mapFeaturesEnabled = mapFeaturesEnabledIn; + this.terrainType = worldIn.getWorldInfo().getTerrainType(); +@@ -85,6 +95,17 @@ + this.oceanBlock = this.settings.useLavaOceans ? Blocks.LAVA.getDefaultState() : Blocks.WATER.getDefaultState(); + worldIn.setSeaLevel(this.settings.seaLevel); + } ++ ++ net.minecraftforge.event.terraingen.InitNoiseGensEvent.ContextOverworld ctx = ++ new net.minecraftforge.event.terraingen.InitNoiseGensEvent.ContextOverworld(minLimitPerlinNoise, maxLimitPerlinNoise, mainPerlinNoise, surfaceNoise, scaleNoise, depthNoise, forestNoise); ++ ctx = net.minecraftforge.event.terraingen.TerrainGen.getModdedNoiseGenerators(worldIn, this.rand, ctx); ++ this.minLimitPerlinNoise = ctx.getLPerlin1(); ++ this.maxLimitPerlinNoise = ctx.getLPerlin2(); ++ this.mainPerlinNoise = ctx.getPerlin(); ++ this.surfaceNoise = ctx.getHeight(); ++ this.scaleNoise = ctx.getScale(); ++ this.depthNoise = ctx.getDepth(); ++ this.forestNoise = ctx.getForest(); + } + + public void setBlocksInChunk(int x, int z, ChunkPrimer primer) { +@@ -148,6 +169,7 @@ + } + + public void replaceBiomeBlocks(int x, int z, ChunkPrimer primer, Biome[] biomesIn) { ++ if (!net.minecraftforge.event.ForgeEventFactory.onReplaceBiomeBlocks(this, x, z, primer, this.world)) return; + double d0 = 0.03125; + this.depthBuffer = this.surfaceNoise.getRegion(this.depthBuffer, x * 16, z * 16, 16, 16, 0.0625, 0.0625, 1.0); + +@@ -349,6 +371,9 @@ + this.rand.setSeed(x * k + z * l ^ this.world.getSeed()); + boolean flag = false; + ChunkPos chunkpos = new ChunkPos(x, z); ++ ++ net.minecraftforge.event.ForgeEventFactory.onChunkPopulate(true, this, this.world, this.rand, x, z, flag); ++ + if (this.mapFeaturesEnabled) { + if (this.settings.useMineShafts) { + this.mineshaftGenerator.generateStructure(this.world, this.rand, chunkpos); +@@ -376,17 +401,19 @@ + } + + if (biome != Biomes.DESERT +- && biome != Biomes.DESERT_HILLS +- && this.settings.useWaterLakes +- && !flag +- && this.rand.nextInt(this.settings.waterLakeChance) == 0) { ++ && biome != Biomes.DESERT_HILLS ++ && this.settings.useWaterLakes ++ && !flag ++ && this.rand.nextInt(this.settings.waterLakeChance) == 0) ++ if (net.minecraftforge.event.terraingen.TerrainGen.populate(this, this.world, this.rand, x, z, flag, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.LAKE)) { + int i1 = this.rand.nextInt(16) + 8; + int j1 = this.rand.nextInt(256); + int k1 = this.rand.nextInt(16) + 8; + new WorldGenLakes(Blocks.WATER).generate(this.world, this.rand, blockpos.add(i1, j1, k1)); + } + +- if (!flag && this.rand.nextInt(this.settings.lavaLakeChance / 10) == 0 && this.settings.useLavaLakes) { ++ if (!flag && this.rand.nextInt(this.settings.lavaLakeChance / 10) == 0 && this.settings.useLavaLakes) ++ if (net.minecraftforge.event.terraingen.TerrainGen.populate(this, this.world, this.rand, x, z, flag, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.LAVA)) { + int i2 = this.rand.nextInt(16) + 8; + int l2 = this.rand.nextInt(this.rand.nextInt(248) + 8); + int k3 = this.rand.nextInt(16) + 8; +@@ -395,7 +422,8 @@ + } + } + +- if (this.settings.useDungeons) { ++ if (this.settings.useDungeons) ++ if (net.minecraftforge.event.terraingen.TerrainGen.populate(this, this.world, this.rand, x, z, flag, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.DUNGEON)) { + for (int j2 = 0; j2 < this.settings.dungeonChance; j2++) { + int i3 = this.rand.nextInt(16) + 8; + int l3 = this.rand.nextInt(256); +@@ -405,9 +433,11 @@ + } + + biome.decorate(this.world, this.rand, new BlockPos(i, 0, j)); ++ if (net.minecraftforge.event.terraingen.TerrainGen.populate(this, this.world, this.rand, x, z, flag, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.ANIMALS)) + WorldEntitySpawner.performWorldGenSpawning(this.world, biome, i + 8, j + 8, 16, 16, this.rand); + blockpos = blockpos.add(8, 0, 8); + ++ if (net.minecraftforge.event.terraingen.TerrainGen.populate(this, this.world, this.rand, x, z, flag, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.ICE)) { + for (int k2 = 0; k2 < 16; k2++) { + for (int j3 = 0; j3 < 16; j3++) { + BlockPos blockpos1 = this.world.getPrecipitationHeight(blockpos.add(k2, 0, j3)); +@@ -421,7 +451,10 @@ + } + } + } ++ }//Forge: End ICE + ++ net.minecraftforge.event.ForgeEventFactory.onChunkPopulate(false, this, this.world, this.rand, x, z, flag); ++ + BlockFalling.fallInstantly = false; + } + diff --git a/module/minecraft/patches/net/minecraft/world/gen/ChunkProviderServer.java.patch b/module/minecraft/patches/net/minecraft/world/gen/ChunkProviderServer.java.patch new file mode 100644 index 000000000..9c0a1faac --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/ChunkProviderServer.java.patch @@ -0,0 +1,82 @@ +--- original/net/minecraft/world/gen/ChunkProviderServer.java ++++ modified/net/minecraft/world/gen/ChunkProviderServer.java +@@ -34,6 +34,7 @@ + /** map of chunk Id's to Chunk instances */ + public final Long2ObjectMap loadedChunks = new Long2ObjectOpenHashMap<>(8192); + public final WorldServer world; ++ private final Set loadingChunks = com.google.common.collect.Sets.newHashSet(); + + public ChunkProviderServer(WorldServer worldObjIn, IChunkLoader chunkLoaderIn, IChunkGenerator chunkGeneratorIn) { + this.world = worldObjIn; +@@ -82,16 +83,41 @@ + + @Nullable + public Chunk loadChunk(int x, int z) { ++ return loadChunk(x, z, null); ++ } ++ ++ @Nullable ++ public Chunk loadChunk(int x, int z, @Nullable Runnable runnable) { + Chunk chunk = this.getLoadedChunk(x, z); + if (chunk == null) { +- chunk = this.loadChunkFromFile(x, z); +- if (chunk != null) { ++ long pos = ChunkPos.asLong(x, z); ++ ++ chunk = net.minecraftforge.common.ForgeChunkManager.fetchDormantChunk(pos, this.world); ++ if (chunk != null || !(this.chunkLoader instanceof net.minecraft.world.chunk.storage.AnvilChunkLoader)) { ++ if (!loadingChunks.add(pos)) net.minecraftforge.fml.common.FMLLog.bigWarning("There is an attempt to load a chunk ({},{}) in dimension {} that is already being loaded. This will cause weird chunk breakages.", x, z, this.world.provider.getDimension()); ++ if (chunk == null) chunk = this.loadChunkFromFile(x, z); ++ ++ if (chunk != null) { + this.loadedChunks.put(ChunkPos.asLong(x, z), chunk); + chunk.onLoad(); + chunk.populate(this, this.chunkGenerator); ++ } ++ ++ loadingChunks.remove(pos); ++ } else { ++ net.minecraft.world.chunk.storage.AnvilChunkLoader loader = (net.minecraft.world.chunk.storage.AnvilChunkLoader) this.chunkLoader; ++ if (runnable == null || !net.minecraftforge.common.ForgeChunkManager.asyncChunkLoading) ++ chunk = net.minecraftforge.common.chunkio.ChunkIOExecutor.syncChunkLoad(this.world, loader, this, x, z); ++ else if (loader.isChunkGeneratedAt(x, z)) { ++ // We can only use the async queue for already generated chunks ++ net.minecraftforge.common.chunkio.ChunkIOExecutor.queueChunkLoad(this.world, loader, this, x, z, runnable); ++ return null; ++ } + } + } + ++ // If we didn't load the chunk async and have a callback run it now ++ if (runnable != null) runnable.run(); + return chunk; + } + +@@ -187,6 +213,10 @@ + public boolean tick() { + if (!this.world.disableLevelSaving) { + if (!this.droppedChunks.isEmpty()) { ++ for (ChunkPos forced : this.world.getPersistentChunks().keySet()) { ++ this.droppedChunks.remove(ChunkPos.asLong(forced.x, forced.z)); ++ } ++ + Iterator iterator = this.droppedChunks.iterator(); + + for (int i = 0; i < 100 && iterator.hasNext(); iterator.remove()) { +@@ -194,6 +224,7 @@ + Chunk chunk = this.loadedChunks.get(olong); + if (chunk != null && chunk.unloadQueued) { + chunk.onUnload(); ++ net.minecraftforge.common.ForgeChunkManager.putDormantChunk(ChunkPos.asLong(chunk.x, chunk.z), chunk); + this.saveChunkData(chunk); + this.saveChunkExtraData(chunk); + this.loadedChunks.remove(olong); +@@ -202,6 +233,8 @@ + } + } + ++ if (this.loadedChunks.isEmpty()) net.minecraftforge.common.DimensionManager.unloadWorld(this.world.provider.getDimension()); ++ + this.chunkLoader.chunkTick(); + } + diff --git a/module/minecraft/patches/net/minecraft/world/gen/MapGenCaves.java.patch b/module/minecraft/patches/net/minecraft/world/gen/MapGenCaves.java.patch new file mode 100644 index 000000000..7ee2071f8 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/MapGenCaves.java.patch @@ -0,0 +1,105 @@ +--- original/net/minecraft/world/gen/MapGenCaves.java ++++ modified/net/minecraft/world/gen/MapGenCaves.java +@@ -173,8 +173,7 @@ + for (int k1 = i3; !flag3 && k1 < i1; k1++) { + for (int l1 = l + 1; !flag3 && l1 >= l2 - 1; l1--) { + if (l1 >= 0 && l1 < 256) { +- IBlockState iblockstate = p_180702_5_.getBlockState(j1, l1, k1); +- if (iblockstate.getBlock() == Blocks.FLOWING_WATER || iblockstate.getBlock() == Blocks.WATER) { ++ if (isOceanBlock(p_180702_5_, j1, l1, k1, p_180702_3_, p_180702_4_)) { + flag3 = true; + } + +@@ -201,32 +200,13 @@ + if (d9 > -0.7 && d10 * d10 + d9 * d9 + d8 * d8 < 1.0) { + IBlockState iblockstate1 = p_180702_5_.getBlockState(j3, j2, i2); + IBlockState iblockstate2 = MoreObjects.firstNonNull(p_180702_5_.getBlockState(j3, j2 + 1, i2), BLK_AIR); +- if (iblockstate1.getBlock() == Blocks.GRASS || iblockstate1.getBlock() == Blocks.MYCELIUM ++ if (isTopBlock(p_180702_5_, j3, j2, i2, p_180702_3_, p_180702_4_) + ) + { + flag1 = true; + } + +- if (this.canReplaceBlock(iblockstate1, iblockstate2)) { +- if (j2 - 1 < 10) { +- p_180702_5_.setBlockState(j3, j2, i2, BLK_LAVA); +- } else { +- p_180702_5_.setBlockState(j3, j2, i2, BLK_AIR); +- if (flag1 && p_180702_5_.getBlockState(j3, j2 - 1, i2).getBlock() == Blocks.DIRT) { +- blockpos$mutableblockpos.setPos(j3 + p_180702_3_ * 16, 0, i2 + p_180702_4_ * 16); +- p_180702_5_.setBlockState( +- j3, +- j2 - 1, +- i2, +- this.world +- .getBiome(blockpos$mutableblockpos) +- .topBlock +- .getBlock() +- .getDefaultState() +- ); +- } +- } +- } ++ digBlock(p_180702_5_, j3, j2, i2, p_180702_3_, p_180702_4_, flag1, iblockstate1, iblockstate2); + } + } + } +@@ -299,4 +279,57 @@ + } + } + } ++ ++ protected boolean isOceanBlock(ChunkPrimer data, int x, int y, int z, int chunkX, int chunkZ) { ++ net.minecraft.block.Block block = data.getBlockState(x, y, z).getBlock(); ++ return block== Blocks.FLOWING_WATER || block == Blocks.WATER; ++ } ++ ++ //Exception biomes to make sure we generate like vanilla ++ private boolean isExceptionBiome(net.minecraft.world.biome.Biome biome) { ++ if (biome == net.minecraft.init.Biomes.BEACH) return true; ++ if (biome == net.minecraft.init.Biomes.DESERT) return true; ++ return false; ++ } ++ ++ //Determine if the block at the specified location is the top block for the biome, we take into account ++ //Vanilla bugs to make sure that we generate the map the same way vanilla does. ++ private boolean isTopBlock(ChunkPrimer data, int x, int y, int z, int chunkX, int chunkZ) { ++ net.minecraft.world.biome.Biome biome = world.getBiome(new BlockPos(x + chunkX * 16, 0, z + chunkZ * 16)); ++ IBlockState state = data.getBlockState(x, y, z); ++ return (isExceptionBiome(biome) ? state.getBlock() == Blocks.GRASS : state.getBlock() == biome.topBlock); ++ } ++ ++ /** ++ * Digs out the current block, default implementation removes stone, filler, and top block ++ * Sets the block to lava if y is less then 10, and air other wise. ++ * If setting to air, it also checks to see if we've broken the surface and if so ++ * tries to make the floor the biome's top block ++ * ++ * @param data Block data array ++ * @param index Pre-calculated index into block data ++ * @param x local X position ++ * @param y local Y position ++ * @param z local Z position ++ * @param chunkX Chunk X position ++ * @param chunkZ Chunk Y position ++ * @param foundTop True if we've encountered the biome's top block. Ideally if we've broken the surface. ++ */ ++ protected void digBlock(ChunkPrimer data, int x, int y, int z, int chunkX, int chunkZ, boolean foundTop, IBlockState state, IBlockState up) { ++ net.minecraft.world.biome.Biome biome = world.getBiome(new BlockPos(x + chunkX * 16, 0, z + chunkZ * 16)); ++ IBlockState top = biome.topBlock; ++ IBlockState filler = biome.fillerBlock; ++ ++ if (this.canReplaceBlock(state, up) || state.getBlock() == top.getBlock() || state.getBlock() == filler.getBlock()) { ++ if (y - 1 < 10) { ++ data.setBlockState(x, y, z, BLK_LAVA); ++ } else { ++ data.setBlockState(x, y, z, BLK_AIR); ++ ++ if (foundTop && data.getBlockState(x, y - 1, z).getBlock() == filler.getBlock()) { ++ data.setBlockState(x, y - 1, z, top.getBlock().getDefaultState()); ++ } ++ } ++ } ++ } + } diff --git a/module/minecraft/patches/net/minecraft/world/gen/MapGenRavine.java.patch b/module/minecraft/patches/net/minecraft/world/gen/MapGenRavine.java.patch new file mode 100644 index 000000000..4de970ca0 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/MapGenRavine.java.patch @@ -0,0 +1,110 @@ +--- original/net/minecraft/world/gen/MapGenRavine.java ++++ modified/net/minecraft/world/gen/MapGenRavine.java +@@ -120,8 +120,7 @@ + for (int k1 = i3; !flag2 && k1 < i1; k1++) { + for (int l1 = l + 1; !flag2 && l1 >= l2 - 1; l1--) { + if (l1 >= 0 && l1 < 256) { +- IBlockState iblockstate = p_180707_5_.getBlockState(j1, l1, k1); +- if (iblockstate.getBlock() == Blocks.FLOWING_WATER || iblockstate.getBlock() == Blocks.WATER) { ++ if (isOceanBlock(p_180707_5_, j1, l1, k1, p_180707_3_, p_180707_4_)) { + flag2 = true; + } + +@@ -134,8 +133,6 @@ + } + + if (!flag2) { +- BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos(); +- + for (int j3 = k2; j3 < k; j3++) { + double d10 = (j3 + p_180707_3_ * 16 + 0.5 - p_180707_6_) / d9; + +@@ -146,26 +143,11 @@ + for (int j2 = l; j2 > l2; j2--) { + double d8 = (j2 - 1 + 0.5 - p_180707_8_) / d2; + if ((d10 * d10 + d7 * d7) * this.rs[j2 - 1] + d8 * d8 / 6.0 < 1.0) { +- IBlockState iblockstate1 = p_180707_5_.getBlockState(j3, j2, i2); +- if (iblockstate1.getBlock() == Blocks.GRASS) { ++ if (isTopBlock(p_180707_5_, j3, j2, i2, p_180707_3_, p_180707_4_)) { + flag = true; + } + +- if (iblockstate1.getBlock() == Blocks.STONE +- || iblockstate1.getBlock() == Blocks.DIRT +- || iblockstate1.getBlock() == Blocks.GRASS) { +- if (j2 - 1 < 10) { +- p_180707_5_.setBlockState(j3, j2, i2, FLOWING_LAVA); +- } else { +- p_180707_5_.setBlockState(j3, j2, i2, AIR); +- if (flag && p_180707_5_.getBlockState(j3, j2 - 1, i2).getBlock() == Blocks.DIRT) { +- blockpos$mutableblockpos.setPos(j3 + p_180707_3_ * 16, 0, i2 + p_180707_4_ * 16); +- p_180707_5_.setBlockState( +- j3, j2 - 1, i2, this.world.getBiome(blockpos$mutableblockpos).topBlock +- ); +- } +- } +- } ++ digBlock(p_180707_5_, j3, j2, i2, p_180707_3_, p_180707_4_, flag); + } + } + } +@@ -198,4 +180,59 @@ + } + } + } ++ protected boolean isOceanBlock(ChunkPrimer data, int x, int y, int z, int chunkX, int chunkZ) { ++ net.minecraft.block.Block block = data.getBlockState(x, y, z).getBlock(); ++ return block== Blocks.FLOWING_WATER || block == Blocks.WATER; ++ } ++ ++ //Exception biomes to make sure we generate like vanilla ++ private boolean isExceptionBiome(net.minecraft.world.biome.Biome biome) { ++ if (biome == net.minecraft.init.Biomes.BEACH) return true; ++ if (biome == net.minecraft.init.Biomes.DESERT) return true; ++ if (biome == net.minecraft.init.Biomes.MUSHROOM_ISLAND) return true; ++ if (biome == net.minecraft.init.Biomes.MUSHROOM_ISLAND_SHORE) return true; ++ return false; ++ } ++ ++ //Determine if the block at the specified location is the top block for the biome, we take into account ++ //Vanilla bugs to make sure that we generate the map the same way vanilla does. ++ private boolean isTopBlock(ChunkPrimer data, int x, int y, int z, int chunkX, int chunkZ) { ++ net.minecraft.world.biome.Biome biome = world.getBiome(new BlockPos(x + chunkX * 16, 0, z + chunkZ * 16)); ++ IBlockState state = data.getBlockState(x, y, z); ++ return (isExceptionBiome(biome) ? state.getBlock() == Blocks.GRASS : state.getBlock() == biome.topBlock); ++ } ++ ++ /** ++ * Digs out the current block, default implementation removes stone, filler, and top block ++ * Sets the block to lava if y is less then 10, and air other wise. ++ * If setting to air, it also checks to see if we've broken the surface and if so ++ * tries to make the floor the biome's top block ++ * ++ * @param data Block data array ++ * @param index Pre-calculated index into block data ++ * @param x local X position ++ * @param y local Y position ++ * @param z local Z position ++ * @param chunkX Chunk X position ++ * @param chunkZ Chunk Y position ++ * @param foundTop True if we've encountered the biome's top block. Ideally if we've broken the surface. ++ */ ++ protected void digBlock(ChunkPrimer data, int x, int y, int z, int chunkX, int chunkZ, boolean foundTop) { ++ net.minecraft.world.biome.Biome biome = world.getBiome(new BlockPos(x + chunkX * 16, 0, z + chunkZ * 16)); ++ IBlockState state = data.getBlockState(x, y, z); ++ IBlockState top = isExceptionBiome(biome) ? Blocks.GRASS.getDefaultState() : biome.topBlock; ++ IBlockState filler = isExceptionBiome(biome) ? Blocks.DIRT.getDefaultState() : biome.fillerBlock; ++ ++ if (state.getBlock() == Blocks.STONE || state.getBlock() == top.getBlock() || state.getBlock() == filler.getBlock()) { ++ if (y - 1 < 10) { ++ data.setBlockState(x, y, z, FLOWING_LAVA); ++ } else { ++ data.setBlockState(x, y, z, AIR); ++ ++ if (foundTop && data.getBlockState(x, y - 1, z).getBlock() == filler.getBlock()) { ++ data.setBlockState(x, y - 1, z, top.getBlock().getDefaultState()); ++ } ++ } ++ } ++ } + } diff --git a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenAbstractTree.java.patch b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenAbstractTree.java.patch new file mode 100644 index 000000000..3991c89ef --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenAbstractTree.java.patch @@ -0,0 +1,12 @@ +--- original/net/minecraft/world/gen/feature/WorldGenAbstractTree.java ++++ modified/net/minecraft/world/gen/feature/WorldGenAbstractTree.java +@@ -37,4 +37,9 @@ + this.setBlockAndNotifyAdequately(worldIn, pos, Blocks.DIRT.getDefaultState()); + } + } ++ ++ public boolean isReplaceable(World world, BlockPos pos) { ++ net.minecraft.block.state.IBlockState state = world.getBlockState(pos); ++ return state.getBlock().isAir(state, world, pos) || state.getBlock().isLeaves(state, world, pos) || state.getBlock().isWood(world, pos) || canGrowInto(state.getBlock()); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenBigMushroom.java.patch b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenBigMushroom.java.patch new file mode 100644 index 000000000..fb6cfa29c --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenBigMushroom.java.patch @@ -0,0 +1,32 @@ +--- original/net/minecraft/world/gen/feature/WorldGenBigMushroom.java ++++ modified/net/minecraft/world/gen/feature/WorldGenBigMushroom.java +@@ -48,8 +48,9 @@ + for (int l = position.getX() - k; l <= position.getX() + k && flag; l++) { + for (int i1 = position.getZ() - k; i1 <= position.getZ() + k && flag; i1++) { + if (j >= 0 && j < 256) { +- Material material = worldIn.getBlockState(blockpos$mutableblockpos.setPos(l, j, i1)).getMaterial(); +- if (material != Material.AIR && material != Material.LEAVES) { ++ IBlockState state = worldIn.getBlockState(blockpos$mutableblockpos.setPos(l, j, i1)); ++ ++ if (!state.getBlock().isAir(state, worldIn, blockpos$mutableblockpos) && !state.getBlock().isLeaves(state, worldIn, blockpos$mutableblockpos)) { + flag = false; + } + } else { +@@ -149,7 +150,7 @@ + if (position.getY() >= position.getY() + i - 1 + || blockhugemushroom$enumtype != BlockHugeMushroom.EnumType.ALL_INSIDE) { + BlockPos blockpos = new BlockPos(l1, l2, i2); +- if (!worldIn.getBlockState(blockpos).isFullBlock()) { ++ IBlockState state = worldIn.getBlockState(blockpos); if (state.getBlock().canBeReplacedByLeaves(state, worldIn, blockpos)) { + this.setBlockAndNotifyAdequately( + worldIn, blockpos, block.getDefaultState().withProperty(BlockHugeMushroom.VARIANT, blockhugemushroom$enumtype) + ); +@@ -161,7 +162,7 @@ + + for (int i3 = 0; i3 < i; i3++) { + IBlockState iblockstate = worldIn.getBlockState(position.up(i3)); +- if (!iblockstate.isFullBlock()) { ++ if (iblockstate.getBlock().canBeReplacedByLeaves(iblockstate, worldIn, position.up(i3))) { + this.setBlockAndNotifyAdequately( + worldIn, + position.up(i3), diff --git a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenBigTree.java.patch b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenBigTree.java.patch new file mode 100644 index 000000000..ef9862922 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenBigTree.java.patch @@ -0,0 +1,51 @@ +--- original/net/minecraft/world/gen/feature/WorldGenBigTree.java ++++ modified/net/minecraft/world/gen/feature/WorldGenBigTree.java +@@ -82,8 +82,9 @@ + for (int k = -i; k <= i; k++) { + if (Math.pow(Math.abs(j) + 0.5, 2.0) + Math.pow(Math.abs(k) + 0.5, 2.0) <= p_181631_2_ * p_181631_2_) { + BlockPos blockpos = pos.add(j, 0, k); +- Material material = this.world.getBlockState(blockpos).getMaterial(); +- if (material == Material.AIR || material == Material.LEAVES) { ++ IBlockState state = this.world.getBlockState(blockpos); ++ ++ if (state.getBlock().isAir(state, world, blockpos) || state.getBlock().isLeaves(state, world, blockpos)) { + this.setBlockAndNotifyAdequately(this.world, blockpos, p_181631_3_); + } + } +@@ -217,7 +218,7 @@ + + for (int j = 0; j <= i; j++) { + BlockPos blockpos1 = posOne.add(0.5F + j * f, 0.5F + j * f1, 0.5F + j * f2); +- if (!this.canGrowInto(this.world.getBlockState(blockpos1).getBlock())) { ++ if (!this.isReplaceable(world, blockpos1)) { + return j; + } + } +@@ -240,6 +241,7 @@ + } + + if (!this.validTreeLocation()) { ++ this.world = null; //Fix vanilla Mem leak, holds latest world + return false; + } + +@@ -247,13 +249,17 @@ + this.generateLeaves(); + this.generateTrunk(); + this.generateLeafNodeBases(); ++ this.world = null; //Fix vanilla Mem leak, holds latest world + return true; + } + + /** Returns a boolean indicating whether or not the current location for the tree, spanning basePos to to the height limit, is valid. */ + private boolean validTreeLocation() { +- Block block = this.world.getBlockState(this.basePos.down()).getBlock(); +- if (block != Blocks.DIRT && block != Blocks.GRASS && block != Blocks.FARMLAND) { ++ BlockPos down = this.basePos.down(); ++ net.minecraft.block.state.IBlockState state = this.world.getBlockState(down); ++ boolean isSoil = state.getBlock().canSustainPlant(state, this.world, down, net.minecraft.util.EnumFacing.UP, ((net.minecraft.block.BlockSapling)Blocks.SAPLING)); ++ ++ if (!isSoil) { + return false; + } + diff --git a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenBirchTree.java.patch b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenBirchTree.java.patch new file mode 100644 index 000000000..6b65c4432 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenBirchTree.java.patch @@ -0,0 +1,53 @@ +--- original/net/minecraft/world/gen/feature/WorldGenBirchTree.java ++++ modified/net/minecraft/world/gen/feature/WorldGenBirchTree.java +@@ -49,9 +49,9 @@ + + for (int l = position.getX() - k; l <= position.getX() + k && flag; l++) { + for (int i1 = position.getZ() - k; i1 <= position.getZ() + k && flag; i1++) { +- if (j < 0 || j >= 256) { ++ if (j < 0 || j >= worldIn.getHeight()) { + flag = false; +- } else if (!this.canGrowInto(worldIn.getBlockState(blockpos$mutableblockpos.setPos(l, j, i1)).getBlock())) { ++ } else if (!this.isReplaceable(worldIn, blockpos$mutableblockpos.setPos(l, j, i1))) { + flag = false; + } + } +@@ -62,10 +62,11 @@ + return false; + } + +- Block block = worldIn.getBlockState(position.down()).getBlock(); +- if ((block == Blocks.GRASS || block == Blocks.DIRT || block == Blocks.FARMLAND) +- && position.getY() < 256 - i - 1) { +- this.setDirtAt(worldIn, position.down()); ++ BlockPos down = position.down(); ++ IBlockState state = worldIn.getBlockState(down); ++ boolean isSoil = state.getBlock().canSustainPlant(state, worldIn, down, net.minecraft.util.EnumFacing.UP, (net.minecraft.block.BlockSapling)Blocks.SAPLING); ++ if (isSoil && position.getY() < worldIn.getHeight() - i - 1) { ++ state.getBlock().onPlantGrow(state, worldIn, down, position); + + for (int i2 = position.getY() - 3 + i; i2 <= position.getY() + i; i2++) { + int k2 = i2 - (position.getY() + i); +@@ -78,8 +79,8 @@ + int l1 = k1 - position.getZ(); + if (Math.abs(j1) != l2 || Math.abs(l1) != l2 || rand.nextInt(2) != 0 && k2 != 0) { + BlockPos blockpos = new BlockPos(i3, i2, k1); +- Material material = worldIn.getBlockState(blockpos).getMaterial(); +- if (material == Material.AIR || material == Material.LEAVES) { ++ IBlockState state2 = worldIn.getBlockState(blockpos); ++ if (state2.getBlock().isAir(state2, worldIn, blockpos) || state2.getBlock().isAir(state2, worldIn, blockpos)) { + this.setBlockAndNotifyAdequately(worldIn, blockpos, LEAF); + } + } +@@ -88,8 +89,9 @@ + } + + for (int j2 = 0; j2 < i; j2++) { +- Material material1 = worldIn.getBlockState(position.up(j2)).getMaterial(); +- if (material1 == Material.AIR || material1 == Material.LEAVES) { ++ BlockPos upN = position.up(j2); ++ IBlockState state2 = worldIn.getBlockState(upN); ++ if (state2.getBlock().isAir(state2, worldIn, upN) || state2.getBlock().isLeaves(state2, worldIn, upN)) { + this.setBlockAndNotifyAdequately(worldIn, position.up(j2), LOG); + } + } diff --git a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenBush.java.patch b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenBush.java.patch new file mode 100644 index 000000000..901c3f109 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenBush.java.patch @@ -0,0 +1,13 @@ +--- original/net/minecraft/world/gen/feature/WorldGenBush.java ++++ modified/net/minecraft/world/gen/feature/WorldGenBush.java +@@ -21,8 +21,8 @@ + rand.nextInt(8) - rand.nextInt(8) + ); + if (worldIn.isAirBlock(blockpos) +- && (!worldIn.provider.isNether() || blockpos.getY() < 255) +- && this.block.canBlockStay(worldIn, blockpos, this.block.getDefaultState())) { ++ && (!worldIn.provider.isNether() || blockpos.getY() < worldIn.getHeight() - 1) ++ && this.block.canBlockStay(worldIn, blockpos, this.block.getDefaultState())) { + worldIn.setBlockState(blockpos, this.block.getDefaultState(), 2); + } + } diff --git a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenCanopyTree.java.patch b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenCanopyTree.java.patch new file mode 100644 index 000000000..5496ebfd1 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenCanopyTree.java.patch @@ -0,0 +1,69 @@ +--- original/net/minecraft/world/gen/feature/WorldGenCanopyTree.java ++++ modified/net/minecraft/world/gen/feature/WorldGenCanopyTree.java +@@ -34,8 +34,10 @@ + int l = position.getZ(); + if (k >= 1 && k + i + 1 < 256) { + BlockPos blockpos = position.down(); +- Block block = worldIn.getBlockState(blockpos).getBlock(); +- if (block != Blocks.GRASS && block != Blocks.DIRT) { ++ IBlockState state = worldIn.getBlockState(blockpos); ++ boolean isSoil = state.getBlock().canSustainPlant(state, worldIn, blockpos, net.minecraft.util.EnumFacing.UP, ((net.minecraft.block.BlockSapling)Blocks.SAPLING)); ++ ++ if (!(isSoil && position.getY() < worldIn.getHeight() - i - 1)) { + return false; + } + +@@ -43,10 +45,10 @@ + return false; + } + +- this.setDirtAt(worldIn, blockpos); +- this.setDirtAt(worldIn, blockpos.east()); +- this.setDirtAt(worldIn, blockpos.south()); +- this.setDirtAt(worldIn, blockpos.south().east()); ++ this.onPlantGrow(worldIn, blockpos, position); ++ this.onPlantGrow(worldIn, blockpos.east(), position); ++ this.onPlantGrow(worldIn, blockpos.south(), position); ++ this.onPlantGrow(worldIn, blockpos.south().east(), position); + EnumFacing enumfacing = EnumFacing.Plane.HORIZONTAL.random(rand); + int i1 = i - rand.nextInt(4); + int j1 = 2 - rand.nextInt(3); +@@ -63,8 +65,8 @@ + + int k2 = k + j2; + BlockPos blockpos1 = new BlockPos(k1, k2, l1); +- Material material = worldIn.getBlockState(blockpos1).getMaterial(); +- if (material == Material.AIR || material == Material.LEAVES) { ++ state = worldIn.getBlockState(blockpos1); ++ if (state.getBlock().isAir(state, worldIn, blockpos1) || state.getBlock().isLeaves(state, worldIn, blockpos1)) { + this.placeLogAt(worldIn, blockpos1); + this.placeLogAt(worldIn, blockpos1.east()); + this.placeLogAt(worldIn, blockpos1.south()); +@@ -158,7 +160,7 @@ + + for (int j1 = -i1; j1 <= i1; j1++) { + for (int k1 = -i1; k1 <= i1; k1++) { +- if (!this.canGrowInto(worldIn.getBlockState(blockpos$mutableblockpos.setPos(i + j1, j + l, k + k1)).getBlock())) { ++ if (!this.isReplaceable(worldIn, blockpos$mutableblockpos.setPos(i + j1, j + l, k + k1))) { + return false; + } + } +@@ -176,9 +178,16 @@ + + private void placeLeafAt(World worldIn, int x, int y, int z) { + BlockPos blockpos = new BlockPos(x, y, z); +- Material material = worldIn.getBlockState(blockpos).getMaterial(); +- if (material == Material.AIR) { ++ IBlockState state = worldIn.getBlockState(blockpos); ++ ++ if (state.getBlock().isAir(state, worldIn, blockpos)) { + this.setBlockAndNotifyAdequately(worldIn, blockpos, DARK_OAK_LEAVES); + } + } ++ ++ //Just a helper macro ++ private void onPlantGrow(World world, BlockPos pos, BlockPos source) { ++ IBlockState state = world.getBlockState(pos); ++ state.getBlock().onPlantGrow(state, world, pos, source); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenDeadBush.java.patch b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenDeadBush.java.patch new file mode 100644 index 000000000..10e9b932e --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenDeadBush.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/world/gen/feature/WorldGenDeadBush.java ++++ modified/net/minecraft/world/gen/feature/WorldGenDeadBush.java +@@ -11,7 +11,7 @@ + @Override + public boolean generate(World worldIn, Random rand, BlockPos position) { + for (IBlockState iblockstate = worldIn.getBlockState(position); +- (iblockstate.getMaterial() == Material.AIR || iblockstate.getMaterial() == Material.LEAVES) ++ (iblockstate.getBlock().isAir(iblockstate, worldIn, position) || iblockstate.getBlock().isLeaves(iblockstate, worldIn, position)) + && position.getY() > 0; + iblockstate = worldIn.getBlockState(position) + ) { diff --git a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenDungeons.java.patch b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenDungeons.java.patch new file mode 100644 index 000000000..41c3f2409 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenDungeons.java.patch @@ -0,0 +1,10 @@ +--- original/net/minecraft/world/gen/feature/WorldGenDungeons.java ++++ modified/net/minecraft/world/gen/feature/WorldGenDungeons.java +@@ -134,6 +134,6 @@ + + /** Randomly decides which spawner to use in a dungeon */ + private ResourceLocation pickMobSpawner(Random rand) { +- return SPAWNERTYPES[rand.nextInt(SPAWNERTYPES.length)]; ++ return net.minecraftforge.common.DungeonHooks.getRandomDungeonMob(rand); + } + } diff --git a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenGlowStone1.java.patch b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenGlowStone1.java.patch new file mode 100644 index 000000000..a34f83fa5 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenGlowStone1.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/world/gen/feature/WorldGenGlowStone1.java ++++ modified/net/minecraft/world/gen/feature/WorldGenGlowStone1.java +@@ -24,7 +24,7 @@ + BlockPos blockpos = position.add( + rand.nextInt(8) - rand.nextInt(8), -rand.nextInt(12), rand.nextInt(8) - rand.nextInt(8) + ); +- if (worldIn.getBlockState(blockpos).getMaterial() == Material.AIR) { ++ if (worldIn.isAirBlock(blockpos)) { + int j = 0; + + for (EnumFacing enumfacing : EnumFacing.values()) { diff --git a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenGlowStone2.java.patch b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenGlowStone2.java.patch new file mode 100644 index 000000000..69f09f94a --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenGlowStone2.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/world/gen/feature/WorldGenGlowStone2.java ++++ modified/net/minecraft/world/gen/feature/WorldGenGlowStone2.java +@@ -24,7 +24,7 @@ + BlockPos blockpos = position.add( + rand.nextInt(8) - rand.nextInt(8), -rand.nextInt(12), rand.nextInt(8) - rand.nextInt(8) + ); +- if (worldIn.getBlockState(blockpos).getMaterial() == Material.AIR) { ++ if (worldIn.isAirBlock(blockpos)) { + int j = 0; + + for (EnumFacing enumfacing : EnumFacing.values()) { diff --git a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenHellLava.java.patch b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenHellLava.java.patch new file mode 100644 index 000000000..578bc4a4b --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenHellLava.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/world/gen/feature/WorldGenHellLava.java ++++ modified/net/minecraft/world/gen/feature/WorldGenHellLava.java +@@ -23,7 +23,7 @@ + return false; + } + +- if (worldIn.getBlockState(position).getMaterial() != Material.AIR ++ if (!worldIn.isAirBlock(position) + && worldIn.getBlockState(position).getBlock() != Blocks.NETHERRACK) { + return false; + } diff --git a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenHugeTrees.java.patch b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenHugeTrees.java.patch new file mode 100644 index 000000000..39c95577a --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenHugeTrees.java.patch @@ -0,0 +1,68 @@ +--- original/net/minecraft/world/gen/feature/WorldGenHugeTrees.java ++++ modified/net/minecraft/world/gen/feature/WorldGenHugeTrees.java +@@ -50,8 +50,8 @@ + for (int k = -j; k <= j && flag; k++) { + for (int l = -j; l <= j && flag; l++) { + if (leavesPos.getY() + i < 0 +- || leavesPos.getY() + i >= 256 +- || !this.canGrowInto(worldIn.getBlockState(leavesPos.add(k, i, l)).getBlock())) { ++ || leavesPos.getY() + i >= 256 ++ || !this.isReplaceable(worldIn,leavesPos.add(k, i, l))) { + flag = false; + } + } +@@ -70,12 +70,14 @@ + */ + private boolean ensureDirtsUnderneath(BlockPos pos, World worldIn) { + BlockPos blockpos = pos.down(); +- Block block = worldIn.getBlockState(blockpos).getBlock(); +- if ((block == Blocks.GRASS || block == Blocks.DIRT) && pos.getY() >= 2) { +- this.setDirtAt(worldIn, blockpos); +- this.setDirtAt(worldIn, blockpos.east()); +- this.setDirtAt(worldIn, blockpos.south()); +- this.setDirtAt(worldIn, blockpos.south().east()); ++ IBlockState state = worldIn.getBlockState(blockpos); ++ boolean isSoil = state.getBlock().canSustainPlant(state, worldIn, blockpos, net.minecraft.util.EnumFacing.UP, ((net.minecraft.block.BlockSapling)Blocks.SAPLING)); ++ ++ if (isSoil && pos.getY() >= 2) { ++ this.onPlantGrow(worldIn, blockpos, pos); ++ this.onPlantGrow(worldIn, blockpos.east(), pos); ++ this.onPlantGrow(worldIn, blockpos.south(), pos); ++ this.onPlantGrow(worldIn, blockpos.south().east(), pos); + return true; + } else { + return false; +@@ -100,8 +102,9 @@ + int i1 = k - 1; + if (j * j + k * k <= i || l * l + i1 * i1 <= i || j * j + i1 * i1 <= i || l * l + k * k <= i) { + BlockPos blockpos = layerCenter.add(j, 0, k); +- Material material = worldIn.getBlockState(blockpos).getMaterial(); +- if (material == Material.AIR || material == Material.LEAVES) { ++ IBlockState state = worldIn.getBlockState(blockpos); ++ ++ if (state.getBlock().isAir(state, worldIn, blockpos) || state.getBlock().isLeaves(state, worldIn, blockpos)) { + this.setBlockAndNotifyAdequately(worldIn, blockpos, this.leavesMetadata); + } + } +@@ -117,12 +120,19 @@ + for (int k = -width; k <= width; k++) { + if (j * j + k * k <= i) { + BlockPos blockpos = layerCenter.add(j, 0, k); +- Material material = worldIn.getBlockState(blockpos).getMaterial(); +- if (material == Material.AIR || material == Material.LEAVES) { ++ IBlockState state = worldIn.getBlockState(blockpos); ++ ++ if (state.getBlock().isAir(state, worldIn, blockpos) || state.getBlock().isLeaves(state, worldIn, blockpos)) { + this.setBlockAndNotifyAdequately(worldIn, blockpos, this.leavesMetadata); + } + } + } + } + } ++ ++ //Just a helper macro ++ private void onPlantGrow(World world, BlockPos pos, BlockPos source) { ++ IBlockState state = world.getBlockState(pos); ++ state.getBlock().onPlantGrow(state, world, pos, source); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenIceSpike.java.patch b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenIceSpike.java.patch new file mode 100644 index 000000000..da77f593d --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenIceSpike.java.patch @@ -0,0 +1,29 @@ +--- original/net/minecraft/world/gen/feature/WorldGenIceSpike.java ++++ modified/net/minecraft/world/gen/feature/WorldGenIceSpike.java +@@ -40,7 +40,7 @@ + && (i1 != -l && i1 != l && j1 != -l && j1 != l || !(rand.nextFloat() > 0.75F))) { + IBlockState iblockstate = worldIn.getBlockState(position.add(i1, k, j1)); + Block block = iblockstate.getBlock(); +- if (iblockstate.getMaterial() == Material.AIR ++ if (iblockstate.getBlock().isAir(iblockstate, worldIn, position.add(i1, k, j1)) + || block == Blocks.DIRT + || block == Blocks.SNOW + || block == Blocks.ICE) { +@@ -50,7 +50,7 @@ + if (k != 0 && l > 1) { + iblockstate = worldIn.getBlockState(position.add(i1, -k, j1)); + block = iblockstate.getBlock(); +- if (iblockstate.getMaterial() == Material.AIR ++ if (iblockstate.getBlock().isAir(iblockstate, worldIn, position.add(i1, -k, j1)) + || block == Blocks.DIRT + || block == Blocks.SNOW + || block == Blocks.ICE) { +@@ -80,7 +80,7 @@ + while (blockpos.getY() > 50) { + IBlockState iblockstate1 = worldIn.getBlockState(blockpos); + Block block1 = iblockstate1.getBlock(); +- if (iblockstate1.getMaterial() != Material.AIR ++ if (!iblockstate1.getBlock().isAir(iblockstate1, worldIn, blockpos) + && block1 != Blocks.DIRT + && block1 != Blocks.SNOW + && block1 != Blocks.ICE diff --git a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenLakes.java.patch b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenLakes.java.patch new file mode 100644 index 000000000..c8be8a3d3 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenLakes.java.patch @@ -0,0 +1,12 @@ +--- original/net/minecraft/world/gen/feature/WorldGenLakes.java ++++ modified/net/minecraft/world/gen/feature/WorldGenLakes.java +@@ -142,7 +142,8 @@ + for (int l3 = 0; l3 < 16; l3++) { + int l4 = 4; + if (worldIn.canBlockFreezeWater(position.add(k2, 4, l3))) { +- worldIn.setBlockState(position.add(k2, 4, l3), Blocks.ICE.getDefaultState(), 2); ++ int flag = net.minecraftforge.common.ForgeModContainer.fixVanillaCascading ? 2| 16 : 2; //Forge: With bit 5 unset, it will notify neighbors and load adjacent chunks. ++ worldIn.setBlockState(position.add(k2, 4, l3), Blocks.ICE.getDefaultState(), flag); //Forge + } + } + } diff --git a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenLiquids.java.patch b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenLiquids.java.patch new file mode 100644 index 000000000..57859170d --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenLiquids.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/world/gen/feature/WorldGenLiquids.java ++++ modified/net/minecraft/world/gen/feature/WorldGenLiquids.java +@@ -26,7 +26,7 @@ + } + + IBlockState iblockstate = worldIn.getBlockState(position); +- if (iblockstate.getMaterial() != Material.AIR && iblockstate.getBlock() != Blocks.STONE) { ++ if (!iblockstate.getBlock().isAir(iblockstate, worldIn, position) && iblockstate.getBlock() != Blocks.STONE) { + return false; + } + diff --git a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenMegaJungle.java.patch b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenMegaJungle.java.patch new file mode 100644 index 000000000..e844aa4fd --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenMegaJungle.java.patch @@ -0,0 +1,49 @@ +--- original/net/minecraft/world/gen/feature/WorldGenMegaJungle.java ++++ modified/net/minecraft/world/gen/feature/WorldGenMegaJungle.java +@@ -45,7 +45,7 @@ + + for (int i2 = 0; i2 < i; i2++) { + BlockPos blockpos = position.up(i2); +- if (this.canGrowInto(worldIn.getBlockState(blockpos).getBlock())) { ++ if (this.isAirLeaves(worldIn,blockpos)) { + this.setBlockAndNotifyAdequately(worldIn, blockpos, this.woodMetadata); + if (i2 > 0) { + this.placeVine(worldIn, rand, blockpos.west(), BlockVine.EAST); +@@ -55,7 +55,7 @@ + + if (i2 < i - 1) { + BlockPos blockpos1 = blockpos.east(); +- if (this.canGrowInto(worldIn.getBlockState(blockpos1).getBlock())) { ++ if (this.isAirLeaves(worldIn,blockpos1)) { + this.setBlockAndNotifyAdequately(worldIn, blockpos1, this.woodMetadata); + if (i2 > 0) { + this.placeVine(worldIn, rand, blockpos1.east(), BlockVine.WEST); +@@ -64,7 +64,7 @@ + } + + BlockPos blockpos2 = blockpos.south().east(); +- if (this.canGrowInto(worldIn.getBlockState(blockpos2).getBlock())) { ++ if (this.isAirLeaves(worldIn,blockpos2)) { + this.setBlockAndNotifyAdequately(worldIn, blockpos2, this.woodMetadata); + if (i2 > 0) { + this.placeVine(worldIn, rand, blockpos2.east(), BlockVine.WEST); +@@ -73,7 +73,7 @@ + } + + BlockPos blockpos3 = blockpos.south(); +- if (this.canGrowInto(worldIn.getBlockState(blockpos3).getBlock())) { ++ if (this.isAirLeaves(worldIn,blockpos3)) { + this.setBlockAndNotifyAdequately(worldIn, blockpos3, this.woodMetadata); + if (i2 > 0) { + this.placeVine(worldIn, rand, blockpos3.west(), BlockVine.EAST); +@@ -99,4 +99,10 @@ + this.growLeavesLayerStrict(worldIn, p_175930_2_.up(j), p_175930_3_ + 1 - j); + } + } ++ ++ //Helper macro ++ private boolean isAirLeaves(World world, BlockPos pos) { ++ IBlockState state = world.getBlockState(pos); ++ return state.getBlock().isAir(state, world, pos) || state.getBlock().isLeaves(state, world, pos); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenMegaPineTree.java.patch b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenMegaPineTree.java.patch new file mode 100644 index 000000000..b997a3142 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenMegaPineTree.java.patch @@ -0,0 +1,52 @@ +--- original/net/minecraft/world/gen/feature/WorldGenMegaPineTree.java ++++ modified/net/minecraft/world/gen/feature/WorldGenMegaPineTree.java +@@ -40,24 +40,20 @@ + this.createCrown(worldIn, position.getX(), position.getZ(), position.getY() + i, 0, rand); + + for (int j = 0; j < i; j++) { +- IBlockState iblockstate = worldIn.getBlockState(position.up(j)); +- if (iblockstate.getMaterial() == Material.AIR || iblockstate.getMaterial() == Material.LEAVES) { ++ if (isAirLeaves(worldIn, position.up(j))) { + this.setBlockAndNotifyAdequately(worldIn, position.up(j), this.woodMetadata); + } + + if (j < i - 1) { +- iblockstate = worldIn.getBlockState(position.add(1, j, 0)); +- if (iblockstate.getMaterial() == Material.AIR || iblockstate.getMaterial() == Material.LEAVES) { ++ if (isAirLeaves(worldIn, position.add(1, j, 0))) { + this.setBlockAndNotifyAdequately(worldIn, position.add(1, j, 0), this.woodMetadata); + } + +- iblockstate = worldIn.getBlockState(position.add(1, j, 1)); +- if (iblockstate.getMaterial() == Material.AIR || iblockstate.getMaterial() == Material.LEAVES) { ++ if (isAirLeaves(worldIn, position.add(1, j, 1))) { + this.setBlockAndNotifyAdequately(worldIn, position.add(1, j, 1), this.woodMetadata); + } + +- iblockstate = worldIn.getBlockState(position.add(0, j, 1)); +- if (iblockstate.getMaterial() == Material.AIR || iblockstate.getMaterial() == Material.LEAVES) { ++ if (isAirLeaves(worldIn, position.add(0, j, 1))) { + this.setBlockAndNotifyAdequately(worldIn, position.add(0, j, 1), this.woodMetadata); + } + } +@@ -110,7 +106,8 @@ + BlockPos blockpos = pos.up(i); + IBlockState iblockstate = worldIn.getBlockState(blockpos); + Block block = iblockstate.getBlock(); +- if (block == Blocks.GRASS || block == Blocks.DIRT) { ++ ++ if (block.canSustainPlant(iblockstate, worldIn, blockpos, net.minecraft.util.EnumFacing.UP, ((net.minecraft.block.BlockSapling)Blocks.SAPLING))) { + this.setBlockAndNotifyAdequately(worldIn, blockpos, PODZOL); + break; + } +@@ -120,4 +117,10 @@ + } + } + } ++ ++ //Helper macro ++ private boolean isAirLeaves(World world, BlockPos pos) { ++ IBlockState state = world.getBlockState(pos); ++ return state.getBlock().isAir(state, world, pos) || state.getBlock().isLeaves(state, world, pos); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenMinable.java.patch b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenMinable.java.patch new file mode 100644 index 000000000..48ac5d4e7 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenMinable.java.patch @@ -0,0 +1,13 @@ +--- original/net/minecraft/world/gen/feature/WorldGenMinable.java ++++ modified/net/minecraft/world/gen/feature/WorldGenMinable.java +@@ -60,7 +60,9 @@ + double d14 = (j2 + 0.5 - d8) / (d10 / 2.0); + if (d12 * d12 + d13 * d13 + d14 * d14 < 1.0) { + BlockPos blockpos = new BlockPos(l1, i2, j2); +- if (this.predicate.apply(worldIn.getBlockState(blockpos))) { ++ ++ IBlockState state = worldIn.getBlockState(blockpos); ++ if (state.getBlock().isReplaceableOreGen(state, worldIn, blockpos, this.predicate)) { + worldIn.setBlockState(blockpos, this.oreBlock, 2); + } + } diff --git a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenSavannaTree.java.patch b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenSavannaTree.java.patch new file mode 100644 index 000000000..654158064 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenSavannaTree.java.patch @@ -0,0 +1,60 @@ +--- original/net/minecraft/world/gen/feature/WorldGenSavannaTree.java ++++ modified/net/minecraft/world/gen/feature/WorldGenSavannaTree.java +@@ -47,7 +47,7 @@ + for (int i1 = position.getZ() - k; i1 <= position.getZ() + k && flag; i1++) { + if (j < 0 || j >= 256) { + flag = false; +- } else if (!this.canGrowInto(worldIn.getBlockState(blockpos$mutableblockpos.setPos(l, j, i1)).getBlock())) { ++ } else if (!this.isReplaceable(worldIn,blockpos$mutableblockpos.setPos(l, j, i1))) { + flag = false; + } + } +@@ -58,9 +58,11 @@ + return false; + } + +- Block block = worldIn.getBlockState(position.down()).getBlock(); +- if ((block == Blocks.GRASS || block == Blocks.DIRT) && position.getY() < 256 - i - 1) { +- this.setDirtAt(worldIn, position.down()); ++ BlockPos down = position.down(); ++ IBlockState state = worldIn.getBlockState(down); ++ boolean isSoil = state.getBlock().canSustainPlant(state, worldIn, down, net.minecraft.util.EnumFacing.UP, (net.minecraft.block.BlockSapling)Blocks.SAPLING); ++ if (isSoil && position.getY() < worldIn.getHeight() - i - 1) { ++ state.getBlock().onPlantGrow(state, worldIn, down, position); + EnumFacing enumfacing = EnumFacing.Plane.HORIZONTAL.random(rand); + int k2 = i - rand.nextInt(4) - 1; + int l2 = 3 - rand.nextInt(3); +@@ -77,8 +79,8 @@ + } + + BlockPos blockpos = new BlockPos(i3, i2, j1); +- Material material = worldIn.getBlockState(blockpos).getMaterial(); +- if (material == Material.AIR || material == Material.LEAVES) { ++ state = worldIn.getBlockState(blockpos); ++ if (state.getBlock().isAir(state, worldIn, blockpos) || state.getBlock().isLeaves(state, worldIn, blockpos)) { + this.placeLogAt(worldIn, blockpos); + k1 = i2; + } +@@ -120,8 +122,8 @@ + i3 += enumfacing1.getXOffset(); + j1 += enumfacing1.getZOffset(); + BlockPos blockpos1 = new BlockPos(i3, j2, j1); +- Material material1 = worldIn.getBlockState(blockpos1).getMaterial(); +- if (material1 == Material.AIR || material1 == Material.LEAVES) { ++ state = worldIn.getBlockState(blockpos1); ++ if (state.getBlock().isAir(state, worldIn, blockpos1) || state.getBlock().isLeaves(state, worldIn, blockpos1)) { + this.placeLogAt(worldIn, blockpos1); + k1 = j2; + } +@@ -165,8 +167,9 @@ + } + + private void placeLeafAt(World worldIn, BlockPos pos) { +- Material material = worldIn.getBlockState(pos).getMaterial(); +- if (material == Material.AIR || material == Material.LEAVES) { ++ IBlockState state = worldIn.getBlockState(pos); ++ ++ if (state.getBlock().isAir(state, worldIn, pos) || state.getBlock().isLeaves(state, worldIn, pos)) { + this.setBlockAndNotifyAdequately(worldIn, pos, LEAF); + } + } diff --git a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenShrub.java.patch b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenShrub.java.patch new file mode 100644 index 000000000..13a06bb24 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenShrub.java.patch @@ -0,0 +1,34 @@ +--- original/net/minecraft/world/gen/feature/WorldGenShrub.java ++++ modified/net/minecraft/world/gen/feature/WorldGenShrub.java +@@ -21,15 +21,16 @@ + @Override + public boolean generate(World worldIn, Random rand, BlockPos position) { + for (IBlockState iblockstate = worldIn.getBlockState(position); +- (iblockstate.getMaterial() == Material.AIR || iblockstate.getMaterial() == Material.LEAVES) ++ (iblockstate.getBlock().isAir(iblockstate, worldIn, position) || iblockstate.getBlock().isLeaves(iblockstate, worldIn, position)) + && position.getY() > 0; + iblockstate = worldIn.getBlockState(position) + ) { + position = position.down(); + } + +- Block block = worldIn.getBlockState(position).getBlock(); +- if (block == Blocks.DIRT || block == Blocks.GRASS) { ++ IBlockState state = worldIn.getBlockState(position); ++ ++ if (state.getBlock().canSustainPlant(state, worldIn, position, net.minecraft.util.EnumFacing.UP, ((net.minecraft.block.BlockSapling)Blocks.SAPLING))) { + position = position.up(); + this.setBlockAndNotifyAdequately(worldIn, position, this.woodMetadata); + +@@ -44,8 +45,9 @@ + int k1 = j1 - position.getZ(); + if (Math.abs(i1) != k || Math.abs(k1) != k || rand.nextInt(2) != 0) { + BlockPos blockpos = new BlockPos(l, i, j1); +- Material material = worldIn.getBlockState(blockpos).getMaterial(); +- if (material == Material.AIR || material == Material.LEAVES) { ++ state = worldIn.getBlockState(blockpos); ++ ++ if (state.getBlock().canBeReplacedByLeaves(state, worldIn, blockpos)) { + this.setBlockAndNotifyAdequately(worldIn, blockpos, this.leavesMetadata); + } + } diff --git a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenSwamp.java.patch b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenSwamp.java.patch new file mode 100644 index 000000000..56ff0812c --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenSwamp.java.patch @@ -0,0 +1,122 @@ +--- original/net/minecraft/world/gen/feature/WorldGenSwamp.java ++++ modified/net/minecraft/world/gen/feature/WorldGenSwamp.java +@@ -51,7 +51,8 @@ + if (j >= 0 && j < 256) { + IBlockState iblockstate = worldIn.getBlockState(blockpos$mutableblockpos.setPos(l, j, i1)); + Block block = iblockstate.getBlock(); +- if (iblockstate.getMaterial() != Material.AIR && iblockstate.getMaterial() != Material.LEAVES) { ++ ++ if (!iblockstate.getBlock().isAir(iblockstate, worldIn, blockpos$mutableblockpos.setPos(l, j, i1)) && !iblockstate.getBlock().isLeaves(iblockstate, worldIn, blockpos$mutableblockpos.setPos(l, j, i1))) { + if (block != Blocks.WATER && block != Blocks.FLOWING_WATER) { + flag = false; + } else if (j > position.getY()) { +@@ -69,9 +70,11 @@ + return false; + } + +- Block block1 = worldIn.getBlockState(position.down()).getBlock(); +- if ((block1 == Blocks.GRASS || block1 == Blocks.DIRT) && position.getY() < 256 - i - 1) { +- this.setDirtAt(worldIn, position.down()); ++ BlockPos down = position.down(); ++ IBlockState state = worldIn.getBlockState(down); ++ boolean isSoil = state.getBlock().canSustainPlant(state, worldIn, down, net.minecraft.util.EnumFacing.UP, (net.minecraft.block.BlockSapling)Blocks.SAPLING); ++ if (isSoil && position.getY() < worldIn.getHeight() - i - 1) { ++ state.getBlock().onPlantGrow(state, worldIn, down, position); + + for (int k1 = position.getY() - 3 + i; k1 <= position.getY() + i; k1++) { + int j2 = k1 - (position.getY() + i); +@@ -84,7 +87,8 @@ + int j1 = i4 - position.getZ(); + if (Math.abs(k3) != l2 || Math.abs(j1) != l2 || rand.nextInt(2) != 0 && j2 != 0) { + BlockPos blockpos = new BlockPos(j3, k1, i4); +- if (!worldIn.getBlockState(blockpos).isFullBlock()) { ++ state = worldIn.getBlockState(blockpos); ++ if (state.getBlock().canBeReplacedByLeaves(state, worldIn, blockpos)) { + this.setBlockAndNotifyAdequately(worldIn, blockpos, LEAF); + } + } +@@ -93,42 +97,45 @@ + } + + for (int l1 = 0; l1 < i; l1++) { +- IBlockState iblockstate1 = worldIn.getBlockState(position.up(l1)); ++ BlockPos upN = position.up(l1); ++ IBlockState iblockstate1 = worldIn.getBlockState(upN); + Block block2 = iblockstate1.getBlock(); +- if (iblockstate1.getMaterial() == Material.AIR +- || iblockstate1.getMaterial() == Material.LEAVES ++ if (block2.isAir(iblockstate1, worldIn, upN) ++ || block2.isLeaves(iblockstate1, worldIn, upN) + || block2 == Blocks.FLOWING_WATER + || block2 == Blocks.WATER) { + this.setBlockAndNotifyAdequately(worldIn, position.up(l1), TRUNK); + } + } + +- for (int i2 = position.getY() - 3 + i; i2 <= position.getY() + i; i2++) { +- int k2 = i2 - (position.getY() + i); +- int i3 = 2 - k2 / 2; +- BlockPos.MutableBlockPos blockpos$mutableblockpos1 = new BlockPos.MutableBlockPos(); ++ for (int i2 = position.getY() - 3 + i; i2 <= position.getY() + i; i2++) { ++ int k2 = i2 - (position.getY() + i); ++ int i3 = 2 - k2 / 2; ++ BlockPos.MutableBlockPos blockpos$mutableblockpos1 = new BlockPos.MutableBlockPos(); + +- for (int l3 = position.getX() - i3; l3 <= position.getX() + i3; l3++) { +- for (int j4 = position.getZ() - i3; j4 <= position.getZ() + i3; j4++) { +- blockpos$mutableblockpos1.setPos(l3, i2, j4); +- if (worldIn.getBlockState(blockpos$mutableblockpos1).getMaterial() == Material.LEAVES) { +- BlockPos blockpos3 = blockpos$mutableblockpos1.west(); +- BlockPos blockpos4 = blockpos$mutableblockpos1.east(); +- BlockPos blockpos1 = blockpos$mutableblockpos1.north(); +- BlockPos blockpos2 = blockpos$mutableblockpos1.south(); +- if (rand.nextInt(4) == 0 && worldIn.getBlockState(blockpos3).getMaterial() == Material.AIR) { +- this.addVine(worldIn, blockpos3, BlockVine.EAST); +- } ++ for (int l3 = position.getX() - i3; l3 <= position.getX() + i3; l3++) { ++ for (int j4 = position.getZ() - i3; j4 <= position.getZ() + i3; j4++) { ++ blockpos$mutableblockpos1.setPos(l3, i2, j4); + +- if (rand.nextInt(4) == 0 && worldIn.getBlockState(blockpos4).getMaterial() == Material.AIR) { +- this.addVine(worldIn, blockpos4, BlockVine.WEST); +- } ++ if (worldIn.getBlockState(blockpos$mutableblockpos1).getMaterial() == Material.LEAVES) { ++ BlockPos blockpos3 = blockpos$mutableblockpos1.west(); ++ BlockPos blockpos4 = blockpos$mutableblockpos1.east(); ++ BlockPos blockpos1 = blockpos$mutableblockpos1.north(); ++ BlockPos blockpos2 = blockpos$mutableblockpos1.south(); + +- if (rand.nextInt(4) == 0 && worldIn.getBlockState(blockpos1).getMaterial() == Material.AIR) { +- this.addVine(worldIn, blockpos1, BlockVine.SOUTH); +- } ++ if (rand.nextInt(4) == 0 && worldIn.isAirBlock(blockpos3)) { ++ this.addVine(worldIn, blockpos3, BlockVine.EAST); ++ } + +- if (rand.nextInt(4) == 0 && worldIn.getBlockState(blockpos2).getMaterial() == Material.AIR) { ++ if (rand.nextInt(4) == 0 && worldIn.isAirBlock(blockpos4)) { ++ this.addVine(worldIn, blockpos4, BlockVine.WEST); ++ } ++ ++ if (rand.nextInt(4) == 0 && worldIn.isAirBlock(blockpos1)) { ++ this.addVine(worldIn, blockpos1, BlockVine.SOUTH); ++ } ++ ++ if (rand.nextInt(4) == 0 && worldIn.isAirBlock(blockpos2)) { + this.addVine(worldIn, blockpos2, BlockVine.NORTH); + } + } +@@ -146,11 +153,11 @@ + } + + private void addVine(World worldIn, BlockPos pos, PropertyBool prop) { +- IBlockState iblockstate = Blocks.VINE.getDefaultState().withProperty(prop, true); ++ IBlockState iblockstate = Blocks.VINE.getDefaultState().withProperty(prop, Boolean.valueOf(true)); + this.setBlockAndNotifyAdequately(worldIn, pos, iblockstate); + int i = 4; + +- for (BlockPos blockpos = pos.down(); worldIn.getBlockState(blockpos).getMaterial() == Material.AIR && i > 0; i--) { ++ for (BlockPos blockpos = pos.down(); worldIn.isAirBlock(blockpos) && i > 0; --i) { + this.setBlockAndNotifyAdequately(worldIn, blockpos, iblockstate); + blockpos = blockpos.down(); + } diff --git a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenTaiga1.java.patch b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenTaiga1.java.patch new file mode 100644 index 000000000..e7227e00d --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenTaiga1.java.patch @@ -0,0 +1,47 @@ +--- original/net/minecraft/world/gen/feature/WorldGenTaiga1.java ++++ modified/net/minecraft/world/gen/feature/WorldGenTaiga1.java +@@ -48,7 +48,7 @@ + for (int l1 = position.getZ() - j1; l1 <= position.getZ() + j1 && flag; l1++) { + if (i1 < 0 || i1 >= 256) { + flag = false; +- } else if (!this.canGrowInto(worldIn.getBlockState(blockpos$mutableblockpos.setPos(k1, i1, l1)).getBlock())) { ++ } else if (!this.isReplaceable(worldIn,blockpos$mutableblockpos.setPos(k1, i1, l1))) { + flag = false; + } + } +@@ -59,9 +59,11 @@ + return false; + } + +- Block block = worldIn.getBlockState(position.down()).getBlock(); +- if ((block == Blocks.GRASS || block == Blocks.DIRT) && position.getY() < 256 - i - 1) { +- this.setDirtAt(worldIn, position.down()); ++ BlockPos down = position.down(); ++ IBlockState state = worldIn.getBlockState(down); ++ boolean isSoil = state.getBlock().canSustainPlant(state, worldIn, down, net.minecraft.util.EnumFacing.UP, (net.minecraft.block.BlockSapling)Blocks.SAPLING); ++ if (isSoil && position.getY() < worldIn.getHeight() - i - 1) { ++ state.getBlock().onPlantGrow(state, worldIn, down, position); + int k2 = 0; + + for (int l2 = position.getY() + i; l2 >= position.getY() + j; l2--) { +@@ -72,7 +74,7 @@ + int j2 = i2 - position.getZ(); + if (Math.abs(k3) != k2 || Math.abs(j2) != k2 || k2 <= 0) { + BlockPos blockpos = new BlockPos(j3, l2, i2); +- if (!worldIn.getBlockState(blockpos).isFullBlock()) { ++ if (state.getBlock().canBeReplacedByLeaves(state, worldIn, blockpos)) { + this.setBlockAndNotifyAdequately(worldIn, blockpos, LEAF); + } + } +@@ -87,8 +89,9 @@ + } + + for (int i3 = 0; i3 < i - 1; i3++) { +- Material material = worldIn.getBlockState(position.up(i3)).getMaterial(); +- if (material == Material.AIR || material == Material.LEAVES) { ++ BlockPos upN = position.up(i3); ++ state = worldIn.getBlockState(upN); ++ if (state.getBlock().isAir(state, worldIn, upN) || state.getBlock().isLeaves(state, worldIn, upN)) { + this.setBlockAndNotifyAdequately(worldIn, position.up(i3), TRUNK); + } + } diff --git a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenTaiga2.java.patch b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenTaiga2.java.patch new file mode 100644 index 000000000..897ddfa8c --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenTaiga2.java.patch @@ -0,0 +1,63 @@ +--- original/net/minecraft/world/gen/feature/WorldGenTaiga2.java ++++ modified/net/minecraft/world/gen/feature/WorldGenTaiga2.java +@@ -32,7 +32,8 @@ + int k = i - j; + int l = 2 + rand.nextInt(2); + boolean flag = true; +- if (position.getY() >= 1 && position.getY() + i + 1 <= 256) { ++ ++ if (position.getY() >= 1 && position.getY() + i + 1 <= worldIn.getHeight()) { + for (int i1 = position.getY(); i1 <= position.getY() + 1 + i && flag; i1++) { + int j1; + if (i1 - position.getY() < j) { +@@ -45,9 +46,10 @@ + + for (int k1 = position.getX() - j1; k1 <= position.getX() + j1 && flag; k1++) { + for (int l1 = position.getZ() - j1; l1 <= position.getZ() + j1 && flag; l1++) { +- if (i1 >= 0 && i1 < 256) { +- Material material = worldIn.getBlockState(blockpos$mutableblockpos.setPos(k1, i1, l1)).getMaterial(); +- if (material != Material.AIR && material != Material.LEAVES) { ++ if (i1 >= 0 && i1 < worldIn.getHeight()) { ++ IBlockState state = worldIn.getBlockState(blockpos$mutableblockpos.setPos(k1, i1, l1)); ++ ++ if (!state.getBlock().isAir(state, worldIn, blockpos$mutableblockpos.setPos(k1, i1, l1)) && !state.getBlock().isLeaves(state, worldIn, blockpos$mutableblockpos.setPos(k1, i1, l1))) { + flag = false; + } + } else { +@@ -61,10 +63,12 @@ + return false; + } + +- Block block = worldIn.getBlockState(position.down()).getBlock(); +- if ((block == Blocks.GRASS || block == Blocks.DIRT || block == Blocks.FARMLAND) +- && position.getY() < 256 - i - 1) { +- this.setDirtAt(worldIn, position.down()); ++ BlockPos down = position.down(); ++ IBlockState state = worldIn.getBlockState(down); ++ boolean isSoil = state.getBlock().canSustainPlant(state, worldIn, down, net.minecraft.util.EnumFacing.UP, (net.minecraft.block.BlockSapling)Blocks.SAPLING); ++ if (isSoil ++ && position.getY() < worldIn.getHeight() - i - 1) { ++ state.getBlock().onPlantGrow(state, worldIn, down, position); + int i3 = rand.nextInt(2); + int j3 = 1; + int k3 = 0; +@@ -79,7 +83,7 @@ + int l2 = k2 - position.getZ(); + if (Math.abs(j2) != i3 || Math.abs(l2) != i3 || i3 <= 0) { + BlockPos blockpos = new BlockPos(i2, j4, k2); +- if (!worldIn.getBlockState(blockpos).isFullBlock()) { ++ if (state.getBlock().canBeReplacedByLeaves(state, worldIn, blockpos)) { + this.setBlockAndNotifyAdequately(worldIn, blockpos, LEAF); + } + } +@@ -100,8 +104,8 @@ + int i4 = rand.nextInt(3); + + for (int k4 = 0; k4 < i - i4; k4++) { +- Material material1 = worldIn.getBlockState(position.up(k4)).getMaterial(); +- if (material1 == Material.AIR || material1 == Material.LEAVES) { ++ BlockPos upN = position.up(k4); state = worldIn.getBlockState(upN); ++ if (state.getBlock().isAir(state, worldIn, upN) || state.getBlock().isLeaves(state, worldIn, upN)) { + this.setBlockAndNotifyAdequately(worldIn, position.up(k4), TRUNK); + } + } diff --git a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenTallGrass.java.patch b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenTallGrass.java.patch new file mode 100644 index 000000000..dfd1cc237 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenTallGrass.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/world/gen/feature/WorldGenTallGrass.java ++++ modified/net/minecraft/world/gen/feature/WorldGenTallGrass.java +@@ -18,7 +18,7 @@ + @Override + public boolean generate(World worldIn, Random rand, BlockPos position) { + for (IBlockState iblockstate = worldIn.getBlockState(position); +- (iblockstate.getMaterial() == Material.AIR || iblockstate.getMaterial() == Material.LEAVES) ++ (iblockstate.getBlock().isAir(iblockstate, worldIn, position) || iblockstate.getBlock().isLeaves(iblockstate, worldIn, position)) + && position.getY() > 0; + iblockstate = worldIn.getBlockState(position) + ) { diff --git a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenTrees.java.patch b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenTrees.java.patch new file mode 100644 index 000000000..966580f05 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenTrees.java.patch @@ -0,0 +1,86 @@ +--- original/net/minecraft/world/gen/feature/WorldGenTrees.java ++++ modified/net/minecraft/world/gen/feature/WorldGenTrees.java +@@ -47,7 +47,8 @@ + public boolean generate(World worldIn, Random rand, BlockPos position) { + int i = rand.nextInt(3) + this.minTreeHeight; + boolean flag = true; +- if (position.getY() >= 1 && position.getY() + i + 1 <= 256) { ++ ++ if (position.getY() >= 1 && position.getY() + i + 1 <= worldIn.getHeight()) { + for (int j = position.getY(); j <= position.getY() + 1 + i; j++) { + int k = 1; + if (j == position.getY()) { +@@ -62,9 +63,9 @@ + + for (int l = position.getX() - k; l <= position.getX() + k && flag; l++) { + for (int i1 = position.getZ() - k; i1 <= position.getZ() + k && flag; i1++) { +- if (j < 0 || j >= 256) { ++ if (j < 0 || j >= worldIn.getHeight()) { + flag = false; +- } else if (!this.canGrowInto(worldIn.getBlockState(blockpos$mutableblockpos.setPos(l, j, i1)).getBlock())) { ++ } else if (!this.isReplaceable(worldIn,blockpos$mutableblockpos.setPos(l, j, i1))) { + flag = false; + } + } +@@ -75,10 +76,12 @@ + return false; + } + +- Block block = worldIn.getBlockState(position.down()).getBlock(); +- if ((block == Blocks.GRASS || block == Blocks.DIRT || block == Blocks.FARMLAND) +- && position.getY() < 256 - i - 1) { +- this.setDirtAt(worldIn, position.down()); ++ BlockPos down = position.down(); ++ IBlockState state = worldIn.getBlockState(down); ++ boolean isSoil = state.getBlock().canSustainPlant(state, worldIn, down, net.minecraft.util.EnumFacing.UP, (net.minecraft.block.BlockSapling)Blocks.SAPLING); ++ if (isSoil ++ && position.getY() < worldIn.getHeight() - i - 1) { ++ state.getBlock().onPlantGrow(state, worldIn, down, position); + int k2 = 3; + int l2 = 0; + +@@ -94,7 +97,7 @@ + if (Math.abs(l1) != j1 || Math.abs(j2) != j1 || rand.nextInt(2) != 0 && i4 != 0) { + BlockPos blockpos = new BlockPos(k1, i3, i2); + Material material = worldIn.getBlockState(blockpos).getMaterial(); +- if (material == Material.AIR || material == Material.LEAVES || material == Material.VINE) { ++ if (state.getBlock().isAir(state, worldIn, blockpos) || state.getBlock().isLeaves(state, worldIn, blockpos) || state.getMaterial() == Material.VINE) { + this.setBlockAndNotifyAdequately(worldIn, blockpos, this.metaLeaves); + } + } +@@ -102,15 +105,18 @@ + } + } + +- for (int j3 = 0; j3 < i; j3++) { +- Material material1 = worldIn.getBlockState(position.up(j3)).getMaterial(); +- if (material1 == Material.AIR || material1 == Material.LEAVES || material1 == Material.VINE) { +- this.setBlockAndNotifyAdequately(worldIn, position.up(j3), this.metaWood); +- if (this.vinesGrow && j3 > 0) { +- if (rand.nextInt(3) > 0 && worldIn.isAirBlock(position.add(-1, j3, 0))) { +- this.addVine(worldIn, position.add(-1, j3, 0), BlockVine.EAST); +- } ++ for (int j3 = 0; j3 < i; j3++) { ++ BlockPos upN = position.up(j3); ++ state = worldIn.getBlockState(upN); + ++ if (state.getBlock().isAir(state, worldIn, upN) || state.getBlock().isLeaves(state, worldIn, upN) || state.getMaterial() == Material.VINE) { ++ this.setBlockAndNotifyAdequately(worldIn, position.up(j3), this.metaWood); ++ ++ if (this.vinesGrow && j3 > 0) { ++ if (rand.nextInt(3) > 0 && worldIn.isAirBlock(position.add(-1, j3, 0))) { ++ this.addVine(worldIn, position.add(-1, j3, 0), BlockVine.EAST); ++ } ++ + if (rand.nextInt(3) > 0 && worldIn.isAirBlock(position.add(1, j3, 0))) { + this.addVine(worldIn, position.add(1, j3, 0), BlockVine.WEST); + } +@@ -202,7 +208,7 @@ + this.addVine(worldIn, pos, prop); + int i = 4; + +- for (BlockPos blockpos = pos.down(); worldIn.getBlockState(blockpos).getMaterial() == Material.AIR && i > 0; i--) { ++ for (BlockPos blockpos = pos.down(); worldIn.isAirBlock(blockpos) && i > 0; --i) { + this.addVine(worldIn, blockpos, prop); + blockpos = blockpos.down(); + } diff --git a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenerator.java.patch b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenerator.java.patch new file mode 100644 index 000000000..0b9f40f16 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenerator.java.patch @@ -0,0 +1,12 @@ +--- original/net/minecraft/world/gen/feature/WorldGenerator.java ++++ modified/net/minecraft/world/gen/feature/WorldGenerator.java +@@ -26,7 +26,8 @@ + if (this.doBlockNotify) { + worldIn.setBlockState(pos, state, 3); + } else { +- worldIn.setBlockState(pos, state, 2); ++ int flag = net.minecraftforge.common.ForgeModContainer.fixVanillaCascading ? 2| 16 : 2; //Forge: With bit 5 unset, it will notify neighbors and load adjacent chunks. ++ worldIn.setBlockState(pos, state, flag); + } + } + } diff --git a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGeneratorBonusChest.java.patch b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGeneratorBonusChest.java.patch new file mode 100644 index 000000000..956fe20b5 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGeneratorBonusChest.java.patch @@ -0,0 +1,35 @@ +--- original/net/minecraft/world/gen/feature/WorldGeneratorBonusChest.java ++++ modified/net/minecraft/world/gen/feature/WorldGeneratorBonusChest.java +@@ -14,7 +14,7 @@ + @Override + public boolean generate(World worldIn, Random rand, BlockPos position) { + for (IBlockState iblockstate = worldIn.getBlockState(position); +- (iblockstate.getMaterial() == Material.AIR || iblockstate.getMaterial() == Material.LEAVES) ++ (iblockstate.getBlock().isAir(iblockstate, worldIn, position) || iblockstate.getBlock().isLeaves(iblockstate, worldIn, position)) + && position.getY() > 1; + iblockstate = worldIn.getBlockState(position) + ) { +@@ -44,19 +44,19 @@ + BlockPos blockpos2 = blockpos.west(); + BlockPos blockpos3 = blockpos.north(); + BlockPos blockpos4 = blockpos.south(); +- if (worldIn.isAirBlock(blockpos2) && worldIn.getBlockState(blockpos2.down()).isTopSolid()) { ++ if (worldIn.isAirBlock(blockpos2) && worldIn.getBlockState(blockpos2.down()).isSideSolid(worldIn, blockpos2.down(), net.minecraft.util.EnumFacing.UP)) { + worldIn.setBlockState(blockpos2, Blocks.TORCH.getDefaultState(), 2); + } + +- if (worldIn.isAirBlock(blockpos1) && worldIn.getBlockState(blockpos1.down()).isTopSolid()) { ++ if (worldIn.isAirBlock(blockpos1) && worldIn.getBlockState(blockpos1.down()).isSideSolid(worldIn, blockpos1.down(), net.minecraft.util.EnumFacing.UP)) { + worldIn.setBlockState(blockpos1, Blocks.TORCH.getDefaultState(), 2); + } + +- if (worldIn.isAirBlock(blockpos3) && worldIn.getBlockState(blockpos3.down()).isTopSolid()) { ++ if (worldIn.isAirBlock(blockpos3) && worldIn.getBlockState(blockpos3.down()).isSideSolid(worldIn, blockpos3.down(), net.minecraft.util.EnumFacing.UP)) { + worldIn.setBlockState(blockpos3, Blocks.TORCH.getDefaultState(), 2); + } + +- if (worldIn.isAirBlock(blockpos4) && worldIn.getBlockState(blockpos4.down()).isTopSolid()) { ++ if (worldIn.isAirBlock(blockpos4) && worldIn.getBlockState(blockpos4.down()).isSideSolid(worldIn, blockpos4.down(), net.minecraft.util.EnumFacing.UP)) { + worldIn.setBlockState(blockpos4, Blocks.TORCH.getDefaultState(), 2); + } + diff --git a/module/minecraft/patches/net/minecraft/world/gen/layer/GenLayer.java.patch b/module/minecraft/patches/net/minecraft/world/gen/layer/GenLayer.java.patch new file mode 100644 index 000000000..f72594e20 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/layer/GenLayer.java.patch @@ -0,0 +1,47 @@ +--- original/net/minecraft/world/gen/layer/GenLayer.java ++++ modified/net/minecraft/world/gen/layer/GenLayer.java +@@ -49,10 +49,7 @@ + GenLayer genlayer1 = genlayer; + genlayer1 = GenLayerZoom.magnify(1000L, genlayer1, 0); + genlayer1 = new GenLayerRiverInit(100L, genlayer1); +- GenLayer genlayer2 = genlayer; +- genlayer2 = new GenLayerBiome(200L, genlayer2, p_180781_2_, p_180781_3_); +- genlayer2 = GenLayerZoom.magnify(1000L, genlayer2, 2); +- genlayer2 = new GenLayerBiomeEdge(1000L, genlayer2); ++ GenLayer genlayer2 = p_180781_2_.getBiomeLayer(seed, genlayer, p_180781_3_); + GenLayer genlayer3 = genlayer1; + genlayer3 = GenLayerZoom.magnify(1000L, genlayer3, 2); + genlayer2 = new GenLayerHills(1000L, genlayer2, genlayer3); +@@ -153,11 +150,29 @@ + + /** returns true if the biomeId is one of the various ocean biomes. */ + protected static boolean isBiomeOceanic(int p_151618_0_) { +- Biome biome = Biome.getBiome(p_151618_0_); +- return biome == Biomes.OCEAN || biome == Biomes.DEEP_OCEAN || biome == Biomes.FROZEN_OCEAN; ++ return net.minecraftforge.common.BiomeManager.oceanBiomes.contains(Biome.getBiome(p_151618_0_)); + } + +- /** selects a random integer from a set of provided integers */ ++ /* ======================================== FORGE START =====================================*/ ++ protected long nextLong(long par1) { ++ long j = (this.chunkSeed >> 24) % par1; ++ ++ if (j < 0) { ++ j += par1; ++ } ++ ++ this.chunkSeed *= this.chunkSeed * 6364136223846793005L + 1442695040888963407L; ++ this.chunkSeed += this.worldGenSeed; ++ return j; ++ } ++ ++ public static int getModdedBiomeSize(WorldType worldType, int original) { ++ net.minecraftforge.event.terraingen.WorldTypeEvent.BiomeSize event = new net.minecraftforge.event.terraingen.WorldTypeEvent.BiomeSize(worldType, original); ++ net.minecraftforge.common.MinecraftForge.TERRAIN_GEN_BUS.post(event); ++ return event.getNewSize(); ++ } ++ /* ========================================= FORGE END ======================================*/ ++ + protected int selectRandom(int... p_151619_1_) { + return p_151619_1_[this.nextInt(p_151619_1_.length)]; + } diff --git a/module/minecraft/patches/net/minecraft/world/gen/layer/GenLayerBiome.java.patch b/module/minecraft/patches/net/minecraft/world/gen/layer/GenLayerBiome.java.patch new file mode 100644 index 000000000..48a1a2672 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/layer/GenLayerBiome.java.patch @@ -0,0 +1,89 @@ +--- original/net/minecraft/world/gen/layer/GenLayerBiome.java ++++ modified/net/minecraft/world/gen/layer/GenLayerBiome.java +@@ -6,23 +6,36 @@ + import net.minecraft.world.gen.ChunkGeneratorSettings; + + public class GenLayerBiome extends GenLayer { +- private Biome[] warmBiomes = new Biome[]{ +- Biomes.DESERT, Biomes.DESERT, Biomes.DESERT, Biomes.SAVANNA, Biomes.SAVANNA, Biomes.PLAINS +- }; +- private final Biome[] mediumBiomes = new Biome[]{ +- Biomes.FOREST, Biomes.ROOFED_FOREST, Biomes.EXTREME_HILLS, Biomes.PLAINS, Biomes.BIRCH_FOREST, Biomes.SWAMPLAND +- }; +- private final Biome[] coldBiomes = new Biome[]{Biomes.FOREST, Biomes.EXTREME_HILLS, Biomes.TAIGA, Biomes.PLAINS}; +- private final Biome[] iceBiomes = new Biome[]{Biomes.ICE_PLAINS, Biomes.ICE_PLAINS, Biomes.ICE_PLAINS, Biomes.COLD_TAIGA}; ++ @SuppressWarnings("unchecked") ++ private java.util.List[] biomes = new java.util.ArrayList[net.minecraftforge.common.BiomeManager.BiomeType.values().length]; + private final ChunkGeneratorSettings settings; + + public GenLayerBiome(long p_i45560_1_, GenLayer p_i45560_3_, WorldType p_i45560_4_, ChunkGeneratorSettings p_i45560_5_) { + super(p_i45560_1_); + this.parent = p_i45560_3_; ++ ++ for (net.minecraftforge.common.BiomeManager.BiomeType type : net.minecraftforge.common.BiomeManager.BiomeType.values()) { ++ com.google.common.collect.ImmutableList biomesToAdd = net.minecraftforge.common.BiomeManager.getBiomes(type); ++ int idx = type.ordinal(); ++ ++ if (biomes[idx] == null) biomes[idx] = new java.util.ArrayList<>(); ++ if (biomesToAdd != null) biomes[idx].addAll(biomesToAdd); ++ } ++ ++ int desertIdx = net.minecraftforge.common.BiomeManager.BiomeType.DESERT.ordinal(); ++ ++ biomes[desertIdx].add(new net.minecraftforge.common.BiomeManager.BiomeEntry(Biomes.DESERT, 30)); ++ biomes[desertIdx].add(new net.minecraftforge.common.BiomeManager.BiomeEntry(Biomes.SAVANNA, 20)); ++ biomes[desertIdx].add(new net.minecraftforge.common.BiomeManager.BiomeEntry(Biomes.PLAINS, 10)); ++ + if (p_i45560_4_ == WorldType.DEFAULT_1_1) { +- this.warmBiomes = new Biome[]{ +- Biomes.DESERT, Biomes.FOREST, Biomes.EXTREME_HILLS, Biomes.SWAMPLAND, Biomes.PLAINS, Biomes.TAIGA +- }; ++ biomes[desertIdx].clear(); ++ biomes[desertIdx].add(new net.minecraftforge.common.BiomeManager.BiomeEntry(Biomes.DESERT, 10)); ++ biomes[desertIdx].add(new net.minecraftforge.common.BiomeManager.BiomeEntry(Biomes.FOREST, 10)); ++ biomes[desertIdx].add(new net.minecraftforge.common.BiomeManager.BiomeEntry(Biomes.EXTREME_HILLS, 10)); ++ biomes[desertIdx].add(new net.minecraftforge.common.BiomeManager.BiomeEntry(Biomes.SWAMPLAND, 10)); ++ biomes[desertIdx].add(new net.minecraftforge.common.BiomeManager.BiomeEntry(Biomes.PLAINS, 10)); ++ biomes[desertIdx].add(new net.minecraftforge.common.BiomeManager.BiomeEntry(Biomes.TAIGA, 10)); + this.settings = null; + } else { + this.settings = p_i45560_5_; +@@ -55,22 +68,22 @@ + aint1[j + i * areaWidth] = Biome.getIdForBiome(Biomes.MESA_ROCK); + } + } else { +- aint1[j + i * areaWidth] = Biome.getIdForBiome(this.warmBiomes[this.nextInt(this.warmBiomes.length)]); ++ aint1[j + i * areaWidth] = Biome.getIdForBiome(getWeightedBiomeEntry(net.minecraftforge.common.BiomeManager.BiomeType.DESERT).biome); + } + } else if (k == 2) { + if (l > 0) { + aint1[j + i * areaWidth] = Biome.getIdForBiome(Biomes.JUNGLE); + } else { +- aint1[j + i * areaWidth] = Biome.getIdForBiome(this.mediumBiomes[this.nextInt(this.mediumBiomes.length)]); ++ aint1[j + i * areaWidth] = Biome.getIdForBiome(getWeightedBiomeEntry(net.minecraftforge.common.BiomeManager.BiomeType.WARM).biome); + } + } else if (k == 3) { + if (l > 0) { + aint1[j + i * areaWidth] = Biome.getIdForBiome(Biomes.REDWOOD_TAIGA); + } else { +- aint1[j + i * areaWidth] = Biome.getIdForBiome(this.coldBiomes[this.nextInt(this.coldBiomes.length)]); ++ aint1[j + i * areaWidth] = Biome.getIdForBiome(getWeightedBiomeEntry(net.minecraftforge.common.BiomeManager.BiomeType.COOL).biome); + } + } else if (k == 4) { +- aint1[j + i * areaWidth] = Biome.getIdForBiome(this.iceBiomes[this.nextInt(this.iceBiomes.length)]); ++ aint1[j + i * areaWidth] = Biome.getIdForBiome(getWeightedBiomeEntry(net.minecraftforge.common.BiomeManager.BiomeType.ICY).biome); + } else { + aint1[j + i * areaWidth] = Biome.getIdForBiome(Biomes.MUSHROOM_ISLAND); + } +@@ -79,4 +92,11 @@ + + return aint1; + } ++ ++ protected net.minecraftforge.common.BiomeManager.BiomeEntry getWeightedBiomeEntry(net.minecraftforge.common.BiomeManager.BiomeType type) { ++ java.util.List biomeList = biomes[type.ordinal()]; ++ int totalWeight = net.minecraft.util.WeightedRandom.getTotalWeight(biomeList); ++ int weight = net.minecraftforge.common.BiomeManager.isTypeListModded(type)?nextInt(totalWeight):nextInt(totalWeight / 10) * 10; ++ return (net.minecraftforge.common.BiomeManager.BiomeEntry)net.minecraft.util.WeightedRandom.getRandomItem(biomeList, weight); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/world/gen/structure/MapGenStronghold.java.patch b/module/minecraft/patches/net/minecraft/world/gen/structure/MapGenStronghold.java.patch new file mode 100644 index 000000000..bcd6ac854 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/structure/MapGenStronghold.java.patch @@ -0,0 +1,30 @@ +--- original/net/minecraft/world/gen/structure/MapGenStronghold.java ++++ modified/net/minecraft/world/gen/structure/MapGenStronghold.java +@@ -15,18 +15,24 @@ + public final List allowedBiomes; + /** is spawned false and set true once the defined BiomeGenBases were compared with the present ones */ + private boolean ranBiomeCheck; +- private ChunkPos[] structureCoords = new ChunkPos[128]; +- private double distance = 32.0; ++ private ChunkPos[] structureCoords= new ChunkPos[128]; ++ private double distance = 32.0D; + private int spread = 3; + + public MapGenStronghold() { + this.allowedBiomes = Lists.newArrayList(); + + for (Biome biome : Biome.REGISTRY) { +- if (biome != null && biome.getBaseHeight() > 0.0F) { ++ if (biome != null && biome.getBaseHeight() > 0.0F && !net.minecraftforge.common.BiomeManager.strongHoldBiomesBlackList.contains(biome)) { + this.allowedBiomes.add(biome); + } + } ++ ++ for (Biome biome : net.minecraftforge.common.BiomeManager.strongHoldBiomes) { ++ if (!this.allowedBiomes.contains(biome)) { ++ this.allowedBiomes.add(biome); ++ } ++ } + } + + public MapGenStronghold(Map p_i2068_1_) { diff --git a/module/minecraft/patches/net/minecraft/world/gen/structure/MapGenStructure.java.patch b/module/minecraft/patches/net/minecraft/world/gen/structure/MapGenStructure.java.patch new file mode 100644 index 000000000..aaa28abd7 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/structure/MapGenStructure.java.patch @@ -0,0 +1,16 @@ +--- original/net/minecraft/world/gen/structure/MapGenStructure.java ++++ modified/net/minecraft/world/gen/structure/MapGenStructure.java +@@ -123,10 +123,11 @@ + + protected void initializeStructureData(World worldIn) { + if (this.structureData == null && worldIn != null) { +- this.structureData = (MapGenStructureData)worldIn.loadData(MapGenStructureData.class, this.getStructureName()); ++ this.structureData = (MapGenStructureData)worldIn.getPerWorldStorage().getOrLoadData(MapGenStructureData.class, this.getStructureName()); ++ + if (this.structureData == null) { + this.structureData = new MapGenStructureData(this.getStructureName()); +- worldIn.setData(this.getStructureName(), this.structureData); ++ worldIn.getPerWorldStorage().setData(this.getStructureName(), this.structureData); + } else { + NBTTagCompound nbttagcompound = this.structureData.getTagCompound(); + diff --git a/module/minecraft/patches/net/minecraft/world/gen/structure/StructureComponent.java.patch b/module/minecraft/patches/net/minecraft/world/gen/structure/StructureComponent.java.patch new file mode 100644 index 000000000..a4808c7fb --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/structure/StructureComponent.java.patch @@ -0,0 +1,12 @@ +--- original/net/minecraft/world/gen/structure/StructureComponent.java ++++ modified/net/minecraft/world/gen/structure/StructureComponent.java +@@ -40,6 +40,9 @@ + + /** Writes structure base data (id, boundingbox, {@link net.minecraft.world.gen.structure.StructureComponent#coordBaseMode coordBase} and {@link net.minecraft.world.gen.structure.StructureComponent#componentType componentType}) to new NBTTagCompound and returns it. */ + public final NBTTagCompound createStructureBaseNBT() { ++ if (MapGenStructureIO.getStructureComponentName(this) == null) { // Friendlier error then the Null String error below. ++ throw new RuntimeException("StructureComponent \"" + this.getClass().getName() + "\" missing ID Mapping, Modder see MapGenStructureIO"); ++ } + NBTTagCompound nbttagcompound = new NBTTagCompound(); + nbttagcompound.setString("id", MapGenStructureIO.getStructureComponentName(this)); + nbttagcompound.setTag("BB", this.boundingBox.toNBTTagIntArray()); diff --git a/module/minecraft/patches/net/minecraft/world/gen/structure/StructureStart.java.patch b/module/minecraft/patches/net/minecraft/world/gen/structure/StructureStart.java.patch new file mode 100644 index 000000000..3d44bae62 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/structure/StructureStart.java.patch @@ -0,0 +1,22 @@ +--- original/net/minecraft/world/gen/structure/StructureStart.java ++++ modified/net/minecraft/world/gen/structure/StructureStart.java +@@ -54,6 +54,9 @@ + } + + public NBTTagCompound writeStructureComponentsToNBT(int chunkX, int chunkZ) { ++ if (MapGenStructureIO.getStructureStartName(this) == null) { // This is just a more friendly error instead of the 'Null String' below ++ throw new RuntimeException("StructureStart \"" + this.getClass().getName() + "\" missing ID Mapping, Modder see MapGenStructureIO"); ++ } + NBTTagCompound nbttagcompound = new NBTTagCompound(); + nbttagcompound.setString("id", MapGenStructureIO.getStructureStartName(this)); + nbttagcompound.setInteger("ChunkX", chunkX); +@@ -83,7 +86,8 @@ + NBTTagList nbttaglist = tagCompound.getTagList("Children", 10); + + for (int i = 0; i < nbttaglist.tagCount(); i++) { +- this.components.add(MapGenStructureIO.getStructureComponent(nbttaglist.getCompoundTagAt(i), worldIn)); ++ StructureComponent tmp = MapGenStructureIO.getStructureComponent(nbttaglist.getCompoundTagAt(i), worldIn); ++ if (tmp != null) this.components.add(tmp); //Forge: Prevent NPEs further down the line when a componenet can't be loaded. + } + + this.readFromNBT(tagCompound); diff --git a/module/minecraft/patches/net/minecraft/world/gen/structure/StructureVillagePieces.java.patch b/module/minecraft/patches/net/minecraft/world/gen/structure/StructureVillagePieces.java.patch new file mode 100644 index 000000000..3964d98bd --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/structure/StructureVillagePieces.java.patch @@ -0,0 +1,123 @@ +--- original/net/minecraft/world/gen/structure/StructureVillagePieces.java ++++ modified/net/minecraft/world/gen/structure/StructureVillagePieces.java +@@ -88,6 +88,7 @@ + StructureVillagePieces.House3.class, 8, MathHelper.getInt(random, 0 + size, 3 + size * 2) + ) + ); ++ net.minecraftforge.fml.common.registry.VillagerRegistry.addExtraVillageComponents(list, random, size); + Iterator iterator = list.iterator(); + + while (iterator.hasNext()) { +@@ -162,8 +163,10 @@ + ); + } else if (oclass == StructureVillagePieces.House3.class) { + structurevillagepieces$village = StructureVillagePieces.House3.createPiece( +- start, structureComponents, rand, structureMinX, structureMinY, structureMinZ, facing, componentType +- ); ++ start, structureComponents, rand, structureMinX, structureMinY, structureMinZ, facing, componentType ++ ); ++ } else { ++ structurevillagepieces$village = net.minecraftforge.fml.common.registry.VillagerRegistry.getVillageComponent(weight, start , structureComponents, rand, structureMinX, structureMinY, structureMinZ, facing, componentType); + } + + return structurevillagepieces$village; +@@ -1617,9 +1620,9 @@ + public Road() { + } + +- protected Road(StructureVillagePieces.Start start, int type) { +- super(start, type); +- } ++ protected Road(StructureVillagePieces.Start start, int type) { ++ super(start, type); ++ } + } + + public static class Start extends StructureVillagePieces.Well { +@@ -1717,6 +1720,7 @@ + private int villagersSpawned; + protected int structureType; + protected boolean isZombieInfested; ++ protected StructureVillagePieces.Start startPiece; + + public Village() { + } +@@ -1726,6 +1730,7 @@ + if (start != null) { + this.structureType = start.structureType; + this.isZombieInfested = start.isZombieInfested; ++ startPiece = start; + } + } + +@@ -1893,39 +1898,46 @@ + } + + /** Spawns a number of villagers in this component. Parameters: world, component bounding box, x offset, y offset, z offset, number of villagers */ +- protected void spawnVillagers(World worldIn, StructureBoundingBox structurebb, int x, int y, int z, int count) { +- if (this.villagersSpawned < count) { +- for (int i = this.villagersSpawned; i < count; i++) { +- int j = this.getXWithOffset(x + i, z); +- int k = this.getYWithOffset(y); +- int l = this.getZWithOffset(x + i, z); +- if (!structurebb.isVecInside(new BlockPos(j, k, l))) { +- break; +- } ++ protected void spawnVillagers(World worldIn, StructureBoundingBox structurebb, int x, int y, int z, int count) { ++ if (this.villagersSpawned < count) { ++ for (int i = this.villagersSpawned; i < count; i++) { ++ int j = this.getXWithOffset(x + i, z); ++ int k = this.getYWithOffset(y); ++ int l = this.getZWithOffset(x + i, z); + +- this.villagersSpawned++; +- if (this.isZombieInfested) { +- EntityZombieVillager entityzombievillager = new EntityZombieVillager(worldIn); +- entityzombievillager.setLocationAndAngles(j + 0.5, k, l + 0.5, 0.0F, 0.0F); +- entityzombievillager.onInitialSpawn(worldIn.getDifficultyForLocation(new BlockPos(entityzombievillager)), null); +- entityzombievillager.setProfession(this.chooseProfession(i, 0)); +- entityzombievillager.enablePersistence(); +- worldIn.spawnEntity(entityzombievillager); +- } else { +- EntityVillager entityvillager = new EntityVillager(worldIn); +- entityvillager.setLocationAndAngles(j + 0.5, k, l + 0.5, 0.0F, 0.0F); +- entityvillager.setProfession(this.chooseProfession(i, worldIn.rand.nextInt(6))); +- entityvillager.finalizeMobSpawn(worldIn.getDifficultyForLocation(new BlockPos(entityvillager)), null, false); +- worldIn.spawnEntity(entityvillager); ++ if (!structurebb.isVecInside(new BlockPos(j, k, l))) { ++ break; ++ } ++ ++ this.villagersSpawned++; ++ ++ if (this.isZombieInfested) { ++ EntityZombieVillager entityzombievillager = new EntityZombieVillager(worldIn); ++ entityzombievillager.setLocationAndAngles(j + 0.5, k, l + 0.5, 0.0F, 0.0F); ++ entityzombievillager.onInitialSpawn(worldIn.getDifficultyForLocation(new BlockPos(entityzombievillager)), null); ++ entityzombievillager.setForgeProfession(this.chooseForgeProfession(i, net.minecraftforge.fml.common.registry.VillagerRegistry.FARMER)); ++ entityzombievillager.enablePersistence(); ++ worldIn.spawnEntity(entityzombievillager); ++ } else { ++ EntityVillager entityvillager = new EntityVillager(worldIn); ++ entityvillager.setLocationAndAngles(j + 0.5, k, l + 0.5, 0.0F, 0.0F); ++ net.minecraftforge.fml.common.registry.VillagerRegistry.setRandomProfession(entityvillager, worldIn.rand); ++ entityvillager.setProfession(this.chooseForgeProfession(i, entityvillager.getProfessionForge())); ++ entityvillager.finalizeMobSpawn(worldIn.getDifficultyForLocation(new BlockPos(entityvillager)), null, false); ++ worldIn.spawnEntity(entityvillager); ++ } + } + } + } +- } + + protected int chooseProfession(int villagersSpawnedIn, int currentVillagerProfession) { + return currentVillagerProfession; + } + ++ protected net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession chooseForgeProfession(int count, net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession prof) { ++ return net.minecraftforge.fml.common.registry.VillagerRegistry.getById(chooseProfession(count, net.minecraftforge.fml.common.registry.VillagerRegistry.getId(prof))); ++ } ++ + protected IBlockState getBiomeSpecificBlockState(IBlockState blockstateIn) { + if (this.structureType == 1) { + if (blockstateIn.getBlock() == Blocks.LOG || blockstateIn.getBlock() == Blocks.LOG2) { diff --git a/module/minecraft/patches/net/minecraft/world/gen/structure/template/Template.java.patch b/module/minecraft/patches/net/minecraft/world/gen/structure/template/Template.java.patch new file mode 100644 index 000000000..83cd198cb --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/gen/structure/template/Template.java.patch @@ -0,0 +1,19 @@ +--- original/net/minecraft/world/gen/structure/template/Template.java ++++ modified/net/minecraft/world/gen/structure/template/Template.java +@@ -221,6 +221,8 @@ + + for (Template.BlockInfo template$blockinfo : this.blocks) { + BlockPos blockpos = transformedBlockPos(placementIn, template$blockinfo.pos).add(pos); ++ // Forge: skip processing blocks outside BB to prevent cascading worldgen issues ++ if (structureboundingbox != null && !structureboundingbox.isVecInside(blockpos)) continue; + Template.BlockInfo template$blockinfo1 = templateProcessor != null + ? templateProcessor.processBlock(worldIn, blockpos, template$blockinfo) + : template$blockinfo; +@@ -493,6 +495,7 @@ + nbttaglist2.appendTag(NBTUtil.writeBlockState(new NBTTagCompound(), iblockstate)); + } + ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().getDataFixer().writeVersionData(nbt); //Moved up for MC updating reasons. + nbt.setTag("palette", nbttaglist2); + nbt.setTag("blocks", nbttaglist); + nbt.setTag("entities", nbttaglist1); diff --git a/module/minecraft/patches/net/minecraft/world/storage/DerivedWorldInfo.java.patch b/module/minecraft/patches/net/minecraft/world/storage/DerivedWorldInfo.java.patch new file mode 100644 index 000000000..68d65fabe --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/storage/DerivedWorldInfo.java.patch @@ -0,0 +1,26 @@ +--- original/net/minecraft/world/storage/DerivedWorldInfo.java ++++ modified/net/minecraft/world/storage/DerivedWorldInfo.java +@@ -247,13 +247,23 @@ + public void setDifficultyLocked(boolean locked) { + } + ++ @Deprecated + @Override + public void setDimensionData(DimensionType dimensionIn, NBTTagCompound compound) { + this.delegate.setDimensionData(dimensionIn, compound); + } + ++ @Deprecated + @Override + public NBTTagCompound getDimensionData(DimensionType dimensionIn) { + return this.delegate.getDimensionData(dimensionIn); + } ++ ++ public void setDimensionData(int dimensionID, NBTTagCompound compound) { ++ this.delegate.setDimensionData(dimensionID, compound); ++ } ++ ++ public NBTTagCompound getDimensionData(int dimensionID) { ++ return this.delegate.getDimensionData(dimensionID); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/world/storage/MapData.java.patch b/module/minecraft/patches/net/minecraft/world/storage/MapData.java.patch new file mode 100644 index 000000000..4cb877937 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/storage/MapData.java.patch @@ -0,0 +1,41 @@ +--- original/net/minecraft/world/storage/MapData.java ++++ modified/net/minecraft/world/storage/MapData.java +@@ -19,7 +19,7 @@ + public class MapData extends WorldSavedData { + public int xCenter; + public int zCenter; +- public byte dimension; ++ public int dimension; //FML byte -> int + public boolean trackingPosition; + public boolean unlimitedTracking; + public byte scale; +@@ -46,7 +46,7 @@ + /** reads in data from the NBTTagCompound into this MapDataBase */ + @Override + public void readFromNBT(NBTTagCompound nbt) { +- this.dimension = nbt.getByte("dimension"); ++ this.dimension = nbt.getInteger("dimension"); + this.xCenter = nbt.getInteger("xCenter"); + this.zCenter = nbt.getInteger("zCenter"); + this.scale = nbt.getByte("scale"); +@@ -84,7 +84,7 @@ + + @Override + public NBTTagCompound writeToNBT(NBTTagCompound compound) { +- compound.setByte("dimension", this.dimension); ++ compound.setInteger("dimension", this.dimension); + compound.setInteger("xCenter", this.xCenter); + compound.setInteger("zCenter", this.zCenter); + compound.setByte("scale", this.scale); +@@ -195,8 +195,9 @@ + if (f >= -63.0F && f1 >= -63.0F && f <= 63.0F && f1 <= 63.0F) { + rotationIn += rotationIn < 0.0 ? -8.0 : 8.0; + b2 = (byte)(rotationIn * 16.0 / 360.0); +- if (this.dimension < 0) { +- int l = (int)(worldIn.getWorldInfo().getWorldTime() / 10L); ++ ++ if (worldIn.provider.shouldMapSpin(decorationName, worldX, worldZ, rotationIn)) { ++ int l = (int)(worldIn.getWorldTime() / 10L); + b2 = (byte)(l * l * 34187121 + l * 121 >> 15 & 15); + } + } else { diff --git a/module/minecraft/patches/net/minecraft/world/storage/MapDecoration.java.patch b/module/minecraft/patches/net/minecraft/world/storage/MapDecoration.java.patch new file mode 100644 index 000000000..dc238f5ae --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/storage/MapDecoration.java.patch @@ -0,0 +1,19 @@ +--- original/net/minecraft/world/storage/MapDecoration.java ++++ modified/net/minecraft/world/storage/MapDecoration.java +@@ -67,6 +67,16 @@ + i = 31 * i + this.y; + return 31 * i + this.rotation; + } ++ /** ++ * Renders this decoration, useful for custom sprite sheets. ++ * @param index The index of this icon in the MapData's list. Used by vanilla to offset the Z-coordinate to prevent Z-fighting ++ * @return false to run vanilla logic for this decoration, true to skip it ++ */ ++ @SideOnly(Side.CLIENT) ++ public boolean render(int index) ++ { ++ return false; ++ } + + public enum Type { + PLAYER(false), diff --git a/module/minecraft/patches/net/minecraft/world/storage/SaveFormatOld.java.patch b/module/minecraft/patches/net/minecraft/world/storage/SaveFormatOld.java.patch new file mode 100644 index 000000000..39f6566d9 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/storage/SaveFormatOld.java.patch @@ -0,0 +1,24 @@ +--- original/net/minecraft/world/storage/SaveFormatOld.java ++++ modified/net/minecraft/world/storage/SaveFormatOld.java +@@ -93,7 +93,20 @@ + } + } + +- /** Renames the world by storing the new name in level.dat. It does *not* rename the directory containing the world data. */ ++ //Forge: Special version of the above that runs during actual world loading and not metadata gathering. ++ public static WorldInfo loadAndFix(File file, DataFixer fixer, SaveHandler save) { ++ try { ++ NBTTagCompound nbt = CompressedStreamTools.readCompressed(new FileInputStream(file)); ++ WorldInfo info = new WorldInfo(fixer.process(FixTypes.LEVEL, nbt.getCompoundTag("Data"))); ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().handleWorldDataLoad(save, info, nbt); ++ return info; ++ } catch (net.minecraftforge.fml.common.StartupQuery.AbortedException e) { throw e; } ++ catch (Exception exception) { ++ LOGGER.error((String)("Exception reading " + file), (Throwable)exception); ++ return null; ++ } ++ } ++ + @SideOnly(Side.CLIENT) + @Override + public void renameWorld(String dirName, String newName) { diff --git a/module/minecraft/patches/net/minecraft/world/storage/SaveHandler.java.patch b/module/minecraft/patches/net/minecraft/world/storage/SaveHandler.java.patch new file mode 100644 index 000000000..119c01f87 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/storage/SaveHandler.java.patch @@ -0,0 +1,64 @@ +--- original/net/minecraft/world/storage/SaveHandler.java ++++ modified/net/minecraft/world/storage/SaveHandler.java +@@ -106,14 +106,16 @@ + public WorldInfo loadWorldInfo() { + File file1 = new File(this.worldDirectory, "level.dat"); + if (file1.exists()) { +- WorldInfo worldinfo = SaveFormatOld.getWorldData(file1, this.dataFixer); ++ WorldInfo worldinfo = SaveFormatOld.loadAndFix(file1, this.dataFixer, this); ++ + if (worldinfo != null) { + return worldinfo; + } + } + ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().confirmBackupLevelDatUse(this); + file1 = new File(this.worldDirectory, "level.dat_old"); +- return file1.exists() ? SaveFormatOld.getWorldData(file1, this.dataFixer) : null; ++ return file1.exists() ? SaveFormatOld.loadAndFix(file1, this.dataFixer, this) : null; + } + + /** Saves the given World Info with the given NBTTagCompound as the Player. */ +@@ -123,6 +125,8 @@ + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + nbttagcompound1.setTag("Data", nbttagcompound); + ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().handleWorldDataSave(this, worldInformation, nbttagcompound1); ++ + try { + File file1 = new File(this.worldDirectory, "level.dat_new"); + File file2 = new File(this.worldDirectory, "level.dat_old"); +@@ -165,6 +169,7 @@ + } + + file1.renameTo(file2); ++ net.minecraftforge.event.ForgeEventFactory.firePlayerSavingEvent(player, this.playersDirectory, player.getUniqueID().toString()); + } catch (Exception exception) { + LOGGER.warn("Failed to save player data for {}", player.getName()); + } +@@ -189,6 +194,7 @@ + player.readFromNBT(this.dataFixer.process(FixTypes.PLAYER, nbttagcompound)); + } + ++ net.minecraftforge.event.ForgeEventFactory.firePlayerLoadingEvent(player, playersDirectory, player.getUniqueID().toString()); + return nbttagcompound; + } + +@@ -229,4 +235,17 @@ + public TemplateManager getStructureTemplateManager() { + return this.structureTemplateManager; + } ++ ++ public NBTTagCompound getPlayerNBT(net.minecraft.entity.player.EntityPlayerMP player) { ++ try { ++ File file1 = new File(this.playersDirectory, player.getUniqueID() + ".dat"); ++ ++ if (file1.exists() && file1.isFile()) { ++ return CompressedStreamTools.readCompressed(new FileInputStream(file1)); ++ } ++ } catch (Exception exception) { ++ LOGGER.warn("Failed to load player data for " + player.getName()); ++ } ++ return null; ++ } + } diff --git a/module/minecraft/patches/net/minecraft/world/storage/WorldInfo.java.patch b/module/minecraft/patches/net/minecraft/world/storage/WorldInfo.java.patch new file mode 100644 index 000000000..c2227e168 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/storage/WorldInfo.java.patch @@ -0,0 +1,100 @@ +--- original/net/minecraft/world/storage/WorldInfo.java ++++ modified/net/minecraft/world/storage/WorldInfo.java +@@ -79,13 +79,9 @@ + private double borderDamagePerBlock = 0.2; + private int borderWarningDistance = 5; + private int borderWarningTime = 15; +- /** +- * Mapping providing data between different dimensions. +- * +- * MODDERS: DO NOT USE. This map will have a different type of key depending on whether forge is installed or not. +- */ +- private final Map dimensionData = Maps.newEnumMap(DimensionType.class); ++ private final Map dimensionData = Maps.newHashMap(); + private GameRules gameRules = new GameRules(); ++ private java.util.Map additionalProperties; + + protected WorldInfo() { + } +@@ -227,7 +223,7 @@ + NBTTagCompound nbttagcompound1 = nbt.getCompoundTag("DimensionData"); + + for (String s : nbttagcompound1.getKeySet()) { +- this.dimensionData.put(DimensionType.getById(Integer.parseInt(s)), nbttagcompound1.getCompoundTag(s)); ++ this.dimensionData.put(Integer.parseInt(s), nbttagcompound1.getCompoundTag(s)); + } + } + } +@@ -337,6 +333,8 @@ + nbt.setDouble("BorderSizeLerpTarget", this.borderSizeLerpTarget); + nbt.setDouble("BorderWarningBlocks", this.borderWarningDistance); + nbt.setDouble("BorderWarningTime", this.borderWarningTime); ++ net.minecraftforge.fml.common.FMLCommonHandler.instance().getDataFixer().writeVersionData(nbt); ++ + if (this.difficulty != null) { + nbt.setByte("Difficulty", (byte)this.difficulty.getId()); + } +@@ -345,8 +343,9 @@ + nbt.setTag("GameRules", this.gameRules.writeToNBT()); + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + +- for (Entry entry : this.dimensionData.entrySet()) { +- nbttagcompound1.setTag(String.valueOf(entry.getKey().getId()), entry.getValue()); ++ for (Entry entry : this.dimensionData.entrySet()) { ++ if (entry.getValue() == null || entry.getValue().isEmpty()) continue; ++ nbttagcompound1.setTag(String.valueOf(entry.getKey()), entry.getValue()); + } + + nbt.setTag("DimensionData", nbttagcompound1); +@@ -658,6 +657,7 @@ + } + + public void setDifficulty(EnumDifficulty newDifficulty) { ++ net.minecraftforge.common.ForgeHooks.onDifficultyChange(newDifficulty, this.difficulty); + this.difficulty = newDifficulty; + } + +@@ -757,16 +757,42 @@ + } + ); + } ++ /** ++ * Allow access to additional mod specific world based properties ++ * Used by FML to store mod list associated with a world, and maybe an id map ++ * Used by Forge to store the dimensions available to a world ++ * @param additionalProperties ++ */ ++ public void setAdditionalProperties(java.util.Map additionalProperties) { ++ // one time set for this ++ if (this.additionalProperties == null) { ++ this.additionalProperties = additionalProperties; ++ } ++ } + ++ public net.minecraft.nbt.NBTBase getAdditionalProperty(String additionalProperty) { ++ return this.additionalProperties!=null? this.additionalProperties.get(additionalProperty) : null; ++ } ++ ++ @Deprecated //Use the int version below, and pass in dimension id NOT TYPE id + public NBTTagCompound getDimensionData(DimensionType dimensionIn) { ++ return getDimensionData(dimensionIn.getId()); ++ } ++ public NBTTagCompound getDimensionData(int dimensionIn) { + NBTTagCompound nbttagcompound = this.dimensionData.get(dimensionIn); + return nbttagcompound == null ? new NBTTagCompound() : nbttagcompound; + } + ++ @Deprecated //Use the int version below, and pass in dimension id NOT TYPE id + public void setDimensionData(DimensionType dimensionIn, NBTTagCompound compound) { +- this.dimensionData.put(dimensionIn, compound); ++ this.setDimensionData(dimensionIn.getId(), compound); + } + ++ //Dimension numerical ID version of setter, as two dimensions could in theory have the same DimensionType. ID should be grabbed from the world NOT the Type ++ public void setDimensionData(int dimensionID, NBTTagCompound compound) { ++ this.dimensionData.put(dimensionID, compound); ++ } ++ + @SideOnly(Side.CLIENT) + public int getVersionId() { + return this.versionId; diff --git a/module/minecraft/patches/net/minecraft/world/storage/WorldSavedData.java.patch b/module/minecraft/patches/net/minecraft/world/storage/WorldSavedData.java.patch new file mode 100644 index 000000000..b6a9dc01b --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/storage/WorldSavedData.java.patch @@ -0,0 +1,25 @@ +--- original/net/minecraft/world/storage/WorldSavedData.java ++++ modified/net/minecraft/world/storage/WorldSavedData.java +@@ -2,8 +2,7 @@ + + import net.minecraft.nbt.NBTTagCompound; + +-public abstract class WorldSavedData { +- /** The name of the map data nbt */ ++public abstract class WorldSavedData implements net.minecraftforge.common.util.INBTSerializable { + public final String mapName; + /** Whether this MapDataBase needs saving to disk. */ + private boolean dirty; +@@ -31,4 +30,12 @@ + public boolean isDirty() { + return this.dirty; + } ++ ++ public void deserializeNBT(NBTTagCompound nbt) { ++ this.readFromNBT(nbt); ++ } ++ ++ public NBTTagCompound serializeNBT() { ++ return this.writeToNBT(new NBTTagCompound()); ++ } + } diff --git a/module/minecraft/patches/net/minecraft/world/storage/loot/LootContext.java.patch b/module/minecraft/patches/net/minecraft/world/storage/loot/LootContext.java.patch new file mode 100644 index 000000000..05e6406e9 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/storage/loot/LootContext.java.patch @@ -0,0 +1,17 @@ +--- original/net/minecraft/world/storage/loot/LootContext.java ++++ modified/net/minecraft/world/storage/loot/LootContext.java +@@ -85,6 +85,14 @@ + } + } + ++ public WorldServer getWorld() { ++ return world; ++ } ++ ++ public int getLootingModifier() { ++ return net.minecraftforge.common.ForgeHooks.getLootingLevel(getLootedEntity(), getKiller(), damageSource); ++ } ++ + public static class Builder { + private final WorldServer world; + private float luck; diff --git a/module/minecraft/patches/net/minecraft/world/storage/loot/LootEntry.java.patch b/module/minecraft/patches/net/minecraft/world/storage/loot/LootEntry.java.patch new file mode 100644 index 000000000..e2357b3a8 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/storage/loot/LootEntry.java.patch @@ -0,0 +1,50 @@ +--- original/net/minecraft/world/storage/loot/LootEntry.java ++++ modified/net/minecraft/world/storage/loot/LootEntry.java +@@ -17,14 +17,16 @@ + import net.minecraft.world.storage.loot.conditions.LootCondition; + + public abstract class LootEntry { ++ protected final String entryName; + protected final int weight; + protected final int quality; + protected final LootCondition[] conditions; + +- protected LootEntry(int weightIn, int qualityIn, LootCondition[] conditionsIn) { ++ protected LootEntry(int weightIn, int qualityIn, LootCondition[] conditionsIn, String entryName) { + this.weight = weightIn; + this.quality = qualityIn; + this.conditions = conditionsIn; ++ this.entryName = entryName; + } + + /** Gets the effective weight based on the loot entry's weight and quality multiplied by looter's luck. */ +@@ -32,6 +34,8 @@ + return Math.max(MathHelper.floor(this.weight + this.quality * luck), 0); + } + ++ public String getEntryName(){ return this.entryName; } ++ + public abstract void addLoot(Collection var1, Random var2, LootContext var3); + + protected abstract void serialize(JsonObject var1, JsonSerializationContext var2); +@@ -59,15 +63,19 @@ + throw new JsonSyntaxException("Unknown loot entry type '" + s + "'"); + } + } +- + public JsonElement serialize(LootEntry p_serialize_1_, Type p_serialize_2_, JsonSerializationContext p_serialize_3_) { + JsonObject jsonobject = new JsonObject(); ++ if (p_serialize_1_.entryName != null && !p_serialize_1_.entryName.startsWith("custom#")) ++ jsonobject.addProperty("entryName", p_serialize_1_.entryName); + jsonobject.addProperty("weight", p_serialize_1_.weight); + jsonobject.addProperty("quality", p_serialize_1_.quality); + if (p_serialize_1_.conditions.length > 0) { + jsonobject.add("conditions", p_serialize_3_.serialize(p_serialize_1_.conditions)); + } + ++ String type = net.minecraftforge.common.ForgeHooks.getLootEntryType(p_serialize_1_); ++ if (type != null) jsonobject.addProperty("type", type); ++ else + if (p_serialize_1_ instanceof LootEntryItem) { + jsonobject.addProperty("type", "item"); + } else if (p_serialize_1_ instanceof LootEntryTable) { diff --git a/module/minecraft/patches/net/minecraft/world/storage/loot/LootEntryEmpty.java.patch b/module/minecraft/patches/net/minecraft/world/storage/loot/LootEntryEmpty.java.patch new file mode 100644 index 000000000..70d535e56 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/storage/loot/LootEntryEmpty.java.patch @@ -0,0 +1,25 @@ +--- original/net/minecraft/world/storage/loot/LootEntryEmpty.java ++++ modified/net/minecraft/world/storage/loot/LootEntryEmpty.java +@@ -9,8 +9,8 @@ + import net.minecraft.world.storage.loot.conditions.LootCondition; + + public class LootEntryEmpty extends LootEntry { +- public LootEntryEmpty(int weightIn, int qualityIn, LootCondition[] conditionsIn) { +- super(weightIn, qualityIn, conditionsIn); ++ public LootEntryEmpty(int weightIn, int qualityIn, LootCondition[] conditionsIn, String entryName) { ++ super(weightIn, qualityIn, conditionsIn, entryName); + } + + @Override +@@ -22,8 +22,8 @@ + } + + public static LootEntryEmpty deserialize( +- JsonObject object, JsonDeserializationContext deserializationContext, int weightIn, int qualityIn, LootCondition[] conditionsIn +- ) { +- return new LootEntryEmpty(weightIn, qualityIn, conditionsIn); ++ JsonObject object, JsonDeserializationContext deserializationContext, int weightIn, int qualityIn, LootCondition[] conditionsIn ++ ) { ++ return new LootEntryEmpty(weightIn, qualityIn, conditionsIn, net.minecraftforge.common.ForgeHooks.readLootEntryName(object, "empty")); + } + } diff --git a/module/minecraft/patches/net/minecraft/world/storage/loot/LootEntryItem.java.patch b/module/minecraft/patches/net/minecraft/world/storage/loot/LootEntryItem.java.patch new file mode 100644 index 000000000..0af340b80 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/storage/loot/LootEntryItem.java.patch @@ -0,0 +1,42 @@ +--- original/net/minecraft/world/storage/loot/LootEntryItem.java ++++ modified/net/minecraft/world/storage/loot/LootEntryItem.java +@@ -17,8 +17,8 @@ + protected final Item item; + protected final LootFunction[] functions; + +- public LootEntryItem(Item itemIn, int weightIn, int qualityIn, LootFunction[] functionsIn, LootCondition[] conditionsIn) { +- super(weightIn, qualityIn, conditionsIn); ++ public LootEntryItem(Item itemIn, int weightIn, int qualityIn, LootFunction[] functionsIn, LootCondition[] conditionsIn, String entryName) { ++ super(weightIn, qualityIn, conditionsIn, entryName); + this.item = itemIn; + this.functions = functionsIn; + } +@@ -34,7 +34,7 @@ + } + + if (!itemstack.isEmpty()) { +- if (itemstack.getCount() < this.item.getItemStackLimit()) { ++ if (itemstack.getCount() < this.item.getItemStackLimit(itemstack)) { + stacks.add(itemstack); + } else { + int i = itemstack.getCount(); +@@ -64,8 +64,9 @@ + } + + public static LootEntryItem deserialize( +- JsonObject object, JsonDeserializationContext deserializationContext, int weightIn, int qualityIn, LootCondition[] conditionsIn +- ) { ++ JsonObject object, JsonDeserializationContext deserializationContext, int weightIn, int qualityIn, LootCondition[] conditionsIn ++ ) { ++ String name = net.minecraftforge.common.ForgeHooks.readLootEntryName(object, "item"); + Item item = JsonUtils.getItem(object, "name"); + LootFunction[] alootfunction; + if (object.has("functions")) { +@@ -74,6 +75,6 @@ + alootfunction = new LootFunction[0]; + } + +- return new LootEntryItem(item, weightIn, qualityIn, alootfunction, conditionsIn); ++ return new LootEntryItem(item, weightIn, qualityIn, alootfunction, conditionsIn, name); + } + } diff --git a/module/minecraft/patches/net/minecraft/world/storage/loot/LootEntryTable.java.patch b/module/minecraft/patches/net/minecraft/world/storage/loot/LootEntryTable.java.patch new file mode 100644 index 000000000..8bed9785c --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/storage/loot/LootEntryTable.java.patch @@ -0,0 +1,27 @@ +--- original/net/minecraft/world/storage/loot/LootEntryTable.java ++++ modified/net/minecraft/world/storage/loot/LootEntryTable.java +@@ -13,8 +13,8 @@ + public class LootEntryTable extends LootEntry { + protected final ResourceLocation table; + +- public LootEntryTable(ResourceLocation tableIn, int weightIn, int qualityIn, LootCondition[] conditionsIn) { +- super(weightIn, qualityIn, conditionsIn); ++ public LootEntryTable(ResourceLocation tableIn, int weightIn, int qualityIn, LootCondition[] conditionsIn, String entryName) { ++ super(weightIn, qualityIn, conditionsIn, entryName); + this.table = tableIn; + } + +@@ -31,9 +31,10 @@ + } + + public static LootEntryTable deserialize( +- JsonObject object, JsonDeserializationContext deserializationContext, int weightIn, int qualityIn, LootCondition[] conditionsIn +- ) { ++ JsonObject object, JsonDeserializationContext deserializationContext, int weightIn, int qualityIn, LootCondition[] conditionsIn ++ ) { ++ String name = net.minecraftforge.common.ForgeHooks.readLootEntryName(object, "loot_table"); + ResourceLocation resourcelocation = new ResourceLocation(JsonUtils.getString(object, "name")); +- return new LootEntryTable(resourcelocation, weightIn, qualityIn, conditionsIn); ++ return new LootEntryTable(resourcelocation, weightIn, qualityIn, conditionsIn, name); + } + } diff --git a/module/minecraft/patches/net/minecraft/world/storage/loot/LootPool.java.patch b/module/minecraft/patches/net/minecraft/world/storage/loot/LootPool.java.patch new file mode 100644 index 000000000..6f427e61d --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/storage/loot/LootPool.java.patch @@ -0,0 +1,97 @@ +--- original/net/minecraft/world/storage/loot/LootPool.java ++++ modified/net/minecraft/world/storage/loot/LootPool.java +@@ -20,16 +20,18 @@ + import org.apache.commons.lang3.ArrayUtils; + + public class LootPool { +- private final LootEntry[] lootEntries; +- private final LootCondition[] poolConditions; ++ private final List lootEntries; ++ private final List poolConditions; + private RandomValueRange rolls; + private RandomValueRange bonusRolls; ++ private final String name; + +- public LootPool(LootEntry[] lootEntriesIn, LootCondition[] poolConditionsIn, RandomValueRange rollsIn, RandomValueRange bonusRollsIn) { +- this.lootEntries = lootEntriesIn; +- this.poolConditions = poolConditionsIn; ++ public LootPool(LootEntry[] lootEntriesIn, LootCondition[] poolConditionsIn, RandomValueRange rollsIn, RandomValueRange bonusRollsIn, String name) { ++ this.lootEntries = Lists.newArrayList(lootEntriesIn); ++ this.poolConditions = Lists.newArrayList(poolConditionsIn); + this.rolls = rollsIn; + this.bonusRolls = bonusRollsIn; ++ this.name = name; + } + + /** +@@ -77,16 +79,60 @@ + } + } + ++ //======================== FORGE START ============================================= ++ private boolean isFrozen = false; ++ public void freeze() { ++ this.isFrozen = true; ++ } ++ public boolean isFrozen(){ return this.isFrozen; } ++ private void checkFrozen() { ++ if (this.isFrozen()) ++ throw new RuntimeException("Attempted to modify LootPool after being frozen!"); ++ } ++ ++ public String getName(){ return this.name; } ++ public RandomValueRange getRolls() { return this.rolls; } ++ public RandomValueRange getBonusRolls() { return this.bonusRolls; } ++ public void setRolls (RandomValueRange v){ checkFrozen(); this.rolls = v; } ++ public void setBonusRolls(RandomValueRange v){ checkFrozen(); this.bonusRolls = v; } ++ ++ public LootEntry getEntry(String name) { ++ for (LootEntry entry : this.lootEntries) ++ if (name.equals(entry.getEntryName())) ++ return entry; ++ return null; ++ } ++ public LootEntry removeEntry(String name) { ++ checkFrozen(); ++ for (LootEntry entry : this.lootEntries) { ++ if (name.equals(entry.getEntryName())) { ++ this.lootEntries.remove(entry); ++ return entry; ++ } ++ } ++ return null; ++ } ++ public void addEntry(LootEntry entry) { ++ checkFrozen(); ++ for (LootEntry e : this.lootEntries) ++ if (e == entry || e.getEntryName().equals(entry.getEntryName())) ++ throw new RuntimeException("Attempted to add a duplicate entry to pool: " + e.getEntryName()); ++ this.lootEntries.add(entry); ++ } ++ //TODO: Allow modifications of conditions? If so need a way to uniquely identify them. ++ //======================== FORGE END =============================================== ++ + public static class Serializer implements JsonDeserializer, JsonSerializer { + public LootPool deserialize(JsonElement p_deserialize_1_, Type p_deserialize_2_, JsonDeserializationContext p_deserialize_3_) throws JsonParseException { + JsonObject jsonobject = JsonUtils.getJsonObject(p_deserialize_1_, "loot pool"); ++ String name = net.minecraftforge.common.ForgeHooks.readPoolName(jsonobject); + LootEntry[] alootentry = JsonUtils.deserializeClass(jsonobject, "entries", p_deserialize_3_, LootEntry[].class); + LootCondition[] alootcondition = JsonUtils.deserializeClass(jsonobject, "conditions", new LootCondition[0], p_deserialize_3_, LootCondition[].class); + RandomValueRange randomvaluerange = JsonUtils.deserializeClass(jsonobject, "rolls", p_deserialize_3_, RandomValueRange.class); + RandomValueRange randomvaluerange1 = JsonUtils.deserializeClass( + jsonobject, "bonus_rolls", new RandomValueRange(0.0F, 0.0F), p_deserialize_3_, RandomValueRange.class + ); +- return new LootPool(alootentry, alootcondition, randomvaluerange, randomvaluerange1); ++ return new LootPool(alootentry, alootcondition, randomvaluerange, randomvaluerange1, name); + } + + public JsonElement serialize(LootPool p_serialize_1_, Type p_serialize_2_, JsonSerializationContext p_serialize_3_) { +@@ -97,7 +143,7 @@ + jsonobject.add("bonus_rolls", p_serialize_3_.serialize(p_serialize_1_.bonusRolls)); + } + +- if (!ArrayUtils.isEmpty(p_serialize_1_.poolConditions)) { ++ if (!p_serialize_1_.poolConditions.isEmpty()) { + jsonobject.add("conditions", p_serialize_3_.serialize(p_serialize_1_.poolConditions)); + } + diff --git a/module/minecraft/patches/net/minecraft/world/storage/loot/LootTable.java.patch b/module/minecraft/patches/net/minecraft/world/storage/loot/LootTable.java.patch new file mode 100644 index 000000000..a344bb221 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/storage/loot/LootTable.java.patch @@ -0,0 +1,65 @@ +--- original/net/minecraft/world/storage/loot/LootTable.java ++++ modified/net/minecraft/world/storage/loot/LootTable.java +@@ -23,10 +23,10 @@ + public class LootTable { + private static final Logger LOGGER = LogManager.getLogger(); + public static final LootTable EMPTY_LOOT_TABLE = new LootTable(new LootPool[0]); +- private final LootPool[] pools; ++ private final List pools; + + public LootTable(LootPool[] poolsIn) { +- this.pools = poolsIn; ++ this.pools = Lists.newArrayList(poolsIn); + } + + /** returns a list of loot generated from a bunch of pools */ +@@ -115,6 +115,49 @@ + return list; + } + ++ //======================== FORGE START ============================================= ++ private boolean isFrozen = false; ++ public void freeze() { ++ this.isFrozen = true; ++ for (LootPool pool : this.pools) ++ pool.freeze(); ++ } ++ public boolean isFrozen(){ return this.isFrozen; } ++ private void checkFrozen() { ++ if (this.isFrozen()) ++ throw new RuntimeException("Attempted to modify LootTable after being finalized!"); ++ } ++ ++ public LootPool getPool(String name) { ++ for (LootPool pool : this.pools) { ++ if (name.equals(pool.getName())) ++ return pool; ++ } ++ return null; ++ } ++ ++ public LootPool removePool(String name) { ++ checkFrozen(); ++ for (LootPool pool : this.pools) { ++ if (name.equals(pool.getName())) { ++ this.pools.remove(pool); ++ return pool; ++ } ++ } ++ ++ return null; ++ } ++ ++ public void addPool(LootPool pool) { ++ checkFrozen(); ++ for (LootPool p : this.pools) { ++ if (p == pool || p.getName().equals(pool.getName())) ++ throw new RuntimeException("Attempted to add a duplicate pool to loot table: " + pool.getName()); ++ } ++ this.pools.add(pool); ++ } ++ //======================== FORGE END =============================================== ++ + public static class Serializer implements JsonDeserializer, JsonSerializer { + public LootTable deserialize(JsonElement p_deserialize_1_, Type p_deserialize_2_, JsonDeserializationContext p_deserialize_3_) throws JsonParseException { + JsonObject jsonobject = JsonUtils.getJsonObject(p_deserialize_1_, "loot table"); diff --git a/module/minecraft/patches/net/minecraft/world/storage/loot/LootTableManager.java.patch b/module/minecraft/patches/net/minecraft/world/storage/loot/LootTableManager.java.patch new file mode 100644 index 000000000..631b30047 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/storage/loot/LootTableManager.java.patch @@ -0,0 +1,20 @@ +--- original/net/minecraft/world/storage/loot/LootTableManager.java ++++ modified/net/minecraft/world/storage/loot/LootTableManager.java +@@ -94,7 +94,7 @@ + } + + try { +- return JsonUtils.gsonDeserialize(LootTableManager.GSON_INSTANCE, s, LootTable.class); ++ return net.minecraftforge.common.ForgeHooks.loadLootTable(LootTableManager.GSON_INSTANCE, resource, s, true, LootTableManager.this); + } catch (JsonParseException | IllegalArgumentException runtimeexception) { + LootTableManager.LOGGER.error("Couldn't load loot table {} from {}", resource, file1, runtimeexception); + return LootTable.EMPTY_LOOT_TABLE; +@@ -121,7 +121,7 @@ + } + + try { +- return JsonUtils.gsonDeserialize(LootTableManager.GSON_INSTANCE, s, LootTable.class); ++ return net.minecraftforge.common.ForgeHooks.loadLootTable(LootTableManager.GSON_INSTANCE, resource, s, false, LootTableManager.this); + } catch (JsonParseException jsonparseexception) { + LootTableManager.LOGGER.error("Couldn't load loot table {} from {}", resource, url, jsonparseexception); + return LootTable.EMPTY_LOOT_TABLE; diff --git a/module/minecraft/patches/net/minecraft/world/storage/loot/conditions/LootConditionManager.java.patch b/module/minecraft/patches/net/minecraft/world/storage/loot/conditions/LootConditionManager.java.patch new file mode 100644 index 000000000..5e5bf7b1c --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/storage/loot/conditions/LootConditionManager.java.patch @@ -0,0 +1,17 @@ +--- original/net/minecraft/world/storage/loot/conditions/LootConditionManager.java ++++ modified/net/minecraft/world/storage/loot/conditions/LootConditionManager.java +@@ -36,6 +36,14 @@ + CLASS_TO_SERIALIZER_MAP.put(oclass, condition); + } + ++ public static boolean testAllConditions(Iterable conditions, Random rand, LootContext context) { ++ if (conditions == null) return true; ++ for (LootCondition cond : conditions) ++ if (!cond.testCondition(rand, context)) ++ return false; ++ return true; ++ } ++ + public static boolean testAllConditions(@Nullable LootCondition[] conditions, Random rand, LootContext context) { + if (conditions == null) { + return true; diff --git a/module/minecraft/patches/net/minecraft/world/storage/loot/conditions/RandomChanceWithLooting.java.patch b/module/minecraft/patches/net/minecraft/world/storage/loot/conditions/RandomChanceWithLooting.java.patch new file mode 100644 index 000000000..c93eff90a --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/storage/loot/conditions/RandomChanceWithLooting.java.patch @@ -0,0 +1,14 @@ +--- original/net/minecraft/world/storage/loot/conditions/RandomChanceWithLooting.java ++++ modified/net/minecraft/world/storage/loot/conditions/RandomChanceWithLooting.java +@@ -21,10 +21,7 @@ + + @Override + public boolean testCondition(Random rand, LootContext context) { +- int i = 0; +- if (context.getKiller() instanceof EntityLivingBase) { +- i = EnchantmentHelper.getLootingModifier((EntityLivingBase)context.getKiller()); +- } ++ int i = context.getLootingModifier(); + + return rand.nextFloat() < this.chance + i * this.lootingMultiplier; + } diff --git a/module/minecraft/patches/net/minecraft/world/storage/loot/functions/LootingEnchantBonus.java.patch b/module/minecraft/patches/net/minecraft/world/storage/loot/functions/LootingEnchantBonus.java.patch new file mode 100644 index 000000000..1e0faf2a9 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/world/storage/loot/functions/LootingEnchantBonus.java.patch @@ -0,0 +1,12 @@ +--- original/net/minecraft/world/storage/loot/functions/LootingEnchantBonus.java ++++ modified/net/minecraft/world/storage/loot/functions/LootingEnchantBonus.java +@@ -28,7 +28,8 @@ + public ItemStack apply(ItemStack stack, Random rand, LootContext context) { + Entity entity = context.getKiller(); + if (entity instanceof EntityLivingBase) { +- int i = EnchantmentHelper.getLootingModifier((EntityLivingBase)entity); ++ int i = context.getLootingModifier(); ++ + if (i == 0) { + return stack; + } From b0a3b36439f3963f7ad2fe091e5ef660367cf87f Mon Sep 17 00:00:00 2001 From: Rongmario Date: Thu, 13 Aug 2026 22:10:40 +0100 Subject: [PATCH 26/99] Get started with the SDL ecosystem --- .../com/cleanroommc/client/input/SDL.java | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/input/SDL.java diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/input/SDL.java b/module/cleanroom/src/main/java/com/cleanroommc/client/input/SDL.java new file mode 100644 index 000000000..e6f96d708 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/input/SDL.java @@ -0,0 +1,88 @@ +package com.cleanroommc.client.input; + +import org.lwjgl.sdl.SDLError; +import org.lwjgl.sdl.SDLInit; + +/** + * SDL's lifecycle helpers. + */ +public final class SDL { + + private static int initializedBits; + + /** + * Brings up the video and event subsystems, if they are not already up. + */ + public static void ensureVideo() { + ensureSubsystem(SDLInit.SDL_INIT_VIDEO | SDLInit.SDL_INIT_EVENTS); + } + + /** + * Initializes whichever SDL {@code flags} is passed through the argument. + * + *

SDL delivers nothing for a subsystem that was never initialized. + * + * @param flags one or more {@code SDL_INIT_*} bits + */ + public static synchronized void ensureSubsystem(int flags) { + int missing = flags & ~initializedBits; + if (missing == 0) { + return; + } + check(SDLInit.SDL_InitSubSystem(missing), "SDL_InitSubSystem"); + initializedBits |= missing; + } + + /** + * @param flags one or more {@code SDL_INIT_*} bits + * @return whether every one of them is up + */ + public static synchronized boolean isInitialized(int flags) { + return (initializedBits & flags) == flags; + } + + /** Tears down every subsystem this class brought up, and clears {@link Inputs}' listeners. */ + public static synchronized void shutdown() { + if (initializedBits == 0) { + return; + } + // Inputs.reset(); + SDLInit.SDL_Quit(); + initializedBits = 0; + } + + /** + * @param result the {@code boolean} an SDL call returned + * @param call the call's name, for the message + * @throws SDLException if the call failed + */ + public static void check(boolean result, String call) { + if (!result) { + throw new SDLException(call + " failed: " + SDLError.SDL_GetError()); + } + } + + /** + * @param handle a pointer an SDL call returned + * @param call the call's name, for the message + * @return {@code handle} + * @throws SDLException if the call returned null + */ + public static long checkHandle(long handle, String call) { + if (handle == 0L) { + throw new SDLException(call + " failed: " + SDLError.SDL_GetError()); + } + return handle; + } + + private SDL() { } + + public static final class SDLException extends RuntimeException { + + SDLException(String message) { + super(message); + } + + } + +} From ba72773e465a9c29399907391fb61450f587cf7c Mon Sep 17 00:00:00 2001 From: Rongmario Date: Fri, 14 Aug 2026 14:31:45 +0100 Subject: [PATCH 27/99] Fix some vanilla/Forge methods to match new LWJGL 3 names --- .../client/ForgeHooksClient.java | 2 +- .../client/renderer/GlStateManager.java.patch | 70 ++++++++++ .../client/renderer/OpenGlHelper.java.patch | 132 +++++++++++++++++- 3 files changed, 202 insertions(+), 2 deletions(-) create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/GlStateManager.java.patch diff --git a/module/forge/src/main/java/net/minecraftforge/client/ForgeHooksClient.java b/module/forge/src/main/java/net/minecraftforge/client/ForgeHooksClient.java index 53d844edb..8114e94db 100644 --- a/module/forge/src/main/java/net/minecraftforge/client/ForgeHooksClient.java +++ b/module/forge/src/main/java/net/minecraftforge/client/ForgeHooksClient.java @@ -454,7 +454,7 @@ public static void multiplyCurrentGlMatrix(Matrix4f matrix) matrixBuf.put(t); } matrixBuf.flip(); - GL11.glMultMatrix(matrixBuf); + GL11.glMultMatrixf(matrixBuf); } // moved and expanded from WorldVertexBufferUploader.draw diff --git a/module/minecraft/patches/net/minecraft/client/renderer/GlStateManager.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/GlStateManager.java.patch new file mode 100644 index 000000000..f800af19d --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/GlStateManager.java.patch @@ -0,0 +1,70 @@ +--- original/net/minecraft/client/renderer/GlStateManager.java ++++ modified/net/minecraft/client/renderer/GlStateManager.java +@@ -97,11 +97,11 @@ + } + + public static void glLight(int light, int pname, FloatBuffer params) { +- GL11.glLight(light, pname, params); ++ GL11.glLightfv(light, pname, params); + } + + public static void glLightModel(int pname, FloatBuffer params) { +- GL11.glLightModel(pname, params); ++ GL11.glLightModelfv(pname, params); + } + + public static void glNormal3f(float nx, float ny, float nz) { +@@ -242,7 +242,7 @@ + } + + public static void glFog(int pname, FloatBuffer param) { +- GL11.glFog(pname, param); ++ GL11.glFogfv(pname, param); + } + + public static void glFogi(int pname, int param) { +@@ -324,7 +324,7 @@ + } + + public static void texGen(GlStateManager.TexGen texGen, int pname, FloatBuffer params) { +- GL11.glTexGen(texGenCoord(texGen).coord, pname, params); ++ GL11.glTexGenfv(texGenCoord(texGen).coord, pname, params); + } + + private static GlStateManager.TexGenCoord texGenCoord(GlStateManager.TexGen texGen) { +@@ -358,7 +358,7 @@ + } + + public static void glTexEnv(int target, int parameterName, FloatBuffer parameters) { +- GL11.glTexEnv(target, parameterName, parameters); ++ GL11.glTexEnvfv(target, parameterName, parameters); + } + + public static void glTexEnvi(int target, int parameterName, int parameter) { +@@ -521,7 +521,7 @@ + } + + public static void getFloat(int pname, FloatBuffer params) { +- GL11.glGetFloat(pname, params); ++ GL11.glGetFloatv(pname, params); + } + + public static void ortho(double left, double right, double bottom, double top, double zNear, double zFar) { +@@ -549,7 +549,7 @@ + } + + public static void multMatrix(FloatBuffer matrix) { +- GL11.glMultMatrix(matrix); ++ GL11.glMultMatrixf(matrix); + } + + public static void rotate(Quaternion quaternionIn) { +@@ -710,7 +710,7 @@ + } + + public static void glGetInteger(int parameterName, IntBuffer parameters) { +- GL11.glGetInteger(parameterName, parameters); ++ GL11.glGetIntegerv(parameterName, parameters); + } + + public static int glGetInteger(int parameterName) { diff --git a/module/minecraft/patches/net/minecraft/client/renderer/OpenGlHelper.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/OpenGlHelper.java.patch index c84a2b199..88a3406a3 100644 --- a/module/minecraft/patches/net/minecraft/client/renderer/OpenGlHelper.java.patch +++ b/module/minecraft/patches/net/minecraft/client/renderer/OpenGlHelper.java.patch @@ -34,7 +34,137 @@ } catch (Throwable throwable) { } } -@@ -676,6 +679,11 @@ +@@ -303,10 +306,13 @@ + } + + public static void glShaderSource(int shaderIn, ByteBuffer string) { ++ // LWJGL 2 took the source as raw bytes; LWJGL 3 takes a CharSequence. Decoded through a ++ // duplicate so the caller's buffer keeps its position -- LWJGL 2 did not consume it either. ++ CharSequence source = java.nio.charset.StandardCharsets.UTF_8.decode(string.duplicate()); + if (arbShaders) { +- ARBShaderObjects.glShaderSourceARB(shaderIn, string); ++ ARBShaderObjects.glShaderSourceARB(shaderIn, source); + } else { +- GL20.glShaderSource(shaderIn, string); ++ GL20.glShaderSource(shaderIn, source); + } + } + +@@ -364,9 +370,9 @@ + + public static void glUniform1(int location, IntBuffer values) { + if (arbShaders) { +- ARBShaderObjects.glUniform1ARB(location, values); ++ ARBShaderObjects.glUniform1ivARB(location, values); + } else { +- GL20.glUniform1(location, values); ++ GL20.glUniform1iv(location, values); + } + } + +@@ -380,81 +386,81 @@ + + public static void glUniform1(int location, FloatBuffer values) { + if (arbShaders) { +- ARBShaderObjects.glUniform1ARB(location, values); ++ ARBShaderObjects.glUniform1fvARB(location, values); + } else { +- GL20.glUniform1(location, values); ++ GL20.glUniform1fv(location, values); + } + } + + public static void glUniform2(int location, IntBuffer values) { + if (arbShaders) { +- ARBShaderObjects.glUniform2ARB(location, values); ++ ARBShaderObjects.glUniform2ivARB(location, values); + } else { +- GL20.glUniform2(location, values); ++ GL20.glUniform2iv(location, values); + } + } + + public static void glUniform2(int location, FloatBuffer values) { + if (arbShaders) { +- ARBShaderObjects.glUniform2ARB(location, values); ++ ARBShaderObjects.glUniform2fvARB(location, values); + } else { +- GL20.glUniform2(location, values); ++ GL20.glUniform2fv(location, values); + } + } + + public static void glUniform3(int location, IntBuffer values) { + if (arbShaders) { +- ARBShaderObjects.glUniform3ARB(location, values); ++ ARBShaderObjects.glUniform3ivARB(location, values); + } else { +- GL20.glUniform3(location, values); ++ GL20.glUniform3iv(location, values); + } + } + + public static void glUniform3(int location, FloatBuffer values) { + if (arbShaders) { +- ARBShaderObjects.glUniform3ARB(location, values); ++ ARBShaderObjects.glUniform3fvARB(location, values); + } else { +- GL20.glUniform3(location, values); ++ GL20.glUniform3fv(location, values); + } + } + + public static void glUniform4(int location, IntBuffer values) { + if (arbShaders) { +- ARBShaderObjects.glUniform4ARB(location, values); ++ ARBShaderObjects.glUniform4ivARB(location, values); + } else { +- GL20.glUniform4(location, values); ++ GL20.glUniform4iv(location, values); + } + } + + public static void glUniform4(int location, FloatBuffer values) { + if (arbShaders) { +- ARBShaderObjects.glUniform4ARB(location, values); ++ ARBShaderObjects.glUniform4fvARB(location, values); + } else { +- GL20.glUniform4(location, values); ++ GL20.glUniform4fv(location, values); + } + } + + public static void glUniformMatrix2(int location, boolean transpose, FloatBuffer matrices) { + if (arbShaders) { +- ARBShaderObjects.glUniformMatrix2ARB(location, transpose, matrices); ++ ARBShaderObjects.glUniformMatrix2fvARB(location, transpose, matrices); + } else { +- GL20.glUniformMatrix2(location, transpose, matrices); ++ GL20.glUniformMatrix2fv(location, transpose, matrices); + } + } + + public static void glUniformMatrix3(int location, boolean transpose, FloatBuffer matrices) { + if (arbShaders) { +- ARBShaderObjects.glUniformMatrix3ARB(location, transpose, matrices); ++ ARBShaderObjects.glUniformMatrix3fvARB(location, transpose, matrices); + } else { +- GL20.glUniformMatrix3(location, transpose, matrices); ++ GL20.glUniformMatrix3fv(location, transpose, matrices); + } + } + + public static void glUniformMatrix4(int location, boolean transpose, FloatBuffer matrices) { + if (arbShaders) { +- ARBShaderObjects.glUniformMatrix4ARB(location, transpose, matrices); ++ ARBShaderObjects.glUniformMatrix4fvARB(location, transpose, matrices); + } else { +- GL20.glUniformMatrix4(location, transpose, matrices); ++ GL20.glUniformMatrix4fv(location, transpose, matrices); + } + } + +@@ -676,6 +682,11 @@ } else { GL13.glMultiTexCoord2f(target, x, y); } From c944066fad96404a137725f08768845371e6e092 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Fri, 14 Aug 2026 14:34:01 +0100 Subject: [PATCH 28/99] Remove comments to minimize OpenGlHelper.java.patch --- .../minecraft/client/renderer/OpenGlHelper.java.patch | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/module/minecraft/patches/net/minecraft/client/renderer/OpenGlHelper.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/OpenGlHelper.java.patch index 88a3406a3..1c7d2c0b0 100644 --- a/module/minecraft/patches/net/minecraft/client/renderer/OpenGlHelper.java.patch +++ b/module/minecraft/patches/net/minecraft/client/renderer/OpenGlHelper.java.patch @@ -34,12 +34,10 @@ } catch (Throwable throwable) { } } -@@ -303,10 +306,13 @@ +@@ -303,10 +306,11 @@ } public static void glShaderSource(int shaderIn, ByteBuffer string) { -+ // LWJGL 2 took the source as raw bytes; LWJGL 3 takes a CharSequence. Decoded through a -+ // duplicate so the caller's buffer keeps its position -- LWJGL 2 did not consume it either. + CharSequence source = java.nio.charset.StandardCharsets.UTF_8.decode(string.duplicate()); if (arbShaders) { - ARBShaderObjects.glShaderSourceARB(shaderIn, string); @@ -50,7 +48,7 @@ } } -@@ -364,9 +370,9 @@ +@@ -364,9 +368,9 @@ public static void glUniform1(int location, IntBuffer values) { if (arbShaders) { @@ -62,7 +60,7 @@ } } -@@ -380,81 +386,81 @@ +@@ -380,81 +384,81 @@ public static void glUniform1(int location, FloatBuffer values) { if (arbShaders) { @@ -164,7 +162,7 @@ } } -@@ -676,6 +682,11 @@ +@@ -676,6 +680,11 @@ } else { GL13.glMultiTexCoord2f(target, x, y); } From 82a2490566bab7b1b47feac2dd2df7071db22808 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Fri, 14 Aug 2026 15:58:59 +0100 Subject: [PATCH 29/99] Add lwjgl-freetype --- build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle b/build.gradle index 57ac27613..7f5a2da7e 100644 --- a/build.gradle +++ b/build.gradle @@ -184,6 +184,7 @@ dependencies { // Kirino api 'org.joml:joml:1.10.9' api 'io.github.classgraph:classgraph:4.8.184' + api 'org.lwjgl:lwjgl-freetype' lwjglNative 'org.lwjgl:lwjgl-freetype' // Test From d8de626c23639c20e535d76dc0cd47e232024f53 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Fri, 14 Aug 2026 18:37:06 +0100 Subject: [PATCH 30/99] Temp exclude kirino classes that depend on local artifacts --- build.gradle | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build.gradle b/build.gradle index 7f5a2da7e..c2c4d0498 100644 --- a/build.gradle +++ b/build.gradle @@ -38,10 +38,14 @@ def modules = [ sourceSets { main { java.srcDirs = modules.collect { "module/${it}/src/main/java" } + 'module/minecraft/injected/java' + // Fixme: Temp + java.exclude 'com/cleanroommc/kirino/utils/KsmlcUtils.java' resources.srcDirs = modules.collect { "module/${it}/src/main/resources" } } test { java.srcDirs = modules.collect { "module/${it}/src/test/java" } + // Fixme: Temp + java.exclude 'com/cleanroommc/test/kirino/gl/ksml/**' resources.srcDirs = modules.collect { "module/${it}/src/test/resources" } } } From 3658721f17fb240fc608fee462223d1c136ad3a2 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Fri, 14 Aug 2026 18:40:34 +0100 Subject: [PATCH 31/99] Remove previous IME hacks --- .../com/cleanroommc/client/IMEHandler.java | 30 ------------ .../client/ime/DummyIMEHandler.java | 10 ---- .../client/ime/WaylandIMEhandler.java | 14 ------ .../client/ime/WindowsIMEHandler.java | 46 ------------------- .../cleanroommc/client/ime/X11IMEHandler.java | 14 ------ .../com/cleanroommc/client/input/SDL.java | 4 +- .../client/ForgeClientHandler.java | 25 +++------- .../common/ForgeModContainer.java | 14 ------ .../resources/assets/forge/lang/en_us.lang | 2 - .../resources/assets/forge/lang/zh_cn.lang | 4 +- .../minecraft/client/gui/GuiSlot.java.patch | 23 +++++++++- .../client/gui/GuiTextField.java.patch | 23 ++++++---- 12 files changed, 46 insertions(+), 163 deletions(-) delete mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/IMEHandler.java delete mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/ime/DummyIMEHandler.java delete mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/ime/WaylandIMEhandler.java delete mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/ime/WindowsIMEHandler.java delete mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/ime/X11IMEHandler.java diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/IMEHandler.java b/module/cleanroom/src/main/java/com/cleanroommc/client/IMEHandler.java deleted file mode 100644 index d3dca95d2..000000000 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/IMEHandler.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.cleanroommc.client; - -import com.cleanroommc.client.ime.*; -import net.minecraftforge.common.ForgeModContainer; -import net.minecraftforge.fml.common.FMLLog; -import org.lwjgl.glfw.GLFW; - -import java.util.function.Consumer; - -public class IMEHandler { - private static final Consumer instance; - static { - if (ForgeModContainer.inputMethodBlockingEnabled) { - switch (GLFW.glfwGetPlatform()) { - case GLFW.GLFW_PLATFORM_WIN32 -> instance = new WindowsIMEHandler(); - case GLFW.GLFW_PLATFORM_X11 -> instance = new X11IMEHandler(); - case GLFW.GLFW_PLATFORM_WAYLAND -> instance = new WaylandIMEhandler(); - default -> { - instance = new DummyIMEHandler(); - FMLLog.log.warn("IME handler initialization failed: Unsupported platform {}", GLFW.glfwGetPlatform()); - } - } - } else { - instance = new DummyIMEHandler(); - } - } - public static void setIME(boolean active) { - instance.accept(active); - } -} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/ime/DummyIMEHandler.java b/module/cleanroom/src/main/java/com/cleanroommc/client/ime/DummyIMEHandler.java deleted file mode 100644 index fcefe048e..000000000 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/ime/DummyIMEHandler.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.cleanroommc.client.ime; - -import java.util.function.Consumer; - -public class DummyIMEHandler implements Consumer { - @Override - public void accept(Boolean aBoolean) { - - } -} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/ime/WaylandIMEhandler.java b/module/cleanroom/src/main/java/com/cleanroommc/client/ime/WaylandIMEhandler.java deleted file mode 100644 index c1b1fd193..000000000 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/ime/WaylandIMEhandler.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.cleanroommc.client.ime; - -import org.lwjgl.glfw.GLFW; -import org.lwjgl.opengl.Display; - -import java.util.function.Consumer; - -public class WaylandIMEhandler implements Consumer { - private static final long window = Display.getWindow(); - @Override - public void accept(Boolean active) { - GLFW.glfwSetInputMode(window, GLFW.GLFW_IME, active ? GLFW.GLFW_TRUE : GLFW.GLFW_FALSE); - } -} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/ime/WindowsIMEHandler.java b/module/cleanroom/src/main/java/com/cleanroommc/client/ime/WindowsIMEHandler.java deleted file mode 100644 index bcc232584..000000000 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/ime/WindowsIMEHandler.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.cleanroommc.client.ime; - -import com.sun.jna.Native; -import com.sun.jna.platform.win32.User32; -import com.sun.jna.platform.win32.WinDef; -import com.sun.jna.platform.win32.WinNT; - -import java.util.function.Consumer; - -/** - * Copied from IMBlocker - */ -public class WindowsIMEHandler implements Consumer { - - private static native WinNT.HANDLE ImmGetContext(WinDef.HWND hwnd); - private static native WinNT.HANDLE ImmAssociateContext(WinDef.HWND hwnd, WinNT.HANDLE himc); - private static native boolean ImmReleaseContext(WinDef.HWND hwnd, WinNT.HANDLE himc); - private static native WinNT.HANDLE ImmCreateContext(); - private static native boolean ImmDestroyContext(WinNT.HANDLE himc); - - static { - Native.register("imm32"); - } - - User32 user32 = User32.INSTANCE; - - @Override - public void accept(Boolean active) { - WinDef.HWND hwnd = user32.GetForegroundWindow(); - WinNT.HANDLE himc; - if (active) { - himc = ImmGetContext(hwnd); - if (himc == null) { - himc = ImmCreateContext(); - ImmAssociateContext(hwnd, himc); - } - } else { - himc = ImmAssociateContext(hwnd, null); - if (himc != null) { - ImmDestroyContext(himc); - } - } - ImmReleaseContext(hwnd, himc); - } - -} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/ime/X11IMEHandler.java b/module/cleanroom/src/main/java/com/cleanroommc/client/ime/X11IMEHandler.java deleted file mode 100644 index dffa14f83..000000000 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/ime/X11IMEHandler.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.cleanroommc.client.ime; - -import org.lwjgl.glfw.GLFW; -import org.lwjgl.opengl.Display; - -import java.util.function.Consumer; - -public class X11IMEHandler implements Consumer { - private static final long window = Display.getWindow(); - @Override - public void accept(Boolean active) { - GLFW.glfwSetInputMode(window, GLFW.GLFW_IME, active ? GLFW.GLFW_TRUE : GLFW.GLFW_FALSE); - } -} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/input/SDL.java b/module/cleanroom/src/main/java/com/cleanroommc/client/input/SDL.java index e6f96d708..4afc74f77 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/input/SDL.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/input/SDL.java @@ -41,12 +41,14 @@ public static synchronized boolean isInitialized(int flags) { return (initializedBits & flags) == flags; } - /** Tears down every subsystem this class brought up, and clears {@link Inputs}' listeners. */ + /** Closes the host window and tears down every subsystem this class brought up. */ public static synchronized void shutdown() { if (initializedBits == 0) { return; } + // TODO: new SDL input stack // Inputs.reset(); + Window.closeMain(); SDLInit.SDL_Quit(); initializedBits = 0; } diff --git a/module/forge/src/main/java/net/minecraftforge/client/ForgeClientHandler.java b/module/forge/src/main/java/net/minecraftforge/client/ForgeClientHandler.java index bdfb1ce42..002044b84 100644 --- a/module/forge/src/main/java/net/minecraftforge/client/ForgeClientHandler.java +++ b/module/forge/src/main/java/net/minecraftforge/client/ForgeClientHandler.java @@ -19,14 +19,13 @@ package net.minecraftforge.client; -import com.cleanroommc.client.IMEHandler; +import com.cleanroommc.client.input.Window; import com.cleanroommc.client.modlist.LegacyModListScreen; import com.cleanroommc.client.modlist.ModListConfig; import com.cleanroommc.client.modlist.ModListConstants; import com.cleanroommc.client.modlist.screen.ModListScreen; import com.cleanroommc.client.windows.TaskbarApi; import com.cleanroommc.client.windows.WindowsProperties; -import net.minecraft.client.gui.GuiChat; import net.minecraft.client.gui.GuiMainMenu; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.GuiScreenBook; @@ -51,14 +50,10 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.oredict.OreDictionary; -import java.util.Arrays; import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; public class ForgeClientHandler { - private static final Set classList = Arrays.stream(ForgeModContainer.inputMethodGuiWhiteList).collect(Collectors.toSet()); private static boolean played = false; @SubscribeEvent public static void registerModels(ModelRegistryEvent event) @@ -83,12 +78,6 @@ public static void registerItemHandlers(ColorHandlerEvent.Item event) public static void onGuiOpen(GuiOpenEvent event) { GuiScreen gui = event.getGui(); - if (gui instanceof GuiChat) - { - // Skip, this should be handled by Focus - return; - } - // Forge's mod list may get mixin in late phase, which leads to crash // Use an interface to avoid this if (ModListConfig.enable && gui instanceof LegacyModListScreen modList) @@ -96,8 +85,11 @@ public static void onGuiOpen(GuiOpenEvent event) event.setGui(new ModListScreen(modList.getParent())); } - IMEHandler.setIME(gui != null && - (gui instanceof GuiScreenBook || gui instanceof GuiEditSign || guiInWhiteList(gui))); + Window window = Window.main(); + if (window != null) + { + window.textInput(gui instanceof GuiScreenBook || gui instanceof GuiEditSign); + } } @SubscribeEvent @@ -126,11 +118,6 @@ public static void onGuiOpenLast(GuiOpenEvent event) } } - private static boolean guiInWhiteList(GuiScreen gui) { - String current = gui.getClass().getName(); - return classList.contains(current); - } - @SubscribeEvent public static void appendAdvancedTooltip(ItemTooltipEvent event) { if (!ForgeModContainer.displayAdvancedTooltips || !event.getFlags().isAdvanced()) diff --git a/module/forge/src/main/java/net/minecraftforge/common/ForgeModContainer.java b/module/forge/src/main/java/net/minecraftforge/common/ForgeModContainer.java index b41218043..712bd3ba9 100644 --- a/module/forge/src/main/java/net/minecraftforge/common/ForgeModContainer.java +++ b/module/forge/src/main/java/net/minecraftforge/common/ForgeModContainer.java @@ -116,8 +116,6 @@ public class ForgeModContainer extends DummyModContainer implements WorldAccessC public static boolean disableVersionCheck = false; public static boolean forgeLightPipelineEnabled = true; public static boolean selectiveResourceReloadEnabled = false; - public static boolean inputMethodBlockingEnabled = true; - public static String[] inputMethodGuiWhiteList = new String[] {""}; @Deprecated // TODO remove in 1.13 public static boolean replaceVanillaBucketModel = true; public static boolean zoomInMissingModelTextInGui = false; @@ -378,18 +376,6 @@ private static void syncConfig(boolean load) prop.setLanguageKey("forge.configgui.selectiveResourceReloadEnabled"); propOrder.add(prop.getName()); - prop = config.get(Configuration.CATEGORY_CLIENT, "inputMethodBlockingEnabled", true, - "When enabled, input methods will be blocked in non-input situations."); - inputMethodBlockingEnabled = prop.getBoolean(true); - prop.setLanguageKey("forge.configgui.inputMethodGuiWhiteList"); - propOrder.add(prop.getName()); - - prop = config.get(Configuration.CATEGORY_CLIENT, "inputMethodGuiWhiteList", new String[]{}, - "A list of modded gui classes considered as input method suitable."); - inputMethodGuiWhiteList = prop.getStringList(); - prop.setLanguageKey("forge.configgui.inputMethodGuiWhiteList"); - propOrder.add(prop.getName()); - prop = config.get(Configuration.CATEGORY_CLIENT, "maxTooltipNBTListLength", 100, "Maximum length (in characters) of NBT data (from NBTTagCompound#toString()) to display in tooltips (set to 0 to disable)."); maxTooltipNBTListLength = prop.getInt(100); diff --git a/module/forge/src/main/resources/assets/forge/lang/en_us.lang b/module/forge/src/main/resources/assets/forge/lang/en_us.lang index 66369e3b0..a8d88fa0f 100644 --- a/module/forge/src/main/resources/assets/forge/lang/en_us.lang +++ b/module/forge/src/main/resources/assets/forge/lang/en_us.lang @@ -93,8 +93,6 @@ forge.configgui.allowEmissiveItems=Allow Emissive Item Rendering forge.configgui.allowEmissiveItems.tooltip=Allow item rendering to detect emissive quads and draw them properly. This allows glowing blocks to look the same in item form, but incurs a very slight performance hit. forge.configgui.selectiveResourceReloadEnabled=Enable Selective Resource Loading forge.configgui.selectiveResourceReloadEnabled.tooltip=When enabled, makes specific reload tasks such as language changing quicker to run. -forge.configgui.inputMethodGuiWhiteList=Input Method Gui White List -forge.configgui.inputMethodGuiWhiteList.tooltip=Classes in this list will be considered as input method suitable and allows input through IME. forge.configgui.hud.category=HUD Settings forge.configgui.hud.category.tooltip=Controls rendering of various HUD elements. diff --git a/module/forge/src/main/resources/assets/forge/lang/zh_cn.lang b/module/forge/src/main/resources/assets/forge/lang/zh_cn.lang index 510aea16f..336312693 100644 --- a/module/forge/src/main/resources/assets/forge/lang/zh_cn.lang +++ b/module/forge/src/main/resources/assets/forge/lang/zh_cn.lang @@ -93,8 +93,6 @@ forge.configgui.allowEmissiveItems=允许物品渲染发光效果 forge.configgui.allowEmissiveItems.tooltip=允许物品在渲染时检测并正确绘制带发光效果的纹理。启用此选项允许发光的方块的物品形态有和方块类似的发光效果,但会略微影响性能。 forge.configgui.selectiveResourceReloadEnabled=启用选择性资源加载 forge.configgui.selectiveResourceReloadEnabled.tooltip=启用此选项可令某些资源重载过程(例如语言切换)速度更快。 -forge.configgui.inputMethodGuiWhiteList=输入法Gui白名单 -forge.configgui.inputMethodGuiWhiteList.tooltip=列表中的类会被游戏视作可开启输入法输入。 forge.configgui.modID.tooltip=你想要定义设置覆盖的Mod ID。 forge.configgui.modID=Mod ID @@ -252,4 +250,4 @@ item.forge.advanced_info=高级信息: item.forge.nbt_list=NBT: item.forge.nbt_limited=(截取到%d个字符) item.forge.oredict=矿物词典: -item.forge.translation_key=未本地化名称: \ No newline at end of file +item.forge.translation_key=未本地化名称: diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiSlot.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiSlot.java.patch index 26f07f387..cfb53291c 100644 --- a/module/minecraft/patches/net/minecraft/client/gui/GuiSlot.java.patch +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiSlot.java.patch @@ -30,7 +30,7 @@ int k = this.left + this.width / 2 - this.getListWidth() / 2 + 2; int l = this.top + 4 - (int)this.amountScrolled; if (this.hasListHeader) { -@@ -438,4 +419,29 @@ +@@ -438,4 +419,51 @@ public int getSlotHeight() { return this.slotHeight; } @@ -58,5 +58,26 @@ + .color(32, 32, 32, 255) + .endVertex(); + tessellator.draw(); ++ } ++ ++ protected boolean drawTopBottomShadow(Tessellator tessellator) { ++ return true; ++ } ++ ++ protected int getScrollThumbHeight() { ++ int viewHeight = this.bottom - this.top; ++ return MathHelper.clamp(viewHeight * viewHeight / this.getContentHeight(), 32, viewHeight - 8); ++ } ++ ++ protected int getListLeft() { ++ return this.left + this.width / 2 - this.getListWidth() / 2; ++ } ++ ++ protected int getListRight() { ++ return this.left + this.width / 2 + this.getListWidth() / 2; ++ } ++ ++ protected int getListEntryLeft() { ++ return this.getListLeft() + 2; + } } diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiTextField.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiTextField.java.patch index 2e421e518..4c48ea26e 100644 --- a/module/minecraft/patches/net/minecraft/client/gui/GuiTextField.java.patch +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiTextField.java.patch @@ -1,18 +1,23 @@ --- original/net/minecraft/client/gui/GuiTextField.java +++ modified/net/minecraft/client/gui/GuiTextField.java -@@ -1,5 +1,6 @@ - package net.minecraft.client.gui; - -+import com.cleanroommc.client.IMEHandler; - import com.google.common.base.Predicate; - import com.google.common.base.Predicates; - import net.minecraft.client.Minecraft; -@@ -519,6 +520,8 @@ +@@ -519,6 +519,10 @@ } this.isFocused = isFocusedIn; -+ IMEHandler.setIME(this.isFocused); ++ com.cleanroommc.client.input.Window window = com.cleanroommc.client.input.Window.main(); ++ if (window != null) { ++ window.textInput(this.isFocused); ++ } + if (Minecraft.getMinecraft().currentScreen != null) { Minecraft.getMinecraft().currentScreen.setFocused(isFocusedIn); } +@@ -592,4 +596,8 @@ + public void setVisible(boolean isVisible) { + this.visible = isVisible; + } ++ ++ public int getLineScrollOffset() { ++ return lineScrollOffset; ++ } + } From ff244a4815b3519fc84f3b369f91547926bff769 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Fri, 14 Aug 2026 22:18:21 +0100 Subject: [PATCH 32/99] Native handle cleanup with taskbars/dwm --- .../com/cleanroommc/client/LoadingTracker.java | 4 ++-- .../com/cleanroommc/client/windows/DwmApi.java | 7 +++---- .../com/cleanroommc/client/windows/TaskbarApi.java | 11 +++++------ .../minecraftforge/client/ForgeHooksClient.java | 14 +++++++++----- .../fml/client/FMLClientHandler.java | 3 --- 5 files changed, 19 insertions(+), 20 deletions(-) diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/LoadingTracker.java b/module/cleanroom/src/main/java/com/cleanroommc/client/LoadingTracker.java index 737cb2435..05eb3bca6 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/LoadingTracker.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/LoadingTracker.java @@ -281,7 +281,7 @@ private static void setTaskbarState(TaskbarApi.TBPFLAG flag) { TaskbarApi api = TaskbarApi.getInstance(); if (api == null || WindowsProperties.handle == Long.MIN_VALUE) return; try { - HWND hwnd = TaskbarApi.hwndFromGlfw(WindowsProperties.handle); + HWND hwnd = TaskbarApi.hwnd(WindowsProperties.handle); api.setProgressState(hwnd, flag); } catch (Throwable t) { FMLLog.log.debug("LoadingTracker: Failed to set taskbar state", t); @@ -293,7 +293,7 @@ private static void updateTaskbar(int progress) { TaskbarApi api = TaskbarApi.getInstance(); if (api == null || WindowsProperties.handle == Long.MIN_VALUE) return; try { - HWND hwnd = TaskbarApi.hwndFromGlfw(WindowsProperties.handle); + HWND hwnd = TaskbarApi.hwnd(WindowsProperties.handle); api.setProgressValue(hwnd, progress, MAX_PROGRESS); } catch (Throwable t) { FMLLog.log.debug("LoadingTracker: Failed to update taskbar progress", t); diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/windows/DwmApi.java b/module/cleanroom/src/main/java/com/cleanroommc/client/windows/DwmApi.java index bd57b3bf2..4d3d2e4fc 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/windows/DwmApi.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/windows/DwmApi.java @@ -10,7 +10,6 @@ import com.sun.jna.platform.win32.WinDef.HWND; import com.sun.jna.ptr.IntByReference; import net.minecraftforge.common.ForgeEarlyConfig; -import org.lwjgl.glfw.GLFWNativeWin32; import org.lwjgl.system.NativeType; import java.util.List; @@ -93,11 +92,11 @@ int DwmSetWindowAttribute( static void updateDwm(final boolean fullscreen, final long window) { // Check build number - if (!WindowsProperties.checkCompatibility()) { + if (!WindowsProperties.checkCompatibility() || window == Long.MIN_VALUE) { return; } - final HWND hwnd = new HWND(Pointer.createConstant(GLFWNativeWin32.glfwGetWin32Window(window))); + final HWND hwnd = TaskbarApi.hwnd(window); if (fullscreen) { DwmApi.disableWindowEffect(hwnd); return; @@ -191,4 +190,4 @@ protected List getFieldOrder() { return List.of("cxLeftWidth", "cxRightWidth", "cyTopHeight", "cyBottomHeight"); } } -} \ No newline at end of file +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/windows/TaskbarApi.java b/module/cleanroom/src/main/java/com/cleanroommc/client/windows/TaskbarApi.java index 60ffdc8e4..56cbcfaac 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/windows/TaskbarApi.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/windows/TaskbarApi.java @@ -13,8 +13,6 @@ import com.sun.jna.platform.win32.WinNT.HRESULT; import com.sun.jna.win32.StdCallLibrary; import com.sun.jna.win32.W32APIOptions; -import org.lwjgl.glfw.GLFWNativeWin32; - import java.util.List; public final class TaskbarApi implements AutoCloseable { @@ -96,8 +94,9 @@ public static TaskbarApi create() { return api; } - public static HWND hwndFromGlfw(long glfwWindow) { - return new HWND(Pointer.createConstant(GLFWNativeWin32.glfwGetWin32Window(glfwWindow))); + /** Converts an operating-system window handle to JNA's HWND wrapper. */ + public static HWND hwnd(long nativeWindow) { + return new HWND(Pointer.createConstant(nativeWindow)); } public void hrInit() { @@ -166,7 +165,7 @@ public static boolean flashTaskbar(HWND hwnd, int count) { } public static boolean flashTaskbarUntilForeground(long window) { - final WinDef.HWND hwnd = TaskbarApi.hwndFromGlfw(window); + final WinDef.HWND hwnd = hwnd(window); User32Ex.FLASHWINFO info = new User32Ex.FLASHWINFO(); info.hwnd = hwnd; info.dwFlags = User32Ex.FLASHW_TRAY | User32Ex.FLASHW_TIMERNOFG; @@ -268,4 +267,4 @@ protected List getFieldOrder() { } } } -} \ No newline at end of file +} diff --git a/module/forge/src/main/java/net/minecraftforge/client/ForgeHooksClient.java b/module/forge/src/main/java/net/minecraftforge/client/ForgeHooksClient.java index 8114e94db..7f985f98c 100644 --- a/module/forge/src/main/java/net/minecraftforge/client/ForgeHooksClient.java +++ b/module/forge/src/main/java/net/minecraftforge/client/ForgeHooksClient.java @@ -38,6 +38,7 @@ import javax.vecmath.Vector4f; import com.cleanroommc.client.LoadingTracker; +import com.cleanroommc.client.input.Window; import com.cleanroommc.client.windows.DwmApi; import com.cleanroommc.client.windows.NtDll; import com.cleanroommc.client.windows.TaskbarApi; @@ -992,16 +993,19 @@ public static void setWindowStyle(boolean isFullScreen) { } } - public static void initializeWindowsInformation(){ + public static void initializeWindowsInformation() { if (SystemUtils.IS_OS_WINDOWS) { - NtDll.initializeWindowsInformation(Display.getWindow()); + Window window = Window.main(); + if (window != null) { + NtDll.initializeWindowsInformation(window.nativeHandle()); + } } } - public static void initializeTaskbarAPI(){ + public static void initializeTaskbarAPI() { if (SystemUtils.IS_OS_WINDOWS) { try { - TaskbarApi taskbarApi = TaskbarApi.create(); + TaskbarApi.create(); } catch (Throwable t) { FMLLog.log.error("Unable to initialize Taskbar API", t); TaskbarApi.clearInstance(); @@ -1023,7 +1027,7 @@ public static void clearTaskbarProgress() { if (SystemUtils.IS_OS_WINDOWS) { var taskbar = TaskbarApi.getInstance(); if (taskbar != null) { - taskbar.clearProgress(TaskbarApi.hwndFromGlfw(WindowsProperties.handle)); + taskbar.clearProgress(TaskbarApi.hwnd(WindowsProperties.handle)); } else { FMLLog.log.error("Unable to clear taskbar progress, cannot invoke a null object."); } diff --git a/module/forge/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java index 77ab308f3..c0ab25a73 100644 --- a/module/forge/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java +++ b/module/forge/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java @@ -125,7 +125,6 @@ import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.message.FormattedMessage; import org.lwjgl.LWJGLUtil; -import org.lwjgl.input.Keyboard; import org.lwjgl.input.Mouse; import org.lwjgl.opengl.Display; @@ -288,8 +287,6 @@ public void beginMinecraftLoading(Minecraft minecraft, List resou } } - Keyboard.populateKeyLookupTables(); - @SuppressWarnings("unchecked") Map> sharedModList = (Map>) Launch.blackboard.get("modList"); if (sharedModList == null) From 8bb595a1dd0ef6d62eba2cb00b4ee96422fcdb4b Mon Sep 17 00:00:00 2001 From: Rongmario Date: Sat, 15 Aug 2026 00:36:33 +0100 Subject: [PATCH 33/99] LWJGLYTransformer --- .../asm/transformers/LWJGLTransformer.java | 83 ++----------------- 1 file changed, 8 insertions(+), 75 deletions(-) diff --git a/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/LWJGLTransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/LWJGLTransformer.java index 803e13759..0a3b62de2 100644 --- a/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/LWJGLTransformer.java +++ b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/LWJGLTransformer.java @@ -1,86 +1,19 @@ package net.minecraftforge.fml.common.asm.transformers; +import com.cleanroommc.lwjgly.LWJGLYTransformer; import net.minecraft.launchwrapper.IClassTransformer; -import net.minecraft.launchwrapper.Launch; -import org.objectweb.asm.ClassReader; -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.ClassWriter; -import org.objectweb.asm.commons.ClassRemapper; -import org.objectweb.asm.commons.Remapper; -import org.objectweb.asm.tree.ClassNode; - -import java.io.IOException; -import java.util.Set; -import java.util.stream.Collectors; public class LWJGLTransformer implements IClassTransformer { - private static final LWJGLXRemapper INSTANCE = new LWJGLXRemapper(); - @Override - public byte[] transform(String s, String s1, byte[] bytes) { - if (!s1.startsWith("org.lwjgl.")) { - return bytes; - } - String lwjglxName = s.replace("org.lwjgl.", "org.lwjglx."); - byte[] lwjglxBytes; - try { - lwjglxBytes = Launch.classLoader.testGetClassBytes(lwjglxName); - } catch (IOException e) { - return bytes; - } - if (lwjglxBytes == null) { - return bytes; - } - ClassReader lwjglxReader = new ClassReader(lwjglxBytes); - ClassWriter writer = new ClassWriter(0); - ClassVisitor classVisitor = new ClassRemapper(writer, INSTANCE); - lwjglxReader.accept(classVisitor, 0); - lwjglxBytes = writer.toByteArray(); - if (bytes == null) { - return lwjglxBytes; - } - ClassNode lwjglNode = new ClassNode(); - ClassReader lwjglReader = new ClassReader(bytes); - lwjglReader.accept(lwjglNode, 0); - - lwjglxReader = new ClassReader(lwjglxBytes); - ClassNode lwjglxNode = new ClassNode(); - lwjglxReader.accept(lwjglxNode, 0); - Set methods = lwjglNode.methods.stream().map(m -> m.name + m.desc).collect(Collectors.toSet()); - lwjglxNode.methods.forEach(m -> { - if (!methods.contains(m.name + m.desc)) { - lwjglNode.methods.add(m); - } - }); - Set fields = lwjglNode.fields.stream().map(f -> f.name + f.desc).collect(Collectors.toSet()); - lwjglxNode.fields.forEach(f -> { - if (!fields.contains(f.name + f.desc)) { - lwjglNode.fields.add(f); - } - }); - if (s1.equals("org.lwjgl.openal.AL")) { - lwjglNode.methods.removeIf(m -> m.name.equals("destroy")); - lwjglxNode.methods.stream().filter(m -> m.name.equals("destroy")).forEach(m -> lwjglNode.methods.add(m)); - } - ClassWriter out = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); - lwjglNode.accept(out); - return out.toByteArray(); + // Initialization + static { + LWJGLYTransformer.targets(); } - static class LWJGLXRemapper extends Remapper { - - @Override - public String map(String typeName) { - if (typeName == null) { - return null; - } - if (typeName.startsWith("org/lwjglx/")) { - return "org/lwjgl/" + typeName.substring(11); - } - - return typeName; - } - + @Override + public byte[] transform(String name, String transformedName, byte[] bytes) { + transformedName = transformedName == null ? null : transformedName.replace('.', '/'); + return LWJGLYTransformer.handles(transformedName) ? LWJGLYTransformer.transform(transformedName, bytes) : bytes; } } From 126d8182c35ae9bc2eb05c5e1fea6217726be7de Mon Sep 17 00:00:00 2001 From: Rongmario Date: Sat, 15 Aug 2026 01:01:07 +0100 Subject: [PATCH 34/99] Bridging classes --- .../client/input/CleanroomWindowBridge.java | 332 ++++++++++ .../client/input/LegacyInputQueues.java | 134 ++++ .../client/input/SharedGLContext.java | 81 +++ .../com/cleanroommc/client/input/Window.java | 598 ++++++++++++++++++ .../fml/relauncher/FMLCorePlugin.java | 12 +- .../net/minecraft/client/Minecraft.java.patch | 106 ++-- .../minecraft/client/gui/GuiSlot.java.patch | 2 +- .../client/gui/GuiTextField.java.patch | 4 +- 8 files changed, 1215 insertions(+), 54 deletions(-) create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/input/CleanroomWindowBridge.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/input/LegacyInputQueues.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/input/SharedGLContext.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/input/Window.java diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/input/CleanroomWindowBridge.java b/module/cleanroom/src/main/java/com/cleanroommc/client/input/CleanroomWindowBridge.java new file mode 100644 index 000000000..d4200da41 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/input/CleanroomWindowBridge.java @@ -0,0 +1,332 @@ +package com.cleanroommc.client.input; + +import com.cleanroommc.lwjgly.LWJGLY; +import com.cleanroommc.lwjgly.spi.WindowBridge; +import org.lwjgl.opengl.GL; +import org.lwjgl.opengl.GLCapabilities; +import org.lwjgl.sdl.SDLVideo; +import org.lwjgl.system.MemoryStack; + +import java.nio.IntBuffer; + +/** Connects LWJGLY's LWJGL 2 compatibility APIs to Cleanroom's SDL window. */ +public final class CleanroomWindowBridge implements WindowBridge { + + private static String validate(ContextRequest request) { + PixelFormatRequest format = request.pixelFormat(); + if (format.auxiliaryBuffers() > 0) { + return "SDL cannot guarantee the requested auxiliary buffers"; + } + if (format.colorSamples() > 0) { + return "SDL cannot guarantee the requested NV coverage color samples"; + } + if (format.floatingPointPacked()) { + return "SDL cannot guarantee a packed floating point color buffer"; + } + String rejection = firstOf( + atLeast("alpha bits", format.alphaBits(), SDLVideo.SDL_GL_ALPHA_SIZE), + atLeast("depth bits", format.depthBits(), SDLVideo.SDL_GL_DEPTH_SIZE), + atLeast("stencil bits", format.stencilBits(), SDLVideo.SDL_GL_STENCIL_SIZE), + atLeast("accumulation alpha bits", format.accumulationAlphaBits(), SDLVideo.SDL_GL_ACCUM_ALPHA_SIZE), + accumulationBits(format.accumulationBitsPerPixel()), + multisampling(format.samples()), + present(format.stereo(), "stereoscopic buffers", SDLVideo.SDL_GL_STEREO), + present(format.floatingPoint(), "a floating point color buffer", SDLVideo.SDL_GL_FLOATBUFFERS), + present(format.sRGB(), "an sRGB capable framebuffer", SDLVideo.SDL_GL_FRAMEBUFFER_SRGB_CAPABLE) + ); + if (rejection != null) { + return rejection; + } + ContextAttributesRequest attributes = request.attributes(); + if (attributes == null) { + return null; + } + if (attributes.layerPlane() != 0) { + return "SDL does not support OpenGL layer planes"; + } + return firstOf( + version(attributes.majorVersion(), attributes.minorVersion()), + profile(attributes.profile()), + flags(attributes), + resetNotification(attributes.resetNotification()), + releaseBehavior(attributes.releaseBehavior()) + ); + } + + private static String atLeast(String name, int required, int attribute) { + if (required <= 0) { + return null; + } + int actual = glAttribute(attribute); + return actual >= required ? null : "the context has " + actual + " " + name + ", but " + required + " were requested"; + } + + private static String accumulationBits(int required) { + if (required <= 0) { + return null; + } + int actual = glAttribute(SDLVideo.SDL_GL_ACCUM_RED_SIZE) + glAttribute(SDLVideo.SDL_GL_ACCUM_GREEN_SIZE) + glAttribute(SDLVideo.SDL_GL_ACCUM_BLUE_SIZE); + return actual >= required ? null : "the context has " + actual + " RGB accumulation bits, but " + required + " were requested"; + } + + private static String multisampling(int required) { + if (required <= 0) { + return null; + } + if (glAttribute(SDLVideo.SDL_GL_MULTISAMPLEBUFFERS) < 1) { + return "the context has no multisample buffer"; + } + int actual = glAttribute(SDLVideo.SDL_GL_MULTISAMPLESAMPLES); + return actual >= required ? null : "the context has " + actual + " samples, but " + required + " were requested"; + } + + private static String present(boolean required, String name, int attribute) { + return !required || glAttribute(attribute) != 0 ? null : "the context has no " + name; + } + + private static String version(int major, int minor) { + int actualMajor = glAttribute(SDLVideo.SDL_GL_CONTEXT_MAJOR_VERSION); + int actualMinor = glAttribute(SDLVideo.SDL_GL_CONTEXT_MINOR_VERSION); + return actualMajor > major || actualMajor == major && actualMinor >= minor + ? null : "the context is OpenGL " + actualMajor + '.' + actualMinor + ", but at least " + major + '.' + minor + " was requested"; + } + + private static String profile(ContextProfile required) { + if (required == ContextProfile.DEFAULT) { + return null; + } + int wanted = switch (required) { + case CORE -> SDLVideo.SDL_GL_CONTEXT_PROFILE_CORE; + case COMPATIBILITY -> SDLVideo.SDL_GL_CONTEXT_PROFILE_COMPATIBILITY; + case ES -> SDLVideo.SDL_GL_CONTEXT_PROFILE_ES; + case DEFAULT -> 0; + }; + return glAttribute(SDLVideo.SDL_GL_CONTEXT_PROFILE_MASK) == wanted ? null : "the context does not use the requested " + required + " profile"; + } + + private static String flags(ContextAttributesRequest attributes) { + int required = (attributes.debug() ? SDLVideo.SDL_GL_CONTEXT_DEBUG_FLAG : 0) + | (attributes.forwardCompatible() ? SDLVideo.SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG : 0) + | (attributes.robustAccess() ? SDLVideo.SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG : 0) + | (attributes.resetIsolation() ? SDLVideo.SDL_GL_CONTEXT_RESET_ISOLATION_FLAG : 0); + int missing = required & ~glAttribute(SDLVideo.SDL_GL_CONTEXT_FLAGS); + return missing == 0 ? null : "the context is missing requested flags 0x" + Integer.toHexString(missing); + } + + private static String resetNotification(ResetNotification required) { + if (required != ResetNotification.LOSE_CONTEXT) { + return null; + } + return glAttribute(SDLVideo.SDL_GL_CONTEXT_RESET_NOTIFICATION) == SDLVideo.SDL_GL_CONTEXT_RESET_LOSE_CONTEXT + ? null : "the context does not use lose-on-reset behavior"; + } + + private static String releaseBehavior(ReleaseBehavior required) { + if (required != ReleaseBehavior.NONE) { + return null; + } + return glAttribute(SDLVideo.SDL_GL_CONTEXT_RELEASE_BEHAVIOR) == SDLVideo.SDL_GL_CONTEXT_RELEASE_BEHAVIOR_NONE + ? null : "the context flushes when released"; + } + + private static int glAttribute(int attribute) { + try (MemoryStack stack = MemoryStack.stackPush()) { + IntBuffer value = stack.mallocInt(1); + SDL.check(SDLVideo.SDL_GL_GetAttribute(attribute, value), "SDL_GL_GetAttribute(" + attribute + ")"); + return value.get(0); + } + } + + private static String firstOf(String... values) { + for (String value : values) { + if (value != null) { + return value; + } + } + return null; + } + + private final Window window; + private final GLCapabilities capabilities; + + private CleanroomWindowBridge(Window window) { + this.window = window; + this.capabilities = GL.getCapabilities(); + } + + /** Installs the bridge before any call to Display, Keyboard or Mouse. */ + public static void install(Window window) { + LWJGLY.setWindowBridge(new CleanroomWindowBridge(window)); + } + + @Override + public long handle() { + return window.handle(); + } + + @Override + public int width() { + return window.width(); + } + + @Override + public int height() { + return window.height(); + } + + @Override + public String title() { + return window.title(); + } + + @Override + public void title(String title) { + window.title(title); + } + + @Override + public boolean closeRequested() { + return window.closeRequested(); + } + + @Override + public boolean focused() { + return window.focused(); + } + + @Override + public boolean consumeResized() { + return window.consumeResized(); + } + + @Override + public boolean fullscreen() { + return window.fullscreen(); + } + + @Override + public void fullscreen(boolean fullscreen) { + window.fullscreen(fullscreen); + } + + @Override + public void vsync(boolean enabled) { + window.vsync(enabled); + } + + @Override + public ContextResult adoptContext(ContextRequest request) { + String rejection; + try { + this.window.makeCurrent(); + rejection = validate(request); + } catch (RuntimeException failure) { + rejection = "Could not adopt the host OpenGL context: " + failure; + } + long currentWindow = SDLVideo.SDL_GL_GetCurrentWindow(); + long currentContext = SDLVideo.SDL_GL_GetCurrentContext(); + if (rejection != null) { + return ContextResult.rejected(rejection, currentWindow, currentContext); + } + GL.setCapabilities(this.capabilities); + return ContextResult.accepted(currentWindow, currentContext); + } + + @Override + public void makeCurrent() { + window.makeCurrent(); + GL.setCapabilities(capabilities); + } + + @Override + public void releaseContext() { + window.releaseContext(); + GL.setCapabilities(null); + } + + @Override + public void swapBuffers() { + window.swapBuffers(); + } + + @Override + public void pump() { + window.pump(); + } + + @Override + public KeyEvent nextKeyEvent() { + return window.nextKeyEvent(); + } + + @Override + public int queuedKeyEvents() { + return window.queuedKeyEvents(); + } + + @Override + public boolean keyDown(int sdlScancode) { + return window.keyDown(sdlScancode); + } + + @Override + public void textInput(boolean enabled) { + window.textInput(enabled); + } + + @Override + public MouseEvent nextMouseEvent() { + return window.nextMouseEvent(); + } + + @Override + public int queuedMouseEvents() { + return window.queuedMouseEvents(); + } + + @Override + public boolean mouseButtonDown(int sdlButton) { + return window.mouseButtonDown(sdlButton); + } + + @Override + public float mouseX() { + return window.mouseX(); + } + + @Override + public float mouseY() { + return window.mouseY(); + } + + @Override + public float takeMouseDeltaX() { + return window.takeMouseDeltaX(); + } + + @Override + public float takeMouseDeltaY() { + return window.takeMouseDeltaY(); + } + + @Override + public float takeMouseWheel() { + return window.takeMouseWheel(); + } + + @Override + public void mousePosition(float x, float y) { + window.mousePosition(x, y); + } + + @Override + public void grabMouse(boolean grab) { + window.grabMouse(grab); + } + + @Override + public boolean mouseGrabbed() { + return window.mouseGrabbed(); + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/input/LegacyInputQueues.java b/module/cleanroom/src/main/java/com/cleanroommc/client/input/LegacyInputQueues.java new file mode 100644 index 000000000..cdf3273b0 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/input/LegacyInputQueues.java @@ -0,0 +1,134 @@ +package com.cleanroommc.client.input; + +import com.cleanroommc.lwjgly.spi.WindowBridge; + +import java.util.ArrayDeque; +import java.util.Deque; + +/** The destructive LWJGL 2 keyboard and mouse queues backed by SDL events. */ +final class LegacyInputQueues { + + private static final int CAPACITY = 1024; + + private static final class PendingKey { + + private final int scancode; + private final int key; + private final boolean pressed; + private final boolean repeat; + private final long timestampNs; + + private char character; + + private PendingKey(int scancode, int key, boolean pressed, boolean repeat, long timestampNs) { + this.scancode = scancode; + this.key = key; + this.pressed = pressed; + this.repeat = repeat; + this.timestampNs = timestampNs; + } + + private WindowBridge.KeyEvent freeze() { + return new WindowBridge.KeyEvent(scancode, key, pressed, repeat, character, timestampNs); + } + + } + + private static void append(Deque queue, T event) { + if (queue.size() == CAPACITY) { + queue.removeFirst(); + } + queue.addLast(event); + } + + private final Deque keys = new ArrayDeque<>(); + private final Deque mice = new ArrayDeque<>(); + + private PendingKey pendingCharacter; + private double deltaX; + private double deltaY; + private double wheel; + + synchronized void key(int scancode, int key, boolean pressed, boolean repeat, long timestampNs) { + this.pendingCharacter = null; + PendingKey event = new PendingKey(scancode, key, pressed, repeat, timestampNs); + append(this.keys, event); + if (pressed) { + this.pendingCharacter = event; + } + } + + synchronized void text(String text, long timestampNs) { + if (text == null) { + return; + } + for (int i = 0; i < text.length(); i++) { + char character = text.charAt(i); + if (this.pendingCharacter != null && this.pendingCharacter.character == 0) { + this.pendingCharacter.character = character; + this.pendingCharacter = null; + } else { + PendingKey event = new PendingKey(0, 0, true, false, timestampNs); + event.character = character; + append(this.keys, event); + } + } + } + + synchronized void motion(float x, float y, float dx, float dy, long timestampNs) { + this.deltaX += dx; + this.deltaY += dy; + append(this.mice, new WindowBridge.MouseEvent(0, false, x, y, dx, dy, 0.0F, timestampNs)); + } + + synchronized void button(int button, boolean pressed, float x, float y, long timestampNs) { + append(this.mice, new WindowBridge.MouseEvent(button, pressed, x, y, 0.0F, 0.0F, 0.0F, timestampNs)); + } + + synchronized void wheel(float x, float y, float amount, long timestampNs) { + this.wheel += amount; + append(this.mice, new WindowBridge.MouseEvent(0, false, x, y, 0.0F, 0.0F, amount, timestampNs)); + } + + synchronized WindowBridge.KeyEvent nextKey() { + PendingKey event = keys.pollFirst(); + if (event == null) { + return null; + } + if (event == this.pendingCharacter) { + this.pendingCharacter = null; + } + return event.freeze(); + } + + synchronized int queuedKeys() { + return this.keys.size(); + } + + synchronized WindowBridge.MouseEvent nextMouse() { + return this.mice.pollFirst(); + } + + synchronized int queuedMice() { + return this.mice.size(); + } + + synchronized float takeDeltaX() { + float value = (float) this.deltaX; + this.deltaX = 0.0; + return value; + } + + synchronized float takeDeltaY() { + float value = (float) this.deltaY; + this.deltaY = 0.0; + return value; + } + + synchronized float takeWheel() { + float value = (float) this.wheel; + this.wheel = 0.0; + return value; + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/input/SharedGLContext.java b/module/cleanroom/src/main/java/com/cleanroommc/client/input/SharedGLContext.java new file mode 100644 index 000000000..8c8b876ce --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/input/SharedGLContext.java @@ -0,0 +1,81 @@ +package com.cleanroommc.client.input; + +import org.lwjgl.opengl.GL; +import org.lwjgl.opengl.GLCapabilities; +import org.lwjgl.sdl.SDLVideo; + +/** A hidden SDL surface and GL context sharing objects with the main window. */ +public final class SharedGLContext implements AutoCloseable { + + /** Creates a context sharing with the main context that is current on this thread. */ + public static SharedGLContext create(Window window) { + if (window == null) { + throw new IllegalStateException("The SDL window does not exist"); + } + long surface = SDL.checkHandle(SDLVideo.SDL_CreateWindow("Cleanroom Shared Context", 1, 1, + SDLVideo.SDL_WINDOW_OPENGL | SDLVideo.SDL_WINDOW_HIDDEN), "SDL_CreateWindow"); + long context = 0L; + try { + SDL.check(SDLVideo.SDL_GL_SetAttribute(SDLVideo.SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1), + "SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT)"); + context = SDL.checkHandle(SDLVideo.SDL_GL_CreateContext(surface), "SDL_GL_CreateContext"); + window.makeCurrent(); + return new SharedGLContext(window, surface, context); + } catch (RuntimeException failure) { + if (context != 0L) { + SDLVideo.SDL_GL_DestroyContext(context); + } + SDLVideo.SDL_DestroyWindow(surface); + throw failure; + } finally { + SDLVideo.SDL_GL_SetAttribute(SDLVideo.SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 0); + } + } + + private final Window window; + private final long surface; + private final long context; + + private GLCapabilities capabilities; + private boolean closed; + + private SharedGLContext(Window window, long surface, long context) { + this.window = window; + this.surface = surface; + this.context = context; + } + + public void makeCurrent() { + this.ensureOpen(); + SDL.check(SDLVideo.SDL_GL_MakeCurrent(surface, context), "SDL_GL_MakeCurrent"); + if (this.capabilities == null) { + this.capabilities = GL.createCapabilities(); + } else { + GL.setCapabilities(this.capabilities); + } + } + + public void release() { + this.ensureOpen(); + SDL.check(SDLVideo.SDL_GL_MakeCurrent(surface, 0L), "SDL_GL_MakeCurrent"); + GL.setCapabilities(null); + } + + @Override + public void close() { + if (this.closed) { + return; + } + this.closed = true; + SDLVideo.SDL_GL_DestroyContext(this.context); + SDLVideo.SDL_DestroyWindow(this.surface); + this.capabilities = null; + } + + private void ensureOpen() { + if (this.closed) { + throw new IllegalStateException("The shared GL context is closed"); + } + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/input/Window.java b/module/cleanroom/src/main/java/com/cleanroommc/client/input/Window.java new file mode 100644 index 000000000..0c19c50ab --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/input/Window.java @@ -0,0 +1,598 @@ +package com.cleanroommc.client.input; + +import com.cleanroommc.lwjgly.spi.WindowBridge; +import org.lwjgl.opengl.GL; +import org.lwjgl.sdl.SDLKeyboard; +import org.lwjgl.sdl.SDLMouse; +import org.lwjgl.sdl.SDLProperties; +import org.lwjgl.sdl.SDLVideo; +import org.lwjgl.sdl.SDLEvents; +import org.lwjgl.sdl.SDL_Event; +import org.lwjgl.sdl.SDL_KeyboardEvent; +import org.lwjgl.sdl.SDL_MouseButtonEvent; +import org.lwjgl.sdl.SDL_MouseMotionEvent; +import org.lwjgl.sdl.SDL_MouseWheelEvent; +import org.lwjgl.sdl.SDL_TextInputEvent; +import org.lwjgl.sdl.SDL_WindowEvent; +import org.lwjgl.system.MemoryStack; + +import java.nio.IntBuffer; +import java.util.Arrays; +import java.util.function.Consumer; + +/** The single SDL window, OpenGL context and event pump owned by Cleanroom. */ +public final class Window implements AutoCloseable { + + private static final int MAX_SCANCODES = 512; + private static final int MAX_MOUSE_BUTTONS = 8; + + private static volatile Window main; + + private final long handle; + private final long glContext; + private final int id; + private final LegacyInputQueues legacy = new LegacyInputQueues(); + private final boolean[] keys = new boolean[MAX_SCANCODES]; + private final boolean[] buttons = new boolean[MAX_MOUSE_BUTTONS + 1]; + + private String title; + private int width; + private int height; + private int pixelWidth; + private int pixelHeight; + private float mouseX; + private float mouseY; + private boolean focused = true; + private boolean closeRequested; + private boolean resized; + private boolean fullscreen; + private boolean borderless; + private boolean minimized; + private boolean mouseGrabbed; + private boolean mouseWarped; + private boolean closed; + + private Window(long handle, long glContext, String title, int width, int height) { + this.handle = handle; + this.glContext = glContext; + this.id = SDLVideo.SDL_GetWindowID(handle); + this.title = title; + this.width = width; + this.height = height; + this.pixelWidth = width; + this.pixelHeight = height; + } + + public static Builder builder() { + return new Builder(); + } + + public static Window main() { + return main; + } + + public static void closeMain() { + Window current = main; + if (current != null) { + current.close(); + } + } + + public long handle() { + return handle; + } + + + /** + * Returns the platform window handle rather than SDL's opaque window pointer. + * TODO: Make compositors into an enum + */ + public long nativeHandle() { + int properties = SDLVideo.SDL_GetWindowProperties(handle); + if (properties == 0) { + return 0L; + } + long hwnd = SDLProperties.SDL_GetPointerProperty(properties, SDLVideo.SDL_PROP_WINDOW_WIN32_HWND_POINTER, 0L); + if (hwnd != 0L) { + return hwnd; + } + long wayland = SDLProperties.SDL_GetPointerProperty(properties, SDLVideo.SDL_PROP_WINDOW_WAYLAND_SURFACE_POINTER, 0L); + if (wayland != 0L) { + return wayland; + } + long x11 = SDLProperties.SDL_GetNumberProperty(properties, SDLVideo.SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0L); + if (x11 != 0L) { + return x11; + } + long macOS = SDLProperties.SDL_GetNumberProperty(properties, SDLVideo.SDL_PROP_WINDOW_COCOA_WINDOW_POINTER, 0L); + if (macOS != 0L) { + return macOS; + } + long android = SDLProperties.SDL_GetNumberProperty(properties, SDLVideo.SDL_PROP_WINDOW_ANDROID_WINDOW_POINTER, 0L); + if (android != 0L) { + return android; + } + long ios = SDLProperties.SDL_GetNumberProperty(properties, SDLVideo.SDL_PROP_WINDOW_UIKIT_WINDOW_POINTER, 0L); + if (ios != 0L) { + return ios; + } + return SDLProperties.SDL_GetNumberProperty(properties, SDLVideo.SDL_PROP_WINDOW_VIVANTE_WINDOW_POINTER, 0L); + } + + public synchronized int width() { + return width; + } + + public synchronized int height() { + return height; + } + + public synchronized int pixelWidth() { + return pixelWidth; + } + + public synchronized int pixelHeight() { + return pixelHeight; + } + + public synchronized String title() { + return title; + } + + public synchronized boolean focused() { + return focused; + } + + public synchronized boolean minimized() { + return minimized; + } + + public synchronized boolean closeRequested() { + return closeRequested; + } + + public synchronized boolean fullscreen() { + return fullscreen; + } + + public synchronized boolean borderless() { + return borderless; + } + + public synchronized boolean consumeResized() { + boolean value = this.resized; + this.resized = false; + return value; + } + + public synchronized Window title(String title) { + SDL.check(SDLVideo.SDL_SetWindowTitle(this.handle, title), "SDL_SetWindowTitle"); + this.title = title; + return this; + } + + public synchronized Window fullscreen(boolean fullscreen) { + SDL.check(SDLVideo.SDL_SetWindowFullscreen(handle, fullscreen), "SDL_SetWindowFullscreen"); + this.fullscreen = fullscreen; + this.refreshSize(); + return this; + } + + public synchronized Window borderless(boolean borderless) { + SDL.check(SDLVideo.SDL_SetWindowBordered(this.handle, !borderless), "SDL_SetWindowBordered"); + this.borderless = borderless; + return this; + } + + public Window vsync(boolean enabled) { + SDL.check(SDLVideo.SDL_GL_SetSwapInterval(enabled ? 1 : 0), "SDL_GL_SetSwapInterval"); + return this; + } + + public Window makeCurrent() { + SDL.check(SDLVideo.SDL_GL_MakeCurrent(this.handle, this.glContext), "SDL_GL_MakeCurrent"); + return this; + } + + public Window releaseContext() { + SDL.check(SDLVideo.SDL_GL_MakeCurrent(this.handle, 0L), "SDL_GL_MakeCurrent"); + return this; + } + + public Window swapBuffers() { + SDL.check(SDLVideo.SDL_GL_SwapWindow(this.handle), "SDL_GL_SwapWindow"); + return this; + } + + public Window textInput(boolean enabled) { + boolean active = SDLKeyboard.SDL_TextInputActive(this.handle); + if (enabled && !active) { + SDL.check(SDLKeyboard.SDL_StartTextInput(this.handle), "SDL_StartTextInput"); + } else if (!enabled && active) { + SDL.check(SDLKeyboard.SDL_StopTextInput(this.handle), "SDL_StopTextInput"); + } + return this; + } + + /** Drains SDL's process-wide event queue exactly once for the frame. */ + public synchronized Window pump() { + try (MemoryStack stack = MemoryStack.stackPush()) { + SDL_Event event = SDL_Event.malloc(stack); + while (SDLEvents.SDL_PollEvent(event)) { + dispatch(event); + } + } + this.mouseWarped = false; + return this; + } + + private void dispatch(SDL_Event event) { + int type = event.type(); + switch (type) { + case SDLEvents.SDL_EVENT_QUIT -> closeRequested = true; + case SDLEvents.SDL_EVENT_KEY_DOWN, SDLEvents.SDL_EVENT_KEY_UP -> key(event.key()); + case SDLEvents.SDL_EVENT_TEXT_INPUT -> text(event.text()); + case SDLEvents.SDL_EVENT_MOUSE_MOTION -> motion(event.motion()); + case SDLEvents.SDL_EVENT_MOUSE_BUTTON_DOWN, SDLEvents.SDL_EVENT_MOUSE_BUTTON_UP -> button(event.button()); + case SDLEvents.SDL_EVENT_MOUSE_WHEEL -> wheel(event.wheel()); + case SDLEvents.SDL_EVENT_WINDOW_CLOSE_REQUESTED, + SDLEvents.SDL_EVENT_WINDOW_RESIZED, + SDLEvents.SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED, + SDLEvents.SDL_EVENT_WINDOW_FOCUS_GAINED, + SDLEvents.SDL_EVENT_WINDOW_FOCUS_LOST, + SDLEvents.SDL_EVENT_WINDOW_MINIMIZED, + SDLEvents.SDL_EVENT_WINDOW_MAXIMIZED, + SDLEvents.SDL_EVENT_WINDOW_RESTORED, + SDLEvents.SDL_EVENT_WINDOW_ENTER_FULLSCREEN, + SDLEvents.SDL_EVENT_WINDOW_LEAVE_FULLSCREEN -> window(type, event.window()); + default -> { } + } + } + + private void key(SDL_KeyboardEvent event) { + if (event.windowID() != this.id) { + return; + } + int scancode = event.scancode(); + if (scancode >= 0 && scancode < this.keys.length) { + this.keys[scancode] = event.down(); + } + this.legacy.key(scancode, event.key(), event.down(), event.repeat(), event.timestamp()); + } + + private void text(SDL_TextInputEvent event) { + if (event.windowID() == this.id) { + this.legacy.text(event.textString(), event.timestamp()); + } + } + + private void motion(SDL_MouseMotionEvent event) { + if (event.windowID() != this.id) { + return; + } + this.mouseX = event.x(); + this.mouseY = event.y(); + float dx = this.mouseWarped ? 0.0F : event.xrel(); + float dy = this.mouseWarped ? 0.0F : event.yrel(); + this.mouseWarped = false; + this.legacy.motion(this.mouseX, this.mouseY, dx, dy, event.timestamp()); + } + + private void button(SDL_MouseButtonEvent event) { + if (event.windowID() != id) { + return; + } + int button = event.button() & 0xFF; + this.mouseX = event.x(); + this.mouseY = event.y(); + if (button > 0 && button < this.buttons.length) { + this.buttons[button] = event.down(); + } + this.legacy.button(button, event.down(), this.mouseX, this.mouseY, event.timestamp()); + } + + private void wheel(SDL_MouseWheelEvent event) { + if (event.windowID() != this.id) { + return; + } + float amount = event.y(); + if (event.direction() == SDLMouse.SDL_MOUSEWHEEL_FLIPPED) { + amount = -amount; + } + this.legacy.wheel(event.mouse_x(), event.mouse_y(), amount, event.timestamp()); + } + + private void window(int type, SDL_WindowEvent event) { + if (event.windowID() != this.id) { + return; + } + switch (type) { + case SDLEvents.SDL_EVENT_WINDOW_CLOSE_REQUESTED -> this.closeRequested = true; + case SDLEvents.SDL_EVENT_WINDOW_RESIZED -> { + this.width = event.data1(); + this.height = event.data2(); + this.resized = true; + } + case SDLEvents.SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED -> { + this.pixelWidth = event.data1(); + this.pixelHeight = event.data2(); + this.resized = true; + } + case SDLEvents.SDL_EVENT_WINDOW_FOCUS_GAINED -> this.focused = true; + case SDLEvents.SDL_EVENT_WINDOW_FOCUS_LOST -> { + this.focused = false; + this.releaseHeldInput(event.timestamp()); + } + case SDLEvents.SDL_EVENT_WINDOW_MINIMIZED -> this.minimized = true; + case SDLEvents.SDL_EVENT_WINDOW_MAXIMIZED, SDLEvents.SDL_EVENT_WINDOW_RESTORED -> this.minimized = false; + case SDLEvents.SDL_EVENT_WINDOW_ENTER_FULLSCREEN -> this.fullscreen = true; + case SDLEvents.SDL_EVENT_WINDOW_LEAVE_FULLSCREEN -> this.fullscreen = false; + default -> { } + } + } + + private void releaseHeldInput(long timestampNs) { + for (int scancode = 0; scancode < this.keys.length; scancode++) { + if (this.keys[scancode]) { + this.keys[scancode] = false; + this.legacy.key(scancode, 0, false, false, timestampNs); + } + } + for (int button = 1; button < this.buttons.length; button++) { + if (this.buttons[button]) { + this.buttons[button] = false; + this.legacy.button(button, false, this.mouseX, this.mouseY, timestampNs); + } + } + } + + private void refreshSize() { + try (MemoryStack stack = MemoryStack.stackPush()) { + IntBuffer w = stack.mallocInt(1); + IntBuffer h = stack.mallocInt(1); + if (SDLVideo.SDL_GetWindowSize(this.handle, w, h)) { + this.width = w.get(0); + this.height = h.get(0); + } + if (SDLVideo.SDL_GetWindowSizeInPixels(this.handle, w, h)) { + this.pixelWidth = w.get(0); + this.pixelHeight = h.get(0); + } + } + } + + synchronized boolean keyDown(int scancode) { + return scancode >= 0 && scancode < this.keys.length && this.keys[scancode]; + } + + synchronized boolean mouseButtonDown(int button) { + return button > 0 && button < this.buttons.length && this.buttons[button]; + } + + synchronized float mouseX() { + return mouseX; + } + + synchronized float mouseY() { + return mouseY; + } + + synchronized void mousePosition(float x, float y) { + SDLMouse.SDL_WarpMouseInWindow(this.handle, x, y); + this.mouseX = x; + this.mouseY = y; + this.mouseWarped = !this.mouseGrabbed; + } + + synchronized void grabMouse(boolean grab) { + SDL.check(SDLMouse.SDL_SetWindowRelativeMouseMode(handle, grab), "SDL_SetWindowRelativeMouseMode"); + this.mouseGrabbed = grab; + } + + synchronized boolean mouseGrabbed() { + return mouseGrabbed; + } + + WindowBridge.KeyEvent nextKeyEvent() { + return this.legacy.nextKey(); + } + + int queuedKeyEvents() { + return this.legacy.queuedKeys(); + } + + WindowBridge.MouseEvent nextMouseEvent() { + return this.legacy.nextMouse(); + } + + int queuedMouseEvents() { + return this.legacy.queuedMice(); + } + + float takeMouseDeltaX() { + return this.legacy.takeDeltaX(); + } + + float takeMouseDeltaY() { + return this.legacy.takeDeltaY(); + } + + float takeMouseWheel() { + return this.legacy.takeWheel(); + } + + @Override + public synchronized void close() { + if (this.closed) { + return; + } + this.closed = true; + Arrays.fill(this.keys, false); + Arrays.fill(this.buttons, false); + if (this.glContext != 0L) { + SDLVideo.SDL_GL_DestroyContext(this.glContext); + } + SDLVideo.SDL_DestroyWindow(this.handle); + if (main == this) { + main = null; + } + } + + public static final class Builder { + + private String title = "Window"; + private int width = 800; + private int height = 600; + private boolean resizable; + private boolean hidden; + private boolean fullscreen; + private boolean vsync; + private GLConfig gl; + + private Builder() { } + + public Builder title(String title) { + this.title = title; + return this; + } + + public Builder size(int width, int height) { + this.width = width; + this.height = height; + return this; + } + + public Builder resizable() { + resizable = true; + return this; + } + + public Builder hidden() { + this.hidden = true; + return this; + } + + public Builder fullscreen() { + this.fullscreen = true; + return this; + } + + public Builder vsync(boolean vsync) { + this.vsync = vsync; + return this; + } + + public Builder openGL() { + return openGL(_ -> { }); + } + + public Builder openGL(Consumer configure) { + this.gl = new GLConfig(); + configure.accept(this.gl); + return this; + } + + public Window build() { + synchronized (Window.class) { + if (main != null) { + throw new IllegalStateException("Cleanroom's SDL window already exists"); + } + return create(); + } + } + + private Window create() { + SDL.ensureVideo(); + long flags = 0L; + if (this.gl != null) { + this.gl.apply(); + flags |= SDLVideo.SDL_WINDOW_OPENGL; + } + if (this.resizable) { + flags |= SDLVideo.SDL_WINDOW_RESIZABLE; + } + if (this.hidden) { + flags |= SDLVideo.SDL_WINDOW_HIDDEN; + } + if (this.fullscreen) { + flags |= SDLVideo.SDL_WINDOW_FULLSCREEN; + } + long handle = SDL.checkHandle(SDLVideo.SDL_CreateWindow(this.title, this.width, this.height, flags), "SDL_CreateWindow"); + long context = 0L; + boolean created = false; + try { + if (this.gl != null) { + context = SDL.checkHandle(SDLVideo.SDL_GL_CreateContext(handle), "SDL_GL_CreateContext"); + SDL.check(SDLVideo.SDL_GL_MakeCurrent(handle, context), "SDL_GL_MakeCurrent"); + SDL.check(SDLVideo.SDL_GL_SetSwapInterval(this.vsync ? 1 : 0), "SDL_GL_SetSwapInterval"); + GL.createCapabilities(); + } + Window window = new Window(handle, context, this.title, this.width, this.height); + window.fullscreen = this.fullscreen; + window.refreshSize(); + main = window; + created = true; + return window; + } finally { + if (!created) { + GL.setCapabilities(null); + if (context != 0L) { + SDLVideo.SDL_GL_DestroyContext(context); + } + SDLVideo.SDL_DestroyWindow(handle); + } + } + } + } + + public static final class GLConfig { + + private static void attribute(int attribute, int value) { + SDL.check(SDLVideo.SDL_GL_SetAttribute(attribute, value), "SDL_GL_SetAttribute(" + attribute + ")"); + } + + private int major = 3; + private int minor = 2; + private boolean core; + private int depthBits = 24; + private int stencilBits = 8; + + private GLConfig() { } + + public GLConfig version(int major, int minor) { + this.major = major; + this.minor = minor; + return this; + } + + public GLConfig coreProfile() { + core = true; + return this; + } + + public GLConfig compatibilityProfile() { + core = false; + return this; + } + + public GLConfig depthBits(int depthBits) { + this.depthBits = depthBits; + return this; + } + + public GLConfig stencilBits(int stencilBits) { + this.stencilBits = stencilBits; + return this; + } + + private void apply() { + attribute(SDLVideo.SDL_GL_CONTEXT_MAJOR_VERSION, this.major); + attribute(SDLVideo.SDL_GL_CONTEXT_MINOR_VERSION, this.minor); + attribute(SDLVideo.SDL_GL_CONTEXT_PROFILE_MASK, core ? SDLVideo.SDL_GL_CONTEXT_PROFILE_CORE : SDLVideo.SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); + attribute(SDLVideo.SDL_GL_DOUBLEBUFFER, 1); + attribute(SDLVideo.SDL_GL_DEPTH_SIZE, depthBits); + attribute(SDLVideo.SDL_GL_STENCIL_SIZE, stencilBits); + } + + } +} diff --git a/module/forge/src/main/java/net/minecraftforge/fml/relauncher/FMLCorePlugin.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/FMLCorePlugin.java index 5fd23c16e..5c77d4f9d 100644 --- a/module/forge/src/main/java/net/minecraftforge/fml/relauncher/FMLCorePlugin.java +++ b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/FMLCorePlugin.java @@ -29,12 +29,12 @@ public class FMLCorePlugin implements IFMLLoadingPlugin public String[] getASMTransformerClass() { return new String[] { - "net.minecraftforge.fml.common.asm.transformers.SideTransformer", - "net.minecraftforge.fml.common.asm.transformers.EventSubscriptionTransformer", - "net.minecraftforge.fml.common.asm.transformers.EventSubscriberTransformer", - "net.minecraftforge.fml.common.asm.transformers.SoundEngineFixTransformer", - "net.minecraftforge.fml.common.asm.transformers.LWJGLTransformer", - }; + "net.minecraftforge.fml.common.asm.transformers.SideTransformer", + "net.minecraftforge.fml.common.asm.transformers.EventSubscriptionTransformer", + "net.minecraftforge.fml.common.asm.transformers.EventSubscriberTransformer", + "net.minecraftforge.fml.common.asm.transformers.SoundEngineFixTransformer", + "net.minecraftforge.fml.common.asm.transformers.LWJGLTransformer", + }; } @Override diff --git a/module/minecraft/patches/net/minecraft/client/Minecraft.java.patch b/module/minecraft/patches/net/minecraft/client/Minecraft.java.patch index 1d2b83cd6..3f253e989 100644 --- a/module/minecraft/patches/net/minecraft/client/Minecraft.java.patch +++ b/module/minecraft/patches/net/minecraft/client/Minecraft.java.patch @@ -16,7 +16,17 @@ this.isDemo = gameConfig.gameInfo.isDemo; this.displayWidth = gameConfig.displayInfo.width > 0 ? gameConfig.displayInfo.width : 1; this.displayHeight = gameConfig.displayInfo.height > 0 ? gameConfig.displayInfo.height : 1; -@@ -470,10 +470,10 @@ +@@ -455,7 +455,8 @@ + this.displayWidth = this.gameSettings.overrideWidth; + this.displayHeight = this.gameSettings.overrideHeight; + } +- ++ com.cleanroommc.client.input.Window window = com.cleanroommc.client.input.Window.builder().title("Cleanroom").size(this.displayWidth, this.displayHeight).resizable().vsync(this.gameSettings.enableVsync).openGL().build(); ++ com.cleanroommc.client.input.CleanroomWindowBridge.install(window); + LOGGER.info("LWJGL Version: {}", Sys.getVersion()); + this.setWindowIcon(); + this.setInitialDisplayMode(); +@@ -470,10 +471,10 @@ this.resourceManager = new SimpleReloadableResourceManager(this.metadataSerializer); this.languageManager = new LanguageManager(this.metadataSerializer, this.gameSettings.language); this.resourceManager.registerReloadListener(this.languageManager); @@ -29,7 +39,7 @@ this.skinManager = new SkinManager(this.renderEngine, new File(this.fileAssets, "skins"), this.sessionService); this.saveLoader = new AnvilSaveConverter(new File(this.gameDir, "saves"), this.dataFixer); this.soundHandler = new SoundHandler(this.resourceManager, this.gameSettings); -@@ -491,6 +491,8 @@ +@@ -491,6 +492,8 @@ this.resourceManager.registerReloadListener(new GrassColorReloadListener()); this.resourceManager.registerReloadListener(new FoliageColorReloadListener()); this.mouseHelper = new MouseHelper(); @@ -38,7 +48,7 @@ this.checkGLError("Pre startup"); GlStateManager.enableTexture2D(); GlStateManager.shadeModel(7425); -@@ -504,19 +506,24 @@ +@@ -504,19 +507,24 @@ GlStateManager.loadIdentity(); GlStateManager.matrixMode(5888); this.checkGLError("Startup"); @@ -63,7 +73,7 @@ this.entityRenderer = new EntityRenderer(this, this.resourceManager); this.resourceManager.registerReloadListener(this.entityRenderer); this.blockRenderDispatcher = new BlockRendererDispatcher(this.modelManager.getBlockModelShapes(), this.blockColors); -@@ -527,18 +534,25 @@ +@@ -527,18 +535,25 @@ this.resourceManager.registerReloadListener(this.searchTreeManager); GlStateManager.viewport(0, 0, this.displayWidth, this.displayHeight); this.effectRenderer = new ParticleManager(this.world, this.renderEngine); @@ -92,12 +102,9 @@ if (this.gameSettings.fullScreen && !this.fullscreen) { this.toggleFullscreen(); } -@@ -597,26 +611,14 @@ - this.metadataSerializer.registerMetadataSectionType(new LanguageMetadataSectionSerializer(), LanguageMetadataSection.class); - } +@@ -599,24 +614,12 @@ -- private void createDisplay() throws LWJGLException { -+ private void createDisplay() { + private void createDisplay() throws LWJGLException { Display.setResizable(true); - Display.setTitle("Minecraft 1.12.2"); + Display.setTitle("Cleanroom"); @@ -125,7 +132,7 @@ } private void setInitialDisplayMode() throws LWJGLException { -@@ -679,6 +681,7 @@ +@@ -679,6 +682,7 @@ } private void startTimerHackThread() { @@ -133,7 +140,7 @@ Thread thread = new Thread("Timer hack thread") { @Override public void run() { -@@ -691,6 +694,7 @@ +@@ -691,6 +695,7 @@ } }; thread.setDaemon(true); @@ -141,7 +148,7 @@ thread.start(); } -@@ -704,22 +708,26 @@ +@@ -704,22 +709,26 @@ File file1 = new File(getMinecraft().gameDir, "crash-reports"); File file2 = new File(file1, "crash-" + new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss").format(new Date()) + "-client.txt"); Bootstrap.printToSYSOUT(crashReportIn.getCompleteReport()); @@ -171,7 +178,7 @@ public void refreshResources() { List list = Lists.newArrayList(this.defaultResourcePacks); if (this.integratedServer != null) { -@@ -902,16 +910,22 @@ +@@ -902,16 +911,22 @@ * @param guiScreenIn The {@link GuiScreen} to display. If it is {@code null}, any open GUI will be closed. */ public void displayGuiScreen(@Nullable GuiScreen guiScreenIn) { @@ -198,7 +205,15 @@ if (guiScreenIn instanceof GuiMainMenu || guiScreenIn instanceof GuiMultiplayer) { this.gameSettings.showDebugInfo = false; this.ingameGUI.getChatGUI().clearChatMessages(true); -@@ -999,7 +1013,7 @@ +@@ -963,6 +978,7 @@ + this.soundHandler.unloadSounds(); + } finally { + Display.destroy(); ++ com.cleanroommc.client.input.SDL.shutdown(); + if (!this.hasCrashed) { + System.exit(0); + } +@@ -999,7 +1015,7 @@ long i1 = System.nanoTime() - l; this.checkGLError("Pre render"); this.profiler.endStartSection("sound"); @@ -207,7 +222,7 @@ this.profiler.endSection(); this.profiler.startSection("render"); GlStateManager.pushMatrix(); -@@ -1009,11 +1023,13 @@ +@@ -1009,11 +1025,13 @@ GlStateManager.enableTexture2D(); this.profiler.endSection(); if (!this.skipRenderWorld) { @@ -221,7 +236,7 @@ } this.profiler.endSection(); -@@ -1308,9 +1324,9 @@ +@@ -1308,9 +1326,9 @@ if (this.leftClickCounter <= 0 && !this.player.isHandActive()) { if (leftClick && this.objectMouseOver != null && this.objectMouseOver.typeOfHit == RayTraceResult.Type.BLOCK) { BlockPos blockpos = this.objectMouseOver.getBlockPos(); @@ -234,7 +249,7 @@ this.player.swingArm(EnumHand.MAIN_HAND); } } else { -@@ -1333,7 +1349,8 @@ +@@ -1333,7 +1351,8 @@ break; case BLOCK: BlockPos blockpos = this.objectMouseOver.getBlockPos(); @@ -244,7 +259,7 @@ this.playerController.clickBlock(blockpos, this.objectMouseOver.sideHit); break; } -@@ -1343,6 +1360,7 @@ +@@ -1343,6 +1362,7 @@ } this.player.resetCooldown(); @@ -252,7 +267,7 @@ } this.player.swingArm(EnumHand.MAIN_HAND); -@@ -1399,6 +1417,7 @@ +@@ -1399,6 +1419,7 @@ } } @@ -260,18 +275,19 @@ if (!itemstack.isEmpty() && this.playerController.processRightClick(this.player, this.world, enumhand) == EnumActionResult.SUCCESS) { this.entityRenderer.itemRenderer.resetEquippedProgress(enumhand); -@@ -1411,6 +1430,10 @@ +@@ -1411,6 +1432,11 @@ /** Toggles fullscreen mode. */ public void toggleFullscreen() { + if (net.minecraftforge.common.ForgeEarlyConfig.WINDOW_BORDERLESS_REPLACES_FULLSCREEN) { -+ Display.toggleBorderless(); ++ com.cleanroommc.client.input.Window window = com.cleanroommc.client.input.Window.main(); ++ if (window != null) window.borderless(!window.borderless()); + return; + } try { this.fullscreen = !this.fullscreen; this.gameSettings.fullScreen = this.fullscreen; -@@ -1445,6 +1468,10 @@ +@@ -1445,6 +1471,10 @@ } Display.setFullscreen(this.fullscreen); @@ -282,7 +298,7 @@ Display.setVSyncEnabled(this.gameSettings.enableVsync); this.updateDisplay(); } catch (Exception exception) { -@@ -1483,6 +1510,8 @@ +@@ -1483,6 +1513,8 @@ this.rightClickDelayTimer--; } @@ -291,7 +307,7 @@ this.profiler.startSection("gui"); if (!this.isGamePaused) { this.ingameGUI.updateTick(); -@@ -1632,6 +1661,7 @@ +@@ -1632,6 +1664,7 @@ } this.profiler.endSection(); @@ -299,7 +315,7 @@ this.systemTime = getSystemTime(); } -@@ -1705,6 +1735,7 @@ +@@ -1705,6 +1738,7 @@ } } } @@ -307,7 +323,7 @@ } this.processKeyBinds(); -@@ -1896,6 +1927,8 @@ +@@ -1896,6 +1930,8 @@ private void runTickMouse() throws IOException { while (Mouse.next()) { @@ -316,7 +332,7 @@ int i = Mouse.getEventButton(); KeyBinding.setKeyBindState(i - 100, Mouse.getEventButtonState()); if (Mouse.getEventButtonState()) { -@@ -1931,6 +1964,7 @@ +@@ -1931,6 +1967,7 @@ this.currentScreen.handleMouseInput(); } } @@ -324,7 +340,7 @@ } } -@@ -1949,6 +1983,7 @@ +@@ -1949,6 +1986,7 @@ /** Arguments: World foldername, World ingame name, WorldSettings */ public void launchIntegratedServer(String folderName, String worldName, @Nullable WorldSettings worldSettingsIn) { @@ -332,7 +348,7 @@ this.loadWorld(null); System.gc(); ISaveHandler isavehandler = this.saveLoader.getSaveLoader(folderName, false); -@@ -1990,6 +2025,11 @@ +@@ -1990,6 +2028,11 @@ this.loadingScreen.displaySavingString(I18n.format("menu.loadingLevel")); while (!this.integratedServer.serverIsInRunLoop()) { @@ -344,7 +360,7 @@ String s = this.integratedServer.getUserMessage(); if (s != null) { this.loadingScreen.displayLoadingString(I18n.format(s)); -@@ -2007,8 +2047,13 @@ +@@ -2007,8 +2050,13 @@ SocketAddress socketaddress = this.integratedServer.getNetworkSystem().addLocalEndpoint(); NetworkManager networkmanager = NetworkManager.provideLocalClient(socketaddress); networkmanager.setNetHandler(new NetHandlerLoginClient(networkmanager, this, null)); @@ -360,7 +376,7 @@ this.networkManager = networkmanager; } -@@ -2019,6 +2064,8 @@ +@@ -2019,6 +2067,8 @@ /** par2Str is displayed on the loading screen to the user unloads the current world first */ public void loadWorld(@Nullable WorldClient worldClientIn, String loadingMessage) { @@ -369,7 +385,7 @@ if (worldClientIn == null) { NetHandlerPlayClient nethandlerplayclient = this.getConnection(); if (nethandlerplayclient != null) { -@@ -2027,6 +2074,14 @@ +@@ -2027,6 +2077,14 @@ if (this.integratedServer != null && this.integratedServer.isAnvilFileSet()) { this.integratedServer.initiateShutdown(); @@ -384,7 +400,7 @@ } this.integratedServer = null; -@@ -2047,6 +2102,7 @@ +@@ -2047,6 +2105,7 @@ this.ingameGUI.resetPlayersOverlayFooterHeader(); this.setServerData(null); this.integratedServerIsRunning = false; @@ -392,7 +408,7 @@ } this.soundHandler.stopSounds(); -@@ -2060,6 +2116,8 @@ +@@ -2060,6 +2119,8 @@ } TileEntityRendererDispatcher.instance.setWorld(worldClientIn); @@ -401,7 +417,7 @@ if (worldClientIn != null) { if (!this.integratedServerIsRunning) { AuthenticationService authenticationservice = new YggdrasilAuthenticationService(this.proxy, UUID.randomUUID().toString()); -@@ -2112,6 +2170,7 @@ +@@ -2112,6 +2173,7 @@ this.player == null ? new RecipeBook() : this.player.getRecipeBook() ); this.player.getDataManager().setEntryValues(entityplayersp.getDataManager().getAll()); @@ -409,7 +425,7 @@ this.player.dimension = dimension; this.renderViewEntity = this.player; this.player.preparePlayerToSpawn(); -@@ -2153,110 +2212,8 @@ +@@ -2153,110 +2215,8 @@ /** Called when user clicked he's mouse middle button (pick block) */ private void middleClickMouse() { if (this.objectMouseOver != null && this.objectMouseOver.typeOfHit != RayTraceResult.Type.MISS) { @@ -522,7 +538,7 @@ } } -@@ -2293,7 +2250,11 @@ +@@ -2293,7 +2253,11 @@ }); theCrash.getCategory().addDetail("OpenGL", new ICrashReportDetail() { public String call() { @@ -535,7 +551,7 @@ } }); theCrash.getCategory().addDetail("GL Caps", new ICrashReportDetail() { -@@ -2372,6 +2333,7 @@ +@@ -2372,6 +2336,7 @@ return instance; } @@ -543,7 +559,7 @@ public ListenableFuture scheduleResourcesRefresh() { return this.addScheduledTask(new Runnable() { @Override -@@ -2536,15 +2498,8 @@ +@@ -2536,15 +2501,8 @@ /** Used in the usage snooper. */ public static int getGLMaximumTextureSize() { @@ -561,7 +577,7 @@ } /** Returns whether snooping is enabled or not. */ -@@ -2658,6 +2613,9 @@ +@@ -2658,6 +2616,9 @@ } if (this.player != null) { @@ -571,7 +587,7 @@ if (this.player.world.provider instanceof WorldProviderHell) { return MusicTicker.MusicType.NETHER; } else if (this.player.world.provider instanceof WorldProviderEnd) { -@@ -2677,9 +2635,9 @@ +@@ -2677,9 +2638,9 @@ if (i != 0 && !Keyboard.isRepeatEvent()) { if (!(this.currentScreen instanceof GuiControls) || ((GuiControls)this.currentScreen).time <= getSystemTime() - 20L) { if (Keyboard.getEventKeyState()) { @@ -583,7 +599,7 @@ this.ingameGUI .getChatGUI() .printChatMessage(ScreenShotHelper.saveScreenshot(this.gameDir, this.displayWidth, this.displayHeight, this.framebuffer)); -@@ -2691,7 +2649,7 @@ +@@ -2691,7 +2652,7 @@ ((ScreenChatOptions)this.currentScreen).updateNarratorButton(); } } @@ -592,7 +608,7 @@ } } } -@@ -2720,7 +2678,7 @@ +@@ -2720,7 +2681,7 @@ try { return Futures.immediateFuture(callableToSchedule.call()); } catch (Exception exception) { @@ -601,7 +617,7 @@ } } else { ListenableFutureTask listenablefuturetask = ListenableFutureTask.create(callableToSchedule); -@@ -2802,7 +2760,11 @@ +@@ -2802,7 +2763,11 @@ return this.blockColors; } @@ -614,7 +630,7 @@ public boolean isReducedDebug() { return this.player != null && this.player.hasReducedDebug() || this.gameSettings.reducedDebugInfo; } -@@ -2814,4 +2776,8 @@ +@@ -2814,4 +2779,8 @@ public Tutorial getTutorial() { return this.tutorial; } diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiSlot.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiSlot.java.patch index cfb53291c..fd24f0eb0 100644 --- a/module/minecraft/patches/net/minecraft/client/gui/GuiSlot.java.patch +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiSlot.java.patch @@ -30,7 +30,7 @@ int k = this.left + this.width / 2 - this.getListWidth() / 2 + 2; int l = this.top + 4 - (int)this.amountScrolled; if (this.hasListHeader) { -@@ -438,4 +419,51 @@ +@@ -438,4 +419,50 @@ public int getSlotHeight() { return this.slotHeight; } diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiTextField.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiTextField.java.patch index 4c48ea26e..c51f10a12 100644 --- a/module/minecraft/patches/net/minecraft/client/gui/GuiTextField.java.patch +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiTextField.java.patch @@ -1,6 +1,6 @@ --- original/net/minecraft/client/gui/GuiTextField.java +++ modified/net/minecraft/client/gui/GuiTextField.java -@@ -519,6 +519,10 @@ +@@ -519,6 +519,11 @@ } this.isFocused = isFocusedIn; @@ -12,7 +12,7 @@ if (Minecraft.getMinecraft().currentScreen != null) { Minecraft.getMinecraft().currentScreen.setFocused(isFocusedIn); } -@@ -592,4 +596,8 @@ +@@ -592,4 +597,8 @@ public void setVisible(boolean isVisible) { this.visible = isVisible; } From fc30f04c8c207649edf1e133a4b7c39fb477430b Mon Sep 17 00:00:00 2001 From: Rongmario Date: Sat, 15 Aug 2026 01:02:16 +0100 Subject: [PATCH 35/99] SplashProgress... --- .../fml/client/SplashProgress.java | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/module/forge/src/main/java/net/minecraftforge/fml/client/SplashProgress.java b/module/forge/src/main/java/net/minecraftforge/fml/client/SplashProgress.java index 61eefc864..ab0d23cb3 100644 --- a/module/forge/src/main/java/net/minecraftforge/fml/client/SplashProgress.java +++ b/module/forge/src/main/java/net/minecraftforge/fml/client/SplashProgress.java @@ -22,6 +22,9 @@ import static org.lwjgl.opengl.GL11.*; import static org.lwjgl.opengl.GL12.*; +import com.cleanroommc.client.input.SharedGLContext; +import com.cleanroommc.client.input.Window; + import java.awt.image.BufferedImage; import java.io.File; import java.io.FileInputStream; @@ -73,8 +76,6 @@ import org.lwjgl.BufferUtils; import org.lwjgl.LWJGLException; import org.lwjgl.opengl.Display; -import org.lwjgl.opengl.Drawable; -import org.lwjgl.opengl.SharedDrawable; import org.lwjgl.util.glu.GLU; import org.lwjgl.input.Keyboard; @@ -85,7 +86,7 @@ @SuppressWarnings("serial") public class SplashProgress { - private static Drawable d; + private static SharedGLContext shared; private static volatile boolean pause = false; private static volatile boolean done = false; private static Thread thread; @@ -236,11 +237,11 @@ public String getLabel() try { - d = new SharedDrawable(Display.getDrawable()); - Display.getDrawable().releaseContext(); - d.makeCurrent(); + shared = SharedGLContext.create(Window.main()); + Display.releaseContext(); + shared.makeCurrent(); } - catch (LWJGLException e) + catch (LWJGLException | RuntimeException e) { FMLLog.log.error("Error starting SplashProgress:", e); disableSplash(e); @@ -610,7 +611,7 @@ private void setGL() lock.lock(); try { - Display.getDrawable().makeCurrent(); + Display.makeCurrent(); } catch (LWJGLException e) { @@ -637,7 +638,7 @@ private void clearGL() glAlphaFunc(GL_GREATER, .1f); try { - Display.getDrawable().releaseContext(); + Display.releaseContext(); } catch (LWJGLException e) { @@ -701,8 +702,8 @@ public static void pause() lock.lock(); try { - d.releaseContext(); - Display.getDrawable().makeCurrent(); + shared.release(); + Display.makeCurrent(); } catch (LWJGLException e) { @@ -722,8 +723,8 @@ public static void resume() pause = false; try { - Display.getDrawable().releaseContext(); - d.makeCurrent(); + Display.releaseContext(); + shared.makeCurrent(); } catch (LWJGLException e) { @@ -742,11 +743,13 @@ public static void finish() done = true; thread.join(); glFlush(); // process any remaining GL calls before releaseContext (prevents missing textures on mac) - d.releaseContext(); - Display.getDrawable().makeCurrent(); + shared.release(); + Display.makeCurrent(); fontTexture.delete(); logoTexture.delete(); forgeTexture.delete(); + shared.close(); + shared = null; } catch (Exception e) { @@ -1093,4 +1096,4 @@ private static int bytesToMb(long bytes) { return (int) (bytes / 1024L / 1024L); } -} \ No newline at end of file +} From 7970b2a81a4095f7d6391d6254720da98af2dbe0 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Sat, 15 Aug 2026 22:11:45 +0100 Subject: [PATCH 36/99] Fixed `World#setBlockState` hunk regression --- .../net/minecraft/world/World.java.patch | 200 ++++++++++-------- 1 file changed, 112 insertions(+), 88 deletions(-) diff --git a/module/minecraft/patches/net/minecraft/world/World.java.patch b/module/minecraft/patches/net/minecraft/world/World.java.patch index d056cc090..4240d8cd4 100644 --- a/module/minecraft/patches/net/minecraft/world/World.java.patch +++ b/module/minecraft/patches/net/minecraft/world/World.java.patch @@ -57,35 +57,59 @@ } public boolean isBlockLoaded(BlockPos pos) { -@@ -344,6 +362,27 @@ - return true; - } +@@ -316,22 +334,37 @@ + } -+ // Split off from original setBlockState(BlockPos, IBlockState, int) method in order to directly send client and physic updates -+ public void markAndNotifyBlock(BlockPos pos, @Nullable Chunk chunk, IBlockState iblockstate, IBlockState newState, int flags) { -+ Block block = newState.getBlock(); { -+ { -+ if ((flags & 2) != 0 && (!this.isRemote || (flags & 4) == 0) && (chunk == null || chunk.isPopulated())) { -+ this.notifyBlockUpdate(pos, iblockstate, newState, flags); -+ } -+ -+ if (!this.isRemote && (flags & 1) != 0) { -+ this.notifyNeighborsRespectDebug(pos, iblockstate.getBlock(), true); -+ -+ if (newState.hasComparatorInputOverride()) { -+ this.updateComparatorOutputLevel(pos, block); -+ } -+ } else if (!this.isRemote && (flags & 16) == 0) { -+ this.updateObservingBlocksAt(pos, block); -+ } -+ } + Chunk chunk = this.getChunk(pos); +- Block block = newState.getBlock(); ++ pos = pos.toImmutable(); // Forge - prevent mutable BlockPos leaks ++ net.minecraftforge.common.util.BlockSnapshot blockSnapshot = null; ++ if (this.captureBlockSnapshots && !this.isRemote) { ++ blockSnapshot = net.minecraftforge.common.util.BlockSnapshot.getBlockSnapshot(this, pos, flags); ++ this.capturedBlockSnapshots.add(blockSnapshot); ++ } ++ IBlockState oldState = getBlockState(pos); ++ int oldLight = oldState.getLightValue(this, pos); ++ int oldOpacity = oldState.getLightOpacity(this, pos); + IBlockState iblockstate = chunk.setBlockState(pos, newState); + if (iblockstate == null) { ++ if (blockSnapshot != null) this.capturedBlockSnapshots.remove(blockSnapshot); + return false; + } +- +- if (newState.getLightOpacity() != iblockstate.getLightOpacity() || newState.getLightValue() != iblockstate.getLightValue()) { ++ if (newState.getLightOpacity(this, pos) != oldOpacity || newState.getLightValue(this, pos) != oldLight) { + this.profiler.startSection("checkLight"); + this.checkLight(pos); + this.profiler.endSection(); + } ++ if (blockSnapshot == null) { // Don't notify clients or update physics while capturing blockstates ++ this.markAndNotifyBlock(pos, chunk, iblockstate, newState, flags); + } ++ return true; + } -+ - public boolean setBlockToAir(BlockPos pos) { - return this.setBlockState(pos, Blocks.AIR.getDefaultState(), 3); + +- if ((flags & 2) != 0 && (!this.isRemote || (flags & 4) == 0) && chunk.isPopulated()) { ++ // Split off from original setBlockState(BlockPos, IBlockState, int) method in order to directly send client and physic updates ++ public void markAndNotifyBlock(BlockPos pos, @Nullable Chunk chunk, IBlockState iblockstate, IBlockState newState, int flags) { ++ Block block = newState.getBlock(); ++ if ((flags & 2) != 0 && (!this.isRemote || (flags & 4) == 0) && (chunk == null || chunk.isPopulated())) { + this.notifyBlockUpdate(pos, iblockstate, newState, flags); + } +- + if (!this.isRemote && (flags & 1) != 0) { + this.notifyNeighborsRespectDebug(pos, iblockstate.getBlock(), true); + if (newState.hasComparatorInputOverride()) { +@@ -340,8 +373,6 @@ + } else if (!this.isRemote && (flags & 16) == 0) { + this.updateObservingBlocksAt(pos, block); + } +- +- return true; } -@@ -352,7 +391,8 @@ + + public boolean setBlockToAir(BlockPos pos) { +@@ -352,7 +383,8 @@ public boolean destroyBlock(BlockPos pos, boolean dropBlock) { IBlockState iblockstate = this.getBlockState(pos); Block block = iblockstate.getBlock(); @@ -95,7 +119,7 @@ return false; } -@@ -431,6 +471,9 @@ +@@ -431,6 +463,9 @@ } public void notifyNeighborsOfStateChange(BlockPos pos, Block blockType, boolean updateObservers) { @@ -105,7 +129,7 @@ this.neighborChanged(pos.west(), blockType, pos); this.neighborChanged(pos.east(), blockType, pos); this.neighborChanged(pos.down(), blockType, pos); -@@ -443,6 +486,11 @@ +@@ -443,6 +478,11 @@ } public void notifyNeighborsOfStateExcept(BlockPos pos, Block blockType, EnumFacing skipSide) { @@ -117,7 +141,7 @@ if (skipSide != EnumFacing.WEST) { this.neighborChanged(pos.west(), blockType, pos); } -@@ -480,19 +528,16 @@ +@@ -480,19 +520,16 @@ crashreportcategory.addDetail( "Source block type", new ICrashReportDetail() { @@ -145,7 +169,7 @@ ); CrashReportCategory.addBlockInfo(crashreportcategory, pos, iblockstate); throw new ReportedException(crashreport); -@@ -503,28 +548,26 @@ +@@ -503,28 +540,26 @@ public void observedNeighborChanged(BlockPos pos, final Block changedBlock, BlockPos changedBlockPos) { if (!this.isRemote) { IBlockState iblockstate = this.getBlockState(pos); @@ -185,7 +209,7 @@ ); CrashReportCategory.addBlockInfo(crashreportcategory, pos, iblockstate); throw new ReportedException(crashreport); -@@ -544,21 +587,23 @@ +@@ -544,21 +579,23 @@ public boolean canBlockSeeSky(BlockPos pos) { if (pos.getY() >= this.getSeaLevel()) { return this.canSeeSky(pos); @@ -220,7 +244,7 @@ } public int getLight(BlockPos pos) { -@@ -768,7 +813,7 @@ +@@ -768,7 +805,7 @@ /** Checks whether its daytime by seeing if the light subtracted from the skylight is less than 4 */ public boolean isDaytime() { @@ -229,7 +253,7 @@ } /** ray traces all blocks, including non-collideable ones */ -@@ -942,6 +987,13 @@ +@@ -942,6 +979,13 @@ float volume, float pitch ) { @@ -243,7 +267,7 @@ for (int i = 0; i < this.eventListeners.size(); i++) { this.eventListeners.get(i).playSoundToAllNearExcept(player, soundIn, category, x, y, z, volume, pitch); } -@@ -1051,12 +1103,18 @@ +@@ -1051,12 +1095,18 @@ /** adds a lightning bolt to the list of lightning bolts in this world. */ public boolean addWeatherEffect(Entity entityIn) { @@ -262,7 +286,7 @@ int i = MathHelper.floor(entityIn.posX / 16.0); int j = MathHelper.floor(entityIn.posZ / 16.0); boolean flag = entityIn.forceSpawn; -@@ -1068,6 +1126,8 @@ +@@ -1068,6 +1118,8 @@ return false; } @@ -271,7 +295,7 @@ if (entityIn instanceof EntityPlayer) { EntityPlayer entityplayer = (EntityPlayer)entityIn; this.playerEntities.add(entityplayer); -@@ -1084,12 +1144,14 @@ +@@ -1084,12 +1136,14 @@ for (int i = 0; i < this.eventListeners.size(); i++) { this.eventListeners.get(i).onEntityAdded(entityIn); } @@ -286,7 +310,7 @@ } /** Schedule the entity for removal during the next tick. Marks the entity dead in anticipation. */ -@@ -1134,8 +1196,6 @@ +@@ -1134,8 +1188,6 @@ this.eventListeners.add(listener); } @@ -295,7 +319,7 @@ public void removeEventListener(IWorldEventListener listener) { this.eventListeners.remove(listener); } -@@ -1162,6 +1222,7 @@ +@@ -1162,6 +1214,7 @@ IBlockState iblockstate = Blocks.STONE.getDefaultState(); BlockPos.PooledMutableBlockPos blockpos$pooledmutableblockpos = BlockPos.PooledMutableBlockPos.retain(); @@ -303,7 +327,7 @@ try { for (int k1 = i; k1 < j; k1++) { for (int l1 = i1; l1 < j1; l1++) { -@@ -1187,7 +1248,8 @@ +@@ -1187,7 +1240,8 @@ } iblockstate1.addCollisionBoxToList(this, blockpos$pooledmutableblockpos, aabb, outList, entityIn, false); @@ -313,7 +337,7 @@ return true; } } -@@ -1224,7 +1286,7 @@ +@@ -1224,7 +1278,7 @@ } } } @@ -322,7 +346,7 @@ return list; } -@@ -1255,19 +1317,36 @@ +@@ -1255,19 +1309,36 @@ /** Returns the amount of skylight subtracted for the current time */ public int calculateSkylightSubtracted(float partialTicks) { @@ -361,7 +385,7 @@ float f = this.getCelestialAngle(partialTicks); float f1 = 1.0F - (MathHelper.cos(f * (float) (Math.PI * 2)) * 2.0F + 0.2F); f1 = MathHelper.clamp(f1, 0.0F, 1.0F); -@@ -1280,6 +1359,11 @@ +@@ -1280,6 +1351,11 @@ /** Calculates the color for the skybox */ @SideOnly(Side.CLIENT) public Vec3d getSkyColor(Entity entityIn, float partialTicks) { @@ -373,7 +397,7 @@ float f = this.getCelestialAngle(partialTicks); float f1 = MathHelper.cos(f * (float) (Math.PI * 2)) * 2.0F + 0.5F; f1 = MathHelper.clamp(f1, 0.0F, 1.0F); -@@ -1287,9 +1371,7 @@ +@@ -1287,9 +1363,7 @@ int j = MathHelper.floor(entityIn.posY); int k = MathHelper.floor(entityIn.posZ); BlockPos blockpos = new BlockPos(i, j, k); @@ -384,7 +408,7 @@ float f3 = (l >> 16 & 0xFF) / 255.0F; float f4 = (l >> 8 & 0xFF) / 255.0F; float f5 = (l & 0xFF) / 255.0F; -@@ -1331,19 +1413,23 @@ +@@ -1331,19 +1405,23 @@ /** calls calculateCelestialAngle */ public float getCelestialAngle(float partialTicks) { @@ -411,7 +435,7 @@ /** Return getCelestialAngle()*2*PI */ public float getCelestialAngleRadians(float partialTicks) { float f = this.getCelestialAngle(partialTicks); -@@ -1352,6 +1438,11 @@ +@@ -1352,6 +1430,11 @@ @SideOnly(Side.CLIENT) public Vec3d getCloudColour(float partialTicks) { @@ -423,7 +447,7 @@ float f = this.getCelestialAngle(partialTicks); float f1 = MathHelper.cos(f * (float) (Math.PI * 2)) * 2.0F + 0.5F; f1 = MathHelper.clamp(f1, 0.0F, 1.0F); -@@ -1400,8 +1491,9 @@ +@@ -1400,8 +1483,9 @@ while (blockpos.getY() >= 0) { BlockPos blockpos1 = blockpos.down(); @@ -435,7 +459,7 @@ break; } -@@ -1414,6 +1506,11 @@ +@@ -1414,6 +1498,11 @@ /** How bright are stars in the sky */ @SideOnly(Side.CLIENT) public float getStarBrightness(float partialTicks) { @@ -447,7 +471,7 @@ float f = this.getCelestialAngle(partialTicks); float f1 = 1.0F - (MathHelper.cos(f * (float) (Math.PI * 2)) * 2.0F + 0.25F); f1 = MathHelper.clamp(f1, 0.0F, 1.0F); -@@ -1444,17 +1541,23 @@ +@@ -1444,17 +1533,23 @@ Entity entity = this.weatherEffects.get(i); try { @@ -471,7 +495,7 @@ throw new ReportedException(crashreport); } -@@ -1470,6 +1573,7 @@ +@@ -1470,6 +1565,7 @@ Entity entity1 = this.unloadedEntityList.get(k); int j = entity1.chunkCoordX; int k1 = entity1.chunkCoordZ; @@ -479,7 +503,7 @@ if (entity1.addedToChunk && this.isChunkLoaded(j, k1, true)) { this.getChunk(j, k1).removeEntity(entity1); } -@@ -1486,6 +1590,7 @@ +@@ -1486,6 +1582,7 @@ for (int i1 = 0; i1 < this.loadedEntityList.size(); i1++) { Entity entity2 = this.loadedEntityList.get(i1); Entity entity3 = entity2.getRidingEntity(); @@ -487,7 +511,7 @@ if (entity3 != null) { if (!entity3.isDead && entity3.isPassenger(entity2)) { continue; -@@ -1495,22 +1600,31 @@ +@@ -1495,22 +1592,31 @@ } this.profiler.startSection("tick"); @@ -519,7 +543,7 @@ if (entity2.addedToChunk && this.isChunkLoaded(l1, i2, true)) { this.getChunk(l1, i2).removeEntity(entity2); } -@@ -1523,28 +1637,46 @@ +@@ -1523,28 +1629,46 @@ } this.profiler.endStartSection("blockEntities"); @@ -571,7 +595,7 @@ throw new ReportedException(crashreport2); } } -@@ -1553,17 +1685,23 @@ +@@ -1553,17 +1677,23 @@ if (tileentity.isInvalid()) { iterator.remove(); this.loadedTileEntityList.remove(tileentity); @@ -596,7 +620,7 @@ if (!tileentity1.isInvalid()) { if (!this.loadedTileEntityList.contains(tileentity1)) { this.addTileEntity(tileentity1); -@@ -1589,10 +1727,16 @@ +@@ -1589,10 +1719,16 @@ } public boolean addTileEntity(TileEntity tile) { @@ -613,7 +637,7 @@ if (this.isRemote) { BlockPos blockpos = tile.getPos(); -@@ -1605,6 +1749,10 @@ +@@ -1605,6 +1741,10 @@ public void addTileEntities(Collection tileEntityCollection) { if (this.processingLoadedTiles) { @@ -624,7 +648,7 @@ this.addedTileEntityList.addAll(tileEntityCollection); } else { for (TileEntity tileentity : tileEntityCollection) { -@@ -1623,8 +1771,13 @@ +@@ -1623,8 +1763,13 @@ if (!(entityIn instanceof EntityPlayer)) { int i = MathHelper.floor(entityIn.posX); int j = MathHelper.floor(entityIn.posZ); @@ -640,7 +664,7 @@ return; } } -@@ -1639,6 +1792,7 @@ +@@ -1639,6 +1784,7 @@ if (entityIn.isRiding()) { entityIn.updateRidden(); } else { @@ -648,7 +672,7 @@ entityIn.onUpdate(); } } -@@ -1702,7 +1856,8 @@ +@@ -1702,7 +1848,8 @@ for (int i = 0; i < list.size(); i++) { Entity entity = list.get(i); @@ -658,7 +682,7 @@ return false; } } -@@ -1750,6 +1905,13 @@ +@@ -1750,6 +1897,13 @@ for (int l1 = k; l1 < l; l1++) { for (int i2 = i1; i2 < j1; i2++) { IBlockState iblockstate = this.getBlockState(blockpos$pooledmutableblockpos.setPos(k1, l1, i2)); @@ -672,7 +696,7 @@ if (iblockstate.getMaterial().isLiquid()) { blockpos$pooledmutableblockpos.release(); return true; -@@ -1779,6 +1941,9 @@ +@@ -1779,6 +1933,9 @@ if (block == Blocks.FIRE || block == Blocks.FLOWING_LAVA || block == Blocks.LAVA) { blockpos$pooledmutableblockpos.release(); return true; @@ -682,7 +706,7 @@ } } } -@@ -1798,41 +1963,53 @@ +@@ -1798,41 +1955,53 @@ int l = MathHelper.ceil(bb.maxY); int i1 = MathHelper.floor(bb.minZ); int j1 = MathHelper.ceil(bb.maxZ); @@ -759,7 +783,7 @@ } /** Returns true if the given bounding box contains the given material */ -@@ -1848,10 +2025,17 @@ +@@ -1848,10 +2017,17 @@ for (int k1 = i; k1 < j; k1++) { for (int l1 = k; l1 < l; l1++) { for (int i2 = i1; i2 < j1; i2++) { @@ -778,7 +802,7 @@ } } } -@@ -1870,6 +2054,7 @@ +@@ -1870,6 +2046,7 @@ @Nullable Entity entityIn, double x, double y, double z, float strength, boolean causesFire, boolean damagesTerrain ) { Explosion explosion = new Explosion(this, entityIn, x, y, z, strength, causesFire, damagesTerrain); @@ -786,7 +810,7 @@ explosion.doExplosionA(); explosion.doExplosionB(true); return explosion; -@@ -1967,23 +2152,29 @@ +@@ -1967,23 +2144,29 @@ } public void setTileEntity(BlockPos pos, @Nullable TileEntity tileEntityIn) { @@ -818,7 +842,7 @@ this.addTileEntity(tileEntityIn); } } -@@ -1995,6 +2186,8 @@ +@@ -1995,6 +2178,8 @@ if (tileentity != null && this.processingLoadedTiles) { tileentity.invalidate(); this.addedTileEntityList.remove(tileentity); @@ -827,7 +851,7 @@ } else { if (tileentity != null) { this.addedTileEntityList.remove(tileentity); -@@ -2004,6 +2197,7 @@ +@@ -2004,6 +2189,7 @@ this.getChunk(pos).removeTileEntity(pos); } @@ -835,7 +859,7 @@ } /** Adds the specified TileEntity to the pending removal list. */ -@@ -2024,7 +2218,7 @@ +@@ -2024,7 +2210,7 @@ Chunk chunk = this.chunkProvider.getLoadedChunk(pos.getX() >> 4, pos.getZ() >> 4); if (chunk != null && !chunk.isEmpty()) { IBlockState iblockstate = this.getBlockState(pos); @@ -844,7 +868,7 @@ } else { return _default; } -@@ -2043,6 +2237,7 @@ +@@ -2043,6 +2229,7 @@ public void setAllowedSpawnTypes(boolean hostile, boolean peaceful) { this.spawnHostileMobs = hostile; this.spawnPeacefulMobs = peaceful; @@ -852,7 +876,7 @@ } /** Runs a single tick for the world */ -@@ -2052,6 +2247,10 @@ +@@ -2052,6 +2239,10 @@ /** Called from World constructor to set rainingStrength and thunderingStrength */ protected void calculateInitialWeather() { @@ -863,7 +887,7 @@ if (this.worldInfo.isRaining()) { this.rainingStrength = 1.0F; if (this.worldInfo.isThundering()) { -@@ -2062,6 +2261,10 @@ +@@ -2062,6 +2253,10 @@ /** Updates all weather states. */ protected void updateWeather() { @@ -874,7 +898,7 @@ if (this.provider.hasSkyLight()) { if (!this.isRemote) { boolean flag = this.getGameRules().getBoolean("doWeatherCycle"); -@@ -2146,6 +2349,10 @@ +@@ -2146,6 +2341,10 @@ /** Checks to see if a given block is both water and cold enough to freeze. */ public boolean canBlockFreeze(BlockPos pos, boolean noWaterAdj) { @@ -885,7 +909,7 @@ Biome biome = this.getBiome(pos); float f = biome.getTemperature(pos); if (f >= 0.15F) { -@@ -2179,6 +2386,10 @@ +@@ -2179,6 +2378,10 @@ /** Checks to see if a given block can accumulate snow from it snowing */ public boolean canSnowAt(BlockPos pos, boolean checkLight) { @@ -896,7 +920,7 @@ Biome biome = this.getBiome(pos); float f = biome.getTemperature(pos); if (f >= 0.15F) { -@@ -2191,7 +2402,7 @@ +@@ -2191,7 +2394,7 @@ if (pos.getY() >= 0 && pos.getY() < 256 && this.getLightFor(EnumSkyBlock.BLOCK, pos) < 10) { IBlockState iblockstate = this.getBlockState(pos); @@ -905,7 +929,7 @@ return true; } } -@@ -2212,153 +2423,163 @@ +@@ -2212,153 +2415,163 @@ private int getRawLight(BlockPos pos, EnumSkyBlock lightType) { if (lightType == EnumSkyBlock.SKY && this.canSeeSky(pos)) { return 15; @@ -1179,7 +1203,7 @@ } /** Runs through the list of updates to run and ticks them */ -@@ -2384,10 +2605,10 @@ +@@ -2384,10 +2597,10 @@ /** Gets all entities within the specified AABB excluding the one passed into it. */ public List getEntitiesInAABBexcluding(@Nullable Entity entityIn, AxisAlignedBB boundingBox, @Nullable Predicate predicate) { List list = Lists.newArrayList(); @@ -1194,7 +1218,7 @@ for (int i1 = i; i1 <= j; i1++) { for (int j1 = k; j1 <= l; j1++) { -@@ -2430,10 +2651,10 @@ +@@ -2430,10 +2643,10 @@ } public List getEntitiesWithinAABB(Class clazz, AxisAlignedBB aabb, @Nullable Predicate filter) { @@ -1209,7 +1233,7 @@ List list = Lists.newArrayList(); for (int i1 = i; i1 < j; i1++) { -@@ -2499,10 +2720,11 @@ +@@ -2499,10 +2712,11 @@ } public void loadEntities(Collection entityCollection) { @@ -1224,7 +1248,7 @@ } } -@@ -2514,7 +2736,9 @@ +@@ -2514,7 +2728,9 @@ public boolean mayPlace(Block blockIn, BlockPos pos, boolean skipCollisionCheck, EnumFacing sidePlacedOn, @Nullable Entity placer) { IBlockState iblockstate = this.getBlockState(pos); AxisAlignedBB axisalignedbb = skipCollisionCheck ? null : blockIn.getDefaultState().getCollisionBoundingBox(this, pos); @@ -1235,7 +1259,7 @@ return false; } else { return iblockstate.getMaterial() == Material.CIRCUITS && blockIn == Blocks.ANVIL -@@ -2580,7 +2804,7 @@ +@@ -2580,7 +2796,7 @@ public int getRedstonePower(BlockPos pos, EnumFacing facing) { IBlockState iblockstate = this.getBlockState(pos); @@ -1244,7 +1268,7 @@ } public boolean isBlockPowered(BlockPos pos) { -@@ -2717,6 +2941,8 @@ +@@ -2717,6 +2933,8 @@ d2 *= MoreObjects.firstNonNull(playerToDouble.apply(entityplayer1), 1.0); } @@ -1253,7 +1277,7 @@ if ((maxYDistance < 0.0 || Math.abs(entityplayer1.posY - posY) < maxYDistance * maxYDistance) && (maxXZDistance < 0.0 || d1 < d2 * d2) && (d0 == -1.0 || d1 < d0)) { -@@ -2771,7 +2997,7 @@ +@@ -2771,7 +2989,7 @@ /** gets the random world seed */ public long getSeed() { @@ -1262,7 +1286,7 @@ } public long getTotalWorldTime() { -@@ -2779,17 +3005,18 @@ +@@ -2779,17 +2997,18 @@ } public long getWorldTime() { @@ -1284,7 +1308,7 @@ if (!this.getWorldBorder().contains(blockpos)) { blockpos = this.getHeight(new BlockPos(this.getWorldBorder().getCenterX(), 0.0, this.getWorldBorder().getCenterZ())); } -@@ -2798,7 +3025,7 @@ +@@ -2798,7 +3017,7 @@ } public void setSpawnPoint(BlockPos pos) { @@ -1293,7 +1317,7 @@ } /** spwans an entity and loads surrounding chunks */ -@@ -2815,11 +3042,16 @@ +@@ -2815,11 +3034,16 @@ } if (!this.loadedEntityList.contains(entityIn)) { @@ -1310,7 +1334,7 @@ return true; } -@@ -2907,8 +3139,7 @@ +@@ -2907,8 +3131,7 @@ } public boolean isBlockinHighHumidity(BlockPos pos) { @@ -1320,7 +1344,7 @@ } @Nullable -@@ -2960,12 +3191,12 @@ +@@ -2960,12 +3183,12 @@ /** Returns maximum world height. */ public int getHeight() { @@ -1335,7 +1359,7 @@ } /** puts the World Random seed to a specific state dependant on the inputs */ -@@ -2978,7 +3209,7 @@ +@@ -2978,7 +3201,7 @@ /** Returns horizon height for use in rendering the sky. */ @SideOnly(Side.CLIENT) public double getHorizon() { @@ -1344,7 +1368,7 @@ } /** Adds some basic stats of the world to the given crash report. */ -@@ -3032,17 +3263,18 @@ +@@ -3032,17 +3255,18 @@ } public void updateComparatorOutputLevel(BlockPos pos, Block blockIn) { @@ -1369,7 +1393,7 @@ } } } -@@ -3098,6 +3330,107 @@ +@@ -3098,6 +3322,107 @@ return i >= -128 && i <= 128 && j >= -128 && j <= 128; } From 565dd6c8c7aacad18338c228bb7ab48fee61a2ff Mon Sep 17 00:00:00 2001 From: Rongmario Date: Sat, 15 Aug 2026 22:13:34 +0100 Subject: [PATCH 37/99] Fixed `WorldGenTaiga1` & `WorldGenTaiga2` hunk regressions --- .../minecraft/world/gen/feature/WorldGenTaiga1.java.patch | 5 +++-- .../minecraft/world/gen/feature/WorldGenTaiga2.java.patch | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenTaiga1.java.patch b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenTaiga1.java.patch index e7227e00d..083d6a4e3 100644 --- a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenTaiga1.java.patch +++ b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenTaiga1.java.patch @@ -24,16 +24,17 @@ int k2 = 0; for (int l2 = position.getY() + i; l2 >= position.getY() + j; l2--) { -@@ -72,7 +74,7 @@ +@@ -72,7 +74,8 @@ int j2 = i2 - position.getZ(); if (Math.abs(k3) != k2 || Math.abs(j2) != k2 || k2 <= 0) { BlockPos blockpos = new BlockPos(j3, l2, i2); - if (!worldIn.getBlockState(blockpos).isFullBlock()) { ++ state = worldIn.getBlockState(blockpos); + if (state.getBlock().canBeReplacedByLeaves(state, worldIn, blockpos)) { this.setBlockAndNotifyAdequately(worldIn, blockpos, LEAF); } } -@@ -87,8 +89,9 @@ +@@ -87,8 +90,9 @@ } for (int i3 = 0; i3 < i - 1; i3++) { diff --git a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenTaiga2.java.patch b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenTaiga2.java.patch index 897ddfa8c..1e687a21c 100644 --- a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenTaiga2.java.patch +++ b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenTaiga2.java.patch @@ -41,16 +41,17 @@ int i3 = rand.nextInt(2); int j3 = 1; int k3 = 0; -@@ -79,7 +83,7 @@ +@@ -79,7 +83,8 @@ int l2 = k2 - position.getZ(); if (Math.abs(j2) != i3 || Math.abs(l2) != i3 || i3 <= 0) { BlockPos blockpos = new BlockPos(i2, j4, k2); - if (!worldIn.getBlockState(blockpos).isFullBlock()) { ++ state = worldIn.getBlockState(blockpos); + if (state.getBlock().canBeReplacedByLeaves(state, worldIn, blockpos)) { this.setBlockAndNotifyAdequately(worldIn, blockpos, LEAF); } } -@@ -100,8 +104,8 @@ +@@ -100,8 +105,8 @@ int i4 = rand.nextInt(3); for (int k4 = 0; k4 < i - i4; k4++) { From 38e0d054c2c6412e148c20845a9f3ca172070e7c Mon Sep 17 00:00:00 2001 From: Rongmario Date: Sat, 15 Aug 2026 22:14:29 +0100 Subject: [PATCH 38/99] Fixed `WorldGenTrees` patch regression --- .../gen/feature/WorldGenTrees.java.patch | 46 ++++++++++++++++--- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenTrees.java.patch b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenTrees.java.patch index 966580f05..ef4cc3a00 100644 --- a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenTrees.java.patch +++ b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenTrees.java.patch @@ -39,16 +39,18 @@ int k2 = 3; int l2 = 0; -@@ -94,7 +97,7 @@ +@@ -93,8 +96,8 @@ + int j2 = i2 - position.getZ(); if (Math.abs(l1) != j1 || Math.abs(j2) != j1 || rand.nextInt(2) != 0 && i4 != 0) { BlockPos blockpos = new BlockPos(k1, i3, i2); - Material material = worldIn.getBlockState(blockpos).getMaterial(); +- Material material = worldIn.getBlockState(blockpos).getMaterial(); - if (material == Material.AIR || material == Material.LEAVES || material == Material.VINE) { ++ state = worldIn.getBlockState(blockpos); + if (state.getBlock().isAir(state, worldIn, blockpos) || state.getBlock().isLeaves(state, worldIn, blockpos) || state.getMaterial() == Material.VINE) { this.setBlockAndNotifyAdequately(worldIn, blockpos, this.metaLeaves); } } -@@ -102,15 +105,18 @@ +@@ -102,14 +105,17 @@ } } @@ -63,7 +65,7 @@ + for (int j3 = 0; j3 < i; j3++) { + BlockPos upN = position.up(j3); + state = worldIn.getBlockState(upN); - ++ + if (state.getBlock().isAir(state, worldIn, upN) || state.getBlock().isLeaves(state, worldIn, upN) || state.getMaterial() == Material.VINE) { + this.setBlockAndNotifyAdequately(worldIn, position.up(j3), this.metaWood); + @@ -71,11 +73,41 @@ + if (rand.nextInt(3) > 0 && worldIn.isAirBlock(position.add(-1, j3, 0))) { + this.addVine(worldIn, position.add(-1, j3, 0), BlockVine.EAST); + } -+ + if (rand.nextInt(3) > 0 && worldIn.isAirBlock(position.add(1, j3, 0))) { this.addVine(worldIn, position.add(1, j3, 0), BlockVine.WEST); - } -@@ -202,7 +208,7 @@ +@@ -135,24 +141,25 @@ + for (int l4 = position.getX() - k4; l4 <= position.getX() + k4; l4++) { + for (int i5 = position.getZ() - k4; i5 <= position.getZ() + k4; i5++) { + blockpos$mutableblockpos1.setPos(l4, k3, i5); +- if (worldIn.getBlockState(blockpos$mutableblockpos1).getMaterial() == Material.LEAVES) { ++ state = worldIn.getBlockState(blockpos$mutableblockpos1); ++ if (state.getBlock().isLeaves(state, worldIn, blockpos$mutableblockpos1)) { + BlockPos blockpos2 = blockpos$mutableblockpos1.west(); + BlockPos blockpos3 = blockpos$mutableblockpos1.east(); + BlockPos blockpos4 = blockpos$mutableblockpos1.north(); + BlockPos blockpos1 = blockpos$mutableblockpos1.south(); +- if (rand.nextInt(4) == 0 && worldIn.getBlockState(blockpos2).getMaterial() == Material.AIR) { ++ if (rand.nextInt(4) == 0 && worldIn.isAirBlock(blockpos2)) { + this.addHangingVine(worldIn, blockpos2, BlockVine.EAST); + } + +- if (rand.nextInt(4) == 0 && worldIn.getBlockState(blockpos3).getMaterial() == Material.AIR) { ++ if (rand.nextInt(4) == 0 && worldIn.isAirBlock(blockpos3)) { + this.addHangingVine(worldIn, blockpos3, BlockVine.WEST); + } + +- if (rand.nextInt(4) == 0 && worldIn.getBlockState(blockpos4).getMaterial() == Material.AIR) { ++ if (rand.nextInt(4) == 0 && worldIn.isAirBlock(blockpos4)) { + this.addHangingVine(worldIn, blockpos4, BlockVine.SOUTH); + } + +- if (rand.nextInt(4) == 0 && worldIn.getBlockState(blockpos1).getMaterial() == Material.AIR) { ++ if (rand.nextInt(4) == 0 && worldIn.isAirBlock(blockpos1)) { + this.addHangingVine(worldIn, blockpos1, BlockVine.NORTH); + } + } +@@ -202,7 +209,7 @@ this.addVine(worldIn, pos, prop); int i = 4; From 4cdc2484b7a3f95741e3c21dbc8cbb81cc3d4dd2 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Sat, 15 Aug 2026 22:17:34 +0100 Subject: [PATCH 39/99] Update kirino submodule --- module/kirino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/kirino b/module/kirino index aaa52d148..d1b71628d 160000 --- a/module/kirino +++ b/module/kirino @@ -1 +1 @@ -Subproject commit aaa52d148213e72571b48acf8a145d1d798e79c7 +Subproject commit d1b71628d6ed7a18855cca89b506eaf6c90c1a7f From 3a4863b7c95d072f876c375b6aed12ea42c14c80 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Sat, 15 Aug 2026 22:19:04 +0100 Subject: [PATCH 40/99] Fixed `WorldGeneratorBonusChest` hunk regression --- .../gen/feature/WorldGeneratorBonusChest.java.patch | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGeneratorBonusChest.java.patch b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGeneratorBonusChest.java.patch index 956fe20b5..fb1fb5948 100644 --- a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGeneratorBonusChest.java.patch +++ b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGeneratorBonusChest.java.patch @@ -9,7 +9,17 @@ && position.getY() > 1; iblockstate = worldIn.getBlockState(position) ) { -@@ -44,19 +44,19 @@ +@@ -33,7 +33,8 @@ + rand.nextInt(3) - rand.nextInt(3), + rand.nextInt(4) - rand.nextInt(4) + ); +- if (worldIn.isAirBlock(blockpos) && worldIn.getBlockState(blockpos.down()).isTopSolid()) { ++ if (worldIn.isAirBlock(blockpos) ++ && worldIn.getBlockState(blockpos.down()).isSideSolid(worldIn, blockpos.down(), net.minecraft.util.EnumFacing.UP)) { + worldIn.setBlockState(blockpos, Blocks.CHEST.getDefaultState(), 2); + TileEntity tileentity = worldIn.getTileEntity(blockpos); + if (tileentity instanceof TileEntityChest) { +@@ -44,19 +45,19 @@ BlockPos blockpos2 = blockpos.west(); BlockPos blockpos3 = blockpos.north(); BlockPos blockpos4 = blockpos.south(); From 1864055277a68834bbff1ab681c02da8b703b001 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Sat, 15 Aug 2026 22:19:38 +0100 Subject: [PATCH 41/99] Fixed `BlockVine` hunk regression --- .../net/minecraft/block/BlockVine.java.patch | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/module/minecraft/patches/net/minecraft/block/BlockVine.java.patch b/module/minecraft/patches/net/minecraft/block/BlockVine.java.patch index a7131cc46..29d2498cd 100644 --- a/module/minecraft/patches/net/minecraft/block/BlockVine.java.patch +++ b/module/minecraft/patches/net/minecraft/block/BlockVine.java.patch @@ -18,6 +18,15 @@ int i = 4; int j = 5; boolean flag = false; +@@ -236,7 +236,7 @@ + BlockPos blockpos4 = pos.down(); + IBlockState iblockstate2 = worldIn.getBlockState(blockpos4); + Block block1 = iblockstate2.getBlock(); +- if (block1.material == Material.AIR) { ++ if (block1.isAir(iblockstate2, worldIn, blockpos4)) { + IBlockState iblockstate3 = state; + + for (EnumFacing enumfacing4 : EnumFacing.Plane.HORIZONTAL) { @@ -273,7 +273,8 @@ BlockPos blockpos3 = pos.offset(enumfacing2); IBlockState iblockstate = worldIn.getBlockState(blockpos3); @@ -28,7 +37,7 @@ EnumFacing enumfacing = enumfacing2.rotateY(); EnumFacing enumfacing1 = enumfacing2.rotateYCCW(); boolean flag1 = state.getValue(getPropertyFor(enumfacing)); -@@ -462,15 +463,16 @@ +@@ -462,14 +463,15 @@ return i; } @@ -43,13 +52,12 @@ + /*************************FORGE START***********************************/ + @Override public boolean isLadder(IBlockState state, IBlockAccess world, BlockPos pos, EntityLivingBase entity){ return true; } + @Override public boolean isShearable(ItemStack item, IBlockAccess world, BlockPos pos){ return true; } - @Override ++ @Override + public java.util.List onSheared(ItemStack item, IBlockAccess world, BlockPos pos, int fortune) { + return java.util.Arrays.asList(new ItemStack(this, 1)); + } + /*************************FORGE END***********************************/ + -+ @Override + @Override public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face) { return BlockFaceShape.UNDEFINED; - } From c692c5bd01a7bf497e7eb986e8d03ce25ffb54cc Mon Sep 17 00:00:00 2001 From: Rongmario Date: Sat, 15 Aug 2026 22:20:04 +0100 Subject: [PATCH 42/99] Fixed `BlockPistonStructureHelper` hunk regression --- .../block/state/BlockPistonStructureHelper.java.patch | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/module/minecraft/patches/net/minecraft/block/state/BlockPistonStructureHelper.java.patch b/module/minecraft/patches/net/minecraft/block/state/BlockPistonStructureHelper.java.patch index 92d0d5f94..e4ff31f0c 100644 --- a/module/minecraft/patches/net/minecraft/block/state/BlockPistonStructureHelper.java.patch +++ b/module/minecraft/patches/net/minecraft/block/state/BlockPistonStructureHelper.java.patch @@ -20,7 +20,7 @@ return true; } -@@ -84,7 +86,7 @@ +@@ -84,11 +86,11 @@ return false; } @@ -29,6 +29,11 @@ BlockPos blockpos = origin.offset(this.moveDirection.getOpposite(), i); iblockstate = this.world.getBlockState(blockpos); block = iblockstate.getBlock(); +- if (iblockstate.getMaterial() == Material.AIR ++ if (iblockstate.getBlock().isAir(iblockstate, this.world, blockpos) + || !BlockPistonBase.canPush(iblockstate, this.world, blockpos, this.moveDirection, false, this.moveDirection.getOpposite()) + || blockpos.equals(this.pistonPos)) { + break; @@ -116,7 +118,7 @@ for (int l = 0; l <= k + i1; l++) { From 0ebcb5ddf05a8f6e73398d10dbb327e051fee18e Mon Sep 17 00:00:00 2001 From: Rongmario Date: Sat, 15 Aug 2026 22:28:54 +0100 Subject: [PATCH 43/99] Include Kirino's ShutdownManager hook in patch --- .../net/minecraft/block/BlockVine.java.patch | 7 +- .../net/minecraft/client/Minecraft.java.patch | 65 ++++++++++--------- .../gen/feature/WorldGenTrees.java.patch | 7 +- 3 files changed, 41 insertions(+), 38 deletions(-) diff --git a/module/minecraft/patches/net/minecraft/block/BlockVine.java.patch b/module/minecraft/patches/net/minecraft/block/BlockVine.java.patch index 29d2498cd..95492263e 100644 --- a/module/minecraft/patches/net/minecraft/block/BlockVine.java.patch +++ b/module/minecraft/patches/net/minecraft/block/BlockVine.java.patch @@ -37,7 +37,7 @@ EnumFacing enumfacing = enumfacing2.rotateY(); EnumFacing enumfacing1 = enumfacing2.rotateYCCW(); boolean flag1 = state.getValue(getPropertyFor(enumfacing)); -@@ -462,14 +463,15 @@ +@@ -462,15 +463,16 @@ return i; } @@ -52,12 +52,13 @@ + /*************************FORGE START***********************************/ + @Override public boolean isLadder(IBlockState state, IBlockAccess world, BlockPos pos, EntityLivingBase entity){ return true; } + @Override public boolean isShearable(ItemStack item, IBlockAccess world, BlockPos pos){ return true; } -+ @Override + @Override + public java.util.List onSheared(ItemStack item, IBlockAccess world, BlockPos pos, int fortune) { + return java.util.Arrays.asList(new ItemStack(this, 1)); + } + /*************************FORGE END***********************************/ + - @Override ++ @Override public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face) { return BlockFaceShape.UNDEFINED; + } diff --git a/module/minecraft/patches/net/minecraft/client/Minecraft.java.patch b/module/minecraft/patches/net/minecraft/client/Minecraft.java.patch index 3f253e989..c1074362f 100644 --- a/module/minecraft/patches/net/minecraft/client/Minecraft.java.patch +++ b/module/minecraft/patches/net/minecraft/client/Minecraft.java.patch @@ -205,15 +205,16 @@ if (guiScreenIn instanceof GuiMainMenu || guiScreenIn instanceof GuiMultiplayer) { this.gameSettings.showDebugInfo = false; this.ingameGUI.getChatGUI().clearChatMessages(true); -@@ -963,6 +978,7 @@ +@@ -963,6 +978,8 @@ this.soundHandler.unloadSounds(); } finally { Display.destroy(); + com.cleanroommc.client.input.SDL.shutdown(); ++ com.cleanroommc.kirino.engine.ShutdownManager.runMainHooks(); if (!this.hasCrashed) { System.exit(0); } -@@ -999,7 +1015,7 @@ +@@ -999,7 +1016,7 @@ long i1 = System.nanoTime() - l; this.checkGLError("Pre render"); this.profiler.endStartSection("sound"); @@ -222,7 +223,7 @@ this.profiler.endSection(); this.profiler.startSection("render"); GlStateManager.pushMatrix(); -@@ -1009,11 +1025,13 @@ +@@ -1009,11 +1026,13 @@ GlStateManager.enableTexture2D(); this.profiler.endSection(); if (!this.skipRenderWorld) { @@ -236,7 +237,7 @@ } this.profiler.endSection(); -@@ -1308,9 +1326,9 @@ +@@ -1308,9 +1327,9 @@ if (this.leftClickCounter <= 0 && !this.player.isHandActive()) { if (leftClick && this.objectMouseOver != null && this.objectMouseOver.typeOfHit == RayTraceResult.Type.BLOCK) { BlockPos blockpos = this.objectMouseOver.getBlockPos(); @@ -249,7 +250,7 @@ this.player.swingArm(EnumHand.MAIN_HAND); } } else { -@@ -1333,7 +1351,8 @@ +@@ -1333,7 +1352,8 @@ break; case BLOCK: BlockPos blockpos = this.objectMouseOver.getBlockPos(); @@ -259,7 +260,7 @@ this.playerController.clickBlock(blockpos, this.objectMouseOver.sideHit); break; } -@@ -1343,6 +1362,7 @@ +@@ -1343,6 +1363,7 @@ } this.player.resetCooldown(); @@ -267,7 +268,7 @@ } this.player.swingArm(EnumHand.MAIN_HAND); -@@ -1399,6 +1419,7 @@ +@@ -1399,6 +1420,7 @@ } } @@ -275,7 +276,7 @@ if (!itemstack.isEmpty() && this.playerController.processRightClick(this.player, this.world, enumhand) == EnumActionResult.SUCCESS) { this.entityRenderer.itemRenderer.resetEquippedProgress(enumhand); -@@ -1411,6 +1432,11 @@ +@@ -1411,6 +1433,11 @@ /** Toggles fullscreen mode. */ public void toggleFullscreen() { @@ -287,7 +288,7 @@ try { this.fullscreen = !this.fullscreen; this.gameSettings.fullScreen = this.fullscreen; -@@ -1445,6 +1471,10 @@ +@@ -1445,6 +1472,10 @@ } Display.setFullscreen(this.fullscreen); @@ -298,7 +299,7 @@ Display.setVSyncEnabled(this.gameSettings.enableVsync); this.updateDisplay(); } catch (Exception exception) { -@@ -1483,6 +1513,8 @@ +@@ -1483,6 +1514,8 @@ this.rightClickDelayTimer--; } @@ -307,7 +308,7 @@ this.profiler.startSection("gui"); if (!this.isGamePaused) { this.ingameGUI.updateTick(); -@@ -1632,6 +1664,7 @@ +@@ -1632,6 +1665,7 @@ } this.profiler.endSection(); @@ -315,7 +316,7 @@ this.systemTime = getSystemTime(); } -@@ -1705,6 +1738,7 @@ +@@ -1705,6 +1739,7 @@ } } } @@ -323,7 +324,7 @@ } this.processKeyBinds(); -@@ -1896,6 +1930,8 @@ +@@ -1896,6 +1931,8 @@ private void runTickMouse() throws IOException { while (Mouse.next()) { @@ -332,7 +333,7 @@ int i = Mouse.getEventButton(); KeyBinding.setKeyBindState(i - 100, Mouse.getEventButtonState()); if (Mouse.getEventButtonState()) { -@@ -1931,6 +1967,7 @@ +@@ -1931,6 +1968,7 @@ this.currentScreen.handleMouseInput(); } } @@ -340,7 +341,7 @@ } } -@@ -1949,6 +1986,7 @@ +@@ -1949,6 +1987,7 @@ /** Arguments: World foldername, World ingame name, WorldSettings */ public void launchIntegratedServer(String folderName, String worldName, @Nullable WorldSettings worldSettingsIn) { @@ -348,7 +349,7 @@ this.loadWorld(null); System.gc(); ISaveHandler isavehandler = this.saveLoader.getSaveLoader(folderName, false); -@@ -1990,6 +2028,11 @@ +@@ -1990,6 +2029,11 @@ this.loadingScreen.displaySavingString(I18n.format("menu.loadingLevel")); while (!this.integratedServer.serverIsInRunLoop()) { @@ -360,7 +361,7 @@ String s = this.integratedServer.getUserMessage(); if (s != null) { this.loadingScreen.displayLoadingString(I18n.format(s)); -@@ -2007,8 +2050,13 @@ +@@ -2007,8 +2051,13 @@ SocketAddress socketaddress = this.integratedServer.getNetworkSystem().addLocalEndpoint(); NetworkManager networkmanager = NetworkManager.provideLocalClient(socketaddress); networkmanager.setNetHandler(new NetHandlerLoginClient(networkmanager, this, null)); @@ -376,7 +377,7 @@ this.networkManager = networkmanager; } -@@ -2019,6 +2067,8 @@ +@@ -2019,6 +2068,8 @@ /** par2Str is displayed on the loading screen to the user unloads the current world first */ public void loadWorld(@Nullable WorldClient worldClientIn, String loadingMessage) { @@ -385,7 +386,7 @@ if (worldClientIn == null) { NetHandlerPlayClient nethandlerplayclient = this.getConnection(); if (nethandlerplayclient != null) { -@@ -2027,6 +2077,14 @@ +@@ -2027,6 +2078,14 @@ if (this.integratedServer != null && this.integratedServer.isAnvilFileSet()) { this.integratedServer.initiateShutdown(); @@ -400,7 +401,7 @@ } this.integratedServer = null; -@@ -2047,6 +2105,7 @@ +@@ -2047,6 +2106,7 @@ this.ingameGUI.resetPlayersOverlayFooterHeader(); this.setServerData(null); this.integratedServerIsRunning = false; @@ -408,7 +409,7 @@ } this.soundHandler.stopSounds(); -@@ -2060,6 +2119,8 @@ +@@ -2060,6 +2120,8 @@ } TileEntityRendererDispatcher.instance.setWorld(worldClientIn); @@ -417,7 +418,7 @@ if (worldClientIn != null) { if (!this.integratedServerIsRunning) { AuthenticationService authenticationservice = new YggdrasilAuthenticationService(this.proxy, UUID.randomUUID().toString()); -@@ -2112,6 +2173,7 @@ +@@ -2112,6 +2174,7 @@ this.player == null ? new RecipeBook() : this.player.getRecipeBook() ); this.player.getDataManager().setEntryValues(entityplayersp.getDataManager().getAll()); @@ -425,7 +426,7 @@ this.player.dimension = dimension; this.renderViewEntity = this.player; this.player.preparePlayerToSpawn(); -@@ -2153,110 +2215,8 @@ +@@ -2153,110 +2216,8 @@ /** Called when user clicked he's mouse middle button (pick block) */ private void middleClickMouse() { if (this.objectMouseOver != null && this.objectMouseOver.typeOfHit != RayTraceResult.Type.MISS) { @@ -538,7 +539,7 @@ } } -@@ -2293,7 +2253,11 @@ +@@ -2293,7 +2254,11 @@ }); theCrash.getCategory().addDetail("OpenGL", new ICrashReportDetail() { public String call() { @@ -551,7 +552,7 @@ } }); theCrash.getCategory().addDetail("GL Caps", new ICrashReportDetail() { -@@ -2372,6 +2336,7 @@ +@@ -2372,6 +2337,7 @@ return instance; } @@ -559,7 +560,7 @@ public ListenableFuture scheduleResourcesRefresh() { return this.addScheduledTask(new Runnable() { @Override -@@ -2536,15 +2501,8 @@ +@@ -2536,15 +2502,8 @@ /** Used in the usage snooper. */ public static int getGLMaximumTextureSize() { @@ -577,7 +578,7 @@ } /** Returns whether snooping is enabled or not. */ -@@ -2658,6 +2616,9 @@ +@@ -2658,6 +2617,9 @@ } if (this.player != null) { @@ -587,7 +588,7 @@ if (this.player.world.provider instanceof WorldProviderHell) { return MusicTicker.MusicType.NETHER; } else if (this.player.world.provider instanceof WorldProviderEnd) { -@@ -2677,9 +2638,9 @@ +@@ -2677,9 +2639,9 @@ if (i != 0 && !Keyboard.isRepeatEvent()) { if (!(this.currentScreen instanceof GuiControls) || ((GuiControls)this.currentScreen).time <= getSystemTime() - 20L) { if (Keyboard.getEventKeyState()) { @@ -599,7 +600,7 @@ this.ingameGUI .getChatGUI() .printChatMessage(ScreenShotHelper.saveScreenshot(this.gameDir, this.displayWidth, this.displayHeight, this.framebuffer)); -@@ -2691,7 +2652,7 @@ +@@ -2691,7 +2653,7 @@ ((ScreenChatOptions)this.currentScreen).updateNarratorButton(); } } @@ -608,7 +609,7 @@ } } } -@@ -2720,7 +2681,7 @@ +@@ -2720,7 +2682,7 @@ try { return Futures.immediateFuture(callableToSchedule.call()); } catch (Exception exception) { @@ -617,7 +618,7 @@ } } else { ListenableFutureTask listenablefuturetask = ListenableFutureTask.create(callableToSchedule); -@@ -2802,7 +2763,11 @@ +@@ -2802,7 +2764,11 @@ return this.blockColors; } @@ -630,7 +631,7 @@ public boolean isReducedDebug() { return this.player != null && this.player.hasReducedDebug() || this.gameSettings.reducedDebugInfo; } -@@ -2814,4 +2779,8 @@ +@@ -2814,4 +2780,8 @@ public Tutorial getTutorial() { return this.tutorial; } diff --git a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenTrees.java.patch b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenTrees.java.patch index ef4cc3a00..ddfa588b1 100644 --- a/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenTrees.java.patch +++ b/module/minecraft/patches/net/minecraft/world/gen/feature/WorldGenTrees.java.patch @@ -50,7 +50,7 @@ this.setBlockAndNotifyAdequately(worldIn, blockpos, this.metaLeaves); } } -@@ -102,14 +105,17 @@ +@@ -102,15 +105,18 @@ } } @@ -65,7 +65,7 @@ + for (int j3 = 0; j3 < i; j3++) { + BlockPos upN = position.up(j3); + state = worldIn.getBlockState(upN); -+ + + if (state.getBlock().isAir(state, worldIn, upN) || state.getBlock().isLeaves(state, worldIn, upN) || state.getMaterial() == Material.VINE) { + this.setBlockAndNotifyAdequately(worldIn, position.up(j3), this.metaWood); + @@ -73,9 +73,10 @@ + if (rand.nextInt(3) > 0 && worldIn.isAirBlock(position.add(-1, j3, 0))) { + this.addVine(worldIn, position.add(-1, j3, 0), BlockVine.EAST); + } - ++ if (rand.nextInt(3) > 0 && worldIn.isAirBlock(position.add(1, j3, 0))) { this.addVine(worldIn, position.add(1, j3, 0), BlockVine.WEST); + } @@ -135,24 +141,25 @@ for (int l4 = position.getX() - k4; l4 <= position.getX() + k4; l4++) { for (int i5 = position.getZ() - k4; i5 <= position.getZ() + k4; i5++) { From 7fe20d998f7555ecc605374ee48eb6a39ff8e9ba Mon Sep 17 00:00:00 2001 From: Rongmario Date: Sat, 15 Aug 2026 22:54:14 +0100 Subject: [PATCH 44/99] Fixed patch regression for `StructureVillagePieces` --- .../StructureVillagePieces.java.patch | 121 ++++++------------ 1 file changed, 41 insertions(+), 80 deletions(-) diff --git a/module/minecraft/patches/net/minecraft/world/gen/structure/StructureVillagePieces.java.patch b/module/minecraft/patches/net/minecraft/world/gen/structure/StructureVillagePieces.java.patch index 3964d98bd..40d975ae2 100644 --- a/module/minecraft/patches/net/minecraft/world/gen/structure/StructureVillagePieces.java.patch +++ b/module/minecraft/patches/net/minecraft/world/gen/structure/StructureVillagePieces.java.patch @@ -8,33 +8,33 @@ Iterator iterator = list.iterator(); while (iterator.hasNext()) { -@@ -162,8 +163,10 @@ - ); - } else if (oclass == StructureVillagePieces.House3.class) { +@@ -164,6 +165,8 @@ structurevillagepieces$village = StructureVillagePieces.House3.createPiece( -- start, structureComponents, rand, structureMinX, structureMinY, structureMinZ, facing, componentType -- ); -+ start, structureComponents, rand, structureMinX, structureMinY, structureMinZ, facing, componentType -+ ); + start, structureComponents, rand, structureMinX, structureMinY, structureMinZ, facing, componentType + ); + } else { + structurevillagepieces$village = net.minecraftforge.fml.common.registry.VillagerRegistry.getVillageComponent(weight, start , structureComponents, rand, structureMinX, structureMinY, structureMinZ, facing, componentType); } return structurevillagepieces$village; -@@ -1617,9 +1620,9 @@ - public Road() { - } +@@ -1631,6 +1634,7 @@ + public List structureVillageWeightedPieceList; + public List pendingHouses = Lists.newArrayList(); + public List pendingRoads = Lists.newArrayList(); ++ public Biome biome; -- protected Road(StructureVillagePieces.Start start, int type) { -- super(start, type); -- } -+ protected Road(StructureVillagePieces.Start start, int type) { -+ super(start, type); -+ } - } - - public static class Start extends StructureVillagePieces.Well { -@@ -1717,6 +1720,7 @@ + public Start() { + } +@@ -1649,6 +1653,8 @@ + this.structureVillageWeightedPieceList = p_i2104_6_; + this.terrainType = p_i2104_7_; + Biome biome = biomeProviderIn.getBiome(new BlockPos(p_i2104_4_, 0, p_i2104_5_), Biomes.DEFAULT); ++ this.biome = biome; ++ this.startPiece = this; + if (biome instanceof BiomeDesert) { + this.structureType = 1; + } else if (biome instanceof BiomeSavanna) { +@@ -1717,6 +1723,7 @@ private int villagersSpawned; protected int structureType; protected boolean isZombieInfested; @@ -42,75 +42,32 @@ public Village() { } -@@ -1726,6 +1730,7 @@ +@@ -1726,6 +1733,7 @@ if (start != null) { this.structureType = start.structureType; this.isZombieInfested = start.isZombieInfested; -+ startPiece = start; ++ this.startPiece = start; } } -@@ -1893,39 +1898,46 @@ - } - - /** Spawns a number of villagers in this component. Parameters: world, component bounding box, x offset, y offset, z offset, number of villagers */ -- protected void spawnVillagers(World worldIn, StructureBoundingBox structurebb, int x, int y, int z, int count) { -- if (this.villagersSpawned < count) { -- for (int i = this.villagersSpawned; i < count; i++) { -- int j = this.getXWithOffset(x + i, z); -- int k = this.getYWithOffset(y); -- int l = this.getZWithOffset(x + i, z); -- if (!structurebb.isVecInside(new BlockPos(j, k, l))) { -- break; -- } -+ protected void spawnVillagers(World worldIn, StructureBoundingBox structurebb, int x, int y, int z, int count) { -+ if (this.villagersSpawned < count) { -+ for (int i = this.villagersSpawned; i < count; i++) { -+ int j = this.getXWithOffset(x + i, z); -+ int k = this.getYWithOffset(y); -+ int l = this.getZWithOffset(x + i, z); - -- this.villagersSpawned++; -- if (this.isZombieInfested) { -- EntityZombieVillager entityzombievillager = new EntityZombieVillager(worldIn); -- entityzombievillager.setLocationAndAngles(j + 0.5, k, l + 0.5, 0.0F, 0.0F); -- entityzombievillager.onInitialSpawn(worldIn.getDifficultyForLocation(new BlockPos(entityzombievillager)), null); +@@ -1908,13 +1916,14 @@ + EntityZombieVillager entityzombievillager = new EntityZombieVillager(worldIn); + entityzombievillager.setLocationAndAngles(j + 0.5, k, l + 0.5, 0.0F, 0.0F); + entityzombievillager.onInitialSpawn(worldIn.getDifficultyForLocation(new BlockPos(entityzombievillager)), null); - entityzombievillager.setProfession(this.chooseProfession(i, 0)); -- entityzombievillager.enablePersistence(); -- worldIn.spawnEntity(entityzombievillager); -- } else { -- EntityVillager entityvillager = new EntityVillager(worldIn); -- entityvillager.setLocationAndAngles(j + 0.5, k, l + 0.5, 0.0F, 0.0F); ++ entityzombievillager.setForgeProfession(this.chooseForgeProfession(i, net.minecraftforge.fml.common.registry.VillagerRegistry.FARMER)); + entityzombievillager.enablePersistence(); + worldIn.spawnEntity(entityzombievillager); + } else { + EntityVillager entityvillager = new EntityVillager(worldIn); + entityvillager.setLocationAndAngles(j + 0.5, k, l + 0.5, 0.0F, 0.0F); - entityvillager.setProfession(this.chooseProfession(i, worldIn.rand.nextInt(6))); -- entityvillager.finalizeMobSpawn(worldIn.getDifficultyForLocation(new BlockPos(entityvillager)), null, false); -- worldIn.spawnEntity(entityvillager); -+ if (!structurebb.isVecInside(new BlockPos(j, k, l))) { -+ break; -+ } -+ -+ this.villagersSpawned++; -+ -+ if (this.isZombieInfested) { -+ EntityZombieVillager entityzombievillager = new EntityZombieVillager(worldIn); -+ entityzombievillager.setLocationAndAngles(j + 0.5, k, l + 0.5, 0.0F, 0.0F); -+ entityzombievillager.onInitialSpawn(worldIn.getDifficultyForLocation(new BlockPos(entityzombievillager)), null); -+ entityzombievillager.setForgeProfession(this.chooseForgeProfession(i, net.minecraftforge.fml.common.registry.VillagerRegistry.FARMER)); -+ entityzombievillager.enablePersistence(); -+ worldIn.spawnEntity(entityzombievillager); -+ } else { -+ EntityVillager entityvillager = new EntityVillager(worldIn); -+ entityvillager.setLocationAndAngles(j + 0.5, k, l + 0.5, 0.0F, 0.0F); -+ net.minecraftforge.fml.common.registry.VillagerRegistry.setRandomProfession(entityvillager, worldIn.rand); -+ entityvillager.setProfession(this.chooseForgeProfession(i, entityvillager.getProfessionForge())); -+ entityvillager.finalizeMobSpawn(worldIn.getDifficultyForLocation(new BlockPos(entityvillager)), null, false); -+ worldIn.spawnEntity(entityvillager); -+ } ++ net.minecraftforge.fml.common.registry.VillagerRegistry.setRandomProfession(entityvillager, worldIn.rand); ++ entityvillager.setProfession(this.chooseForgeProfession(i, entityvillager.getProfessionForge())); + entityvillager.finalizeMobSpawn(worldIn.getDifficultyForLocation(new BlockPos(entityvillager)), null, false); + worldIn.spawnEntity(entityvillager); } - } - } -- } - - protected int chooseProfession(int villagersSpawnedIn, int currentVillagerProfession) { +@@ -1926,7 +1935,14 @@ return currentVillagerProfession; } @@ -119,5 +76,9 @@ + } + protected IBlockState getBiomeSpecificBlockState(IBlockState blockstateIn) { ++ net.minecraftforge.event.terraingen.BiomeEvent.GetVillageBlockID event = new net.minecraftforge.event.terraingen.BiomeEvent.GetVillageBlockID(startPiece == null ? null : startPiece.biome, blockstateIn); ++ net.minecraftforge.common.MinecraftForge.TERRAIN_GEN_BUS.post(event); ++ if (event.getResult() == net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) return event.getReplacement(); if (this.structureType == 1) { if (blockstateIn.getBlock() == Blocks.LOG || blockstateIn.getBlock() == Blocks.LOG2) { + return Blocks.SANDSTONE.getDefaultState(); From f5e9227e74d058a6381ce81610eddb07994ce643 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Sun, 16 Aug 2026 10:24:49 +0100 Subject: [PATCH 45/99] Remove ChunkPos getX + getY helpers --- .../net/minecraft/util/math/ChunkPos.java.patch | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 module/minecraft/patches/net/minecraft/util/math/ChunkPos.java.patch diff --git a/module/minecraft/patches/net/minecraft/util/math/ChunkPos.java.patch b/module/minecraft/patches/net/minecraft/util/math/ChunkPos.java.patch deleted file mode 100644 index 31c5f895e..000000000 --- a/module/minecraft/patches/net/minecraft/util/math/ChunkPos.java.patch +++ /dev/null @@ -1,17 +0,0 @@ ---- original/net/minecraft/util/math/ChunkPos.java -+++ modified/net/minecraft/util/math/ChunkPos.java -@@ -23,6 +23,14 @@ - return x & 4294967295L | (z & 4294967295L) << 32; - } - -+ public static int getX(long key) { -+ return (int) (key & 0xFFFFFFFFL); -+ } -+ -+ public static int getZ(long key) { -+ return (int) ((key >>> 32) & 0xFFFFFFFFL); -+ } -+ - @Override - public int hashCode() { - int i = 1664525 * this.x + 1013904223; From b7e5f6c4b6b6d15af56943690a43c659235e07f8 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Sun, 16 Aug 2026 18:37:30 +0100 Subject: [PATCH 46/99] Bring Kirino's ShutdownManager before clearing window --- .../patches/net/minecraft/client/Minecraft.java.patch | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/module/minecraft/patches/net/minecraft/client/Minecraft.java.patch b/module/minecraft/patches/net/minecraft/client/Minecraft.java.patch index c1074362f..951987850 100644 --- a/module/minecraft/patches/net/minecraft/client/Minecraft.java.patch +++ b/module/minecraft/patches/net/minecraft/client/Minecraft.java.patch @@ -205,15 +205,15 @@ if (guiScreenIn instanceof GuiMainMenu || guiScreenIn instanceof GuiMultiplayer) { this.gameSettings.showDebugInfo = false; this.ingameGUI.getChatGUI().clearChatMessages(true); -@@ -963,6 +978,8 @@ +@@ -962,6 +977,8 @@ + this.soundHandler.unloadSounds(); } finally { - Display.destroy(); -+ com.cleanroommc.client.input.SDL.shutdown(); + com.cleanroommc.kirino.engine.ShutdownManager.runMainHooks(); ++ com.cleanroommc.client.input.SDL.shutdown(); + Display.destroy(); if (!this.hasCrashed) { System.exit(0); - } @@ -999,7 +1016,7 @@ long i1 = System.nanoTime() - l; this.checkGLError("Pre render"); From 83022df518eb39ab7ae529b6fd315706b4e3f690 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Sun, 16 Aug 2026 18:54:33 +0100 Subject: [PATCH 47/99] Catch up versioning, and use temp version class before token plugin gets published --- .gitignore | 3 --- build.gradle | 53 ++++++++++++++++++++++++++++++++++++++++------- gradle.properties | 10 ++++----- 3 files changed, 51 insertions(+), 15 deletions(-) diff --git a/.gitignore b/.gitignore index 964d1a49b..385108d11 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,4 @@ **/run/ /module/minecraft/src/ -# TODO -module/cleanroom/src/main/java/com/cleanroommc/common/CleanroomVersion.java - !/.idea/icon.svg diff --git a/build.gradle b/build.gradle index c2c4d0498..01ceb63cd 100644 --- a/build.gradle +++ b/build.gradle @@ -22,7 +22,6 @@ idea { cleanroom { loaderProject = true - developInitialPatches = false accessTransformers.from file('module/forge/src/main/resources/forge_at.cfg') } @@ -35,9 +34,22 @@ def modules = [ 'builtin/configanytime' ] +def generatedVersionRoot = layout.buildDirectory.dir('generated/sources/version/java') +def generateCleanroomVersion = tasks.register('generateCleanroomVersion', Copy) { + def shortVersion = version.toString().replaceFirst(/\+.*$/, '') + def fullVersion = version.toString() + inputs.property('shortVersion', shortVersion) + inputs.property('fullVersion', fullVersion) + from 'templates/CleanroomVersion.java' + into generatedVersionRoot.map { it.dir('com/cleanroommc/common') } + filter { it.replace('%VERSION%', shortVersion).replace('%BUILD_VERSION%', fullVersion) } + filteringCharset = 'UTF-8' +} + sourceSets { main { - java.srcDirs = modules.collect { "module/${it}/src/main/java" } + 'module/minecraft/injected/java' + java.srcDirs = modules.collect { "module/${it}/src/main/java" } + java.srcDir files(generatedVersionRoot).builtBy(generateCleanroomVersion) // Fixme: Temp java.exclude 'com/cleanroommc/kirino/utils/KsmlcUtils.java' resources.srcDirs = modules.collect { "module/${it}/src/main/resources" } @@ -62,12 +74,20 @@ var export_arguments = [ '--add-exports=java.base/jdk.internal.reflect=ALL-UNNAMED' ] -configurations.configureEach { +def toolConfigurations = [ + 'decompiler', 'mergetool', 'mcinjector', 'installertools', 'accesstransformer' +] as Set + +configurations.configureEach { configuration -> exclude group: 'com.ibm.icu', module: 'icu4j-core-mojang' // patchy ships its own copy of io.netty.bootstrap.Bootstrap // Against 4.2 netty it shadows the real class and dies on a superclass method that no longer exists exclude group: 'com.mojang', module: 'patchy' + if (configuration.name in toolConfigurations) { + return + } + resolutionStrategy.eachDependency { details -> switch ("${details.requested.group}:${details.requested.name}") { case 'com.google.guava:guava': details.useVersion '33.6.0-jre'; break @@ -198,6 +218,13 @@ dependencies { testRuntimeOnly 'org.junit.platform:junit-platform-launcher' } +tasks.register('printVersion') { + group = 'help' + description = 'Prints the computed project version.' + def v = version.toString() + doLast { println v } +} + tasks.named('test', Test) { maxParallelForks = 1 useJUnitPlatform() @@ -205,17 +232,29 @@ tasks.named('test', Test) { jvmArgs open_arguments + export_arguments } -tasks.register('printBuildInfo') { +tasks.named('compileJava', JavaCompile).configure { compile -> + dependsOn generateCleanroomVersion def v = version.toString() - outputs.upToDateWhen { false } - doLast { + doFirst { logger.lifecycle("Cleanroom ${v}") logger.lifecycle("Java: ${System.getProperty('java.version')} | JVM: ${System.getProperty('java.vm.version')} | Vendor: ${System.getProperty('java.vendor')} | Arch: ${System.getProperty('os.arch')}") } } tasks.withType(JavaCompile).configureEach { - dependsOn 'printBuildInfo' options.encoding = 'UTF-8' options.compilerArgs += export_arguments } + +publishing { + repositories { + maven { + name = 'CleanroomMaven' + url = 'https://repo.cleanroommc.com/releases' + credentials(PasswordCredentials) + authentication { + basic(BasicAuthentication) + } + } + } +} diff --git a/gradle.properties b/gradle.properties index ef93edba7..02ef029c6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ # Project -version = 0.6.0 +version = 0.6.10 # Stage only accepts 'alpha', 'beta', 'rc' or 'release' version_stage = alpha java_major = 25 @@ -11,7 +11,7 @@ mixinextras_version = 0.5.5 # Gradle org.gradle.jvmargs = -Xmx3G -org.gradle.parallel=true -org.gradle.caching=true -org.gradle.configuration-cache=true -org.gradle.configuration-cache.problems=warn +org.gradle.parallel = true +org.gradle.caching = true +org.gradle.configuration-cache = true +org.gradle.configuration-cache.problems = warn From cd473dc2c8ff6892bdff6e56712f877f5e60135a Mon Sep 17 00:00:00 2001 From: Rongmario Date: Mon, 17 Aug 2026 10:24:29 +0100 Subject: [PATCH 48/99] Bump CG to 0.7.0 --- settings.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle b/settings.gradle index 51f7ef479..8f40a0e65 100644 --- a/settings.gradle +++ b/settings.gradle @@ -14,5 +14,5 @@ pluginManagement { } plugins { - id 'com.cleanroommc.cleanroomgradle.settings' version '0.6.0' + id 'com.cleanroommc.cleanroomgradle.settings' version '0.7.0' } From 02d1f1729739acae3b4d0bc4af7bb7b536fae4cf Mon Sep 17 00:00:00 2001 From: Rongmario Date: Mon, 17 Aug 2026 11:58:30 +0100 Subject: [PATCH 49/99] Update kirino submodule --- module/kirino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/kirino b/module/kirino index d1b71628d..b629d0ada 160000 --- a/module/kirino +++ b/module/kirino @@ -1 +1 @@ -Subproject commit d1b71628d6ed7a18855cca89b506eaf6c90c1a7f +Subproject commit b629d0ada714e41aeafb7d43ccdbb9c85ecb8a58 From b39853842de87aeb96328566b342766a00cb28df Mon Sep 17 00:00:00 2001 From: Rongmario Date: Mon, 17 Aug 2026 11:59:10 +0100 Subject: [PATCH 50/99] Uninstall WindowBridge --- .../client/input/CleanroomWindowBridge.java | 15 ++++++++++----- .../java/com/cleanroommc/client/input/SDL.java | 3 ++- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/input/CleanroomWindowBridge.java b/module/cleanroom/src/main/java/com/cleanroommc/client/input/CleanroomWindowBridge.java index d4200da41..25ae963d7 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/input/CleanroomWindowBridge.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/input/CleanroomWindowBridge.java @@ -12,6 +12,16 @@ /** Connects LWJGLY's LWJGL 2 compatibility APIs to Cleanroom's SDL window. */ public final class CleanroomWindowBridge implements WindowBridge { + /** Installs the bridge before any call to Display, Keyboard or Mouse. */ + public static void install(Window window) { + LWJGLY.setWindowBridge(new CleanroomWindowBridge(window)); + } + + /** Uninstalls the bridge, allowing LWJGLY shim to report a properly closed Display. */ + public static void uninstall() { + LWJGLY.setWindowBridge(null); + } + private static String validate(ContextRequest request) { PixelFormatRequest format = request.pixelFormat(); if (format.auxiliaryBuffers() > 0) { @@ -154,11 +164,6 @@ private CleanroomWindowBridge(Window window) { this.capabilities = GL.getCapabilities(); } - /** Installs the bridge before any call to Display, Keyboard or Mouse. */ - public static void install(Window window) { - LWJGLY.setWindowBridge(new CleanroomWindowBridge(window)); - } - @Override public long handle() { return window.handle(); diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/input/SDL.java b/module/cleanroom/src/main/java/com/cleanroommc/client/input/SDL.java index 4afc74f77..4e82a0fb9 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/input/SDL.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/input/SDL.java @@ -29,8 +29,8 @@ public static synchronized void ensureSubsystem(int flags) { if (missing == 0) { return; } - check(SDLInit.SDL_InitSubSystem(missing), "SDL_InitSubSystem"); initializedBits |= missing; + check(SDLInit.SDL_InitSubSystem(missing), "SDL_InitSubSystem"); } /** @@ -48,6 +48,7 @@ public static synchronized void shutdown() { } // TODO: new SDL input stack // Inputs.reset(); + CleanroomWindowBridge.uninstall(); Window.closeMain(); SDLInit.SDL_Quit(); initializedBits = 0; From 5c1d2d4a9c1ee349a6ff4132f69750598a76c6c1 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Mon, 17 Aug 2026 12:00:47 +0100 Subject: [PATCH 51/99] Close/swap contexts with more grace --- .../client/input/SharedGLContext.java | 8 +++- .../com/cleanroommc/client/input/Window.java | 41 +++++++++++++++++-- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/input/SharedGLContext.java b/module/cleanroom/src/main/java/com/cleanroommc/client/input/SharedGLContext.java index 8c8b876ce..5045410d0 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/input/SharedGLContext.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/input/SharedGLContext.java @@ -56,7 +56,9 @@ public void makeCurrent() { } public void release() { - this.ensureOpen(); + if (this.closed) { + return; + } SDL.check(SDLVideo.SDL_GL_MakeCurrent(surface, 0L), "SDL_GL_MakeCurrent"); GL.setCapabilities(null); } @@ -67,6 +69,10 @@ public void close() { return; } this.closed = true; + if (SDLVideo.SDL_GL_GetCurrentContext() == this.context) { + SDLVideo.SDL_GL_MakeCurrent(this.surface, 0L); + GL.setCapabilities(null); + } SDLVideo.SDL_GL_DestroyContext(this.context); SDLVideo.SDL_DestroyWindow(this.surface); this.capabilities = null; diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/input/Window.java b/module/cleanroom/src/main/java/com/cleanroommc/client/input/Window.java index 0c19c50ab..76d2b5bec 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/input/Window.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/input/Window.java @@ -50,7 +50,8 @@ public final class Window implements AutoCloseable { private boolean minimized; private boolean mouseGrabbed; private boolean mouseWarped; - private boolean closed; + + private volatile boolean closed; private Window(long handle, long glContext, String title, int width, int height) { this.handle = handle; @@ -79,6 +80,7 @@ public static void closeMain() { } public long handle() { + this.ensureOpen(); return handle; } @@ -88,6 +90,7 @@ public long handle() { * TODO: Make compositors into an enum */ public long nativeHandle() { + this.ensureOpen(); int properties = SDLVideo.SDL_GetWindowProperties(handle); if (properties == 0) { return 0L; @@ -166,12 +169,14 @@ public synchronized boolean consumeResized() { } public synchronized Window title(String title) { + this.ensureOpen(); SDL.check(SDLVideo.SDL_SetWindowTitle(this.handle, title), "SDL_SetWindowTitle"); this.title = title; return this; } public synchronized Window fullscreen(boolean fullscreen) { + this.ensureOpen(); SDL.check(SDLVideo.SDL_SetWindowFullscreen(handle, fullscreen), "SDL_SetWindowFullscreen"); this.fullscreen = fullscreen; this.refreshSize(); @@ -179,32 +184,44 @@ public synchronized Window fullscreen(boolean fullscreen) { } public synchronized Window borderless(boolean borderless) { + this.ensureOpen(); SDL.check(SDLVideo.SDL_SetWindowBordered(this.handle, !borderless), "SDL_SetWindowBordered"); this.borderless = borderless; return this; } + /** + * Sets the swap interval of whichever context is current on this thread, which SDL keys to the context rather than + * to the window. Make this window current first if another context may have taken over the thread. + */ public Window vsync(boolean enabled) { + this.ensureOpen(); SDL.check(SDLVideo.SDL_GL_SetSwapInterval(enabled ? 1 : 0), "SDL_GL_SetSwapInterval"); return this; } public Window makeCurrent() { + this.ensureOpen(); SDL.check(SDLVideo.SDL_GL_MakeCurrent(this.handle, this.glContext), "SDL_GL_MakeCurrent"); return this; } public Window releaseContext() { + if (this.closed) { + return this; + } SDL.check(SDLVideo.SDL_GL_MakeCurrent(this.handle, 0L), "SDL_GL_MakeCurrent"); return this; } public Window swapBuffers() { + this.ensureOpen(); SDL.check(SDLVideo.SDL_GL_SwapWindow(this.handle), "SDL_GL_SwapWindow"); return this; } public Window textInput(boolean enabled) { + this.ensureOpen(); boolean active = SDLKeyboard.SDL_TextInputActive(this.handle); if (enabled && !active) { SDL.check(SDLKeyboard.SDL_StartTextInput(this.handle), "SDL_StartTextInput"); @@ -216,6 +233,7 @@ public Window textInput(boolean enabled) { /** Drains SDL's process-wide event queue exactly once for the frame. */ public synchronized Window pump() { + this.ensureOpen(); try (MemoryStack stack = MemoryStack.stackPush()) { SDL_Event event = SDL_Event.malloc(stack); while (SDLEvents.SDL_PollEvent(event)) { @@ -346,6 +364,15 @@ private void releaseHeldInput(long timestampNs) { } } + /** + * @throws IllegalStateException if the window is closed, rather than letting SDL fail on a freed handle + */ + private void ensureOpen() { + if (this.closed) { + throw new IllegalStateException("Cleanroom's SDL window is closed"); + } + } + private void refreshSize() { try (MemoryStack stack = MemoryStack.stackPush()) { IntBuffer w = stack.mallocInt(1); @@ -378,6 +405,7 @@ synchronized float mouseY() { } synchronized void mousePosition(float x, float y) { + this.ensureOpen(); SDLMouse.SDL_WarpMouseInWindow(this.handle, x, y); this.mouseX = x; this.mouseY = y; @@ -385,6 +413,7 @@ synchronized void mousePosition(float x, float y) { } synchronized void grabMouse(boolean grab) { + this.ensureOpen(); SDL.check(SDLMouse.SDL_SetWindowRelativeMouseMode(handle, grab), "SDL_SetWindowRelativeMouseMode"); this.mouseGrabbed = grab; } @@ -430,11 +459,17 @@ public synchronized void close() { Arrays.fill(this.keys, false); Arrays.fill(this.buttons, false); if (this.glContext != 0L) { + if (SDLVideo.SDL_GL_GetCurrentContext() == this.glContext) { + SDLVideo.SDL_GL_MakeCurrent(this.handle, 0L); + GL.setCapabilities(null); + } SDLVideo.SDL_GL_DestroyContext(this.glContext); } SDLVideo.SDL_DestroyWindow(this.handle); - if (main == this) { - main = null; + synchronized (Window.class) { + if (main == this) { + main = null; + } } } From 9a6d9f4a81d7dbd9fe21ddeb7424a3b88b4f4834 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Mon, 17 Aug 2026 12:51:06 +0100 Subject: [PATCH 52/99] Nuke old patches --- .../AdvancementManager.java.patch | 10 - .../AdvancementRewards.java.patch | 11 - .../advancements/DisplayInfo.java.patch | 13 - .../PlayerAdvancements.java.patch | 21 - .../critereon/ItemPredicate.java.patch | 16 - .../net/minecraft/block/Block.java.patch | 1661 ----------------- .../minecraft/block/BlockBanner.java.patch | 51 - .../net/minecraft/block/BlockBed.java.patch | 14 - .../net/minecraft/block/BlockBush.java.patch | 70 - .../minecraft/block/BlockButton.java.patch | 11 - .../minecraft/block/BlockCactus.java.patch | 68 - .../net/minecraft/block/BlockChest.java.patch | 32 - .../block/BlockChorusFlower.java.patch | 27 - .../net/minecraft/block/BlockCocoa.java.patch | 44 - .../net/minecraft/block/BlockCrops.java.patch | 81 - .../minecraft/block/BlockDeadBush.java.patch | 29 - .../net/minecraft/block/BlockDoor.java.patch | 32 - .../block/BlockDoublePlant.java.patch | 86 - .../minecraft/block/BlockDragonEgg.java.patch | 29 - .../minecraft/block/BlockDropper.java.patch | 11 - .../block/BlockDynamicLiquid.java.patch | 64 - .../block/BlockEnchantmentTable.java.patch | 11 - .../block/BlockEnderChest.java.patch | 11 - .../minecraft/block/BlockFalling.java.patch | 30 - .../minecraft/block/BlockFarmland.java.patch | 33 - .../net/minecraft/block/BlockFence.java.patch | 41 - .../minecraft/block/BlockFenceGate.java.patch | 44 - .../net/minecraft/block/BlockFire.java.patch | 230 --- .../minecraft/block/BlockFlowerPot.java.patch | 67 - .../net/minecraft/block/BlockGrass.java.patch | 42 - .../block/BlockHugeMushroom.java.patch | 31 - .../net/minecraft/block/BlockIce.java.patch | 29 - .../minecraft/block/BlockLadder.java.patch | 14 - .../minecraft/block/BlockLeaves.java.patch | 148 -- .../minecraft/block/BlockLiquid.java.patch | 59 - .../net/minecraft/block/BlockLog.java.patch | 33 - .../block/BlockMobSpawner.java.patch | 17 - .../minecraft/block/BlockMushroom.java.patch | 11 - .../minecraft/block/BlockMycelium.java.patch | 21 - .../block/BlockNetherWart.java.patch | 62 - .../minecraft/block/BlockNewLeaf.java.patch | 13 - .../net/minecraft/block/BlockNote.java.patch | 23 - .../minecraft/block/BlockObserver.java.patch | 15 - .../minecraft/block/BlockOldLeaf.java.patch | 20 - .../net/minecraft/block/BlockOre.java.patch | 50 - .../net/minecraft/block/BlockPane.java.patch | 54 - .../block/BlockPistonBase.java.patch | 46 - .../block/BlockPistonMoving.java.patch | 37 - .../minecraft/block/BlockPortal.java.patch | 20 - .../minecraft/block/BlockPotato.java.patch | 25 - .../minecraft/block/BlockPumpkin.java.patch | 13 - .../minecraft/block/BlockQuartz.java.patch | 38 - .../minecraft/block/BlockRailBase.java.patch | 259 --- .../block/BlockRailDetector.java.patch | 11 - .../block/BlockRailPowered.java.patch | 30 - .../block/BlockRedstoneComparator.java.patch | 24 - .../block/BlockRedstoneDiode.java.patch | 54 - .../block/BlockRedstoneOre.java.patch | 22 - .../block/BlockRedstoneTorch.java.patch | 11 - .../block/BlockRedstoneWire.java.patch | 73 - .../net/minecraft/block/BlockReed.java.patch | 58 - .../block/BlockRotatedPillar.java.patch | 24 - .../minecraft/block/BlockSapling.java.patch | 18 - .../net/minecraft/block/BlockSkull.java.patch | 58 - .../net/minecraft/block/BlockSlab.java.patch | 39 - .../net/minecraft/block/BlockSnow.java.patch | 60 - .../minecraft/block/BlockStairs.java.patch | 32 - .../block/BlockStaticLiquid.java.patch | 39 - .../net/minecraft/block/BlockStem.java.patch | 72 - .../minecraft/block/BlockTallGrass.java.patch | 55 - .../net/minecraft/block/BlockTorch.java.patch | 23 - .../minecraft/block/BlockTrapDoor.java.patch | 21 - .../net/minecraft/block/BlockVine.java.patch | 46 - .../net/minecraft/block/BlockWall.java.patch | 41 - .../net/minecraft/block/BlockWeb.java.patch | 29 - .../net/minecraft/block/SoundType.java.patch | 18 - .../BlockPistonStructureHelper.java.patch | 47 - .../block/state/BlockStateBase.java.patch | 13 - .../state/BlockStateContainer.java.patch | 140 -- .../block/state/IBlockProperties.java.patch | 30 - .../client/ClientBrandRetriever.java.patch | 10 - .../client/LoadingScreenRenderer.java.patch | 26 - .../net/minecraft/client/Minecraft.java.patch | 708 ------- .../client/audio/SoundHandler.java.patch | 52 - .../client/audio/SoundManager.java.patch | 64 - .../entity/AbstractClientPlayer.java.patch | 19 - .../entity/EntityOtherPlayerMP.java.patch | 10 - .../client/entity/EntityPlayerSP.java.patch | 133 -- .../client/gui/FontRenderer.java.patch | 257 --- .../client/gui/GuiBossOverlay.java.patch | 22 - .../minecraft/client/gui/GuiButton.java.patch | 22 - .../minecraft/client/gui/GuiChat.java.patch | 190 -- .../client/gui/GuiCommandBlock.java.patch | 166 -- .../client/gui/GuiControls.java.patch | 50 - .../client/gui/GuiCreateWorld.java.patch | 64 - .../client/gui/GuiEnchantment.java.patch | 26 - .../client/gui/GuiGameOver.java.patch | 11 - .../minecraft/client/gui/GuiIngame.java.patch | 36 - .../client/gui/GuiIngameMenu.java.patch | 58 - .../client/gui/GuiKeyBindingList.java.patch | 67 - .../client/gui/GuiLanguage.java.patch | 11 - .../client/gui/GuiListExtended.java.patch | 20 - .../gui/GuiListWorldSelectionEntry.java.patch | 11 - .../client/gui/GuiMainMenu.java.patch | 158 -- .../client/gui/GuiMultiplayer.java.patch | 19 - .../client/gui/GuiOptions.java.patch | 11 - .../client/gui/GuiOverlayDebug.java.patch | 64 - .../minecraft/client/gui/GuiScreen.java.patch | 119 -- .../client/gui/GuiScreenBook.java.patch | 10 - .../client/gui/GuiScreenDemo.java.patch | 29 - .../client/gui/GuiSleepMP.java.patch | 11 - .../minecraft/client/gui/GuiSlot.java.patch | 169 -- .../client/gui/GuiSpectator.java.patch | 11 - .../client/gui/GuiTextField.java.patch | 45 - .../gui/GuiUtilRenderComponents.java.patch | 28 - .../client/gui/GuiVideoSettings.java.patch | 15 - .../client/gui/MapItemRenderer.java.patch | 11 - .../client/gui/ScaledResolution.java.patch | 11 - .../gui/ServerListEntryNormal.java.patch | 23 - .../advancements/GuiAdvancementTab.java.patch | 40 - .../GuiScreenAdvancements.java.patch | 89 - .../gui/inventory/GuiContainer.java.patch | 157 -- .../inventory/GuiContainerCreative.java.patch | 325 ---- .../GuiEditCommandBlockMinecart.java.patch | 170 -- .../gui/recipebook/GuiRecipeBook.java.patch | 29 - .../recipebook/GuiRecipeOverlay.java.patch | 18 - .../client/gui/toasts/RecipeToast.java.patch | 11 - .../client/model/ModelBase.java.patch | 10 - .../client/model/ModelBox.java.patch | 18 - .../client/model/ModelRenderer.java.patch | 42 - .../client/model/ModelSkeleton.java.patch | 20 - .../model/PositionTextureVertex.java.patch | 13 - .../client/model/TexturedQuad.java.patch | 18 - .../ChunkProviderClient.java.patch | 36 - .../multiplayer/GuiConnecting.java.patch | 11 - .../multiplayer/PlayerControllerMP.java.patch | 217 --- .../client/multiplayer/WorldClient.java.patch | 22 - .../NetHandlerHandshakeMemory.java.patch | 10 - .../network/NetHandlerLoginClient.java.patch | 14 - .../network/NetHandlerPlayClient.java.patch | 153 -- .../client/network/ServerPinger.java.patch | 19 - .../client/particle/Particle.java.patch | 22 - .../particle/ParticleItemPickup.java.patch | 12 - .../particle/ParticleManager.java.patch | 33 - .../renderer/ActiveRenderInfo.java.patch | 39 - .../renderer/BlockFluidRenderer.java.patch | 14 - .../renderer/BlockModelRenderer.java.patch | 52 - .../renderer/BlockModelShapes.java.patch | 9 - .../BlockRendererDispatcher.java.patch | 31 - .../client/renderer/BufferBuilder.java.patch | 73 - .../client/renderer/ChestRenderer.java.patch | 11 - .../client/renderer/EntityRenderer.java.patch | 375 ---- .../InventoryEffectRenderer.java.patch | 40 - .../renderer/ItemModelMesher.java.patch | 13 - .../client/renderer/ItemRenderer.java.patch | 103 - .../client/renderer/OpenGlHelper.java.patch | 118 -- .../client/renderer/RenderGlobal.java.patch | 174 -- .../client/renderer/RenderItem.java.patch | 133 -- .../WorldVertexBufferUploader.java.patch | 57 - .../renderer/block/model/BakedQuad.java.patch | 55 - .../model/BakedQuadRetextured.java.patch | 39 - .../block/model/FaceBakery.java.patch | 150 -- .../block/model/IBakedModel.java.patch | 22 - .../model/ItemCameraTransforms.java.patch | 45 - .../block/model/ItemOverrideList.java.patch | 34 - .../block/model/ItemTransformVec3f.java.patch | 18 - .../block/model/ModelBakery.java.patch | 191 -- .../model/ModelBlockDefinition.java.patch | 15 - .../block/model/ModelManager.java.patch | 14 - .../model/ModelResourceLocation.java.patch | 14 - .../block/model/ModelRotation.java.patch | 21 - .../block/model/SimpleBakedModel.java.patch | 11 - .../renderer/block/model/Variant.java.patch | 39 - .../block/model/WeightedBakedModel.java.patch | 15 - .../block/statemap/StateMap.java.patch | 11 - .../chunk/ChunkRenderDispatcher.java.patch | 19 - .../chunk/ChunkRenderWorker.java.patch | 11 - .../renderer/chunk/RenderChunk.java.patch | 105 -- .../renderer/color/BlockColors.java.patch | 47 - .../renderer/color/ItemColors.java.patch | 49 - .../entity/RenderEntityItem.java.patch | 86 - .../renderer/entity/RenderFish.java.patch | 11 - .../entity/RenderItemFrame.java.patch | 43 - .../entity/RenderLivingBase.java.patch | 72 - .../renderer/entity/RenderManager.java.patch | 26 - .../renderer/entity/RenderPlayer.java.patch | 46 - .../renderer/entity/RenderVillager.java.patch | 26 - .../entity/RenderZombieVillager.java.patch | 10 - .../entity/layers/LayerArmorBase.java.patch | 93 - .../entity/layers/LayerBipedArmor.java.patch | 22 - .../entity/layers/LayerHeldItem.java.patch | 18 - .../layers/LayerHeldItemWitch.java.patch | 11 - .../LayeredColorMaskTexture.java.patch | 13 - .../renderer/texture/Stitcher.java.patch | 49 - .../texture/TextureAtlasSprite.java.patch | 59 - .../texture/TextureManager.java.patch | 31 - .../renderer/texture/TextureMap.java.patch | 264 --- .../renderer/texture/TextureUtil.java.patch | 48 - .../TileEntityItemStackRenderer.java.patch | 10 - .../TileEntityPistonRenderer.java.patch | 17 - .../TileEntityRendererDispatcher.java.patch | 94 - .../TileEntitySpecialRenderer.java.patch | 11 - .../renderer/vertex/VertexFormat.java.patch | 39 - .../vertex/VertexFormatElement.java.patch | 20 - .../resources/AbstractResourcePack.java.patch | 21 - .../FallbackResourceManager.java.patch | 10 - .../IResourceManagerReloadListener.java.patch | 14 - .../client/resources/Language.java.patch | 24 - .../resources/LegacyV2Adapter.java.patch | 11 - .../client/resources/Locale.java.patch | 38 - .../client/resources/ResourceIndex.java.patch | 11 - .../ResourcePackRepository.java.patch | 31 - ...SimpleReloadableResourceManager.java.patch | 45 - .../resources/SimpleResource.java.patch | 11 - .../client/settings/GameSettings.java.patch | 160 -- .../client/settings/KeyBinding.java.patch | 205 -- .../client/shader/Framebuffer.java.patch | 57 - .../client/shader/ShaderGroup.java.patch | 27 - .../client/shader/ShaderLoader.java.patch | 12 - .../client/shader/ShaderManager.java.patch | 21 - .../client/util/RecipeBookClient.java.patch | 19 - .../client/util/RecipeItemHelper.java.patch | 19 - .../minecraft/command/CommandBase.java.patch | 11 - .../minecraft/command/CommandFill.java.patch | 20 - .../command/CommandGameRule.java.patch | 10 - .../command/CommandHandler.java.patch | 20 - .../command/EntitySelector.java.patch | 46 - .../command/server/CommandSetBlock.java.patch | 11 - .../minecraft/crash/CrashReport.java.patch | 26 - .../crash/CrashReportCategory.java.patch | 25 - .../creativetab/CreativeTabs.java.patch | 98 - .../enchantment/Enchantment.java.patch | 50 - .../EnchantmentFrostWalker.java.patch | 10 - .../enchantment/EnchantmentHelper.java.patch | 67 - .../enchantment/EnchantmentThorns.java.patch | 44 - .../EnumEnchantmentType.java.patch | 17 - .../net/minecraft/entity/Entity.java.patch | 475 ----- .../minecraft/entity/EntityAgeable.java.patch | 20 - .../minecraft/entity/EntityFlying.java.patch | 46 - .../minecraft/entity/EntityHanging.java.patch | 12 - .../entity/EntityLeashKnot.java.patch | 10 - .../minecraft/entity/EntityList.java.patch | 180 -- .../minecraft/entity/EntityLiving.java.patch | 88 - .../entity/EntityLivingBase.java.patch | 541 ------ .../EntitySpawnPlacementRegistry.java.patch | 16 - .../minecraft/entity/EntityTracker.java.patch | 37 - .../entity/EntityTrackerEntry.java.patch | 44 - .../minecraft/entity/NpcMerchant.java.patch | 11 - .../entity/SharedMonsterAttributes.java.patch | 11 - .../entity/ai/EntityAIAttackMelee.java.patch | 55 - .../ai/EntityAIAttackRangedBow.java.patch | 11 - .../entity/ai/EntityAIBreakDoor.java.patch | 25 - .../entity/ai/EntityAIEatGrass.java.patch | 20 - .../ai/EntityAIHarvestFarmland.java.patch | 24 - .../entity/ai/EntityAIMate.java.patch | 21 - .../ai/EntityAIRunAroundLikeCrazy.java.patch | 11 - .../entity/ai/EntityAIVillagerMate.java.patch | 19 - .../entity/boss/EntityDragon.java.patch | 25 - .../entity/boss/EntityWither.java.patch | 31 - .../phase/PhaseSittingFlaming.java.patch | 11 - .../effect/EntityLightningBolt.java.patch | 12 - .../entity/item/EntityArmorStand.java.patch | 11 - .../entity/item/EntityBoat.java.patch | 83 - .../entity/item/EntityEnderPearl.java.patch | 41 - .../entity/item/EntityFallingBlock.java.patch | 28 - .../entity/item/EntityItem.java.patch | 151 -- .../entity/item/EntityItemFrame.java.patch | 18 - .../entity/item/EntityMinecart.java.patch | 499 ----- .../EntityMinecartCommandBlock.java.patch | 10 - .../item/EntityMinecartContainer.java.patch | 61 - .../item/EntityMinecartEmpty.java.patch | 11 - .../item/EntityMinecartFurnace.java.patch | 11 - .../item/EntityMinecartHopper.java.patch | 10 - .../item/EntityMinecartMobSpawner.java.patch | 13 - .../entity/item/EntityXPOrb.java.patch | 60 - .../monster/AbstractSkeleton.java.patch | 20 - .../entity/monster/EntityCreeper.java.patch | 11 - .../entity/monster/EntityEnderman.java.patch | 68 - .../entity/monster/EntityEvoker.java.patch | 11 - .../monster/EntityIllusionIllager.java.patch | 11 - .../entity/monster/EntityIronGolem.java.patch | 11 - .../entity/monster/EntityMagmaCube.java.patch | 10 - .../entity/monster/EntityMob.java.patch | 20 - .../entity/monster/EntityShulker.java.patch | 24 - .../monster/EntitySilverfish.java.patch | 20 - .../entity/monster/EntitySlime.java.patch | 43 - .../entity/monster/EntitySnowman.java.patch | 49 - .../entity/monster/EntitySpider.java.patch | 17 - .../entity/monster/EntityZombie.java.patch | 75 - .../monster/EntityZombieVillager.java.patch | 95 - .../entity/passive/AbstractHorse.java.patch | 34 - .../entity/passive/EntityHorse.java.patch | 80 - .../entity/passive/EntityLlama.java.patch | 12 - .../entity/passive/EntityMooshroom.java.patch | 56 - .../entity/passive/EntityOcelot.java.patch | 20 - .../entity/passive/EntityParrot.java.patch | 134 -- .../entity/passive/EntityRabbit.java.patch | 11 - .../entity/passive/EntitySheep.java.patch | 47 - .../entity/passive/EntityVillager.java.patch | 219 --- .../entity/passive/EntityWolf.java.patch | 11 - .../entity/passive/HorseArmorType.java.patch | 53 - .../entity/player/EntityPlayer.java.patch | 675 ------- .../entity/player/EntityPlayerMP.java.patch | 146 -- .../entity/player/InventoryPlayer.java.patch | 35 - .../entity/projectile/EntityArrow.java.patch | 11 - .../projectile/EntityFireball.java.patch | 11 - .../projectile/EntityFishHook.java.patch | 77 - .../projectile/EntityLargeFireball.java.patch | 11 - .../projectile/EntityLlamaSpit.java.patch | 11 - .../projectile/EntityShulkerBullet.java.patch | 11 - .../projectile/EntitySmallFireball.java.patch | 11 - .../projectile/EntityThrowable.java.patch | 11 - .../projectile/EntityWitherSkull.java.patch | 20 - .../net/minecraft/init/Bootstrap.java.patch | 28 - .../minecraft/inventory/Container.java.patch | 47 - .../inventory/ContainerBeacon.java.patch | 27 - .../ContainerBrewingStand.java.patch | 29 - .../inventory/ContainerEnchantment.java.patch | 99 - .../inventory/ContainerPlayer.java.patch | 11 - .../inventory/ContainerRepair.java.patch | 51 - .../net/minecraft/inventory/Slot.java.patch | 86 - .../inventory/SlotCrafting.java.patch | 20 - .../inventory/SlotFurnaceOutput.java.patch | 9 - .../net/minecraft/item/EnumRarity.java.patch | 29 - .../net/minecraft/item/Item.java.patch | 903 --------- .../net/minecraft/item/ItemArmor.java.patch | 73 - .../net/minecraft/item/ItemArrow.java.patch | 13 - .../net/minecraft/item/ItemAxe.java.patch | 16 - .../net/minecraft/item/ItemBed.java.patch | 11 - .../net/minecraft/item/ItemBlock.java.patch | 90 - .../item/ItemBlockSpecial.java.patch | 40 - .../net/minecraft/item/ItemBow.java.patch | 63 - .../net/minecraft/item/ItemBucket.java.patch | 30 - .../minecraft/item/ItemBucketMilk.java.patch | 33 - .../net/minecraft/item/ItemDoor.java.patch | 11 - .../net/minecraft/item/ItemDye.java.patch | 64 - .../item/ItemFlintAndSteel.java.patch | 11 - .../net/minecraft/item/ItemHoe.java.patch | 17 - .../net/minecraft/item/ItemLilyPad.java.patch | 18 - .../net/minecraft/item/ItemMap.java.patch | 46 - .../minecraft/item/ItemMinecart.java.patch | 29 - .../item/ItemMonsterPlacer.java.patch | 10 - .../minecraft/item/ItemRedstone.java.patch | 11 - .../minecraft/item/ItemSeedFood.java.patch | 41 - .../net/minecraft/item/ItemSeeds.java.patch | 41 - .../net/minecraft/item/ItemShears.java.patch | 84 - .../net/minecraft/item/ItemSkull.java.patch | 22 - .../net/minecraft/item/ItemSlab.java.patch | 20 - .../net/minecraft/item/ItemSnow.java.patch | 24 - .../net/minecraft/item/ItemStack.java.patch | 432 ----- .../net/minecraft/item/ItemSword.java.patch | 13 - .../net/minecraft/item/ItemTool.java.patch | 73 - .../item/crafting/CraftingManager.java.patch | 42 - .../item/crafting/FurnaceRecipes.java.patch | 20 - .../item/crafting/IRecipe.java.patch | 37 - .../item/crafting/Ingredient.java.patch | 113 -- .../crafting/RecipeBookCloning.java.patch | 22 - .../item/crafting/RecipeFireworks.java.patch | 67 - .../item/crafting/RecipeRepairItem.java.patch | 73 - .../crafting/RecipeTippedArrow.java.patch | 22 - .../item/crafting/RecipesArmorDyes.java.patch | 59 - .../item/crafting/RecipesBanners.java.patch | 97 - .../crafting/RecipesMapCloning.java.patch | 35 - .../item/crafting/ShapedRecipes.java.patch | 84 - .../item/crafting/ShapelessRecipes.java.patch | 103 - .../item/crafting/ShieldRecipes.java.patch | 24 - .../crafting/ShulkerBoxRecipes.java.patch | 50 - .../nbt/CompressedStreamTools.java.patch | 53 - .../minecraft/nbt/NBTSizeTracker.java.patch | 37 - .../minecraft/nbt/NBTTagCompound.java.patch | 26 - .../net/minecraft/nbt/NBTTagList.java.patch | 17 - .../net/minecraft/nbt/NBTTagString.java.patch | 11 - .../network/NetHandlerPlayServer.java.patch | 144 -- .../network/NettyPacketEncoder.java.patch | 11 - .../network/NetworkManager.java.patch | 61 - .../network/NetworkSystem.java.patch | 61 - .../minecraft/network/PacketBuffer.java.patch | 20 - .../network/ServerStatusResponse.java.patch | 90 - .../datasync/DataSerializers.java.patch | 27 - .../datasync/EntityDataManager.java.patch | 22 - .../handshake/client/C00Handshake.java.patch | 51 - .../server/SPacketLoginSuccess.java.patch | 11 - .../play/client/CPacketClickWindow.java.patch | 11 - .../CPacketCreativeInventoryAction.java.patch | 11 - .../client/CPacketCustomPayload.java.patch | 14 - .../server/SPacketCustomPayload.java.patch | 21 - .../play/server/SPacketSpawnMob.java.patch | 11 - .../FlyingNodeProcessor.java.patch | 22 - .../PathNavigateClimber.java.patch | 11 - .../pathfinding/WalkNodeProcessor.java.patch | 65 - .../net/minecraft/potion/Potion.java.patch | 144 -- .../minecraft/potion/PotionEffect.java.patch | 150 -- .../minecraft/potion/PotionHelper.java.patch | 67 - .../minecraft/potion/PotionType.java.patch | 16 - .../minecraft/profiler/Profiler.java.patch | 19 - .../minecraft/realms/RealmsConnect.java.patch | 19 - .../server/MinecraftServer.java.patch | 342 ---- .../dedicated/DedicatedServer.java.patch | 92 - .../dedicated/ServerHangWatchdog.java.patch | 11 - .../server/gui/MinecraftServerGui.java.patch | 24 - .../integrated/IntegratedServer.java.patch | 79 - .../management/PlayerChunkMapEntry.java.patch | 162 -- .../PlayerInteractionManager.java.patch | 291 --- .../server/management/PlayerList.java.patch | 267 --- .../network/NetHandlerHandshakeTCP.java.patch | 11 - .../network/NetHandlerLoginServer.java.patch | 29 - .../net/minecraft/stats/RecipeBook.java.patch | 21 - .../stats/RecipeBookServer.java.patch | 23 - .../net/minecraft/stats/StatList.java.patch | 139 -- .../stats/StatisticsManagerServer.java.patch | 11 - .../tileentity/MobSpawnerBaseLogic.java.patch | 25 - .../tileentity/TileEntity.java.patch | 285 --- .../tileentity/TileEntityBeacon.java.patch | 48 - .../TileEntityBrewingStand.java.patch | 87 - .../tileentity/TileEntityChest.java.patch | 47 - .../tileentity/TileEntityFurnace.java.patch | 99 - .../tileentity/TileEntityHopper.java.patch | 62 - .../tileentity/TileEntityLockable.java.patch | 30 - .../TileEntityLockableLoot.java.patch | 11 - .../tileentity/TileEntityNote.java.patch | 12 - .../tileentity/TileEntityPiston.java.patch | 11 - .../TileEntityShulkerBox.java.patch | 12 - .../tileentity/TileEntitySign.java.patch | 11 - .../minecraft/util/ActionResult.java.patch | 13 - .../util/BlockRenderLayer.java.patch | 12 - .../util/ChatAllowedCharacters.java.patch | 10 - .../util/ClassInheritanceMultiMap.java.patch | 12 - .../net/minecraft/util/EnumFacing.java.patch | 67 - .../util/IntIdentityHashBiMap.java.patch | 10 - .../net/minecraft/util/MouseHelper.java.patch | 10 - .../util/ScreenShotHelper.java.patch | 17 - .../util/ServerRecipeBookHelper.java.patch | 30 - .../net/minecraft/util/Session.java.patch | 59 - .../net/minecraft/util/SoundEvent.java.patch | 14 - .../minecraft/util/TabCompleter.java.patch | 39 - .../util/datafix/DataFixesManager.java.patch | 10 - .../minecraft/util/math/ChunkPos.java.patch | 19 - .../util/math/RayTraceResult.java.patch | 15 - .../net/minecraft/util/math/Vec2f.java.patch | 12 - .../net/minecraft/util/math/Vec3d.java.patch | 42 - .../util/text/ITextComponent.java.patch | 10 - .../net/minecraft/util/text/Style.java.patch | 18 - .../util/text/TextComponentBase.java.patch | 10 - .../text/translation/LanguageMap.java.patch | 61 - .../net/minecraft/village/Village.java.patch | 202 -- .../village/VillageCollection.java.patch | 10 - .../minecraft/village/VillageSiege.java.patch | 10 - .../net/minecraft/world/BossInfo.java.patch | 27 - .../minecraft/world/BossInfoServer.java.patch | 27 - .../net/minecraft/world/ChunkCache.java.patch | 76 - .../minecraft/world/DimensionType.java.patch | 39 - .../net/minecraft/world/Explosion.java.patch | 52 - .../minecraft/world/IBlockAccess.java.patch | 17 - .../world/ServerWorldEventHandler.java.patch | 20 - .../net/minecraft/world/Teleporter.java.patch | 26 - .../net/minecraft/world/World.java.patch | 1290 ------------- .../world/WorldEntitySpawner.java.patch | 109 -- .../minecraft/world/WorldProvider.java.patch | 447 ----- .../world/WorldProviderEnd.java.patch | 44 - .../world/WorldProviderSurface.java.patch | 10 - .../minecraft/world/WorldServer.java.patch | 307 --- .../world/WorldServerMulti.java.patch | 65 - .../net/minecraft/world/WorldType.java.patch | 157 -- .../minecraft/world/biome/Biome.java.patch | 180 -- .../world/biome/BiomeDecorator.java.patch | 224 --- .../world/biome/BiomeDesert.java.patch | 18 - .../world/biome/BiomeForest.java.patch | 52 - .../world/biome/BiomeHills.java.patch | 65 - .../world/biome/BiomeJungle.java.patch | 19 - .../world/biome/BiomeMesa.java.patch | 27 - .../world/biome/BiomePlains.java.patch | 40 - .../world/biome/BiomeProvider.java.patch | 34 - .../world/biome/BiomeSavanna.java.patch | 10 - .../world/biome/BiomeSnow.java.patch | 11 - .../world/biome/BiomeSwamp.java.patch | 36 - .../world/biome/BiomeTaiga.java.patch | 19 - .../world/border/WorldBorder.java.patch | 12 - .../chunk/BlockStateContainer.java.patch | 39 - .../minecraft/world/chunk/Chunk.java.patch | 403 ---- .../chunk/storage/AnvilChunkLoader.java.patch | 196 -- .../chunk/storage/AnvilSaveHandler.java.patch | 22 - .../storage/ExtendedBlockStorage.java.patch | 11 - .../world/chunk/storage/RegionFile.java.patch | 116 -- .../world/end/DragonFightManager.java.patch | 34 - .../world/gen/ChunkGeneratorEnd.java.patch | 73 - .../world/gen/ChunkGeneratorFlat.java.patch | 29 - .../world/gen/ChunkGeneratorHell.java.patch | 129 -- .../gen/ChunkGeneratorOverworld.java.patch | 101 - .../world/gen/ChunkProviderServer.java.patch | 91 - .../world/gen/MapGenCaves.java.patch | 118 -- .../world/gen/MapGenRavine.java.patch | 128 -- .../feature/WorldGenAbstractTree.java.patch | 13 - .../feature/WorldGenBigMushroom.java.patch | 34 - .../gen/feature/WorldGenBigTree.java.patch | 52 - .../gen/feature/WorldGenBirchTree.java.patch | 59 - .../world/gen/feature/WorldGenBush.java.patch | 11 - .../gen/feature/WorldGenCanopyTree.java.patch | 72 - .../gen/feature/WorldGenDeadBush.java.patch | 11 - .../gen/feature/WorldGenDungeons.java.patch | 10 - .../gen/feature/WorldGenGlowStone1.java.patch | 11 - .../gen/feature/WorldGenGlowStone2.java.patch | 11 - .../gen/feature/WorldGenHellLava.java.patch | 11 - .../gen/feature/WorldGenHugeTrees.java.patch | 69 - .../gen/feature/WorldGenIceSpike.java.patch | 29 - .../gen/feature/WorldGenLakes.java.patch | 12 - .../gen/feature/WorldGenLiquids.java.patch | 11 - .../gen/feature/WorldGenMegaJungle.java.patch | 51 - .../feature/WorldGenMegaPineTree.java.patch | 61 - .../gen/feature/WorldGenMinable.java.patch | 12 - .../feature/WorldGenSavannaTree.java.patch | 64 - .../gen/feature/WorldGenShrub.java.patch | 34 - .../gen/feature/WorldGenSwamp.java.patch | 96 - .../gen/feature/WorldGenTaiga1.java.patch | 52 - .../gen/feature/WorldGenTaiga2.java.patch | 68 - .../gen/feature/WorldGenTallGrass.java.patch | 11 - .../gen/feature/WorldGenTrees.java.patch | 112 -- .../gen/feature/WorldGenerator.java.patch | 12 - .../WorldGeneratorBonusChest.java.patch | 47 - .../world/gen/layer/GenLayer.java.patch | 57 - .../world/gen/layer/GenLayerBiome.java.patch | 103 - .../gen/structure/MapGenStronghold.java.patch | 30 - .../gen/structure/MapGenStructure.java.patch | 17 - .../structure/StructureComponent.java.patch | 13 - .../gen/structure/StructureStart.java.patch | 23 - .../StructureVillagePieces.java.patch | 95 - .../structure/template/Template.java.patch | 19 - .../world/storage/DerivedWorldInfo.java.patch | 30 - .../world/storage/MapData.java.patch | 41 - .../world/storage/MapDecoration.java.patch | 20 - .../world/storage/SaveFormatOld.java.patch | 27 - .../world/storage/SaveHandler.java.patch | 71 - .../world/storage/WorldInfo.java.patch | 101 - .../world/storage/WorldSavedData.java.patch | 27 - .../world/storage/loot/LootContext.java.patch | 19 - .../world/storage/loot/LootEntry.java.patch | 59 - .../storage/loot/LootEntryEmpty.java.patch | 22 - .../storage/loot/LootEntryItem.java.patch | 39 - .../storage/loot/LootEntryTable.java.patch | 24 - .../world/storage/loot/LootPool.java.patch | 114 -- .../world/storage/loot/LootTable.java.patch | 75 - .../storage/loot/LootTableManager.java.patch | 20 - .../LootConditionManager.java.patch | 18 - .../RandomChanceWithLooting.java.patch | 16 - .../functions/LootingEnchantBonus.java.patch | 11 - 544 files changed, 33501 deletions(-) delete mode 100644 patches/minecraft/net/minecraft/advancements/AdvancementManager.java.patch delete mode 100644 patches/minecraft/net/minecraft/advancements/AdvancementRewards.java.patch delete mode 100644 patches/minecraft/net/minecraft/advancements/DisplayInfo.java.patch delete mode 100644 patches/minecraft/net/minecraft/advancements/PlayerAdvancements.java.patch delete mode 100644 patches/minecraft/net/minecraft/advancements/critereon/ItemPredicate.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/Block.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockBanner.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockBed.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockBush.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockButton.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockCactus.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockChest.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockChorusFlower.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockCocoa.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockCrops.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockDeadBush.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockDoor.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockDoublePlant.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockDragonEgg.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockDropper.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockDynamicLiquid.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockEnchantmentTable.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockEnderChest.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockFalling.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockFarmland.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockFence.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockFenceGate.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockFire.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockFlowerPot.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockGrass.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockHugeMushroom.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockIce.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockLadder.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockLeaves.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockLiquid.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockLog.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockMobSpawner.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockMushroom.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockMycelium.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockNetherWart.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockNewLeaf.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockNote.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockObserver.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockOldLeaf.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockOre.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockPane.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockPistonBase.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockPistonMoving.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockPortal.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockPotato.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockPumpkin.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockQuartz.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockRailBase.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockRailDetector.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockRailPowered.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockRedstoneComparator.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockRedstoneDiode.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockRedstoneOre.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockRedstoneTorch.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockRedstoneWire.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockReed.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockRotatedPillar.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockSapling.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockSkull.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockSlab.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockSnow.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockStairs.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockStaticLiquid.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockStem.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockTallGrass.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockTorch.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockTrapDoor.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockVine.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockWall.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/BlockWeb.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/SoundType.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/state/BlockPistonStructureHelper.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/state/BlockStateBase.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/state/BlockStateContainer.java.patch delete mode 100644 patches/minecraft/net/minecraft/block/state/IBlockProperties.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/ClientBrandRetriever.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/LoadingScreenRenderer.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/Minecraft.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/audio/SoundHandler.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/audio/SoundManager.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/entity/AbstractClientPlayer.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/entity/EntityOtherPlayerMP.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/entity/EntityPlayerSP.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/FontRenderer.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/GuiBossOverlay.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/GuiButton.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/GuiChat.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/GuiCommandBlock.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/GuiControls.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/GuiCreateWorld.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/GuiEnchantment.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/GuiGameOver.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/GuiIngame.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/GuiIngameMenu.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/GuiKeyBindingList.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/GuiLanguage.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/GuiListExtended.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/GuiListWorldSelectionEntry.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/GuiMainMenu.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/GuiMultiplayer.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/GuiOptions.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/GuiOverlayDebug.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/GuiScreen.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/GuiScreenBook.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/GuiScreenDemo.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/GuiSleepMP.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/GuiSlot.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/GuiSpectator.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/GuiTextField.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/GuiUtilRenderComponents.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/GuiVideoSettings.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/MapItemRenderer.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/ScaledResolution.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/ServerListEntryNormal.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/advancements/GuiAdvancementTab.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/advancements/GuiScreenAdvancements.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/inventory/GuiContainer.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/inventory/GuiContainerCreative.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/inventory/GuiEditCommandBlockMinecart.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/recipebook/GuiRecipeBook.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/recipebook/GuiRecipeOverlay.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/gui/toasts/RecipeToast.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/model/ModelBase.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/model/ModelBox.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/model/ModelRenderer.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/model/ModelSkeleton.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/model/PositionTextureVertex.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/model/TexturedQuad.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/multiplayer/ChunkProviderClient.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/multiplayer/GuiConnecting.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/multiplayer/PlayerControllerMP.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/multiplayer/WorldClient.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/network/NetHandlerHandshakeMemory.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/network/NetHandlerLoginClient.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/network/NetHandlerPlayClient.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/network/ServerPinger.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/particle/Particle.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/particle/ParticleItemPickup.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/particle/ParticleManager.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/ActiveRenderInfo.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/BlockFluidRenderer.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/BlockModelRenderer.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/BlockModelShapes.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/BlockRendererDispatcher.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/BufferBuilder.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/ChestRenderer.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/EntityRenderer.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/InventoryEffectRenderer.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/ItemModelMesher.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/ItemRenderer.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/OpenGlHelper.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/RenderGlobal.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/RenderItem.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/WorldVertexBufferUploader.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/block/model/BakedQuad.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/block/model/BakedQuadRetextured.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/block/model/FaceBakery.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/block/model/IBakedModel.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/block/model/ItemCameraTransforms.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/block/model/ItemOverrideList.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/block/model/ItemTransformVec3f.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/block/model/ModelBakery.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/block/model/ModelBlockDefinition.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/block/model/ModelManager.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/block/model/ModelResourceLocation.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/block/model/ModelRotation.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/block/model/SimpleBakedModel.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/block/model/Variant.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/block/model/WeightedBakedModel.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/block/statemap/StateMap.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/chunk/ChunkRenderDispatcher.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/chunk/ChunkRenderWorker.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/chunk/RenderChunk.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/color/BlockColors.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/color/ItemColors.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/entity/RenderEntityItem.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/entity/RenderFish.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/entity/RenderItemFrame.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/entity/RenderLivingBase.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/entity/RenderManager.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/entity/RenderPlayer.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/entity/RenderVillager.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/entity/RenderZombieVillager.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/entity/layers/LayerArmorBase.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/entity/layers/LayerBipedArmor.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/entity/layers/LayerHeldItem.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/entity/layers/LayerHeldItemWitch.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/texture/LayeredColorMaskTexture.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/texture/Stitcher.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/texture/TextureAtlasSprite.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/texture/TextureManager.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/texture/TextureMap.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/texture/TextureUtil.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/tileentity/TileEntityItemStackRenderer.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/tileentity/TileEntityPistonRenderer.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/tileentity/TileEntityRendererDispatcher.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/tileentity/TileEntitySpecialRenderer.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/vertex/VertexFormat.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/vertex/VertexFormatElement.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/resources/AbstractResourcePack.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/resources/FallbackResourceManager.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/resources/IResourceManagerReloadListener.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/resources/Language.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/resources/LegacyV2Adapter.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/resources/Locale.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/resources/ResourceIndex.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/resources/ResourcePackRepository.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/resources/SimpleReloadableResourceManager.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/resources/SimpleResource.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/settings/GameSettings.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/settings/KeyBinding.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/shader/Framebuffer.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/shader/ShaderGroup.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/shader/ShaderLoader.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/shader/ShaderManager.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/util/RecipeBookClient.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/util/RecipeItemHelper.java.patch delete mode 100644 patches/minecraft/net/minecraft/command/CommandBase.java.patch delete mode 100644 patches/minecraft/net/minecraft/command/CommandFill.java.patch delete mode 100644 patches/minecraft/net/minecraft/command/CommandGameRule.java.patch delete mode 100644 patches/minecraft/net/minecraft/command/CommandHandler.java.patch delete mode 100644 patches/minecraft/net/minecraft/command/EntitySelector.java.patch delete mode 100644 patches/minecraft/net/minecraft/command/server/CommandSetBlock.java.patch delete mode 100644 patches/minecraft/net/minecraft/crash/CrashReport.java.patch delete mode 100644 patches/minecraft/net/minecraft/crash/CrashReportCategory.java.patch delete mode 100644 patches/minecraft/net/minecraft/creativetab/CreativeTabs.java.patch delete mode 100644 patches/minecraft/net/minecraft/enchantment/Enchantment.java.patch delete mode 100644 patches/minecraft/net/minecraft/enchantment/EnchantmentFrostWalker.java.patch delete mode 100644 patches/minecraft/net/minecraft/enchantment/EnchantmentHelper.java.patch delete mode 100644 patches/minecraft/net/minecraft/enchantment/EnchantmentThorns.java.patch delete mode 100644 patches/minecraft/net/minecraft/enchantment/EnumEnchantmentType.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/Entity.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/EntityAgeable.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/EntityFlying.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/EntityHanging.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/EntityLeashKnot.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/EntityList.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/EntityLiving.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/EntityLivingBase.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/EntitySpawnPlacementRegistry.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/EntityTracker.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/EntityTrackerEntry.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/NpcMerchant.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/SharedMonsterAttributes.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/ai/EntityAIAttackMelee.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/ai/EntityAIAttackRangedBow.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/ai/EntityAIBreakDoor.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/ai/EntityAIEatGrass.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/ai/EntityAIHarvestFarmland.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/ai/EntityAIMate.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/ai/EntityAIRunAroundLikeCrazy.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/ai/EntityAIVillagerMate.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/boss/EntityDragon.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/boss/EntityWither.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/boss/dragon/phase/PhaseSittingFlaming.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/effect/EntityLightningBolt.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/item/EntityArmorStand.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/item/EntityBoat.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/item/EntityEnderPearl.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/item/EntityFallingBlock.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/item/EntityItem.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/item/EntityItemFrame.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/item/EntityMinecart.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/item/EntityMinecartCommandBlock.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/item/EntityMinecartContainer.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/item/EntityMinecartEmpty.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/item/EntityMinecartFurnace.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/item/EntityMinecartHopper.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/item/EntityMinecartMobSpawner.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/item/EntityXPOrb.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/monster/AbstractSkeleton.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/monster/EntityCreeper.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/monster/EntityEnderman.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/monster/EntityEvoker.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/monster/EntityIllusionIllager.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/monster/EntityIronGolem.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/monster/EntityMagmaCube.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/monster/EntityMob.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/monster/EntityShulker.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/monster/EntitySilverfish.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/monster/EntitySlime.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/monster/EntitySnowman.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/monster/EntitySpider.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/monster/EntityZombie.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/monster/EntityZombieVillager.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/passive/AbstractHorse.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/passive/EntityHorse.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/passive/EntityLlama.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/passive/EntityMooshroom.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/passive/EntityOcelot.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/passive/EntityParrot.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/passive/EntityRabbit.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/passive/EntitySheep.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/passive/EntityVillager.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/passive/EntityWolf.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/passive/HorseArmorType.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/player/EntityPlayer.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/player/EntityPlayerMP.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/player/InventoryPlayer.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/projectile/EntityArrow.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/projectile/EntityFireball.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/projectile/EntityFishHook.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/projectile/EntityLargeFireball.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/projectile/EntityLlamaSpit.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/projectile/EntityShulkerBullet.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/projectile/EntitySmallFireball.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/projectile/EntityThrowable.java.patch delete mode 100644 patches/minecraft/net/minecraft/entity/projectile/EntityWitherSkull.java.patch delete mode 100644 patches/minecraft/net/minecraft/init/Bootstrap.java.patch delete mode 100644 patches/minecraft/net/minecraft/inventory/Container.java.patch delete mode 100644 patches/minecraft/net/minecraft/inventory/ContainerBeacon.java.patch delete mode 100644 patches/minecraft/net/minecraft/inventory/ContainerBrewingStand.java.patch delete mode 100644 patches/minecraft/net/minecraft/inventory/ContainerEnchantment.java.patch delete mode 100644 patches/minecraft/net/minecraft/inventory/ContainerPlayer.java.patch delete mode 100644 patches/minecraft/net/minecraft/inventory/ContainerRepair.java.patch delete mode 100644 patches/minecraft/net/minecraft/inventory/Slot.java.patch delete mode 100644 patches/minecraft/net/minecraft/inventory/SlotCrafting.java.patch delete mode 100644 patches/minecraft/net/minecraft/inventory/SlotFurnaceOutput.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/EnumRarity.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/Item.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/ItemArmor.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/ItemArrow.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/ItemAxe.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/ItemBed.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/ItemBlock.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/ItemBlockSpecial.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/ItemBow.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/ItemBucket.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/ItemBucketMilk.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/ItemDoor.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/ItemDye.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/ItemFlintAndSteel.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/ItemHoe.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/ItemLilyPad.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/ItemMap.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/ItemMinecart.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/ItemMonsterPlacer.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/ItemRedstone.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/ItemSeedFood.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/ItemSeeds.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/ItemShears.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/ItemSkull.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/ItemSlab.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/ItemSnow.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/ItemStack.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/ItemSword.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/ItemTool.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/crafting/CraftingManager.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/crafting/FurnaceRecipes.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/crafting/IRecipe.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/crafting/Ingredient.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/crafting/RecipeBookCloning.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/crafting/RecipeFireworks.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/crafting/RecipeRepairItem.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/crafting/RecipeTippedArrow.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/crafting/RecipesArmorDyes.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/crafting/RecipesBanners.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/crafting/RecipesMapCloning.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/crafting/ShapedRecipes.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/crafting/ShapelessRecipes.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/crafting/ShieldRecipes.java.patch delete mode 100644 patches/minecraft/net/minecraft/item/crafting/ShulkerBoxRecipes.java.patch delete mode 100644 patches/minecraft/net/minecraft/nbt/CompressedStreamTools.java.patch delete mode 100644 patches/minecraft/net/minecraft/nbt/NBTSizeTracker.java.patch delete mode 100644 patches/minecraft/net/minecraft/nbt/NBTTagCompound.java.patch delete mode 100644 patches/minecraft/net/minecraft/nbt/NBTTagList.java.patch delete mode 100644 patches/minecraft/net/minecraft/nbt/NBTTagString.java.patch delete mode 100644 patches/minecraft/net/minecraft/network/NetHandlerPlayServer.java.patch delete mode 100644 patches/minecraft/net/minecraft/network/NettyPacketEncoder.java.patch delete mode 100644 patches/minecraft/net/minecraft/network/NetworkManager.java.patch delete mode 100644 patches/minecraft/net/minecraft/network/NetworkSystem.java.patch delete mode 100644 patches/minecraft/net/minecraft/network/PacketBuffer.java.patch delete mode 100644 patches/minecraft/net/minecraft/network/ServerStatusResponse.java.patch delete mode 100644 patches/minecraft/net/minecraft/network/datasync/DataSerializers.java.patch delete mode 100644 patches/minecraft/net/minecraft/network/datasync/EntityDataManager.java.patch delete mode 100644 patches/minecraft/net/minecraft/network/handshake/client/C00Handshake.java.patch delete mode 100644 patches/minecraft/net/minecraft/network/login/server/SPacketLoginSuccess.java.patch delete mode 100644 patches/minecraft/net/minecraft/network/play/client/CPacketClickWindow.java.patch delete mode 100644 patches/minecraft/net/minecraft/network/play/client/CPacketCreativeInventoryAction.java.patch delete mode 100644 patches/minecraft/net/minecraft/network/play/client/CPacketCustomPayload.java.patch delete mode 100644 patches/minecraft/net/minecraft/network/play/server/SPacketCustomPayload.java.patch delete mode 100644 patches/minecraft/net/minecraft/network/play/server/SPacketSpawnMob.java.patch delete mode 100644 patches/minecraft/net/minecraft/pathfinding/FlyingNodeProcessor.java.patch delete mode 100644 patches/minecraft/net/minecraft/pathfinding/PathNavigateClimber.java.patch delete mode 100644 patches/minecraft/net/minecraft/pathfinding/WalkNodeProcessor.java.patch delete mode 100644 patches/minecraft/net/minecraft/potion/Potion.java.patch delete mode 100644 patches/minecraft/net/minecraft/potion/PotionEffect.java.patch delete mode 100644 patches/minecraft/net/minecraft/potion/PotionHelper.java.patch delete mode 100644 patches/minecraft/net/minecraft/potion/PotionType.java.patch delete mode 100644 patches/minecraft/net/minecraft/profiler/Profiler.java.patch delete mode 100644 patches/minecraft/net/minecraft/realms/RealmsConnect.java.patch delete mode 100644 patches/minecraft/net/minecraft/server/MinecraftServer.java.patch delete mode 100644 patches/minecraft/net/minecraft/server/dedicated/DedicatedServer.java.patch delete mode 100644 patches/minecraft/net/minecraft/server/dedicated/ServerHangWatchdog.java.patch delete mode 100644 patches/minecraft/net/minecraft/server/gui/MinecraftServerGui.java.patch delete mode 100644 patches/minecraft/net/minecraft/server/integrated/IntegratedServer.java.patch delete mode 100644 patches/minecraft/net/minecraft/server/management/PlayerChunkMapEntry.java.patch delete mode 100644 patches/minecraft/net/minecraft/server/management/PlayerInteractionManager.java.patch delete mode 100644 patches/minecraft/net/minecraft/server/management/PlayerList.java.patch delete mode 100644 patches/minecraft/net/minecraft/server/network/NetHandlerHandshakeTCP.java.patch delete mode 100644 patches/minecraft/net/minecraft/server/network/NetHandlerLoginServer.java.patch delete mode 100644 patches/minecraft/net/minecraft/stats/RecipeBook.java.patch delete mode 100644 patches/minecraft/net/minecraft/stats/RecipeBookServer.java.patch delete mode 100644 patches/minecraft/net/minecraft/stats/StatList.java.patch delete mode 100644 patches/minecraft/net/minecraft/stats/StatisticsManagerServer.java.patch delete mode 100644 patches/minecraft/net/minecraft/tileentity/MobSpawnerBaseLogic.java.patch delete mode 100644 patches/minecraft/net/minecraft/tileentity/TileEntity.java.patch delete mode 100644 patches/minecraft/net/minecraft/tileentity/TileEntityBeacon.java.patch delete mode 100644 patches/minecraft/net/minecraft/tileentity/TileEntityBrewingStand.java.patch delete mode 100644 patches/minecraft/net/minecraft/tileentity/TileEntityChest.java.patch delete mode 100644 patches/minecraft/net/minecraft/tileentity/TileEntityFurnace.java.patch delete mode 100644 patches/minecraft/net/minecraft/tileentity/TileEntityHopper.java.patch delete mode 100644 patches/minecraft/net/minecraft/tileentity/TileEntityLockable.java.patch delete mode 100644 patches/minecraft/net/minecraft/tileentity/TileEntityLockableLoot.java.patch delete mode 100644 patches/minecraft/net/minecraft/tileentity/TileEntityNote.java.patch delete mode 100644 patches/minecraft/net/minecraft/tileentity/TileEntityPiston.java.patch delete mode 100644 patches/minecraft/net/minecraft/tileentity/TileEntityShulkerBox.java.patch delete mode 100644 patches/minecraft/net/minecraft/tileentity/TileEntitySign.java.patch delete mode 100644 patches/minecraft/net/minecraft/util/ActionResult.java.patch delete mode 100644 patches/minecraft/net/minecraft/util/BlockRenderLayer.java.patch delete mode 100644 patches/minecraft/net/minecraft/util/ChatAllowedCharacters.java.patch delete mode 100644 patches/minecraft/net/minecraft/util/ClassInheritanceMultiMap.java.patch delete mode 100644 patches/minecraft/net/minecraft/util/EnumFacing.java.patch delete mode 100644 patches/minecraft/net/minecraft/util/IntIdentityHashBiMap.java.patch delete mode 100644 patches/minecraft/net/minecraft/util/MouseHelper.java.patch delete mode 100644 patches/minecraft/net/minecraft/util/ScreenShotHelper.java.patch delete mode 100644 patches/minecraft/net/minecraft/util/ServerRecipeBookHelper.java.patch delete mode 100644 patches/minecraft/net/minecraft/util/Session.java.patch delete mode 100644 patches/minecraft/net/minecraft/util/SoundEvent.java.patch delete mode 100644 patches/minecraft/net/minecraft/util/TabCompleter.java.patch delete mode 100644 patches/minecraft/net/minecraft/util/datafix/DataFixesManager.java.patch delete mode 100644 patches/minecraft/net/minecraft/util/math/ChunkPos.java.patch delete mode 100644 patches/minecraft/net/minecraft/util/math/RayTraceResult.java.patch delete mode 100644 patches/minecraft/net/minecraft/util/math/Vec2f.java.patch delete mode 100644 patches/minecraft/net/minecraft/util/math/Vec3d.java.patch delete mode 100644 patches/minecraft/net/minecraft/util/text/ITextComponent.java.patch delete mode 100644 patches/minecraft/net/minecraft/util/text/Style.java.patch delete mode 100644 patches/minecraft/net/minecraft/util/text/TextComponentBase.java.patch delete mode 100644 patches/minecraft/net/minecraft/util/text/translation/LanguageMap.java.patch delete mode 100644 patches/minecraft/net/minecraft/village/Village.java.patch delete mode 100644 patches/minecraft/net/minecraft/village/VillageCollection.java.patch delete mode 100644 patches/minecraft/net/minecraft/village/VillageSiege.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/BossInfo.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/BossInfoServer.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/ChunkCache.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/DimensionType.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/Explosion.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/IBlockAccess.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/ServerWorldEventHandler.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/Teleporter.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/World.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/WorldEntitySpawner.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/WorldProvider.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/WorldProviderEnd.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/WorldProviderSurface.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/WorldServer.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/WorldServerMulti.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/WorldType.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/biome/Biome.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/biome/BiomeDecorator.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/biome/BiomeDesert.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/biome/BiomeForest.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/biome/BiomeHills.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/biome/BiomeJungle.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/biome/BiomeMesa.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/biome/BiomePlains.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/biome/BiomeProvider.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/biome/BiomeSavanna.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/biome/BiomeSnow.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/biome/BiomeSwamp.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/biome/BiomeTaiga.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/border/WorldBorder.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/chunk/BlockStateContainer.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/chunk/Chunk.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/chunk/storage/AnvilChunkLoader.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/chunk/storage/AnvilSaveHandler.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/chunk/storage/ExtendedBlockStorage.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/chunk/storage/RegionFile.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/end/DragonFightManager.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/ChunkGeneratorEnd.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/ChunkGeneratorFlat.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/ChunkGeneratorHell.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/ChunkGeneratorOverworld.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/ChunkProviderServer.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/MapGenCaves.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/MapGenRavine.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/feature/WorldGenAbstractTree.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/feature/WorldGenBigMushroom.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/feature/WorldGenBigTree.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/feature/WorldGenBirchTree.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/feature/WorldGenBush.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/feature/WorldGenCanopyTree.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/feature/WorldGenDeadBush.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/feature/WorldGenDungeons.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/feature/WorldGenGlowStone1.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/feature/WorldGenGlowStone2.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/feature/WorldGenHellLava.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/feature/WorldGenHugeTrees.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/feature/WorldGenIceSpike.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/feature/WorldGenLakes.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/feature/WorldGenLiquids.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/feature/WorldGenMegaJungle.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/feature/WorldGenMegaPineTree.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/feature/WorldGenMinable.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/feature/WorldGenSavannaTree.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/feature/WorldGenShrub.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/feature/WorldGenSwamp.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/feature/WorldGenTaiga1.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/feature/WorldGenTaiga2.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/feature/WorldGenTallGrass.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/feature/WorldGenTrees.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/feature/WorldGenerator.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/feature/WorldGeneratorBonusChest.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/layer/GenLayer.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/layer/GenLayerBiome.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/structure/MapGenStronghold.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/structure/MapGenStructure.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/structure/StructureComponent.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/structure/StructureStart.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/structure/StructureVillagePieces.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/gen/structure/template/Template.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/storage/DerivedWorldInfo.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/storage/MapData.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/storage/MapDecoration.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/storage/SaveFormatOld.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/storage/SaveHandler.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/storage/WorldInfo.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/storage/WorldSavedData.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/storage/loot/LootContext.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/storage/loot/LootEntry.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/storage/loot/LootEntryEmpty.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/storage/loot/LootEntryItem.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/storage/loot/LootEntryTable.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/storage/loot/LootPool.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/storage/loot/LootTable.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/storage/loot/LootTableManager.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/storage/loot/conditions/LootConditionManager.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/storage/loot/conditions/RandomChanceWithLooting.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/storage/loot/functions/LootingEnchantBonus.java.patch diff --git a/patches/minecraft/net/minecraft/advancements/AdvancementManager.java.patch b/patches/minecraft/net/minecraft/advancements/AdvancementManager.java.patch deleted file mode 100644 index e3b4f75e0..000000000 --- a/patches/minecraft/net/minecraft/advancements/AdvancementManager.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- before/net/minecraft/advancements/AdvancementManager.java -+++ after/net/minecraft/advancements/AdvancementManager.java -@@ -74,6 +74,7 @@ - ADVANCEMENT_LIST.clear(); - Map map = this.loadCustomAdvancements(); - this.loadBuiltInAdvancements(map); -+ this.hasErrored |= net.minecraftforge.common.ForgeHooks.loadAdvancements(map); - ADVANCEMENT_LIST.loadAdvancements(map); - - for (Advancement advancement : ADVANCEMENT_LIST.getRoots()) diff --git a/patches/minecraft/net/minecraft/advancements/AdvancementRewards.java.patch b/patches/minecraft/net/minecraft/advancements/AdvancementRewards.java.patch deleted file mode 100644 index 52f78a513..000000000 --- a/patches/minecraft/net/minecraft/advancements/AdvancementRewards.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/advancements/AdvancementRewards.java -+++ after/net/minecraft/advancements/AdvancementRewards.java -@@ -50,7 +50,7 @@ - public void apply(final EntityPlayerMP player) - { - player.addExperience(this.experience); -- LootContext lootcontext = new LootContext.Builder(player.getServerWorld()).withLootedEntity(player).build(); -+ LootContext lootcontext = new LootContext.Builder(player.getServerWorld()).withLootedEntity(player).withPlayer(player).withLuck(player.getLuck()).build(); // Forge: add player & luck to LootContext - boolean flag = false; - - for (ResourceLocation resourcelocation : this.loot) diff --git a/patches/minecraft/net/minecraft/advancements/DisplayInfo.java.patch b/patches/minecraft/net/minecraft/advancements/DisplayInfo.java.patch deleted file mode 100644 index 6999696f8..000000000 --- a/patches/minecraft/net/minecraft/advancements/DisplayInfo.java.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- before/net/minecraft/advancements/DisplayInfo.java -+++ after/net/minecraft/advancements/DisplayInfo.java -@@ -141,7 +141,9 @@ - { - Item item = JsonUtils.getItem(object, "item"); - int i = JsonUtils.getInt(object, "data", 0); -- return new ItemStack(item, 1, i); -+ ItemStack ret = new ItemStack(item, 1, i); -+ ret.setTagCompound(net.minecraftforge.common.util.JsonUtils.readNBT(object, "nbt")); -+ return ret; - } - } - diff --git a/patches/minecraft/net/minecraft/advancements/PlayerAdvancements.java.patch b/patches/minecraft/net/minecraft/advancements/PlayerAdvancements.java.patch deleted file mode 100644 index 0bd53a136..000000000 --- a/patches/minecraft/net/minecraft/advancements/PlayerAdvancements.java.patch +++ /dev/null @@ -1,21 +0,0 @@ ---- before/net/minecraft/advancements/PlayerAdvancements.java -+++ after/net/minecraft/advancements/PlayerAdvancements.java -@@ -197,6 +197,9 @@ - - public boolean grantCriterion(Advancement p_192750_1_, String p_192750_2_) - { -+ // Forge: don't grant advancements for fake players -+ if (this.player instanceof net.minecraftforge.common.util.FakePlayer) return false; -+ - boolean flag = false; - AdvancementProgress advancementprogress = this.getProgress(p_192750_1_); - boolean flag1 = advancementprogress.isDone(); -@@ -225,6 +228,8 @@ - ) - ); - } -+ -+ net.minecraftforge.common.ForgeHooks.onAdvancement(this.player, p_192750_1_); - } - } - diff --git a/patches/minecraft/net/minecraft/advancements/critereon/ItemPredicate.java.patch b/patches/minecraft/net/minecraft/advancements/critereon/ItemPredicate.java.patch deleted file mode 100644 index 47c745405..000000000 --- a/patches/minecraft/net/minecraft/advancements/critereon/ItemPredicate.java.patch +++ /dev/null @@ -1,16 +0,0 @@ ---- before/net/minecraft/advancements/critereon/ItemPredicate.java -+++ after/net/minecraft/advancements/critereon/ItemPredicate.java -@@ -104,6 +104,13 @@ - if (element != null && !element.isJsonNull()) - { - JsonObject jsonobject = JsonUtils.getJsonObject(element, "item"); -+ if (jsonobject.has("type")) -+ { -+ final ResourceLocation rl = new ResourceLocation(JsonUtils.getString(jsonobject, "type")); -+ final Map> map = net.minecraftforge.advancements.critereon.ItemPredicates.getPredicates(); -+ if (map.containsKey(rl)) return map.get(rl).apply(jsonobject); -+ else throw new JsonSyntaxException("There is no ItemPredicate of type "+rl); -+ } - MinMaxBounds minmaxbounds = MinMaxBounds.deserialize(jsonobject.get("count")); - MinMaxBounds minmaxbounds1 = MinMaxBounds.deserialize(jsonobject.get("durability")); - Integer integer = jsonobject.has("data") ? JsonUtils.getInt(jsonobject, "data") : null; diff --git a/patches/minecraft/net/minecraft/block/Block.java.patch b/patches/minecraft/net/minecraft/block/Block.java.patch deleted file mode 100644 index 4d314b312..000000000 --- a/patches/minecraft/net/minecraft/block/Block.java.patch +++ /dev/null @@ -1,1661 +0,0 @@ ---- before/net/minecraft/block/Block.java -+++ after/net/minecraft/block/Block.java -@@ -8,6 +8,7 @@ - import net.minecraft.block.material.EnumPushReaction; - import net.minecraft.block.material.MapColor; - import net.minecraft.block.material.Material; -+import net.minecraft.block.properties.IProperty; - import net.minecraft.block.state.BlockFaceShape; - import net.minecraft.block.state.BlockStateContainer; - import net.minecraft.block.state.IBlockState; -@@ -50,11 +51,12 @@ - import net.minecraftforge.fml.relauncher.Side; - import net.minecraftforge.fml.relauncher.SideOnly; - --public class Block -+public class Block extends net.minecraftforge.registries.IForgeRegistryEntry.Impl - { - private static final ResourceLocation AIR_ID = new ResourceLocation("air"); -- public static final RegistryNamespacedDefaultedByKey REGISTRY = new RegistryNamespacedDefaultedByKey<>(AIR_ID); -- public static final ObjectIntIdentityMap BLOCK_STATE_IDS = new ObjectIntIdentityMap<>(); -+ public static final RegistryNamespacedDefaultedByKey REGISTRY = net.minecraftforge.registries.GameData.getWrapperDefaulted(Block.class); -+ @Deprecated //Modders: DO NOT use this! Use GameRegistry -+ public static final ObjectIntIdentityMap BLOCK_STATE_IDS = net.minecraftforge.registries.GameData.getBlockStateIDMap(); - public static final AxisAlignedBB FULL_BLOCK_AABB = new AxisAlignedBB(0.0, 0.0, 0.0, 1.0, 1.0, 1.0); - @Nullable - public static final AxisAlignedBB NULL_AABB = null; -@@ -73,6 +75,7 @@ - public float blockParticleGravity = 1.0F; - protected final Material material; - protected final MapColor blockMapColor; -+ @Deprecated // Forge: State/world/pos/entity sensitive version below - public float slipperiness = 0.6F; - protected final BlockStateContainer blockState; - private IBlockState defaultBlockState; -@@ -322,7 +325,7 @@ - - public boolean isReplaceable(IBlockAccess worldIn, BlockPos pos) - { -- return false; -+ return worldIn.getBlockState(pos).getMaterial().isReplaceable(); - } - - public Block setHardness(float hardness) -@@ -360,9 +363,10 @@ - return this.needsRandomTick; - } - -+ @Deprecated //Forge: New State sensitive version. - public boolean hasTileEntity() - { -- return this.hasTileEntity; -+ return hasTileEntity(getDefaultState()); - } - - @Deprecated -@@ -375,13 +379,13 @@ - @SideOnly(Side.CLIENT) - public int getPackedLightmapCoords(IBlockState state, IBlockAccess source, BlockPos pos) - { -- int i = source.getCombinedLight(pos, state.getLightValue()); -+ int i = source.getCombinedLight(pos, state.getLightValue(source, pos)); - - if (i == 0 && state.getBlock() instanceof BlockSlab) - { - pos = pos.down(); - state = source.getBlockState(pos); -- return source.getCombinedLight(pos, state.getLightValue()); -+ return source.getCombinedLight(pos, state.getLightValue(source, pos)); - } - else - { -@@ -445,7 +449,7 @@ - } - } - -- return !blockAccess.getBlockState(pos.offset(side)).isOpaqueCube(); -+ return !blockAccess.getBlockState(pos.offset(side)).doesSideBlockRendering(blockAccess, pos.offset(side), side.getOpposite()); - } - - @Deprecated -@@ -545,6 +549,10 @@ - - public void breakBlock(World worldIn, BlockPos pos, IBlockState state) - { -+ if (hasTileEntity(state) && !(this instanceof BlockContainer)) -+ { -+ worldIn.removeTileEntity(pos); -+ } - } - - public int quantityDropped(Random random) -@@ -560,18 +568,7 @@ - @Deprecated - public float getPlayerRelativeBlockHardness(IBlockState state, EntityPlayer player, World worldIn, BlockPos pos) - { -- float f = state.getBlockHardness(worldIn, pos); -- -- if (f < 0.0F) -- { -- return 0.0F; -- } -- else -- { -- return !player.canHarvestBlock(state) -- ? player.getDigSpeed(state) / f / 100.0F -- : player.getDigSpeed(state) / f / 30.0F; -- } -+ return net.minecraftforge.common.ForgeHooks.blockStrength(state, player, worldIn, pos); - } - - public final void dropBlockAsItem(World worldIn, BlockPos pos, IBlockState state, int fortune) -@@ -581,20 +578,16 @@ - - public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, IBlockState state, float chance, int fortune) - { -- if (!worldIn.isRemote) -+ if (!worldIn.isRemote && !worldIn.restoringBlockSnapshots) // do not drop items while restoring blockstates, prevents item dupe - { -- int i = this.quantityDroppedWithBonus(fortune, worldIn.rand); -+ List drops = getDrops(worldIn, pos, state, fortune); // use the old method until it gets removed, for backward compatibility -+ chance = net.minecraftforge.event.ForgeEventFactory.fireBlockHarvesting(drops, worldIn, pos, state, fortune, chance, false, harvesters.get()); - -- for (int j = 0; j < i; j++) -+ for (ItemStack drop : drops) - { -- if (!(worldIn.rand.nextFloat() > chance)) -+ if (worldIn.rand.nextFloat() <= chance) - { -- Item item = this.getItemDropped(state, worldIn.rand, fortune); -- -- if (item != Items.AIR) -- { -- spawnAsEntity(worldIn, pos, new ItemStack(item, 1, this.damageDropped(state))); -- } -+ spawnAsEntity(worldIn, pos, drop); - } - } - } -@@ -602,8 +595,13 @@ - - public static void spawnAsEntity(World worldIn, BlockPos pos, ItemStack stack) - { -- if (!worldIn.isRemote && !stack.isEmpty() && worldIn.getGameRules().getBoolean("doTileDrops")) -+ if (!worldIn.isRemote && !stack.isEmpty() && worldIn.getGameRules().getBoolean("doTileDrops")&& !worldIn.restoringBlockSnapshots) // do not drop items while restoring blockstates, prevents item dupe - { -+ if (captureDrops.get()) -+ { -+ capturedDrops.get().add(stack); -+ return; -+ } - float f = 0.5F; - double d0 = worldIn.rand.nextFloat() * 0.5F + 0.25; - double d1 = worldIn.rand.nextFloat() * 0.5F + 0.25; -@@ -636,6 +634,7 @@ - return 0; - } - -+ @Deprecated //Forge: State sensitive version - public float getExplosionResistance(Entity exploder) - { - return this.blockResistance / 5.0F; -@@ -680,7 +679,7 @@ - - public boolean canPlaceBlockAt(World worldIn, BlockPos pos) - { -- return worldIn.getBlockState(pos).getBlock().material.isReplaceable(); -+ return worldIn.getBlockState(pos).getBlock().isReplaceable(worldIn, pos); - } - - public boolean onBlockActivated( -@@ -702,6 +701,8 @@ - { - } - -+ // Forge: use getStateForPlacement -+ @Deprecated - public IBlockState getStateForPlacement( - World worldIn, - BlockPos pos, -@@ -754,21 +755,35 @@ - player.addStat(StatList.getBlockStats(this)); - player.addExhaustion(0.005F); - -- if (this.canSilkHarvest() && EnchantmentHelper.getEnchantmentLevel(Enchantments.SILK_TOUCH, stack) > 0) -+ if (this.canSilkHarvest(worldIn, pos, state, player) && EnchantmentHelper.getEnchantmentLevel(Enchantments.SILK_TOUCH, stack) > 0) - { -+ java.util.List items = new java.util.ArrayList(); - ItemStack itemstack = this.getSilkTouchDrop(state); -- spawnAsEntity(worldIn, pos, itemstack); -+ -+ if (!itemstack.isEmpty()) -+ { -+ items.add(itemstack); -+ } -+ -+ net.minecraftforge.event.ForgeEventFactory.fireBlockHarvesting(items, worldIn, pos, state, 0, 1.0f, true, player); -+ for (ItemStack item : items) -+ { -+ spawnAsEntity(worldIn, pos, item); -+ } - } - else - { -+ harvesters.set(player); - int i = EnchantmentHelper.getEnchantmentLevel(Enchantments.FORTUNE, stack); - this.dropBlockAsItem(worldIn, pos, state, i); -+ harvesters.set(null); - } - } - -+ @Deprecated //Forge: State sensitive version - protected boolean canSilkHarvest() - { -- return this.getDefaultState().isFullCube() && !this.hasTileEntity; -+ return this.getDefaultState().isFullCube() && !this.hasTileEntity(silk_check_state.get()); - } - - protected ItemStack getSilkTouchDrop(IBlockState state) -@@ -854,6 +869,7 @@ - entityIn.motionY = 0.0; - } - -+ @Deprecated // Forge: Use more sensitive version below: getPickBlock - public ItemStack getItem(World worldIn, BlockPos pos, IBlockState state) - { - return new ItemStack(Item.getItemFromBlock(this), 1, this.damageDropped(state)); -@@ -967,6 +983,7 @@ - } - } - -+ @Deprecated // Forge - World/state/pos/entity sensitive version below - public SoundType getSoundType() - { - return this.blockSoundType; -@@ -983,6 +1000,1388 @@ - { - } - -+ /* ======================================== FORGE START =====================================*/ -+ //For ForgeInternal use Only! -+ protected ThreadLocal harvesters = new ThreadLocal(); -+ private ThreadLocal silk_check_state = new ThreadLocal(); -+ protected static java.util.Random RANDOM = new java.util.Random(); // Useful for random things without a seed. -+ -+ /** -+ * Gets the slipperiness at the given location at the given state. Normally -+ * between 0 and 1. -+ *

-+ * Note that entities may reduce slipperiness by a certain factor of their own; -+ * for {@link net.minecraft.entity.EntityLivingBase}, this is {@code .91}. -+ * {@link net.minecraft.entity.item.EntityItem} uses {@code .98}, and -+ * {@link net.minecraft.entity.projectile.EntityFishHook} uses {@code .92}. -+ * -+ * @param state state of the block -+ * @param world the world -+ * @param pos the position in the world -+ * @param entity the entity in question -+ * @return the factor by which the entity's motion should be multiplied -+ */ -+ public float getSlipperiness(IBlockState state, IBlockAccess world, BlockPos pos, @Nullable Entity entity) -+ { -+ return slipperiness; -+ } -+ -+ /** -+ * Sets the base slipperiness level. Normally between 0 and 1. -+ *

-+ * Calling this method may have no effect on the function of this block, -+ * or may not have the expected result. This block is free to caclculate -+ * its slipperiness arbitrarily. This method is guaranteed to work on the -+ * base {@code Block} class. -+ * -+ * @param slipperiness the base slipperiness of this block -+ * @see #getSlipperiness(IBlockState, IBlockAccess, BlockPos, Entity) -+ */ -+ public void setDefaultSlipperiness(float slipperiness) -+ { -+ this.slipperiness = slipperiness; -+ } -+ -+ /** -+ * Get a light value for this block, taking into account the given state and coordinates, normal ranges are between 0 and 15 -+ * -+ * @param state Block state -+ * @param world The current world -+ * @param pos Block position in world -+ * @return The light value -+ */ -+ public int getLightValue(IBlockState state, IBlockAccess world, BlockPos pos) -+ { -+ return state.getLightValue(); -+ } -+ -+ /** -+ * Checks if a player or entity can use this block to 'climb' like a ladder. -+ * -+ * @param state The current state -+ * @param world The current world -+ * @param pos Block position in world -+ * @param entity The entity trying to use the ladder, CAN be null. -+ * @return True if the block should act like a ladder -+ */ -+ public boolean isLadder(IBlockState state, IBlockAccess world, BlockPos pos, EntityLivingBase entity) { return false; } -+ -+ /** -+ * Return true if the block is a normal, solid cube. This -+ * determines indirect power state, entity ejection from blocks, and a few -+ * others. -+ * -+ * @param state The current state -+ * @param world The current world -+ * @param pos Block position in world -+ * @return True if the block is a full cube -+ */ -+ public boolean isNormalCube(IBlockState state, IBlockAccess world, BlockPos pos) -+ { -+ return state.isNormalCube(); -+ } -+ -+ /** -+ * Check if the face of a block should block rendering. -+ * -+ * Faces which are fully opaque should return true, faces with transparency -+ * or faces which do not span the full size of the block should return false. -+ * -+ * @param state The current block state -+ * @param world The current world -+ * @param pos Block position in world -+ * @param face The side to check -+ * @return True if the block is opaque on the specified side. -+ */ -+ public boolean doesSideBlockRendering(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing face) -+ { -+ return state.isOpaqueCube(); -+ } -+ -+ /** -+ * Checks if the block is a solid face on the given side, used by placement logic. -+ * -+ * @param base_state The base state, getActualState should be called first -+ * @param world The current world -+ * @param pos Block position in world -+ * @param side The side to check -+ * @return True if the block is solid on the specified side. -+ */ -+ @Deprecated //Use IBlockState.getBlockFaceShape -+ public boolean isSideSolid(IBlockState base_state, IBlockAccess world, BlockPos pos, EnumFacing side) -+ { -+ if (base_state.isTopSolid() && side == EnumFacing.UP) // Short circuit to vanilla function if its true -+ return true; -+ -+ if (this instanceof BlockSlab) -+ { -+ IBlockState state = this.getActualState(base_state, world, pos); -+ return base_state.isFullBlock() -+ || (state.getValue(BlockSlab.HALF) == BlockSlab.EnumBlockHalf.TOP && side == EnumFacing.UP ) -+ || (state.getValue(BlockSlab.HALF) == BlockSlab.EnumBlockHalf.BOTTOM && side == EnumFacing.DOWN); -+ } -+ else if (this instanceof BlockFarmland) -+ { -+ return (side != EnumFacing.DOWN && side != EnumFacing.UP); -+ } -+ else if (this instanceof BlockStairs) -+ { -+ IBlockState state = this.getActualState(base_state, world, pos); -+ boolean flipped = state.getValue(BlockStairs.HALF) == BlockStairs.EnumHalf.TOP; -+ BlockStairs.EnumShape shape = (BlockStairs.EnumShape)state.getValue(BlockStairs.SHAPE); -+ EnumFacing facing = (EnumFacing)state.getValue(BlockStairs.FACING); -+ if (side == EnumFacing.UP) return flipped; -+ if (side == EnumFacing.DOWN) return !flipped; -+ if (facing == side) return true; -+ if (flipped) -+ { -+ if (shape == BlockStairs.EnumShape.INNER_LEFT ) return side == facing.rotateYCCW(); -+ if (shape == BlockStairs.EnumShape.INNER_RIGHT) return side == facing.rotateY(); -+ } -+ else -+ { -+ if (shape == BlockStairs.EnumShape.INNER_LEFT ) return side == facing.rotateY(); -+ if (shape == BlockStairs.EnumShape.INNER_RIGHT) return side == facing.rotateYCCW(); -+ } -+ return false; -+ } -+ else if (this instanceof BlockSnow) -+ { -+ IBlockState state = this.getActualState(base_state, world, pos); -+ return ((Integer)state.getValue(BlockSnow.LAYERS)) >= 8; -+ } -+ else if (this instanceof BlockHopper && side == EnumFacing.UP) -+ { -+ return true; -+ } -+ else if (this instanceof BlockCompressedPowered) -+ { -+ return true; -+ } -+ return isNormalCube(base_state, world, pos); -+ } -+ -+ /** -+ * Determines if this block should set fire and deal fire damage -+ * to entities coming into contact with it. -+ * -+ * @param world The current world -+ * @param pos Block position in world -+ * @return True if the block should deal damage -+ */ -+ public boolean isBurning(IBlockAccess world, BlockPos pos) -+ { -+ return false; -+ } -+ -+ /** -+ * Determines this block should be treated as an air block -+ * by the rest of the code. This method is primarily -+ * useful for creating pure logic-blocks that will be invisible -+ * to the player and otherwise interact as air would. -+ * -+ * @param state The current state -+ * @param world The current world -+ * @param pos Block position in world -+ * @return True if the block considered air -+ */ -+ public boolean isAir(IBlockState state, IBlockAccess world, BlockPos pos) -+ { -+ return state.getMaterial() == Material.AIR; -+ } -+ -+ /** -+ * Determines if the player can harvest this block, obtaining it's drops when the block is destroyed. -+ * -+ * @param player The player damaging the block -+ * @param pos The block's current position -+ * @return True to spawn the drops -+ */ -+ public boolean canHarvestBlock(IBlockAccess world, BlockPos pos, EntityPlayer player) -+ { -+ return net.minecraftforge.common.ForgeHooks.canHarvestBlock(this, player, world, pos); -+ } -+ -+ /** -+ * Called when a player removes a block. This is responsible for -+ * actually destroying the block, and the block is intact at time of call. -+ * This is called regardless of whether the player can harvest the block or -+ * not. -+ * -+ * Return true if the block is actually destroyed. -+ * -+ * Note: When used in multiplayer, this is called on both client and -+ * server sides! -+ * -+ * @param state The current state. -+ * @param world The current world -+ * @param player The player damaging the block, may be null -+ * @param pos Block position in world -+ * @param willHarvest True if Block.harvestBlock will be called after this, if the return in true. -+ * Can be useful to delay the destruction of tile entities till after harvestBlock -+ * @return True if the block is actually destroyed. -+ */ -+ public boolean removedByPlayer(IBlockState state, World world, BlockPos pos, EntityPlayer player, boolean willHarvest) -+ { -+ this.onBlockHarvested(world, pos, state, player); -+ return world.setBlockState(pos, net.minecraft.init.Blocks.AIR.getDefaultState(), world.isRemote ? 11 : 3); -+ } -+ -+ /** -+ * Chance that fire will spread and consume this block. -+ * 300 being a 100% chance, 0, being a 0% chance. -+ * -+ * @param world The current world -+ * @param pos Block position in world -+ * @param face The face that the fire is coming from -+ * @return A number ranging from 0 to 300 relating used to determine if the block will be consumed by fire -+ */ -+ public int getFlammability(IBlockAccess world, BlockPos pos, EnumFacing face) -+ { -+ return net.minecraft.init.Blocks.FIRE.getFlammability(this); -+ } -+ -+ /** -+ * Called when fire is updating, checks if a block face can catch fire. -+ * -+ * -+ * @param world The current world -+ * @param pos Block position in world -+ * @param face The face that the fire is coming from -+ * @return True if the face can be on fire, false otherwise. -+ */ -+ public boolean isFlammable(IBlockAccess world, BlockPos pos, EnumFacing face) -+ { -+ return getFlammability(world, pos, face) > 0; -+ } -+ -+ /** -+ * Called when fire is updating on a neighbor block. -+ * The higher the number returned, the faster fire will spread around this block. -+ * -+ * @param world The current world -+ * @param pos Block position in world -+ * @param face The face that the fire is coming from -+ * @return A number that is used to determine the speed of fire growth around the block -+ */ -+ public int getFireSpreadSpeed(IBlockAccess world, BlockPos pos, EnumFacing face) -+ { -+ return net.minecraft.init.Blocks.FIRE.getEncouragement(this); -+ } -+ -+ /** -+ * Currently only called by fire when it is on top of this block. -+ * Returning true will prevent the fire from naturally dying during updating. -+ * Also prevents firing from dying from rain. -+ * -+ * @param world The current world -+ * @param pos Block position in world -+ * @param side The face that the fire is coming from -+ * @return True if this block sustains fire, meaning it will never go out. -+ */ -+ public boolean isFireSource(World world, BlockPos pos, EnumFacing side) -+ { -+ if (side != EnumFacing.UP) -+ return false; -+ if (this == Blocks.NETHERRACK || this == Blocks.MAGMA) -+ return true; -+ if ((world.provider instanceof net.minecraft.world.WorldProviderEnd) && this == Blocks.BEDROCK) -+ return true; -+ return false; -+ } -+ -+ private boolean isTileProvider = this instanceof ITileEntityProvider; -+ /** -+ * Called throughout the code as a replacement for block instanceof BlockContainer -+ * Moving this to the Block base class allows for mods that wish to extend vanilla -+ * blocks, and also want to have a tile entity on that block, may. -+ * -+ * Return true from this function to specify this block has a tile entity. -+ * -+ * @param state State of the current block -+ * @return True if block has a tile entity, false otherwise -+ */ -+ public boolean hasTileEntity(IBlockState state) -+ { -+ return isTileProvider; -+ } -+ -+ /** -+ * Called throughout the code as a replacement for ITileEntityProvider.createNewTileEntity -+ * Return the same thing you would from that function. -+ * This will fall back to ITileEntityProvider.createNewTileEntity(World) if this block is a ITileEntityProvider -+ * -+ * @param state The state of the current block -+ * @return A instance of a class extending TileEntity -+ */ -+ @Nullable -+ public TileEntity createTileEntity(World world, IBlockState state) -+ { -+ if (isTileProvider) -+ { -+ return ((ITileEntityProvider)this).createNewTileEntity(world, getMetaFromState(state)); -+ } -+ return null; -+ } -+ -+ /** -+ * State and fortune sensitive version, this replaces the old (int meta, Random rand) -+ * version in 1.1. -+ * -+ * @param state Current state -+ * @param fortune Current item fortune level -+ * @param random Random number generator -+ * @return The number of items to drop -+ */ -+ public int quantityDropped(IBlockState state, int fortune, Random random) -+ { -+ return quantityDroppedWithBonus(fortune, random); -+ } -+ -+ /** -+ * @deprecated use {@link #getDrops(NonNullList, IBlockAccess, BlockPos, IBlockState, int)} -+ */ -+ @Deprecated -+ public List getDrops(IBlockAccess world, BlockPos pos, IBlockState state, int fortune) -+ { -+ NonNullList ret = NonNullList.create(); -+ getDrops(ret, world, pos, state, fortune); -+ return ret; -+ } -+ -+ /** -+ * This gets a complete list of items dropped from this block. -+ * -+ * @param drops add all items this block drops to this drops list -+ * @param world The current world -+ * @param pos Block position in world -+ * @param state Current state -+ * @param fortune Breakers fortune level -+ */ -+ public void getDrops(NonNullList drops, IBlockAccess world, BlockPos pos, IBlockState state, int fortune) -+ { -+ Random rand = world instanceof World ? ((World)world).rand : RANDOM; -+ -+ int count = quantityDropped(state, fortune, rand); -+ for (int i = 0; i < count; i++) -+ { -+ Item item = this.getItemDropped(state, rand, fortune); -+ if (item != Items.AIR) -+ { -+ drops.add(new ItemStack(item, 1, this.damageDropped(state))); -+ } -+ } -+ } -+ -+ /** -+ * Return true from this function if the player with silk touch can harvest this block directly, and not it's normal drops. -+ * -+ * @param world The world -+ * @param pos Block position in world -+ * @param state current block state -+ * @param player The player doing the harvesting -+ * @return True if the block can be directly harvested using silk touch -+ */ -+ public boolean canSilkHarvest(World world, BlockPos pos, IBlockState state, EntityPlayer player) -+ { -+ silk_check_state.set(state);; -+ boolean ret = this.canSilkHarvest(); -+ silk_check_state.set(null); -+ return ret; -+ } -+ -+ /** -+ * Determines if a specified mob type can spawn on this block, returning false will -+ * prevent any mob from spawning on the block. -+ * -+ * @param state The current state -+ * @param world The current world -+ * @param pos Block position in world -+ * @param type The Mob Category Type -+ * @return True to allow a mob of the specified category to spawn, false to prevent it. -+ */ -+ public boolean canCreatureSpawn(IBlockState state, IBlockAccess world, BlockPos pos, net.minecraft.entity.EntityLiving.SpawnPlacementType type) -+ { -+ return isSideSolid(state, world, pos, EnumFacing.UP); -+ } -+ -+ /** -+ * Determines if this block is classified as a Bed, Allowing -+ * players to sleep in it, though the block has to specifically -+ * perform the sleeping functionality in it's activated event. -+ * -+ * @param state The current state -+ * @param world The current world -+ * @param pos Block position in world -+ * @param player The player or camera entity, null in some cases. -+ * @return True to treat this as a bed -+ */ -+ public boolean isBed(IBlockState state, IBlockAccess world, BlockPos pos, @Nullable Entity player) -+ { -+ return this == net.minecraft.init.Blocks.BED; -+ } -+ -+ /** -+ * Returns the position that the player is moved to upon -+ * waking up, or respawning at the bed. -+ * -+ * @param state The current state -+ * @param world The current world -+ * @param pos Block position in world -+ * @param player The player or camera entity, null in some cases. -+ * @return The spawn position -+ */ -+ @Nullable -+ public BlockPos getBedSpawnPosition(IBlockState state, IBlockAccess world, BlockPos pos, @Nullable EntityPlayer player) -+ { -+ if (world instanceof World) -+ return BlockBed.getSafeExitLocation((World)world, pos, 0); -+ return null; -+ } -+ -+ /** -+ * Called when a user either starts or stops sleeping in the bed. -+ * -+ * @param world The current world -+ * @param pos Block position in world -+ * @param player The player or camera entity, null in some cases. -+ * @param occupied True if we are occupying the bed, or false if they are stopping use of the bed -+ */ -+ public void setBedOccupied(IBlockAccess world, BlockPos pos, EntityPlayer player, boolean occupied) -+ { -+ if (world instanceof World) -+ { -+ IBlockState state = world.getBlockState(pos); -+ state = state.getBlock().getActualState(state, world, pos); -+ state = state.withProperty(BlockBed.OCCUPIED, occupied); -+ ((World)world).setBlockState(pos, state, 4); -+ } -+ } -+ -+ /** -+ * Returns the direction of the block. Same values that -+ * are returned by BlockDirectional -+ * -+ * @param state The current state -+ * @param world The current world -+ * @param pos Block position in world -+ * @return Bed direction -+ */ -+ public EnumFacing getBedDirection(IBlockState state, IBlockAccess world, BlockPos pos) -+ { -+ return (EnumFacing)getActualState(state, world, pos).getValue(BlockHorizontal.FACING); -+ } -+ -+ /** -+ * Determines if the current block is the foot half of the bed. -+ * -+ * @param world The current world -+ * @param pos Block position in world -+ * @return True if the current block is the foot side of a bed. -+ */ -+ public boolean isBedFoot(IBlockAccess world, BlockPos pos) -+ { -+ return getActualState(world.getBlockState(pos), world, pos).getValue(BlockBed.PART) == BlockBed.EnumPartType.FOOT; -+ } -+ -+ /** -+ * Called when a leaf should start its decay process. -+ * -+ * @param state The current state -+ * @param world The current world -+ * @param pos Block position in world -+ */ -+ public void beginLeavesDecay(IBlockState state, World world, BlockPos pos){} -+ -+ /** -+ * Determines if this block can prevent leaves connected to it from decaying. -+ * @param state The current state -+ * @param world The current world -+ * @param pos Block position in world -+ * @return true if the presence this block can prevent leaves from decaying. -+ */ -+ public boolean canSustainLeaves(IBlockState state, IBlockAccess world, BlockPos pos) -+ { -+ return false; -+ } -+ -+ /** -+ * Determines if this block is considered a leaf block, used to apply the leaf decay and generation system. -+ * -+ * @param state The current state -+ * @param world The current world -+ * @param pos Block position in world -+ * @return true if this block is considered leaves. -+ */ -+ public boolean isLeaves(IBlockState state, IBlockAccess world, BlockPos pos) -+ { -+ return state.getMaterial() == Material.LEAVES; -+ } -+ -+ /** -+ * Used during tree growth to determine if newly generated leaves can replace this block. -+ * -+ * @param state The current state -+ * @param world The current world -+ * @param pos Block position in world -+ * @return true if this block can be replaced by growing leaves. -+ */ -+ public boolean canBeReplacedByLeaves(IBlockState state, IBlockAccess world, BlockPos pos) -+ { -+ return isAir(state, world, pos) || isLeaves(state, world, pos); //!state.isFullBlock(); -+ } -+ -+ /** -+ * -+ * @param world The current world -+ * @param pos Block position in world -+ * @return true if the block is wood (logs) -+ */ -+ public boolean isWood(IBlockAccess world, BlockPos pos) -+ { -+ return false; -+ } -+ -+ /** -+ * Determines if the current block is replaceable by Ore veins during world generation. -+ * -+ * @param state The current state -+ * @param world The current world -+ * @param pos Block position in world -+ * @param target The generic target block the gen is looking for, Standards define stone -+ * for overworld generation, and neatherack for the nether. -+ * @return True to allow this block to be replaced by a ore -+ */ -+ public boolean isReplaceableOreGen(IBlockState state, IBlockAccess world, BlockPos pos, com.google.common.base.Predicate target) -+ { -+ return target.apply(state); -+ } -+ -+ /** -+ * Location sensitive version of getExplosionResistance -+ * -+ * @param world The current world -+ * @param pos Block position in world -+ * @param exploder The entity that caused the explosion, can be null -+ * @param explosion The explosion -+ * @return The amount of the explosion absorbed. -+ */ -+ public float getExplosionResistance(World world, BlockPos pos, @Nullable Entity exploder, Explosion explosion) -+ { -+ return getExplosionResistance(exploder); -+ } -+ -+ /** -+ * Called when the block is destroyed by an explosion. -+ * Useful for allowing the block to take into account tile entities, -+ * state, etc. when exploded, before it is removed. -+ * -+ * @param world The current world -+ * @param pos Block position in world -+ * @param explosion The explosion instance affecting the block -+ */ -+ public void onBlockExploded(World world, BlockPos pos, Explosion explosion) -+ { -+ world.setBlockToAir(pos); -+ onExplosionDestroy(world, pos, explosion); -+ } -+ -+ /** -+ * Determine if this block can make a redstone connection on the side provided, -+ * Useful to control which sides are inputs and outputs for redstone wires. -+ * -+ * @param state The current state -+ * @param world The current world -+ * @param pos Block position in world -+ * @param side The side that is trying to make the connection, CAN BE NULL -+ * @return True to make the connection -+ */ -+ public boolean canConnectRedstone(IBlockState state, IBlockAccess world, BlockPos pos, @Nullable EnumFacing side) -+ { -+ return state.canProvidePower() && side != null; -+ } -+ -+ /** -+ * Determines if a torch can be placed on the top surface of this block. -+ * Useful for creating your own block that torches can be on, such as fences. -+ * -+ * @param state The current state -+ * @param world The current world -+ * @param pos Block position in world -+ * @return True to allow the torch to be placed -+ */ -+ public boolean canPlaceTorchOnTop(IBlockState state, IBlockAccess world, BlockPos pos) -+ { -+ if (this == Blocks.END_GATEWAY || this == Blocks.LIT_PUMPKIN) -+ { -+ return false; -+ } -+ else if (state.isTopSolid() || this instanceof BlockFence || this == Blocks.GLASS || this == Blocks.COBBLESTONE_WALL || this == Blocks.STAINED_GLASS) -+ { -+ return true; -+ } -+ else -+ { -+ BlockFaceShape shape = state.getBlockFaceShape(world, pos, EnumFacing.UP); -+ return (shape == BlockFaceShape.SOLID || shape == BlockFaceShape.CENTER || shape == BlockFaceShape.CENTER_BIG) && !isExceptionBlockForAttaching(this); -+ } -+ } -+ -+ /** -+ * Called when a user uses the creative pick block button on this block -+ * -+ * @param target The full target the player is looking at -+ * @return A ItemStack to add to the player's inventory, empty itemstack if nothing should be added. -+ */ -+ public ItemStack getPickBlock(IBlockState state, RayTraceResult target, World world, BlockPos pos, EntityPlayer player) -+ { -+ return getItem(world, pos, state); -+ } -+ -+ /** -+ * Used by getTopSolidOrLiquidBlock while placing biome decorations, villages, etc -+ * Also used to determine if the player can spawn on this block. -+ * -+ * @return False to disallow spawning -+ */ -+ public boolean isFoliage(IBlockAccess world, BlockPos pos) -+ { -+ return false; -+ } -+ -+ /** -+ * Allows a block to override the standard EntityLivingBase.updateFallState -+ * particles, this is a server side method that spawns particles with -+ * WorldServer.spawnParticle -+ * -+ * @param world The current Server world -+ * @param blockPosition of the block that the entity landed on. -+ * @param iblockstate State at the specific world/pos -+ * @param entity the entity that hit landed on the block. -+ * @param numberOfParticles that vanilla would have spawned. -+ * @return True to prevent vanilla landing particles form spawning. -+ */ -+ public boolean addLandingEffects(IBlockState state, net.minecraft.world.WorldServer worldObj, BlockPos blockPosition, IBlockState iblockstate, EntityLivingBase entity, int numberOfParticles ) -+ { -+ return false; -+ } -+ -+ /** -+ * Allows a block to override the standard vanilla running particles. -+ * This is called from {@link Entity#spawnRunningParticles} and is called both, -+ * Client and server side, it's up to the implementor to client check / server check. -+ * By default vanilla spawns particles only on the client and the server methods no-op. -+ * -+ * @param state The BlockState the entity is running on. -+ * @param world The world. -+ * @param pos The position at the entities feet. -+ * @param entity The entity running on the block. -+ * @return True to prevent vanilla running particles from spawning. -+ */ -+ public boolean addRunningEffects(IBlockState state, World world, BlockPos pos, Entity entity) -+ { -+ return false; -+ } -+ -+ /** -+ * Spawn a digging particle effect in the world, this is a wrapper -+ * around EffectRenderer.addBlockHitEffects to allow the block more -+ * control over the particles. Useful when you have entirely different -+ * texture sheets for different sides/locations in the world. -+ * -+ * @param state The current state -+ * @param world The current world -+ * @param target The target the player is looking at {x/y/z/side/sub} -+ * @param manager A reference to the current particle manager. -+ * @return True to prevent vanilla digging particles form spawning. -+ */ -+ @SideOnly(Side.CLIENT) -+ public boolean addHitEffects(IBlockState state, World worldObj, RayTraceResult target, net.minecraft.client.particle.ParticleManager manager) -+ { -+ return false; -+ } -+ -+ /** -+ * Spawn particles for when the block is destroyed. Due to the nature -+ * of how this is invoked, the x/y/z locations are not always guaranteed -+ * to host your block. So be sure to do proper sanity checks before assuming -+ * that the location is this block. -+ * -+ * @param world The current world -+ * @param pos Position to spawn the particle -+ * @param manager A reference to the current particle manager. -+ * @return True to prevent vanilla break particles from spawning. -+ */ -+ @SideOnly(Side.CLIENT) -+ public boolean addDestroyEffects(World world, BlockPos pos, net.minecraft.client.particle.ParticleManager manager) -+ { -+ return false; -+ } -+ -+ /** -+ * Determines if this block can support the passed in plant, allowing it to be planted and grow. -+ * Some examples: -+ * Reeds check if its a reed, or if its sand/dirt/grass and adjacent to water -+ * Cacti checks if its a cacti, or if its sand -+ * Nether types check for soul sand -+ * Crops check for tilled soil -+ * Caves check if it's a solid surface -+ * Plains check if its grass or dirt -+ * Water check if its still water -+ * -+ * @param state The Current state -+ * @param world The current world -+ * @param pos Block position in world -+ * @param direction The direction relative to the given position the plant wants to be, typically its UP -+ * @param plantable The plant that wants to check -+ * @return True to allow the plant to be planted/stay. -+ */ -+ public boolean canSustainPlant(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing direction, net.minecraftforge.common.IPlantable plantable) -+ { -+ IBlockState plant = plantable.getPlant(world, pos.offset(direction)); -+ net.minecraftforge.common.EnumPlantType plantType = plantable.getPlantType(world, pos.offset(direction)); -+ -+ if (plant.getBlock() == net.minecraft.init.Blocks.CACTUS) -+ { -+ return this == net.minecraft.init.Blocks.CACTUS || this == net.minecraft.init.Blocks.SAND; -+ } -+ -+ if (plant.getBlock() == net.minecraft.init.Blocks.REEDS && this == net.minecraft.init.Blocks.REEDS) -+ { -+ return true; -+ } -+ -+ if (plantable instanceof BlockBush && ((BlockBush)plantable).canSustainBush(state)) -+ { -+ return true; -+ } -+ -+ switch (plantType) -+ { -+ case Desert: return this == net.minecraft.init.Blocks.SAND || this == net.minecraft.init.Blocks.HARDENED_CLAY || this == net.minecraft.init.Blocks.STAINED_HARDENED_CLAY; -+ case Nether: return this == net.minecraft.init.Blocks.SOUL_SAND; -+ case Crop: return this == net.minecraft.init.Blocks.FARMLAND; -+ case Cave: return state.isSideSolid(world, pos, EnumFacing.UP); -+ case Plains: return this == net.minecraft.init.Blocks.GRASS || this == net.minecraft.init.Blocks.DIRT || this == net.minecraft.init.Blocks.FARMLAND; -+ case Water: return state.getMaterial() == Material.WATER && state.getValue(BlockLiquid.LEVEL) == 0; -+ case Beach: -+ boolean isBeach = this == net.minecraft.init.Blocks.GRASS || this == net.minecraft.init.Blocks.DIRT || this == net.minecraft.init.Blocks.SAND; -+ boolean hasWater = (world.getBlockState(pos.east()).getMaterial() == Material.WATER || -+ world.getBlockState(pos.west()).getMaterial() == Material.WATER || -+ world.getBlockState(pos.north()).getMaterial() == Material.WATER || -+ world.getBlockState(pos.south()).getMaterial() == Material.WATER); -+ return isBeach && hasWater; -+ } -+ -+ return false; -+ } -+ -+ /** -+ * Called when a plant grows on this block, only implemented for saplings using the WorldGen*Trees classes right now. -+ * Modder may implement this for custom plants. -+ * This does not use ForgeDirection, because large/huge trees can be located in non-representable direction, -+ * so the source location is specified. -+ * Currently this just changes the block to dirt if it was grass. -+ * -+ * Note: This happens DURING the generation, the generation may not be complete when this is called. -+ * -+ * @param state The current state -+ * @param world Current world -+ * @param pos Block position in world -+ * @param source Source plant's position in world -+ */ -+ public void onPlantGrow(IBlockState state, World world, BlockPos pos, BlockPos source) -+ { -+ if (this == net.minecraft.init.Blocks.GRASS || this == net.minecraft.init.Blocks.FARMLAND) -+ { -+ world.setBlockState(pos, net.minecraft.init.Blocks.DIRT.getDefaultState(), 2); -+ } -+ } -+ -+ /** -+ * Checks if this soil is fertile, typically this means that growth rates -+ * of plants on this soil will be slightly sped up. -+ * Only vanilla case is tilledField when it is within range of water. -+ * -+ * @param world The current world -+ * @param pos Block position in world -+ * @return True if the soil should be considered fertile. -+ */ -+ public boolean isFertile(World world, BlockPos pos) -+ { -+ if (this == net.minecraft.init.Blocks.FARMLAND) -+ { -+ return ((Integer)world.getBlockState(pos).getValue(BlockFarmland.MOISTURE)) > 0; -+ } -+ -+ return false; -+ } -+ -+ /** -+ * Location aware and overrideable version of the lightOpacity array, -+ * return the number to subtract from the light value when it passes through this block. -+ * -+ * This is not guaranteed to have the tile entity in place before this is called, so it is -+ * Recommended that you have your tile entity call relight after being placed if you -+ * rely on it for light info. -+ * -+ * @param state The Block state -+ * @param world The current world -+ * @param pos Block position in world -+ * @return The amount of light to block, 0 for air, 255 for fully opaque. -+ */ -+ public int getLightOpacity(IBlockState state, IBlockAccess world, BlockPos pos) -+ { -+ return state.getLightOpacity(); -+ } -+ -+ /** -+ * Determines if this block is can be destroyed by the specified entities normal behavior. -+ * -+ * @param state The current state -+ * @param world The current world -+ * @param pos Block position in world -+ * @return True to allow the ender dragon to destroy this block -+ */ -+ public boolean canEntityDestroy(IBlockState state, IBlockAccess world, BlockPos pos, Entity entity) -+ { -+ if (entity instanceof net.minecraft.entity.boss.EntityDragon) -+ { -+ return this != net.minecraft.init.Blocks.BARRIER && -+ this != net.minecraft.init.Blocks.OBSIDIAN && -+ this != net.minecraft.init.Blocks.END_STONE && -+ this != net.minecraft.init.Blocks.BEDROCK && -+ this != net.minecraft.init.Blocks.END_PORTAL && -+ this != net.minecraft.init.Blocks.END_PORTAL_FRAME && -+ this != net.minecraft.init.Blocks.COMMAND_BLOCK && -+ this != net.minecraft.init.Blocks.REPEATING_COMMAND_BLOCK && -+ this != net.minecraft.init.Blocks.CHAIN_COMMAND_BLOCK && -+ this != net.minecraft.init.Blocks.IRON_BARS && -+ this != net.minecraft.init.Blocks.END_GATEWAY; -+ } -+ else if ((entity instanceof net.minecraft.entity.boss.EntityWither) || -+ (entity instanceof net.minecraft.entity.projectile.EntityWitherSkull)) -+ { -+ return net.minecraft.entity.boss.EntityWither.canDestroyBlock(this); -+ } -+ -+ return true; -+ } -+ -+ /** -+ * Determines if this block can be used as the base of a beacon. -+ * -+ * @param world The current world -+ * @param pos Block position in world -+ * @param beacon Beacon position in world -+ * @return True, to support the beacon, and make it active with this block. -+ */ -+ public boolean isBeaconBase(IBlockAccess worldObj, BlockPos pos, BlockPos beacon) -+ { -+ return this == net.minecraft.init.Blocks.EMERALD_BLOCK || this == net.minecraft.init.Blocks.GOLD_BLOCK || this == net.minecraft.init.Blocks.DIAMOND_BLOCK || this == net.minecraft.init.Blocks.IRON_BLOCK; -+ } -+ -+ /** -+ * Rotate the block. For vanilla blocks this rotates around the axis passed in (generally, it should be the "face" that was hit). -+ * Note: for mod blocks, this is up to the block and modder to decide. It is not mandated that it be a rotation around the -+ * face, but could be a rotation to orient *to* that face, or a visiting of possible rotations. -+ * The method should return true if the rotation was successful though. -+ * -+ * @param world The world -+ * @param pos Block position in world -+ * @param axis The axis to rotate around -+ * @return True if the rotation was successful, False if the rotation failed, or is not possible -+ */ -+ public boolean rotateBlock(World world, BlockPos pos, EnumFacing axis) -+ { -+ IBlockState state = world.getBlockState(pos); -+ for (IProperty prop : state.getProperties().keySet()) -+ { -+ if ((prop.getName().equals("facing") || prop.getName().equals("rotation")) && prop.getValueClass() == EnumFacing.class) -+ { -+ Block block = state.getBlock(); -+ if (!(block instanceof BlockBed) && !(block instanceof BlockPistonExtension)) -+ { -+ IBlockState newState; -+ //noinspection unchecked -+ IProperty facingProperty = (IProperty) prop; -+ EnumFacing facing = state.getValue(facingProperty); -+ java.util.Collection validFacings = facingProperty.getAllowedValues(); -+ -+ // rotate horizontal facings clockwise -+ if (validFacings.size() == 4 && !validFacings.contains(EnumFacing.UP) && !validFacings.contains(EnumFacing.DOWN)) -+ { -+ newState = state.withProperty(facingProperty, facing.rotateY()); -+ } -+ else -+ { -+ // rotate other facings about the axis -+ EnumFacing rotatedFacing = facing.rotateAround(axis.getAxis()); -+ if (validFacings.contains(rotatedFacing)) -+ { -+ newState = state.withProperty(facingProperty, rotatedFacing); -+ } -+ else // abnormal facing property, just cycle it -+ { -+ newState = state.cycleProperty(facingProperty); -+ } -+ } -+ -+ world.setBlockState(pos, newState); -+ return true; -+ } -+ } -+ } -+ return false; -+ } -+ -+ /** -+ * Get the rotations that can apply to the block at the specified coordinates. Null means no rotations are possible. -+ * Note, this is up to the block to decide. It may not be accurate or representative. -+ * @param world The world -+ * @param pos Block position in world -+ * @return An array of valid axes to rotate around, or null for none or unknown -+ */ -+ @Nullable -+ public EnumFacing[] getValidRotations(World world, BlockPos pos) -+ { -+ IBlockState state = world.getBlockState(pos); -+ for (IProperty prop : state.getProperties().keySet()) -+ { -+ if ((prop.getName().equals("facing") || prop.getName().equals("rotation")) && prop.getValueClass() == EnumFacing.class) -+ { -+ @SuppressWarnings("unchecked") -+ java.util.Collection values = ((java.util.Collection)prop.getAllowedValues()); -+ return values.toArray(new EnumFacing[values.size()]); -+ } -+ } -+ return null; -+ } -+ -+ /** -+ * Determines the amount of enchanting power this block can provide to an enchanting table. -+ * @param world The World -+ * @param pos Block position in world -+ * @return The amount of enchanting power this block produces. -+ */ -+ public float getEnchantPowerBonus(World world, BlockPos pos) -+ { -+ return this == net.minecraft.init.Blocks.BOOKSHELF ? 1 : 0; -+ } -+ -+ /** -+ * Common way to recolor a block with an external tool -+ * @param world The world -+ * @param pos Block position in world -+ * @param side The side hit with the coloring tool -+ * @param color The color to change to -+ * @return If the recoloring was successful -+ */ -+ @SuppressWarnings({ "unchecked", "rawtypes" }) -+ public boolean recolorBlock(World world, BlockPos pos, EnumFacing side, net.minecraft.item.EnumDyeColor color) -+ { -+ IBlockState state = world.getBlockState(pos); -+ for (IProperty prop : state.getProperties().keySet()) -+ { -+ if (prop.getName().equals("color") && prop.getValueClass() == net.minecraft.item.EnumDyeColor.class) -+ { -+ net.minecraft.item.EnumDyeColor current = (net.minecraft.item.EnumDyeColor)state.getValue(prop); -+ if (current != color && prop.getAllowedValues().contains(color)) -+ { -+ world.setBlockState(pos, state.withProperty(prop, color)); -+ return true; -+ } -+ } -+ } -+ return false; -+ } -+ -+ /** -+ * Gathers how much experience this block drops when broken. -+ * -+ * @param state The current state -+ * @param world The world -+ * @param pos Block position -+ * @param fortune -+ * @return Amount of XP from breaking this block. -+ */ -+ public int getExpDrop(IBlockState state, IBlockAccess world, BlockPos pos, int fortune) -+ { -+ return 0; -+ } -+ -+ /** -+ * Called when a tile entity on a side of this block changes is created or is destroyed. -+ * @param world The world -+ * @param pos Block position in world -+ * @param neighbor Block position of neighbor -+ */ -+ public void onNeighborChange(IBlockAccess world, BlockPos pos, BlockPos neighbor){} -+ -+ /** -+ * Called on an Observer block whenever an update for an Observer is received. -+ * -+ * @param observerState The Observer block's state. -+ * @param world The current world. -+ * @param observerPos The Observer block's position. -+ * @param changedBlock The updated block. -+ * @param changedBlockPos The updated block's position. -+ */ -+ public void observedNeighborChange(IBlockState observerState, World world, BlockPos observerPos, Block changedBlock, BlockPos changedBlockPos){} -+ -+ /** -+ * Called to determine whether to allow the a block to handle its own indirect power rather than using the default rules. -+ * @param world The world -+ * @param pos Block position in world -+ * @param side The INPUT side of the block to be powered - ie the opposite of this block's output side -+ * @return Whether Block#isProvidingWeakPower should be called when determining indirect power -+ */ -+ public boolean shouldCheckWeakPower(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing side) -+ { -+ return state.isNormalCube(); -+ } -+ -+ /** -+ * If this block should be notified of weak changes. -+ * Weak changes are changes 1 block away through a solid block. -+ * Similar to comparators. -+ * -+ * @param world The current world -+ * @param pos Block position in world -+ * @return true To be notified of changes -+ */ -+ public boolean getWeakChanges(IBlockAccess world, BlockPos pos) -+ { -+ return false; -+ } -+ -+ private String[] harvestTool = new String[16];; -+ private int[] harvestLevel = new int[]{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; -+ /** -+ * Sets or removes the tool and level required to harvest this block. -+ * -+ * @param toolClass Class -+ * @param level Harvest level: -+ * Wood: 0 -+ * Stone: 1 -+ * Iron: 2 -+ * Diamond: 3 -+ * Gold: 0 -+ */ -+ public void setHarvestLevel(String toolClass, int level) -+ { -+ java.util.Iterator itr = getBlockState().getValidStates().iterator(); -+ while (itr.hasNext()) -+ { -+ setHarvestLevel(toolClass, level, itr.next()); -+ } -+ } -+ -+ /** -+ * Sets or removes the tool and level required to harvest this block. -+ * -+ * @param toolClass Class -+ * @param level Harvest level: -+ * Wood: 0 -+ * Stone: 1 -+ * Iron: 2 -+ * Diamond: 3 -+ * Gold: 0 -+ * @param state The specific state. -+ */ -+ public void setHarvestLevel(String toolClass, int level, IBlockState state) -+ { -+ int idx = this.getMetaFromState(state); -+ this.harvestTool[idx] = toolClass; -+ this.harvestLevel[idx] = level; -+ } -+ -+ /** -+ * Queries the class of tool required to harvest this block, if null is returned -+ * we assume that anything can harvest this block. -+ */ -+ @Nullable public String getHarvestTool(IBlockState state) -+ { -+ return harvestTool[getMetaFromState(state)]; -+ } -+ -+ /** -+ * Queries the harvest level of this item stack for the specified tool class, -+ * Returns -1 if this tool is not of the specified type -+ * -+ * @return Harvest level, or -1 if not the specified tool type. -+ */ -+ public int getHarvestLevel(IBlockState state) -+ { -+ return harvestLevel[getMetaFromState(state)]; -+ } -+ -+ /** -+ * Checks if the specified tool type is efficient on this block, -+ * meaning that it digs at full speed. -+ */ -+ public boolean isToolEffective(String type, IBlockState state) -+ { -+ if ("pickaxe".equals(type) && (this == net.minecraft.init.Blocks.REDSTONE_ORE || this == net.minecraft.init.Blocks.LIT_REDSTONE_ORE || this == net.minecraft.init.Blocks.OBSIDIAN)) -+ return false; -+ return type != null && type.equals(getHarvestTool(state)); -+ } -+ -+ /** -+ * Can return IExtendedBlockState -+ */ -+ public IBlockState getExtendedState(IBlockState state, IBlockAccess world, BlockPos pos) -+ { -+ return state; -+ } -+ -+ /** -+ * Called when the entity is inside this block, may be used to determined if the entity can breathing, -+ * display material overlays, or if the entity can swim inside a block. -+ * -+ * @param world that is being tested. -+ * @param blockpos position thats being tested. -+ * @param iblockstate state at world/blockpos -+ * @param entity that is being tested. -+ * @param yToTest, primarily for testingHead, which sends the the eye level of the entity, other wise it sends a y that can be tested vs liquid height. -+ * @param materialIn to test for. -+ * @param testingHead when true, its testing the entities head for vision, breathing ect... otherwise its testing the body, for swimming and movement adjustment. -+ * @return null for default behavior, true if the entity is within the material, false if it was not. -+ */ -+ @Nullable -+ public Boolean isEntityInsideMaterial(IBlockAccess world, BlockPos blockpos, IBlockState iblockstate, Entity entity, double yToTest, Material materialIn, boolean testingHead) -+ { -+ return null; -+ } -+ -+ /** -+ * Called when boats or fishing hooks are inside the block to check if they are inside -+ * the material requested. -+ * -+ * @param world world that is being tested. -+ * @param pos block thats being tested. -+ * @param boundingBox box to test, generally the bounds of an entity that are besting tested. -+ * @param materialIn to check for. -+ * @return null for default behavior, true if the box is within the material, false if it was not. -+ */ -+ @Nullable -+ public Boolean isAABBInsideMaterial(World world, BlockPos pos, AxisAlignedBB boundingBox, Material materialIn) -+ { -+ return null; -+ } -+ -+ /** -+ * Called when entities are moving to check if they are inside a liquid -+ * -+ * @param world world that is being tested. -+ * @param pos block thats being tested. -+ * @param boundingBox box to test, generally the bounds of an entity that are besting tested. -+ * @return null for default behavior, true if the box is within the material, false if it was not. -+ */ -+ @Nullable -+ public Boolean isAABBInsideLiquid(World world, BlockPos pos, AxisAlignedBB boundingBox) -+ { -+ return null; -+ } -+ -+ /** -+ * Called when entities are swimming in the given liquid and returns the relative height (used by {@link net.minecraft.entity.item.EntityBoat}) -+ * -+ * @param world world that is being tested. -+ * @param pos block thats being tested. -+ * @param state state at world/pos -+ * @param material liquid thats being tested. -+ * @return relative height of the given liquid (material), a value between 0 and 1 -+ */ -+ public float getBlockLiquidHeight(World world, BlockPos pos, IBlockState state, Material material) -+ { -+ return 0; -+ } -+ -+ /** -+ * Queries if this block should render in a given layer. -+ * ISmartBlockModel can use {@link net.minecraftforge.client.MinecraftForgeClient#getRenderLayer()} to alter their model based on layer. -+ */ -+ public boolean canRenderInLayer(IBlockState state, BlockRenderLayer layer) -+ { -+ return getRenderLayer() == layer; -+ } -+ // For Internal use only to capture droped items inside getDrops -+ protected static ThreadLocal captureDrops = ThreadLocal.withInitial(() -> false); -+ protected static ThreadLocal> capturedDrops = ThreadLocal.withInitial(NonNullList::create); -+ protected NonNullList captureDrops(boolean start) -+ { -+ if (start) -+ { -+ captureDrops.set(true); -+ capturedDrops.get().clear(); -+ return NonNullList.create(); -+ } -+ else -+ { -+ captureDrops.set(false); -+ return capturedDrops.get(); -+ } -+ } -+ -+ /** -+ * Sensitive version of getSoundType -+ * @param state The state -+ * @param world The world -+ * @param pos The position. Note that the world may not necessarily have {@code state} here! -+ * @param entity The entity that is breaking/stepping on/placing/hitting/falling on this block, or null if no entity is in this context -+ * @return A SoundType to use -+ */ -+ public SoundType getSoundType(IBlockState state, World world, BlockPos pos, @Nullable Entity entity) -+ { -+ return getSoundType(); -+ } -+ -+ /** -+ * @param state The state -+ * @param world The world -+ * @param pos The position of this state -+ * @param beaconPos The position of the beacon -+ * @return A float RGB [0.0, 1.0] array to be averaged with a beacon's existing beam color, or null to do nothing to the beam -+ */ -+ @Nullable -+ public float[] getBeaconColorMultiplier(IBlockState state, World world, BlockPos pos, BlockPos beaconPos) -+ { -+ return null; -+ } -+ -+ /** -+ * Use this to change the fog color used when the entity is "inside" a material. -+ * Vec3d is used here as "r/g/b" 0 - 1 values. -+ * -+ * @param world The world. -+ * @param pos The position at the entity viewport. -+ * @param state The state at the entity viewport. -+ * @param entity the entity -+ * @param originalColor The current fog color, You are not expected to use this, Return as the default if applicable. -+ * @return The new fog color. -+ */ -+ @SideOnly (Side.CLIENT) -+ public Vec3d getFogColor(World world, BlockPos pos, IBlockState state, Entity entity, Vec3d originalColor, float partialTicks) -+ { -+ if (state.getMaterial() == Material.WATER) -+ { -+ float f12 = 0.0F; -+ -+ if (entity instanceof net.minecraft.entity.EntityLivingBase) -+ { -+ net.minecraft.entity.EntityLivingBase ent = (net.minecraft.entity.EntityLivingBase)entity; -+ f12 = (float)net.minecraft.enchantment.EnchantmentHelper.getRespirationModifier(ent) * 0.2F; -+ -+ if (ent.isPotionActive(net.minecraft.init.MobEffects.WATER_BREATHING)) -+ { -+ f12 = f12 * 0.3F + 0.6F; -+ } -+ } -+ return new Vec3d(0.02F + f12, 0.02F + f12, 0.2F + f12); -+ } -+ else if (state.getMaterial() == Material.LAVA) -+ { -+ return new Vec3d(0.6F, 0.1F, 0.0F); -+ } -+ return originalColor; -+ } -+ -+ /** -+ * Used to determine the state 'viewed' by an entity (see -+ * {@link net.minecraft.client.renderer.ActiveRenderInfo#getBlockStateAtEntityViewpoint(World, Entity, float)}). -+ * Can be used by fluid blocks to determine if the viewpoint is within the fluid or not. -+ * -+ * @param state the state -+ * @param world the world -+ * @param pos the position -+ * @param viewpoint the viewpoint -+ * @return the block state that should be 'seen' -+ */ -+ public IBlockState getStateAtViewpoint(IBlockState state, IBlockAccess world, BlockPos pos, Vec3d viewpoint) -+ { -+ return state; -+ } -+ -+ /** -+ * Gets the {@link IBlockState} to place -+ * @param world The world the block is being placed in -+ * @param pos The position the block is being placed at -+ * @param facing The side the block is being placed on -+ * @param hitX The X coordinate of the hit vector -+ * @param hitY The Y coordinate of the hit vector -+ * @param hitZ The Z coordinate of the hit vector -+ * @param meta The metadata of {@link ItemStack} as processed by {@link Item#getMetadata(int)} -+ * @param placer The entity placing the block -+ * @param hand The player hand used to place this block -+ * @return The state to be placed in the world -+ */ -+ public IBlockState getStateForPlacement(World world, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer, EnumHand hand) -+ { -+ return getStateForPlacement(world, pos, facing, hitX, hitY, hitZ, meta, placer); -+ } -+ -+ /** -+ * Determines if another block can connect to this block -+ * -+ * @param world The current world -+ * @param pos The position of this block -+ * @param facing The side the connecting block is on -+ * @return True to allow another block to connect to this block -+ */ -+ public boolean canBeConnectedTo(IBlockAccess world, BlockPos pos, EnumFacing facing) -+ { -+ return false; -+ } -+ -+ /** @deprecated use {@link #getAiPathNodeType(IBlockState, IBlockAccess, BlockPos, net.minecraft.entity.EntityLiving)} */ -+ @Nullable -+ @Deprecated // TODO: remove -+ public net.minecraft.pathfinding.PathNodeType getAiPathNodeType(IBlockState state, IBlockAccess world, BlockPos pos) -+ { -+ return isBurning(world, pos) ? net.minecraft.pathfinding.PathNodeType.DAMAGE_FIRE : null; -+ } -+ -+ /** -+ * Get the {@code PathNodeType} for this block. Return {@code null} for vanilla behavior. -+ * -+ * @return the PathNodeType -+ */ -+ @Nullable -+ public net.minecraft.pathfinding.PathNodeType getAiPathNodeType(IBlockState state, IBlockAccess world, BlockPos pos, @Nullable net.minecraft.entity.EntityLiving entity) -+ { -+ return getAiPathNodeType(state, world, pos); -+ } -+ -+ /** -+ * @param blockState The state for this block -+ * @param world The world this block is in -+ * @param pos The position of this block -+ * @param side The side of this block that the chest lid is trying to open into -+ * @return true if the chest should be prevented from opening by this block -+ */ -+ public boolean doesSideBlockChestOpening(IBlockState blockState, IBlockAccess world, BlockPos pos, EnumFacing side) -+ { -+ ResourceLocation registryName = this.getRegistryName(); -+ if (registryName != null && "minecraft".equals(registryName.getNamespace())) -+ { -+ // maintain the vanilla behavior of https://bugs.mojang.com/browse/MC-378 -+ return isNormalCube(blockState, world, pos); -+ } -+ return isSideSolid(blockState, world, pos, side); -+ } -+ -+ /** -+ * @param state The state -+ * @return true if the block is sticky block which used for pull or push adjacent blocks (use by piston) -+ */ -+ public boolean isStickyBlock(IBlockState state) -+ { -+ return state.getBlock() == Blocks.SLIME_BLOCK; -+ } -+ -+ /* ========================================= FORGE END ======================================*/ -+ - public static void registerBlocks() - { - registerBlock(0, AIR_ID, new BlockAir().setTranslationKey("air")); -@@ -1509,7 +2908,7 @@ - "quartz_stairs", - new BlockStairs(block11.getDefaultState().withProperty(BlockQuartz.VARIANT, BlockQuartz.EnumType.DEFAULT)).setTranslationKey("stairsQuartz") - ); -- registerBlock(157, "activator_rail", new BlockRailPowered().setHardness(0.7F).setSoundType(SoundType.METAL).setTranslationKey("activatorRail")); -+ registerBlock(157, "activator_rail", new BlockRailPowered(true).setHardness(0.7F).setSoundType(SoundType.METAL).setTranslationKey("activatorRail")); - registerBlock(158, "dropper", new BlockDropper().setHardness(3.5F).setSoundType(SoundType.STONE).setTranslationKey("dropper")); - registerBlock( - 159, -@@ -1925,28 +3324,6 @@ - } - - block15.useNeighborBrightness = flag; -- } -- } -- -- Set set = Sets.newHashSet(REGISTRY.getObject(new ResourceLocation("tripwire"))); -- -- for (Block block16 : REGISTRY) -- { -- if (set.contains(block16)) -- { -- for (int i = 0; i < 15; i++) -- { -- int j = REGISTRY.getIDForObject(block16) << 4 | i; -- BLOCK_STATE_IDS.put(block16.getStateFromMeta(i), j); -- } -- } -- else -- { -- for (IBlockState iblockstate : block16.getBlockState().getValidStates()) -- { -- int k = REGISTRY.getIDForObject(block16) << 4 | block16.getMetaFromState(iblockstate); -- BLOCK_STATE_IDS.put(iblockstate, k); -- } - } - } - } diff --git a/patches/minecraft/net/minecraft/block/BlockBanner.java.patch b/patches/minecraft/net/minecraft/block/BlockBanner.java.patch deleted file mode 100644 index 9b7841bcb..000000000 --- a/patches/minecraft/net/minecraft/block/BlockBanner.java.patch +++ /dev/null @@ -1,51 +0,0 @@ ---- before/net/minecraft/block/BlockBanner.java -+++ after/net/minecraft/block/BlockBanner.java -@@ -3,6 +3,7 @@ - import java.util.Random; - import javax.annotation.Nullable; - import net.minecraft.block.material.Material; -+import net.minecraft.block.properties.IProperty; - import net.minecraft.block.properties.PropertyDirection; - import net.minecraft.block.properties.PropertyInteger; - import net.minecraft.block.state.BlockFaceShape; -@@ -99,16 +100,9 @@ - @Override - public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, IBlockState state, float chance, int fortune) - { -- ItemStack itemstack = this.getTileDataItemStack(worldIn, pos); -- -- if (itemstack.isEmpty()) - { - super.dropBlockAsItemWithChance(worldIn, pos, state, chance, fortune); - } -- else -- { -- spawnAsEntity(worldIn, pos, itemstack); -- } - } - - @Override -@@ -138,6 +132,23 @@ - public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face) - { - return BlockFaceShape.UNDEFINED; -+ } -+ -+ @Override -+ public void getDrops(net.minecraft.util.NonNullList drops, IBlockAccess world, BlockPos pos, IBlockState state, int fortune) -+ { -+ TileEntity te = world.getTileEntity(pos); -+ -+ if (te instanceof TileEntityBanner) -+ { -+ TileEntityBanner tileentitybanner = (TileEntityBanner)te; -+ ItemStack itemstack = tileentitybanner.getItem(); -+ drops.add(itemstack); -+ } -+ else -+ { -+ drops.add(new ItemStack(Items.BANNER, 1, 0)); -+ } - } - - public static class BlockBannerHanging extends BlockBanner diff --git a/patches/minecraft/net/minecraft/block/BlockBed.java.patch b/patches/minecraft/net/minecraft/block/BlockBed.java.patch deleted file mode 100644 index c604db262..000000000 --- a/patches/minecraft/net/minecraft/block/BlockBed.java.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- before/net/minecraft/block/BlockBed.java -+++ after/net/minecraft/block/BlockBed.java -@@ -95,8 +95,10 @@ - } - } - -- if (worldIn.provider.canRespawnHere() && worldIn.getBiome(pos) != Biomes.HELL) -+ net.minecraft.world.WorldProvider.WorldSleepResult sleepResult = worldIn.provider.canSleepAt(playerIn, pos); -+ if (sleepResult != net.minecraft.world.WorldProvider.WorldSleepResult.BED_EXPLODES) - { -+ if (sleepResult == net.minecraft.world.WorldProvider.WorldSleepResult.DENY) return true; - if (state.getValue(OCCUPIED)) - { - EntityPlayer entityplayer = this.getPlayerInBed(worldIn, pos); diff --git a/patches/minecraft/net/minecraft/block/BlockBush.java.patch b/patches/minecraft/net/minecraft/block/BlockBush.java.patch deleted file mode 100644 index 55addc63f..000000000 --- a/patches/minecraft/net/minecraft/block/BlockBush.java.patch +++ /dev/null @@ -1,70 +0,0 @@ ---- before/net/minecraft/block/BlockBush.java -+++ after/net/minecraft/block/BlockBush.java -@@ -17,7 +17,7 @@ - import net.minecraftforge.fml.relauncher.Side; - import net.minecraftforge.fml.relauncher.SideOnly; - --public class BlockBush extends Block -+public class BlockBush extends Block implements net.minecraftforge.common.IPlantable - { - protected static final AxisAlignedBB BUSH_AABB = new AxisAlignedBB(0.3F, 0.0, 0.3F, 0.7F, 0.6F, 0.7F); - -@@ -41,7 +41,8 @@ - @Override - public boolean canPlaceBlockAt(World worldIn, BlockPos pos) - { -- return super.canPlaceBlockAt(worldIn, pos) && this.canSustainBush(worldIn.getBlockState(pos.down())); -+ IBlockState soil = worldIn.getBlockState(pos.down()); -+ return super.canPlaceBlockAt(worldIn, pos) && soil.getBlock().canSustainPlant(soil, worldIn, pos.down(), net.minecraft.util.EnumFacing.UP, this); - } - - protected boolean canSustainBush(IBlockState state) -@@ -75,6 +76,11 @@ - - public boolean canBlockStay(World worldIn, BlockPos pos, IBlockState state) - { -+ if (state.getBlock() == this) //Forge: This function is called during world gen and placement, before this block is set, so if we are not 'here' then assume it's the pre-check. -+ { -+ IBlockState soil = worldIn.getBlockState(pos.down()); -+ return soil.getBlock().canSustainPlant(soil, worldIn, pos.down(), net.minecraft.util.EnumFacing.UP, this); -+ } - return this.canSustainBush(worldIn.getBlockState(pos.down())); - } - -@@ -101,6 +107,36 @@ - public boolean isFullCube(IBlockState state) - { - return false; -+ } -+ -+ @Override -+ public net.minecraftforge.common.EnumPlantType getPlantType(net.minecraft.world.IBlockAccess world, BlockPos pos) -+ { -+ if (this == Blocks.WHEAT) return net.minecraftforge.common.EnumPlantType.Crop; -+ if (this == Blocks.CARROTS) return net.minecraftforge.common.EnumPlantType.Crop; -+ if (this == Blocks.POTATOES) return net.minecraftforge.common.EnumPlantType.Crop; -+ if (this == Blocks.BEETROOTS) return net.minecraftforge.common.EnumPlantType.Crop; -+ if (this == Blocks.MELON_STEM) return net.minecraftforge.common.EnumPlantType.Crop; -+ if (this == Blocks.PUMPKIN_STEM) return net.minecraftforge.common.EnumPlantType.Crop; -+ if (this == Blocks.DEADBUSH) return net.minecraftforge.common.EnumPlantType.Desert; -+ if (this == Blocks.WATERLILY) return net.minecraftforge.common.EnumPlantType.Water; -+ if (this == Blocks.RED_MUSHROOM) return net.minecraftforge.common.EnumPlantType.Cave; -+ if (this == Blocks.BROWN_MUSHROOM) return net.minecraftforge.common.EnumPlantType.Cave; -+ if (this == Blocks.NETHER_WART) return net.minecraftforge.common.EnumPlantType.Nether; -+ if (this == Blocks.SAPLING) return net.minecraftforge.common.EnumPlantType.Plains; -+ if (this == Blocks.TALLGRASS) return net.minecraftforge.common.EnumPlantType.Plains; -+ if (this == Blocks.DOUBLE_PLANT) return net.minecraftforge.common.EnumPlantType.Plains; -+ if (this == Blocks.RED_FLOWER) return net.minecraftforge.common.EnumPlantType.Plains; -+ if (this == Blocks.YELLOW_FLOWER) return net.minecraftforge.common.EnumPlantType.Plains; -+ return net.minecraftforge.common.EnumPlantType.Plains; -+ } -+ -+ @Override -+ public IBlockState getPlant(net.minecraft.world.IBlockAccess world, BlockPos pos) -+ { -+ IBlockState state = world.getBlockState(pos); -+ if (state.getBlock() != this) return getDefaultState(); -+ return state; - } - - @SideOnly(Side.CLIENT) diff --git a/patches/minecraft/net/minecraft/block/BlockButton.java.patch b/patches/minecraft/net/minecraft/block/BlockButton.java.patch deleted file mode 100644 index b8094b2de..000000000 --- a/patches/minecraft/net/minecraft/block/BlockButton.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/block/BlockButton.java -+++ after/net/minecraft/block/BlockButton.java -@@ -100,7 +100,7 @@ - IBlockState iblockstate = worldIn.getBlockState(blockpos); - boolean flag = iblockstate.getBlockFaceShape(worldIn, blockpos, direction) == BlockFaceShape.SOLID; - Block block = iblockstate.getBlock(); -- return direction == EnumFacing.UP ? block == Blocks.HOPPER || !isExceptionBlockForAttaching(block) && flag : !isExceptBlockForAttachWithPiston(block) && flag; -+ return direction == EnumFacing.UP ? iblockstate.isTopSolid() || !isExceptionBlockForAttaching(block) && flag : !isExceptBlockForAttachWithPiston(block) && flag; - } - - @Override diff --git a/patches/minecraft/net/minecraft/block/BlockCactus.java.patch b/patches/minecraft/net/minecraft/block/BlockCactus.java.patch deleted file mode 100644 index 6e1172f8b..000000000 --- a/patches/minecraft/net/minecraft/block/BlockCactus.java.patch +++ /dev/null @@ -1,68 +0,0 @@ ---- before/net/minecraft/block/BlockCactus.java -+++ after/net/minecraft/block/BlockCactus.java -@@ -19,7 +19,7 @@ - import net.minecraftforge.fml.relauncher.Side; - import net.minecraftforge.fml.relauncher.SideOnly; - --public class BlockCactus extends Block -+public class BlockCactus extends Block implements net.minecraftforge.common.IPlantable - { - public static final PropertyInteger AGE = PropertyInteger.create("age", 0, 15); - protected static final AxisAlignedBB CACTUS_COLLISION_AABB = new AxisAlignedBB(0.0625, 0.0, 0.0625, 0.9375, 0.9375, 0.9375); -@@ -36,6 +36,7 @@ - @Override - public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand) - { -+ if (!worldIn.isAreaLoaded(pos, 1)) return; // Forge: prevent growing cactus from loading unloaded chunks with block update - BlockPos blockpos = pos.up(); - - if (worldIn.isAirBlock(blockpos)) -@@ -51,6 +52,8 @@ - { - int j = state.getValue(AGE); - -+ if(net.minecraftforge.common.ForgeHooks.onCropsGrowPre(worldIn, blockpos, state, true)) -+ { - if (j == 15) - { - worldIn.setBlockState(blockpos, this.getDefaultState()); -@@ -62,6 +65,8 @@ - { - worldIn.setBlockState(pos, state.withProperty(AGE, j + 1), 4); - } -+ net.minecraftforge.common.ForgeHooks.onCropsGrowPost(worldIn, pos, state, worldIn.getBlockState(pos)); -+ } - } - } - } -@@ -118,9 +123,8 @@ - } - } - -- Block block = worldIn.getBlockState(pos.down()).getBlock(); -- return block == Blocks.CACTUS -- || block == Blocks.SAND && !worldIn.getBlockState(pos.up()).getMaterial().isLiquid(); -+ IBlockState state = worldIn.getBlockState(pos.down()); -+ return state.getBlock().canSustainPlant(state, worldIn, pos.down(), EnumFacing.UP, this) && !worldIn.getBlockState(pos.up()).getMaterial().isLiquid(); - } - - @Override -@@ -146,6 +150,18 @@ - public int getMetaFromState(IBlockState state) - { - return state.getValue(AGE); -+ } -+ -+ @Override -+ public net.minecraftforge.common.EnumPlantType getPlantType(net.minecraft.world.IBlockAccess world, BlockPos pos) -+ { -+ return net.minecraftforge.common.EnumPlantType.Desert; -+ } -+ -+ @Override -+ public IBlockState getPlant(net.minecraft.world.IBlockAccess world, BlockPos pos) -+ { -+ return getDefaultState(); - } - - @Override diff --git a/patches/minecraft/net/minecraft/block/BlockChest.java.patch b/patches/minecraft/net/minecraft/block/BlockChest.java.patch deleted file mode 100644 index be995446e..000000000 --- a/patches/minecraft/net/minecraft/block/BlockChest.java.patch +++ /dev/null @@ -1,32 +0,0 @@ ---- before/net/minecraft/block/BlockChest.java -+++ after/net/minecraft/block/BlockChest.java -@@ -500,7 +500,7 @@ - - if (block == this) - { -- if (this.isBlocked(worldIn, blockpos)) -+ if (!allowBlocking && this.isBlocked(worldIn, blockpos)) // Forge: fix MC-99321 - { - return null; - } -@@ -572,7 +572,7 @@ - - private boolean isBelowSolidBlock(World worldIn, BlockPos pos) - { -- return worldIn.getBlockState(pos.up()).isNormalCube(); -+ return worldIn.getBlockState(pos.up()).doesSideBlockChestOpening(worldIn, pos.up(), EnumFacing.DOWN); - } - - private boolean isOcelotSittingOnChest(World worldIn, BlockPos pos) -@@ -659,5 +659,11 @@ - { - BASIC, - TRAP; -+ } -+ -+ /* ======================================== FORGE START =====================================*/ -+ public boolean rotateBlock(World world, BlockPos pos, EnumFacing axis) -+ { -+ return !isDoubleChest(world, pos) && super.rotateBlock(world, pos, axis); - } - } diff --git a/patches/minecraft/net/minecraft/block/BlockChorusFlower.java.patch b/patches/minecraft/net/minecraft/block/BlockChorusFlower.java.patch deleted file mode 100644 index c24c16456..000000000 --- a/patches/minecraft/net/minecraft/block/BlockChorusFlower.java.patch +++ /dev/null @@ -1,27 +0,0 @@ ---- before/net/minecraft/block/BlockChorusFlower.java -+++ after/net/minecraft/block/BlockChorusFlower.java -@@ -4,6 +4,7 @@ - import javax.annotation.Nullable; - import net.minecraft.block.material.MapColor; - import net.minecraft.block.material.Material; -+import net.minecraft.block.properties.IProperty; - import net.minecraft.block.properties.PropertyInteger; - import net.minecraft.block.state.BlockFaceShape; - import net.minecraft.block.state.BlockStateContainer; -@@ -56,7 +57,7 @@ - { - int i = state.getValue(AGE); - -- if (i < 5 && rand.nextInt(1) == 0) -+ if (i < 5 && net.minecraftforge.common.ForgeHooks.onCropsGrowPre(worldIn, blockpos, state, rand.nextInt(1) == 0)) - { - boolean flag = false; - boolean flag1 = false; -@@ -147,6 +148,7 @@ - { - this.placeDeadFlower(worldIn, pos); - } -+ net.minecraftforge.common.ForgeHooks.onCropsGrowPost(worldIn, pos, state, worldIn.getBlockState(pos)); - } - } - } diff --git a/patches/minecraft/net/minecraft/block/BlockCocoa.java.patch b/patches/minecraft/net/minecraft/block/BlockCocoa.java.patch deleted file mode 100644 index 18e147e00..000000000 --- a/patches/minecraft/net/minecraft/block/BlockCocoa.java.patch +++ /dev/null @@ -1,44 +0,0 @@ ---- before/net/minecraft/block/BlockCocoa.java -+++ after/net/minecraft/block/BlockCocoa.java -@@ -64,13 +64,14 @@ - { - this.dropBlock(worldIn, pos, state); - } -- else if (worldIn.rand.nextInt(5) == 0) -+ else - { - int i = state.getValue(AGE); - -- if (i < 2) -+ if (i < 2 && net.minecraftforge.common.ForgeHooks.onCropsGrowPre(worldIn, pos, state, rand.nextInt(5) == 0)) - { - worldIn.setBlockState(pos, state.withProperty(AGE, i + 1), 2); -+ net.minecraftforge.common.ForgeHooks.onCropsGrowPost(worldIn, pos, state, worldIn.getBlockState(pos)); - } - } - } -@@ -170,7 +171,14 @@ - @Override - public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, IBlockState state, float chance, int fortune) - { -- int i = state.getValue(AGE); -+ super.dropBlockAsItemWithChance(worldIn, pos, state, chance, fortune); -+ } -+ -+ @Override -+ public void getDrops(net.minecraft.util.NonNullList drops, IBlockAccess world, BlockPos pos, IBlockState state, int fortune) -+ { -+ super.getDrops(drops, world, pos, state, fortune); -+ int i = ((Integer)state.getValue(AGE)).intValue(); - int j = 1; - - if (i >= 2) -@@ -180,7 +188,7 @@ - - for (int k = 0; k < j; k++) - { -- spawnAsEntity(worldIn, pos, new ItemStack(Items.DYE, 1, EnumDyeColor.BROWN.getDyeDamage())); -+ drops.add(new ItemStack(Items.DYE, 1, EnumDyeColor.BROWN.getDyeDamage())); - } - } - diff --git a/patches/minecraft/net/minecraft/block/BlockCrops.java.patch b/patches/minecraft/net/minecraft/block/BlockCrops.java.patch deleted file mode 100644 index 2d703ea4f..000000000 --- a/patches/minecraft/net/minecraft/block/BlockCrops.java.patch +++ /dev/null @@ -1,81 +0,0 @@ ---- before/net/minecraft/block/BlockCrops.java -+++ after/net/minecraft/block/BlockCrops.java -@@ -81,6 +81,7 @@ - { - super.updateTick(worldIn, pos, state, rand); - -+ if (!worldIn.isAreaLoaded(pos, 1)) return; // Forge: prevent loading unloaded chunks when checking neighbor's light - if (worldIn.getLightFromNeighbors(pos.up()) >= 9) - { - int i = this.getAge(state); -@@ -89,9 +90,10 @@ - { - float f = getGrowthChance(this, worldIn, pos); - -- if (rand.nextInt((int)(25.0F / f) + 1) == 0) -+ if(net.minecraftforge.common.ForgeHooks.onCropsGrowPre(worldIn, pos, state, rand.nextInt((int)(25.0F / f) + 1) == 0)) - { - worldIn.setBlockState(pos, this.withAge(i + 1), 2); -+ net.minecraftforge.common.ForgeHooks.onCropsGrowPost(worldIn, pos, state, worldIn.getBlockState(pos)); - } - } - } -@@ -127,11 +129,11 @@ - float f1 = 0.0F; - IBlockState iblockstate = worldIn.getBlockState(blockpos.add(i, 0, j)); - -- if (iblockstate.getBlock() == Blocks.FARMLAND) -+ if (iblockstate.getBlock().canSustainPlant(iblockstate, worldIn, blockpos.add(i, 0, j), net.minecraft.util.EnumFacing.UP, (net.minecraftforge.common.IPlantable)blockIn)) - { - f1 = 1.0F; - -- if (iblockstate.getValue(BlockFarmland.MOISTURE) > 0) -+ if (iblockstate.getBlock().isFertile(worldIn, blockpos.add(i, 0, j))) - { - f1 = 3.0F; - } -@@ -177,8 +179,8 @@ - @Override - public boolean canBlockStay(World worldIn, BlockPos pos, IBlockState state) - { -- return (worldIn.getLight(pos) >= 8 || worldIn.canSeeSky(pos)) -- && this.canSustainBush(worldIn.getBlockState(pos.down())); -+ IBlockState soil = worldIn.getBlockState(pos.down()); -+ return (worldIn.getLight(pos) >= 8 || worldIn.canSeeSky(pos)) && soil.getBlock().canSustainPlant(soil, worldIn, pos.down(), net.minecraft.util.EnumFacing.UP, this); - } - - protected Item getSeed() -@@ -192,11 +194,31 @@ - } - - @Override -+ public void getDrops(net.minecraft.util.NonNullList drops, net.minecraft.world.IBlockAccess world, BlockPos pos, IBlockState state, int fortune) -+ { -+ super.getDrops(drops, world, pos, state, 0); -+ int age = getAge(state); -+ Random rand = world instanceof World ? ((World)world).rand : new Random(); -+ -+ if (age >= getMaxAge()) -+ { -+ int k = 3 + fortune; -+ -+ for (int i = 0; i < 3 + fortune; ++i) -+ { -+ if (rand.nextInt(2 * getMaxAge()) <= age) -+ { -+ drops.add(new ItemStack(this.getSeed(), 1, 0)); -+ } -+ } -+ } -+ } -+ - public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, IBlockState state, float chance, int fortune) - { -- super.dropBlockAsItemWithChance(worldIn, pos, state, chance, 0); -+ super.dropBlockAsItemWithChance(worldIn, pos, state, chance, fortune); - -- if (!worldIn.isRemote) -+ if (false && !worldIn.isRemote) // Forge: NOP all this. - { - int i = this.getAge(state); - diff --git a/patches/minecraft/net/minecraft/block/BlockDeadBush.java.patch b/patches/minecraft/net/minecraft/block/BlockDeadBush.java.patch deleted file mode 100644 index 8f94fc7d2..000000000 --- a/patches/minecraft/net/minecraft/block/BlockDeadBush.java.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- before/net/minecraft/block/BlockDeadBush.java -+++ after/net/minecraft/block/BlockDeadBush.java -@@ -17,7 +17,7 @@ - import net.minecraft.world.IBlockAccess; - import net.minecraft.world.World; - --public class BlockDeadBush extends BlockBush -+public class BlockDeadBush extends BlockBush implements net.minecraftforge.common.IShearable - { - protected static final AxisAlignedBB DEAD_BUSH_AABB = new AxisAlignedBB(0.099999994F, 0.0, 0.099999994F, 0.9F, 0.8F, 0.9F); - -@@ -79,5 +79,17 @@ - { - super.harvestBlock(worldIn, player, pos, state, te, stack); - } -+ } -+ -+ @Override -+ public boolean isShearable(ItemStack item, net.minecraft.world.IBlockAccess world, BlockPos pos) -+ { -+ return true; -+ } -+ -+ @Override -+ public java.util.List onSheared(ItemStack item, net.minecraft.world.IBlockAccess world, BlockPos pos, int fortune) -+ { -+ return java.util.List.of(new ItemStack(Blocks.DEADBUSH)); - } - } diff --git a/patches/minecraft/net/minecraft/block/BlockDoor.java.patch b/patches/minecraft/net/minecraft/block/BlockDoor.java.patch deleted file mode 100644 index b5fa0d127..000000000 --- a/patches/minecraft/net/minecraft/block/BlockDoor.java.patch +++ /dev/null @@ -1,32 +0,0 @@ ---- before/net/minecraft/block/BlockDoor.java -+++ after/net/minecraft/block/BlockDoor.java -@@ -230,7 +230,7 @@ - flag1 = true; - } - -- if (!worldIn.getBlockState(pos.down()).isTopSolid()) -+ if (!worldIn.getBlockState(pos.down()).isSideSolid(worldIn, pos.down(), EnumFacing.UP)) - { - worldIn.setBlockToAir(pos); - flag1 = true; -@@ -276,11 +276,15 @@ - @Override - public boolean canPlaceBlockAt(World worldIn, BlockPos pos) - { -- return pos.getY() >= 255 -- ? false -- : worldIn.getBlockState(pos.down()).isTopSolid() -- && super.canPlaceBlockAt(worldIn, pos) -- && super.canPlaceBlockAt(worldIn, pos.up()); -+ if (pos.getY() >= worldIn.getHeight() - 1) -+ { -+ return false; -+ } -+ else -+ { -+ IBlockState state = worldIn.getBlockState(pos.down()); -+ return (state.isTopSolid() || state.getBlockFaceShape(worldIn, pos.down(), EnumFacing.UP) == BlockFaceShape.SOLID) && super.canPlaceBlockAt(worldIn, pos) && super.canPlaceBlockAt(worldIn, pos.up()); -+ } - } - - @Override diff --git a/patches/minecraft/net/minecraft/block/BlockDoublePlant.java.patch b/patches/minecraft/net/minecraft/block/BlockDoublePlant.java.patch deleted file mode 100644 index 7308169be..000000000 --- a/patches/minecraft/net/minecraft/block/BlockDoublePlant.java.patch +++ /dev/null @@ -1,86 +0,0 @@ ---- before/net/minecraft/block/BlockDoublePlant.java -+++ after/net/minecraft/block/BlockDoublePlant.java -@@ -23,7 +23,7 @@ - import net.minecraft.world.IBlockAccess; - import net.minecraft.world.World; - --public class BlockDoublePlant extends BlockBush implements IGrowable -+public class BlockDoublePlant extends BlockBush implements IGrowable, net.minecraftforge.common.IShearable - { - public static final PropertyEnum VARIANT = PropertyEnum.create("variant", BlockDoublePlant.EnumPlantType.class); - public static final PropertyEnum HALF = PropertyEnum.create("half", BlockDoublePlant.EnumBlockHalf.class); -@@ -96,6 +96,8 @@ - Block block = (Block)(flag ? this : worldIn.getBlockState(blockpos).getBlock()); - Block block1 = (Block)(flag ? worldIn.getBlockState(blockpos1).getBlock() : this); - -+ if (!flag) this.dropBlockAsItem(worldIn, pos, state, 0); //Forge move above the setting to air. -+ - if (block == this) - { - worldIn.setBlockState(blockpos, Blocks.AIR.getDefaultState(), 2); -@@ -104,11 +106,6 @@ - if (block1 == this) - { - worldIn.setBlockState(blockpos1, Blocks.AIR.getDefaultState(), 3); -- -- if (!flag) -- { -- this.dropBlockAsItem(worldIn, blockpos1, state, 0); -- } - } - } - } -@@ -116,6 +113,7 @@ - @Override - public boolean canBlockStay(World worldIn, BlockPos pos, IBlockState state) - { -+ if (state.getBlock() != this) return super.canBlockStay(worldIn, pos, state); //Forge: This function is called during world gen and placement, before this block is set, so if we are not 'here' then assume it's the pre-check. - if (state.getValue(HALF) == BlockDoublePlant.EnumBlockHalf.UPPER) - { - return worldIn.getBlockState(pos.down()).getBlock() == this; -@@ -185,10 +183,6 @@ - World worldIn, EntityPlayer player, BlockPos pos, IBlockState state, @Nullable TileEntity te, ItemStack stack - ) - { -- if (worldIn.isRemote -- || stack.getItem() != Items.SHEARS -- || state.getValue(HALF) != BlockDoublePlant.EnumBlockHalf.LOWER -- || !this.onHarvest(worldIn, pos, state, player)) - { - super.harvestBlock(worldIn, player, pos, state, te, stack); - } -@@ -250,9 +244,6 @@ - else - { - player.addStat(StatList.getBlockStats(this)); -- int i = (blockdoubleplant$enumplanttype == BlockDoublePlant.EnumPlantType.GRASS ? BlockTallGrass.EnumType.GRASS : BlockTallGrass.EnumType.FERN) -- .getMeta(); -- spawnAsEntity(worldIn, pos, new ItemStack(Blocks.TALLGRASS, 2, i)); - return true; - } - } -@@ -335,6 +326,24 @@ - public Block.EnumOffsetType getOffsetType() - { - return Block.EnumOffsetType.XZ; -+ } -+ -+ @Override -+ public boolean isShearable(ItemStack item, IBlockAccess world, BlockPos pos) -+ { -+ IBlockState state = world.getBlockState(pos); -+ EnumPlantType type = state.getValue(VARIANT); -+ return state.getValue(HALF) == EnumBlockHalf.LOWER && (type == EnumPlantType.FERN || type == EnumPlantType.GRASS); -+ } -+ -+ @Override -+ public java.util.List onSheared(ItemStack item, net.minecraft.world.IBlockAccess world, BlockPos pos, int fortune) -+ { -+ java.util.List ret = new java.util.ArrayList(); -+ EnumPlantType type = world.getBlockState(pos).getValue(VARIANT); -+ if (type == EnumPlantType.FERN) ret.add(new ItemStack(Blocks.TALLGRASS, 2, BlockTallGrass.EnumType.FERN.getMeta())); -+ if (type == EnumPlantType.GRASS) ret.add(new ItemStack(Blocks.TALLGRASS, 2, BlockTallGrass.EnumType.GRASS.getMeta())); -+ return ret; - } - - public static enum EnumBlockHalf implements IStringSerializable diff --git a/patches/minecraft/net/minecraft/block/BlockDragonEgg.java.patch b/patches/minecraft/net/minecraft/block/BlockDragonEgg.java.patch deleted file mode 100644 index 593ec44a4..000000000 --- a/patches/minecraft/net/minecraft/block/BlockDragonEgg.java.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- before/net/minecraft/block/BlockDragonEgg.java -+++ after/net/minecraft/block/BlockDragonEgg.java -@@ -52,7 +52,7 @@ - - private void checkFall(World worldIn, BlockPos pos) - { -- if (BlockFalling.canFallThrough(worldIn.getBlockState(pos.down())) && pos.getY() >= 0) -+ if (worldIn.isAirBlock(pos.down()) && BlockFalling.canFallThrough(worldIn.getBlockState(pos.down())) && pos.getY() >= 0) - { - int i = 32; - -@@ -69,7 +69,7 @@ - worldIn.setBlockToAir(pos); - BlockPos blockpos = pos; - -- while (BlockFalling.canFallThrough(worldIn.getBlockState(blockpos)) && blockpos.getY() > 0) -+ while (worldIn.isAirBlock(blockpos) && BlockFalling.canFallThrough(worldIn.getBlockState(blockpos)) && blockpos.getY() > 0) - { - blockpos = blockpos.down(); - } -@@ -119,7 +119,7 @@ - worldIn.rand.nextInt(16) - worldIn.rand.nextInt(16) - ); - -- if (worldIn.getBlockState(blockpos).getBlock().material == Material.AIR) -+ if (worldIn.isAirBlock(blockpos)) - { - if (worldIn.isRemote) - { diff --git a/patches/minecraft/net/minecraft/block/BlockDropper.java.patch b/patches/minecraft/net/minecraft/block/BlockDropper.java.patch deleted file mode 100644 index a43a4c6cb..000000000 --- a/patches/minecraft/net/minecraft/block/BlockDropper.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/block/BlockDropper.java -+++ after/net/minecraft/block/BlockDropper.java -@@ -46,7 +46,7 @@ - { - ItemStack itemstack = tileentitydispenser.getStackInSlot(i); - -- if (!itemstack.isEmpty()) -+ if (!itemstack.isEmpty() && net.minecraftforge.items.VanillaInventoryCodeHooks.dropperInsertHook(worldIn, pos, tileentitydispenser, i, itemstack)) - { - EnumFacing enumfacing = worldIn.getBlockState(pos).getValue(FACING); - BlockPos blockpos = pos.offset(enumfacing); diff --git a/patches/minecraft/net/minecraft/block/BlockDynamicLiquid.java.patch b/patches/minecraft/net/minecraft/block/BlockDynamicLiquid.java.patch deleted file mode 100644 index 3a363214b..000000000 --- a/patches/minecraft/net/minecraft/block/BlockDynamicLiquid.java.patch +++ /dev/null @@ -1,64 +0,0 @@ ---- before/net/minecraft/block/BlockDynamicLiquid.java -+++ after/net/minecraft/block/BlockDynamicLiquid.java -@@ -29,6 +29,7 @@ - @Override - public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand) - { -+ if (!worldIn.isAreaLoaded(pos, this.getSlopeFindDistance(worldIn))) return; // Forge: avoid loading unloaded chunks - int i = state.getValue(LEVEL); - int j = 1; - -@@ -70,7 +71,7 @@ - } - } - -- if (this.adjacentSourceBlocks >= 2 && this.material == Material.WATER) -+ if (this.adjacentSourceBlocks >= 2 && net.minecraftforge.event.ForgeEventFactory.canCreateFluidSource(worldIn, pos, state, this.material == Material.WATER)) - { - IBlockState iblockstate = worldIn.getBlockState(pos.down()); - -@@ -122,7 +123,7 @@ - if (this.material == Material.LAVA - && worldIn.getBlockState(pos.down()).getMaterial() == Material.WATER) - { -- worldIn.setBlockState(pos.down(), Blocks.STONE.getDefaultState()); -+ worldIn.setBlockState(pos.down(), net.minecraftforge.event.ForgeEventFactory.fireFluidPlaceBlockEvent(worldIn, pos.down(), pos, Blocks.STONE.getDefaultState())); - this.triggerMixEffects(worldIn, pos.down()); - return; - } -@@ -170,6 +171,7 @@ - } - else - { -+ if (state.getBlock() != Blocks.SNOW_LAYER) //Forge: Vanilla has a 'bug' where snowballs don't drop like every other block. So special case because ewww... - state.getBlock().dropBlockAsItem(worldIn, pos, state, 0); - } - } -@@ -192,7 +194,7 @@ - if (!this.isBlocked(worldIn, blockpos, iblockstate) - && (iblockstate.getMaterial() != this.material || iblockstate.getValue(LEVEL) > 0)) - { -- if (!this.isBlocked(worldIn, blockpos.down(), iblockstate)) -+ if (!this.isBlocked(worldIn, blockpos.down(), worldIn.getBlockState(blockpos.down()))) - { - return distance; - } -@@ -260,7 +262,8 @@ - - private boolean isBlocked(World worldIn, BlockPos pos, IBlockState state) - { -- Block block = worldIn.getBlockState(pos).getBlock(); -+ Block block = state.getBlock(); //Forge: state must be valid for position -+ Material mat = state.getMaterial(); - - if (block instanceof BlockDoor || block == Blocks.STANDING_SIGN || block == Blocks.LADDER || block == Blocks.REEDS) - { -@@ -268,7 +271,7 @@ - } - else - { -- return block.material != Material.PORTAL && block.material != Material.STRUCTURE_VOID ? block.material.blocksMovement() : true; -+ return mat != Material.PORTAL && mat != Material.STRUCTURE_VOID ? mat.blocksMovement() : true; - } - } - diff --git a/patches/minecraft/net/minecraft/block/BlockEnchantmentTable.java.patch b/patches/minecraft/net/minecraft/block/BlockEnchantmentTable.java.patch deleted file mode 100644 index 0e81e27cb..000000000 --- a/patches/minecraft/net/minecraft/block/BlockEnchantmentTable.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/block/BlockEnchantmentTable.java -+++ after/net/minecraft/block/BlockEnchantmentTable.java -@@ -67,7 +67,7 @@ - { - BlockPos blockpos = pos.add(i, k, j); - -- if (worldIn.getBlockState(blockpos).getBlock() == Blocks.BOOKSHELF) -+ if (net.minecraftforge.common.ForgeHooks.getEnchantPower(worldIn, blockpos) > 0) - { - if (!worldIn.isAirBlock(pos.add(i / 2, 0, j / 2))) - { diff --git a/patches/minecraft/net/minecraft/block/BlockEnderChest.java.patch b/patches/minecraft/net/minecraft/block/BlockEnderChest.java.patch deleted file mode 100644 index 5275492d3..000000000 --- a/patches/minecraft/net/minecraft/block/BlockEnderChest.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/block/BlockEnderChest.java -+++ after/net/minecraft/block/BlockEnderChest.java -@@ -131,7 +131,7 @@ - { - return true; - } -- else if (worldIn.getBlockState(pos.up()).isNormalCube()) -+ else if (worldIn.getBlockState(pos.up()).doesSideBlockChestOpening(worldIn, pos.up(), EnumFacing.DOWN)) - { - return true; - } diff --git a/patches/minecraft/net/minecraft/block/BlockFalling.java.patch b/patches/minecraft/net/minecraft/block/BlockFalling.java.patch deleted file mode 100644 index 213a0e290..000000000 --- a/patches/minecraft/net/minecraft/block/BlockFalling.java.patch +++ /dev/null @@ -1,30 +0,0 @@ ---- before/net/minecraft/block/BlockFalling.java -+++ after/net/minecraft/block/BlockFalling.java -@@ -50,23 +50,24 @@ - - private void checkFallable(World worldIn, BlockPos pos) - { -- if (canFallThrough(worldIn.getBlockState(pos.down())) && pos.getY() >= 0) -+ if ((worldIn.isAirBlock(pos.down()) || canFallThrough(worldIn.getBlockState(pos.down()))) && pos.getY() >= 0) - { - int i = 32; - - if (fallInstantly || !worldIn.isAreaLoaded(pos.add(-32, -32, -32), pos.add(32, 32, 32))) - { -+ IBlockState state = worldIn.getBlockState(pos); - worldIn.setBlockToAir(pos); - BlockPos blockpos = pos.down(); - -- while (canFallThrough(worldIn.getBlockState(blockpos)) && blockpos.getY() > 0) -+ while ((worldIn.isAirBlock(blockpos) || canFallThrough(worldIn.getBlockState(blockpos))) && blockpos.getY() > 0) - { - blockpos = blockpos.down(); - } - - if (blockpos.getY() > 0) - { -- worldIn.setBlockState(blockpos.up(), this.getDefaultState()); -+ worldIn.setBlockState(blockpos.up(), state); //Forge: Fix loss of state information during world gen. - } - } - else if (!worldIn.isRemote) diff --git a/patches/minecraft/net/minecraft/block/BlockFarmland.java.patch b/patches/minecraft/net/minecraft/block/BlockFarmland.java.patch deleted file mode 100644 index 7603f869e..000000000 --- a/patches/minecraft/net/minecraft/block/BlockFarmland.java.patch +++ /dev/null @@ -1,33 +0,0 @@ ---- before/net/minecraft/block/BlockFarmland.java -+++ after/net/minecraft/block/BlockFarmland.java -@@ -76,11 +76,7 @@ - @Override - public void onFallenUpon(World worldIn, BlockPos pos, Entity entityIn, float fallDistance) - { -- if (!worldIn.isRemote -- && worldIn.rand.nextFloat() < fallDistance - 0.5F -- && entityIn instanceof EntityLivingBase -- && (entityIn instanceof EntityPlayer || worldIn.getGameRules().getBoolean("mobGriefing")) -- && entityIn.width * entityIn.width * entityIn.height > 0.512F) -+ if (net.minecraftforge.common.ForgeHooks.onFarmlandTrample(worldIn, pos, Blocks.DIRT.getDefaultState(), fallDistance, entityIn)) // Forge: Move logic to Entity#canTrample - { - turnToDirt(worldIn, pos); - } -@@ -103,7 +99,7 @@ - private boolean hasCrops(World worldIn, BlockPos pos) - { - Block block = worldIn.getBlockState(pos.up()).getBlock(); -- return block instanceof BlockCrops || block instanceof BlockStem; -+ return block instanceof net.minecraftforge.common.IPlantable && canSustainPlant(worldIn.getBlockState(pos), worldIn, pos, net.minecraft.util.EnumFacing.UP, (net.minecraftforge.common.IPlantable)block); - } - - private boolean hasWater(World worldIn, BlockPos pos) -@@ -116,7 +112,7 @@ - } - } - -- return false; -+ return net.minecraftforge.common.FarmlandWaterManager.hasBlockWaterTicket(worldIn, pos); - } - - @Override diff --git a/patches/minecraft/net/minecraft/block/BlockFence.java.patch b/patches/minecraft/net/minecraft/block/BlockFence.java.patch deleted file mode 100644 index 9a25c8a71..000000000 --- a/patches/minecraft/net/minecraft/block/BlockFence.java.patch +++ /dev/null @@ -1,41 +0,0 @@ ---- before/net/minecraft/block/BlockFence.java -+++ after/net/minecraft/block/BlockFence.java -@@ -220,10 +220,10 @@ - @Override - public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos) - { -- return state.withProperty(NORTH, this.canConnectTo(worldIn, pos.north(), EnumFacing.SOUTH)) -- .withProperty(EAST, this.canConnectTo(worldIn, pos.east(), EnumFacing.WEST)) -- .withProperty(SOUTH, this.canConnectTo(worldIn, pos.south(), EnumFacing.NORTH)) -- .withProperty(WEST, this.canConnectTo(worldIn, pos.west(), EnumFacing.EAST)); -+ return state.withProperty(NORTH, canFenceConnectTo(worldIn, pos, EnumFacing.NORTH)) -+ .withProperty(EAST, canFenceConnectTo(worldIn, pos, EnumFacing.EAST)) -+ .withProperty(SOUTH, canFenceConnectTo(worldIn, pos, EnumFacing.SOUTH)) -+ .withProperty(WEST, canFenceConnectTo(worldIn, pos, EnumFacing.WEST)); - } - - @Override -@@ -272,6 +272,23 @@ - { - return new BlockStateContainer(this, NORTH, EAST, WEST, SOUTH); - } -+ -+ /* ======================================== FORGE START ======================================== */ -+ -+ @Override -+ public boolean canBeConnectedTo(IBlockAccess world, BlockPos pos, EnumFacing facing) -+ { -+ return canConnectTo(world, pos.offset(facing), facing.getOpposite()); -+ } -+ -+ private boolean canFenceConnectTo(IBlockAccess world, BlockPos pos, EnumFacing facing) -+ { -+ BlockPos other = pos.offset(facing); -+ Block block = world.getBlockState(other).getBlock(); -+ return block.canBeConnectedTo(world, other, facing.getOpposite()) || canConnectTo(world, other, facing.getOpposite()); -+ } -+ -+ /* ======================================== FORGE END ======================================== */ - - @Override - public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face) diff --git a/patches/minecraft/net/minecraft/block/BlockFenceGate.java.patch b/patches/minecraft/net/minecraft/block/BlockFenceGate.java.patch deleted file mode 100644 index 3594286db..000000000 --- a/patches/minecraft/net/minecraft/block/BlockFenceGate.java.patch +++ /dev/null @@ -1,44 +0,0 @@ ---- before/net/minecraft/block/BlockFenceGate.java -+++ after/net/minecraft/block/BlockFenceGate.java -@@ -64,13 +64,13 @@ - - if (enumfacing$axis == EnumFacing.Axis.Z - && ( -- worldIn.getBlockState(pos.west()).getBlock() == Blocks.COBBLESTONE_WALL -- || worldIn.getBlockState(pos.east()).getBlock() == Blocks.COBBLESTONE_WALL -+ worldIn.getBlockState(pos.west()).getBlock() instanceof BlockWall -+ || worldIn.getBlockState(pos.east()).getBlock() instanceof BlockWall - ) - || enumfacing$axis == EnumFacing.Axis.X - && ( -- worldIn.getBlockState(pos.north()).getBlock() == Blocks.COBBLESTONE_WALL -- || worldIn.getBlockState(pos.south()).getBlock() == Blocks.COBBLESTONE_WALL -+ worldIn.getBlockState(pos.north()).getBlock() instanceof BlockWall -+ || worldIn.getBlockState(pos.south()).getBlock() instanceof BlockWall - )) - { - state = state.withProperty(IN_WALL, true); -@@ -243,6 +243,23 @@ - { - return new BlockStateContainer(this, FACING, OPEN, POWERED, IN_WALL); - } -+ -+ /* ======================================== FORGE START ======================================== */ -+ -+ @Override -+ public boolean canBeConnectedTo(IBlockAccess world, BlockPos pos, EnumFacing facing) -+ { -+ IBlockState state = world.getBlockState(pos); -+ if (state.getBlock() instanceof BlockFenceGate && -+ state.getBlockFaceShape(world, pos, facing) == BlockFaceShape.MIDDLE_POLE) -+ { -+ Block connector = world.getBlockState(pos.offset(facing)).getBlock(); -+ return connector instanceof BlockFence || connector instanceof BlockWall; -+ } -+ return false; -+ } -+ -+ /* ======================================== FORGE END ======================================== */ - - @Override - public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face) diff --git a/patches/minecraft/net/minecraft/block/BlockFire.java.patch b/patches/minecraft/net/minecraft/block/BlockFire.java.patch deleted file mode 100644 index 978276769..000000000 --- a/patches/minecraft/net/minecraft/block/BlockFire.java.patch +++ /dev/null @@ -1,230 +0,0 @@ ---- before/net/minecraft/block/BlockFire.java -+++ after/net/minecraft/block/BlockFire.java -@@ -39,13 +39,13 @@ - @Override - public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos) - { -- return !worldIn.getBlockState(pos.down()).isTopSolid() -- && !Blocks.FIRE.canCatchFire(worldIn, pos.down()) -- ? state.withProperty(NORTH, this.canCatchFire(worldIn, pos.north())) -- .withProperty(EAST, this.canCatchFire(worldIn, pos.east())) -- .withProperty(SOUTH, this.canCatchFire(worldIn, pos.south())) -- .withProperty(WEST, this.canCatchFire(worldIn, pos.west())) -- .withProperty(UPPER, this.canCatchFire(worldIn, pos.up())) -+ return !worldIn.getBlockState(pos.down()).isSideSolid(worldIn, pos.down(), EnumFacing.UP) -+ && !Blocks.FIRE.canCatchFire(worldIn, pos.down(), EnumFacing.UP) -+ ? state.withProperty(NORTH, this.canCatchFire(worldIn, pos.north(), EnumFacing.SOUTH)) -+ .withProperty(EAST, this.canCatchFire(worldIn, pos.east(), EnumFacing.WEST)) -+ .withProperty(SOUTH, this.canCatchFire(worldIn, pos.south(), EnumFacing.NORTH)) -+ .withProperty(WEST, this.canCatchFire(worldIn, pos.west(), EnumFacing.EAST)) -+ .withProperty(UPPER, this.canCatchFire(worldIn, pos.up(), EnumFacing.DOWN)) - : this.getDefaultState(); - } - -@@ -108,6 +108,7 @@ - - public void setFireInfo(Block blockIn, int encouragement, int flammability) - { -+ if (blockIn == Blocks.AIR) throw new IllegalArgumentException("Tried to set air on fire... This is bad."); - this.encouragements.put(blockIn, encouragement); - this.flammabilities.put(blockIn, flammability); - } -@@ -148,18 +149,14 @@ - { - if (worldIn.getGameRules().getBoolean("doFireTick")) - { -+ if (!worldIn.isAreaLoaded(pos, 2)) return; // Forge: prevent loading unloaded chunks when spreading fire - if (!this.canPlaceBlockAt(worldIn, pos)) - { - worldIn.setBlockToAir(pos); - } - - Block block = worldIn.getBlockState(pos.down()).getBlock(); -- boolean flag = block == Blocks.NETHERRACK || block == Blocks.MAGMA; -- -- if (worldIn.provider instanceof WorldProviderEnd && block == Blocks.BEDROCK) -- { -- flag = true; -- } -+ boolean flag = block.isFireSource(worldIn, pos.down(), EnumFacing.UP); - - int i = state.getValue(AGE); - -@@ -181,7 +178,7 @@ - { - if (!this.canNeighborCatchFire(worldIn, pos)) - { -- if (!worldIn.getBlockState(pos.down()).isTopSolid() || i > 3) -+ if (!worldIn.getBlockState(pos.down()).isSideSolid(worldIn, pos.down(), EnumFacing.UP) || i > 3) - { - worldIn.setBlockToAir(pos); - } -@@ -189,7 +186,7 @@ - return; - } - -- if (!this.canCatchFire(worldIn, pos.down()) && i == 15 && rand.nextInt(4) == 0) -+ if (!this.canCatchFire(worldIn, pos.down(), EnumFacing.UP) && i == 15 && rand.nextInt(4) == 0) - { - worldIn.setBlockToAir(pos); - return; -@@ -204,12 +201,12 @@ - j = -50; - } - -- this.catchOnFire(worldIn, pos.east(), 300 + j, rand, i); -- this.catchOnFire(worldIn, pos.west(), 300 + j, rand, i); -- this.catchOnFire(worldIn, pos.down(), 250 + j, rand, i); -- this.catchOnFire(worldIn, pos.up(), 250 + j, rand, i); -- this.catchOnFire(worldIn, pos.north(), 300 + j, rand, i); -- this.catchOnFire(worldIn, pos.south(), 300 + j, rand, i); -+ this.tryCatchFire(worldIn, pos.east(), 300 + j, rand, i, EnumFacing.WEST); -+ this.tryCatchFire(worldIn, pos.west(), 300 + j, rand, i, EnumFacing.EAST); -+ this.tryCatchFire(worldIn, pos.down(), 250 + j, rand, i, EnumFacing.UP); -+ this.tryCatchFire(worldIn, pos.up(), 250 + j, rand, i, EnumFacing.DOWN); -+ this.tryCatchFire(worldIn, pos.north(), 300 + j, rand, i, EnumFacing.SOUTH); -+ this.tryCatchFire(worldIn, pos.south(), 300 + j, rand, i, EnumFacing.NORTH); - - for (int k = -1; k <= 1; k++) - { -@@ -273,21 +270,29 @@ - return false; - } - -+ @Deprecated // Use Block.getFlammability - public int getFlammability(Block blockIn) - { - Integer integer = this.flammabilities.get(blockIn); - return integer == null ? 0 : integer; - } - -+ @Deprecated // Use Block.getFireSpreadSpeed - public int getEncouragement(Block blockIn) - { - Integer integer = this.encouragements.get(blockIn); - return integer == null ? 0 : integer; - } - -+ @Deprecated // Use tryCatchFire with face below - private void catchOnFire(World worldIn, BlockPos pos, int chance, Random random, int age) - { -- int i = this.getFlammability(worldIn.getBlockState(pos).getBlock()); -+ this.tryCatchFire(worldIn, pos, chance, random, age, EnumFacing.UP); -+ } -+ -+ private void tryCatchFire(World worldIn, BlockPos pos, int chance, Random random, int age, EnumFacing face) -+ { -+ int i = worldIn.getBlockState(pos).getBlock().getFlammability(worldIn, pos, face); - - if (random.nextInt(chance) < i) - { -@@ -320,7 +325,7 @@ - { - for (EnumFacing enumfacing : EnumFacing.values()) - { -- if (this.canCatchFire(worldIn, pos.offset(enumfacing))) -+ if (this.canCatchFire(worldIn, pos.offset(enumfacing), enumfacing.getOpposite())) - { - return true; - } -@@ -341,7 +346,7 @@ - - for (EnumFacing enumfacing : EnumFacing.values()) - { -- i = Math.max(this.getEncouragement(worldIn.getBlockState(pos.offset(enumfacing)).getBlock()), i); -+ i = Math.max(worldIn.getBlockState(pos.offset(enumfacing)).getBlock().getFireSpreadSpeed(worldIn, pos.offset(enumfacing), enumfacing.getOpposite()), i); - } - - return i; -@@ -354,9 +359,10 @@ - return false; - } - -+ @Deprecated // Use canCatchFire with face sensitive version below - public boolean canCatchFire(IBlockAccess worldIn, BlockPos pos) - { -- return this.getEncouragement(worldIn.getBlockState(pos).getBlock()) > 0; -+ return canCatchFire(worldIn, pos, EnumFacing.UP); - } - - @Override -@@ -401,17 +407,17 @@ - pos.getY() + 0.5F, - pos.getZ() + 0.5F, - SoundEvents.BLOCK_FIRE_AMBIENT, -- SoundCategory.BLOCKS, -+ SoundCategory.BLOCKS, - 1.0F + rand.nextFloat(), - rand.nextFloat() * 0.7F + 0.3F, - false - ); - } - -- if (!worldIn.getBlockState(pos.down()).isTopSolid() -- && !Blocks.FIRE.canCatchFire(worldIn, pos.down())) -+ if (!worldIn.getBlockState(pos.down()).isSideSolid(worldIn, pos.down(), EnumFacing.UP) -+ && !Blocks.FIRE.canCatchFire(worldIn, pos.down(), EnumFacing.UP)) - { -- if (Blocks.FIRE.canCatchFire(worldIn, pos.west())) -+ if (Blocks.FIRE.canCatchFire(worldIn, pos.west(), EnumFacing.EAST)) - { - for (int j = 0; j < 2; j++) - { -@@ -422,7 +428,7 @@ - } - } - -- if (Blocks.FIRE.canCatchFire(worldIn, pos.east())) -+ if (Blocks.FIRE.canCatchFire(worldIn, pos.east(), EnumFacing.WEST)) - { - for (int k = 0; k < 2; k++) - { -@@ -433,7 +439,7 @@ - } - } - -- if (Blocks.FIRE.canCatchFire(worldIn, pos.north())) -+ if (Blocks.FIRE.canCatchFire(worldIn, pos.north(), EnumFacing.SOUTH)) - { - for (int l = 0; l < 2; l++) - { -@@ -444,7 +450,7 @@ - } - } - -- if (Blocks.FIRE.canCatchFire(worldIn, pos.south())) -+ if (Blocks.FIRE.canCatchFire(worldIn, pos.south(), EnumFacing.NORTH)) - { - for (int i1 = 0; i1 < 2; i1++) - { -@@ -455,7 +461,7 @@ - } - } - -- if (Blocks.FIRE.canCatchFire(worldIn, pos.up())) -+ if (Blocks.FIRE.canCatchFire(worldIn, pos.up(), EnumFacing.DOWN)) - { - for (int j1 = 0; j1 < 2; j1++) - { -@@ -508,6 +514,21 @@ - { - return new BlockStateContainer(this, AGE, NORTH, EAST, SOUTH, WEST, UPPER); - } -+ -+ /*================================= Forge Start ======================================*/ -+ /** -+ * Side sensitive version that calls the block function. -+ * -+ * @param world The current world -+ * @param pos Block position -+ * @param face The side the fire is coming from -+ * @return True if the face can catch fire. -+ */ -+ public boolean canCatchFire(IBlockAccess world, BlockPos pos, EnumFacing face) -+ { -+ return world.getBlockState(pos).getBlock().isFlammable(world, pos, face); -+ } -+ /*================================= Forge Start ======================================*/ - - @Override - public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face) diff --git a/patches/minecraft/net/minecraft/block/BlockFlowerPot.java.patch b/patches/minecraft/net/minecraft/block/BlockFlowerPot.java.patch deleted file mode 100644 index 9f60ce852..000000000 --- a/patches/minecraft/net/minecraft/block/BlockFlowerPot.java.patch +++ /dev/null @@ -1,67 +0,0 @@ ---- before/net/minecraft/block/BlockFlowerPot.java -+++ after/net/minecraft/block/BlockFlowerPot.java -@@ -177,13 +177,15 @@ - @Override - public boolean canPlaceBlockAt(World worldIn, BlockPos pos) - { -- return super.canPlaceBlockAt(worldIn, pos) && worldIn.getBlockState(pos.down()).isTopSolid(); -+ IBlockState downState = worldIn.getBlockState(pos.down()); -+ return super.canPlaceBlockAt(worldIn, pos) && (downState.isTopSolid() || downState.getBlockFaceShape(worldIn, pos.down(), EnumFacing.UP) == BlockFaceShape.SOLID); - } - - @Override - public void neighborChanged(IBlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos) - { -- if (!worldIn.getBlockState(pos.down()).isTopSolid()) -+ IBlockState downState = worldIn.getBlockState(pos.down()); -+ if (!downState.isTopSolid() && downState.getBlockFaceShape(worldIn, pos.down(), EnumFacing.UP) != BlockFaceShape.SOLID) - { - this.dropBlockAsItem(worldIn, pos, state, 0); - worldIn.setBlockToAir(pos); -@@ -193,13 +195,6 @@ - @Override - public void breakBlock(World worldIn, BlockPos pos, IBlockState state) - { -- TileEntityFlowerPot tileentityflowerpot = this.getTileEntity(worldIn, pos); -- -- if (tileentityflowerpot != null && tileentityflowerpot.getFlowerPotItem() != null) -- { -- spawnAsEntity(worldIn, pos, new ItemStack(tileentityflowerpot.getFlowerPotItem(), 1, tileentityflowerpot.getFlowerPotData())); -- } -- - super.breakBlock(worldIn, pos, state); - } - -@@ -434,6 +429,32 @@ - { - return BlockFaceShape.UNDEFINED; - } -+ -+ -+ /*============================FORGE START=====================================*/ -+ @Override -+ public void getDrops(net.minecraft.util.NonNullList drops, IBlockAccess world, BlockPos pos, IBlockState state, int fortune) -+ { -+ super.getDrops(drops, world, pos, state, fortune); -+ TileEntityFlowerPot te = world.getTileEntity(pos) instanceof TileEntityFlowerPot ? (TileEntityFlowerPot)world.getTileEntity(pos) : null; -+ if (te != null && te.getFlowerPotItem() != null) -+ drops.add(new ItemStack(te.getFlowerPotItem(), 1, te.getFlowerPotData())); -+ } -+ -+ @Override -+ public boolean removedByPlayer(IBlockState state, World world, BlockPos pos, EntityPlayer player, boolean willHarvest) -+ { -+ if (willHarvest) return true; //If it will harvest, delay deletion of the block until after getDrops -+ return super.removedByPlayer(state, world, pos, player, willHarvest); -+ } -+ -+ @Override -+ public void harvestBlock(World world, EntityPlayer player, BlockPos pos, IBlockState state, @Nullable TileEntity te, ItemStack tool) -+ { -+ super.harvestBlock(world, player, pos, state, te, tool); -+ world.setBlockToAir(pos); -+ } -+ /*===========================FORGE END==========================================*/ - - public static enum EnumFlowerType implements IStringSerializable - { diff --git a/patches/minecraft/net/minecraft/block/BlockGrass.java.patch b/patches/minecraft/net/minecraft/block/BlockGrass.java.patch deleted file mode 100644 index a7653635c..000000000 --- a/patches/minecraft/net/minecraft/block/BlockGrass.java.patch +++ /dev/null @@ -1,42 +0,0 @@ ---- before/net/minecraft/block/BlockGrass.java -+++ after/net/minecraft/block/BlockGrass.java -@@ -39,7 +39,8 @@ - { - if (!worldIn.isRemote) - { -- if (worldIn.getLightFromNeighbors(pos.up()) < 4 && worldIn.getBlockState(pos.up()).getLightOpacity() > 2) -+ if (!worldIn.isAreaLoaded(pos, 3)) return; // Forge: prevent loading unloaded chunks when checking neighbor's light and spreading -+ if (worldIn.getLightFromNeighbors(pos.up()) < 4 && worldIn.getBlockState(pos.up()).getLightOpacity(worldIn, pos.up()) > 2) - { - worldIn.setBlockState(pos, Blocks.DIRT.getDefaultState()); - } -@@ -62,7 +63,7 @@ - if (iblockstate1.getBlock() == Blocks.DIRT - && iblockstate1.getValue(BlockDirt.VARIANT) == BlockDirt.DirtType.DIRT - && worldIn.getLightFromNeighbors(blockpos.up()) >= 4 -- && iblockstate.getLightOpacity() <= 2) -+ && iblockstate.getLightOpacity(worldIn, pos.up()) <= 2) - { - worldIn.setBlockState(blockpos, Blocks.GRASS.getDefaultState()); - } -@@ -114,18 +115,11 @@ - } - } - -- if (worldIn.getBlockState(blockpos1).getBlock().material == Material.AIR) -+ if (worldIn.isAirBlock(blockpos1)) - { - if (rand.nextInt(8) == 0) - { -- BlockFlower.EnumFlowerType blockflower$enumflowertype = worldIn.getBiome(blockpos1).pickRandomFlower(rand, blockpos1); -- BlockFlower blockflower = blockflower$enumflowertype.getBlockType().getBlock(); -- IBlockState iblockstate = blockflower.getDefaultState().withProperty(blockflower.getTypeProperty(), blockflower$enumflowertype); -- -- if (blockflower.canBlockStay(worldIn, blockpos1, iblockstate)) -- { -- worldIn.setBlockState(blockpos1, iblockstate, 3); -- } -+ worldIn.getBiome(blockpos1).plantFlower(worldIn, rand, blockpos1); - } - else - { diff --git a/patches/minecraft/net/minecraft/block/BlockHugeMushroom.java.patch b/patches/minecraft/net/minecraft/block/BlockHugeMushroom.java.patch deleted file mode 100644 index 2cf4c97fb..000000000 --- a/patches/minecraft/net/minecraft/block/BlockHugeMushroom.java.patch +++ /dev/null @@ -1,31 +0,0 @@ ---- before/net/minecraft/block/BlockHugeMushroom.java -+++ after/net/minecraft/block/BlockHugeMushroom.java -@@ -3,6 +3,7 @@ - import java.util.Random; - import net.minecraft.block.material.MapColor; - import net.minecraft.block.material.Material; -+import net.minecraft.block.properties.IProperty; - import net.minecraft.block.properties.PropertyEnum; - import net.minecraft.block.state.BlockStateContainer; - import net.minecraft.block.state.IBlockState; -@@ -237,6 +238,20 @@ - protected BlockStateContainer createBlockState() - { - return new BlockStateContainer(this, VARIANT); -+ } -+ -+ public boolean rotateBlock(World world, BlockPos pos, EnumFacing axis) -+ { -+ IBlockState state = world.getBlockState(pos); -+ for (IProperty prop : (java.util.Set>)state.getProperties().keySet()) -+ { -+ if (prop.getName().equals("variant")) -+ { -+ world.setBlockState(pos, state.cycleProperty(prop)); -+ return true; -+ } -+ } -+ return false; - } - - public static enum EnumType implements IStringSerializable diff --git a/patches/minecraft/net/minecraft/block/BlockIce.java.patch b/patches/minecraft/net/minecraft/block/BlockIce.java.patch deleted file mode 100644 index 38c63662e..000000000 --- a/patches/minecraft/net/minecraft/block/BlockIce.java.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- before/net/minecraft/block/BlockIce.java -+++ after/net/minecraft/block/BlockIce.java -@@ -45,9 +45,14 @@ - player.addStat(StatList.getBlockStats(this)); - player.addExhaustion(0.005F); - -- if (this.canSilkHarvest() && EnchantmentHelper.getEnchantmentLevel(Enchantments.SILK_TOUCH, stack) > 0) -+ if (this.canSilkHarvest(worldIn, pos, state, player) && EnchantmentHelper.getEnchantmentLevel(Enchantments.SILK_TOUCH, stack) > 0) - { -- spawnAsEntity(worldIn, pos, this.getSilkTouchDrop(state)); -+ java.util.List items = new java.util.ArrayList(); -+ items.add(this.getSilkTouchDrop(state)); -+ -+ net.minecraftforge.event.ForgeEventFactory.fireBlockHarvesting(items, worldIn, pos, state, 0, 1.0f, true, player); -+ for (ItemStack is : items) -+ spawnAsEntity(worldIn, pos, is); - } - else - { -@@ -58,7 +63,9 @@ - } - - int i = EnchantmentHelper.getEnchantmentLevel(Enchantments.FORTUNE, stack); -+ harvesters.set(player); - this.dropBlockAsItem(worldIn, pos, state, i); -+ harvesters.set(null); - Material material = worldIn.getBlockState(pos.down()).getMaterial(); - - if (material.blocksMovement() || material.isLiquid()) diff --git a/patches/minecraft/net/minecraft/block/BlockLadder.java.patch b/patches/minecraft/net/minecraft/block/BlockLadder.java.patch deleted file mode 100644 index bb62bbb9d..000000000 --- a/patches/minecraft/net/minecraft/block/BlockLadder.java.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- before/net/minecraft/block/BlockLadder.java -+++ after/net/minecraft/block/BlockLadder.java -@@ -177,6 +177,11 @@ - } - - @Override -+ public boolean isLadder(IBlockState state, IBlockAccess world, BlockPos pos, EntityLivingBase entity) { -+ return true; -+ } -+ -+ @Override - public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face) - { - return BlockFaceShape.UNDEFINED; diff --git a/patches/minecraft/net/minecraft/block/BlockLeaves.java.patch b/patches/minecraft/net/minecraft/block/BlockLeaves.java.patch deleted file mode 100644 index 1c4e1eabf..000000000 --- a/patches/minecraft/net/minecraft/block/BlockLeaves.java.patch +++ /dev/null @@ -1,148 +0,0 @@ ---- before/net/minecraft/block/BlockLeaves.java -+++ after/net/minecraft/block/BlockLeaves.java -@@ -17,7 +17,7 @@ - import net.minecraftforge.fml.relauncher.Side; - import net.minecraftforge.fml.relauncher.SideOnly; - --public abstract class BlockLeaves extends Block -+public abstract class BlockLeaves extends Block implements net.minecraftforge.common.IShearable - { - public static final PropertyBool DECAYABLE = PropertyBool.create("decayable"); - public static final PropertyBool CHECK_DECAY = PropertyBool.create("check_decay"); -@@ -54,9 +54,9 @@ - BlockPos blockpos = pos.add(j1, k1, l1); - IBlockState iblockstate = worldIn.getBlockState(blockpos); - -- if (iblockstate.getMaterial() == Material.LEAVES && !iblockstate.getValue(CHECK_DECAY)) -+ if (iblockstate.getBlock().isLeaves(iblockstate, worldIn, blockpos)) - { -- worldIn.setBlockState(blockpos, iblockstate.withProperty(CHECK_DECAY, true), 4); -+ iblockstate.getBlock().beginLeavesDecay(iblockstate, worldIn, blockpos); - } - } - } -@@ -85,7 +85,8 @@ - this.surroundings = new int[32768]; - } - -- if (worldIn.isAreaLoaded(new BlockPos(k - 5, l - 5, i1 - 5), new BlockPos(k + 5, l + 5, i1 + 5))) -+ if (!worldIn.isAreaLoaded(pos, 1)) return; // Forge: prevent decaying leaves from updating neighbors and loading unloaded chunks -+ if (worldIn.isAreaLoaded(pos, 6)) // Forge: extend range from 5 to 6 to account for neighbor checks in world.markAndNotifyBlock -> world.updateObservingBlocksAt - { - BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos(); - -@@ -98,9 +99,9 @@ - IBlockState iblockstate = worldIn.getBlockState(blockpos$mutableblockpos.setPos(k + i2, l + j2, i1 + k2)); - Block block = iblockstate.getBlock(); - -- if (block != Blocks.LOG && block != Blocks.LOG2) -+ if (!block.canSustainLeaves(iblockstate, worldIn, blockpos$mutableblockpos.setPos(k + i2, l + j2, i1 + k2))) - { -- if (iblockstate.getMaterial() == Material.LEAVES) -+ if (block.isLeaves(iblockstate, worldIn, blockpos$mutableblockpos.setPos(k + i2, l + j2, i1 + k2))) - { - this.surroundings[(i2 + 16) * 1024 + (j2 + 16) * 32 + k2 + 16] = -2; - } -@@ -213,40 +214,7 @@ - @Override - public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, IBlockState state, float chance, int fortune) - { -- if (!worldIn.isRemote) -- { -- int i = this.getSaplingDropChance(state); -- -- if (fortune > 0) -- { -- i -= 2 << fortune; -- -- if (i < 10) -- { -- i = 10; -- } -- } -- -- if (worldIn.rand.nextInt(i) == 0) -- { -- Item item = this.getItemDropped(state, worldIn.rand, fortune); -- spawnAsEntity(worldIn, pos, new ItemStack(item, 1, this.damageDropped(state))); -- } -- -- i = 200; -- -- if (fortune > 0) -- { -- i -= 10 << fortune; -- -- if (i < 40) -- { -- i = 40; -- } -- } -- -- this.dropApple(worldIn, pos, state, i); -- } -+ super.dropBlockAsItemWithChance(worldIn, pos, state, chance, fortune); - } - - protected void dropApple(World worldIn, BlockPos pos, IBlockState state, int chance) -@@ -284,6 +252,60 @@ - } - - public abstract BlockPlanks.EnumType getWoodType(int meta); -+ -+ @Override -+ public boolean isShearable(ItemStack item, IBlockAccess world, BlockPos pos) -+ { -+ return true; -+ } -+ -+ @Override -+ public boolean isLeaves(IBlockState state, IBlockAccess world, BlockPos pos) -+ { -+ return true; -+ } -+ -+ @Override -+ public void beginLeavesDecay(IBlockState state, World world, BlockPos pos) -+ { -+ if (!(Boolean)state.getValue(CHECK_DECAY)) -+ { -+ world.setBlockState(pos, state.withProperty(CHECK_DECAY, true), 4); -+ } -+ } -+ -+ @Override -+ public void getDrops(net.minecraft.util.NonNullList drops, IBlockAccess world, BlockPos pos, IBlockState state, int fortune) -+ { -+ Random rand = world instanceof World ? ((World)world).rand : new Random(); -+ int chance = this.getSaplingDropChance(state); -+ -+ if (fortune > 0) -+ { -+ chance -= 2 << fortune; -+ if (chance < 10) chance = 10; -+ } -+ -+ if (rand.nextInt(chance) == 0) -+ { -+ ItemStack drop = new ItemStack(getItemDropped(state, rand, fortune), 1, damageDropped(state)); -+ if (!drop.isEmpty()) -+ drops.add(drop); -+ } -+ -+ chance = 200; -+ if (fortune > 0) -+ { -+ chance -= 10 << fortune; -+ if (chance < 40) chance = 40; -+ } -+ -+ this.captureDrops(true); -+ if (world instanceof World) -+ this.dropApple((World)world, pos, state, chance); // Dammet mojang -+ drops.addAll(this.captureDrops(false)); -+ } -+ - - @SideOnly(Side.CLIENT) - @Override diff --git a/patches/minecraft/net/minecraft/block/BlockLiquid.java.patch b/patches/minecraft/net/minecraft/block/BlockLiquid.java.patch deleted file mode 100644 index a4e91b9db..000000000 --- a/patches/minecraft/net/minecraft/block/BlockLiquid.java.patch +++ /dev/null @@ -1,59 +0,0 @@ ---- before/net/minecraft/block/BlockLiquid.java -+++ after/net/minecraft/block/BlockLiquid.java -@@ -409,14 +409,14 @@ - - if (integer == 0) - { -- worldIn.setBlockState(pos, Blocks.OBSIDIAN.getDefaultState()); -+ worldIn.setBlockState(pos, net.minecraftforge.event.ForgeEventFactory.fireFluidPlaceBlockEvent(worldIn, pos, pos, Blocks.OBSIDIAN.getDefaultState())); - this.triggerMixEffects(worldIn, pos); - return true; - } - - if (integer <= 4) - { -- worldIn.setBlockState(pos, Blocks.COBBLESTONE.getDefaultState()); -+ worldIn.setBlockState(pos, net.minecraftforge.event.ForgeEventFactory.fireFluidPlaceBlockEvent(worldIn, pos, pos, Blocks.COBBLESTONE.getDefaultState())); - this.triggerMixEffects(worldIn, pos); - return true; - } -@@ -508,8 +508,39 @@ - } - - @Override -+ public float getBlockLiquidHeight(World world, BlockPos pos, IBlockState state, Material material) -+ { -+ return BlockLiquid.getBlockLiquidHeight(state, world, pos); -+ } -+ -+ @Override - public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face) - { - return BlockFaceShape.UNDEFINED; -+ } -+ -+ @Override -+ @SideOnly (Side.CLIENT) -+ public Vec3d getFogColor(World world, BlockPos pos, IBlockState state, Entity entity, Vec3d originalColor, float partialTicks) -+ { -+ Vec3d viewport = net.minecraft.client.renderer.ActiveRenderInfo.projectViewFromEntity(entity, partialTicks); -+ -+ if (state.getMaterial().isLiquid()) -+ { -+ float height = 0.0F; -+ if (state.getBlock() instanceof BlockLiquid) -+ { -+ height = getLiquidHeightPercent(state.getValue(LEVEL)) - 0.11111111F; -+ } -+ float f1 = (float) (pos.getY() + 1) - height; -+ if (viewport.y > (double)f1) -+ { -+ BlockPos upPos = pos.up(); -+ IBlockState upState = world.getBlockState(upPos); -+ return upState.getBlock().getFogColor(world, upPos, upState, entity, originalColor, partialTicks); -+ } -+ } -+ -+ return super.getFogColor(world, pos, state, entity, originalColor, partialTicks); - } - } diff --git a/patches/minecraft/net/minecraft/block/BlockLog.java.patch b/patches/minecraft/net/minecraft/block/BlockLog.java.patch deleted file mode 100644 index 387972dc0..000000000 --- a/patches/minecraft/net/minecraft/block/BlockLog.java.patch +++ /dev/null @@ -1,33 +0,0 @@ ---- before/net/minecraft/block/BlockLog.java -+++ after/net/minecraft/block/BlockLog.java -@@ -35,9 +35,9 @@ - { - IBlockState iblockstate = worldIn.getBlockState(blockpos); - -- if (iblockstate.getMaterial() == Material.LEAVES && !iblockstate.getValue(BlockLeaves.CHECK_DECAY)) -+ if (iblockstate.getBlock().isLeaves(iblockstate, worldIn, blockpos)) - { -- worldIn.setBlockState(blockpos, iblockstate.withProperty(BlockLeaves.CHECK_DECAY, true), 4); -+ iblockstate.getBlock().beginLeavesDecay(iblockstate, worldIn, blockpos); - } - } - } -@@ -79,6 +79,18 @@ - default: - return state; - } -+ } -+ -+ @Override -+ public boolean canSustainLeaves(IBlockState state, net.minecraft.world.IBlockAccess world, BlockPos pos) -+ { -+ return true; -+ } -+ -+ @Override -+ public boolean isWood(net.minecraft.world.IBlockAccess world, BlockPos pos) -+ { -+ return true; - } - - public static enum EnumAxis implements IStringSerializable diff --git a/patches/minecraft/net/minecraft/block/BlockMobSpawner.java.patch b/patches/minecraft/net/minecraft/block/BlockMobSpawner.java.patch deleted file mode 100644 index c210890db..000000000 --- a/patches/minecraft/net/minecraft/block/BlockMobSpawner.java.patch +++ /dev/null @@ -1,17 +0,0 @@ ---- before/net/minecraft/block/BlockMobSpawner.java -+++ after/net/minecraft/block/BlockMobSpawner.java -@@ -44,8 +44,12 @@ - public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, IBlockState state, float chance, int fortune) - { - super.dropBlockAsItemWithChance(worldIn, pos, state, chance, fortune); -- int i = 15 + worldIn.rand.nextInt(15) + worldIn.rand.nextInt(15); -- this.dropXpOnBlockBreak(worldIn, pos, i); -+ } -+ -+ @Override -+ public int getExpDrop(IBlockState state, net.minecraft.world.IBlockAccess world, BlockPos pos, int fortune) -+ { -+ return 15 + RANDOM.nextInt(15) + RANDOM.nextInt(15); - } - - @Override diff --git a/patches/minecraft/net/minecraft/block/BlockMushroom.java.patch b/patches/minecraft/net/minecraft/block/BlockMushroom.java.patch deleted file mode 100644 index 80e907816..000000000 --- a/patches/minecraft/net/minecraft/block/BlockMushroom.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/block/BlockMushroom.java -+++ after/net/minecraft/block/BlockMushroom.java -@@ -90,7 +90,7 @@ - { - return iblockstate.getBlock() == Blocks.DIRT && iblockstate.getValue(BlockDirt.VARIANT) == BlockDirt.DirtType.PODZOL - ? true -- : worldIn.getLight(pos) < 13 && this.canSustainBush(iblockstate); -+ : worldIn.getLight(pos) < 13 && iblockstate.getBlock().canSustainPlant(iblockstate, worldIn, pos.down(), net.minecraft.util.EnumFacing.UP, this); - } - } - else diff --git a/patches/minecraft/net/minecraft/block/BlockMycelium.java.patch b/patches/minecraft/net/minecraft/block/BlockMycelium.java.patch deleted file mode 100644 index 2366b9167..000000000 --- a/patches/minecraft/net/minecraft/block/BlockMycelium.java.patch +++ /dev/null @@ -1,21 +0,0 @@ ---- before/net/minecraft/block/BlockMycelium.java -+++ after/net/minecraft/block/BlockMycelium.java -@@ -40,7 +40,8 @@ - { - if (!worldIn.isRemote) - { -- if (worldIn.getLightFromNeighbors(pos.up()) < 4 && worldIn.getBlockState(pos.up()).getLightOpacity() > 2) -+ if (!worldIn.isAreaLoaded(pos, 2)) return; // Forge: prevent loading unloaded chunks when checking neighbor's light and spreading -+ if (worldIn.getLightFromNeighbors(pos.up()) < 4 && worldIn.getBlockState(pos.up()).getLightOpacity(worldIn, pos.up()) > 2) - { - worldIn.setBlockState(pos, Blocks.DIRT.getDefaultState().withProperty(BlockDirt.VARIANT, BlockDirt.DirtType.DIRT)); - } -@@ -57,7 +58,7 @@ - if (iblockstate.getBlock() == Blocks.DIRT - && iblockstate.getValue(BlockDirt.VARIANT) == BlockDirt.DirtType.DIRT - && worldIn.getLightFromNeighbors(blockpos.up()) >= 4 -- && iblockstate1.getLightOpacity() <= 2) -+ && iblockstate1.getLightOpacity(worldIn, blockpos.up()) <= 2) - { - worldIn.setBlockState(blockpos, this.getDefaultState()); - } diff --git a/patches/minecraft/net/minecraft/block/BlockNetherWart.java.patch b/patches/minecraft/net/minecraft/block/BlockNetherWart.java.patch deleted file mode 100644 index f057f57a8..000000000 --- a/patches/minecraft/net/minecraft/block/BlockNetherWart.java.patch +++ /dev/null @@ -1,62 +0,0 @@ ---- before/net/minecraft/block/BlockNetherWart.java -+++ after/net/minecraft/block/BlockNetherWart.java -@@ -49,7 +49,7 @@ - @Override - public boolean canBlockStay(World worldIn, BlockPos pos, IBlockState state) - { -- return this.canSustainBush(worldIn.getBlockState(pos.down())); -+ return super.canBlockStay(worldIn, pos, state); - } - - @Override -@@ -57,19 +57,22 @@ - { - int i = state.getValue(AGE); - -- if (i < 3 && rand.nextInt(10) == 0) -+ if (i < 3 && net.minecraftforge.common.ForgeHooks.onCropsGrowPre(worldIn, pos, state, rand.nextInt(10) == 0)) - { -- state = state.withProperty(AGE, i + 1); -- worldIn.setBlockState(pos, state, 2); -+ IBlockState newState = state.withProperty(AGE, i + 1); -+ worldIn.setBlockState(pos, newState, 2); -+ net.minecraftforge.common.ForgeHooks.onCropsGrowPost(worldIn, pos, state, newState); - } - - super.updateTick(worldIn, pos, state, rand); - } - -+ @SuppressWarnings("unused") - @Override - public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, IBlockState state, float chance, int fortune) - { -- if (!worldIn.isRemote) -+ super.dropBlockAsItemWithChance(worldIn, pos, state, chance, fortune); -+ if (false && !worldIn.isRemote) - { - int i = 1; - -@@ -118,6 +121,23 @@ - public int getMetaFromState(IBlockState state) - { - return state.getValue(AGE); -+ } -+ -+ @Override -+ public void getDrops(net.minecraft.util.NonNullList drops, net.minecraft.world.IBlockAccess world, BlockPos pos, IBlockState state, int fortune) -+ { -+ Random rand = world instanceof World ? ((World)world).rand : new Random(); -+ int count = 1; -+ -+ if (state.getValue(AGE) >= 3) -+ { -+ count = 2 + rand.nextInt(3) + (fortune > 0 ? rand.nextInt(fortune + 1) : 0); -+ } -+ -+ for (int i = 0; i < count; i++) -+ { -+ drops.add(new ItemStack(Items.NETHER_WART)); -+ } - } - - @Override diff --git a/patches/minecraft/net/minecraft/block/BlockNewLeaf.java.patch b/patches/minecraft/net/minecraft/block/BlockNewLeaf.java.patch deleted file mode 100644 index 82ed27f39..000000000 --- a/patches/minecraft/net/minecraft/block/BlockNewLeaf.java.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- before/net/minecraft/block/BlockNewLeaf.java -+++ after/net/minecraft/block/BlockNewLeaf.java -@@ -128,4 +128,10 @@ - super.harvestBlock(worldIn, player, pos, state, te, stack); - } - } -+ -+ @Override -+ public NonNullList onSheared(ItemStack item, net.minecraft.world.IBlockAccess world, BlockPos pos, int fortune) -+ { -+ return NonNullList.withSize(1, new ItemStack(this, 1, world.getBlockState(pos).getValue(VARIANT).getMetadata() - 4)); -+ } - } diff --git a/patches/minecraft/net/minecraft/block/BlockNote.java.patch b/patches/minecraft/net/minecraft/block/BlockNote.java.patch deleted file mode 100644 index 02c59ed69..000000000 --- a/patches/minecraft/net/minecraft/block/BlockNote.java.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- before/net/minecraft/block/BlockNote.java -+++ after/net/minecraft/block/BlockNote.java -@@ -86,7 +86,9 @@ - if (tileentity instanceof TileEntityNote) - { - TileEntityNote tileentitynote = (TileEntityNote)tileentity; -+ int old = tileentitynote.note; - tileentitynote.changePitch(); -+ if (old == tileentitynote.note) return false; - tileentitynote.triggerNote(worldIn, pos); - playerIn.addStat(StatList.NOTEBLOCK_TUNED); - } -@@ -129,6 +131,10 @@ - @Override - public boolean eventReceived(IBlockState state, World worldIn, BlockPos pos, int id, int param) - { -+ net.minecraftforge.event.world.NoteBlockEvent.Play e = new net.minecraftforge.event.world.NoteBlockEvent.Play(worldIn, pos, state, param, id); -+ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(e)) return false; -+ id = e.getInstrument().ordinal(); -+ param = e.getVanillaNoteId(); - float f = (float)Math.pow(2.0, (param - 12) / 12.0); - worldIn.playSound(null, pos, this.getInstrument(id), SoundCategory.RECORDS, 3.0F, f); - worldIn.spawnParticle( diff --git a/patches/minecraft/net/minecraft/block/BlockObserver.java.patch b/patches/minecraft/net/minecraft/block/BlockObserver.java.patch deleted file mode 100644 index a7d7be856..000000000 --- a/patches/minecraft/net/minecraft/block/BlockObserver.java.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- before/net/minecraft/block/BlockObserver.java -+++ after/net/minecraft/block/BlockObserver.java -@@ -166,4 +166,12 @@ - { - return this.getDefaultState().withProperty(FACING, EnumFacing.byIndex(meta & 7)); - } -+ -+ /* ======================================== FORGE START =====================================*/ -+ @Override -+ public void observedNeighborChange(IBlockState observerState, World world, BlockPos observerPos, Block changedBlock, BlockPos changedBlockPos) -+ { -+ observedNeighborChanged(observerState, world, observerPos, changedBlock, changedBlockPos); -+ } -+ /* ========================================= FORGE END ======================================*/ - } diff --git a/patches/minecraft/net/minecraft/block/BlockOldLeaf.java.patch b/patches/minecraft/net/minecraft/block/BlockOldLeaf.java.patch deleted file mode 100644 index 145fcd686..000000000 --- a/patches/minecraft/net/minecraft/block/BlockOldLeaf.java.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- before/net/minecraft/block/BlockOldLeaf.java -+++ after/net/minecraft/block/BlockOldLeaf.java -@@ -123,11 +123,16 @@ - if (!worldIn.isRemote && stack.getItem() == Items.SHEARS) - { - player.addStat(StatList.getBlockStats(this)); -- spawnAsEntity(worldIn, pos, new ItemStack(Item.getItemFromBlock(this), 1, state.getValue(VARIANT).getMetadata())); - } - else - { - super.harvestBlock(worldIn, player, pos, state, te, stack); - } -+ } -+ -+ @Override -+ public NonNullList onSheared(ItemStack item, net.minecraft.world.IBlockAccess world, BlockPos pos, int fortune) -+ { -+ return NonNullList.withSize(1, new ItemStack(this, 1, world.getBlockState(pos).getValue(VARIANT).getMetadata())); - } - } diff --git a/patches/minecraft/net/minecraft/block/BlockOre.java.patch b/patches/minecraft/net/minecraft/block/BlockOre.java.patch deleted file mode 100644 index 6a366115a..000000000 --- a/patches/minecraft/net/minecraft/block/BlockOre.java.patch +++ /dev/null @@ -1,50 +0,0 @@ ---- before/net/minecraft/block/BlockOre.java -+++ after/net/minecraft/block/BlockOre.java -@@ -82,34 +82,39 @@ - public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, IBlockState state, float chance, int fortune) - { - super.dropBlockAsItemWithChance(worldIn, pos, state, chance, fortune); -- -- if (this.getItemDropped(state, worldIn.rand, fortune) != Item.getItemFromBlock(this)) -+ } -+ @Override -+ public int getExpDrop(IBlockState state, net.minecraft.world.IBlockAccess world, BlockPos pos, int fortune) -+ { -+ Random rand = world instanceof World ? ((World)world).rand : new Random(); -+ if (this.getItemDropped(state, rand, fortune) != Item.getItemFromBlock(this)) - { - int i = 0; - - if (this == Blocks.COAL_ORE) - { -- i = MathHelper.getInt(worldIn.rand, 0, 2); -+ i = MathHelper.getInt(rand, 0, 2); - } - else if (this == Blocks.DIAMOND_ORE) - { -- i = MathHelper.getInt(worldIn.rand, 3, 7); -+ i = MathHelper.getInt(rand, 3, 7); - } - else if (this == Blocks.EMERALD_ORE) - { -- i = MathHelper.getInt(worldIn.rand, 3, 7); -+ i = MathHelper.getInt(rand, 3, 7); - } - else if (this == Blocks.LAPIS_ORE) - { -- i = MathHelper.getInt(worldIn.rand, 2, 5); -+ i = MathHelper.getInt(rand, 2, 5); - } - else if (this == Blocks.QUARTZ_ORE) - { -- i = MathHelper.getInt(worldIn.rand, 2, 5); -+ i = MathHelper.getInt(rand, 2, 5); - } - -- this.dropXpOnBlockBreak(worldIn, pos, i); -+ return i; - } -+ return 0; - } - - @Override diff --git a/patches/minecraft/net/minecraft/block/BlockPane.java.patch b/patches/minecraft/net/minecraft/block/BlockPane.java.patch deleted file mode 100644 index 1a1171100..000000000 --- a/patches/minecraft/net/minecraft/block/BlockPane.java.patch +++ /dev/null @@ -1,54 +0,0 @@ ---- before/net/minecraft/block/BlockPane.java -+++ after/net/minecraft/block/BlockPane.java -@@ -147,22 +147,10 @@ - @Override - public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos) - { -- return state.withProperty( -- NORTH, -- this.attachesTo(worldIn, worldIn.getBlockState(pos.north()), pos.north(), EnumFacing.SOUTH) -- ) -- .withProperty( -- SOUTH, -- this.attachesTo(worldIn, worldIn.getBlockState(pos.south()), pos.south(), EnumFacing.NORTH) -- ) -- .withProperty( -- WEST, -- this.attachesTo(worldIn, worldIn.getBlockState(pos.west()), pos.west(), EnumFacing.EAST) -- ) -- .withProperty( -- EAST, -- this.attachesTo(worldIn, worldIn.getBlockState(pos.east()), pos.east(), EnumFacing.WEST) -- ); -+ return state.withProperty(NORTH, canPaneConnectTo(worldIn, pos, EnumFacing.NORTH)) -+ .withProperty(SOUTH, canPaneConnectTo(worldIn, pos, EnumFacing.SOUTH)) -+ .withProperty(WEST, canPaneConnectTo(worldIn, pos, EnumFacing.WEST)) -+ .withProperty(EAST, canPaneConnectTo(worldIn, pos, EnumFacing.EAST)); - } - - @Override -@@ -282,6 +270,24 @@ - { - return new BlockStateContainer(this, NORTH, EAST, WEST, SOUTH); - } -+ -+ /* ======================================== FORGE START ======================================== */ -+ -+ @Override -+ public boolean canBeConnectedTo(IBlockAccess world, BlockPos pos, EnumFacing facing) -+ { -+ BlockPos offset = pos.offset(facing); -+ return attachesTo(world, world.getBlockState(offset), offset, facing.getOpposite()); -+ } -+ -+ public boolean canPaneConnectTo(IBlockAccess world, BlockPos pos, EnumFacing dir) -+ { -+ BlockPos other = pos.offset(dir); -+ IBlockState state = world.getBlockState(other); -+ return state.getBlock().canBeConnectedTo(world, other, dir.getOpposite()) || attachesTo(world, state, other, dir.getOpposite()); -+ } -+ -+ /* ======================================== FORGE END ======================================== */ - - @Override - public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face) diff --git a/patches/minecraft/net/minecraft/block/BlockPistonBase.java.patch b/patches/minecraft/net/minecraft/block/BlockPistonBase.java.patch deleted file mode 100644 index ddabd6c93..000000000 --- a/patches/minecraft/net/minecraft/block/BlockPistonBase.java.patch +++ /dev/null @@ -1,46 +0,0 @@ ---- before/net/minecraft/block/BlockPistonBase.java -+++ after/net/minecraft/block/BlockPistonBase.java -@@ -279,7 +279,7 @@ - } - - if (!flag1 -- && iblockstate.getMaterial() != Material.AIR -+ && !iblockstate.getBlock().isAir(iblockstate, worldIn, blockpos) - && canPush(iblockstate, worldIn, blockpos, enumfacing.getOpposite(), false, enumfacing) - && (iblockstate.getPushReaction() == EnumPushReaction.NORMAL || block == Blocks.PISTON || block == Blocks.STICKY_PISTON)) - { -@@ -353,7 +353,7 @@ - return false; - } - -- return !block.hasTileEntity(); -+ return !block.hasTileEntity(blockStateIn); - } - else - { -@@ -399,7 +399,9 @@ - { - BlockPos blockpos1 = list2.get(j); - IBlockState iblockstate = worldIn.getBlockState(blockpos1); -- iblockstate.getBlock().dropBlockAsItem(worldIn, blockpos1, iblockstate, 0); -+ // Forge: With our change to how snowballs are dropped this needs to disallow to mimic vanilla behavior. -+ float chance = iblockstate.getBlock() instanceof BlockSnow ? -1.0f : 1.0f; -+ iblockstate.getBlock().dropBlockAsItemWithChance(worldIn, blockpos1, iblockstate, chance, 0); - worldIn.setBlockState(blockpos1, Blocks.AIR.getDefaultState(), 4); - aiblockstate[--k] = iblockstate; - } -@@ -493,6 +495,14 @@ - { - return new BlockStateContainer(this, FACING, EXTENDED); - } -+ -+ /* ======================================== FORGE START =====================================*/ -+ public boolean rotateBlock(World world, BlockPos pos, EnumFacing axis) -+ { -+ IBlockState state = world.getBlockState(pos); -+ return !state.getValue(EXTENDED) && super.rotateBlock(world, pos, axis); -+ } -+ /* ======================================== FORGE END =======================================*/ - - @Override - public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face) diff --git a/patches/minecraft/net/minecraft/block/BlockPistonMoving.java.patch b/patches/minecraft/net/minecraft/block/BlockPistonMoving.java.patch deleted file mode 100644 index 7fcd1778d..000000000 --- a/patches/minecraft/net/minecraft/block/BlockPistonMoving.java.patch +++ /dev/null @@ -1,37 +0,0 @@ ---- before/net/minecraft/block/BlockPistonMoving.java -+++ after/net/minecraft/block/BlockPistonMoving.java -@@ -140,7 +140,7 @@ - @Override - public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, IBlockState state, float chance, int fortune) - { -- if (!worldIn.isRemote) -+ if (false && !worldIn.isRemote) // Forge: Noop this out - { - TileEntityPiston tileentitypiston = this.getTilePistonAt(worldIn, pos); - -@@ -150,6 +150,7 @@ - iblockstate.getBlock().dropBlockAsItem(worldIn, pos, iblockstate, 0); - } - } -+ super.dropBlockAsItemWithChance(worldIn, pos, state, 1, fortune); // mimic vanilla behavior from above and ignore chance - } - - @Nullable -@@ -253,6 +254,17 @@ - protected BlockStateContainer createBlockState() - { - return new BlockStateContainer(this, FACING, TYPE); -+ } -+ -+ @Override -+ public void getDrops(net.minecraft.util.NonNullList drops, IBlockAccess world, BlockPos pos, IBlockState state, int fortune) -+ { -+ TileEntityPiston tileentitypiston = this.getTilePistonAt(world, pos); -+ if (tileentitypiston != null) -+ { -+ IBlockState pushed = tileentitypiston.getPistonState(); -+ drops.addAll(pushed.getBlock().getDrops(world, pos, pushed, fortune)); // use the old method until it gets removed, for backward compatibility -+ } - } - - @Override diff --git a/patches/minecraft/net/minecraft/block/BlockPortal.java.patch b/patches/minecraft/net/minecraft/block/BlockPortal.java.patch deleted file mode 100644 index ca6d6425c..000000000 --- a/patches/minecraft/net/minecraft/block/BlockPortal.java.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- before/net/minecraft/block/BlockPortal.java -+++ after/net/minecraft/block/BlockPortal.java -@@ -124,7 +124,7 @@ - { - BlockPortal.Size blockportal$size = new BlockPortal.Size(worldIn, pos, EnumFacing.Axis.X); - -- if (blockportal$size.isValid() && blockportal$size.portalBlockCount == 0) -+ if (blockportal$size.isValid() && blockportal$size.portalBlockCount == 0 && !net.minecraftforge.event.ForgeEventFactory.onTrySpawnPortal(worldIn, pos, blockportal$size)) - { - blockportal$size.placePortalBlocks(); - return true; -@@ -133,7 +133,7 @@ - { - BlockPortal.Size blockportal$size1 = new BlockPortal.Size(worldIn, pos, EnumFacing.Axis.Z); - -- if (blockportal$size1.isValid() && blockportal$size1.portalBlockCount == 0) -+ if (blockportal$size1.isValid() && blockportal$size1.portalBlockCount == 0 && !net.minecraftforge.event.ForgeEventFactory.onTrySpawnPortal(worldIn, pos, blockportal$size1)) - { - blockportal$size1.placePortalBlocks(); - return true; diff --git a/patches/minecraft/net/minecraft/block/BlockPotato.java.patch b/patches/minecraft/net/minecraft/block/BlockPotato.java.patch deleted file mode 100644 index 916210d2e..000000000 --- a/patches/minecraft/net/minecraft/block/BlockPotato.java.patch +++ /dev/null @@ -1,25 +0,0 @@ ---- before/net/minecraft/block/BlockPotato.java -+++ after/net/minecraft/block/BlockPotato.java -@@ -40,7 +40,7 @@ - { - super.dropBlockAsItemWithChance(worldIn, pos, state, chance, fortune); - -- if (!worldIn.isRemote) -+ if (false && !worldIn.isRemote) //Forge: Moved to getDrops - { - if (this.isMaxAge(state) && worldIn.rand.nextInt(50) == 0) - { -@@ -53,5 +53,13 @@ - public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos) - { - return POTATO_AABB[state.getValue(this.getAgeProperty())]; -+ } -+ -+ @Override -+ public void getDrops(net.minecraft.util.NonNullList drops, net.minecraft.world.IBlockAccess world, BlockPos pos, IBlockState state, int fortune) -+ { -+ super.getDrops(drops, world, pos, state, fortune); -+ if (this.isMaxAge(state) && RANDOM.nextInt(50) == 0) -+ drops.add(new ItemStack(Items.POISONOUS_POTATO)); - } - } diff --git a/patches/minecraft/net/minecraft/block/BlockPumpkin.java.patch b/patches/minecraft/net/minecraft/block/BlockPumpkin.java.patch deleted file mode 100644 index 64474c24d..000000000 --- a/patches/minecraft/net/minecraft/block/BlockPumpkin.java.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- before/net/minecraft/block/BlockPumpkin.java -+++ after/net/minecraft/block/BlockPumpkin.java -@@ -153,8 +153,8 @@ - @Override - public boolean canPlaceBlockAt(World worldIn, BlockPos pos) - { -- return worldIn.getBlockState(pos).getBlock().material.isReplaceable() -- && worldIn.getBlockState(pos.down()).isTopSolid(); -+ return worldIn.getBlockState(pos).getBlock().isReplaceable(worldIn, pos) -+ && worldIn.isSideSolid(pos.down(), EnumFacing.UP); - } - - @Override diff --git a/patches/minecraft/net/minecraft/block/BlockQuartz.java.patch b/patches/minecraft/net/minecraft/block/BlockQuartz.java.patch deleted file mode 100644 index 908cd352d..000000000 --- a/patches/minecraft/net/minecraft/block/BlockQuartz.java.patch +++ /dev/null @@ -1,38 +0,0 @@ ---- before/net/minecraft/block/BlockQuartz.java -+++ after/net/minecraft/block/BlockQuartz.java -@@ -2,6 +2,7 @@ - - import net.minecraft.block.material.MapColor; - import net.minecraft.block.material.Material; -+import net.minecraft.block.properties.IProperty; - import net.minecraft.block.properties.PropertyEnum; - import net.minecraft.block.state.BlockStateContainer; - import net.minecraft.block.state.IBlockState; -@@ -129,6 +130,27 @@ - protected BlockStateContainer createBlockState() - { - return new BlockStateContainer(this, VARIANT); -+ } -+ -+ @Override -+ public boolean rotateBlock(World world, BlockPos pos, EnumFacing axis) -+ { -+ IBlockState state = world.getBlockState(pos); -+ for (IProperty prop : state.getProperties().keySet()) -+ { -+ if (prop.getName().equals("variant") && prop.getValueClass() == EnumType.class) -+ { -+ EnumType current = (EnumType)state.getValue(prop); -+ EnumType next = current == EnumType.LINES_X ? EnumType.LINES_Y : -+ current == EnumType.LINES_Y ? EnumType.LINES_Z : -+ current == EnumType.LINES_Z ? EnumType.LINES_X : current; -+ if (next == current) -+ return false; -+ world.setBlockState(pos, state.withProperty(prop, next)); -+ return true; -+ } -+ } -+ return false; - } - - public static enum EnumType implements IStringSerializable diff --git a/patches/minecraft/net/minecraft/block/BlockRailBase.java.patch b/patches/minecraft/net/minecraft/block/BlockRailBase.java.patch deleted file mode 100644 index 198d568e0..000000000 --- a/patches/minecraft/net/minecraft/block/BlockRailBase.java.patch +++ /dev/null @@ -1,259 +0,0 @@ ---- before/net/minecraft/block/BlockRailBase.java -+++ after/net/minecraft/block/BlockRailBase.java -@@ -34,7 +34,7 @@ - public static boolean isRailBlock(IBlockState state) - { - Block block = state.getBlock(); -- return block == Blocks.RAIL || block == Blocks.GOLDEN_RAIL || block == Blocks.DETECTOR_RAIL || block == Blocks.ACTIVATOR_RAIL; -+ return block instanceof BlockRailBase; - } - - protected BlockRailBase(boolean isPowered) -@@ -61,7 +61,7 @@ - public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos) - { - BlockRailBase.EnumRailDirection blockrailbase$enumraildirection = state.getBlock() == this -- ? state.getValue(this.getShapeProperty()) -+ ? getRailDirection(source, pos, state, null) - : null; - return blockrailbase$enumraildirection != null && blockrailbase$enumraildirection.isAscending() ? ASCENDING_AABB : FLAT_AABB; - } -@@ -81,7 +81,7 @@ - @Override - public boolean canPlaceBlockAt(World worldIn, BlockPos pos) - { -- return worldIn.getBlockState(pos.down()).isTopSolid(); -+ return worldIn.getBlockState(pos.down()).isSideSolid(worldIn, pos.down(), EnumFacing.UP); - } - - @Override -@@ -103,36 +103,33 @@ - { - if (!worldIn.isRemote) - { -- BlockRailBase.EnumRailDirection blockrailbase$enumraildirection = state.getValue(this.getShapeProperty()); -+ final IBlockState currentState = worldIn.getBlockState(pos); -+ BlockRailBase.EnumRailDirection blockrailbase$enumraildirection = getRailDirection(worldIn, pos, currentState.getBlock() == this ? currentState : state, null); - boolean flag = false; - -- if (!worldIn.getBlockState(pos.down()).isTopSolid()) -- { -- flag = true; -- } -- -- if (blockrailbase$enumraildirection == BlockRailBase.EnumRailDirection.ASCENDING_EAST -- && !worldIn.getBlockState(pos.east()).isTopSolid()) -- { -- flag = true; -- } -- else if (blockrailbase$enumraildirection == BlockRailBase.EnumRailDirection.ASCENDING_WEST -- && !worldIn.getBlockState(pos.west()).isTopSolid()) -- { -- flag = true; -- } -- else if (blockrailbase$enumraildirection == BlockRailBase.EnumRailDirection.ASCENDING_NORTH -- && !worldIn.getBlockState(pos.north()).isTopSolid()) -- { -- flag = true; -- } -- else if (blockrailbase$enumraildirection == BlockRailBase.EnumRailDirection.ASCENDING_SOUTH -- && !worldIn.getBlockState(pos.south()).isTopSolid()) -- { -- flag = true; -- } -- -- if (flag && !worldIn.isAirBlock(pos)) -+ if (!worldIn.getBlockState(pos.down()).isSideSolid(worldIn, pos.down(), EnumFacing.UP)) -+ { -+ flag = true; -+ } -+ -+ if (blockrailbase$enumraildirection == BlockRailBase.EnumRailDirection.ASCENDING_EAST && !worldIn.getBlockState(pos.east()).isSideSolid(worldIn, pos.east(), EnumFacing.UP)) -+ { -+ flag = true; -+ } -+ else if (blockrailbase$enumraildirection == BlockRailBase.EnumRailDirection.ASCENDING_WEST && !worldIn.getBlockState(pos.west()).isSideSolid(worldIn, pos.west(), EnumFacing.UP)) -+ { -+ flag = true; -+ } -+ else if (blockrailbase$enumraildirection == BlockRailBase.EnumRailDirection.ASCENDING_NORTH && !worldIn.getBlockState(pos.north()).isSideSolid(worldIn, pos.north(), EnumFacing.UP)) -+ { -+ flag = true; -+ } -+ else if (blockrailbase$enumraildirection == BlockRailBase.EnumRailDirection.ASCENDING_SOUTH && !worldIn.getBlockState(pos.south()).isSideSolid(worldIn, pos.south(), EnumFacing.UP)) -+ { -+ flag = true; -+ } -+ -+ if (flag && !currentState.getBlock().isAir(currentState, worldIn, pos)) - { - this.dropBlockAsItem(worldIn, pos, state, 0); - worldIn.setBlockToAir(pos); -@@ -173,7 +170,7 @@ - { - super.breakBlock(worldIn, pos, state); - -- if (state.getValue(this.getShapeProperty()).isAscending()) -+ if (getRailDirection(worldIn, pos, state, null).isAscending()) - { - worldIn.notifyNeighborsOfStateChange(pos.up(), this, false); - } -@@ -185,8 +182,102 @@ - } - } - -+ //Forge: Use getRailDirection(IBlockAccess, BlockPos, IBlockState, EntityMinecart) for enhanced ability - public abstract IProperty getShapeProperty(); - -+ /* ======================================== FORGE START =====================================*/ -+ /** -+ * Return true if the rail can make corners. -+ * Used by placement logic. -+ * @param world The world. -+ * @param pos Block's position in world -+ * @return True if the rail can make corners. -+ */ -+ public boolean isFlexibleRail(IBlockAccess world, BlockPos pos) -+ { -+ return !this.isPowered; -+ } -+ -+ /** -+ * Returns true if the rail can make up and down slopes. -+ * Used by placement logic. -+ * @param world The world. -+ * @param pos Block's position in world -+ * @return True if the rail can make slopes. -+ */ -+ public boolean canMakeSlopes(IBlockAccess world, BlockPos pos) -+ { -+ return true; -+ } -+ -+ /** -+ * Return the rail's direction. -+ * Can be used to make the cart think the rail is a different shape, -+ * for example when making diamond junctions or switches. -+ * The cart parameter will often be null unless it it called from EntityMinecart. -+ * -+ * @param world The world. -+ * @param pos Block's position in world -+ * @param state The BlockState -+ * @param cart The cart asking for the metadata, null if it is not called by EntityMinecart. -+ * @return The direction. -+ */ -+ public EnumRailDirection getRailDirection(IBlockAccess world, BlockPos pos, IBlockState state, @javax.annotation.Nullable net.minecraft.entity.item.EntityMinecart cart) -+ { -+ return state.getValue(getShapeProperty()); -+ } -+ -+ /** -+ * Returns the max speed of the rail at the specified position. -+ * @param world The world. -+ * @param cart The cart on the rail, may be null. -+ * @param pos Block's position in world -+ * @return The max speed of the current rail. -+ */ -+ public float getRailMaxSpeed(World world, net.minecraft.entity.item.EntityMinecart cart, BlockPos pos) -+ { -+ return 0.4f; -+ } -+ -+ /** -+ * This function is called by any minecart that passes over this rail. -+ * It is called once per update tick that the minecart is on the rail. -+ * @param world The world. -+ * @param cart The cart on the rail. -+ * @param pos Block's position in world -+ */ -+ public void onMinecartPass(World world, net.minecraft.entity.item.EntityMinecart cart, BlockPos pos) -+ { -+ } -+ -+ /** -+ * Rotate the block. For vanilla blocks this rotates around the axis passed in (generally, it should be the "face" that was hit). -+ * Note: for mod blocks, this is up to the block and modder to decide. It is not mandated that it be a rotation around the -+ * face, but could be a rotation to orient *to* that face, or a visiting of possible rotations. -+ * The method should return true if the rotation was successful though. -+ * -+ * @param world The world -+ * @param pos Block position in world -+ * @param axis The axis to rotate around -+ * @return True if the rotation was successful, False if the rotation failed, or is not possible -+ */ -+ @Override -+ public boolean rotateBlock(World world, BlockPos pos, EnumFacing axis) -+ { -+ IBlockState state = world.getBlockState(pos); -+ for (IProperty prop : state.getProperties().keySet()) -+ { -+ if (prop.getName().equals("shape")) -+ { -+ world.setBlockState(pos, state.cycleProperty(prop)); -+ return true; -+ } -+ } -+ return false; -+ } -+ -+ /* ======================================== FORGE END =====================================*/ -+ - public static enum EnumRailDirection implements IStringSerializable - { - NORTH_SOUTH(0, "north_south"), -@@ -259,6 +350,7 @@ - private IBlockState state; - private final boolean isPowered; - private final List connectedRails = Lists.newArrayList(); -+ private final boolean canMakeSlopes; - - public Rail(World worldIn, BlockPos pos, IBlockState state) - { -@@ -266,8 +358,9 @@ - this.pos = pos; - this.state = state; - this.block = (BlockRailBase)state.getBlock(); -- BlockRailBase.EnumRailDirection blockrailbase$enumraildirection = state.getValue(this.block.getShapeProperty()); -- this.isPowered = this.block.isPowered; -+ BlockRailBase.EnumRailDirection blockrailbase$enumraildirection = block.getRailDirection(worldIn, pos, state, null); -+ this.isPowered = !this.block.isFlexibleRail(worldIn, pos); -+ this.canMakeSlopes = this.block.canMakeSlopes(worldIn, pos); - this.updateConnectedRails(blockrailbase$enumraildirection); - } - -@@ -461,7 +554,7 @@ - } - } - -- if (blockrailbase$enumraildirection == BlockRailBase.EnumRailDirection.NORTH_SOUTH) -+ if (blockrailbase$enumraildirection == BlockRailBase.EnumRailDirection.NORTH_SOUTH && canMakeSlopes) - { - if (BlockRailBase.isRailBlock(this.world, blockpos.up())) - { -@@ -474,7 +567,7 @@ - } - } - -- if (blockrailbase$enumraildirection == BlockRailBase.EnumRailDirection.EAST_WEST) -+ if (blockrailbase$enumraildirection == BlockRailBase.EnumRailDirection.EAST_WEST && canMakeSlopes) - { - if (BlockRailBase.isRailBlock(this.world, blockpos3.up())) - { -@@ -617,7 +710,7 @@ - } - } - -- if (blockrailbase$enumraildirection == BlockRailBase.EnumRailDirection.NORTH_SOUTH) -+ if (blockrailbase$enumraildirection == BlockRailBase.EnumRailDirection.NORTH_SOUTH && canMakeSlopes) - { - if (BlockRailBase.isRailBlock(this.world, blockpos.up())) - { -@@ -630,7 +723,7 @@ - } - } - -- if (blockrailbase$enumraildirection == BlockRailBase.EnumRailDirection.EAST_WEST) -+ if (blockrailbase$enumraildirection == BlockRailBase.EnumRailDirection.EAST_WEST && canMakeSlopes) - { - if (BlockRailBase.isRailBlock(this.world, blockpos3.up())) - { diff --git a/patches/minecraft/net/minecraft/block/BlockRailDetector.java.patch b/patches/minecraft/net/minecraft/block/BlockRailDetector.java.patch deleted file mode 100644 index 1872a724c..000000000 --- a/patches/minecraft/net/minecraft/block/BlockRailDetector.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/block/BlockRailDetector.java -+++ after/net/minecraft/block/BlockRailDetector.java -@@ -183,6 +183,8 @@ - { - if (blockState.getValue(POWERED)) - { -+ List carts = this.findMinecarts(worldIn, pos, EntityMinecart.class); -+ if (!carts.isEmpty() && carts.getFirst().getComparatorLevel() > -1) return carts.getFirst().getComparatorLevel(); - List list = this.findMinecarts(worldIn, pos, EntityMinecartCommandBlock.class); - - if (!list.isEmpty()) diff --git a/patches/minecraft/net/minecraft/block/BlockRailPowered.java.patch b/patches/minecraft/net/minecraft/block/BlockRailPowered.java.patch deleted file mode 100644 index 9ba041daa..000000000 --- a/patches/minecraft/net/minecraft/block/BlockRailPowered.java.patch +++ /dev/null @@ -1,30 +0,0 @@ ---- before/net/minecraft/block/BlockRailPowered.java -+++ after/net/minecraft/block/BlockRailPowered.java -@@ -29,10 +29,18 @@ - } - ); - public static final PropertyBool POWERED = PropertyBool.create("powered"); -+ -+ private final boolean isActivator; - - protected BlockRailPowered() - { -+ this(false); -+ } -+ -+ protected BlockRailPowered(boolean isActivator) -+ { - super(true); -+ this.isActivator = isActivator; - this.setDefaultState( - this.blockState.getBaseState().withProperty(SHAPE, BlockRailBase.EnumRailDirection.NORTH_SOUTH).withProperty(POWERED, false) - ); -@@ -149,7 +157,7 @@ - { - IBlockState iblockstate = worldIn.getBlockState(pos); - -- if (iblockstate.getBlock() != this) -+ if (!(iblockstate.getBlock() instanceof BlockRailPowered) || isActivator != ((BlockRailPowered)iblockstate.getBlock()).isActivator) - { - return false; - } diff --git a/patches/minecraft/net/minecraft/block/BlockRedstoneComparator.java.patch b/patches/minecraft/net/minecraft/block/BlockRedstoneComparator.java.patch deleted file mode 100644 index c942b3901..000000000 --- a/patches/minecraft/net/minecraft/block/BlockRedstoneComparator.java.patch +++ /dev/null @@ -1,24 +0,0 @@ ---- before/net/minecraft/block/BlockRedstoneComparator.java -+++ after/net/minecraft/block/BlockRedstoneComparator.java -@@ -385,6 +385,21 @@ - .withProperty(MODE, BlockRedstoneComparator.Mode.COMPARE); - } - -+ @Override -+ public void onNeighborChange(IBlockAccess world, BlockPos pos, BlockPos neighbor) -+ { -+ if (pos.getY() == neighbor.getY() && world instanceof World && !((World) world).isRemote) -+ { -+ neighborChanged(world.getBlockState(pos), (World)world, pos, world.getBlockState(neighbor).getBlock(), neighbor); -+ } -+ } -+ -+ @Override -+ public boolean getWeakChanges(IBlockAccess world, BlockPos pos) -+ { -+ return true; -+ } -+ - public static enum Mode implements IStringSerializable - { - COMPARE("compare"), diff --git a/patches/minecraft/net/minecraft/block/BlockRedstoneDiode.java.patch b/patches/minecraft/net/minecraft/block/BlockRedstoneDiode.java.patch deleted file mode 100644 index eba37388d..000000000 --- a/patches/minecraft/net/minecraft/block/BlockRedstoneDiode.java.patch +++ /dev/null @@ -1,54 +0,0 @@ ---- before/net/minecraft/block/BlockRedstoneDiode.java -+++ after/net/minecraft/block/BlockRedstoneDiode.java -@@ -42,12 +42,14 @@ - @Override - public boolean canPlaceBlockAt(World worldIn, BlockPos pos) - { -- return worldIn.getBlockState(pos.down()).isTopSolid() ? super.canPlaceBlockAt(worldIn, pos) : false; -+ IBlockState downState = worldIn.getBlockState(pos.down()); -+ return (downState.isTopSolid() || downState.getBlockFaceShape(worldIn, pos.down(), EnumFacing.UP) == BlockFaceShape.SOLID) && super.canPlaceBlockAt(worldIn, pos); - } - - public boolean canBlockStay(World worldIn, BlockPos pos) - { -- return worldIn.getBlockState(pos.down()).isTopSolid(); -+ IBlockState downState = worldIn.getBlockState(pos.down()); -+ return downState.isTopSolid() || downState.getBlockFaceShape(worldIn, pos.down(), EnumFacing.UP) == BlockFaceShape.SOLID; - } - - @Override -@@ -254,6 +256,8 @@ - { - EnumFacing enumfacing = state.getValue(FACING); - BlockPos blockpos = pos.offset(enumfacing.getOpposite()); -+ if(net.minecraftforge.event.ForgeEventFactory.onNeighborNotify(worldIn, pos, worldIn.getBlockState(pos), java.util.EnumSet.of(enumfacing.getOpposite()), false).isCanceled()) -+ return; - worldIn.neighborChanged(blockpos, this, pos); - worldIn.notifyNeighborsOfStateExcept(blockpos, this, enumfacing); - } -@@ -328,6 +332,25 @@ - public BlockRenderLayer getRenderLayer() - { - return BlockRenderLayer.CUTOUT; -+ } -+ -+ /* ======================================== FORGE START =====================================*/ -+ @Override -+ public boolean rotateBlock(World world, BlockPos pos, EnumFacing axis) -+ { -+ if (super.rotateBlock(world, pos, axis)) -+ { -+ IBlockState state = world.getBlockState(pos); -+ state = getUnpoweredState(state); -+ world.setBlockState(pos, state); -+ -+ if (shouldBePowered(world, pos, state)) -+ { -+ world.scheduleUpdate(pos, this, 1); -+ } -+ return true; -+ } -+ return false; - } - - @Override diff --git a/patches/minecraft/net/minecraft/block/BlockRedstoneOre.java.patch b/patches/minecraft/net/minecraft/block/BlockRedstoneOre.java.patch deleted file mode 100644 index 8eb7bdd6d..000000000 --- a/patches/minecraft/net/minecraft/block/BlockRedstoneOre.java.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- before/net/minecraft/block/BlockRedstoneOre.java -+++ after/net/minecraft/block/BlockRedstoneOre.java -@@ -111,12 +111,16 @@ - public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, IBlockState state, float chance, int fortune) - { - super.dropBlockAsItemWithChance(worldIn, pos, state, chance, fortune); -+ } - -- if (this.getItemDropped(state, worldIn.rand, fortune) != Item.getItemFromBlock(this)) -+ @Override -+ public int getExpDrop(IBlockState state, net.minecraft.world.IBlockAccess world, BlockPos pos, int fortune) -+ { -+ if (this.getItemDropped(state, RANDOM, fortune) != Item.getItemFromBlock(this)) - { -- int i = 1 + worldIn.rand.nextInt(5); -- this.dropXpOnBlockBreak(worldIn, pos, i); -+ return 1 + RANDOM.nextInt(5); - } -+ return 0; - } - - @SideOnly(Side.CLIENT) diff --git a/patches/minecraft/net/minecraft/block/BlockRedstoneTorch.java.patch b/patches/minecraft/net/minecraft/block/BlockRedstoneTorch.java.patch deleted file mode 100644 index 5777779f1..000000000 --- a/patches/minecraft/net/minecraft/block/BlockRedstoneTorch.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/block/BlockRedstoneTorch.java -+++ after/net/minecraft/block/BlockRedstoneTorch.java -@@ -21,7 +21,7 @@ - - public class BlockRedstoneTorch extends BlockTorch - { -- private static final Map> toggles = Maps.newHashMap(); -+ private static final Map> toggles = new java.util.WeakHashMap>(); // FORGE - fix vanilla MC-101233 - private final boolean isOn; - - private boolean isBurnedOut(World worldIn, BlockPos pos, boolean turnOff) diff --git a/patches/minecraft/net/minecraft/block/BlockRedstoneWire.java.patch b/patches/minecraft/net/minecraft/block/BlockRedstoneWire.java.patch deleted file mode 100644 index f81878f36..000000000 --- a/patches/minecraft/net/minecraft/block/BlockRedstoneWire.java.patch +++ /dev/null @@ -1,73 +0,0 @@ ---- before/net/minecraft/block/BlockRedstoneWire.java -+++ after/net/minecraft/block/BlockRedstoneWire.java -@@ -133,16 +133,17 @@ - BlockPos blockpos = pos.offset(direction); - IBlockState iblockstate = worldIn.getBlockState(pos.offset(direction)); - -- if (!canConnectTo(worldIn.getBlockState(blockpos), direction) -- && (iblockstate.isNormalCube() || !canConnectUpwardsTo(worldIn.getBlockState(blockpos.down())))) -+ if (!canConnectTo(worldIn.getBlockState(blockpos), direction, worldIn, blockpos) -+ && (iblockstate.isNormalCube() || !canConnectUpwardsTo(worldIn, blockpos.down()))) - { - IBlockState iblockstate1 = worldIn.getBlockState(pos.up()); - - if (!iblockstate1.isNormalCube()) - { -- boolean flag = worldIn.getBlockState(blockpos).isTopSolid() || worldIn.getBlockState(blockpos).getBlock() == Blocks.GLOWSTONE; -+ boolean flag = worldIn.getBlockState(blockpos).isSideSolid(worldIn, blockpos, EnumFacing.UP) -+ || worldIn.getBlockState(blockpos).getBlock() == Blocks.GLOWSTONE; - -- if (flag && canConnectUpwardsTo(worldIn.getBlockState(blockpos.up()))) -+ if (flag && canConnectUpwardsTo(worldIn, blockpos.up())) - { - if (iblockstate.isBlockNormalCube()) - { -@@ -183,7 +184,9 @@ - @Override - public boolean canPlaceBlockAt(World worldIn, BlockPos pos) - { -- return worldIn.getBlockState(pos.down()).isTopSolid() -+ IBlockState downState = worldIn.getBlockState(pos.down()); -+ return downState.isTopSolid() -+ || downState.getBlockFaceShape(worldIn, pos.down(), EnumFacing.UP) == BlockFaceShape.SOLID - || worldIn.getBlockState(pos.down()).getBlock() == Blocks.GLOWSTONE; - } - -@@ -456,7 +459,7 @@ - { - return true; - } -- else if (canConnectTo(iblockstate, side)) -+ else if (canConnectTo(iblockstate, side, worldIn, pos)) - { - return true; - } -@@ -470,15 +473,10 @@ - - protected static boolean canConnectUpwardsTo(IBlockAccess worldIn, BlockPos pos) - { -- return canConnectUpwardsTo(worldIn.getBlockState(pos)); -- } -- -- protected static boolean canConnectUpwardsTo(IBlockState state) -- { -- return canConnectTo(state, null); -- } -- -- protected static boolean canConnectTo(IBlockState blockState, @Nullable EnumFacing side) -+ return canConnectTo(worldIn.getBlockState(pos), null, worldIn, pos); -+ } -+ -+ protected static boolean canConnectTo(IBlockState blockState, @Nullable EnumFacing side, IBlockAccess world, BlockPos pos) - { - Block block = blockState.getBlock(); - -@@ -495,7 +493,7 @@ - { - return Blocks.OBSERVER == blockState.getBlock() - ? side == blockState.getValue(BlockObserver.FACING) -- : blockState.canProvidePower() && side != null; -+ : blockState.getBlock().canConnectRedstone(blockState, world, pos, side); - } - } - diff --git a/patches/minecraft/net/minecraft/block/BlockReed.java.patch b/patches/minecraft/net/minecraft/block/BlockReed.java.patch deleted file mode 100644 index 58797f201..000000000 --- a/patches/minecraft/net/minecraft/block/BlockReed.java.patch +++ /dev/null @@ -1,58 +0,0 @@ ---- before/net/minecraft/block/BlockReed.java -+++ after/net/minecraft/block/BlockReed.java -@@ -20,7 +20,7 @@ - import net.minecraftforge.fml.relauncher.Side; - import net.minecraftforge.fml.relauncher.SideOnly; - --public class BlockReed extends Block -+public class BlockReed extends Block implements net.minecraftforge.common.IPlantable - { - public static final PropertyInteger AGE = PropertyInteger.create("age", 0, 15); - protected static final AxisAlignedBB REED_AABB = new AxisAlignedBB(0.125, 0.0, 0.125, 0.875, 1.0, 0.875); -@@ -57,6 +57,8 @@ - { - int j = state.getValue(AGE); - -+ if(net.minecraftforge.common.ForgeHooks.onCropsGrowPre(worldIn, pos, state, true)) -+ { - if (j == 15) - { - worldIn.setBlockState(pos.up(), this.getDefaultState()); -@@ -66,6 +68,8 @@ - { - worldIn.setBlockState(pos, state.withProperty(AGE, j + 1), 4); - } -+ net.minecraftforge.common.ForgeHooks.onCropsGrowPost(worldIn, pos, state, worldIn.getBlockState(pos)); -+ } - } - } - } -@@ -74,7 +78,9 @@ - @Override - public boolean canPlaceBlockAt(World worldIn, BlockPos pos) - { -- Block block = worldIn.getBlockState(pos.down()).getBlock(); -+ IBlockState state = worldIn.getBlockState(pos.down()); -+ Block block = state.getBlock(); -+ if (block.canSustainPlant(state, worldIn, pos.down(), EnumFacing.UP, this)) return true; - - if (block == this) - { -@@ -175,6 +181,17 @@ - public int getMetaFromState(IBlockState state) - { - return state.getValue(AGE); -+ } -+ -+ @Override -+ public net.minecraftforge.common.EnumPlantType getPlantType(IBlockAccess world, BlockPos pos) -+ { -+ return net.minecraftforge.common.EnumPlantType.Beach; -+ } -+ @Override -+ public IBlockState getPlant(IBlockAccess world, BlockPos pos) -+ { -+ return this.getDefaultState(); - } - - @Override diff --git a/patches/minecraft/net/minecraft/block/BlockRotatedPillar.java.patch b/patches/minecraft/net/minecraft/block/BlockRotatedPillar.java.patch deleted file mode 100644 index 72881bfc2..000000000 --- a/patches/minecraft/net/minecraft/block/BlockRotatedPillar.java.patch +++ /dev/null @@ -1,24 +0,0 @@ ---- before/net/minecraft/block/BlockRotatedPillar.java -+++ after/net/minecraft/block/BlockRotatedPillar.java -@@ -28,6 +28,21 @@ - } - - @Override -+ public boolean rotateBlock(net.minecraft.world.World world, BlockPos pos, EnumFacing axis) -+ { -+ net.minecraft.block.state.IBlockState state = world.getBlockState(pos); -+ for (net.minecraft.block.properties.IProperty prop : state.getProperties().keySet()) -+ { -+ if (prop.getName().equals("axis")) -+ { -+ world.setBlockState(pos, state.cycleProperty(prop)); -+ return true; -+ } -+ } -+ return false; -+ } -+ -+ @Override - public IBlockState withRotation(IBlockState state, Rotation rot) - { - switch (rot) diff --git a/patches/minecraft/net/minecraft/block/BlockSapling.java.patch b/patches/minecraft/net/minecraft/block/BlockSapling.java.patch deleted file mode 100644 index 06619bf6b..000000000 --- a/patches/minecraft/net/minecraft/block/BlockSapling.java.patch +++ /dev/null @@ -1,18 +0,0 @@ ---- before/net/minecraft/block/BlockSapling.java -+++ after/net/minecraft/block/BlockSapling.java -@@ -55,6 +55,7 @@ - { - super.updateTick(worldIn, pos, state, rand); - -+ if (!worldIn.isAreaLoaded(pos, 1)) return; // Forge: prevent loading unloaded chunks when checking neighbor's light - if (worldIn.getLightFromNeighbors(pos.up()) >= 9 && rand.nextInt(7) == 0) - { - this.grow(worldIn, pos, state, rand); -@@ -76,6 +77,7 @@ - - public void generateTree(World worldIn, BlockPos pos, IBlockState state, Random rand) - { -+ if (!net.minecraftforge.event.terraingen.TerrainGen.saplingGrowTree(worldIn, rand, pos)) return; - WorldGenerator worldgenerator = (WorldGenerator)(rand.nextInt(10) == 0 ? new WorldGenBigTree(true) : new WorldGenTrees(true)); - int i = 0; - int j = 0; diff --git a/patches/minecraft/net/minecraft/block/BlockSkull.java.patch b/patches/minecraft/net/minecraft/block/BlockSkull.java.patch deleted file mode 100644 index 43ab28982..000000000 --- a/patches/minecraft/net/minecraft/block/BlockSkull.java.patch +++ /dev/null @@ -1,58 +0,0 @@ ---- before/net/minecraft/block/BlockSkull.java -+++ after/net/minecraft/block/BlockSkull.java -@@ -148,11 +148,6 @@ - } - - @Override -- public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, IBlockState state, float chance, int fortune) -- { -- } -- -- @Override - public void onBlockHarvested(World worldIn, BlockPos pos, IBlockState state, EntityPlayer player) - { - if (player.capabilities.isCreativeMode) -@@ -160,6 +155,7 @@ - state = state.withProperty(NODROP, true); - worldIn.setBlockState(pos, state, 4); - } -+ this.dropBlockAsItem(worldIn, pos, state, 0); - - super.onBlockHarvested(worldIn, pos, state, player); - } -@@ -167,7 +163,12 @@ - @Override - public void breakBlock(World worldIn, BlockPos pos, IBlockState state) - { -- if (!worldIn.isRemote) -+ super.breakBlock(worldIn, pos, state); -+ } -+ -+ @Override -+ public void getDrops(net.minecraft.util.NonNullList drops, IBlockAccess worldIn, BlockPos pos, IBlockState state, int fortune) -+ { - { - if (!state.getValue(NODROP)) - { -@@ -176,7 +177,7 @@ - if (tileentity instanceof TileEntitySkull) - { - TileEntitySkull tileentityskull = (TileEntitySkull)tileentity; -- ItemStack itemstack = this.getItem(worldIn, pos, state); -+ ItemStack itemstack = new ItemStack(Items.SKULL, 1, tileentityskull.getSkullType()); - - if (tileentityskull.getSkullType() == 3 && tileentityskull.getPlayerProfile() != null) - { -@@ -186,11 +187,9 @@ - itemstack.getTagCompound().setTag("SkullOwner", nbttagcompound); - } - -- spawnAsEntity(worldIn, pos, itemstack); -+ drops.add(itemstack); - } - } -- -- super.breakBlock(worldIn, pos, state); - } - } - diff --git a/patches/minecraft/net/minecraft/block/BlockSlab.java.patch b/patches/minecraft/net/minecraft/block/BlockSlab.java.patch deleted file mode 100644 index 786c553cf..000000000 --- a/patches/minecraft/net/minecraft/block/BlockSlab.java.patch +++ /dev/null @@ -1,39 +0,0 @@ ---- before/net/minecraft/block/BlockSlab.java -+++ after/net/minecraft/block/BlockSlab.java -@@ -88,6 +88,19 @@ - } - - @Override -+ public boolean doesSideBlockRendering(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing face) -+ { -+ if (net.minecraftforge.common.ForgeModContainer.disableStairSlabCulling) -+ return super.doesSideBlockRendering(state, world, pos, face); -+ -+ if ( state.isOpaqueCube() ) -+ return true; -+ -+ EnumBlockHalf side = state.getValue(HALF); -+ return (side == EnumBlockHalf.TOP && face == EnumFacing.UP) || (side == EnumBlockHalf.BOTTOM && face == EnumFacing.DOWN); -+ } -+ -+ @Override - public IBlockState getStateForPlacement( - World worldIn, - BlockPos pos, -@@ -138,7 +151,7 @@ - { - return false; - } -- else -+ else if (false) // Forge: Additional logic breaks doesSideBlockRendering and is no longer useful. - { - IBlockState iblockstate = blockAccess.getBlockState(pos.offset(side)); - boolean flag = isHalfSlab(iblockstate) && iblockstate.getValue(HALF) == BlockSlab.EnumBlockHalf.TOP; -@@ -168,6 +181,7 @@ - : !isHalfSlab(iblockstate) || flag; - } - } -+ return super.shouldSideBeRendered(blockState, blockAccess, pos, side); - } - - @SideOnly(Side.CLIENT) diff --git a/patches/minecraft/net/minecraft/block/BlockSnow.java.patch b/patches/minecraft/net/minecraft/block/BlockSnow.java.patch deleted file mode 100644 index 93f3714a5..000000000 --- a/patches/minecraft/net/minecraft/block/BlockSnow.java.patch +++ /dev/null @@ -1,60 +0,0 @@ ---- before/net/minecraft/block/BlockSnow.java -+++ after/net/minecraft/block/BlockSnow.java -@@ -111,7 +111,7 @@ - { - BlockFaceShape blockfaceshape = iblockstate.getBlockFaceShape(worldIn, pos.down(), EnumFacing.UP); - return blockfaceshape == BlockFaceShape.SOLID -- || iblockstate.getMaterial() == Material.LEAVES -+ || iblockstate.getBlock().isLeaves(iblockstate, worldIn, pos.down()) - || block == this && iblockstate.getValue(LAYERS) == 8; - } - else -@@ -130,7 +130,6 @@ - { - if (!this.canPlaceBlockAt(worldIn, pos)) - { -- this.dropBlockAsItem(worldIn, pos, state, 0); - worldIn.setBlockToAir(pos); - return false; - } -@@ -145,9 +144,8 @@ - World worldIn, EntityPlayer player, BlockPos pos, IBlockState state, @Nullable TileEntity te, ItemStack stack - ) - { -- spawnAsEntity(worldIn, pos, new ItemStack(Items.SNOWBALL, state.getValue(LAYERS) + 1, 0)); -+ super.harvestBlock(worldIn, player, pos, state, te, stack); - worldIn.setBlockToAir(pos); -- player.addStat(StatList.getBlockStats(this)); - } - - @Override -@@ -159,7 +157,7 @@ - @Override - public int quantityDropped(Random random) - { -- return 0; -+ return 1; - } - - @Override -@@ -167,7 +165,6 @@ - { - if (worldIn.getLightFor(EnumSkyBlock.BLOCK, pos) > 11) - { -- this.dropBlockAsItem(worldIn, pos, worldIn.getBlockState(pos), 0); - worldIn.setBlockToAir(pos); - } - } -@@ -205,6 +202,12 @@ - public int getMetaFromState(IBlockState state) - { - return state.getValue(LAYERS) - 1; -+ } -+ -+ @Override -+ public int quantityDropped(IBlockState state, int fortune, Random random) -+ { -+ return state.getValue(LAYERS) + 1; - } - - @Override diff --git a/patches/minecraft/net/minecraft/block/BlockStairs.java.patch b/patches/minecraft/net/minecraft/block/BlockStairs.java.patch deleted file mode 100644 index a3aab7800..000000000 --- a/patches/minecraft/net/minecraft/block/BlockStairs.java.patch +++ /dev/null @@ -1,32 +0,0 @@ ---- before/net/minecraft/block/BlockStairs.java -+++ after/net/minecraft/block/BlockStairs.java -@@ -556,6 +556,29 @@ - return new BlockStateContainer(this, FACING, HALF, SHAPE); - } - -+ @Override -+ public boolean doesSideBlockRendering(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing face) -+ { -+ if (net.minecraftforge.common.ForgeModContainer.disableStairSlabCulling) -+ return super.doesSideBlockRendering(state, world, pos, face); -+ -+ if ( state.isOpaqueCube() ) -+ return true; -+ -+ state = this.getActualState(state, world, pos); -+ -+ EnumHalf half = state.getValue(HALF); -+ EnumFacing side = state.getValue(FACING); -+ EnumShape shape = state.getValue(SHAPE); -+ if (face == EnumFacing.UP) return half == EnumHalf.TOP; -+ if (face == EnumFacing.DOWN) return half == EnumHalf.BOTTOM; -+ if (shape == EnumShape.OUTER_LEFT || shape == EnumShape.OUTER_RIGHT) return false; -+ if (face == side) return true; -+ if (shape == EnumShape.INNER_LEFT && face.rotateY() == side) return true; -+ if (shape == EnumShape.INNER_RIGHT && face.rotateYCCW() == side) return true; -+ return false; -+ } -+ - public static enum EnumHalf implements IStringSerializable - { - TOP("top"), diff --git a/patches/minecraft/net/minecraft/block/BlockStaticLiquid.java.patch b/patches/minecraft/net/minecraft/block/BlockStaticLiquid.java.patch deleted file mode 100644 index 2e8d5edf0..000000000 --- a/patches/minecraft/net/minecraft/block/BlockStaticLiquid.java.patch +++ /dev/null @@ -1,39 +0,0 @@ ---- before/net/minecraft/block/BlockStaticLiquid.java -+++ after/net/minecraft/block/BlockStaticLiquid.java -@@ -54,22 +54,22 @@ - { - blockpos = blockpos.add(rand.nextInt(3) - 1, 1, rand.nextInt(3) - 1); - -- if (blockpos.getY() >= 0 && blockpos.getY() < 256 && !worldIn.isBlockLoaded(blockpos)) -+ if (blockpos.getY() >= 0 && blockpos.getY() < worldIn.getHeight() && !worldIn.isBlockLoaded(blockpos)) - { - return; - } - -- Block block = worldIn.getBlockState(blockpos).getBlock(); -+ IBlockState block = worldIn.getBlockState(blockpos); - -- if (block.material == Material.AIR) -+ if (block.getBlock().isAir(block, worldIn, blockpos)) - { - if (this.isSurroundingBlockFlammable(worldIn, blockpos)) - { -- worldIn.setBlockState(blockpos, Blocks.FIRE.getDefaultState()); -+ worldIn.setBlockState(blockpos, net.minecraftforge.event.ForgeEventFactory.fireFluidPlaceBlockEvent(worldIn, blockpos, pos, Blocks.FIRE.getDefaultState())); - return; - } - } -- else if (block.material.blocksMovement()) -+ else if (block.getMaterial().blocksMovement()) - { - return; - } -@@ -88,7 +88,7 @@ - - if (worldIn.isAirBlock(blockpos1.up()) && this.getCanBlockBurn(worldIn, blockpos1)) - { -- worldIn.setBlockState(blockpos1.up(), Blocks.FIRE.getDefaultState()); -+ worldIn.setBlockState(blockpos1.up(), net.minecraftforge.event.ForgeEventFactory.fireFluidPlaceBlockEvent(worldIn, blockpos1.up(), pos, Blocks.FIRE.getDefaultState())); - } - } - } diff --git a/patches/minecraft/net/minecraft/block/BlockStem.java.patch b/patches/minecraft/net/minecraft/block/BlockStem.java.patch deleted file mode 100644 index e92f7e424..000000000 --- a/patches/minecraft/net/minecraft/block/BlockStem.java.patch +++ /dev/null @@ -1,72 +0,0 @@ ---- before/net/minecraft/block/BlockStem.java -+++ after/net/minecraft/block/BlockStem.java -@@ -78,18 +78,19 @@ - { - super.updateTick(worldIn, pos, state, rand); - -+ if (!worldIn.isAreaLoaded(pos, 1)) return; // Forge: prevent loading unloaded chunks when checking neighbor's light - if (worldIn.getLightFromNeighbors(pos.up()) >= 9) - { - float f = BlockCrops.getGrowthChance(this, worldIn, pos); - -- if (rand.nextInt((int)(25.0F / f) + 1) == 0) -+ if(net.minecraftforge.common.ForgeHooks.onCropsGrowPre(worldIn, pos, state, rand.nextInt((int)(25.0F / f) + 1) == 0)) - { - int i = state.getValue(AGE); - - if (i < 7) - { -- state = state.withProperty(AGE, i + 1); -- worldIn.setBlockState(pos, state, 2); -+ IBlockState newState = state.withProperty(AGE, i + 1); -+ worldIn.setBlockState(pos, newState, 2); - } - else - { -@@ -102,14 +103,18 @@ - } - - pos = pos.offset(EnumFacing.Plane.HORIZONTAL.random(rand)); -- Block block = worldIn.getBlockState(pos.down()).getBlock(); -+ IBlockState soil = worldIn.getBlockState(pos.down()); -+ Block block = soil.getBlock(); - -- if (worldIn.getBlockState(pos).getBlock().material == Material.AIR -- && (block == Blocks.FARMLAND || block == Blocks.DIRT || block == Blocks.GRASS)) -+ if (worldIn.isAirBlock(pos) -+ && (block.canSustainPlant(soil, worldIn, pos.down(), EnumFacing.UP, this) -+ || block == Blocks.DIRT -+ || block == Blocks.GRASS)) - { - worldIn.setBlockState(pos, this.crop.getDefaultState()); - } - } -+ net.minecraftforge.common.ForgeHooks.onCropsGrowPost(worldIn, pos, state, worldIn.getBlockState(pos)); - } - } - } -@@ -124,8 +129,11 @@ - public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, IBlockState state, float chance, int fortune) - { - super.dropBlockAsItemWithChance(worldIn, pos, state, chance, fortune); -+ } - -- if (!worldIn.isRemote) -+ @Override -+ public void getDrops(net.minecraft.util.NonNullList drops, IBlockAccess world, BlockPos pos, IBlockState state, int fortune) -+ { - { - Item item = this.getSeedItem(); - -@@ -135,9 +143,9 @@ - - for (int j = 0; j < 3; j++) - { -- if (worldIn.rand.nextInt(15) <= i) -+ if (RANDOM.nextInt(15) <= i) - { -- spawnAsEntity(worldIn, pos, new ItemStack(item)); -+ drops.add(new ItemStack(item)); - } - } - } diff --git a/patches/minecraft/net/minecraft/block/BlockTallGrass.java.patch b/patches/minecraft/net/minecraft/block/BlockTallGrass.java.patch deleted file mode 100644 index 9bb4ca673..000000000 --- a/patches/minecraft/net/minecraft/block/BlockTallGrass.java.patch +++ /dev/null @@ -1,55 +0,0 @@ ---- before/net/minecraft/block/BlockTallGrass.java -+++ after/net/minecraft/block/BlockTallGrass.java -@@ -21,7 +21,7 @@ - import net.minecraft.world.IBlockAccess; - import net.minecraft.world.World; - --public class BlockTallGrass extends BlockBush implements IGrowable -+public class BlockTallGrass extends BlockBush implements IGrowable, net.minecraftforge.common.IShearable - { - public static final PropertyEnum TYPE = PropertyEnum.create("type", BlockTallGrass.EnumType.class); - protected static final AxisAlignedBB TALL_GRASS_AABB = new AxisAlignedBB(0.099999994F, 0.0, 0.099999994F, 0.9F, 0.8F, 0.9F); -@@ -41,7 +41,7 @@ - @Override - public boolean canBlockStay(World worldIn, BlockPos pos, IBlockState state) - { -- return this.canSustainBush(worldIn.getBlockState(pos.down())); -+ return super.canBlockStay(worldIn, pos, state); - } - - @Override -@@ -53,7 +53,7 @@ - @Override - public Item getItemDropped(IBlockState state, Random rand, int fortune) - { -- return rand.nextInt(8) == 0 ? Items.WHEAT_SEEDS : Items.AIR; -+ return null; - } - - @Override -@@ -195,5 +195,25 @@ - META_LOOKUP[blocktallgrass$enumtype.getMeta()] = blocktallgrass$enumtype; - } - } -+ } -+ -+ @Override public boolean isShearable(ItemStack item, IBlockAccess world, BlockPos pos) -+ { -+ return true; -+ } -+ -+ @Override -+ public NonNullList onSheared(ItemStack item, IBlockAccess world, BlockPos pos, int fortune) -+ { -+ return NonNullList.withSize(1, new ItemStack(Blocks.TALLGRASS, 1, world.getBlockState(pos).getValue(TYPE).getMeta())); -+ } -+ -+ @Override -+ public void getDrops(NonNullList drops, IBlockAccess world, BlockPos pos, IBlockState state, int fortune) -+ { -+ if (RANDOM.nextInt(8) != 0) return; -+ ItemStack seed = net.minecraftforge.common.ForgeHooks.getGrassSeed(RANDOM, fortune); -+ if (!seed.isEmpty()) -+ drops.add(seed); - } - } diff --git a/patches/minecraft/net/minecraft/block/BlockTorch.java.patch b/patches/minecraft/net/minecraft/block/BlockTorch.java.patch deleted file mode 100644 index fd2c389c4..000000000 --- a/patches/minecraft/net/minecraft/block/BlockTorch.java.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- before/net/minecraft/block/BlockTorch.java -+++ after/net/minecraft/block/BlockTorch.java -@@ -85,18 +85,8 @@ - - private boolean canPlaceOn(World worldIn, BlockPos pos) - { -- Block block = worldIn.getBlockState(pos).getBlock(); -- boolean flag = block == Blocks.END_GATEWAY || block == Blocks.LIT_PUMPKIN; -- -- if (worldIn.getBlockState(pos).isTopSolid()) -- { -- return !flag; -- } -- else -- { -- boolean flag1 = block instanceof BlockFence || block == Blocks.GLASS || block == Blocks.COBBLESTONE_WALL || block == Blocks.STAINED_GLASS; -- return flag1 && !flag; -- } -+ IBlockState state = worldIn.getBlockState(pos); -+ return state.getBlock().canPlaceTorchOnTop(state, worldIn, pos); - } - - @Override diff --git a/patches/minecraft/net/minecraft/block/BlockTrapDoor.java.patch b/patches/minecraft/net/minecraft/block/BlockTrapDoor.java.patch deleted file mode 100644 index 00a9154e0..000000000 --- a/patches/minecraft/net/minecraft/block/BlockTrapDoor.java.patch +++ /dev/null @@ -1,21 +0,0 @@ ---- before/net/minecraft/block/BlockTrapDoor.java -+++ after/net/minecraft/block/BlockTrapDoor.java -@@ -298,6 +298,18 @@ - : BlockFaceShape.UNDEFINED; - } - -+ @Override -+ public boolean isLadder(IBlockState state, IBlockAccess world, BlockPos pos, EntityLivingBase entity) -+ { -+ if (state.getValue(OPEN)) -+ { -+ IBlockState down = world.getBlockState(pos.down()); -+ if (down.getBlock() == net.minecraft.init.Blocks.LADDER) -+ return down.getValue(BlockLadder.FACING) == state.getValue(FACING); -+ } -+ return false; -+ } -+ - public static enum DoorHalf implements IStringSerializable - { - TOP("top"), diff --git a/patches/minecraft/net/minecraft/block/BlockVine.java.patch b/patches/minecraft/net/minecraft/block/BlockVine.java.patch deleted file mode 100644 index 3dd7bfea2..000000000 --- a/patches/minecraft/net/minecraft/block/BlockVine.java.patch +++ /dev/null @@ -1,46 +0,0 @@ ---- before/net/minecraft/block/BlockVine.java -+++ after/net/minecraft/block/BlockVine.java -@@ -27,7 +27,7 @@ - import net.minecraftforge.fml.relauncher.Side; - import net.minecraftforge.fml.relauncher.SideOnly; - --public class BlockVine extends Block -+public class BlockVine extends Block implements net.minecraftforge.common.IShearable - { - public static final PropertyBool UP = PropertyBool.create("up"); - public static final PropertyBool NORTH = PropertyBool.create("north"); -@@ -212,7 +212,7 @@ - { - if (!worldIn.isRemote) - { -- if (worldIn.rand.nextInt(4) == 0) -+ if (worldIn.rand.nextInt(4) == 0 && worldIn.isAreaLoaded(pos, 4)) // Forge: check area to prevent loading unloaded chunks - { - int i = 4; - int j = 5; -@@ -322,7 +322,7 @@ - IBlockState iblockstate = worldIn.getBlockState(blockpos3); - Block block = iblockstate.getBlock(); - -- if (block.material == Material.AIR) -+ if (block.isAir(iblockstate, worldIn, blockpos3)) - { - EnumFacing enumfacing = enumfacing2.rotateY(); - EnumFacing enumfacing1 = enumfacing2.rotateYCCW(); -@@ -531,6 +531,16 @@ - - return i; - } -+ -+ /*************************FORGE START***********************************/ -+ @Override public boolean isLadder(IBlockState state, IBlockAccess world, BlockPos pos, EntityLivingBase entity){ return true; } -+ @Override public boolean isShearable(ItemStack item, IBlockAccess world, BlockPos pos){ return true; } -+ @Override -+ public java.util.List onSheared(ItemStack item, IBlockAccess world, BlockPos pos, int fortune) -+ { -+ return java.util.Arrays.asList(new ItemStack(this, 1)); -+ } -+ /*************************FORGE END***********************************/ - - @Override - public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face) diff --git a/patches/minecraft/net/minecraft/block/BlockWall.java.patch b/patches/minecraft/net/minecraft/block/BlockWall.java.patch deleted file mode 100644 index 6a0000a45..000000000 --- a/patches/minecraft/net/minecraft/block/BlockWall.java.patch +++ /dev/null @@ -1,41 +0,0 @@ ---- before/net/minecraft/block/BlockWall.java -+++ after/net/minecraft/block/BlockWall.java -@@ -228,10 +228,10 @@ - @Override - public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos) - { -- boolean flag = this.canConnectTo(worldIn, pos.north(), EnumFacing.SOUTH); -- boolean flag1 = this.canConnectTo(worldIn, pos.east(), EnumFacing.WEST); -- boolean flag2 = this.canConnectTo(worldIn, pos.south(), EnumFacing.NORTH); -- boolean flag3 = this.canConnectTo(worldIn, pos.west(), EnumFacing.EAST); -+ boolean flag = canWallConnectTo(worldIn, pos, EnumFacing.NORTH); -+ boolean flag1 = canWallConnectTo(worldIn, pos, EnumFacing.EAST); -+ boolean flag2 = canWallConnectTo(worldIn, pos, EnumFacing.SOUTH); -+ boolean flag3 = canWallConnectTo(worldIn, pos, EnumFacing.WEST); - boolean flag4 = flag && !flag1 && flag2 && !flag3 || !flag && flag1 && !flag2 && flag3; - return state.withProperty(UP, !flag4 || !worldIn.isAirBlock(pos.up())) - .withProperty(NORTH, flag) -@@ -251,6 +251,23 @@ - { - return face != EnumFacing.UP && face != EnumFacing.DOWN ? BlockFaceShape.MIDDLE_POLE_THICK : BlockFaceShape.CENTER_BIG; - } -+ -+ /* ======================================== FORGE START ======================================== */ -+ -+ @Override -+ public boolean canBeConnectedTo(IBlockAccess world, BlockPos pos, EnumFacing facing) -+ { -+ return canConnectTo(world, pos.offset(facing), facing.getOpposite()); -+ } -+ -+ private boolean canWallConnectTo(IBlockAccess world, BlockPos pos, EnumFacing facing) -+ { -+ BlockPos other = pos.offset(facing); -+ Block block = world.getBlockState(other).getBlock(); -+ return block.canBeConnectedTo(world, other, facing.getOpposite()) || canConnectTo(world, other, facing.getOpposite()); -+ } -+ -+ /* ======================================== FORGE END ======================================== */ - - public static enum EnumType implements IStringSerializable - { diff --git a/patches/minecraft/net/minecraft/block/BlockWeb.java.patch b/patches/minecraft/net/minecraft/block/BlockWeb.java.patch deleted file mode 100644 index f0f09aca8..000000000 --- a/patches/minecraft/net/minecraft/block/BlockWeb.java.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- before/net/minecraft/block/BlockWeb.java -+++ after/net/minecraft/block/BlockWeb.java -@@ -22,7 +22,7 @@ - import net.minecraftforge.fml.relauncher.Side; - import net.minecraftforge.fml.relauncher.SideOnly; - --public class BlockWeb extends Block -+public class BlockWeb extends Block implements net.minecraftforge.common.IShearable - { - public BlockWeb() - { -@@ -88,6 +88,17 @@ - { - super.harvestBlock(worldIn, player, pos, state, te, stack); - } -+ } -+ -+ @Override -+ public boolean isShearable(ItemStack item, IBlockAccess world, BlockPos pos) -+ { -+ return true; -+ } -+ -+ @Override -+ public java.util.List onSheared(ItemStack item, IBlockAccess world, BlockPos pos, int fortune) { -+ return com.google.common.collect.Lists.newArrayList(new ItemStack(Item.getItemFromBlock(this))); - } - - @Override diff --git a/patches/minecraft/net/minecraft/block/SoundType.java.patch b/patches/minecraft/net/minecraft/block/SoundType.java.patch deleted file mode 100644 index 0eb90e5e1..000000000 --- a/patches/minecraft/net/minecraft/block/SoundType.java.patch +++ /dev/null @@ -1,18 +0,0 @@ ---- before/net/minecraft/block/SoundType.java -+++ after/net/minecraft/block/SoundType.java -@@ -146,7 +146,6 @@ - return this.pitch; - } - -- @SideOnly(Side.CLIENT) - public SoundEvent getBreakSound() - { - return this.breakSound; -@@ -162,7 +161,6 @@ - return this.placeSound; - } - -- @SideOnly(Side.CLIENT) - public SoundEvent getHitSound() - { - return this.hitSound; diff --git a/patches/minecraft/net/minecraft/block/state/BlockPistonStructureHelper.java.patch b/patches/minecraft/net/minecraft/block/state/BlockPistonStructureHelper.java.patch deleted file mode 100644 index 14665ce4d..000000000 --- a/patches/minecraft/net/minecraft/block/state/BlockPistonStructureHelper.java.patch +++ /dev/null @@ -1,47 +0,0 @@ ---- before/net/minecraft/block/state/BlockPistonStructureHelper.java -+++ after/net/minecraft/block/state/BlockPistonStructureHelper.java -@@ -65,7 +65,7 @@ - { - BlockPos blockpos = this.toMove.get(i); - -- if (this.world.getBlockState(blockpos).getBlock() == Blocks.SLIME_BLOCK && !this.addBranchingBlocks(blockpos)) -+ if (this.world.getBlockState(blockpos).getBlock().isStickyBlock(this.world.getBlockState(blockpos)) && !this.addBranchingBlocks(blockpos)) - { - return false; - } -@@ -80,7 +80,7 @@ - IBlockState iblockstate = this.world.getBlockState(origin); - Block block = iblockstate.getBlock(); - -- if (iblockstate.getMaterial() == Material.AIR) -+ if (iblockstate.getBlock().isAir(iblockstate, this.world, origin)) - { - return true; - } -@@ -106,7 +106,7 @@ - } - else - { -- while (block == Blocks.SLIME_BLOCK) -+ while (block.isStickyBlock(iblockstate)) - { - BlockPos blockpos = origin.offset(this.moveDirection.getOpposite(), i); - iblockstate = this.world.getBlockState(blockpos); -@@ -148,7 +148,7 @@ - { - BlockPos blockpos2 = this.toMove.get(l); - -- if (this.world.getBlockState(blockpos2).getBlock() == Blocks.SLIME_BLOCK && !this.addBranchingBlocks(blockpos2)) -+ if (this.world.getBlockState(blockpos2).getBlock().isStickyBlock(this.world.getBlockState(blockpos2)) && !this.addBranchingBlocks(blockpos2)) - { - return false; - } -@@ -159,7 +159,7 @@ - - iblockstate = this.world.getBlockState(blockpos1); - -- if (iblockstate.getMaterial() == Material.AIR) -+ if (iblockstate.getBlock().isAir(iblockstate, this.world, blockpos1)) - { - return true; - } diff --git a/patches/minecraft/net/minecraft/block/state/BlockStateBase.java.patch b/patches/minecraft/net/minecraft/block/state/BlockStateBase.java.patch deleted file mode 100644 index f9b1b2b21..000000000 --- a/patches/minecraft/net/minecraft/block/state/BlockStateBase.java.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- before/net/minecraft/block/state/BlockStateBase.java -+++ after/net/minecraft/block/state/BlockStateBase.java -@@ -75,4 +75,10 @@ - - return stringbuilder.toString(); - } -+ -+ @Nullable -+ public com.google.common.collect.ImmutableTable, Comparable, IBlockState> getPropertyValueTable() -+ { -+ return null; -+ } - } diff --git a/patches/minecraft/net/minecraft/block/state/BlockStateContainer.java.patch b/patches/minecraft/net/minecraft/block/state/BlockStateContainer.java.patch deleted file mode 100644 index 1a053209c..000000000 --- a/patches/minecraft/net/minecraft/block/state/BlockStateContainer.java.patch +++ /dev/null @@ -1,140 +0,0 @@ ---- before/net/minecraft/block/state/BlockStateContainer.java -+++ after/net/minecraft/block/state/BlockStateContainer.java -@@ -57,6 +57,16 @@ - - public BlockStateContainer(Block blockIn, IProperty... properties) - { -+ this(blockIn, properties, null); -+ } -+ -+ protected StateImplementation createState(Block block, ImmutableMap, Comparable> properties, @Nullable ImmutableMap, java.util.Optional> unlistedProperties) -+ { -+ return new StateImplementation(block, properties); -+ } -+ -+ protected BlockStateContainer(Block blockIn, IProperty[] properties, ImmutableMap, java.util.Optional> unlistedProperties) -+ { - this.block = blockIn; - Map < String, IProperty> map = Maps.newHashMap(); - -@@ -73,9 +83,7 @@ - for (List < Comparable> list : Cartesian.cartesianProduct(this.getAllowedValues())) - { - Map < IProperty, Comparable> map1 = MapPopulator.createMap(this.properties.values(), list); -- BlockStateContainer.StateImplementation blockstatecontainer$stateimplementation = new BlockStateContainer.StateImplementation( -- blockIn, ImmutableMap.copyOf(map1) -- ); -+ BlockStateContainer.StateImplementation blockstatecontainer$stateimplementation = createState(blockIn, ImmutableMap.copyOf(map1), unlistedProperties); - map2.put(map1, blockstatecontainer$stateimplementation); - list1.add(blockstatecontainer$stateimplementation); - } -@@ -170,6 +178,13 @@ - this.block = blockIn; - this.properties = propertiesIn; - } -+ -+ protected StateImplementation(Block blockIn, ImmutableMap, Comparable> propertiesIn, ImmutableTable, Comparable, IBlockState> propertyValueTable) -+ { -+ this.block = blockIn; -+ this.properties = propertiesIn; -+ this.propertyValueTable = propertyValueTable; -+ } - - @Override - public Collection < IProperty> getPropertyKeys() -@@ -528,5 +543,94 @@ - { - return this.block.getBlockFaceShape(worldIn, this, pos, facing); - } -- } -+ -+ //Forge Start -+ @Override -+ public ImmutableTable, Comparable, IBlockState> getPropertyValueTable() -+ { -+ return propertyValueTable; -+ } -+ -+ @Override -+ public int getLightOpacity(IBlockAccess world, BlockPos pos) -+ { -+ return this.block.getLightOpacity(this, world, pos); -+ } -+ -+ @Override -+ public int getLightValue(IBlockAccess world, BlockPos pos) -+ { -+ return this.block.getLightValue(this, world, pos); -+ } -+ -+ @Override -+ public boolean isSideSolid(IBlockAccess world, BlockPos pos, EnumFacing side) -+ { -+ return this.block.isSideSolid(this, world, pos, side); -+ } -+ -+ @Override -+ public boolean doesSideBlockChestOpening(IBlockAccess world, BlockPos pos, EnumFacing side) -+ { -+ return this.block.doesSideBlockChestOpening(this, world, pos, side); -+ } -+ -+ @Override -+ public boolean doesSideBlockRendering(IBlockAccess world, BlockPos pos, EnumFacing side) -+ { -+ return this.block.doesSideBlockRendering(this, world, pos, side); -+ } -+ } -+ -+ /** -+ * Forge added class to make building things easier. -+ * Will return an instance of BlockStateContainer appropriate for -+ * the list of properties passed in. -+ * -+ * Example usage: -+ * -+ * protected BlockStateContainer createBlockState() -+ * { -+ * return (new BlockStateContainer.Builder(this)).add(FACING).add(SOME_UNLISTED).build(); -+ * } -+ * -+ */ -+ public static class Builder -+ { -+ private final Block block; -+ private final List> listed = Lists.newArrayList(); -+ private final List> unlisted = Lists.newArrayList(); -+ -+ public Builder(Block block) -+ { -+ this.block = block; -+ } -+ -+ public Builder add(IProperty... props) -+ { -+ for (IProperty prop : props) -+ this.listed.add(prop); -+ return this; -+ } -+ -+ public Builder add(net.minecraftforge.common.property.IUnlistedProperty... props) -+ { -+ for (net.minecraftforge.common.property.IUnlistedProperty prop : props) -+ this.unlisted.add(prop); -+ return this; -+ } -+ -+ public BlockStateContainer build() -+ { -+ IProperty[] listed = new IProperty[this.listed.size()]; -+ listed = this.listed.toArray(listed); -+ if (this.unlisted.size() == 0) -+ return new BlockStateContainer(this.block, listed); -+ -+ net.minecraftforge.common.property.IUnlistedProperty[] unlisted = new net.minecraftforge.common.property.IUnlistedProperty[this.unlisted.size()]; -+ unlisted = this.unlisted.toArray(unlisted); -+ -+ return new net.minecraftforge.common.property.ExtendedBlockState(this.block, listed, unlisted); -+ } -+ } - } diff --git a/patches/minecraft/net/minecraft/block/state/IBlockProperties.java.patch b/patches/minecraft/net/minecraft/block/state/IBlockProperties.java.patch deleted file mode 100644 index 4bb7f2268..000000000 --- a/patches/minecraft/net/minecraft/block/state/IBlockProperties.java.patch +++ /dev/null @@ -1,30 +0,0 @@ ---- before/net/minecraft/block/state/IBlockProperties.java -+++ after/net/minecraft/block/state/IBlockProperties.java -@@ -28,9 +28,13 @@ - - boolean canEntitySpawn(Entity entityIn); - -+ @Deprecated //Forge location aware version below - int getLightOpacity(); -+ int getLightOpacity(IBlockAccess world, BlockPos pos); - -+ @Deprecated //Forge location aware version below - int getLightValue(); -+ int getLightValue(IBlockAccess world, BlockPos pos); - - @SideOnly(Side.CLIENT) - boolean isTranslucent(); -@@ -97,7 +101,13 @@ - - RayTraceResult collisionRayTrace(World worldIn, BlockPos pos, Vec3d start, Vec3d end); - -+ @Deprecated // Forge: Use isSideSolid(IBlockAccess, BlockPos, EnumFacing.UP) instead - boolean isTopSolid(); -+ -+ //Forge added functions -+ boolean doesSideBlockRendering(IBlockAccess world, BlockPos pos, EnumFacing side); -+ boolean isSideSolid(IBlockAccess world, BlockPos pos, EnumFacing side); -+ boolean doesSideBlockChestOpening(IBlockAccess world, BlockPos pos, EnumFacing side); - - Vec3d getOffset(IBlockAccess access, BlockPos pos); - diff --git a/patches/minecraft/net/minecraft/client/ClientBrandRetriever.java.patch b/patches/minecraft/net/minecraft/client/ClientBrandRetriever.java.patch deleted file mode 100644 index 39aba1780..000000000 --- a/patches/minecraft/net/minecraft/client/ClientBrandRetriever.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- before/net/minecraft/client/ClientBrandRetriever.java -+++ after/net/minecraft/client/ClientBrandRetriever.java -@@ -8,6 +8,6 @@ - { - public static String getClientModName() - { -- return "vanilla"; -+ return net.minecraftforge.fml.common.FMLCommonHandler.instance().getModName(); - } - } diff --git a/patches/minecraft/net/minecraft/client/LoadingScreenRenderer.java.patch b/patches/minecraft/net/minecraft/client/LoadingScreenRenderer.java.patch deleted file mode 100644 index 1b407e18a..000000000 --- a/patches/minecraft/net/minecraft/client/LoadingScreenRenderer.java.patch +++ /dev/null @@ -1,26 +0,0 @@ ---- before/net/minecraft/client/LoadingScreenRenderer.java -+++ after/net/minecraft/client/LoadingScreenRenderer.java -@@ -143,6 +143,10 @@ - GlStateManager.clear(16640); - } - -+ try -+ { -+ if (!net.minecraftforge.fml.client.FMLClientHandler.instance().handleLoadingScreen(scaledresolution)) //FML Don't render while FML's pre-screen is rendering -+ { - Tessellator tessellator = Tessellator.getInstance(); - BufferBuilder bufferbuilder = tessellator.getBuffer(); - this.mc.getTextureManager().bindTexture(Gui.OPTIONS_BACKGROUND); -@@ -187,6 +191,12 @@ - this.mc - .fontRenderer - .drawStringWithShadow(this.message, (k - this.mc.fontRenderer.getStringWidth(this.message)) / 2, l / 2 - 4 + 8, 16777215); -+ } -+ } -+ catch (java.io.IOException e) -+ { -+ throw new RuntimeException(e); -+ } //FML End - this.framebuffer.unbindFramebuffer(); - - if (OpenGlHelper.isFramebufferEnabled()) diff --git a/patches/minecraft/net/minecraft/client/Minecraft.java.patch b/patches/minecraft/net/minecraft/client/Minecraft.java.patch deleted file mode 100644 index 96dc61961..000000000 --- a/patches/minecraft/net/minecraft/client/Minecraft.java.patch +++ /dev/null @@ -1,708 +0,0 @@ ---- before/net/minecraft/client/Minecraft.java -+++ after/net/minecraft/client/Minecraft.java -@@ -328,6 +328,7 @@ - public Minecraft(GameConfiguration gameConfig) - { - instance = this; -+ net.minecraftforge.client.ForgeHooksClient.invalidateLog4jThreadCache(); - this.gameDir = gameConfig.folderInfo.gameDir; - this.fileAssets = gameConfig.folderInfo.assetsDir; - this.fileResourcepacks = gameConfig.folderInfo.resourcePacksDir; -@@ -340,7 +341,6 @@ - this.sessionService = new YggdrasilAuthenticationService(this.proxy, UUID.randomUUID().toString()).createMinecraftSessionService(); - this.session = gameConfig.userInfo.session; - LOGGER.info("Setting user: {}", this.session.getUsername()); -- LOGGER.debug("(Session ID is {})", this.session.getSessionID()); - this.isDemo = gameConfig.gameInfo.isDemo; - this.displayWidth = gameConfig.displayInfo.width > 0 ? gameConfig.displayInfo.width : 1; - this.displayHeight = gameConfig.displayInfo.height > 0 ? gameConfig.displayInfo.height : 1; -@@ -460,10 +460,10 @@ - this.resourceManager = new SimpleReloadableResourceManager(this.metadataSerializer); - this.languageManager = new LanguageManager(this.metadataSerializer, this.gameSettings.language); - this.resourceManager.registerReloadListener(this.languageManager); -- this.refreshResources(); -+ net.minecraftforge.fml.client.FMLClientHandler.instance().beginMinecraftLoading(this, this.defaultResourcePacks, this.resourceManager, this.metadataSerializer); - this.renderEngine = new TextureManager(this.resourceManager); - this.resourceManager.registerReloadListener(this.renderEngine); -- this.drawSplashScreen(this.renderEngine); -+ net.minecraftforge.fml.client.SplashProgress.drawVanillaScreen(this.renderEngine); - this.skinManager = new SkinManager(this.renderEngine, new File(this.fileAssets, "skins"), this.sessionService); - this.saveLoader = new AnvilSaveConverter(new File(this.gameDir, "saves"), this.dataFixer); - this.soundHandler = new SoundHandler(this.resourceManager, this.gameSettings); -@@ -483,6 +483,8 @@ - this.resourceManager.registerReloadListener(new GrassColorReloadListener()); - this.resourceManager.registerReloadListener(new FoliageColorReloadListener()); - this.mouseHelper = new MouseHelper(); -+ net.minecraftforge.fml.common.ProgressManager.ProgressBar bar= net.minecraftforge.fml.common.ProgressManager.push("Rendering Setup", 5, true); -+ bar.step("GL Setup"); - this.checkGLError("Pre startup"); - GlStateManager.enableTexture2D(); - GlStateManager.shadeModel(7425); -@@ -496,19 +498,24 @@ - GlStateManager.loadIdentity(); - GlStateManager.matrixMode(5888); - this.checkGLError("Startup"); -+ bar.step("Loading Texture Map"); - this.textureMapBlocks = new TextureMap("textures"); - this.textureMapBlocks.setMipmapLevels(this.gameSettings.mipmapLevels); - this.renderEngine.loadTickableTexture(TextureMap.LOCATION_BLOCKS_TEXTURE, this.textureMapBlocks); - this.renderEngine.bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); - this.textureMapBlocks.setBlurMipmapDirect(false, this.gameSettings.mipmapLevels > 0); -+ bar.step("Loading Model Manager"); - this.modelManager = new ModelManager(this.textureMapBlocks); - this.resourceManager.registerReloadListener(this.modelManager); - this.blockColors = BlockColors.init(); - this.itemColors = ItemColors.init(this.blockColors); -+ bar.step("Loading Item Renderer"); - this.renderItem = new RenderItem(this.renderEngine, this.modelManager, this.itemColors); - this.renderManager = new RenderManager(this.renderEngine, this.renderItem); - this.itemRenderer = new ItemRenderer(this); - this.resourceManager.registerReloadListener(this.renderItem); -+ bar.step("Loading Entity Renderer"); -+ net.minecraftforge.fml.client.SplashProgress.pause(); - this.entityRenderer = new EntityRenderer(this, this.resourceManager); - this.resourceManager.registerReloadListener(this.entityRenderer); - this.blockRenderDispatcher = new BlockRendererDispatcher(this.modelManager.getBlockModelShapes(), this.blockColors); -@@ -519,23 +526,28 @@ - this.resourceManager.registerReloadListener(this.searchTreeManager); - GlStateManager.viewport(0, 0, this.displayWidth, this.displayHeight); - this.effectRenderer = new ParticleManager(this.world, this.renderEngine); -+ net.minecraftforge.fml.client.SplashProgress.resume(); -+ net.minecraftforge.fml.common.ProgressManager.pop(bar); -+ net.minecraftforge.fml.client.FMLClientHandler.instance().finishMinecraftLoading(); -+ net.minecraftforge.client.ForgeHooksClient.clearTaskbarProgress(); - this.checkGLError("Post startup"); -- this.ingameGUI = new GuiIngame(this); -+ this.ingameGUI = new net.minecraftforge.client.GuiIngameForge(this); - - if (this.serverName != null) - { -- this.displayGuiScreen(new GuiConnecting(new GuiMainMenu(), this, this.serverName, this.serverPort)); -+ net.minecraftforge.fml.client.FMLClientHandler.instance().connectToServerAtStartup(this.serverName, this.serverPort); - } - else - { - this.displayGuiScreen(new GuiMainMenu()); - } - -- this.renderEngine.deleteTexture(this.mojangLogo); -+ net.minecraftforge.fml.client.SplashProgress.clearVanillaResources(renderEngine, mojangLogo); - this.mojangLogo = null; - this.loadingScreen = new LoadingScreenRenderer(this); - this.debugRenderer = new DebugRenderer(this); - -+ net.minecraftforge.fml.client.FMLClientHandler.instance().onInitializationComplete(); - if (this.gameSettings.fullScreen && !this.fullscreen) - { - this.toggleFullscreen(); -@@ -600,34 +612,15 @@ - this.metadataSerializer.registerMetadataSectionType(new LanguageMetadataSectionSerializer(), LanguageMetadataSection.class); - } - -- private void createDisplay() throws LWJGLException -+ private void createDisplay() - { - Display.setResizable(true); -- Display.setTitle("Minecraft 1.12.2"); -- -- try -- { -- Display.create(new PixelFormat().withDepthBits(24)); -- } -- catch (LWJGLException lwjglexception) -- { -- LOGGER.error("Couldn't set pixel format", (Throwable)lwjglexception); -- -- try -- { -- Thread.sleep(1000L); -- } -- catch (InterruptedException interruptedexception) -- { -- } -- -- if (this.fullscreen) -- { -- this.updateDisplayMode(); -- } -- -- Display.create(); -- } -+ Display.setTitle("Cleanroom"); -+ -+ Display.create((new PixelFormat()).withDepthBits(24)); -+ net.minecraftforge.client.ForgeHooksClient.initializeWindowsInformation(); -+ net.minecraftforge.client.ForgeHooksClient.setWindowStyle(fullscreen); -+ net.minecraftforge.client.ForgeHooksClient.initializeTaskbarAPI(); - } - - private void setInitialDisplayMode() throws LWJGLException -@@ -710,6 +703,7 @@ - - private void startTimerHackThread() - { -+ if (!org.apache.commons.lang3.SystemUtils.IS_OS_WINDOWS) return; - Thread thread = new Thread("Timer hack thread") - { - @Override -@@ -728,6 +722,7 @@ - } - }; - thread.setDaemon(true); -+ thread.setPriority(Thread.MIN_PRIORITY); - thread.start(); - } - -@@ -743,21 +738,23 @@ - File file2 = new File(file1, "crash-" + new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss").format(new Date()) + "-client.txt"); - Bootstrap.printToSYSOUT(crashReportIn.getCompleteReport()); - -+ int retVal; - if (crashReportIn.getFile() != null) - { - Bootstrap.printToSYSOUT("#@!@# Game crashed! Crash report saved to: #@!@# " + crashReportIn.getFile()); -- System.exit(-1); -+ retVal = -1; - } - else if (crashReportIn.saveToFile(file2)) - { - Bootstrap.printToSYSOUT("#@!@# Game crashed! Crash report saved to: #@!@# " + file2.getAbsolutePath()); -- System.exit(-1); -+ retVal = -1; - } - else - { - Bootstrap.printToSYSOUT("#@?@# Game crashed! Crash report could not be saved. #@?@#"); -- System.exit(-2); -+ retVal = -2; - } -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().handleExit(retVal); - } - - public boolean isUnicode() -@@ -765,6 +762,7 @@ - return this.languageManager.isCurrentLocaleUnicode() || this.gameSettings.forceUnicodeFont; - } - -+ @Deprecated // Forge: Use selective refreshResources method in FMLClientHandler - public void refreshResources() - { - List list = Lists.newArrayList(this.defaultResourcePacks); -@@ -964,11 +962,6 @@ - - public void displayGuiScreen(@Nullable GuiScreen guiScreenIn) - { -- if (this.currentScreen != null) -- { -- this.currentScreen.onGuiClosed(); -- } -- - if (guiScreenIn == null && this.world == null) - { - guiScreenIn = new GuiMainMenu(); -@@ -978,6 +971,17 @@ - guiScreenIn = new GuiGameOver(null); - } - -+ GuiScreen old = this.currentScreen; -+ net.minecraftforge.client.event.GuiOpenEvent event = new net.minecraftforge.client.event.GuiOpenEvent(guiScreenIn); -+ -+ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event)) return; -+ -+ guiScreenIn = event.getGui(); -+ if (old != null && guiScreenIn != old) -+ { -+ old.onGuiClosed(); -+ } -+ - if (guiScreenIn instanceof GuiMainMenu || guiScreenIn instanceof GuiMultiplayer) - { - this.gameSettings.showDebugInfo = false; -@@ -1088,7 +1092,7 @@ - long i1 = System.nanoTime() - l; - this.checkGLError("Pre render"); - this.profiler.endStartSection("sound"); -- this.soundHandler.setListener(this.player, this.timer.renderPartialTicks); -+ this.soundHandler.setListener(this.getRenderViewEntity(), this.timer.renderPartialTicks); //Forge: MC-46445 Spectator mode particles and sounds computed from where you have been before - this.profiler.endSection(); - this.profiler.startSection("render"); - GlStateManager.pushMatrix(); -@@ -1100,11 +1104,13 @@ - - if (!this.skipRenderWorld) - { -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().onRenderTickStart(this.timer.renderPartialTicks); - this.profiler.endStartSection("gameRenderer"); - this.entityRenderer.updateCameraAndRender(this.isGamePaused ? this.renderPartialTicksPaused : this.timer.renderPartialTicks, i); - this.profiler.endStartSection("toasts"); - this.toastGui.drawToast(new ScaledResolution(this)); - this.profiler.endSection(); -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().onRenderTickEnd(this.timer.renderPartialTicks); - } - - this.profiler.endSection(); -@@ -1469,10 +1475,9 @@ - { - BlockPos blockpos = this.objectMouseOver.getBlockPos(); - -- if (this.world.getBlockState(blockpos).getMaterial() != Material.AIR -- && this.playerController.onPlayerDamageBlock(blockpos, this.objectMouseOver.sideHit)) -+ if (!this.world.isAirBlock(blockpos) && this.playerController.onPlayerDamageBlock(blockpos, this.objectMouseOver.sideHit)) - { -- this.effectRenderer.addBlockHitEffects(blockpos, this.objectMouseOver.sideHit); -+ this.effectRenderer.addBlockHitEffects(blockpos, this.objectMouseOver); - this.player.swingArm(EnumHand.MAIN_HAND); - } - } -@@ -1506,7 +1511,7 @@ - case BLOCK: - BlockPos blockpos = this.objectMouseOver.getBlockPos(); - -- if (this.world.getBlockState(blockpos).getMaterial() != Material.AIR) -+ if (!this.world.isAirBlock(blockpos)) - { - this.playerController.clickBlock(blockpos, this.objectMouseOver.sideHit); - break; -@@ -1520,6 +1525,7 @@ - } - - this.player.resetCooldown(); -+ net.minecraftforge.common.ForgeHooks.onEmptyLeftClick(this.player); - } - - this.player.swingArm(EnumHand.MAIN_HAND); -@@ -1594,6 +1600,7 @@ - } - } - -+ if (itemstack.isEmpty() && (this.objectMouseOver == null || this.objectMouseOver.typeOfHit == RayTraceResult.Type.MISS)) net.minecraftforge.common.ForgeHooks.onEmptyClick(this.player, enumhand); - if (!itemstack.isEmpty() && this.playerController.processRightClick(this.player, this.world, enumhand) == EnumActionResult.SUCCESS - ) - { -@@ -1607,6 +1614,10 @@ - - public void toggleFullscreen() - { -+ if (net.minecraftforge.common.ForgeEarlyConfig.WINDOW_BORDERLESS_REPLACES_FULLSCREEN) { -+ Display.toggleBorderless(); -+ return; -+ } - try - { - this.fullscreen = !this.fullscreen; -@@ -1655,6 +1666,11 @@ - } - - Display.setFullscreen(this.fullscreen); -+ if (!this.fullscreen && (Util.getOSType() == Util.EnumOS.WINDOWS)) //Forge: Fix MC-68754, Screen is not resizeable after exiting fullscreen due to LWJGL bug https://github.com/LWJGL/lwjgl/issues/142 which is fixed, but not in the version MC ships -+ { -+ Display.setResizable(false); -+ Display.setResizable(true); -+ } - Display.setVSyncEnabled(this.gameSettings.enableVsync); - this.updateDisplay(); - } -@@ -1701,6 +1717,8 @@ - this.rightClickDelayTimer--; - } - -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().onPreClientTick(); -+ - this.profiler.startSection("gui"); - - if (!this.isGamePaused) -@@ -1907,6 +1925,7 @@ - } - - this.profiler.endSection(); -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().onPostClientTick(); - this.systemTime = getSystemTime(); - } - -@@ -2012,6 +2031,7 @@ - } - } - } -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().fireKeyInput(); - } - - this.processKeyBinds(); -@@ -2260,6 +2280,8 @@ - { - while (Mouse.next()) - { -+ if (net.minecraftforge.client.ForgeHooksClient.postMouseEvent()) continue; -+ - int i = Mouse.getEventButton(); - KeyBinding.setKeyBindState(i - 100, Mouse.getEventButtonState()); - -@@ -2315,6 +2337,7 @@ - this.currentScreen.handleMouseInput(); - } - } -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().fireMouseInput(); - } - } - -@@ -2332,6 +2355,7 @@ - - public void launchIntegratedServer(String folderName, String worldName, @Nullable WorldSettings worldSettingsIn) - { -+ net.minecraftforge.fml.client.FMLClientHandler.instance().startIntegratedServer(folderName, worldName, worldSettingsIn); - this.loadWorld(null); - System.gc(); - ISaveHandler isavehandler = this.saveLoader.getSaveLoader(folderName, false); -@@ -2378,6 +2402,12 @@ - - while (!this.integratedServer.serverIsInRunLoop()) - { -+ if (!net.minecraftforge.fml.common.StartupQuery.check() || this.integratedServer.isServerStopped()) -+ { -+ loadWorld(null); -+ displayGuiScreen(null); -+ return; -+ } - String s = this.integratedServer.getUserMessage(); - - if (s != null) -@@ -2402,8 +2432,14 @@ - SocketAddress socketaddress = this.integratedServer.getNetworkSystem().addLocalEndpoint(); - NetworkManager networkmanager = NetworkManager.provideLocalClient(socketaddress); - networkmanager.setNetHandler(new NetHandlerLoginClient(networkmanager, this, null)); -- networkmanager.sendPacket(new C00Handshake(socketaddress.toString(), 0, EnumConnectionState.LOGIN)); -- networkmanager.sendPacket(new CPacketLoginStart(this.getSession().getProfile())); -+ networkmanager.sendPacket(new C00Handshake(socketaddress.toString(), 0, EnumConnectionState.LOGIN, true)); -+ com.mojang.authlib.GameProfile gameProfile = this.getSession().getProfile(); -+ if (!this.getSession().hasCachedProperties()) -+ { -+ gameProfile = sessionService.fillProfileProperties(gameProfile, true); //Forge: Fill profile properties upon game load. Fixes MC-52974. -+ this.getSession().setProperties(gameProfile.getProperties()); -+ } -+ networkmanager.sendPacket(new CPacketLoginStart(gameProfile)); - this.networkManager = networkmanager; - } - -@@ -2414,6 +2450,8 @@ - - public void loadWorld(@Nullable WorldClient worldClientIn, String loadingMessage) - { -+ if (world != null) net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.WorldEvent.Unload(world)); -+ - if (worldClientIn == null) - { - NetHandlerPlayClient nethandlerplayclient = this.getConnection(); -@@ -2426,6 +2464,18 @@ - if (this.integratedServer != null && this.integratedServer.isAnvilFileSet()) - { - this.integratedServer.initiateShutdown(); -+ if (loadingScreen != null && this.running) -+ { -+ this.loadingScreen.displayLoadingString(I18n.format("forge.client.shutdown.internal")); -+ } -+ while (!integratedServer.isServerStopped()) -+ { -+ try -+ { -+ Thread.sleep(10); -+ } -+ catch (InterruptedException ie) {} -+ } - } - - this.integratedServer = null; -@@ -2449,6 +2499,7 @@ - this.ingameGUI.resetPlayersOverlayFooterHeader(); - this.setServerData(null); - this.integratedServerIsRunning = false; -+ net.minecraftforge.fml.client.FMLClientHandler.instance().handleClientWorldClosing(this.world); - } - - this.soundHandler.stopSounds(); -@@ -2465,6 +2516,7 @@ - } - - TileEntityRendererDispatcher.instance.setWorld(worldClientIn); -+ net.minecraftforge.client.MinecraftForgeClient.clearRenderCache(); - - if (worldClientIn != null) - { -@@ -2526,6 +2578,7 @@ - this.player == null ? new RecipeBook() : this.player.getRecipeBook() - ); - this.player.getDataManager().setEntryValues(entityplayersp.getDataManager().getAll()); -+ this.player.updateSyncFields(entityplayersp); // Forge: fix MC-10657 - this.player.dimension = dimension; - this.renderViewEntity = this.player; - this.player.preparePlayerToSpawn(); -@@ -2573,159 +2626,8 @@ - { - if (this.objectMouseOver != null && this.objectMouseOver.typeOfHit != RayTraceResult.Type.MISS) - { -- boolean flag = this.player.capabilities.isCreativeMode; -- TileEntity tileentity = null; -- ItemStack itemstack; -- -- if (this.objectMouseOver.typeOfHit == RayTraceResult.Type.BLOCK) -- { -- BlockPos blockpos = this.objectMouseOver.getBlockPos(); -- IBlockState iblockstate = this.world.getBlockState(blockpos); -- Block block = iblockstate.getBlock(); -- -- if (iblockstate.getMaterial() == Material.AIR) -- { -- return; -- } -- -- itemstack = block.getItem(this.world, blockpos, iblockstate); -- -- if (itemstack.isEmpty()) -- { -- return; -- } -- -- if (flag && GuiScreen.isCtrlKeyDown() && block.hasTileEntity()) -- { -- tileentity = this.world.getTileEntity(blockpos); -- } -- } -- else -- { -- if (this.objectMouseOver.typeOfHit != RayTraceResult.Type.ENTITY || this.objectMouseOver.entityHit == null || !flag) -- { -- return; -- } -- -- if (this.objectMouseOver.entityHit instanceof EntityPainting) -- { -- itemstack = new ItemStack(Items.PAINTING); -- } -- else if (this.objectMouseOver.entityHit instanceof EntityLeashKnot) -- { -- itemstack = new ItemStack(Items.LEAD); -- } -- else if (this.objectMouseOver.entityHit instanceof EntityItemFrame) -- { -- EntityItemFrame entityitemframe = (EntityItemFrame)this.objectMouseOver.entityHit; -- ItemStack itemstack1 = entityitemframe.getDisplayedItem(); -- -- if (itemstack1.isEmpty()) -- { -- itemstack = new ItemStack(Items.ITEM_FRAME); -- } -- else -- { -- itemstack = itemstack1.copy(); -- } -- } -- else if (this.objectMouseOver.entityHit instanceof EntityMinecart) -- { -- EntityMinecart entityminecart = (EntityMinecart)this.objectMouseOver.entityHit; -- Item item; -- -- switch (entityminecart.getType()) -- { -- case FURNACE: -- item = Items.FURNACE_MINECART; -- break; -- case CHEST: -- item = Items.CHEST_MINECART; -- break; -- case TNT: -- item = Items.TNT_MINECART; -- break; -- case HOPPER: -- item = Items.HOPPER_MINECART; -- break; -- case COMMAND_BLOCK: -- item = Items.COMMAND_BLOCK_MINECART; -- break; -- default: -- item = Items.MINECART; -- } -- -- itemstack = new ItemStack(item); -- } -- else if (this.objectMouseOver.entityHit instanceof EntityBoat) -- { -- itemstack = new ItemStack(((EntityBoat)this.objectMouseOver.entityHit).getItemBoat()); -- } -- else if (this.objectMouseOver.entityHit instanceof EntityArmorStand) -- { -- itemstack = new ItemStack(Items.ARMOR_STAND); -- } -- else if (this.objectMouseOver.entityHit instanceof EntityEnderCrystal) -- { -- itemstack = new ItemStack(Items.END_CRYSTAL); -- } -- else -- { -- ResourceLocation resourcelocation = EntityList.getKey(this.objectMouseOver.entityHit); -- -- if (resourcelocation == null || !EntityList.ENTITY_EGGS.containsKey(resourcelocation)) -- { -- return; -- } -- -- itemstack = new ItemStack(Items.SPAWN_EGG); -- ItemMonsterPlacer.applyEntityIdToItemStack(itemstack, resourcelocation); -- } -- } -- -- if (itemstack.isEmpty()) -- { -- String s = ""; -- -- if (this.objectMouseOver.typeOfHit == RayTraceResult.Type.BLOCK) -- { -- s = Block.REGISTRY.getNameForObject(this.world.getBlockState(this.objectMouseOver.getBlockPos()).getBlock()).toString(); -- } -- else if (this.objectMouseOver.typeOfHit == RayTraceResult.Type.ENTITY) -- { -- s = EntityList.getKey(this.objectMouseOver.entityHit).toString(); -- } -- -- LOGGER.warn("Picking on: [{}] {} gave null item", this.objectMouseOver.typeOfHit, s); -- } -- else -- { -- InventoryPlayer inventoryplayer = this.player.inventory; -- -- if (tileentity != null) -- { -- this.storeTEInStack(itemstack, tileentity); -- } -- -- int i = inventoryplayer.getSlotFor(itemstack); -- -- if (flag) -- { -- inventoryplayer.setPickedItemStack(itemstack); -- this.playerController.sendSlotPacket(this.player.getHeldItem(EnumHand.MAIN_HAND), 36 + inventoryplayer.currentItem); -- } -- else if (i != -1) -- { -- if (InventoryPlayer.isHotbar(i)) -- { -- inventoryplayer.currentItem = i; -- } -- else -- { -- this.playerController.pickItem(i); -- } -- } -- } -+ net.minecraftforge.common.ForgeHooks.onPickBlock(this.objectMouseOver, this.player, this.world); -+ // We delete this code wholly instead of commenting it out, to make sure we detect changes in it between MC versions - } - } - -@@ -2773,7 +2675,14 @@ - { - public String call() - { -- return GlStateManager.glGetString(7937) + " GL version " + GlStateManager.glGetString(7938) + ", " + GlStateManager.glGetString(7936); -+ if (Minecraft.getMinecraft().isCallingFromMinecraftThread() && Display.isCreated()) -+ { -+ return GlStateManager.glGetString(7937) + " GL version " + GlStateManager.glGetString(7938) + ", " + GlStateManager.glGetString(7936); -+ } -+ else -+ { -+ return "No OpenGL context found in the current thread"; -+ } - } - }); - theCrash.getCategory().addDetail("GL Caps", new ICrashReportDetail() -@@ -2878,6 +2787,7 @@ - return instance; - } - -+ @Deprecated // Forge: Use selective scheduleResourceRefresh method in FMLClientHandler - public ListenableFuture scheduleResourcesRefresh() - { - return this.addScheduledTask(new Runnable() -@@ -3056,18 +2966,8 @@ - - public static int getGLMaximumTextureSize() - { -- for (int i = 16384; i > 0; i >>= 1) -- { -- GlStateManager.glTexImage2D(32868, 0, 6408, i, i, 0, 6408, 5121, null); -- int j = GlStateManager.glGetTexLevelParameteri(32868, 0, 4096); -- -- if (j != 0) -- { -- return i; -- } -- } -- -- return -1; -+ //Forge we redirect this to our code which caches the value before any splash screen stuff is done. -+ return net.minecraftforge.fml.client.SplashProgress.getMaxTextureSize(); - } - - @Override -@@ -3200,6 +3100,9 @@ - } - else if (this.player != null) - { -+ MusicTicker.MusicType type = this.world.provider.getMusicType(); -+ if (type != null) return type; -+ - if (this.player.world.provider instanceof WorldProviderHell) - { - return MusicTicker.MusicType.NETHER; -@@ -3231,11 +3134,11 @@ - { - if (Keyboard.getEventKeyState()) - { -- if (i == this.gameSettings.keyBindFullscreen.getKeyCode()) -+ if (this.gameSettings.keyBindFullscreen.isActiveAndMatches(i)) - { - this.toggleFullscreen(); - } -- else if (i == this.gameSettings.keyBindScreenshot.getKeyCode()) -+ else if (this.gameSettings.keyBindScreenshot.isActiveAndMatches(i)) - { - this.ingameGUI - .getChatGUI() -@@ -3253,6 +3156,7 @@ - } - } - } -+ else if (this.currentScreen instanceof GuiControls) ((GuiControls)this.currentScreen).buttonId = null; - } - } - } -@@ -3291,7 +3195,7 @@ - } - catch (Exception exception) - { -- return Futures.immediateFailedCheckedFuture(exception); -+ return Futures.immediateFailedFuture(exception); - } - } - else -@@ -3384,6 +3288,12 @@ - return this.blockColors; - } - -+ // FORGE -+ public ItemColors getItemColors() -+ { -+ return this.itemColors; -+ } -+ - public boolean isReducedDebug() - { - return this.player != null && this.player.hasReducedDebug() || this.gameSettings.reducedDebugInfo; -@@ -3397,5 +3307,10 @@ - public Tutorial getTutorial() - { - return this.tutorial; -+ } -+ -+ public SearchTreeManager getSearchTreeManager() -+ { -+ return this.searchTreeManager; - } - } diff --git a/patches/minecraft/net/minecraft/client/audio/SoundHandler.java.patch b/patches/minecraft/net/minecraft/client/audio/SoundHandler.java.patch deleted file mode 100644 index 7b556fdd8..000000000 --- a/patches/minecraft/net/minecraft/client/audio/SoundHandler.java.patch +++ /dev/null @@ -1,52 +0,0 @@ ---- before/net/minecraft/client/audio/SoundHandler.java -+++ after/net/minecraft/client/audio/SoundHandler.java -@@ -73,6 +73,7 @@ - { - this.soundRegistry.clearMap(); - -+ java.util.List> resources = new java.util.LinkedList<>(); - for (String s : resourceManager.getResourceDomains()) - { - try -@@ -85,7 +86,7 @@ - - for (Entry entry : map.entrySet()) - { -- this.loadSoundResource(new ResourceLocation(s, entry.getKey()), entry.getValue()); -+ resources.add(new net.minecraft.util.Tuple<>(new ResourceLocation(s, entry.getKey()), entry.getValue())); - } - } - catch (RuntimeException runtimeexception) -@@ -99,6 +100,20 @@ - } - } - -+ net.minecraftforge.fml.common.ProgressManager.ProgressBar resourcesBar = net.minecraftforge.fml.common.ProgressManager.push("Loading sounds", resources.size()); -+ resources.forEach(entry -> -+ { -+ resourcesBar.step(entry.getFirst().toString()); -+ try -+ { -+ this.loadSoundResource(entry.getFirst(), entry.getSecond()); -+ } -+ catch (RuntimeException e) -+ { -+ LOGGER.warn("Invalid sounds.json", e); -+ } -+ }); -+ net.minecraftforge.fml.common.ProgressManager.pop(resourcesBar); - for (ResourceLocation resourcelocation : this.soundRegistry.getKeys()) - { - SoundEventAccessor soundeventaccessor = this.soundRegistry.getObject(resourcelocation); -@@ -263,6 +278,11 @@ - public void setListener(EntityPlayer player, float p_147691_2_) - { - this.sndManager.setListener(player, p_147691_2_); -+ } -+ -+ public void setListener(net.minecraft.entity.Entity entity, float partialTicks) -+ { -+ this.sndManager.setListener(entity, partialTicks); - } - - public void pauseSounds() diff --git a/patches/minecraft/net/minecraft/client/audio/SoundManager.java.patch b/patches/minecraft/net/minecraft/client/audio/SoundManager.java.patch deleted file mode 100644 index db084e7f4..000000000 --- a/patches/minecraft/net/minecraft/client/audio/SoundManager.java.patch +++ /dev/null @@ -1,64 +0,0 @@ ---- before/net/minecraft/client/audio/SoundManager.java -+++ after/net/minecraft/client/audio/SoundManager.java -@@ -69,6 +69,7 @@ - { - SoundSystemConfig.addLibrary(LibraryLWJGLOpenAL.class); - SoundSystemConfig.setCodec("ogg", CodecJOrbis.class); -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.sound.SoundSetupEvent(this)); - } - catch (SoundSystemException soundsystemexception) - { -@@ -93,6 +94,7 @@ - - this.unloadSoundSystem(); - this.loadSoundSystem(); -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.sound.SoundLoadEvent(this)); - } - - private synchronized void loadSoundSystem() -@@ -202,6 +204,7 @@ - this.sndSystem.stop(s); - } - -+ this.pausedChannels.clear(); //Forge: MC-35856 Fixed paused sounds repeating when switching worlds - this.playingSounds.clear(); - this.delayedSounds.clear(); - this.tickableSounds.clear(); -@@ -334,6 +337,9 @@ - { - if (this.loaded) - { -+ p_sound = net.minecraftforge.client.ForgeHooksClient.playSound(this, p_sound); -+ if (p_sound == null) return; -+ - SoundEventAccessor soundeventaccessor = p_sound.createAccessor(this.sndHandler); - ResourceLocation resourcelocation = p_sound.getSoundLocation(); - -@@ -408,6 +414,7 @@ - p_sound.getAttenuationType().getTypeInt(), - f - ); -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.sound.PlayStreamingSourceEvent(this, p_sound, s)); - } - else - { -@@ -424,6 +431,7 @@ - p_sound.getAttenuationType().getTypeInt(), - f - ); -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.sound.PlaySoundSourceEvent(this, p_sound, s)); - } - - LOGGER.debug(LOG_MARKER, "Playing sound {} for event {} as channel {}", sound.getSoundLocation(), resourcelocation, s); -@@ -521,6 +529,11 @@ - } - - public void setListener(EntityPlayer player, float p_148615_2_) -+ { -+ setListener((net.minecraft.entity.Entity) player, p_148615_2_); -+ } -+ -+ public void setListener(net.minecraft.entity.Entity player, float p_148615_2_) - { - if (this.loaded && player != null) - { diff --git a/patches/minecraft/net/minecraft/client/entity/AbstractClientPlayer.java.patch b/patches/minecraft/net/minecraft/client/entity/AbstractClientPlayer.java.patch deleted file mode 100644 index 0cd04da4c..000000000 --- a/patches/minecraft/net/minecraft/client/entity/AbstractClientPlayer.java.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- before/net/minecraft/client/entity/AbstractClientPlayer.java -+++ after/net/minecraft/client/entity/AbstractClientPlayer.java -@@ -141,7 +141,7 @@ - f = 1.0F; - } - -- if (this.isHandActive() && this.getActiveItemStack().getItem() == Items.BOW) -+ if (this.isHandActive() && this.getActiveItemStack().getItem() instanceof net.minecraft.item.ItemBow) - { - int i = this.getItemInUseMaxCount(); - float f1 = i / 20.0F; -@@ -158,6 +158,6 @@ - f *= 1.0F - f1 * 0.15F; - } - -- return f; -+ return net.minecraftforge.client.ForgeHooksClient.getOffsetFOV(this, f); - } - } diff --git a/patches/minecraft/net/minecraft/client/entity/EntityOtherPlayerMP.java.patch b/patches/minecraft/net/minecraft/client/entity/EntityOtherPlayerMP.java.patch deleted file mode 100644 index 7c45d8559..000000000 --- a/patches/minecraft/net/minecraft/client/entity/EntityOtherPlayerMP.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- before/net/minecraft/client/entity/EntityOtherPlayerMP.java -+++ after/net/minecraft/client/entity/EntityOtherPlayerMP.java -@@ -45,6 +45,7 @@ - @Override - public boolean attackEntityFrom(DamageSource source, float amount) - { -+ net.minecraftforge.common.ForgeHooks.onPlayerAttack(this, source, amount); - return true; - } - diff --git a/patches/minecraft/net/minecraft/client/entity/EntityPlayerSP.java.patch b/patches/minecraft/net/minecraft/client/entity/EntityPlayerSP.java.patch deleted file mode 100644 index 128b14067..000000000 --- a/patches/minecraft/net/minecraft/client/entity/EntityPlayerSP.java.patch +++ /dev/null @@ -1,133 +0,0 @@ ---- before/net/minecraft/client/entity/EntityPlayerSP.java -+++ after/net/minecraft/client/entity/EntityPlayerSP.java -@@ -131,6 +131,7 @@ - @Override - public boolean attackEntityFrom(DamageSource source, float amount) - { -+ net.minecraftforge.common.ForgeHooks.onPlayerAttack(this, source, amount); - return false; - } - -@@ -474,6 +475,15 @@ - } - } - -+ private boolean isHeadspaceFree(BlockPos pos, int height) -+ { -+ for (int y = 0; y < height; y++) -+ { -+ if (!isOpenBlockSpace(pos.add(0, y, 0))) return false; -+ } -+ return true; -+ } -+ - @Override - protected boolean pushOutOfBlocks(double x, double y, double z) - { -@@ -487,30 +497,34 @@ - double d0 = x - blockpos.getX(); - double d1 = z - blockpos.getZ(); - -- if (!this.isOpenBlockSpace(blockpos)) -+ int entHeight = Math.max((int)Math.ceil(this.height), 1); -+ -+ boolean inTranslucentBlock = !this.isHeadspaceFree(blockpos, entHeight); -+ -+ if (inTranslucentBlock) - { - int i = -1; - double d2 = 9999.0; - -- if (this.isOpenBlockSpace(blockpos.west()) && d0 < d2) -+ if (this.isHeadspaceFree(blockpos.west(), entHeight) && d0 < d2) - { - d2 = d0; - i = 0; - } - -- if (this.isOpenBlockSpace(blockpos.east()) && 1.0 - d0 < d2) -+ if (this.isHeadspaceFree(blockpos.east(), entHeight) && 1.0D - d0 < d2) - { - d2 = 1.0 - d0; - i = 1; - } - -- if (this.isOpenBlockSpace(blockpos.north()) && d1 < d2) -+ if (this.isHeadspaceFree(blockpos.north(), entHeight) && d1 < d2) - { - d2 = d1; - i = 4; - } - -- if (this.isOpenBlockSpace(blockpos.south()) && 1.0 - d1 < d2) -+ if (this.isHeadspaceFree(blockpos.south(), entHeight) && 1.0D - d1 < d2) - { - d2 = 1.0 - d1; - i = 5; -@@ -545,7 +559,8 @@ - - private boolean isOpenBlockSpace(BlockPos pos) - { -- return !this.world.getBlockState(pos).isNormalCube() && !this.world.getBlockState(pos.up()).isNormalCube(); -+ IBlockState iblockstate = world.getBlockState(pos); -+ return !iblockstate.getBlock().isNormalCube(iblockstate, world, pos); - } - - @Override -@@ -596,8 +611,13 @@ - @Override - public void playSound(SoundEvent soundIn, float volume, float pitch) - { -- this.world -- .playSound(this.posX, this.posY, this.posZ, soundIn, this.getSoundCategory(), volume, pitch, false); -+ net.minecraftforge.event.entity.PlaySoundAtEntityEvent event = net.minecraftforge.event.ForgeEventFactory.onPlaySoundAtEntity(this, soundIn, this.getSoundCategory(), volume, pitch); -+ if (event.isCanceled() || event.getSound() == null) return; -+ soundIn = event.getSound(); -+ volume = event.getVolume(); -+ pitch = event.getPitch(); -+ -+ this.world.playSound(this.posX, this.posY, this.posZ, soundIn, event.getCategory(), volume, pitch, false); - } - - @Override -@@ -893,6 +913,7 @@ - float f = 0.8F; - boolean flag2 = this.movementInput.moveForward >= 0.8F; - this.movementInput.updatePlayerMoveState(); -+ net.minecraftforge.client.ForgeHooksClient.onInputUpdate(this, this.movementInput); - this.mc.getTutorial().handleMovement(this.movementInput); - - if (this.isHandActive() && !this.isRiding()) -@@ -912,10 +933,13 @@ - } - - AxisAlignedBB axisalignedbb = this.getEntityBoundingBox(); -+ net.minecraftforge.client.event.PlayerSPPushOutOfBlocksEvent event = new net.minecraftforge.client.event.PlayerSPPushOutOfBlocksEvent(this, axisalignedbb); -+ if(!net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event)) { axisalignedbb = event.getEntityBoundingBox(); - this.pushOutOfBlocks(this.posX - this.width * 0.35, axisalignedbb.minY + 0.5, this.posZ + this.width * 0.35); - this.pushOutOfBlocks(this.posX - this.width * 0.35, axisalignedbb.minY + 0.5, this.posZ - this.width * 0.35); - this.pushOutOfBlocks(this.posX + this.width * 0.35, axisalignedbb.minY + 0.5, this.posZ - this.width * 0.35); - this.pushOutOfBlocks(this.posX + this.width * 0.35, axisalignedbb.minY + 0.5, this.posZ + this.width * 0.35); -+ } - boolean flag4 = this.getFoodStats().getFoodLevel() > 6.0F || this.capabilities.allowFlying; - - if (this.onGround -@@ -1243,5 +1267,18 @@ - } - } - } -+ } -+ -+ public void updateSyncFields(EntityPlayerSP old) -+ { -+ this.lastReportedPosX = old.lastReportedPosX; -+ this.lastReportedPosY = old.lastReportedPosY; -+ this.lastReportedPosZ = old.lastReportedPosZ; -+ this.lastReportedYaw = old.lastReportedYaw; -+ this.lastReportedPitch = old.lastReportedPitch; -+ this.prevOnGround = old.prevOnGround; -+ this.serverSneakState = old.serverSneakState; -+ this.serverSprintState = old.serverSprintState; -+ this.positionUpdateTicks = old.positionUpdateTicks; - } - } diff --git a/patches/minecraft/net/minecraft/client/gui/FontRenderer.java.patch b/patches/minecraft/net/minecraft/client/gui/FontRenderer.java.patch deleted file mode 100644 index 93fcdda48..000000000 --- a/patches/minecraft/net/minecraft/client/gui/FontRenderer.java.patch +++ /dev/null @@ -1,257 +0,0 @@ ---- before/net/minecraft/client/gui/FontRenderer.java -+++ after/net/minecraft/client/gui/FontRenderer.java -@@ -56,7 +56,7 @@ - this.locationFontTexture = location; - this.renderEngine = textureManagerIn; - this.unicodeFlag = unicode; -- textureManagerIn.bindTexture(this.locationFontTexture); -+ bindTexture(this.locationFontTexture); - - for (int i = 0; i < 32; i++) - { -@@ -107,7 +107,7 @@ - - try - { -- iresource = Minecraft.getMinecraft().getResourceManager().getResource(this.locationFontTexture); -+ iresource = getResource(this.locationFontTexture); - bufferedimage = TextureUtil.readBufferedImage(iresource.getInputStream()); - } - catch (IOException ioexception) -@@ -171,7 +171,7 @@ - - try - { -- iresource = Minecraft.getMinecraft().getResourceManager().getResource(new ResourceLocation("font/glyph_sizes.bin")); -+ iresource = getResource(new ResourceLocation("font/glyph_sizes.bin")); - iresource.getInputStream().read(this.glyphWidth); - } - catch (IOException ioexception) -@@ -186,6 +186,7 @@ - - private float renderChar(char ch, boolean italic) - { -+ if (ch == 160) return 4.0F; // forge: display nbsp as space. MC-2595 - if (ch == ' ') - { - return 4.0F; -@@ -203,7 +204,7 @@ - int i = ch % 16 * 8; - int j = ch / 16 * 8; - int k = italic ? 1 : 0; -- this.renderEngine.bindTexture(this.locationFontTexture); -+ bindTexture(this.locationFontTexture); - int l = this.charWidth[ch]; - float f = l - 0.01F; - GlStateManager.glBegin(5); -@@ -231,7 +232,7 @@ - - private void loadGlyphTexture(int page) - { -- this.renderEngine.bindTexture(this.getUnicodePageLocation(page)); -+ bindTexture(this.getUnicodePageLocation(page)); - } - - protected float renderUnicodeChar(char ch, boolean italic) -@@ -280,7 +281,7 @@ - - public int drawString(String text, float x, float y, int color, boolean dropShadow) - { -- GlStateManager.enableAlpha(); -+ enableAlpha(); - this.resetStyles(); - int i; - -@@ -350,7 +351,7 @@ - - int j1 = this.colorCode[i1]; - this.textColor = j1; -- GlStateManager.color((j1 >> 16) / 255.0F, (j1 >> 8 & 0xFF) / 255.0F, (j1 & 0xFF) / 255.0F, this.alpha); -+ setColor((j1 >> 16) / 255.0F, (j1 >> 8 & 255) / 255.0F, (j1 & 255) / 255.0F, this.alpha); - } - else if (i1 == 16) - { -@@ -379,7 +380,7 @@ - this.strikethroughStyle = false; - this.underlineStyle = false; - this.italicStyle = false; -- GlStateManager.color(this.red, this.blue, this.green, this.alpha); -+ setColor(this.red, this.blue, this.green, this.alpha); - } - - i++; -@@ -409,7 +410,7 @@ - c0 = c1; - } - -- float f1 = this.unicodeFlag ? 0.5F : 1.0F; -+ float f1 = j == -1 || this.unicodeFlag ? 0.5f : 1f; - boolean flag = (c0 == 0 || j == -1 || this.unicodeFlag) && shadow; - - if (flag) -@@ -447,6 +448,15 @@ - - f++; - } -+ doDraw(f); -+ } -+ } -+ } -+ -+ protected void doDraw(float f) -+ { -+ { -+ { - - if (this.strikethroughStyle) - { -@@ -520,7 +530,7 @@ - this.blue = (color >> 8 & 0xFF) / 255.0F; - this.green = (color & 0xFF) / 255.0F; - this.alpha = (color >> 24 & 0xFF) / 255.0F; -- GlStateManager.color(this.red, this.blue, this.green, this.alpha); -+ setColor(this.red, this.blue, this.green, this.alpha); - this.posX = x; - this.posY = y; - this.renderStringAtPos(text, dropShadow); -@@ -574,6 +584,7 @@ - - public int getCharWidth(char character) - { -+ if (character == 160) return 4; // forge: display nbsp as space. MC-2595 - if (character == 167) - { - return -1; -@@ -672,7 +683,7 @@ - - private String trimStringNewline(String text) - { -- while (text != null && text.endsWith("\n")) -+ while (text.endsWith("\n")) - { - text = text.substring(0, text.length() - 1); - } -@@ -719,9 +730,87 @@ - - public List listFormattedStringToWidth(String str, int wrapWidth) - { -- return Arrays.asList(this.wrapFormattedStringToWidth(str, wrapWidth).split("\n")); -+ if (str.isEmpty()) -+ { -+ return java.util.Collections.singletonList(""); -+ } -+ com.ibm.icu.segmenter.Segments segments = com.cleanroommc.client.ICU4JInstances.SEGMENTER.segment(str); -+ List list = new java.util.ArrayList<>(); -+ StringBuilder line = new StringBuilder(); -+ StringBuilder current = new StringBuilder(); -+ StringBuilder format = new StringBuilder(); -+ StringBuilder segFormat = new StringBuilder(); -+ boolean bold = false; -+ int lineWidth = 0; -+ int segmentWidth; -+ out: -+ for (java.util.Iterator it = segments.segments().iterator(); it.hasNext(); ) { -+ com.ibm.icu.segmenter.Segment segment = it.next(); -+ segmentWidth = 0; -+ int size = segment.limit - segment.start; -+ CharSequence sequence = segment.getSubSequence(); -+ segFormat.setLength(0); -+ segFormat.append(format); -+ for (int i = 0; i < size; i++) { -+ char c = sequence.charAt(i); -+ switch (c) { -+ case '\n': -+ line.append(current); -+ current.setLength(0); -+ list.add(line.toString()); -+ line.setLength(0); -+ line.append(format); -+ lineWidth = 0; -+ continue out; -+ case '§': -+ if (++i < size) { -+ char next = sequence.charAt(i); -+ if (next == 'l' || next == 'L') { -+ bold = true; -+ } else if (next == 'r' || next == 'R') { -+ bold = false; -+ format.setLength(0); -+ } else if (isFormatColor(next)) { -+ bold = false; -+ } -+ format.append('§').append(next); -+ current.append('§').append(next); -+ continue; -+ } -+ default: -+ int cWidth = getCharWidth(c); -+ if (bold) cWidth++; -+ if (lineWidth + cWidth > wrapWidth) { -+ if (i >= current.length()) { -+ lineWidth = 0; -+ segmentWidth = 0; -+ line.append(current); -+ format.setLength(0); -+ format.append(segFormat); -+ current.setLength(0); -+ } else { -+ lineWidth = segmentWidth; -+ line.append(current, 0, current.length() - i); -+ current.delete(0, current.length() - i); -+ } -+ list.add(line.toString()); -+ line.setLength(0); -+ line.append(format); -+ } -+ current.append(c); -+ lineWidth += cWidth; -+ segmentWidth += cWidth; -+ } -+ } -+ } -+ line.append(current); -+ if (!line.isEmpty()) { -+ list.add(line.toString()); -+ } -+ return list; - } - -+ @Deprecated - String wrapFormattedStringToWidth(String str, int wrapWidth) - { - int i = this.sizeStringToWidth(str, wrapWidth); -@@ -740,6 +829,7 @@ - } - } - -+ @Deprecated - private int sizeStringToWidth(String str, int wrapWidth) - { - int i = str.length(); -@@ -838,6 +928,26 @@ - public boolean getBidiFlag() - { - return this.bidiFlag; -+ } -+ -+ protected void setColor(float r, float g, float b, float a) -+ { -+ GlStateManager.color(r,g,b,a); -+ } -+ -+ protected void enableAlpha() -+ { -+ GlStateManager.enableAlpha(); -+ } -+ -+ protected void bindTexture(ResourceLocation location) -+ { -+ renderEngine.bindTexture(location); -+ } -+ -+ protected IResource getResource(ResourceLocation location) throws IOException -+ { -+ return Minecraft.getMinecraft().getResourceManager().getResource(location); - } - - public int getColorCode(char character) diff --git a/patches/minecraft/net/minecraft/client/gui/GuiBossOverlay.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiBossOverlay.java.patch deleted file mode 100644 index 3f40256d8..000000000 --- a/patches/minecraft/net/minecraft/client/gui/GuiBossOverlay.java.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- before/net/minecraft/client/gui/GuiBossOverlay.java -+++ after/net/minecraft/client/gui/GuiBossOverlay.java -@@ -34,13 +34,18 @@ - for (BossInfoClient bossinfoclient : this.mapBossInfos.values()) - { - int k = i / 2 - 91; -+ net.minecraftforge.client.event.RenderGameOverlayEvent.BossInfo event = -+ net.minecraftforge.client.ForgeHooksClient.bossBarRenderPre(scaledresolution, bossinfoclient, k, j, 10 + this.client.fontRenderer.FONT_HEIGHT); -+ if (!event.isCanceled()) { - GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); - this.client.getTextureManager().bindTexture(GUI_BARS_TEXTURES); - this.render(k, j, bossinfoclient); - String s = bossinfoclient.getName().getFormattedText(); - this.client.fontRenderer.drawStringWithShadow(s, i / 2 - this.client.fontRenderer.getStringWidth(s) / 2, j - 9, 16777215); -- j += 10 + this.client.fontRenderer.FONT_HEIGHT; -+ } -+ j += event.getIncrement(); - -+ net.minecraftforge.client.ForgeHooksClient.bossBarRenderPost(scaledresolution); - if (j >= scaledresolution.getScaledHeight() / 3) - { - break; diff --git a/patches/minecraft/net/minecraft/client/gui/GuiButton.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiButton.java.patch deleted file mode 100644 index 380abc345..000000000 --- a/patches/minecraft/net/minecraft/client/gui/GuiButton.java.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- before/net/minecraft/client/gui/GuiButton.java -+++ after/net/minecraft/client/gui/GuiButton.java -@@ -22,6 +22,7 @@ - public boolean enabled = true; - public boolean visible = true; - protected boolean hovered; -+ public int packedFGColour; //FML - - public GuiButton(int buttonId, int x, int y, String buttonText) - { -@@ -86,6 +87,11 @@ - this.mouseDragged(mc, mouseX, mouseY); - int j = 14737632; - -+ if (packedFGColour != 0) -+ { -+ j = packedFGColour; -+ } -+ else - if (!this.enabled) - { - j = 10526880; diff --git a/patches/minecraft/net/minecraft/client/gui/GuiChat.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiChat.java.patch deleted file mode 100644 index 5bf18f9d3..000000000 --- a/patches/minecraft/net/minecraft/client/gui/GuiChat.java.patch +++ /dev/null @@ -1,190 +0,0 @@ ---- before/net/minecraft/client/gui/GuiChat.java -+++ after/net/minecraft/client/gui/GuiChat.java -@@ -26,6 +26,8 @@ - private TabCompleter tabCompleter; - protected GuiTextField inputField; - private String defaultInputFieldText = ""; -+ private com.cleanroommc.client.chat.suggestion.SuggestionList suggestionList; -+ private com.cleanroommc.client.chat.suggestion.SuggestionUpdater suggestionUpdater; - - public GuiChat() - { -@@ -48,6 +50,13 @@ - this.inputField.setText(this.defaultInputFieldText); - this.inputField.setCanLoseFocus(false); - this.tabCompleter = new GuiChat.ChatTabCompleter(this.inputField); -+ this.suggestionList = new com.cleanroommc.client.chat.suggestion.SuggestionList(this.inputField, false); -+ this.suggestionUpdater = new com.cleanroommc.client.chat.suggestion.SuggestionUpdater(this.suggestionList, this.tabCompleter, this.inputField, false); -+ this.inputField.setGuiResponder(this.suggestionUpdater); -+ if (this.defaultInputFieldText != null) -+ { -+ this.suggestionUpdater.setEntryValue(0, this.defaultInputFieldText); -+ } - } - - @Override -@@ -70,6 +79,15 @@ - - if (keyCode == 15) - { -+ if (this.suggestionList.isVisible()) -+ { -+ String selected = this.suggestionList.getSelected(); -+ if (selected == null) { -+ selected = this.suggestionList.getFirst(); -+ } -+ this.suggestionList.applySuggestion(this.inputField, selected); -+ return; -+ } - this.tabCompleter.complete(); - } - else -@@ -79,10 +97,22 @@ - - if (keyCode == 1) - { -+ // Cleanroom: first esc only dismisses the suggestion dropdown and leaves chat open -+ if (this.suggestionList.isVisible()) -+ { -+ this.suggestionList.hide(); -+ return; -+ } - this.mc.displayGuiScreen(null); - } - else if (keyCode == 28 || keyCode == 156) - { -+ String selected = this.suggestionList.getSelected(); -+ if (selected != null) -+ { -+ this.suggestionList.applySuggestion(this.inputField, selected); -+ return; -+ } - String s = this.inputField.getText().trim(); - - if (!s.isEmpty()) -@@ -94,10 +124,21 @@ - } - else if (keyCode == 200) - { -+ if (this.suggestionList.isVisible()) -+ { -+ // Cleanroom: list grows upward, so Up moves to the next (visually higher) suggestion -+ this.suggestionList.selectNext(); -+ return; -+ } - this.getSentHistory(-1); - } - else if (keyCode == 208) - { -+ if (this.suggestionList.isVisible()) -+ { -+ this.suggestionList.selectPrev(); -+ return; -+ } - this.getSentHistory(1); - } - else if (keyCode == 201) -@@ -111,6 +152,8 @@ - else - { - this.inputField.textboxKeyTyped(typedChar, keyCode); -+ // Cleanroom: cursor-move keys change the cursor without firing the GuiResponder - refresh here -+ this.suggestionUpdater.refresh(); - } - } - -@@ -132,6 +175,13 @@ - i = -1; - } - -+ int mouseX = Mouse.getEventX() * this.width / this.mc.displayWidth; -+ int mouseY = this.height - Mouse.getEventY() * this.height / this.mc.displayHeight - 1; -+ if (this.suggestionList.isMouseOver(mouseX, mouseY)) -+ { -+ this.suggestionList.scroll(i); -+ return; -+ } - if (!isShiftKeyDown()) - { - i *= 7; -@@ -146,6 +196,12 @@ - { - if (mouseButton == 0) - { -+ String clicked = this.suggestionList.mouseClicked(mouseX, mouseY); -+ if (clicked != null) -+ { -+ this.suggestionList.applySuggestion(this.inputField, clicked); -+ return; -+ } - ITextComponent itextcomponent = this.mc.ingameGUI.getChatGUI().getChatComponent(Mouse.getX(), Mouse.getY()); - - if (itextcomponent != null && this.handleComponentClick(itextcomponent)) -@@ -155,6 +211,8 @@ - } - - this.inputField.mouseClicked(mouseX, mouseY, mouseButton); -+ // Cleanroom: click repositions the cursor without firing the GuiResponder - refresh to follow it -+ this.suggestionUpdater.refresh(); - super.mouseClicked(mouseX, mouseY, mouseButton); - } - -@@ -201,7 +259,9 @@ - public void drawScreen(int mouseX, int mouseY, float partialTicks) - { - drawRect(2, this.height - 14, this.width - 2, this.height - 2, Integer.MIN_VALUE); -+ this.suggestionList.drawGhostText(this.inputField, this.fontRenderer); - this.inputField.drawTextBox(); -+ this.suggestionList.drawCommandColor(this.inputField, this.fontRenderer); - ITextComponent itextcomponent = this.mc.ingameGUI.getChatGUI().getChatComponent(Mouse.getX(), Mouse.getY()); - - if (itextcomponent != null && itextcomponent.getStyle().getHoverEvent() != null) -@@ -209,6 +269,7 @@ - this.handleComponentHover(itextcomponent, mouseX, mouseY); - } - -+ this.suggestionList.render(mouseX, mouseY); - super.drawScreen(mouseX, mouseY, partialTicks); - } - -@@ -222,6 +283,10 @@ - public void setCompletions(String... newCompletions) - { - this.tabCompleter.setCompletions(newCompletions); -+ // Cleanroom: one reply consumes the Tab request, or every auto-suggest reply would keep mutating the field -+ this.tabCompleter.resetRequested(); -+ // Cleanroom: route through the updater so stale async replies can be validated against the current prefix -+ this.suggestionUpdater.onServerCompletions(newCompletions); - } - - @SideOnly(Side.CLIENT) -@@ -232,29 +297,6 @@ - public ChatTabCompleter(GuiTextField p_i46749_1_) - { - super(p_i46749_1_, false); -- } -- -- @Override -- public void complete() -- { -- super.complete(); -- -- if (this.completions.size() > 1) -- { -- StringBuilder stringbuilder = new StringBuilder(); -- -- for (String s : this.completions) -- { -- if (stringbuilder.length() > 0) -- { -- stringbuilder.append(", "); -- } -- -- stringbuilder.append(s); -- } -- -- this.client.ingameGUI.getChatGUI().printChatMessageWithOptionalDeletion(new TextComponentString(stringbuilder.toString()), 1); -- } - } - - @Nullable diff --git a/patches/minecraft/net/minecraft/client/gui/GuiCommandBlock.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiCommandBlock.java.patch deleted file mode 100644 index 92aa5ae88..000000000 --- a/patches/minecraft/net/minecraft/client/gui/GuiCommandBlock.java.patch +++ /dev/null @@ -1,166 +0,0 @@ ---- before/net/minecraft/client/gui/GuiCommandBlock.java -+++ after/net/minecraft/client/gui/GuiCommandBlock.java -@@ -19,6 +19,8 @@ - public class GuiCommandBlock extends GuiScreen implements ITabCompleter - { - private GuiTextField commandTextField; -+ private com.cleanroommc.client.chat.suggestion.SuggestionList suggestionList; -+ private com.cleanroommc.client.chat.suggestion.SuggestionUpdater suggestionUpdater; - private GuiTextField previousOutputTextField; - private final TileEntityCommandBlock commandBlock; - private GuiButton doneBtn; -@@ -85,6 +87,10 @@ - return commandblockbaselogic.getPosition(); - } - }; -+ // Cleanroom: dropdown completion -+ this.suggestionList = new com.cleanroommc.client.chat.suggestion.SuggestionList(this.commandTextField, true); -+ this.suggestionUpdater = new com.cleanroommc.client.chat.suggestion.SuggestionUpdater(this.suggestionList, this.tabCompleter, this.commandTextField, true); -+ this.commandTextField.setGuiResponder(this.suggestionUpdater); - } - - public void updateGui() -@@ -172,6 +178,17 @@ - - if (keyCode == 15) - { -+ // Cleanroom: Tab applies the selected/first suggestion while the dropdown is open -+ if (this.suggestionList.isVisible()) -+ { -+ String selected = this.suggestionList.getSelected(); -+ if (selected == null) -+ { -+ selected = this.suggestionList.getFirst(); -+ } -+ this.suggestionList.applySuggestion(this.commandTextField, selected); -+ return; -+ } - this.tabCompleter.complete(); - } - else -@@ -179,25 +196,90 @@ - this.tabCompleter.resetDidComplete(); - } - -+ // Cleanroom: reroute navigation/confirm keys to the dropdown while it is visible -+ if (keyCode == 1) -+ { -+ if (this.suggestionList.isVisible()) -+ { -+ this.suggestionList.hide(); -+ return; -+ } -+ this.actionPerformed(this.cancelBtn); -+ return; -+ } -+ else if (keyCode == 28 || keyCode == 156) -+ { -+ String selected = this.suggestionList.getSelected(); -+ if (selected != null) -+ { -+ this.suggestionList.applySuggestion(this.commandTextField, selected); -+ return; -+ } -+ this.actionPerformed(this.doneBtn); -+ return; -+ } -+ else if (keyCode == 200) -+ { -+ if (this.suggestionList.isVisible()) -+ { -+ // Cleanroom: list grows upward, so Up moves to the next (visually higher) suggestion -+ this.suggestionList.selectNext(); -+ return; -+ } -+ } -+ else if (keyCode == 208) -+ { -+ if (this.suggestionList.isVisible()) -+ { -+ this.suggestionList.selectPrev(); -+ return; -+ } -+ } -+ - this.commandTextField.textboxKeyTyped(typedChar, keyCode); - this.previousOutputTextField.textboxKeyTyped(typedChar, keyCode); -+ // Cleanroom: cursor-move keys change the cursor without firing the GuiResponder - refresh here -+ this.suggestionUpdater.refresh(); -+ } - -- if (keyCode == 28 || keyCode == 156) -- { -- this.actionPerformed(this.doneBtn); -- } -- else if (keyCode == 1) -- { -- this.actionPerformed(this.cancelBtn); -+ @Override -+ public void handleMouseInput() throws IOException -+ { -+ super.handleMouseInput(); -+ // Cleanroom: scroll the suggestion dropdown with the mouse wheel while hovering it -+ if (this.suggestionList.isVisible()) -+ { -+ int wheel = org.lwjgl.input.Mouse.getEventDWheel(); -+ if (wheel != 0) -+ { -+ int mouseX = org.lwjgl.input.Mouse.getEventX() * this.width / this.mc.displayWidth; -+ int mouseY = this.height - org.lwjgl.input.Mouse.getEventY() * this.height / this.mc.displayHeight - 1; -+ if (this.suggestionList.isMouseOver(mouseX, mouseY)) -+ { -+ this.suggestionList.scroll(wheel); -+ } -+ } - } - } - - @Override - protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException - { -+ if (mouseButton == 0) -+ { -+ // Cleanroom: clicking a suggestion applies it -+ String clicked = this.suggestionList.mouseClicked(mouseX, mouseY); -+ if (clicked != null) -+ { -+ this.suggestionList.applySuggestion(this.commandTextField, clicked); -+ return; -+ } -+ } - super.mouseClicked(mouseX, mouseY, mouseButton); - this.commandTextField.mouseClicked(mouseX, mouseY, mouseButton); - this.previousOutputTextField.mouseClicked(mouseX, mouseY, mouseButton); -+ // Cleanroom: click repositions the cursor without firing the GuiResponder - refresh to follow it -+ this.suggestionUpdater.refresh(); - } - - @Override -@@ -206,7 +288,9 @@ - this.drawDefaultBackground(); - this.drawCenteredString(this.fontRenderer, I18n.format("advMode.setCommand"), this.width / 2, 20, 16777215); - this.drawString(this.fontRenderer, I18n.format("advMode.command"), this.width / 2 - 150, 40, 10526880); -+ this.suggestionList.drawGhostText(this.commandTextField, this.fontRenderer); - this.commandTextField.drawTextBox(); -+ this.suggestionList.drawCommandColor(this.commandTextField, this.fontRenderer); - int i = 75; - int j = 0; - this.drawString( -@@ -232,6 +316,7 @@ - this.previousOutputTextField.drawTextBox(); - } - -+ this.suggestionList.render(mouseX, mouseY); - super.drawScreen(mouseX, mouseY, partialTicks); - } - -@@ -313,5 +398,9 @@ - public void setCompletions(String... newCompletions) - { - this.tabCompleter.setCompletions(newCompletions); -+ // Cleanroom: one reply consumes the Tab request, or every auto-suggest reply would keep mutating the field -+ this.tabCompleter.resetRequested(); -+ // Cleanroom: route through the updater so stale async replies can be validated against the current prefix -+ this.suggestionUpdater.onServerCompletions(newCompletions); - } - } diff --git a/patches/minecraft/net/minecraft/client/gui/GuiControls.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiControls.java.patch deleted file mode 100644 index 453568aa6..000000000 --- a/patches/minecraft/net/minecraft/client/gui/GuiControls.java.patch +++ /dev/null @@ -1,50 +0,0 @@ ---- before/net/minecraft/client/gui/GuiControls.java -+++ after/net/minecraft/client/gui/GuiControls.java -@@ -87,7 +87,7 @@ - { - for (KeyBinding keybinding : this.mc.gameSettings.keyBindings) - { -- keybinding.setKeyCode(keybinding.getKeyCodeDefault()); -+ keybinding.setToDefault(); - } - - KeyBinding.resetKeyBindingArrayAndHash(); -@@ -104,6 +104,7 @@ - { - if (this.buttonId != null) - { -+ this.buttonId.setKeyModifierAndCode(net.minecraftforge.client.settings.KeyModifier.getActiveModifier(), -100 + mouseButton); - this.options.setOptionKeyBinding(this.buttonId, -100 + mouseButton); - this.buttonId = null; - KeyBinding.resetKeyBindingArrayAndHash(); -@@ -130,17 +131,21 @@ - { - if (keyCode == 1) - { -+ this.buttonId.setKeyModifierAndCode(net.minecraftforge.client.settings.KeyModifier.NONE, 0); - this.options.setOptionKeyBinding(this.buttonId, 0); - } - else if (keyCode != 0) - { -+ this.buttonId.setKeyModifierAndCode(net.minecraftforge.client.settings.KeyModifier.getActiveModifier(), keyCode); - this.options.setOptionKeyBinding(this.buttonId, keyCode); - } - else if (typedChar > 0) - { -+ this.buttonId.setKeyModifierAndCode(net.minecraftforge.client.settings.KeyModifier.getActiveModifier(), typedChar + 256); - this.options.setOptionKeyBinding(this.buttonId, typedChar + 256); - } - -+ if (!net.minecraftforge.client.settings.KeyModifier.isKeyCodeModifier(keyCode)) - this.buttonId = null; - this.time = Minecraft.getSystemTime(); - KeyBinding.resetKeyBindingArrayAndHash(); -@@ -161,7 +166,7 @@ - - for (KeyBinding keybinding : this.options.keyBindings) - { -- if (keybinding.getKeyCode() != keybinding.getKeyCodeDefault()) -+ if (!keybinding.isSetToDefaultValue()) - { - flag = true; - break; diff --git a/patches/minecraft/net/minecraft/client/gui/GuiCreateWorld.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiCreateWorld.java.patch deleted file mode 100644 index 29f9068b5..000000000 --- a/patches/minecraft/net/minecraft/client/gui/GuiCreateWorld.java.patch +++ /dev/null @@ -1,64 +0,0 @@ ---- before/net/minecraft/client/gui/GuiCreateWorld.java -+++ after/net/minecraft/client/gui/GuiCreateWorld.java -@@ -240,6 +240,8 @@ - } - } - -+ WorldType.WORLD_TYPES[this.selectedIndex].onGUICreateWorldPress(); -+ - WorldSettings worldsettings = new WorldSettings( - i, GameType.getByName(this.gameMode), this.generateStructuresEnabled, this.hardCoreMode, WorldType.WORLD_TYPES[this.selectedIndex] - ); -@@ -348,14 +350,7 @@ - } - else if (button.id == 8) - { -- if (WorldType.WORLD_TYPES[this.selectedIndex] == WorldType.FLAT) -- { -- this.mc.displayGuiScreen(new GuiCreateFlatWorld(this, this.chunkProviderSettingsJson)); -- } -- else -- { -- this.mc.displayGuiScreen(new GuiCustomizeWorldScreen(this, this.chunkProviderSettingsJson)); -- } -+ WorldType.WORLD_TYPES[this.selectedIndex].onCustomizeButton(mc, this); - } - } - } -@@ -415,11 +410,7 @@ - this.btnBonusItems.visible = this.inMoreWorldOptionsDisplay; - this.btnMapType.visible = this.inMoreWorldOptionsDisplay; - this.btnAllowCommands.visible = this.inMoreWorldOptionsDisplay; -- this.btnCustomizeType.visible = this.inMoreWorldOptionsDisplay -- && ( -- WorldType.WORLD_TYPES[this.selectedIndex] == WorldType.FLAT -- || WorldType.WORLD_TYPES[this.selectedIndex] == WorldType.CUSTOMIZED -- ); -+ this.btnCustomizeType.visible = this.inMoreWorldOptionsDisplay && WorldType.WORLD_TYPES[this.selectedIndex].isCustomizable(); - } - - this.updateDisplayState(); -@@ -460,6 +451,23 @@ - @Override - protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException - { -+ if (this.btnMapType.mousePressed(this.mc, mouseX, mouseY)) { -+ if (mouseButton == 1) { -+ -+ do { -+ this.selectedIndex--; -+ -+ if (this.selectedIndex < 0) { -+ this.selectedIndex = WorldType.WORLD_TYPES.length - 1; -+ } -+ } while (!this.canSelectCurWorldType()); -+ -+ this.chunkProviderSettingsJson = ""; -+ this.updateDisplayState(); -+ this.showMoreWorldOptions(this.inMoreWorldOptionsDisplay); -+ } -+ } -+ - super.mouseClicked(mouseX, mouseY, mouseButton); - - if (this.inMoreWorldOptionsDisplay) diff --git a/patches/minecraft/net/minecraft/client/gui/GuiEnchantment.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiEnchantment.java.patch deleted file mode 100644 index 4ce1bcc20..000000000 --- a/patches/minecraft/net/minecraft/client/gui/GuiEnchantment.java.patch +++ /dev/null @@ -1,26 +0,0 @@ ---- before/net/minecraft/client/gui/GuiEnchantment.java -+++ after/net/minecraft/client/gui/GuiEnchantment.java -@@ -179,7 +179,7 @@ - FontRenderer fontrenderer = this.mc.standardGalacticFontRenderer; - int i2 = 6839882; - -- if ((k < l + 1 || this.mc.player.experienceLevel < k1) && !this.mc.player.capabilities.isCreativeMode) -+ if (((k < l + 1 || this.mc.player.experienceLevel < k1) && !this.mc.player.capabilities.isCreativeMode) || this.container.enchantClue[l] == -1) // Forge: render buttons as disabled when enchantable but enchantability not met on lower levels - { - this.drawTexturedModalRect(i1, j + 14 + 19 * l, 0, 185, 108, 19); - this.drawTexturedModalRect(i1 + 1, j + 15 + 19 * l, 16 * l, 239, 16, 16); -@@ -229,11 +229,12 @@ - int l = this.container.worldClue[j]; - int i1 = j + 1; - -- if (this.isPointInRegion(60, 14 + 19 * j, 108, 17, mouseX, mouseY) && k > 0 && l >= 0 && enchantment != null) -+ if (this.isPointInRegion(60, 14 + 19 * j, 108, 17, mouseX, mouseY) && k > 0) - { - List list = Lists.newArrayList(); -- list.add("" + TextFormatting.WHITE + TextFormatting.ITALIC + I18n.format("container.enchant.clue", enchantment.getTranslatedName(l))); -+ list.add("" + TextFormatting.WHITE + TextFormatting.ITALIC + I18n.format("container.enchant.clue", enchantment == null ? "" : enchantment.getTranslatedName(l))); - -+ if(enchantment == null) java.util.Collections.addAll(list, "", TextFormatting.RED + I18n.format("forge.container.enchant.limitedEnchantability")); else - if (!flag) - { - list.add(""); diff --git a/patches/minecraft/net/minecraft/client/gui/GuiGameOver.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiGameOver.java.patch deleted file mode 100644 index 40477d501..000000000 --- a/patches/minecraft/net/minecraft/client/gui/GuiGameOver.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/client/gui/GuiGameOver.java -+++ after/net/minecraft/client/gui/GuiGameOver.java -@@ -74,7 +74,7 @@ - - if (this.mc.world.getWorldInfo().isHardcoreModeEnabled()) - { -- this.mc.displayGuiScreen(new GuiMainMenu()); -+ confirmClicked(true, 0); // Forge : Fix MC-30646 - } - else - { diff --git a/patches/minecraft/net/minecraft/client/gui/GuiIngame.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiIngame.java.patch deleted file mode 100644 index 2be731775..000000000 --- a/patches/minecraft/net/minecraft/client/gui/GuiIngame.java.patch +++ /dev/null @@ -1,36 +0,0 @@ ---- before/net/minecraft/client/gui/GuiIngame.java -+++ after/net/minecraft/client/gui/GuiIngame.java -@@ -400,8 +400,8 @@ - - BlockPos blockpos = raytraceresult.getBlockPos(); - -- if (!this.mc.world.getBlockState(blockpos).getBlock().hasTileEntity() -- || !(this.mc.world.getTileEntity(blockpos) instanceof IInventory)) -+ net.minecraft.block.state.IBlockState state = this.mc.world.getBlockState(blockpos); -+ if (!state.getBlock().hasTileEntity(state) || !(this.mc.world.getTileEntity(blockpos) instanceof IInventory)) - { - return; - } -@@ -476,7 +476,10 @@ - { - Potion potion = potioneffect.getPotion(); - -- if (potion.hasStatusIcon() && potioneffect.doesShowParticles()) -+ if (!potion.shouldRenderHUD(potioneffect)) continue; -+ // Rebind in case previous renderHUDEffect changed texture -+ this.mc.getTextureManager().bindTexture(GuiContainer.INVENTORY_BACKGROUND); -+ if (potioneffect.doesShowParticles()) - { - int k = resolution.getScaledWidth(); - int l = 1; -@@ -521,7 +524,10 @@ - } - - GlStateManager.color(1.0F, 1.0F, 1.0F, f); -+ // FORGE - Move status icon check down from above so renderHUDEffect will still be called without a status icon -+ if (potion.hasStatusIcon()) - this.drawTexturedModalRect(k + 3, l + 3, i1 % 8 * 18, 198 + i1 / 8 * 18, 18, 18); -+ potion.renderHUDEffect(potioneffect, this, k, l, this.zLevel, f); - } - } - } diff --git a/patches/minecraft/net/minecraft/client/gui/GuiIngameMenu.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiIngameMenu.java.patch deleted file mode 100644 index 5e8d36641..000000000 --- a/patches/minecraft/net/minecraft/client/gui/GuiIngameMenu.java.patch +++ /dev/null @@ -1,58 +0,0 @@ ---- before/net/minecraft/client/gui/GuiIngameMenu.java -+++ after/net/minecraft/client/gui/GuiIngameMenu.java -@@ -13,6 +13,7 @@ - { - private int saveStep; - private int visibleTime; -+ private net.minecraftforge.client.gui.NotificationModUpdateScreen modUpdateNotification; - - @Override - public void initGui() -@@ -30,13 +31,15 @@ - - this.buttonList.add(new GuiButton(4, this.width / 2 - 100, this.height / 4 + 24 + -16, I18n.format("menu.returnToGame"))); - this.buttonList.add(new GuiButton(0, this.width / 2 - 100, this.height / 4 + 96 + -16, 98, 20, I18n.format("menu.options"))); -- GuiButton guibutton = this.addButton( -- new GuiButton(7, this.width / 2 + 2, this.height / 4 + 96 + -16, 98, 20, I18n.format("menu.shareToLan")) -- ); -+ GuiButton modButton = this.addButton(new GuiButton(12, this.width / 2 + 2, this.height / 4 + 96 + i, 98, 20, I18n.format("fml.menu.mods"))); -+ GuiButton guibutton = this.addButton(new GuiButton(7, this.width / 2 - 100, this.height / 4 + 72 + -16, 200, 20, I18n.format("menu.shareToLan", new Object[0]))); - guibutton.enabled = this.mc.isSingleplayer() && !this.mc.getIntegratedServer().getPublic(); -- this.buttonList -- .add(new GuiButton(5, this.width / 2 - 100, this.height / 4 + 48 + -16, 98, 20, I18n.format("gui.advancements"))); -+ this.buttonList.add(new GuiButton(5, this.width / 2 - 100, this.height / 4 + 48 + -16, 98, 20, I18n.format("gui.advancements"))); - this.buttonList.add(new GuiButton(6, this.width / 2 + 2, this.height / 4 + 48 + -16, 98, 20, I18n.format("gui.stats"))); -+ -+ this.modUpdateNotification = new net.minecraftforge.client.gui.NotificationModUpdateScreen(modButton); -+ this.modUpdateNotification.setGuiSize(this.width, this.height); -+ this.modUpdateNotification.initGui(); - } - - @Override -@@ -77,13 +80,19 @@ - this.mc.setIngameFocus(); - break; - case 5: -+ if (this.mc.player != null) - this.mc.displayGuiScreen(new GuiScreenAdvancements(this.mc.player.connection.getAdvancementManager())); - break; - case 6: -+ if (this.mc.player != null) - this.mc.displayGuiScreen(new GuiStats(this, this.mc.player.getStatFileWriter())); - break; - case 7: - this.mc.displayGuiScreen(new GuiShareToLan(this)); -+ break; -+ case 12: -+ net.minecraftforge.fml.client.FMLClientHandler.instance().showInGameModOptions(this); -+ break; - } - } - -@@ -100,5 +109,6 @@ - this.drawDefaultBackground(); - this.drawCenteredString(this.fontRenderer, I18n.format("menu.game"), this.width / 2, 40, 16777215); - super.drawScreen(mouseX, mouseY, partialTicks); -+ this.modUpdateNotification.drawScreen(mouseX, mouseY, partialTicks); - } - } diff --git a/patches/minecraft/net/minecraft/client/gui/GuiKeyBindingList.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiKeyBindingList.java.patch deleted file mode 100644 index df9e9daf4..000000000 --- a/patches/minecraft/net/minecraft/client/gui/GuiKeyBindingList.java.patch +++ /dev/null @@ -1,67 +0,0 @@ ---- before/net/minecraft/client/gui/GuiKeyBindingList.java -+++ after/net/minecraft/client/gui/GuiKeyBindingList.java -@@ -65,7 +65,7 @@ - @Override - protected int getScrollBarX() - { -- return super.getScrollBarX() + 15; -+ return super.getScrollBarX() + 35; - } - - @Override -@@ -138,7 +138,7 @@ - { - this.keybinding = name; - this.keyDesc = I18n.format(name.getKeyDescription()); -- this.btnChangeKeyBinding = new GuiButton(0, 0, 0, 75, 20, I18n.format(name.getKeyDescription())); -+ this.btnChangeKeyBinding = new GuiButton(0, 0, 0, 95, 20, I18n.format(name.getKeyDescription())); - this.btnReset = new GuiButton(0, 0, 0, 50, 20, I18n.format("controls.reset")); - } - -@@ -164,23 +164,24 @@ - y + slotHeight / 2 - GuiKeyBindingList.this.mc.fontRenderer.FONT_HEIGHT / 2, - 16777215 - ); -- this.btnReset.x = x + 190; -+ this.btnReset.x = x + 210; - this.btnReset.y = y; -- this.btnReset.enabled = this.keybinding.getKeyCode() != this.keybinding.getKeyCodeDefault(); -+ this.btnReset.enabled = !this.keybinding.isSetToDefaultValue(); - this.btnReset.drawButton(GuiKeyBindingList.this.mc, mouseX, mouseY, partialTicks); - this.btnChangeKeyBinding.x = x + 105; - this.btnChangeKeyBinding.y = y; -- this.btnChangeKeyBinding.displayString = GameSettings.getKeyDisplayString(this.keybinding.getKeyCode()); -+ this.btnChangeKeyBinding.displayString = this.keybinding.getDisplayName(); - boolean flag1 = false; -+ boolean keyCodeModifierConflict = true; // less severe form of conflict, like SHIFT conflicting with SHIFT+G - - if (this.keybinding.getKeyCode() != 0) - { - for (KeyBinding keybinding : GuiKeyBindingList.this.mc.gameSettings.keyBindings) - { -- if (keybinding != this.keybinding && keybinding.getKeyCode() == this.keybinding.getKeyCode()) -+ if (keybinding != this.keybinding && keybinding.conflicts(this.keybinding)) - { - flag1 = true; -- break; -+ keyCodeModifierConflict &= keybinding.hasKeyCodeModifierConflict(this.keybinding); - } - } - } -@@ -196,7 +197,7 @@ - } - else if (flag1) - { -- this.btnChangeKeyBinding.displayString = TextFormatting.RED + this.btnChangeKeyBinding.displayString; -+ this.btnChangeKeyBinding.displayString = (keyCodeModifierConflict ? TextFormatting.GOLD : TextFormatting.RED) + this.btnChangeKeyBinding.displayString; - } - - this.btnChangeKeyBinding.drawButton(GuiKeyBindingList.this.mc, mouseX, mouseY, partialTicks); -@@ -212,6 +213,7 @@ - } - else if (this.btnReset.mousePressed(GuiKeyBindingList.this.mc, mouseX, mouseY)) - { -+ this.keybinding.setToDefault(); - GuiKeyBindingList.this.mc.gameSettings.setOptionKeyBinding(this.keybinding, this.keybinding.getKeyCodeDefault()); - KeyBinding.resetKeyBindingArrayAndHash(); - return true; diff --git a/patches/minecraft/net/minecraft/client/gui/GuiLanguage.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiLanguage.java.patch deleted file mode 100644 index ac0eff4c8..000000000 --- a/patches/minecraft/net/minecraft/client/gui/GuiLanguage.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/client/gui/GuiLanguage.java -+++ after/net/minecraft/client/gui/GuiLanguage.java -@@ -126,7 +126,7 @@ - Language language = this.languageMap.get(this.langCodeList.get(slotIndex)); - GuiLanguage.this.languageManager.setCurrentLanguage(language); - GuiLanguage.this.game_settings_3.language = language.getLanguageCode(); -- this.mc.refreshResources(); -+ net.minecraftforge.fml.client.FMLClientHandler.instance().refreshResources(net.minecraftforge.client.resource.VanillaResourceType.LANGUAGES); - GuiLanguage.this.fontRenderer.setUnicodeFlag(GuiLanguage.this.languageManager.isCurrentLocaleUnicode() || GuiLanguage.this.game_settings_3.forceUnicodeFont); - GuiLanguage.this.fontRenderer.setBidiFlag(GuiLanguage.this.languageManager.isCurrentLanguageBidirectional()); - GuiLanguage.this.confirmSettingsBtn.displayString = I18n.format("gui.done"); diff --git a/patches/minecraft/net/minecraft/client/gui/GuiListExtended.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiListExtended.java.patch deleted file mode 100644 index 042e7bfe3..000000000 --- a/patches/minecraft/net/minecraft/client/gui/GuiListExtended.java.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- before/net/minecraft/client/gui/GuiListExtended.java -+++ after/net/minecraft/client/gui/GuiListExtended.java -@@ -59,7 +59,7 @@ - - if (i >= 0) - { -- int j = this.left + this.width / 2 - this.getListWidth() / 2 + 2; -+ int j = this.getListEntryLeft(); - int k = this.top + 4 - this.getAmountScrolled() + i * this.slotHeight + this.headerPadding; - int l = mouseX - j; - int i1 = mouseY - k; -@@ -79,7 +79,7 @@ - { - for (int i = 0; i < this.getSize(); i++) - { -- int j = this.left + this.width / 2 - this.getListWidth() / 2 + 2; -+ int j = this.getListEntryLeft(); - int k = this.top + 4 - this.getAmountScrolled() + i * this.slotHeight + this.headerPadding; - int l = x - j; - int i1 = y - k; diff --git a/patches/minecraft/net/minecraft/client/gui/GuiListWorldSelectionEntry.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiListWorldSelectionEntry.java.patch deleted file mode 100644 index a887cae7a..000000000 --- a/patches/minecraft/net/minecraft/client/gui/GuiListWorldSelectionEntry.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/client/gui/GuiListWorldSelectionEntry.java -+++ after/net/minecraft/client/gui/GuiListWorldSelectionEntry.java -@@ -300,7 +300,7 @@ - - if (this.client.getSaveLoader().canLoadWorld(this.worldSummary.getFileName())) - { -- this.client.launchIntegratedServer(this.worldSummary.getFileName(), this.worldSummary.getDisplayName(), null); -+ net.minecraftforge.fml.client.FMLClientHandler.instance().tryLoadExistingWorld(worldSelScreen, this.worldSummary); - } - } - diff --git a/patches/minecraft/net/minecraft/client/gui/GuiMainMenu.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiMainMenu.java.patch deleted file mode 100644 index c829707bd..000000000 --- a/patches/minecraft/net/minecraft/client/gui/GuiMainMenu.java.patch +++ /dev/null @@ -1,158 +0,0 @@ ---- before/net/minecraft/client/gui/GuiMainMenu.java -+++ after/net/minecraft/client/gui/GuiMainMenu.java -@@ -77,6 +77,8 @@ - private GuiScreen realmsNotification; - private int widthCopyright; - private int widthCopyrightRest; -+ private GuiButton modButton; -+ private net.minecraftforge.client.gui.NotificationModUpdateScreen modUpdateNotification; - - public GuiMainMenu() - { -@@ -130,19 +132,9 @@ - - private boolean areRealmsNotificationsEnabled() - { -- return Minecraft.getMinecraft().gameSettings.getOptionOrdinalValue(GameSettings.Options.REALMS_NOTIFICATIONS) && this.realmsNotification != null; -- } -- -- @Override -- public void updateScreen() -- { -- if (this.areRealmsNotificationsEnabled()) -- { -- this.realmsNotification.updateScreen(); -- } -- } -- -- @Override -+ return false; -+ } -+ - public boolean doesGuiPauseGame() - { - return false; -@@ -205,25 +197,14 @@ - - this.mc.setConnectedToRealms(false); - -- if (Minecraft.getMinecraft().gameSettings.getOptionOrdinalValue(GameSettings.Options.REALMS_NOTIFICATIONS) && !this.hasCheckedForRealmsNotification) -- { -- RealmsBridge realmsbridge = new RealmsBridge(); -- this.realmsNotification = realmsbridge.getNotificationScreen(this); -- this.hasCheckedForRealmsNotification = true; -- } -- -- if (this.areRealmsNotificationsEnabled()) -- { -- this.realmsNotification.setGuiSize(this.width, this.height); -- this.realmsNotification.initGui(); -- } -+ this.modUpdateNotification = net.minecraftforge.client.gui.NotificationModUpdateScreen.init(this, this.modButton); - } - - private void addSingleplayerMultiplayerButtons(int p_73969_1_, int p_73969_2_) - { - this.buttonList.add(new GuiButton(1, this.width / 2 - 100, p_73969_1_, I18n.format("menu.singleplayer"))); - this.buttonList.add(new GuiButton(2, this.width / 2 - 100, p_73969_1_ + p_73969_2_ * 1, I18n.format("menu.multiplayer"))); -- this.realmsButton = this.addButton(new GuiButton(14, this.width / 2 - 100, p_73969_1_ + p_73969_2_ * 2, I18n.format("menu.online"))); -+ this.buttonList.add(this.modButton = new GuiButton(6, this.width / 2 - 100, p_73969_1_ + p_73969_2_ * 2, I18n.format("fml.menu.mods"))); - } - - private void addDemoButtons(int p_73972_1_, int p_73972_2_) -@@ -264,16 +245,16 @@ - this.mc.displayGuiScreen(new GuiMultiplayer(this)); - } - -- if (button.id == 14 && this.realmsButton.visible) -- { -- this.switchToRealms(); -- } -- - if (button.id == 4) - { - this.mc.shutdown(); - } - -+ if (button.id == 6) -+ { -+ this.mc.displayGuiScreen(new net.minecraftforge.fml.client.GuiModList(this)); -+ } -+ - if (button.id == 11) - { - this.mc.launchIntegratedServer("Demo_World", "Demo_World", WorldServerDemo.DEMO_WORLD_SETTINGS); -@@ -303,8 +284,6 @@ - - private void switchToRealms() - { -- RealmsBridge realmsbridge = new RealmsBridge(); -- realmsbridge.switchToRealms(this); - } - - @Override -@@ -524,6 +503,9 @@ - - this.mc.getTextureManager().bindTexture(field_194400_H); - drawModalRectWithCustomSizedTexture(j + 88, 67, 0.0F, 0.0F, 98, 14, 128.0F, 16.0F); -+ -+ this.splashText = net.minecraftforge.client.ForgeHooksClient.renderMainMenu(this, this.fontRenderer, this.width, this.height, this.splashText); -+ - GlStateManager.pushMatrix(); - GlStateManager.translate(this.width / 2 + 90, 70.0F, 0.0F); - GlStateManager.rotate(-20.0F, 0.0F, 0.0F, 1.0F); -@@ -543,7 +525,16 @@ - s = s + ("release".equalsIgnoreCase(this.mc.getVersionType()) ? "" : "/" + this.mc.getVersionType()); - } - -- this.drawString(this.fontRenderer, s, 2, this.height - 10, -1); -+ java.util.List brandings = com.google.common.collect.Lists.reverse(net.minecraftforge.fml.common.FMLCommonHandler.instance().getBrandings(true)); -+ for (int brdline = 0; brdline < brandings.size(); brdline++) -+ { -+ String brd = brandings.get(brdline); -+ if (!com.google.common.base.Strings.isNullOrEmpty(brd)) -+ { -+ this.drawString(this.fontRenderer, brd, 2, this.height - ( 10 + brdline * (this.fontRenderer.FONT_HEIGHT + 1)), 16777215); -+ } -+ } -+ - this.drawString(this.fontRenderer, "Copyright Mojang AB. Do not distribute!", this.widthCopyrightRest, this.height - 10, -1); - - if (mouseX > this.widthCopyrightRest -@@ -566,10 +557,7 @@ - - super.drawScreen(mouseX, mouseY, partialTicks); - -- if (this.areRealmsNotificationsEnabled()) -- { -- this.realmsNotification.drawScreen(mouseX, mouseY, partialTicks); -- } -+ modUpdateNotification.drawScreen(mouseX, mouseY, partialTicks); - } - - @Override -@@ -592,11 +580,6 @@ - } - } - -- if (this.areRealmsNotificationsEnabled()) -- { -- this.realmsNotification.mouseClicked(mouseX, mouseY, mouseButton); -- } -- - if (mouseX > this.widthCopyrightRest - && mouseX < this.widthCopyrightRest + this.widthCopyright - && mouseY > this.height - 10 -@@ -606,12 +589,4 @@ - } - } - -- @Override -- public void onGuiClosed() -- { -- if (this.realmsNotification != null) -- { -- this.realmsNotification.onGuiClosed(); -- } -- } - } diff --git a/patches/minecraft/net/minecraft/client/gui/GuiMultiplayer.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiMultiplayer.java.patch deleted file mode 100644 index 376374714..000000000 --- a/patches/minecraft/net/minecraft/client/gui/GuiMultiplayer.java.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- before/net/minecraft/client/gui/GuiMultiplayer.java -+++ after/net/minecraft/client/gui/GuiMultiplayer.java -@@ -41,6 +41,7 @@ - public GuiMultiplayer(GuiScreen parentScreen) - { - this.parentScreen = parentScreen; -+ net.minecraftforge.fml.client.FMLClientHandler.instance().setupServerList(); - } - - @Override -@@ -395,7 +396,7 @@ - - private void connectToServer(ServerData server) - { -- this.mc.displayGuiScreen(new GuiConnecting(this, this.mc, server)); -+ net.minecraftforge.fml.client.FMLClientHandler.instance().connectToServer(this, server); - } - - public void selectServer(int index) diff --git a/patches/minecraft/net/minecraft/client/gui/GuiOptions.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiOptions.java.patch deleted file mode 100644 index 6c2d484ca..000000000 --- a/patches/minecraft/net/minecraft/client/gui/GuiOptions.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/client/gui/GuiOptions.java -+++ after/net/minecraft/client/gui/GuiOptions.java -@@ -85,7 +85,7 @@ - this.difficultyButton.enabled = false; - } - } -- else -+ else if (false) // removed realms button - { - this.buttonList - .add( diff --git a/patches/minecraft/net/minecraft/client/gui/GuiOverlayDebug.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiOverlayDebug.java.patch deleted file mode 100644 index 29155c0b9..000000000 --- a/patches/minecraft/net/minecraft/client/gui/GuiOverlayDebug.java.patch +++ /dev/null @@ -1,64 +0,0 @@ ---- before/net/minecraft/client/gui/GuiOverlayDebug.java -+++ after/net/minecraft/client/gui/GuiOverlayDebug.java -@@ -2,6 +2,7 @@ - - import com.google.common.base.Strings; - import com.google.common.collect.Lists; -+import com.google.common.collect.UnmodifiableIterator; - import java.util.List; - import java.util.Map.Entry; - import net.minecraft.block.Block; -@@ -25,6 +26,7 @@ - import net.minecraft.world.chunk.Chunk; - import net.minecraftforge.fml.relauncher.Side; - import net.minecraftforge.fml.relauncher.SideOnly; -+import org.lwjgl.Sys; - import org.lwjgl.opengl.Display; - - @SideOnly(Side.CLIENT) -@@ -254,6 +256,7 @@ - long l = j - k; - List list = Lists.newArrayList( - String.format("Java: %s %dbit", System.getProperty("java.version"), this.mc.isJava64bit() ? 64 : 32), -+ "LWJGL: " + Sys.getVersion(), - String.format("Mem: % 2d%% %03d/%03dMB", l * 100L / i, bytesToMb(l), bytesToMb(i)), - String.format("Allocated: % 2d%% %03dMB", j * 100L / i, bytesToMb(j)), - "", -@@ -264,6 +267,9 @@ - GlStateManager.glGetString(7938) - ); - -+ list.add(""); -+ list.addAll(net.minecraftforge.fml.common.FMLCommonHandler.instance().getBrandings(false)); -+ - if (this.mc.isReducedDebug()) - { - return list; -@@ -284,12 +290,15 @@ - - list.add(""); - list.add(String.valueOf(Block.REGISTRY.getNameForObject(iblockstate.getBlock()))); -+ IProperty iproperty; -+ String s; - -- for (Entry entry : iblockstate.getProperties().entrySet()) -+ for (UnmodifiableIterator unmodifiableiterator = iblockstate.getProperties().entrySet().iterator(); unmodifiableiterator.hasNext(); list.add(iproperty.getName() + ": " + s)) - { -- IProperty iproperty = (IProperty)entry.getKey(); -+ Entry < IProperty, Comparable> entry = (Entry)unmodifiableiterator.next(); -+ iproperty = (IProperty)entry.getKey(); - T t = (T)entry.getValue(); -- String s = iproperty.getName(t); -+ s = iproperty.getName(t); - - if (Boolean.TRUE.equals(t)) - { -@@ -299,8 +308,6 @@ - { - s = TextFormatting.RED + s; - } -- -- list.add(iproperty.getName() + ": " + s); - } - } - diff --git a/patches/minecraft/net/minecraft/client/gui/GuiScreen.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiScreen.java.patch deleted file mode 100644 index 99927254b..000000000 --- a/patches/minecraft/net/minecraft/client/gui/GuiScreen.java.patch +++ /dev/null @@ -1,119 +0,0 @@ ---- before/net/minecraft/client/gui/GuiScreen.java -+++ after/net/minecraft/client/gui/GuiScreen.java -@@ -60,6 +60,7 @@ - private int touchValue; - private URI clickedLinkURI; - private boolean focused; -+ protected boolean keyHandled, mouseHandled; // Forge: allow canceling key and mouse Post events from handleMouseInput and handleKeyboardInput - - public void drawScreen(int mouseX, int mouseY, float partialTicks) - { -@@ -128,7 +129,10 @@ - - protected void renderToolTip(ItemStack stack, int x, int y) - { -- this.drawHoveringText(this.getItemToolTip(stack), x, y); -+ FontRenderer font = stack.getItem().getFontRenderer(stack); -+ net.minecraftforge.fml.client.config.GuiUtils.preItemToolTip(stack); -+ this.drawHoveringText(this.getItemToolTip(stack), x, y, (font == null ? fontRenderer : font)); -+ net.minecraftforge.fml.client.config.GuiUtils.postItemToolTip(); - } - - public List getItemToolTip(ItemStack p_191927_1_) -@@ -142,7 +146,7 @@ - { - if (i == 0) - { -- list.set(i, p_191927_1_.getRarity().color + list.get(i)); -+ list.set(i, p_191927_1_.getItem().getForgeRarity(p_191927_1_).getColor() + (String)list.get(i)); - } - else - { -@@ -170,7 +174,13 @@ - - public void drawHoveringText(List textLines, int x, int y) - { -- if (!textLines.isEmpty()) -+ drawHoveringText(textLines, x, y, fontRenderer); -+ } -+ -+ protected void drawHoveringText(List textLines, int x, int y, FontRenderer font) -+ { -+ net.minecraftforge.fml.client.config.GuiUtils.drawHoveringText(textLines, x, y, width, height, -1, font); -+ if (false && !textLines.isEmpty()) - { - GlStateManager.disableRescaleNormal(); - RenderHelper.disableStandardItemLighting(); -@@ -406,10 +416,13 @@ - - public void sendChatMessage(String msg, boolean addToChat) - { -+ msg = net.minecraftforge.event.ForgeEventFactory.onClientSendMessage(msg); -+ if (msg.isEmpty()) return; - if (addToChat) - { - this.mc.ingameGUI.getChatGUI().addToSentMessages(msg); - } -+ if (net.minecraftforge.client.ClientCommandHandler.instance.executeCommand(mc.player, msg) != 0) return; - - this.mc.player.sendChatMessage(msg); - } -@@ -424,9 +437,15 @@ - - if (guibutton.mousePressed(this.mc, mouseX, mouseY)) - { -+ net.minecraftforge.client.event.GuiScreenEvent.ActionPerformedEvent.Pre event = new net.minecraftforge.client.event.GuiScreenEvent.ActionPerformedEvent.Pre(this, guibutton, this.buttonList); -+ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event)) -+ break; -+ guibutton = event.getButton(); - this.selectedButton = guibutton; - guibutton.playPressSound(this.mc.getSoundHandler()); - this.actionPerformed(guibutton); -+ if (this.equals(this.mc.currentScreen)) -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.GuiScreenEvent.ActionPerformedEvent.Post(this, event.getButton(), this.buttonList)); - } - } - } -@@ -456,8 +475,12 @@ - this.fontRenderer = mc.fontRenderer; - this.width = width; - this.height = height; -+ if (!net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.GuiScreenEvent.InitGuiEvent.Pre(this, this.buttonList))) -+ { - this.buttonList.clear(); - this.initGui(); -+ } -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.GuiScreenEvent.InitGuiEvent.Post(this, this.buttonList)); - } - - public void setGuiSize(int w, int h) -@@ -476,7 +499,10 @@ - { - while (Mouse.next()) - { -+ this.mouseHandled = false; -+ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.GuiScreenEvent.MouseInputEvent.Pre(this))) continue; - this.handleMouseInput(); -+ if (this.equals(this.mc.currentScreen) && !this.mouseHandled) net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.GuiScreenEvent.MouseInputEvent.Post(this)); - } - } - -@@ -484,7 +510,10 @@ - { - while (Keyboard.next()) - { -+ this.keyHandled = false; -+ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.GuiScreenEvent.KeyboardInputEvent.Pre(this))) continue; - this.handleKeyboardInput(); -+ if (this.equals(this.mc.currentScreen) && !this.keyHandled) net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.GuiScreenEvent.KeyboardInputEvent.Post(this)); - } - } - } -@@ -546,6 +575,7 @@ - public void drawDefaultBackground() - { - this.drawWorldBackground(0); -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.GuiScreenEvent.BackgroundDrawnEvent(this)); - } - - public void drawWorldBackground(int tint) diff --git a/patches/minecraft/net/minecraft/client/gui/GuiScreenBook.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiScreenBook.java.patch deleted file mode 100644 index cf4739514..000000000 --- a/patches/minecraft/net/minecraft/client/gui/GuiScreenBook.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- before/net/minecraft/client/gui/GuiScreenBook.java -+++ after/net/minecraft/client/gui/GuiScreenBook.java -@@ -69,6 +69,7 @@ - - if (this.bookTotalPages < 1) - { -+ this.bookPages.appendTag(new NBTTagString("")); // Forge: fix MC-1685 - this.bookTotalPages = 1; - } - } diff --git a/patches/minecraft/net/minecraft/client/gui/GuiScreenDemo.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiScreenDemo.java.patch deleted file mode 100644 index 8ea519edd..000000000 --- a/patches/minecraft/net/minecraft/client/gui/GuiScreenDemo.java.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- before/net/minecraft/client/gui/GuiScreenDemo.java -+++ after/net/minecraft/client/gui/GuiScreenDemo.java -@@ -78,10 +78,10 @@ - .drawString( - I18n.format( - "demo.help.movementShort", -- GameSettings.getKeyDisplayString(gamesettings.keyBindForward.getKeyCode()), -- GameSettings.getKeyDisplayString(gamesettings.keyBindLeft.getKeyCode()), -- GameSettings.getKeyDisplayString(gamesettings.keyBindBack.getKeyCode()), -- GameSettings.getKeyDisplayString(gamesettings.keyBindRight.getKeyCode()) -+ gamesettings.keyBindForward.getDisplayName(), -+ gamesettings.keyBindLeft.getDisplayName(), -+ gamesettings.keyBindBack.getDisplayName(), -+ gamesettings.keyBindRight.getDisplayName() - ), - i, - j, -@@ -89,9 +89,9 @@ - ); - this.fontRenderer.drawString(I18n.format("demo.help.movementMouse"), i, j + 12, 5197647); - this.fontRenderer -- .drawString(I18n.format("demo.help.jump", GameSettings.getKeyDisplayString(gamesettings.keyBindJump.getKeyCode())), i, j + 24, 5197647); -+ .drawString(I18n.format("demo.help.jump", gamesettings.keyBindJump.getDisplayName()), i, j + 24, 5197647); - this.fontRenderer -- .drawString(I18n.format("demo.help.inventory", GameSettings.getKeyDisplayString(gamesettings.keyBindInventory.getKeyCode())), i, j + 36, 5197647); -+ .drawString(I18n.format("demo.help.inventory", gamesettings.keyBindInventory.getDisplayName()), i, j + 36, 5197647); - this.fontRenderer.drawSplitString(I18n.format("demo.help.fullWrapped"), i, j + 68, 218, 2039583); - super.drawScreen(mouseX, mouseY, partialTicks); - } diff --git a/patches/minecraft/net/minecraft/client/gui/GuiSleepMP.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiSleepMP.java.patch deleted file mode 100644 index a0e000873..000000000 --- a/patches/minecraft/net/minecraft/client/gui/GuiSleepMP.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/client/gui/GuiSleepMP.java -+++ after/net/minecraft/client/gui/GuiSleepMP.java -@@ -34,7 +34,7 @@ - - if (!s.isEmpty()) - { -- this.mc.player.sendChatMessage(s); -+ this.sendChatMessage(s); // Forge: fix vanilla not adding messages to the sent list while sleeping - } - - this.inputField.setText(""); diff --git a/patches/minecraft/net/minecraft/client/gui/GuiSlot.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiSlot.java.patch deleted file mode 100644 index b5c9df4d2..000000000 --- a/patches/minecraft/net/minecraft/client/gui/GuiSlot.java.patch +++ /dev/null @@ -1,169 +0,0 @@ ---- before/net/minecraft/client/gui/GuiSlot.java -+++ after/net/minecraft/client/gui/GuiSlot.java -@@ -110,8 +110,8 @@ - - public int getSlotIndexFromScreenCoords(int posX, int posY) - { -- int i = this.left + this.width / 2 - this.getListWidth() / 2; -- int j = this.left + this.width / 2 + this.getListWidth() / 2; -+ int i = this.getListLeft(); -+ int j = this.getListRight(); - int k = posY - this.top - this.headerPadding + (int)this.amountScrolled - 4; - int l = k / this.slotHeight; - return posX < this.getScrollBarX() && posX >= i && posX <= j && l >= 0 && k >= 0 && l < this.getSize() ? l : -1; -@@ -186,28 +186,9 @@ - GlStateManager.disableFog(); - Tessellator tessellator = Tessellator.getInstance(); - BufferBuilder bufferbuilder = tessellator.getBuffer(); -- this.mc.getTextureManager().bindTexture(Gui.OPTIONS_BACKGROUND); -- GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); -- float f = 32.0F; -- bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR); -- bufferbuilder.pos(this.left, this.bottom, 0.0) -- .tex(this.left / 32.0F, (this.bottom + (int)this.amountScrolled) / 32.0F) -- .color(32, 32, 32, 255) -- .endVertex(); -- bufferbuilder.pos(this.right, this.bottom, 0.0) -- .tex(this.right / 32.0F, (this.bottom + (int)this.amountScrolled) / 32.0F) -- .color(32, 32, 32, 255) -- .endVertex(); -- bufferbuilder.pos(this.right, this.top, 0.0) -- .tex(this.right / 32.0F, (this.top + (int)this.amountScrolled) / 32.0F) -- .color(32, 32, 32, 255) -- .endVertex(); -- bufferbuilder.pos(this.left, this.top, 0.0) -- .tex(this.left / 32.0F, (this.top + (int)this.amountScrolled) / 32.0F) -- .color(32, 32, 32, 255) -- .endVertex(); -- tessellator.draw(); -- int k = this.left + this.width / 2 - this.getListWidth() / 2 + 2; -+ // Forge: background rendering moved into separate method. -+ this.drawContainerBackground(tessellator); -+ int k = this.getListEntryLeft(); - int l = this.top + 4 - (int)this.amountScrolled; - - if (this.hasListHeader) -@@ -229,6 +210,7 @@ - GlStateManager.disableAlpha(); - GlStateManager.shadeModel(7425); - GlStateManager.disableTexture2D(); -+ if (this.drawTopBottomShadow(tessellator)) { - int i1 = 4; - bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR); - bufferbuilder.pos(this.left, this.top + 4, 0.0).tex(0.0, 1.0).color(0, 0, 0, 0).endVertex(); -@@ -242,12 +224,12 @@ - bufferbuilder.pos(this.right, this.bottom - 4, 0.0).tex(1.0, 0.0).color(0, 0, 0, 0).endVertex(); - bufferbuilder.pos(this.left, this.bottom - 4, 0.0).tex(0.0, 0.0).color(0, 0, 0, 0).endVertex(); - tessellator.draw(); -+ } - int j1 = this.getMaxScroll(); - - if (j1 > 0) - { -- int k1 = (this.bottom - this.top) * (this.bottom - this.top) / this.getContentHeight(); -- k1 = MathHelper.clamp(k1, 32, this.bottom - this.top - 8); -+ int k1 = this.getScrollThumbHeight(); - int l1 = (int)this.amountScrolled * (this.bottom - this.top - k1) / j1 + this.top; - - if (l1 < this.top) -@@ -292,8 +274,8 @@ - && this.mouseY >= this.top - && this.mouseY <= this.bottom) - { -- int i = (this.width - this.getListWidth()) / 2; -- int j = (this.width + this.getListWidth()) / 2; -+ int i = this.getListLeft(); -+ int j = this.getListRight(); - int k = this.mouseY - this.top - this.headerPadding + (int)this.amountScrolled - 4; - int l = k / this.slotHeight; - -@@ -318,8 +300,8 @@ - - if (this.mouseY >= this.top && this.mouseY <= this.bottom) - { -- int j2 = (this.width - this.getListWidth()) / 2; -- int k2 = (this.width + this.getListWidth()) / 2; -+ int j2 = this.getListLeft(); -+ int k2 = this.getListRight(); - int l2 = this.mouseY - this.top - this.headerPadding + (int)this.amountScrolled - 4; - int i1 = l2 / this.slotHeight; - -@@ -349,8 +331,7 @@ - k1 = 1; - } - -- int l1 = (int)((float)((this.bottom - this.top) * (this.bottom - this.top)) / this.getContentHeight()); -- l1 = MathHelper.clamp(l1, 32, this.bottom - this.top - 8); -+ int l1 = this.getScrollThumbHeight(); - this.scrollMultiplier = this.scrollMultiplier / ((float)(this.bottom - this.top - l1) / k1); - } - else -@@ -429,8 +410,8 @@ - - if (this.showSelectionBox && this.isSelected(j)) - { -- int i1 = this.left + (this.width / 2 - this.getListWidth() / 2); -- int j1 = this.left + this.width / 2 + this.getListWidth() / 2; -+ int i1 = this.getListLeft(); -+ int j1 = this.getListRight(); - GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); - GlStateManager.disableTexture2D(); - bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR); -@@ -491,5 +472,57 @@ - public int getSlotHeight() - { - return this.slotHeight; -+ } -+ -+ protected void drawContainerBackground(Tessellator tessellator) -+ { -+ BufferBuilder buffer = tessellator.getBuffer(); -+ this.mc.getTextureManager().bindTexture(Gui.OPTIONS_BACKGROUND); -+ GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); -+ float f = 32.0F; -+ buffer.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR); -+ buffer.pos(this.left, this.bottom, 0.0) -+ .tex((float)this.left / f, (float)(this.bottom + (int)this.amountScrolled) / f) -+ .color(32, 32, 32, 255) -+ .endVertex(); -+ buffer.pos(this.right, this.bottom, 0.0) -+ .tex((float)this.right / f, (float)(this.bottom + (int)this.amountScrolled) / f) -+ .color(32, 32, 32, 255) -+ .endVertex(); -+ buffer.pos(this.right, this.top, 0.0) -+ .tex((float)this.right / f, (float)(this.top + (int)this.amountScrolled) / f) -+ .color(32, 32, 32, 255) -+ .endVertex(); -+ buffer.pos(this.left, this.top, 0.0) -+ .tex((float)this.left / f, (float)(this.top + (int)this.amountScrolled) / f) -+ .color(32, 32, 32, 255) -+ .endVertex(); -+ tessellator.draw(); -+ } -+ -+ protected boolean drawTopBottomShadow(Tessellator tessellator) -+ { -+ return true; -+ } -+ -+ protected int getScrollThumbHeight() -+ { -+ int viewHeight = this.bottom - this.top; -+ return MathHelper.clamp(viewHeight * viewHeight / this.getContentHeight(), 32, viewHeight - 8); -+ } -+ -+ protected int getListLeft() -+ { -+ return this.left + this.width / 2 - this.getListWidth() / 2; -+ } -+ -+ protected int getListRight() -+ { -+ return this.left + this.width / 2 + this.getListWidth() / 2; -+ } -+ -+ protected int getListEntryLeft() -+ { -+ return this.getListLeft() + 2; - } - } diff --git a/patches/minecraft/net/minecraft/client/gui/GuiSpectator.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiSpectator.java.patch deleted file mode 100644 index 9fed00003..000000000 --- a/patches/minecraft/net/minecraft/client/gui/GuiSpectator.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/client/gui/GuiSpectator.java -+++ after/net/minecraft/client/gui/GuiSpectator.java -@@ -111,7 +111,7 @@ - GlStateManager.color(f, f, f, p_175266_4_); - p_175266_5_.renderIcon(f, i); - GlStateManager.popMatrix(); -- String s = String.valueOf(GameSettings.getKeyDisplayString(this.mc.gameSettings.keyBindsHotbar[p_175266_1_].getKeyCode())); -+ String s = String.valueOf(this.mc.gameSettings.keyBindsHotbar[p_175266_1_].getDisplayName()); - - if (i > 3 && p_175266_5_.isEnabled()) - { diff --git a/patches/minecraft/net/minecraft/client/gui/GuiTextField.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiTextField.java.patch deleted file mode 100644 index 649fae2e3..000000000 --- a/patches/minecraft/net/minecraft/client/gui/GuiTextField.java.patch +++ /dev/null @@ -1,45 +0,0 @@ ---- before/net/minecraft/client/gui/GuiTextField.java -+++ after/net/minecraft/client/gui/GuiTextField.java -@@ -1,5 +1,6 @@ - package net.minecraft.client.gui; - -+import com.cleanroommc.client.IMEHandler; - import com.google.common.base.Predicate; - import com.google.common.base.Predicates; - import net.minecraft.client.Minecraft; -@@ -71,6 +72,7 @@ - } - - this.setCursorPositionEnd(); -+ this.setResponderEntryValue(this.id, this.text); - } - } - -@@ -590,6 +592,7 @@ - if (this.text.length() > length) - { - this.text = this.text.substring(0, length); -+ this.setResponderEntryValue(this.id, this.text); - } - } - -@@ -603,6 +606,11 @@ - return this.cursorPosition; - } - -+ public int getLineScrollOffset() -+ { -+ return this.lineScrollOffset; -+ } -+ - public boolean getEnableBackgroundDrawing() - { - return this.enableBackgroundDrawing; -@@ -631,6 +639,7 @@ - } - - this.isFocused = isFocusedIn; -+ IMEHandler.setIME(this.isFocused); - - if (Minecraft.getMinecraft().currentScreen != null) - { diff --git a/patches/minecraft/net/minecraft/client/gui/GuiUtilRenderComponents.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiUtilRenderComponents.java.patch deleted file mode 100644 index d06777f47..000000000 --- a/patches/minecraft/net/minecraft/client/gui/GuiUtilRenderComponents.java.patch +++ /dev/null @@ -1,28 +0,0 @@ ---- before/net/minecraft/client/gui/GuiUtilRenderComponents.java -+++ after/net/minecraft/client/gui/GuiUtilRenderComponents.java -@@ -56,13 +56,14 @@ - - if (s3 != null && !s3.isEmpty()) - { -- int l = s2.lastIndexOf(32); -+ com.cleanroommc.client.ICU4JInstances.BREAK_ITERATOR.setText(s4); -+ int l = com.cleanroommc.client.ICU4JInstances.BREAK_ITERATOR.preceding(s2.length()); - - if (l >= 0 && fontRendererIn.getStringWidth(s4.substring(0, l)) > 0) - { - s2 = s4.substring(0, l); - -- if (p_178908_3_) -+ if (p_178908_3_ && s4.charAt(l) == ' ') - { - l++; - } -@@ -74,6 +75,8 @@ - s2 = ""; - s3 = s4; - } -+ -+ s3 = FontRenderer.getFormatFromString(s2) + s3; //Forge: Fix chat formatting not surviving line wrapping. - - TextComponentString textcomponentstring1 = new TextComponentString(s3); - textcomponentstring1.setStyle(itextcomponent1.getStyle().createShallowCopy()); diff --git a/patches/minecraft/net/minecraft/client/gui/GuiVideoSettings.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiVideoSettings.java.patch deleted file mode 100644 index 143b7a4a7..000000000 --- a/patches/minecraft/net/minecraft/client/gui/GuiVideoSettings.java.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- before/net/minecraft/client/gui/GuiVideoSettings.java -+++ after/net/minecraft/client/gui/GuiVideoSettings.java -@@ -146,4 +146,12 @@ - this.drawCenteredString(this.fontRenderer, this.screenTitle, this.width / 2, 5, 16777215); - super.drawScreen(mouseX, mouseY, partialTicks); - } -+ -+ // FORGE: fix for MC-64581 very laggy mipmap slider -+ @Override -+ public void onGuiClosed() -+ { -+ super.onGuiClosed(); -+ this.mc.gameSettings.onGuiClosed(); -+ } - } diff --git a/patches/minecraft/net/minecraft/client/gui/MapItemRenderer.java.patch b/patches/minecraft/net/minecraft/client/gui/MapItemRenderer.java.patch deleted file mode 100644 index e7d949988..000000000 --- a/patches/minecraft/net/minecraft/client/gui/MapItemRenderer.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/client/gui/MapItemRenderer.java -+++ after/net/minecraft/client/gui/MapItemRenderer.java -@@ -141,6 +141,8 @@ - { - if (!noOverlayRendering || mapdecoration.renderOnFrame()) - { -+ if (mapdecoration.render(k)) { k++; continue; } -+ MapItemRenderer.this.textureManager.bindTexture(MapItemRenderer.TEXTURE_MAP_ICONS); // Rebind in case custom render changes it - GlStateManager.pushMatrix(); - GlStateManager.translate(0.0F + mapdecoration.getX() / 2.0F + 64.0F, 0.0F + mapdecoration.getY() / 2.0F + 64.0F, -0.02F); - GlStateManager.rotate(mapdecoration.getRotation() * 360 / 16.0F, 0.0F, 0.0F, 1.0F); diff --git a/patches/minecraft/net/minecraft/client/gui/ScaledResolution.java.patch b/patches/minecraft/net/minecraft/client/gui/ScaledResolution.java.patch deleted file mode 100644 index ccb5e7367..000000000 --- a/patches/minecraft/net/minecraft/client/gui/ScaledResolution.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/client/gui/ScaledResolution.java -+++ after/net/minecraft/client/gui/ScaledResolution.java -@@ -34,7 +34,7 @@ - - if (flag && this.scaleFactor % 2 != 0 && this.scaleFactor != 1) - { -- this.scaleFactor--; -+ this.scaleFactor++; - } - - this.scaledWidthD = (double)this.scaledWidth / this.scaleFactor; diff --git a/patches/minecraft/net/minecraft/client/gui/ServerListEntryNormal.java.patch b/patches/minecraft/net/minecraft/client/gui/ServerListEntryNormal.java.patch deleted file mode 100644 index df53548ee..000000000 --- a/patches/minecraft/net/minecraft/client/gui/ServerListEntryNormal.java.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- before/net/minecraft/client/gui/ServerListEntryNormal.java -+++ after/net/minecraft/client/gui/ServerListEntryNormal.java -@@ -97,7 +97,7 @@ - boolean flag1 = this.server.version < 340; - boolean flag2 = flag || flag1; - this.mc.fontRenderer.drawString(this.server.serverName, x + 32 + 3, y + 1, 16777215); -- List list = this.mc.fontRenderer.listFormattedStringToWidth(this.server.serverMOTD, listWidth - 32 - 2); -+ List list = this.mc.fontRenderer.listFormattedStringToWidth(net.minecraftforge.fml.client.FMLClientHandler.instance().fixDescription(this.server.serverMOTD), listWidth - 32 - 2); - - for (int i = 0; i < Math.min(list.size(), 2); i++) - { -@@ -193,6 +193,11 @@ - int i1 = mouseX - x; - int j1 = mouseY - y; - -+ String tooltip = net.minecraftforge.fml.client.FMLClientHandler.instance().enhanceServerListEntry(this, this.server, x, listWidth, y, i1, j1); -+ if (tooltip != null) -+ { -+ this.owner.setHoveringText(tooltip); -+ } else - if (i1 >= listWidth - 15 && i1 <= listWidth - 5 && j1 >= 0 && j1 <= 8) - { - this.owner.setHoveringText(s1); diff --git a/patches/minecraft/net/minecraft/client/gui/advancements/GuiAdvancementTab.java.patch b/patches/minecraft/net/minecraft/client/gui/advancements/GuiAdvancementTab.java.patch deleted file mode 100644 index da90f0f2e..000000000 --- a/patches/minecraft/net/minecraft/client/gui/advancements/GuiAdvancementTab.java.patch +++ /dev/null @@ -1,40 +0,0 @@ ---- before/net/minecraft/client/gui/advancements/GuiAdvancementTab.java -+++ after/net/minecraft/client/gui/advancements/GuiAdvancementTab.java -@@ -37,6 +37,7 @@ - private int maxY = Integer.MIN_VALUE; - private float fade; - private boolean centered; -+ private int page; - - public GuiAdvancementTab( - Minecraft p_i47589_1_, -@@ -167,9 +168,9 @@ - { - for (AdvancementTabType advancementtabtype : AdvancementTabType.values()) - { -- if (p_193936_2_ < advancementtabtype.getMax()) -+ if ((p_193936_2_ % AdvancementTabType.MAX_TABS) < advancementtabtype.getMax()) - { -- return new GuiAdvancementTab(p_193936_0_, p_193936_1_, advancementtabtype, p_193936_2_, p_193936_3_, p_193936_3_.getDisplay()); -+ return new GuiAdvancementTab(p_193936_0_, p_193936_1_, advancementtabtype, p_193936_2_ % AdvancementTabType.MAX_TABS, p_193936_2_ / AdvancementTabType.MAX_TABS, p_193936_3_, p_193936_3_.getDisplay()); - } - - p_193936_2_ -= advancementtabtype.getMax(); -@@ -229,4 +230,17 @@ - { - return this.screen; - } -+ -+ /* ======================================== FORGE START =====================================*/ -+ public int getPage() -+ { -+ return this.page; -+ } -+ -+ public GuiAdvancementTab(Minecraft p_i47589_1_, GuiScreenAdvancements p_i47589_2_, AdvancementTabType p_i47589_3_, int p_i47589_4_, int page, Advancement p_i47589_5_, DisplayInfo p_i47589_6_) -+ { -+ this(p_i47589_1_, p_i47589_2_, p_i47589_3_, p_i47589_4_, p_i47589_5_, p_i47589_6_); -+ this.page = page; -+ } -+ /* ======================================== FORGE END =====================================*/ - } diff --git a/patches/minecraft/net/minecraft/client/gui/advancements/GuiScreenAdvancements.java.patch b/patches/minecraft/net/minecraft/client/gui/advancements/GuiScreenAdvancements.java.patch deleted file mode 100644 index 37d169a53..000000000 --- a/patches/minecraft/net/minecraft/client/gui/advancements/GuiScreenAdvancements.java.patch +++ /dev/null @@ -1,89 +0,0 @@ ---- before/net/minecraft/client/gui/advancements/GuiScreenAdvancements.java -+++ after/net/minecraft/client/gui/advancements/GuiScreenAdvancements.java -@@ -29,6 +29,7 @@ - private int scrollMouseX; - private int scrollMouseY; - private boolean isScrolling; -+ private static int tabPage, maxPages; - - public GuiScreenAdvancements(ClientAdvancementManager p_i47383_1_) - { -@@ -50,6 +51,14 @@ - { - this.clientAdvancementManager.setSelectedTab(this.selectedTab == null ? null : this.selectedTab.getAdvancement(), true); - } -+ if (this.tabs.size() > AdvancementTabType.MAX_TABS) -+ { -+ int guiLeft = (this.width - 252) / 2; -+ int guiTop = (this.height - 140) / 2; -+ this.buttonList.add(new net.minecraft.client.gui.GuiButton(101, guiLeft, guiTop - 50, 20, 20, "<")); -+ this.buttonList.add(new net.minecraft.client.gui.GuiButton(102, guiLeft + 252 - 20, guiTop - 50, 20, 20, ">")); -+ maxPages = this.tabs.size() / AdvancementTabType.MAX_TABS; -+ } - } - - @Override -@@ -74,7 +83,7 @@ - - for (GuiAdvancementTab guiadvancementtab : this.tabs.values()) - { -- if (guiadvancementtab.isMouseOver(i, j, mouseX, mouseY)) -+ if (guiadvancementtab.getPage() == tabPage && guiadvancementtab.isMouseOver(i, j, mouseX, mouseY)) - { - this.clientAdvancementManager.setSelectedTab(guiadvancementtab.getAdvancement(), true); - break; -@@ -127,6 +136,14 @@ - this.drawDefaultBackground(); - this.renderInside(mouseX, mouseY, i, j); - this.renderWindow(i, j); -+ super.drawScreen(mouseX, mouseY, partialTicks); -+ if (maxPages != 0) -+ { -+ String page = String.format("%d / %d", tabPage + 1, maxPages + 1); -+ int width = this.fontRenderer.getStringWidth(page); -+ GlStateManager.disableLighting(); -+ this.fontRenderer.drawStringWithShadow(page, i + (252 / 2) - (width / 2), j - 44, -1); -+ } - this.renderToolTips(mouseX, mouseY, i, j); - } - -@@ -171,6 +188,7 @@ - - for (GuiAdvancementTab guiadvancementtab : this.tabs.values()) - { -+ if(guiadvancementtab.getPage() == tabPage) - guiadvancementtab.drawTab(p_191934_1_, p_191934_2_, guiadvancementtab == this.selectedTab); - } - -@@ -185,6 +203,7 @@ - - for (GuiAdvancementTab guiadvancementtab1 : this.tabs.values()) - { -+ if(guiadvancementtab1.getPage() == tabPage) - guiadvancementtab1.drawIcon(p_191934_1_, p_191934_2_, this.itemRender); - } - -@@ -212,7 +231,7 @@ - { - for (GuiAdvancementTab guiadvancementtab : this.tabs.values()) - { -- if (guiadvancementtab.isMouseOver(p_191937_3_, p_191937_4_, p_191937_1_, p_191937_2_)) -+ if (guiadvancementtab.getPage() == tabPage && guiadvancementtab.isMouseOver(p_191937_3_, p_191937_4_, p_191937_1_, p_191937_2_)) - { - this.drawHoveringText(guiadvancementtab.getTitle(), p_191937_1_, p_191937_2_); - } -@@ -292,5 +311,14 @@ - } - - return this.tabs.get(p_191935_1_); -+ } -+ -+ @Override -+ protected void actionPerformed(net.minecraft.client.gui.GuiButton button) throws IOException -+ { -+ if(button.id == 101) -+ tabPage = Math.max(tabPage - 1, 0); -+ else if(button.id == 102) -+ tabPage = Math.min(tabPage + 1, maxPages); - } - } diff --git a/patches/minecraft/net/minecraft/client/gui/inventory/GuiContainer.java.patch b/patches/minecraft/net/minecraft/client/gui/inventory/GuiContainer.java.patch deleted file mode 100644 index a380caf72..000000000 --- a/patches/minecraft/net/minecraft/client/gui/inventory/GuiContainer.java.patch +++ /dev/null @@ -1,157 +0,0 @@ ---- before/net/minecraft/client/gui/inventory/GuiContainer.java -+++ after/net/minecraft/client/gui/inventory/GuiContainer.java -@@ -118,6 +118,7 @@ - RenderHelper.disableStandardItemLighting(); - this.drawGuiContainerForegroundLayer(mouseX, mouseY); - RenderHelper.enableGUIStandardItemLighting(); -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.GuiContainerEvent.DrawForeground(this, mouseX, mouseY)); - InventoryPlayer inventoryplayer = this.mc.player.inventory; - ItemStack itemstack = this.draggedStack.isEmpty() ? inventoryplayer.getItemStack() : this.draggedStack; - -@@ -182,9 +183,11 @@ - GlStateManager.translate(0.0F, 0.0F, 32.0F); - this.zLevel = 200.0F; - this.itemRender.zLevel = 200.0F; -+ net.minecraft.client.gui.FontRenderer font = stack.getItem().getFontRenderer(stack); -+ if (font == null) font = fontRenderer; - this.itemRender.renderItemAndEffectIntoGUI(stack, x, y); - this.itemRender -- .renderItemOverlayIntoGUI(this.fontRenderer, stack, x, y - (this.draggedStack.isEmpty() ? 0 : 8), altText); -+ .renderItemOverlayIntoGUI(font, stack, x, y - (this.draggedStack.isEmpty() ? 0 : 8), altText); - this.zLevel = 0.0F; - this.itemRender.zLevel = 0.0F; - } -@@ -244,13 +247,12 @@ - - if (itemstack.isEmpty() && slotIn.isEnabled()) - { -- String s1 = slotIn.getSlotTexture(); -+ TextureAtlasSprite textureatlassprite = slotIn.getBackgroundSprite(); - -- if (s1 != null) -+ if (textureatlassprite != null) - { -- TextureAtlasSprite textureatlassprite = this.mc.getTextureMapBlocks().getAtlasSprite(s1); - GlStateManager.disableLighting(); -- this.mc.getTextureManager().bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); -+ this.mc.getTextureManager().bindTexture(slotIn.getBackgroundLocation()); - this.drawTexturedModalRect(i, j, textureatlassprite, 16, 16); - GlStateManager.enableLighting(); - flag1 = true; -@@ -325,7 +327,7 @@ - protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException - { - super.mouseClicked(mouseX, mouseY, mouseButton); -- boolean flag = mouseButton == this.mc.gameSettings.keyBindPickBlock.getKeyCode() + 100; -+ boolean flag = this.mc.gameSettings.keyBindPickBlock.isActiveAndMatches(mouseButton - 100); - Slot slot = this.getSlotAtPosition(mouseX, mouseY); - long i = Minecraft.getSystemTime(); - this.doubleClick = this.lastClickSlot == slot && i - this.lastClickTime < 250L && this.lastClickButton == mouseButton; -@@ -336,6 +338,7 @@ - int j = this.guiLeft; - int k = this.guiTop; - boolean flag1 = this.hasClickedOutside(mouseX, mouseY, j, k); -+ if (slot != null) flag1 = false; // Forge, prevent dropping of items through slots outside of GUI boundaries - int l = -1; - - if (slot != null) -@@ -373,7 +376,7 @@ - { - if (this.mc.player.inventory.getItemStack().isEmpty()) - { -- if (mouseButton == this.mc.gameSettings.keyBindPickBlock.getKeyCode() + 100) -+ if (this.mc.gameSettings.keyBindPickBlock.isActiveAndMatches(mouseButton - 100)) - { - this.handleMouseClick(slot, l, mouseButton, ClickType.CLONE); - } -@@ -411,7 +414,7 @@ - { - this.dragSplittingLimit = 1; - } -- else if (mouseButton == this.mc.gameSettings.keyBindPickBlock.getKeyCode() + 100) -+ else if (this.mc.gameSettings.keyBindPickBlock.isActiveAndMatches(mouseButton - 100)) - { - this.dragSplittingLimit = 2; - } -@@ -489,10 +492,12 @@ - @Override - protected void mouseReleased(int mouseX, int mouseY, int state) - { -+ super.mouseReleased(mouseX, mouseY, state); //Forge, Call parent to release buttons - Slot slot = this.getSlotAtPosition(mouseX, mouseY); - int i = this.guiLeft; - int j = this.guiTop; - boolean flag = this.hasClickedOutside(mouseX, mouseY, i, j); -+ if (slot != null) flag = false; // Forge, prevent dropping of items through slots outside of GUI boundaries - int k = -1; - - if (slot != null) -@@ -516,7 +521,7 @@ - if (slot2 != null - && slot2.canTakeStack(this.mc.player) - && slot2.getHasStack() -- && slot2.inventory == slot.inventory -+ && slot2.isSameInventory(slot) - && Container.canAddItemToSlot(slot2, this.shiftClickedSlot, true)) - { - this.handleMouseClick(slot2, slot2.slotNumber, state, ClickType.QUICK_MOVE); -@@ -604,7 +609,7 @@ - } - else if (!this.mc.player.inventory.getItemStack().isEmpty()) - { -- if (state == this.mc.gameSettings.keyBindPickBlock.getKeyCode() + 100) -+ if (this.mc.gameSettings.keyBindPickBlock.isActiveAndMatches(state - 100)) - { - this.handleMouseClick(slot, k, state, ClickType.CLONE); - } -@@ -662,7 +667,7 @@ - @Override - protected void keyTyped(char typedChar, int keyCode) throws IOException - { -- if (keyCode == 1 || keyCode == this.mc.gameSettings.keyBindInventory.getKeyCode()) -+ if (keyCode == 1 || this.mc.gameSettings.keyBindInventory.isActiveAndMatches(keyCode)) - { - this.mc.player.closeScreen(); - } -@@ -671,11 +676,11 @@ - - if (this.hoveredSlot != null && this.hoveredSlot.getHasStack()) - { -- if (keyCode == this.mc.gameSettings.keyBindPickBlock.getKeyCode()) -+ if (this.mc.gameSettings.keyBindPickBlock.isActiveAndMatches(keyCode)) - { - this.handleMouseClick(this.hoveredSlot, this.hoveredSlot.slotNumber, 0, ClickType.CLONE); - } -- else if (keyCode == this.mc.gameSettings.keyBindDrop.getKeyCode()) -+ else if (this.mc.gameSettings.keyBindDrop.isActiveAndMatches(keyCode)) - { - this.handleMouseClick(this.hoveredSlot, this.hoveredSlot.slotNumber, isCtrlKeyDown() ? 1 : 0, ClickType.THROW); - } -@@ -688,7 +693,7 @@ - { - for (int i = 0; i < 9; i++) - { -- if (keyCode == this.mc.gameSettings.keyBindsHotbar[i].getKeyCode()) -+ if (this.mc.gameSettings.keyBindsHotbar[i].isActiveAndMatches(keyCode)) - { - this.handleMouseClick(this.hoveredSlot, this.hoveredSlot.slotNumber, i, ClickType.SWAP); - return true; -@@ -724,4 +729,18 @@ - this.mc.player.closeScreen(); - } - } -+ -+ /* ======================================== FORGE START =====================================*/ -+ -+ /** -+ * Returns the slot that is currently displayed under the mouse. -+ */ -+ @javax.annotation.Nullable -+ public Slot getSlotUnderMouse() { return this.hoveredSlot; } -+ public int getGuiLeft() { return guiLeft; } -+ public int getGuiTop() { return guiTop; } -+ public int getXSize() { return xSize; } -+ public int getYSize() { return ySize; } -+ -+ /* ======================================== FORGE END =====================================*/ - } diff --git a/patches/minecraft/net/minecraft/client/gui/inventory/GuiContainerCreative.java.patch b/patches/minecraft/net/minecraft/client/gui/inventory/GuiContainerCreative.java.patch deleted file mode 100644 index ff08abb6c..000000000 --- a/patches/minecraft/net/minecraft/client/gui/inventory/GuiContainerCreative.java.patch +++ /dev/null @@ -1,325 +0,0 @@ ---- before/net/minecraft/client/gui/inventory/GuiContainerCreative.java -+++ after/net/minecraft/client/gui/inventory/GuiContainerCreative.java -@@ -57,6 +57,8 @@ - private Slot destroyItemSlot; - private boolean clearSearch; - private CreativeCrafting listener; -+ private static int tabPage = 0; -+ private int maxPages = 0; - - public GuiContainerCreative(EntityPlayer player) - { -@@ -305,6 +307,13 @@ - this.setCurrentCreativeTab(CreativeTabs.CREATIVE_TAB_ARRAY[i]); - this.listener = new CreativeCrafting(this.mc); - this.mc.player.inventoryContainer.addListener(this.listener); -+ int tabCount = CreativeTabs.CREATIVE_TAB_ARRAY.length; -+ if (tabCount > 12) -+ { -+ buttonList.add(new GuiButton(101, guiLeft, guiTop - 50, 20, 20, "<")); -+ buttonList.add(new GuiButton(102, guiLeft + xSize - 20, guiTop - 50, 20, 20, ">")); -+ maxPages = (int) Math.ceil((tabCount - 12) / 10D); -+ } - } - else - { -@@ -328,7 +337,7 @@ - @Override - protected void keyTyped(char typedChar, int keyCode) throws IOException - { -- if (selectedTabIndex != CreativeTabs.SEARCH.getIndex()) -+ if (!CreativeTabs.CREATIVE_TAB_ARRAY[selectedTabIndex].hasSearchBar()) - { - if (GameSettings.isKeyDown(this.mc.gameSettings.keyBindChat)) - { -@@ -366,6 +375,34 @@ - GuiContainerCreative.ContainerCreative guicontainercreative$containercreative = (GuiContainerCreative.ContainerCreative)this.inventorySlots; - guicontainercreative$containercreative.itemList.clear(); - -+ CreativeTabs tab = CreativeTabs.CREATIVE_TAB_ARRAY[selectedTabIndex]; -+ if (tab.hasSearchBar() && tab != CreativeTabs.SEARCH) -+ { -+ tab.displayAllRelevantItems(guicontainercreative$containercreative.itemList); -+ if (!this.searchField.getText().isEmpty()) -+ { -+ //TODO: Make this a SearchTree not a manual search -+ String search = this.searchField.getText().toLowerCase(Locale.ROOT); -+ java.util.Iterator itr = guicontainercreative$containercreative.itemList.iterator(); -+ while (itr.hasNext()) { -+ ItemStack stack = itr.next(); -+ boolean matches = false; -+ for (String line : stack.getTooltip(this.mc.player, this.mc.gameSettings.advancedItemTooltips ? ITooltipFlag.TooltipFlags.ADVANCED : ITooltipFlag.TooltipFlags.NORMAL)) -+ { -+ if (TextFormatting.getTextWithoutFormattingCodes(line).toLowerCase(Locale.ROOT).contains(search)) { -+ matches = true; -+ break; -+ } -+ } -+ if (!matches) -+ itr.remove(); -+ } -+ } -+ this.currentScroll = 0.0F; -+ guicontainercreative$containercreative.scrollTo(0.0F); -+ return; -+ } -+ - if (this.searchField.getText().isEmpty()) - { - for (Item item : Item.REGISTRY) -@@ -390,10 +427,10 @@ - { - CreativeTabs creativetabs = CreativeTabs.CREATIVE_TAB_ARRAY[selectedTabIndex]; - -- if (creativetabs.drawInForegroundOfTab()) -+ if (creativetabs != null && creativetabs.drawInForegroundOfTab()) - { - GlStateManager.disableBlend(); -- this.fontRenderer.drawString(I18n.format(creativetabs.getTranslationKey()), 8, 6, 4210752); -+ this.fontRenderer.drawString(I18n.format(creativetabs.getTranslationKey()), 8, 6, creativetabs.getLabelColor()); - } - } - -@@ -427,7 +464,7 @@ - - for (CreativeTabs creativetabs : CreativeTabs.CREATIVE_TAB_ARRAY) - { -- if (this.isMouseOverTab(creativetabs, i, j)) -+ if (creativetabs != null && this.isMouseOverTab(creativetabs, i, j)) - { - this.setCurrentCreativeTab(creativetabs); - return; -@@ -440,6 +477,7 @@ - - private boolean needsScrollBars() - { -+ if (CreativeTabs.CREATIVE_TAB_ARRAY[selectedTabIndex] == null) return false; - return selectedTabIndex != CreativeTabs.INVENTORY.getIndex() - && CreativeTabs.CREATIVE_TAB_ARRAY[selectedTabIndex].hasScrollbar() - && ((GuiContainerCreative.ContainerCreative)this.inventorySlots).canScroll(); -@@ -447,6 +485,7 @@ - - private void setCurrentCreativeTab(CreativeTabs tab) - { -+ if (tab == null) return; - int i = selectedTabIndex; - selectedTabIndex = tab.getIndex(); - GuiContainerCreative.ContainerCreative guicontainercreative$containercreative = (GuiContainerCreative.ContainerCreative)this.inventorySlots; -@@ -552,12 +591,14 @@ - - if (this.searchField != null) - { -- if (tab == CreativeTabs.SEARCH) -+ if (tab.hasSearchBar()) - { - this.searchField.setVisible(true); - this.searchField.setCanLoseFocus(false); - this.searchField.setFocused(true); - this.searchField.setText(""); -+ this.searchField.width = tab.getSearchbarWidth(); -+ this.searchField.x = this.guiLeft + (82 /*default left*/ + 89 /*default width*/) - this.searchField.width; - this.updateCreativeSearch(); - } - else -@@ -631,14 +672,26 @@ - - super.drawScreen(mouseX, mouseY, partialTicks); - -- for (CreativeTabs creativetabs : CreativeTabs.CREATIVE_TAB_ARRAY) -+ int start = tabPage * 10; -+ int end = Math.min(CreativeTabs.CREATIVE_TAB_ARRAY.length, ((tabPage + 1) * 10) + 2); -+ if (tabPage != 0) start += 2; -+ boolean rendered = false; -+ -+ for (CreativeTabs creativetabs : java.util.Arrays.copyOfRange(CreativeTabs.CREATIVE_TAB_ARRAY,start,end)) - { -+ if (creativetabs == null) continue; - if (this.renderCreativeInventoryHoveringText(creativetabs, mouseX, mouseY)) - { -+ rendered = true; - break; - } - } - -+ if (!rendered && !renderCreativeInventoryHoveringText(CreativeTabs.SEARCH, mouseX, mouseY)) -+ { -+ renderCreativeInventoryHoveringText(CreativeTabs.INVENTORY, mouseX, mouseY); -+ } -+ - if (this.destroyItemSlot != null - && selectedTabIndex == CreativeTabs.INVENTORY.getIndex() - && this.isPointInRegion(this.destroyItemSlot.xPos, this.destroyItemSlot.yPos, 16, 16, mouseX, mouseY)) -@@ -646,6 +699,18 @@ - this.drawHoveringText(I18n.format("inventory.binSlot"), mouseX, mouseY); - } - -+ if (maxPages != 0) -+ { -+ String page = String.format("%d / %d", tabPage + 1, maxPages + 1); -+ int width = fontRenderer.getStringWidth(page); -+ GlStateManager.disableLighting(); -+ this.zLevel = 300.0F; -+ itemRender.zLevel = 300.0F; -+ fontRenderer.drawString(page, guiLeft + (xSize / 2) - (width / 2), guiTop - 44, -1); -+ this.zLevel = 0.0F; -+ itemRender.zLevel = 0.0F; -+ } -+ - GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); - GlStateManager.disableLighting(); - this.renderHoveredToolTip(mouseX, mouseY); -@@ -690,7 +755,7 @@ - { - if (i == 0) - { -- list.set(i, stack.getRarity().color + list.get(i)); -+ list.set(i, stack.getItem().getForgeRarity(stack).getColor() + list.get(i)); - } - else - { -@@ -698,7 +763,10 @@ - } - } - -- this.drawHoveringText(list, x, y); -+ net.minecraft.client.gui.FontRenderer font = stack.getItem().getFontRenderer(stack); -+ net.minecraftforge.fml.client.config.GuiUtils.preItemToolTip(stack); -+ this.drawHoveringText(list, x, y, (font == null ? fontRenderer : font)); -+ net.minecraftforge.fml.client.config.GuiUtils.postItemToolTip(); - } - else - { -@@ -713,17 +781,36 @@ - RenderHelper.enableGUIStandardItemLighting(); - CreativeTabs creativetabs = CreativeTabs.CREATIVE_TAB_ARRAY[selectedTabIndex]; - -- for (CreativeTabs creativetabs1 : CreativeTabs.CREATIVE_TAB_ARRAY) -+ int start = tabPage * 10; -+ int end = Math.min(CreativeTabs.CREATIVE_TAB_ARRAY.length, ((tabPage + 1) * 10 + 2)); -+ if (tabPage != 0) start += 2; -+ -+ for (CreativeTabs creativetabs1 : java.util.Arrays.copyOfRange(CreativeTabs.CREATIVE_TAB_ARRAY,start,end)) - { - this.mc.getTextureManager().bindTexture(CREATIVE_INVENTORY_TABS); - -+ if (creativetabs1 == null) continue; - if (creativetabs1.getIndex() != selectedTabIndex) - { - this.drawTab(creativetabs1); - } - } - -- this.mc.getTextureManager().bindTexture(new ResourceLocation("textures/gui/container/creative_inventory/tab_" + creativetabs.getBackgroundImageName())); -+ if (tabPage != 0) -+ { -+ if (creativetabs != CreativeTabs.SEARCH) -+ { -+ this.mc.getTextureManager().bindTexture(CREATIVE_INVENTORY_TABS); -+ drawTab(CreativeTabs.SEARCH); -+ } -+ if (creativetabs != CreativeTabs.INVENTORY) -+ { -+ this.mc.getTextureManager().bindTexture(CREATIVE_INVENTORY_TABS); -+ drawTab(CreativeTabs.INVENTORY); -+ } -+ } -+ -+ this.mc.getTextureManager().bindTexture(creativetabs.getBackgroundImage()); - this.drawTexturedModalRect(this.guiLeft, this.guiTop, 0, 0, this.xSize, this.ySize); - this.searchField.drawTextBox(); - GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); -@@ -737,6 +824,14 @@ - this.drawTexturedModalRect(i, j + (int)((k - j - 17) * this.currentScroll), 232 + (this.needsScrollBars() ? 0 : 12), 0, 12, 15); - } - -+ if (creativetabs == null || creativetabs.getTabPage() != tabPage) -+ { -+ if (creativetabs != CreativeTabs.SEARCH && creativetabs != CreativeTabs.INVENTORY) -+ { -+ return; -+ } -+ } -+ - this.drawTab(creativetabs); - - if (creativetabs == CreativeTabs.INVENTORY) -@@ -754,6 +849,14 @@ - - protected boolean isMouseOverTab(CreativeTabs tab, int mouseX, int mouseY) - { -+ if (tab.getTabPage() != tabPage) -+ { -+ if (tab != CreativeTabs.SEARCH && tab != CreativeTabs.INVENTORY) -+ { -+ return false; -+ } -+ } -+ - int i = tab.getColumn(); - int j = 28 * i; - int k = 0; -@@ -850,6 +953,8 @@ - } - - GlStateManager.disableLighting(); -+ GlStateManager.color(1F, 1F, 1F); //Forge: Reset color in case Items change it. -+ GlStateManager.enableBlend(); //Forge: Make sure blend is enabled else tabs show a white border. - this.drawTexturedModalRect(l, i1, j, k, 28, 32); - this.zLevel = 100.0F; - this.itemRender.zLevel = 100.0F; -@@ -872,6 +977,15 @@ - { - this.mc.displayGuiScreen(new GuiStats(this, this.mc.player.getStatFileWriter())); - } -+ -+ if (button.id == 101) -+ { -+ tabPage = Math.max(tabPage - 1, 0); -+ } -+ else if (button.id == 102) -+ { -+ tabPage = Math.min(tabPage + 1, maxPages); -+ } - } - - public int getSelectedTabIndex() -@@ -1093,6 +1207,39 @@ - { - return this.slot.canTakeStack(playerIn); - } -+ -+ /*========================================= FORGE START =====================================*/ -+ public net.minecraft.util.ResourceLocation getBackgroundLocation() -+ { -+ return this.slot.getBackgroundLocation(); -+ } -+ -+ public void setBackgroundLocation(net.minecraft.util.ResourceLocation texture) -+ { -+ this.slot.setBackgroundLocation(texture); -+ } -+ -+ public void setBackgroundName(@Nullable String name) -+ { -+ this.slot.setBackgroundName(name); -+ } -+ -+ @Nullable -+ public net.minecraft.client.renderer.texture.TextureAtlasSprite getBackgroundSprite() -+ { -+ return this.slot.getBackgroundSprite(); -+ } -+ -+ public int getSlotIndex() -+ { -+ return this.slot.getSlotIndex(); -+ } -+ -+ public boolean isSameInventory(Slot other) -+ { -+ return this.slot.isSameInventory(other); -+ } -+ /*========================================= FORGE END =====================================*/ - } - - @SideOnly(Side.CLIENT) diff --git a/patches/minecraft/net/minecraft/client/gui/inventory/GuiEditCommandBlockMinecart.java.patch b/patches/minecraft/net/minecraft/client/gui/inventory/GuiEditCommandBlockMinecart.java.patch deleted file mode 100644 index eccb241dd..000000000 --- a/patches/minecraft/net/minecraft/client/gui/inventory/GuiEditCommandBlockMinecart.java.patch +++ /dev/null @@ -1,170 +0,0 @@ ---- before/net/minecraft/client/gui/inventory/GuiEditCommandBlockMinecart.java -+++ after/net/minecraft/client/gui/inventory/GuiEditCommandBlockMinecart.java -@@ -21,6 +21,8 @@ - public class GuiEditCommandBlockMinecart extends GuiScreen implements ITabCompleter - { - private GuiTextField commandField; -+ private com.cleanroommc.client.chat.suggestion.SuggestionList suggestionList; -+ private com.cleanroommc.client.chat.suggestion.SuggestionUpdater suggestionUpdater; - private GuiTextField previousEdit; - private final CommandBlockBaseLogic commandBlockLogic; - private GuiButton doneButton; -@@ -72,6 +74,10 @@ - return GuiEditCommandBlockMinecart.this.commandBlockLogic.getPosition(); - } - }; -+ // Cleanroom: modern dropdown completion, in command-block mode (suggest with or without a leading "/") -+ this.suggestionList = new com.cleanroommc.client.chat.suggestion.SuggestionList(this.commandField, true); -+ this.suggestionUpdater = new com.cleanroommc.client.chat.suggestion.SuggestionUpdater(this.suggestionList, this.tabCompleter, this.commandField, true); -+ this.commandField.setGuiResponder(this.suggestionUpdater); - } - - @Override -@@ -121,6 +127,18 @@ - - if (keyCode == 15) - { -+ // Cleanroom: Tab applies the selected/first suggestion while the dropdown is open -+ if (this.suggestionList.isVisible()) -+ { -+ String selected = this.suggestionList.getSelected(); -+ if (selected == null) -+ { -+ selected = this.suggestionList.getFirst(); -+ } -+ this.suggestionList.applySuggestion(this.commandField, selected); -+ this.doneButton.enabled = !this.commandField.getText().trim().isEmpty(); -+ return; -+ } - this.tabCompleter.complete(); - } - else -@@ -128,26 +146,93 @@ - this.tabCompleter.resetDidComplete(); - } - -+ // Cleanroom: reroute navigation/confirm keys to the dropdown while it is visible -+ if (keyCode == 1) -+ { -+ if (this.suggestionList.isVisible()) -+ { -+ this.suggestionList.hide(); -+ return; -+ } -+ this.actionPerformed(this.cancelButton); -+ return; -+ } -+ else if (keyCode == 28 || keyCode == 156) -+ { -+ String selected = this.suggestionList.getSelected(); -+ if (selected != null) -+ { -+ this.suggestionList.applySuggestion(this.commandField, selected); -+ this.doneButton.enabled = !this.commandField.getText().trim().isEmpty(); -+ return; -+ } -+ this.actionPerformed(this.doneButton); -+ return; -+ } -+ else if (keyCode == 200) -+ { -+ if (this.suggestionList.isVisible()) -+ { -+ // Cleanroom: list grows upward, so Up moves to the next (visually higher) suggestion -+ this.suggestionList.selectNext(); -+ return; -+ } -+ } -+ else if (keyCode == 208) -+ { -+ if (this.suggestionList.isVisible()) -+ { -+ this.suggestionList.selectPrev(); -+ return; -+ } -+ } -+ - this.commandField.textboxKeyTyped(typedChar, keyCode); - this.previousEdit.textboxKeyTyped(typedChar, keyCode); - this.doneButton.enabled = !this.commandField.getText().trim().isEmpty(); -+ // Cleanroom: cursor-move keys change the cursor without firing the GuiResponder - refresh here -+ this.suggestionUpdater.refresh(); -+ } - -- if (keyCode == 28 || keyCode == 156) -- { -- this.actionPerformed(this.doneButton); -- } -- else if (keyCode == 1) -- { -- this.actionPerformed(this.cancelButton); -+ @Override -+ public void handleMouseInput() throws IOException -+ { -+ super.handleMouseInput(); -+ // Cleanroom: scroll the suggestion dropdown with the mouse wheel while hovering it -+ if (this.suggestionList.isVisible()) -+ { -+ int wheel = org.lwjgl.input.Mouse.getEventDWheel(); -+ if (wheel != 0) -+ { -+ int mouseX = org.lwjgl.input.Mouse.getEventX() * this.width / this.mc.displayWidth; -+ int mouseY = this.height - org.lwjgl.input.Mouse.getEventY() * this.height / this.mc.displayHeight - 1; -+ if (this.suggestionList.isMouseOver(mouseX, mouseY)) -+ { -+ this.suggestionList.scroll(wheel); -+ } -+ } - } - } - - @Override - protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException - { -+ if (mouseButton == 0) -+ { -+ // Cleanroom: clicking a suggestion applies it -+ String clicked = this.suggestionList.mouseClicked(mouseX, mouseY); -+ if (clicked != null) -+ { -+ this.suggestionList.applySuggestion(this.commandField, clicked); -+ this.doneButton.enabled = !this.commandField.getText().trim().isEmpty(); -+ return; -+ } -+ } - super.mouseClicked(mouseX, mouseY, mouseButton); - this.commandField.mouseClicked(mouseX, mouseY, mouseButton); - this.previousEdit.mouseClicked(mouseX, mouseY, mouseButton); -+ // Cleanroom: click repositions the cursor without firing the GuiResponder - refresh to follow it -+ this.suggestionUpdater.refresh(); - } - - @Override -@@ -156,7 +241,9 @@ - this.drawDefaultBackground(); - this.drawCenteredString(this.fontRenderer, I18n.format("advMode.setCommand"), this.width / 2, 20, 16777215); - this.drawString(this.fontRenderer, I18n.format("advMode.command"), this.width / 2 - 150, 40, 10526880); -+ this.suggestionList.drawGhostText(this.commandField, this.fontRenderer); - this.commandField.drawTextBox(); -+ this.suggestionList.drawCommandColor(this.commandField, this.fontRenderer); - int i = 75; - int j = 0; - this.drawString( -@@ -182,6 +269,7 @@ - this.previousEdit.drawTextBox(); - } - -+ this.suggestionList.render(mouseX, mouseY); - super.drawScreen(mouseX, mouseY, partialTicks); - } - -@@ -207,5 +295,9 @@ - public void setCompletions(String... newCompletions) - { - this.tabCompleter.setCompletions(newCompletions); -+ // Cleanroom: one reply consumes the Tab request, or every auto-suggest reply would keep mutating the field -+ this.tabCompleter.resetRequested(); -+ // Cleanroom: route through the updater so stale async replies can be validated against the current prefix -+ this.suggestionUpdater.onServerCompletions(newCompletions); - } - } diff --git a/patches/minecraft/net/minecraft/client/gui/recipebook/GuiRecipeBook.java.patch b/patches/minecraft/net/minecraft/client/gui/recipebook/GuiRecipeBook.java.patch deleted file mode 100644 index 88e1d710c..000000000 --- a/patches/minecraft/net/minecraft/client/gui/recipebook/GuiRecipeBook.java.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- before/net/minecraft/client/gui/recipebook/GuiRecipeBook.java -+++ after/net/minecraft/client/gui/recipebook/GuiRecipeBook.java -@@ -450,7 +450,7 @@ - - languagemanager.setCurrentLanguage(language); - this.mc.gameSettings.language = language.getLanguageCode(); -- this.mc.refreshResources(); -+ net.minecraftforge.fml.client.FMLClientHandler.instance().refreshResources(net.minecraftforge.client.resource.VanillaResourceType.LANGUAGES); - this.mc - .fontRenderer - .setUnicodeFlag(this.mc.getLanguageManager().isCurrentLocaleUnicode() || this.mc.gameSettings.forceUnicodeFont); -@@ -490,7 +490,7 @@ - this.ghostRecipe.addIngredient(Ingredient.fromStacks(itemstack), p_193951_2_.get(0).xPos, p_193951_2_.get(0).yPos); - int i = this.craftingSlots.getWidth(); - int j = this.craftingSlots.getHeight(); -- int k = p_193951_1_ instanceof ShapedRecipes ? ((ShapedRecipes)p_193951_1_).getWidth() : i; -+ int k = p_193951_1_ instanceof net.minecraftforge.common.crafting.IShapedRecipe ? ((net.minecraftforge.common.crafting.IShapedRecipe)p_193951_1_).getRecipeWidth() : i; - int l = 1; - Iterator iterator = p_193951_1_.getIngredients().iterator(); - -@@ -505,7 +505,7 @@ - - Ingredient ingredient = iterator.next(); - -- if (ingredient != Ingredient.EMPTY) -+ if (ingredient.getMatchingStacks().length > 0) - { - Slot slot = p_193951_2_.get(l); - this.ghostRecipe.addIngredient(ingredient, slot.xPos, slot.yPos); diff --git a/patches/minecraft/net/minecraft/client/gui/recipebook/GuiRecipeOverlay.java.patch b/patches/minecraft/net/minecraft/client/gui/recipebook/GuiRecipeOverlay.java.patch deleted file mode 100644 index f45c6db0d..000000000 --- a/patches/minecraft/net/minecraft/client/gui/recipebook/GuiRecipeOverlay.java.patch +++ /dev/null @@ -1,18 +0,0 @@ ---- before/net/minecraft/client/gui/recipebook/GuiRecipeOverlay.java -+++ after/net/minecraft/client/gui/recipebook/GuiRecipeOverlay.java -@@ -338,11 +338,11 @@ - int k = 3; - int l = 3; - -- if (this.recipe instanceof ShapedRecipes) -+ if (this.recipe instanceof net.minecraftforge.common.crafting.IShapedRecipe) - { -- ShapedRecipes shapedrecipes = (ShapedRecipes)this.recipe; -- k = shapedrecipes.getWidth(); -- l = shapedrecipes.getHeight(); -+ net.minecraftforge.common.crafting.IShapedRecipe shapedrecipes = (net.minecraftforge.common.crafting.IShapedRecipe)this.recipe; -+ k = shapedrecipes.getRecipeWidth(); -+ l = shapedrecipes.getRecipeHeight(); - } - - Iterator iterator = this.recipe.getIngredients().iterator(); diff --git a/patches/minecraft/net/minecraft/client/gui/toasts/RecipeToast.java.patch b/patches/minecraft/net/minecraft/client/gui/toasts/RecipeToast.java.patch deleted file mode 100644 index e41271baa..000000000 --- a/patches/minecraft/net/minecraft/client/gui/toasts/RecipeToast.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/client/gui/toasts/RecipeToast.java -+++ after/net/minecraft/client/gui/toasts/RecipeToast.java -@@ -45,7 +45,7 @@ - RenderHelper.enableGUIStandardItemLighting(); - toastGui.getMinecraft() - .getRenderItem() -- .renderItemAndEffectIntoGUI(null, this.recipesOutputs.get((int)(delta / (5000L / this.recipesOutputs.size()) % this.recipesOutputs.size())), 8, 8); -+ .renderItemAndEffectIntoGUI(null, this.recipesOutputs.get((int)(delta * this.recipesOutputs.size() / 5000L % this.recipesOutputs.size())), 8, 8); //Forge: fix math so that it doesn't divide by 0 when there are more than 5000 recipes - return delta - this.firstDrawTime >= 5000L ? IToast.Visibility.HIDE : IToast.Visibility.SHOW; - } - } diff --git a/patches/minecraft/net/minecraft/client/model/ModelBase.java.patch b/patches/minecraft/net/minecraft/client/model/ModelBase.java.patch deleted file mode 100644 index be654473d..000000000 --- a/patches/minecraft/net/minecraft/client/model/ModelBase.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- before/net/minecraft/client/model/ModelBase.java -+++ after/net/minecraft/client/model/ModelBase.java -@@ -10,7 +10,6 @@ - import net.minecraftforge.fml.relauncher.Side; - import net.minecraftforge.fml.relauncher.SideOnly; - --@SideOnly(Side.CLIENT) - public abstract class ModelBase - { - public float swingProgress; diff --git a/patches/minecraft/net/minecraft/client/model/ModelBox.java.patch b/patches/minecraft/net/minecraft/client/model/ModelBox.java.patch deleted file mode 100644 index e3f3d516b..000000000 --- a/patches/minecraft/net/minecraft/client/model/ModelBox.java.patch +++ /dev/null @@ -1,18 +0,0 @@ ---- before/net/minecraft/client/model/ModelBox.java -+++ after/net/minecraft/client/model/ModelBox.java -@@ -4,7 +4,6 @@ - import net.minecraftforge.fml.relauncher.Side; - import net.minecraftforge.fml.relauncher.SideOnly; - --@SideOnly(Side.CLIENT) - public class ModelBox - { - private final PositionTextureVertex[] vertexPositions; -@@ -164,6 +163,7 @@ - } - } - -+ @SideOnly(Side.CLIENT) - public void render(BufferBuilder renderer, float scale) - { - for (TexturedQuad texturedquad : this.quadList) diff --git a/patches/minecraft/net/minecraft/client/model/ModelRenderer.java.patch b/patches/minecraft/net/minecraft/client/model/ModelRenderer.java.patch deleted file mode 100644 index fd87e7f4e..000000000 --- a/patches/minecraft/net/minecraft/client/model/ModelRenderer.java.patch +++ /dev/null @@ -1,42 +0,0 @@ ---- before/net/minecraft/client/model/ModelRenderer.java -+++ after/net/minecraft/client/model/ModelRenderer.java -@@ -9,7 +9,6 @@ - import net.minecraftforge.fml.relauncher.Side; - import net.minecraftforge.fml.relauncher.SideOnly; - --@SideOnly(Side.CLIENT) - public class ModelRenderer - { - public float textureWidth = 64.0F; -@@ -117,6 +116,7 @@ - this.rotationPointZ = rotationPointZIn; - } - -+ @SideOnly(Side.CLIENT) - public void render(float scale) - { - if (!this.isHidden) -@@ -195,6 +195,7 @@ - } - } - -+ @SideOnly(Side.CLIENT) - public void renderWithRotation(float scale) - { - if (!this.isHidden) -@@ -230,6 +231,7 @@ - } - } - -+ @SideOnly(Side.CLIENT) - public void postRender(float scale) - { - if (!this.isHidden) -@@ -268,6 +270,7 @@ - } - } - -+ @SideOnly(Side.CLIENT) - private void compileDisplayList(float scale) - { - this.displayList = GLAllocation.generateDisplayLists(1); diff --git a/patches/minecraft/net/minecraft/client/model/ModelSkeleton.java.patch b/patches/minecraft/net/minecraft/client/model/ModelSkeleton.java.patch deleted file mode 100644 index 27f4b9619..000000000 --- a/patches/minecraft/net/minecraft/client/model/ModelSkeleton.java.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- before/net/minecraft/client/model/ModelSkeleton.java -+++ after/net/minecraft/client/model/ModelSkeleton.java -@@ -49,7 +49,7 @@ - this.leftArmPose = ModelBiped.ArmPose.EMPTY; - ItemStack itemstack = entitylivingbaseIn.getHeldItem(EnumHand.MAIN_HAND); - -- if (itemstack.getItem() == Items.BOW && ((AbstractSkeleton)entitylivingbaseIn).isSwingingArms()) -+ if (itemstack.getItem() instanceof net.minecraft.item.ItemBow && ((AbstractSkeleton)entitylivingbaseIn).isSwingingArms()) - { - if (entitylivingbaseIn.getPrimaryHand() == EnumHandSide.RIGHT) - { -@@ -71,7 +71,7 @@ - ItemStack itemstack = ((EntityLivingBase)entityIn).getHeldItemMainhand(); - AbstractSkeleton abstractskeleton = (AbstractSkeleton)entityIn; - -- if (abstractskeleton.isSwingingArms() && (itemstack.isEmpty() || itemstack.getItem() != Items.BOW)) -+ if (abstractskeleton.isSwingingArms() && (itemstack.isEmpty() || !(itemstack.getItem() instanceof net.minecraft.item.ItemBow))) - { - float f = MathHelper.sin(this.swingProgress * (float) Math.PI); - float f1 = MathHelper.sin((1.0F - (1.0F - this.swingProgress) * (1.0F - this.swingProgress)) * (float) Math.PI); diff --git a/patches/minecraft/net/minecraft/client/model/PositionTextureVertex.java.patch b/patches/minecraft/net/minecraft/client/model/PositionTextureVertex.java.patch deleted file mode 100644 index c0a4e1e80..000000000 --- a/patches/minecraft/net/minecraft/client/model/PositionTextureVertex.java.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- before/net/minecraft/client/model/PositionTextureVertex.java -+++ after/net/minecraft/client/model/PositionTextureVertex.java -@@ -1,10 +1,7 @@ - package net.minecraft.client.model; - - import net.minecraft.util.math.Vec3d; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; - --@SideOnly(Side.CLIENT) - public class PositionTextureVertex - { - public Vec3d vector3D; diff --git a/patches/minecraft/net/minecraft/client/model/TexturedQuad.java.patch b/patches/minecraft/net/minecraft/client/model/TexturedQuad.java.patch deleted file mode 100644 index d9f13b004..000000000 --- a/patches/minecraft/net/minecraft/client/model/TexturedQuad.java.patch +++ /dev/null @@ -1,18 +0,0 @@ ---- before/net/minecraft/client/model/TexturedQuad.java -+++ after/net/minecraft/client/model/TexturedQuad.java -@@ -7,7 +7,6 @@ - import net.minecraftforge.fml.relauncher.Side; - import net.minecraftforge.fml.relauncher.SideOnly; - --@SideOnly(Side.CLIENT) - public class TexturedQuad - { - public PositionTextureVertex[] vertexPositions; -@@ -43,6 +42,7 @@ - this.vertexPositions = apositiontexturevertex; - } - -+ @SideOnly(Side.CLIENT) - public void draw(BufferBuilder renderer, float scale) - { - Vec3d vec3d = this.vertexPositions[1].vector3D.subtractReverse(this.vertexPositions[0].vector3D); diff --git a/patches/minecraft/net/minecraft/client/multiplayer/ChunkProviderClient.java.patch b/patches/minecraft/net/minecraft/client/multiplayer/ChunkProviderClient.java.patch deleted file mode 100644 index 6380e11af..000000000 --- a/patches/minecraft/net/minecraft/client/multiplayer/ChunkProviderClient.java.patch +++ /dev/null @@ -1,36 +0,0 @@ ---- before/net/minecraft/client/multiplayer/ChunkProviderClient.java -+++ after/net/minecraft/client/multiplayer/ChunkProviderClient.java -@@ -32,6 +32,9 @@ - }; - private final World world; - -+ private java.util.function.BiConsumer loadChunkCallback = null; -+ private java.util.function.BiConsumer unloadChunkCallback = null; -+ - public ChunkProviderClient(World worldIn) - { - this.blankChunk = new EmptyChunk(worldIn, 0, 0); -@@ -48,6 +51,10 @@ - } - - this.loadedChunks.remove(ChunkPos.asLong(x, z)); -+ if (unloadChunkCallback != null) -+ { -+ unloadChunkCallback.accept(x, z); -+ } - } - - @Nullable -@@ -61,7 +68,12 @@ - { - Chunk chunk = new Chunk(this.world, chunkX, chunkZ); - this.loadedChunks.put(ChunkPos.asLong(chunkX, chunkZ), chunk); -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.ChunkEvent.Load(chunk)); - chunk.markLoaded(true); -+ if (loadChunkCallback != null) -+ { -+ loadChunkCallback.accept(chunkX, chunkZ); -+ } - return chunk; - } - diff --git a/patches/minecraft/net/minecraft/client/multiplayer/GuiConnecting.java.patch b/patches/minecraft/net/minecraft/client/multiplayer/GuiConnecting.java.patch deleted file mode 100644 index c04dc282a..000000000 --- a/patches/minecraft/net/minecraft/client/multiplayer/GuiConnecting.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/client/multiplayer/GuiConnecting.java -+++ after/net/minecraft/client/multiplayer/GuiConnecting.java -@@ -73,7 +73,7 @@ - .setNetHandler( - new NetHandlerLoginClient(GuiConnecting.this.networkManager, GuiConnecting.this.mc, GuiConnecting.this.previousGuiScreen) - ); -- GuiConnecting.this.networkManager.sendPacket(new C00Handshake(ip, port, EnumConnectionState.LOGIN)); -+ GuiConnecting.this.networkManager.sendPacket(new C00Handshake(ip, port, EnumConnectionState.LOGIN, true)); - GuiConnecting.this.networkManager.sendPacket(new CPacketLoginStart(GuiConnecting.this.mc.getSession().getProfile())); - } - catch (UnknownHostException unknownhostexception) diff --git a/patches/minecraft/net/minecraft/client/multiplayer/PlayerControllerMP.java.patch b/patches/minecraft/net/minecraft/client/multiplayer/PlayerControllerMP.java.patch deleted file mode 100644 index 8919e739e..000000000 --- a/patches/minecraft/net/minecraft/client/multiplayer/PlayerControllerMP.java.patch +++ /dev/null @@ -1,217 +0,0 @@ ---- before/net/minecraft/client/multiplayer/PlayerControllerMP.java -+++ after/net/minecraft/client/multiplayer/PlayerControllerMP.java -@@ -126,9 +126,13 @@ - } - } - -- if (this.currentGameType.isCreative() -- && !this.mc.player.getHeldItemMainhand().isEmpty() -- && this.mc.player.getHeldItemMainhand().getItem() instanceof ItemSword) -+ ItemStack stack = mc.player.getHeldItemMainhand(); -+ if (!stack.isEmpty() && stack.getItem().onBlockStartBreak(stack, pos, mc.player)) -+ { -+ return false; -+ } -+ -+ if (this.currentGameType.isCreative() && !stack.isEmpty() && !stack.getItem().canDestroyBlockInCreative(mc.world, pos, stack, mc.player)) - { - return false; - } -@@ -149,19 +153,13 @@ - else - { - world.playEvent(2001, pos, Block.getStateId(iblockstate)); -- block.onBlockHarvested(world, pos, iblockstate, this.mc.player); -- boolean flag = world.setBlockState(pos, Blocks.AIR.getDefaultState(), 11); -- -- if (flag) -- { -- block.onPlayerDestroy(world, pos, iblockstate); -- } - - this.currentBlock = new BlockPos(this.currentBlock.getX(), -1, this.currentBlock.getZ()); - - if (!this.currentGameType.isCreative()) - { - ItemStack itemstack1 = this.mc.player.getHeldItemMainhand(); -+ ItemStack copyBeforeUse = itemstack1.copy(); - - if (!itemstack1.isEmpty()) - { -@@ -169,11 +167,18 @@ - - if (itemstack1.isEmpty()) - { -+ net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(this.mc.player, copyBeforeUse, EnumHand.MAIN_HAND); - this.mc.player.setHeldItem(EnumHand.MAIN_HAND, ItemStack.EMPTY); - } - } - } - -+ boolean flag = block.removedByPlayer(iblockstate, world, pos, mc.player, false); -+ -+ if (flag) -+ { -+ block.onPlayerDestroy(world, pos, iblockstate); -+ } - return flag; - } - } -@@ -216,6 +221,7 @@ - .getTutorial() - .onHitBlock(this.mc.world, loc, this.mc.world.getBlockState(loc), 1.0F); - this.connection.sendPacket(new CPacketPlayerDigging(CPacketPlayerDigging.Action.START_DESTROY_BLOCK, loc, face)); -+ if (!net.minecraftforge.common.ForgeHooks.onLeftClickBlock(this.mc.player, loc, face, net.minecraftforge.common.ForgeHooks.rayTraceEyeHitVec(this.mc.player, getBlockReachDistance() + 1)).isCanceled()) - clickBlockCreative(this.mc, this, loc, face); - this.blockHitDelay = 5; - } -@@ -225,6 +231,7 @@ - { - this.connection.sendPacket(new CPacketPlayerDigging(CPacketPlayerDigging.Action.ABORT_DESTROY_BLOCK, this.currentBlock, face)); - } -+ net.minecraftforge.event.entity.player.PlayerInteractEvent.LeftClickBlock event = net.minecraftforge.common.ForgeHooks.onLeftClickBlock(this.mc.player, loc, face, net.minecraftforge.common.ForgeHooks.rayTraceEyeHitVec(this.mc.player, getBlockReachDistance() + 1)); - - IBlockState iblockstate = this.mc.world.getBlockState(loc); - this.mc.getTutorial().onHitBlock(this.mc.world, loc, iblockstate, 0.0F); -@@ -233,9 +240,11 @@ - - if (flag && this.curBlockDamageMP == 0.0F) - { -+ if (event.getUseBlock() != net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) - iblockstate.getBlock().onBlockClicked(this.mc.world, loc, this.mc.player); - } - -+ if (event.getUseItem() == net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) return true; - if (flag && iblockstate.getPlayerRelativeBlockHardness(this.mc.player, this.mc.player.world, loc) >= 1.0F) - { - this.onPlayerDestroyBlock(loc); -@@ -308,7 +317,7 @@ - - if (this.stepSoundTickCounter % 4.0F == 0.0F) - { -- SoundType soundtype = block.getSoundType(); -+ SoundType soundtype = block.getSoundType(iblockstate, mc.world, posBlock, mc.player); - this.mc - .getSoundHandler() - .playSound( -@@ -351,7 +360,8 @@ - - public float getBlockReachDistance() - { -- return this.currentGameType.isCreative() ? 5.0F : 4.5F; -+ float attrib = (float) mc.player.getEntityAttribute(EntityPlayer.REACH_DISTANCE).getAttributeValue(); -+ return this.currentGameType.isCreative() ? attrib : attrib - 0.5F; - } - - public void updateController() -@@ -375,9 +385,7 @@ - - if (!this.currentItemHittingBlock.isEmpty() && !itemstack.isEmpty()) - { -- flag = itemstack.getItem() == this.currentItemHittingBlock.getItem() -- && ItemStack.areItemStackTagsEqual(itemstack, this.currentItemHittingBlock) -- && (itemstack.isItemStackDamageable() || itemstack.getMetadata() == this.currentItemHittingBlock.getMetadata()); -+ flag = !net.minecraftforge.client.ForgeHooksClient.shouldCauseBlockBreakReset(this.currentItemHittingBlock, itemstack); - } - - return pos.equals(this.currentBlock) && flag; -@@ -411,14 +419,34 @@ - } - else - { -+ net.minecraftforge.event.entity.player.PlayerInteractEvent.RightClickBlock event = net.minecraftforge.common.ForgeHooks -+ .onRightClickBlock(player, hand, pos, direction, net.minecraftforge.common.ForgeHooks.rayTraceEyeHitVec(player, getBlockReachDistance() + 1)); -+ if (event.isCanceled()) -+ { -+ // Give the server a chance to fire event as well. That way server event is not dependant on client event. -+ this.connection.sendPacket(new CPacketPlayerTryUseItemOnBlock(pos, direction, hand, f, f1, f2)); -+ return event.getCancellationResult(); -+ } -+ EnumActionResult result = EnumActionResult.PASS; -+ - if (this.currentGameType != GameType.SPECTATOR) - { -+ EnumActionResult ret = itemstack.onItemUseFirst(player, worldIn, pos, hand, direction, f, f1, f2); -+ if (ret != EnumActionResult.PASS) -+ { -+ // The server needs to process the item use as well. Otherwise onItemUseFirst won't ever be called on the server without causing weird bugs -+ this.connection.sendPacket(new CPacketPlayerTryUseItemOnBlock(pos, direction, hand, f, f1, f2)); -+ return ret; -+ } -+ - IBlockState iblockstate = worldIn.getBlockState(pos); -+ boolean bypass = player.getHeldItemMainhand().doesSneakBypassUse(worldIn, pos, player) && player.getHeldItemOffhand().doesSneakBypassUse(worldIn, pos, player); - -- if ((!player.isSneaking() || player.getHeldItemMainhand().isEmpty() && player.getHeldItemOffhand().isEmpty()) -- && iblockstate.getBlock().onBlockActivated(worldIn, pos, iblockstate, player, hand, direction, f, f1, f2)) -+ if ((!player.isSneaking() || bypass || event.getUseBlock() == net.minecraftforge.fml.common.eventhandler.Event.Result.ALLOW)) - { -- flag = true; -+ if (event.getUseBlock() != net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) -+ flag = iblockstate.getBlock().onBlockActivated(worldIn, pos, iblockstate, player, hand, direction, f, f1, f2); -+ if (flag) result = EnumActionResult.SUCCESS; - } - - if (!flag && itemstack.getItem() instanceof ItemBlock) -@@ -434,7 +462,7 @@ - - this.connection.sendPacket(new CPacketPlayerTryUseItemOnBlock(pos, direction, hand, f, f1, f2)); - -- if (flag || this.currentGameType == GameType.SPECTATOR) -+ if ((flag || this.currentGameType == GameType.SPECTATOR) && event.getUseItem() != net.minecraftforge.fml.common.eventhandler.Event.Result.ALLOW) - { - return EnumActionResult.SUCCESS; - } -@@ -462,14 +490,21 @@ - { - int i = itemstack.getMetadata(); - int j = itemstack.getCount(); -+ if (event.getUseItem() != net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) { - EnumActionResult enumactionresult = itemstack.onItemUse(player, worldIn, pos, hand, direction, f, f1, f2); - itemstack.setItemDamage(i); - itemstack.setCount(j); - return enumactionresult; -+ } else return result; - } - else - { -- return itemstack.onItemUse(player, worldIn, pos, hand, direction, f, f1, f2); -+ ItemStack copyForUse = itemstack.copy(); -+ if (event.getUseItem() != net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) -+ result = itemstack.onItemUse(player, worldIn, pos, hand, direction, f, f1, f2); -+ if (itemstack.isEmpty()) -+ net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(player, copyForUse, hand); -+ return result; - } - } - } -@@ -493,6 +528,8 @@ - } - else - { -+ EnumActionResult cancelResult = net.minecraftforge.common.ForgeHooks.onItemRightClick(player, hand); -+ if (cancelResult != null) return cancelResult; - int i = itemstack.getCount(); - ActionResult actionresult = itemstack.useItemRightClick(worldIn, player, hand); - ItemStack itemstack1 = actionresult.getResult(); -@@ -500,6 +537,10 @@ - if (itemstack1 != itemstack || itemstack1.getCount() != i) - { - player.setHeldItem(hand, itemstack1); -+ if (itemstack1.isEmpty()) -+ { -+ net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(player, itemstack, hand); -+ } - } - - return actionresult.getType(); -@@ -540,6 +581,9 @@ - ray.hitVec.z - target.posZ - ); - this.connection.sendPacket(new CPacketUseEntity(target, hand, vec3d)); -+ if (this.currentGameType == GameType.SPECTATOR) return EnumActionResult.PASS; // don't fire for spectators to match non-specific EntityInteract -+ EnumActionResult cancelResult = net.minecraftforge.common.ForgeHooks.onInteractEntityAt(player, target, ray, hand); -+ if(cancelResult != null) return cancelResult; - return this.currentGameType == GameType.SPECTATOR ? EnumActionResult.PASS : target.applyPlayerInteraction(player, vec3d, hand); - } - diff --git a/patches/minecraft/net/minecraft/client/multiplayer/WorldClient.java.patch b/patches/minecraft/net/minecraft/client/multiplayer/WorldClient.java.patch deleted file mode 100644 index f12597e8f..000000000 --- a/patches/minecraft/net/minecraft/client/multiplayer/WorldClient.java.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- before/net/minecraft/client/multiplayer/WorldClient.java -+++ after/net/minecraft/client/multiplayer/WorldClient.java -@@ -60,15 +60,17 @@ - - public WorldClient(NetHandlerPlayClient netHandler, WorldSettings settings, int dimension, EnumDifficulty difficulty, Profiler profilerIn) - { -- super(new SaveHandlerMP(), new WorldInfo(settings, "MpServer"), DimensionType.getById(dimension).createDimension(), profilerIn, true); -+ super(new SaveHandlerMP(), new WorldInfo(settings, "MpServer"), net.minecraftforge.common.DimensionManager.createProviderFor(dimension), profilerIn, true); - this.connection = netHandler; - this.getWorldInfo().setDifficulty(difficulty); -- this.setSpawnPoint(new BlockPos(8, 64, 8)); - this.provider.setWorld(this); -+ this.setSpawnPoint(new BlockPos(8, 64, 8)); //Forge: Moved below registerWorld to prevent NPE in our redirect. - this.chunkProvider = this.createChunkProvider(); - this.mapStorage = new SaveDataMemoryStorage(); - this.calculateInitialSkylight(); - this.calculateInitialWeather(); -+ this.initCapabilities(); -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.WorldEvent.Load(this)); - } - - @Override diff --git a/patches/minecraft/net/minecraft/client/network/NetHandlerHandshakeMemory.java.patch b/patches/minecraft/net/minecraft/client/network/NetHandlerHandshakeMemory.java.patch deleted file mode 100644 index a46091a9d..000000000 --- a/patches/minecraft/net/minecraft/client/network/NetHandlerHandshakeMemory.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- before/net/minecraft/client/network/NetHandlerHandshakeMemory.java -+++ after/net/minecraft/client/network/NetHandlerHandshakeMemory.java -@@ -24,6 +24,7 @@ - @Override - public void processHandshake(C00Handshake packetIn) - { -+ if (!net.minecraftforge.fml.common.FMLCommonHandler.instance().handleServerHandshake(packetIn, this.networkManager)) return; - this.networkManager.setConnectionState(packetIn.getRequestedState()); - this.networkManager.setNetHandler(new NetHandlerLoginServer(this.server, this.networkManager)); - } diff --git a/patches/minecraft/net/minecraft/client/network/NetHandlerLoginClient.java.patch b/patches/minecraft/net/minecraft/client/network/NetHandlerLoginClient.java.patch deleted file mode 100644 index c9e61079b..000000000 --- a/patches/minecraft/net/minecraft/client/network/NetHandlerLoginClient.java.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- before/net/minecraft/client/network/NetHandlerLoginClient.java -+++ after/net/minecraft/client/network/NetHandlerLoginClient.java -@@ -118,7 +118,10 @@ - { - this.gameProfile = packetIn.getProfile(); - this.networkManager.setConnectionState(EnumConnectionState.PLAY); -- this.networkManager.setNetHandler(new NetHandlerPlayClient(this.mc, this.previousGuiScreen, this.networkManager, this.gameProfile)); -+ NetHandlerPlayClient nhpc = new NetHandlerPlayClient(this.mc, this.previousGuiScreen, this.networkManager, this.gameProfile); -+ this.networkManager.setNetHandler(nhpc); -+ net.minecraftforge.fml.client.FMLClientHandler.instance().setPlayClient(nhpc); -+ net.minecraftforge.fml.common.network.internal.FMLNetworkHandler.fmlClientHandshake(this.networkManager); - } - - @Override diff --git a/patches/minecraft/net/minecraft/client/network/NetHandlerPlayClient.java.patch b/patches/minecraft/net/minecraft/client/network/NetHandlerPlayClient.java.patch deleted file mode 100644 index 2a2284228..000000000 --- a/patches/minecraft/net/minecraft/client/network/NetHandlerPlayClient.java.patch +++ /dev/null @@ -1,153 +0,0 @@ ---- before/net/minecraft/client/network/NetHandlerPlayClient.java -+++ after/net/minecraft/client/network/NetHandlerPlayClient.java -@@ -297,7 +297,7 @@ - this.world = new WorldClient( - this, - new WorldSettings(0L, packetIn.getGameType(), false, packetIn.isHardcoreMode(), packetIn.getWorldType()), -- packetIn.getDimension(), -+ net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.get(getNetworkManager()).getOverrideDimension(packetIn), - packetIn.getDifficulty(), - this.client.profiler - ); -@@ -810,7 +810,7 @@ - (packetIn.getChunkZ() << 4) + 15 - ); - -- if (!packetIn.isFullChunk() || !(this.world.provider instanceof WorldProviderSurface)) -+ if (!packetIn.isFullChunk() || this.world.provider.shouldClientCheckLighting()) - { - chunk.resetRelightChecks(); - } -@@ -822,7 +822,7 @@ - - if (tileentity != null) - { -- tileentity.readFromNBT(nbttagcompound); -+ tileentity.handleUpdateTag(nbttagcompound); - } - } - } -@@ -934,7 +934,9 @@ - public void handleChat(SPacketChat packetIn) - { - PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client); -- this.client.ingameGUI.addChatMessage(packetIn.getType(), packetIn.getChatComponent()); -+ net.minecraft.util.text.ITextComponent message = net.minecraftforge.event.ForgeEventFactory.onClientChat(packetIn.getType(), packetIn.getChatComponent()); -+ if (message == null) return; -+ this.client.ingameGUI.addChatMessage(packetIn.getType(), message); - } - - @Override -@@ -1074,7 +1076,7 @@ - this.client - .ingameGUI - .setOverlayMessage( -- I18n.format("mount.onboard", GameSettings.getKeyDisplayString(this.client.gameSettings.keyBindSneak.getKeyCode())), false -+ I18n.format("mount.onboard", this.client.gameSettings.keyBindSneak.getDisplayName()), false - ); - } - } -@@ -1364,6 +1366,15 @@ - { - tileentity.readFromNBT(packetIn.getNbtCompound()); - } -+ else -+ { -+ if(tileentity == null) -+ { -+ LOGGER.error("Received invalid update packet for null tile entity at {} with data: {}", packetIn.getPos(), packetIn.getNbtCompound()); -+ return; -+ } -+ tileentity.onDataPacket(netManager, packetIn); -+ } - - if (flag && this.client.currentScreen instanceof GuiCommandBlock) - { -@@ -1481,10 +1492,10 @@ - .printChatMessage( - new TextComponentTranslation( - "demo.help.movement", -- GameSettings.getKeyDisplayString(gamesettings.keyBindForward.getKeyCode()), -- GameSettings.getKeyDisplayString(gamesettings.keyBindLeft.getKeyCode()), -- GameSettings.getKeyDisplayString(gamesettings.keyBindBack.getKeyCode()), -- GameSettings.getKeyDisplayString(gamesettings.keyBindRight.getKeyCode()) -+ gamesettings.keyBindForward.getDisplayName(), -+ gamesettings.keyBindLeft.getDisplayName(), -+ gamesettings.keyBindBack.getDisplayName(), -+ gamesettings.keyBindRight.getDisplayName() - ) - ); - } -@@ -1493,14 +1504,14 @@ - this.client - .ingameGUI - .getChatGUI() -- .printChatMessage(new TextComponentTranslation("demo.help.jump", GameSettings.getKeyDisplayString(gamesettings.keyBindJump.getKeyCode()))); -+ .printChatMessage(new TextComponentTranslation("demo.help.jump", gamesettings.keyBindJump.getDisplayName())); - } - else if (f == 103.0F) - { - this.client - .ingameGUI - .getChatGUI() -- .printChatMessage(new TextComponentTranslation("demo.help.inventory", GameSettings.getKeyDisplayString(gamesettings.keyBindInventory.getKeyCode()))); -+ .printChatMessage(new TextComponentTranslation("demo.help.inventory", gamesettings.keyBindInventory.getDisplayName())); - } - } - else if (i == 6) -@@ -1679,7 +1690,7 @@ - - if (entity instanceof EntityLivingBase) - { -- Potion potion = Potion.getPotionById(packetIn.getEffectId()); -+ Potion potion = Potion.getPotionById(packetIn.getEffectId() & 0xFF); - - if (potion != null) - { -@@ -1925,7 +1936,7 @@ - if (file2.isFile()) - { - this.netManager.sendPacket(new CPacketResourcePackStatus(CPacketResourcePackStatus.Action.ACCEPTED)); -- Futures.addCallback(this.client.getResourcePackRepository().setServerResourcePack(file2), this.createDownloadCallback()); -+ Futures.addCallback(this.client.getResourcePackRepository().setServerResourcePack(file2), this.createDownloadCallback(), Runnable::run); - return; - } - } -@@ -1942,7 +1953,7 @@ - if (serverdata != null && serverdata.getResourceMode() == ServerData.ServerResourceMode.ENABLED) - { - this.netManager.sendPacket(new CPacketResourcePackStatus(CPacketResourcePackStatus.Action.ACCEPTED)); -- Futures.addCallback(this.client.getResourcePackRepository().downloadResourcePack(s, s1), this.createDownloadCallback()); -+ Futures.addCallback(this.client.getResourcePackRepository().downloadResourcePack(s, s1), this.createDownloadCallback(), Runnable::run); - } - else if (serverdata != null && serverdata.getResourceMode() != ServerData.ServerResourceMode.PROMPT) - { -@@ -1979,7 +1990,8 @@ - .sendPacket(new CPacketResourcePackStatus(CPacketResourcePackStatus.Action.ACCEPTED)); - Futures.addCallback( - NetHandlerPlayClient.this.client.getResourcePackRepository().downloadResourcePack(s, s1), -- NetHandlerPlayClient.this.createDownloadCallback() -+ NetHandlerPlayClient.this.createDownloadCallback(), -+ Runnable::run - ); - } - else -@@ -2119,6 +2131,7 @@ - } - finally - { -+ if (false) // Forge: let packet handle releasing buffer - packetbuffer.release(); - } - } -@@ -2381,8 +2394,8 @@ - if (iattributeinstance == null) - { - iattributeinstance = abstractattributemap.registerAttribute( -- new RangedAttribute(null, spacketentityproperties$snapshot.getName(), 0.0, Double.MIN_NORMAL, Double.MAX_VALUE) -- ); -+ new RangedAttribute(null, spacketentityproperties$snapshot.getName(), 0.0, -Double.MAX_VALUE, Double.MAX_VALUE) -+ ); // Forge: fix invalid value range (MC-150405) - } - - iattributeinstance.setBaseValue(spacketentityproperties$snapshot.getBaseValue()); diff --git a/patches/minecraft/net/minecraft/client/network/ServerPinger.java.patch b/patches/minecraft/net/minecraft/client/network/ServerPinger.java.patch deleted file mode 100644 index a095e9f23..000000000 --- a/patches/minecraft/net/minecraft/client/network/ServerPinger.java.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- before/net/minecraft/client/network/ServerPinger.java -+++ after/net/minecraft/client/network/ServerPinger.java -@@ -166,6 +166,7 @@ - server.setBase64EncodedIconData(null); - } - -+ net.minecraftforge.fml.client.FMLClientHandler.instance().bindServerListData(server, serverstatusresponse); - this.pingSentAt = Minecraft.getSystemTime(); - networkmanager.sendPacket(new CPacketPing(this.pingSentAt)); - this.successful = true; -@@ -195,7 +196,7 @@ - - try - { -- networkmanager.sendPacket(new C00Handshake(serveraddress.getIP(), serveraddress.getPort(), EnumConnectionState.STATUS)); -+ networkmanager.sendPacket(new C00Handshake(serveraddress.getIP(), serveraddress.getPort(), EnumConnectionState.STATUS, true)); - networkmanager.sendPacket(new CPacketServerQuery()); - } - catch (Throwable throwable) diff --git a/patches/minecraft/net/minecraft/client/particle/Particle.java.patch b/patches/minecraft/net/minecraft/client/particle/Particle.java.patch deleted file mode 100644 index 5504bbaef..000000000 --- a/patches/minecraft/net/minecraft/client/particle/Particle.java.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- before/net/minecraft/client/particle/Particle.java -+++ after/net/minecraft/client/particle/Particle.java -@@ -312,17 +312,8 @@ - { - this.width = particleWidth; - this.height = particleHeight; -- AxisAlignedBB axisalignedbb = this.getBoundingBox(); -- this.setBoundingBox( -- new AxisAlignedBB( -- axisalignedbb.minX, -- axisalignedbb.minY, -- axisalignedbb.minZ, -- axisalignedbb.minX + this.width, -- axisalignedbb.minY + this.height, -- axisalignedbb.minZ + this.width -- ) -- ); -+ // FORGE: Fix MC-12269 - Glitchy movement when setSize is called without setPosition -+ setPosition(posX, posY, posZ); - } - } - diff --git a/patches/minecraft/net/minecraft/client/particle/ParticleItemPickup.java.patch b/patches/minecraft/net/minecraft/client/particle/ParticleItemPickup.java.patch deleted file mode 100644 index d3f5311e8..000000000 --- a/patches/minecraft/net/minecraft/client/particle/ParticleItemPickup.java.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- before/net/minecraft/client/particle/ParticleItemPickup.java -+++ after/net/minecraft/client/particle/ParticleItemPickup.java -@@ -71,7 +71,9 @@ - d7 -= interpPosY; - d8 -= interpPosZ; - GlStateManager.enableLighting(); -+ GlStateManager.enableCull(); - this.renderManager.renderEntity(this.item, d6, d7, d8, this.item.rotationYaw, partialTicks, false); -+ GlStateManager.disableCull(); - } - - @Override diff --git a/patches/minecraft/net/minecraft/client/particle/ParticleManager.java.patch b/patches/minecraft/net/minecraft/client/particle/ParticleManager.java.patch deleted file mode 100644 index 4f066ba8c..000000000 --- a/patches/minecraft/net/minecraft/client/particle/ParticleManager.java.patch +++ /dev/null @@ -1,33 +0,0 @@ ---- before/net/minecraft/client/particle/ParticleManager.java -+++ after/net/minecraft/client/particle/ParticleManager.java -@@ -164,6 +164,7 @@ - - public void addEffect(Particle effect) - { -+ if (effect == null) return; //Forge: Prevent modders from being bad and adding nulls causing untraceable NPEs. - this.queue.add(effect); - } - -@@ -420,7 +421,7 @@ - - public void addBlockDestroyEffects(BlockPos pos, IBlockState state) - { -- if (state.getMaterial() != Material.AIR) -+ if (!state.getBlock().isAir(state, this.world, pos) && !state.getBlock().addDestroyEffects(world, pos, this)) - { - state = state.getActualState(this.world, pos); - int i = 4; -@@ -527,4 +528,13 @@ - - return "" + i; - } -+ -+ public void addBlockHitEffects(BlockPos pos, net.minecraft.util.math.RayTraceResult target) -+ { -+ IBlockState state = world.getBlockState(pos); -+ if (state != null && !state.getBlock().addHitEffects(state, world, target, this)) -+ { -+ addBlockHitEffects(pos, target.sideHit); -+ } -+ } - } diff --git a/patches/minecraft/net/minecraft/client/renderer/ActiveRenderInfo.java.patch b/patches/minecraft/net/minecraft/client/renderer/ActiveRenderInfo.java.patch deleted file mode 100644 index b62c5b6ab..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/ActiveRenderInfo.java.patch +++ /dev/null @@ -1,39 +0,0 @@ ---- before/net/minecraft/client/renderer/ActiveRenderInfo.java -+++ after/net/minecraft/client/renderer/ActiveRenderInfo.java -@@ -30,6 +30,11 @@ - - public static void updateRenderInfo(EntityPlayer entityplayerIn, boolean p_74583_1_) - { -+ updateRenderInfo((Entity) entityplayerIn, p_74583_1_); -+ } -+ -+ public static void updateRenderInfo(Entity entityplayerIn, boolean p_74583_1_) -+ { - GlStateManager.getFloat(2982, MODELVIEW); - GlStateManager.getFloat(2983, PROJECTION); - GlStateManager.glGetInteger(2978, VIEWPORT); -@@ -81,7 +86,7 @@ - } - } - -- return iblockstate; -+ return iblockstate.getBlock().getStateAtViewpoint(iblockstate, worldIn, blockpos, vec3d); - } - - public static float getRotationX() -@@ -107,5 +112,15 @@ - public static float getRotationXY() - { - return rotationXY; -+ } -+ -+ /* ======================================== FORGE START =====================================*/ -+ -+ /** -+ * Vector from render view entity position (corrected for partialTickTime) to the middle of screen -+ */ -+ public static Vec3d getCameraPosition() -+ { -+ return position; - } - } diff --git a/patches/minecraft/net/minecraft/client/renderer/BlockFluidRenderer.java.patch b/patches/minecraft/net/minecraft/client/renderer/BlockFluidRenderer.java.patch deleted file mode 100644 index 391e15173..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/BlockFluidRenderer.java.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- before/net/minecraft/client/renderer/BlockFluidRenderer.java -+++ after/net/minecraft/client/renderer/BlockFluidRenderer.java -@@ -226,9 +226,9 @@ - - if (!flag) - { -- Block block = blockAccess.getBlockState(blockpos).getBlock(); -+ IBlockState state = blockAccess.getBlockState(blockpos); - -- if (block == Blocks.GLASS || block == Blocks.STAINED_GLASS) -+ if (state.getBlockFaceShape(blockAccess, blockpos, EnumFacing.VALUES[i1+2].getOpposite()) == net.minecraft.block.state.BlockFaceShape.SOLID) - { - textureatlassprite1 = this.atlasSpriteWaterOverlay; - } diff --git a/patches/minecraft/net/minecraft/client/renderer/BlockModelRenderer.java.patch b/patches/minecraft/net/minecraft/client/renderer/BlockModelRenderer.java.patch deleted file mode 100644 index a678475cc..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/BlockModelRenderer.java.patch +++ /dev/null @@ -1,52 +0,0 @@ ---- before/net/minecraft/client/renderer/BlockModelRenderer.java -+++ after/net/minecraft/client/renderer/BlockModelRenderer.java -@@ -50,7 +50,7 @@ - long rand - ) - { -- boolean flag = Minecraft.isAmbientOcclusionEnabled() && stateIn.getLightValue() == 0 && modelIn.isAmbientOcclusion(); -+ boolean flag = Minecraft.isAmbientOcclusionEnabled() && stateIn.getLightValue(worldIn, posIn) == 0 && modelIn.isAmbientOcclusion(stateIn); - - try - { -@@ -166,6 +166,14 @@ - buffer.addVertexData(bakedquad.getVertexData()); - buffer.putBrightness4(aoFace.vertexBrightness[0], aoFace.vertexBrightness[1], aoFace.vertexBrightness[2], aoFace.vertexBrightness[3]); - -+ if(bakedquad.shouldApplyDiffuseLighting()) -+ { -+ float diffuse = net.minecraftforge.client.model.pipeline.LightUtil.diffuseLight(bakedquad.getFace()); -+ aoFace.vertexColorMultiplier[0] *= diffuse; -+ aoFace.vertexColorMultiplier[1] *= diffuse; -+ aoFace.vertexColorMultiplier[2] *= diffuse; -+ aoFace.vertexColorMultiplier[3] *= diffuse; -+ } - if (bakedquad.hasTintIndex()) - { - int k = this.blockColors.colorMultiplier(stateIn, blockAccessIn, posIn, bakedquad.getTintIndex()); -@@ -308,10 +316,25 @@ - float f = (k >> 16 & 0xFF) / 255.0F; - float f1 = (k >> 8 & 0xFF) / 255.0F; - float f2 = (k & 0xFF) / 255.0F; -+ if(bakedquad.shouldApplyDiffuseLighting()) -+ { -+ float diffuse = net.minecraftforge.client.model.pipeline.LightUtil.diffuseLight(bakedquad.getFace()); -+ f *= diffuse; -+ f1 *= diffuse; -+ f2 *= diffuse; -+ } - buffer.putColorMultiplier(f, f1, f2, 4); - buffer.putColorMultiplier(f, f1, f2, 3); - buffer.putColorMultiplier(f, f1, f2, 2); - buffer.putColorMultiplier(f, f1, f2, 1); -+ } -+ else if(bakedquad.shouldApplyDiffuseLighting()) -+ { -+ float diffuse = net.minecraftforge.client.model.pipeline.LightUtil.diffuseLight(bakedquad.getFace()); -+ buffer.putColorMultiplier(diffuse, diffuse, diffuse, 4); -+ buffer.putColorMultiplier(diffuse, diffuse, diffuse, 3); -+ buffer.putColorMultiplier(diffuse, diffuse, diffuse, 2); -+ buffer.putColorMultiplier(diffuse, diffuse, diffuse, 1); - } - - buffer.putPosition(d0, d1, d2); diff --git a/patches/minecraft/net/minecraft/client/renderer/BlockModelShapes.java.patch b/patches/minecraft/net/minecraft/client/renderer/BlockModelShapes.java.patch deleted file mode 100644 index 5af4dbcf1..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/BlockModelShapes.java.patch +++ /dev/null @@ -1,9 +0,0 @@ ---- before/net/minecraft/client/renderer/BlockModelShapes.java -+++ after/net/minecraft/client/renderer/BlockModelShapes.java -@@ -469,5 +469,6 @@ - return new ModelResourceLocation(s + "_double_slab", s1); - } - }); -+ net.minecraftforge.client.model.ModelLoader.onRegisterAllBlocks(this); - } - } diff --git a/patches/minecraft/net/minecraft/client/renderer/BlockRendererDispatcher.java.patch b/patches/minecraft/net/minecraft/client/renderer/BlockRendererDispatcher.java.patch deleted file mode 100644 index 15673f14b..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/BlockRendererDispatcher.java.patch +++ /dev/null @@ -1,31 +0,0 @@ ---- before/net/minecraft/client/renderer/BlockRendererDispatcher.java -+++ after/net/minecraft/client/renderer/BlockRendererDispatcher.java -@@ -28,7 +28,7 @@ - public BlockRendererDispatcher(BlockModelShapes p_i46577_1_, BlockColors p_i46577_2_) - { - this.blockModelShapes = p_i46577_1_; -- this.blockModelRenderer = new BlockModelRenderer(p_i46577_2_); -+ this.blockModelRenderer = new net.minecraftforge.client.model.pipeline.ForgeBlockModelRenderer(p_i46577_2_); - this.fluidRenderer = new BlockFluidRenderer(p_i46577_2_); - } - -@@ -43,7 +43,7 @@ - { - state = state.getActualState(blockAccess, pos); - IBakedModel ibakedmodel = this.blockModelShapes.getModelForState(state); -- IBakedModel ibakedmodel1 = new SimpleBakedModel.Builder(state, ibakedmodel, texture, pos).makeBakedModel(); -+ IBakedModel ibakedmodel1 = net.minecraftforge.client.ForgeHooksClient.getDamageModel(ibakedmodel, texture, state, blockAccess, pos); - this.blockModelRenderer.renderModel(blockAccess, ibakedmodel1, state, pos, Tessellator.getInstance().getBuffer(), true); - } - } -@@ -74,7 +74,9 @@ - switch (enumblockrendertype) - { - case MODEL: -- return this.blockModelRenderer.renderModel(blockAccess, this.getModelForState(state), state, pos, bufferBuilderIn, true); -+ IBakedModel model = this.getModelForState(state); -+ state = state.getBlock().getExtendedState(state, blockAccess, pos); -+ return this.blockModelRenderer.renderModel(blockAccess, model, state, pos, bufferBuilderIn, true); - case ENTITYBLOCK_ANIMATED: - return false; - case LIQUID: diff --git a/patches/minecraft/net/minecraft/client/renderer/BufferBuilder.java.patch b/patches/minecraft/net/minecraft/client/renderer/BufferBuilder.java.patch deleted file mode 100644 index 660b9bee3..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/BufferBuilder.java.patch +++ /dev/null @@ -1,73 +0,0 @@ ---- before/net/minecraft/client/renderer/BufferBuilder.java -+++ after/net/minecraft/client/renderer/BufferBuilder.java -@@ -132,6 +132,8 @@ - - bitset.set(i1); - } -+ this.rawIntBuffer.limit(this.rawIntBuffer.capacity()); -+ this.rawIntBuffer.position(this.getBufferSize()); - } - - public BufferBuilder.State getVertexState() -@@ -424,8 +426,8 @@ - - public void addVertexData(int[] vertexData) - { -- this.growBuffer(vertexData.length * 4); -- ((Buffer)this.rawIntBuffer).position(this.getBufferSize()); -+ this.growBuffer(vertexData.length * 4 + this.vertexFormat.getSize());//Forge, fix MC-122110 -+ this.rawIntBuffer.position(this.getBufferSize()); - this.rawIntBuffer.put(vertexData); - this.vertexCount = this.vertexCount + vertexData.length / this.vertexFormat.getIntegerSize(); - } -@@ -515,15 +517,15 @@ - break; - case USHORT: - case SHORT: -- this.byteBuffer.putShort(i, (short)((int)x * 32767 & 65535)); -- this.byteBuffer.putShort(i + 2, (short)((int)y * 32767 & 65535)); -- this.byteBuffer.putShort(i + 4, (short)((int)z * 32767 & 65535)); -+ this.byteBuffer.putShort(i, (short)((int)(x * 32767) & 65535)); -+ this.byteBuffer.putShort(i + 2, (short)((int)(y * 32767) & 65535)); -+ this.byteBuffer.putShort(i + 4, (short)((int)(z * 32767) & 65535)); - break; - case UBYTE: - case BYTE: -- this.byteBuffer.put(i, (byte)((int)x * 127 & 0xFF)); -- this.byteBuffer.put(i + 1, (byte)((int)y * 127 & 0xFF)); -- this.byteBuffer.put(i + 2, (byte)((int)z * 127 & 0xFF)); -+ this.byteBuffer.put(i, (byte)((int)(x * 127) & 0xFF)); -+ this.byteBuffer.put(i + 1, (byte)((int)(y * 127) & 0xFF)); -+ this.byteBuffer.put(i + 2, (byte)((int)(z * 127) & 0xFF)); - } - - this.nextVertexFormatIndex(); -@@ -613,5 +615,28 @@ - { - return this.stateVertexFormat; - } -+ } -+ -+ -+ //For some unknown reason Mojang changed the vanilla function to hardcode alpha as 255.... So lets re-add the parameter -.- -+ public void putColorRGBA(int index, int red, int green, int blue, int alpha) -+ { -+ if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) -+ this.rawIntBuffer.put(index, alpha << 24 | blue << 16 | green << 8 | red); -+ else -+ this.rawIntBuffer.put(index, red << 24 | green << 16 | blue << 8 | alpha); -+ } -+ -+ public boolean isColorDisabled() -+ { -+ return this.noColor; -+ } -+ -+ public void putBulkData(ByteBuffer buffer) -+ { -+ growBuffer(buffer.limit() + this.vertexFormat.getSize()); -+ this.byteBuffer.position(this.vertexCount * this.vertexFormat.getSize()); -+ this.byteBuffer.put(buffer); -+ this.vertexCount += buffer.limit() / this.vertexFormat.getSize(); - } - } diff --git a/patches/minecraft/net/minecraft/client/renderer/ChestRenderer.java.patch b/patches/minecraft/net/minecraft/client/renderer/ChestRenderer.java.patch deleted file mode 100644 index 5268d2b44..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/ChestRenderer.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/client/renderer/ChestRenderer.java -+++ after/net/minecraft/client/renderer/ChestRenderer.java -@@ -13,6 +13,7 @@ - { - GlStateManager.color(color, color, color, 1.0F); - GlStateManager.rotate(90.0F, 0.0F, 1.0F, 0.0F); -- TileEntityItemStackRenderer.instance.renderByItem(new ItemStack(blockIn)); -+ ItemStack stack = new ItemStack(blockIn); -+ stack.getItem().getTileEntityItemStackRenderer().renderByItem(stack); - } - } diff --git a/patches/minecraft/net/minecraft/client/renderer/EntityRenderer.java.patch b/patches/minecraft/net/minecraft/client/renderer/EntityRenderer.java.patch deleted file mode 100644 index 3fbb2b78e..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/EntityRenderer.java.patch +++ /dev/null @@ -1,375 +0,0 @@ ---- before/net/minecraft/client/renderer/EntityRenderer.java -+++ after/net/minecraft/client/renderer/EntityRenderer.java -@@ -235,6 +235,7 @@ - { - this.loadShader(new ResourceLocation("shaders/post/invert.json")); - } -+ else net.minecraftforge.client.ForgeHooksClient.loadEntityShader(entityIn, this); - } - } - -@@ -315,7 +316,7 @@ - this.mc.setRenderViewEntity(this.mc.player); - } - -- float f3 = this.mc.world.getLightBrightness(new BlockPos(this.mc.getRenderViewEntity())); -+ float f3 = this.mc.world.getLightBrightness(new BlockPos(this.mc.getRenderViewEntity().getPositionEyes(1.0F))); // Forge: fix MC-51150 - float f4 = this.mc.gameSettings.renderDistanceChunks / 32.0F; - float f2 = f3 * (1.0F - f4) + f4; - this.fogColor1 = this.fogColor1 + (f2 - this.fogColor1) * 0.1F; -@@ -445,7 +446,7 @@ - - if (d3 < d2 || d2 == 0.0) - { -- if (entity1.getLowestRidingEntity() == entity.getLowestRidingEntity()) -+ if (entity1.getLowestRidingEntity() == entity.getLowestRidingEntity() && !entity1.canRiderInteract()) - { - if (d2 == 0.0) - { -@@ -538,7 +539,7 @@ - f = f * 60.0F / 70.0F; - } - -- return f; -+ return net.minecraftforge.client.ForgeHooksClient.getFOVModifier(this, entity, iblockstate, partialTicks, f); - } - } - -@@ -604,13 +605,7 @@ - { - BlockPos blockpos = new BlockPos(entity); - IBlockState iblockstate = this.mc.world.getBlockState(blockpos); -- Block block = iblockstate.getBlock(); -- -- if (block == Blocks.BED) -- { -- int j = iblockstate.getValue(BlockBed.FACING).getHorizontalIndex(); -- GlStateManager.rotate(j * 90, 0.0F, 1.0F, 0.0F); -- } -+ net.minecraftforge.client.ForgeHooksClient.orientBedCamera(this.mc.world, blockpos, iblockstate, entity); - - GlStateManager.rotate(entity.prevRotationYaw + (entity.rotationYaw - entity.prevRotationYaw) * partialTicks + 180.0F, 0.0F, -1.0F, 0.0F); - GlStateManager.rotate(entity.prevRotationPitch + (entity.rotationPitch - entity.prevRotationPitch) * partialTicks, -1.0F, 0.0F, 0.0F); -@@ -680,19 +675,20 @@ - - if (!this.mc.gameSettings.debugCamEnable) - { -- GlStateManager.rotate(entity.prevRotationPitch + (entity.rotationPitch - entity.prevRotationPitch) * partialTicks, 1.0F, 0.0F, 0.0F); -- -+ float yaw = entity.prevRotationYaw + (entity.rotationYaw - entity.prevRotationYaw) * partialTicks + 180.0F; -+ float pitch = entity.prevRotationPitch + (entity.rotationPitch - entity.prevRotationPitch) * partialTicks; -+ float roll = 0.0F; - if (entity instanceof EntityAnimal) - { - EntityAnimal entityanimal = (EntityAnimal)entity; -- GlStateManager.rotate( -- entityanimal.prevRotationYawHead + (entityanimal.rotationYawHead - entityanimal.prevRotationYawHead) * partialTicks + 180.0F, 0.0F, 1.0F, 0.0F -- ); -- } -- else -- { -- GlStateManager.rotate(entity.prevRotationYaw + (entity.rotationYaw - entity.prevRotationYaw) * partialTicks + 180.0F, 0.0F, 1.0F, 0.0F); -- } -+ yaw = entityanimal.prevRotationYawHead + (entityanimal.rotationYawHead - entityanimal.prevRotationYawHead) * partialTicks + 180.0F; -+ } -+ IBlockState state = ActiveRenderInfo.getBlockStateAtEntityViewpoint(this.mc.world, entity, partialTicks); -+ net.minecraftforge.client.event.EntityViewRenderEvent.CameraSetup event = new net.minecraftforge.client.event.EntityViewRenderEvent.CameraSetup(this, entity, state, partialTicks, yaw, pitch, roll); -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event); -+ GlStateManager.rotate(event.getRoll(), 0.0F, 0.0F, 1.0F); -+ GlStateManager.rotate(event.getPitch(), 1.0F, 0.0F, 0.0F); -+ GlStateManager.rotate(event.getYaw(), 0.0F, 1.0F, 0.0F); - } - - GlStateManager.translate(0.0F, -f, 0.0F); -@@ -819,6 +815,7 @@ - boolean flag = this.mc.getRenderViewEntity() instanceof EntityLivingBase - && ((EntityLivingBase)this.mc.getRenderViewEntity()).isPlayerSleeping(); - -+ if (!net.minecraftforge.client.ForgeHooksClient.renderFirstPersonHand(mc.renderGlobal, partialTicks, pass)) - if (this.mc.gameSettings.thirdPersonView == 0 - && !flag - && !this.mc.gameSettings.hideGUI -@@ -926,6 +923,15 @@ - f10 = 0.25F + f7 * 0.75F; - } - -+ float[] colors = {f8, f9, f10}; -+ world.provider.getLightmapColors(partialTicks, f, f2, f3, colors); -+ f8 = colors[0]; f9 = colors[1]; f10 = colors[2]; -+ -+ // Forge: fix MC-58177 -+ f8 = MathHelper.clamp(f8, 0f, 1f); -+ f9 = MathHelper.clamp(f9, 0f, 1f); -+ f10 = MathHelper.clamp(f10, 0f, 1f); -+ - if (this.mc.player.isPotionActive(MobEffects.NIGHT_VISION)) - { - float f15 = this.getNightVisionBrightness(this.mc.player, partialTicks); -@@ -1102,7 +1108,17 @@ - j = Math.max(j, 60); - long k = System.nanoTime() - nanoTime; - long l = Math.max(1000000000 / j / 4 - k, 0L); -- this.renderWorld(partialTicks, System.nanoTime() + l); -+ -+ if (com.cleanroommc.kirino.KirinoCommonCore.KIRINO_CONFIG_HUB.isEnable() -+ && com.cleanroommc.kirino.KirinoCommonCore.KIRINO_CONFIG_HUB.isEnableRenderDelegate() -+ && !com.cleanroommc.kirino.KirinoClientCore.isRenderUnsupported()) -+ { -+ com.cleanroommc.kirino.KirinoClientCore.EntityRenderer$renderWorld(System.nanoTime() + l); -+ } -+ else -+ { -+ this.renderWorld(partialTicks, System.nanoTime() + l); -+ } - - if (this.mc.isSingleplayer() && this.timeWorldIcon < Minecraft.getSystemTime() - 1000L) - { -@@ -1152,6 +1168,10 @@ - GlStateManager.loadIdentity(); - this.setupOverlayRendering(); - this.renderEndNanoTime = System.nanoTime(); -+ // Forge: Fix MC-112292 -+ net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher.instance.renderEngine = this.mc.getTextureManager(); -+ // Forge: also fix rendering text before entering world (not part of MC-112292, but the same reason) -+ net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher.instance.fontRenderer = this.mc.fontRenderer; - } - - if (this.mc.currentScreen != null) -@@ -1160,7 +1180,7 @@ - - try - { -- this.mc.currentScreen.drawScreen(k1, l1, this.mc.getTickLength()); -+ net.minecraftforge.client.ForgeHooksClient.drawScreen(this.mc.currentScreen, k1, l1, this.mc.getTickLength()); - } - catch (Throwable throwable) - { -@@ -1269,7 +1289,7 @@ - - if (this.mc.playerController.getCurrentGameType() == GameType.SPECTATOR) - { -- flag = block.hasTileEntity() && this.mc.world.getTileEntity(blockpos) instanceof IInventory; -+ flag = block.hasTileEntity(this.mc.world.getBlockState(blockpos)) && this.mc.world.getTileEntity(blockpos) instanceof IInventory; - } - else - { -@@ -1317,6 +1337,17 @@ - - private void renderWorldPass(int pass, float partialTicks, long finishTimeNano) - { -+ if (com.cleanroommc.kirino.KirinoCommonCore.KIRINO_CONFIG_HUB.isEnable() -+ && (!com.cleanroommc.kirino.KirinoCommonCore.KIRINO_CONFIG_HUB.isEnableRenderDelegate() -+ || com.cleanroommc.kirino.KirinoClientCore.isRenderUnsupported())) -+ { -+ if (com.cleanroommc.kirino.KirinoCommonCore.KIRINO_ENGINE.isAfterFirstPrepare()) -+ { -+ com.cleanroommc.kirino.KirinoClientCore.runHeadlessly(com.cleanroommc.kirino.engine.FramePhase.PREPARE); -+ } -+ com.cleanroommc.kirino.KirinoClientCore.runHeadlessly(com.cleanroommc.kirino.engine.FramePhase.PRE_UPDATE); -+ } -+ - RenderGlobal renderglobal = this.mc.renderGlobal; - ParticleManager particlemanager = this.mc.effectRenderer; - boolean flag = this.isDrawBlockOutline(); -@@ -1327,7 +1358,7 @@ - GlStateManager.clear(16640); - this.mc.profiler.endStartSection("camera"); - this.setupCameraTransform(partialTicks, pass); -- ActiveRenderInfo.updateRenderInfo(this.mc.player, this.mc.gameSettings.thirdPersonView == 2); -+ ActiveRenderInfo.updateRenderInfo(this.mc.getRenderViewEntity(), this.mc.gameSettings.thirdPersonView == 2); //Forge: MC-46445 Spectator mode particles and sounds computed from where you have been before - this.mc.profiler.endStartSection("frustum"); - ClippingHelperImpl.getInstance(); - this.mc.profiler.endStartSection("culling"); -@@ -1368,6 +1399,14 @@ - this.renderCloudsCheck(renderglobal, partialTicks, pass, d0, d1, d2); - } - -+ if (com.cleanroommc.kirino.KirinoCommonCore.KIRINO_CONFIG_HUB.isEnable() -+ && (!com.cleanroommc.kirino.KirinoCommonCore.KIRINO_CONFIG_HUB.isEnableRenderDelegate() -+ || com.cleanroommc.kirino.KirinoClientCore.isRenderUnsupported())) -+ { -+ com.cleanroommc.kirino.KirinoClientCore.runHeadlessly(com.cleanroommc.kirino.engine.FramePhase.UPDATE); -+ com.cleanroommc.kirino.KirinoClientCore.runHeadlessly(com.cleanroommc.kirino.engine.FramePhase.RENDER_OPAQUE); -+ } -+ - this.mc.profiler.endStartSection("prepareterrain"); - this.setupFog(0, partialTicks); - this.mc.getTextureManager().bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); -@@ -1387,7 +1426,9 @@ - GlStateManager.disableAlpha(); - renderglobal.renderBlockLayer(BlockRenderLayer.SOLID, partialTicks, pass, entity); - GlStateManager.enableAlpha(); -+ this.mc.getTextureManager().getTexture(TextureMap.LOCATION_BLOCKS_TEXTURE).setBlurMipmap(false, this.mc.gameSettings.mipmapLevels > 0); // FORGE: fix flickering leaves when mods mess up the blurMipmap settings - renderglobal.renderBlockLayer(BlockRenderLayer.CUTOUT_MIPPED, partialTicks, pass, entity); -+ this.mc.getTextureManager().getTexture(TextureMap.LOCATION_BLOCKS_TEXTURE).restoreLastBlurMipmap(); - this.mc.getTextureManager().getTexture(TextureMap.LOCATION_BLOCKS_TEXTURE).setBlurMipmap(false, false); - renderglobal.renderBlockLayer(BlockRenderLayer.CUTOUT, partialTicks, pass, entity); - this.mc.getTextureManager().getTexture(TextureMap.LOCATION_BLOCKS_TEXTURE).restoreLastBlurMipmap(); -@@ -1401,7 +1442,9 @@ - GlStateManager.pushMatrix(); - RenderHelper.enableStandardItemLighting(); - this.mc.profiler.endStartSection("entities"); -+ net.minecraftforge.client.ForgeHooksClient.setRenderPass(0); - renderglobal.renderEntities(entity, icamera, partialTicks); -+ net.minecraftforge.client.ForgeHooksClient.setRenderPass(0); - RenderHelper.disableStandardItemLighting(); - this.disableLightmap(); - } -@@ -1414,6 +1457,7 @@ - EntityPlayer entityplayer = (EntityPlayer)entity; - GlStateManager.disableAlpha(); - this.mc.profiler.endStartSection("outline"); -+ if (!net.minecraftforge.client.ForgeHooksClient.onDrawBlockHighlight(renderglobal, entityplayer, mc.objectMouseOver, 0, partialTicks)) - renderglobal.drawSelectionBox(entityplayer, this.mc.objectMouseOver, 0, partialTicks); - GlStateManager.enableAlpha(); - } -@@ -1462,8 +1506,27 @@ - GlStateManager.depthMask(false); - this.mc.getTextureManager().bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); - GlStateManager.shadeModel(7425); -+ -+ if (com.cleanroommc.kirino.KirinoCommonCore.KIRINO_CONFIG_HUB.isEnable() -+ && (!com.cleanroommc.kirino.KirinoCommonCore.KIRINO_CONFIG_HUB.isEnableRenderDelegate() -+ || com.cleanroommc.kirino.KirinoClientCore.isRenderUnsupported())) -+ { -+ com.cleanroommc.kirino.KirinoClientCore.runHeadlessly(com.cleanroommc.kirino.engine.FramePhase.RENDER_TRANSPARENT); -+ } -+ - this.mc.profiler.endStartSection("translucent"); - renderglobal.renderBlockLayer(BlockRenderLayer.TRANSLUCENT, partialTicks, pass, entity); -+ if (!this.debugView) //Only render if render pass 0 happens as well. -+ { -+ RenderHelper.enableStandardItemLighting(); -+ this.mc.profiler.endStartSection("entities"); -+ net.minecraftforge.client.ForgeHooksClient.setRenderPass(1); -+ renderglobal.renderEntities(entity, icamera, partialTicks); -+ // restore blending function changed by RenderGlobal.preRenderDamagedBlocks -+ GlStateManager.tryBlendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO); -+ net.minecraftforge.client.ForgeHooksClient.setRenderPass(-1); -+ RenderHelper.disableStandardItemLighting(); -+ } - GlStateManager.shadeModel(7424); - GlStateManager.depthMask(true); - GlStateManager.enableCull(); -@@ -1476,6 +1539,9 @@ - this.renderCloudsCheck(renderglobal, partialTicks, pass, d0, d1, d2); - } - -+ this.mc.profiler.endStartSection("forge_render_last"); -+ net.minecraftforge.client.ForgeHooksClient.dispatchRenderLast(renderglobal, partialTicks); -+ - this.mc.profiler.endStartSection("hand"); - - if (this.renderHand) -@@ -1483,6 +1549,14 @@ - GlStateManager.clear(256); - this.renderHand(partialTicks, pass); - } -+ -+ if (com.cleanroommc.kirino.KirinoCommonCore.KIRINO_CONFIG_HUB.isEnable() -+ && (!com.cleanroommc.kirino.KirinoCommonCore.KIRINO_CONFIG_HUB.isEnableRenderDelegate() -+ || com.cleanroommc.kirino.KirinoClientCore.isRenderUnsupported())) -+ { -+ com.cleanroommc.kirino.KirinoClientCore.runHeadlessly(com.cleanroommc.kirino.engine.FramePhase.POST_UPDATE); -+ com.cleanroommc.kirino.KirinoClientCore.runHeadlessly(com.cleanroommc.kirino.engine.FramePhase.RENDER_OVERLAY); -+ } - } - - private void renderCloudsCheck(RenderGlobal renderGlobalIn, float partialTicks, int pass, double x, double y, double z) -@@ -1620,6 +1694,13 @@ - - protected void renderRainSnow(float partialTicks) - { -+ net.minecraftforge.client.IRenderHandler renderer = this.mc.world.provider.getWeatherRenderer(); -+ if (renderer != null) -+ { -+ renderer.render(partialTicks, this.mc.world, mc); -+ return; -+ } -+ - float f = this.mc.world.getRainStrength(partialTicks); - - if (!(f <= 0.0F)) -@@ -1893,29 +1974,16 @@ - this.fogColorGreen = (float)vec3d3.y; - this.fogColorBlue = (float)vec3d3.z; - } -- else if (iblockstate.getMaterial() == Material.WATER) -- { -- float f12 = 0.0F; -- -- if (entity instanceof EntityLivingBase) -- { -- f12 = EnchantmentHelper.getRespirationModifier((EntityLivingBase)entity) * 0.2F; -- -- if (((EntityLivingBase)entity).isPotionActive(MobEffects.WATER_BREATHING)) -- { -- f12 = f12 * 0.3F + 0.6F; -- } -- } -- -- this.fogColorRed = 0.02F + f12; -- this.fogColorGreen = 0.02F + f12; -- this.fogColorBlue = 0.2F + f12; -- } -- else if (iblockstate.getMaterial() == Material.LAVA) -- { -- this.fogColorRed = 0.6F; -- this.fogColorGreen = 0.1F; -- this.fogColorBlue = 0.0F; -+ else -+ { -+ //Forge Moved to Block. -+ Vec3d viewport = ActiveRenderInfo.projectViewFromEntity(entity, partialTicks); -+ BlockPos viewportPos = new BlockPos(viewport); -+ IBlockState viewportState = this.mc.world.getBlockState(viewportPos); -+ Vec3d inMaterialColor = viewportState.getBlock().getFogColor(this.mc.world, viewportPos, viewportState, entity, new Vec3d(fogColorRed, fogColorGreen, fogColorBlue), partialTicks); -+ this.fogColorRed = (float)inMaterialColor.x; -+ this.fogColorGreen = (float)inMaterialColor.y; -+ this.fogColorBlue = (float)inMaterialColor.z; - } - - float f13 = this.fogColor2 + (this.fogColor1 - this.fogColor2) * partialTicks; -@@ -1974,6 +2042,9 @@ - f6 = 1.0F / this.fogColorBlue; - } - -+ // Forge: fix MC-4647 and MC-10480 -+ if (Float.isInfinite(f6)) f6 = Math.nextAfter(f6, 0.0); -+ - this.fogColorRed = this.fogColorRed * (1.0F - f15) + this.fogColorRed * f6 * f15; - this.fogColorGreen = this.fogColorGreen * (1.0F - f15) + this.fogColorGreen * f6 * f15; - this.fogColorBlue = this.fogColorBlue * (1.0F - f15) + this.fogColorBlue * f6 * f15; -@@ -1989,6 +2060,13 @@ - this.fogColorBlue = f7; - } - -+ net.minecraftforge.client.event.EntityViewRenderEvent.FogColors event = new net.minecraftforge.client.event.EntityViewRenderEvent.FogColors(this, entity, iblockstate, partialTicks, this.fogColorRed, this.fogColorGreen, this.fogColorBlue); -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event); -+ -+ this.fogColorRed = event.getRed(); -+ this.fogColorGreen = event.getGreen(); -+ this.fogColorBlue = event.getBlue(); -+ - GlStateManager.clearColor(this.fogColorRed, this.fogColorGreen, this.fogColorBlue, 0.0F); - } - -@@ -1999,7 +2077,9 @@ - GlStateManager.glNormal3f(0.0F, -1.0F, 0.0F); - GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); - IBlockState iblockstate = ActiveRenderInfo.getBlockStateAtEntityViewpoint(this.mc.world, entity, partialTicks); -- -+ float hook = net.minecraftforge.client.ForgeHooksClient.getFogDensity(this, entity, iblockstate, partialTicks, 0.1F); -+ if (hook >= 0) GlStateManager.setFogDensity(hook); -+ else - if (entity instanceof EntityLivingBase && ((EntityLivingBase)entity).isPotionActive(MobEffects.BLINDNESS)) - { - float f1 = 5.0F; -@@ -2085,6 +2165,7 @@ - GlStateManager.setFogStart(f * 0.05F); - GlStateManager.setFogEnd(Math.min(f, 192.0F) * 0.5F); - } -+ net.minecraftforge.client.ForgeHooksClient.onFogRender(this, entity, iblockstate, partialTicks, startCoords, f); - } - - GlStateManager.enableColorMaterial(); diff --git a/patches/minecraft/net/minecraft/client/renderer/InventoryEffectRenderer.java.patch b/patches/minecraft/net/minecraft/client/renderer/InventoryEffectRenderer.java.patch deleted file mode 100644 index ff80c61b4..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/InventoryEffectRenderer.java.patch +++ /dev/null @@ -1,40 +0,0 @@ ---- before/net/minecraft/client/renderer/InventoryEffectRenderer.java -+++ after/net/minecraft/client/renderer/InventoryEffectRenderer.java -@@ -29,13 +29,19 @@ - - protected void updateActivePotionEffects() - { -- if (this.mc.player.getActivePotionEffects().isEmpty()) -+ boolean hasVisibleEffect = false; -+ for(PotionEffect potioneffect : this.mc.player.getActivePotionEffects()) { -+ Potion potion = potioneffect.getPotion(); -+ if(potion.shouldRender(potioneffect)) { hasVisibleEffect = true; break; } -+ } -+ if (this.mc.player.getActivePotionEffects().isEmpty() || !hasVisibleEffect) - { - this.guiLeft = (this.width - this.xSize) / 2; - this.hasActivePotionEffects = false; - } - else - { -+ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.GuiScreenEvent.PotionShiftEvent(this))) this.guiLeft = (this.width - this.xSize) / 2; else - this.guiLeft = 160 + (this.width - this.xSize - 200) / 2; - this.hasActivePotionEffects = true; - } -@@ -73,6 +79,7 @@ - for (PotionEffect potioneffect : Ordering.natural().sortedCopy(collection)) - { - Potion potion = potioneffect.getPotion(); -+ if(!potion.shouldRender(potioneffect)) continue; - GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); - this.mc.getTextureManager().bindTexture(INVENTORY_BACKGROUND); - this.drawTexturedModalRect(i, j, 0, 166, 140, 32); -@@ -83,6 +90,8 @@ - this.drawTexturedModalRect(i + 6, j + 7, 0 + i1 % 8 * 18, 198 + i1 / 8 * 18, 18, 18); - } - -+ potion.renderInventoryEffect(potioneffect, this, i, j, this.zLevel); -+ if (!potion.shouldRenderInvText(potioneffect)) { j += l; continue; } - String s1 = I18n.format(potion.getName()); - - if (potioneffect.getAmplifier() == 1) diff --git a/patches/minecraft/net/minecraft/client/renderer/ItemModelMesher.java.patch b/patches/minecraft/net/minecraft/client/renderer/ItemModelMesher.java.patch deleted file mode 100644 index 6d59f82e6..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/ItemModelMesher.java.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- before/net/minecraft/client/renderer/ItemModelMesher.java -+++ after/net/minecraft/client/renderer/ItemModelMesher.java -@@ -33,7 +33,9 @@ - - public TextureAtlasSprite getParticleIcon(Item item, int meta) - { -- return this.getItemModel(new ItemStack(item, 1, meta)).getParticleTexture(); -+ ItemStack stack = new ItemStack(item, 1, meta); -+ IBakedModel model = this.getItemModel(stack); -+ return model.getOverrides().handleItemState(model, stack, null, null).getParticleTexture(); - } - - public IBakedModel getItemModel(ItemStack stack) diff --git a/patches/minecraft/net/minecraft/client/renderer/ItemRenderer.java.patch b/patches/minecraft/net/minecraft/client/renderer/ItemRenderer.java.patch deleted file mode 100644 index 4ab6b1bf2..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/ItemRenderer.java.patch +++ /dev/null @@ -1,103 +0,0 @@ ---- before/net/minecraft/client/renderer/ItemRenderer.java -+++ after/net/minecraft/client/renderer/ItemRenderer.java -@@ -222,7 +222,7 @@ - bufferbuilder.pos(135.0, -7.0, 0.0).tex(1.0, 0.0).endVertex(); - bufferbuilder.pos(-7.0, -7.0, 0.0).tex(0.0, 0.0).endVertex(); - tessellator.draw(); -- MapData mapdata = Items.FILLED_MAP.getMapData(stack, this.mc.world); -+ MapData mapdata = ((net.minecraft.item.ItemMap) stack.getItem()).getMapData(stack, this.mc.world); - - if (mapdata != null) - { -@@ -318,7 +318,7 @@ - { - ItemStack itemstack = abstractclientplayer.getActiveItemStack(); - -- if (itemstack.getItem() == Items.BOW) -+ if (itemstack.getItem() instanceof net.minecraft.item.ItemBow) - { - EnumHand enumhand1 = abstractclientplayer.getActiveHand(); - flag = enumhand1 == EnumHand.MAIN_HAND; -@@ -335,6 +335,7 @@ - { - float f3 = enumhand == EnumHand.MAIN_HAND ? f : 0.0F; - float f5 = 1.0F - (this.prevEquippedProgressMainHand + (this.equippedProgressMainHand - this.prevEquippedProgressMainHand) * partialTicks); -+ if(!net.minecraftforge.client.ForgeHooksClient.renderSpecificFirstPersonHand(EnumHand.MAIN_HAND, partialTicks, f1, f3, f5, this.itemStackMainHand)) - this.renderItemInFirstPerson(abstractclientplayer, partialTicks, f1, EnumHand.MAIN_HAND, f3, this.itemStackMainHand, f5); - } - -@@ -342,6 +343,7 @@ - { - float f4 = enumhand == EnumHand.OFF_HAND ? f : 0.0F; - float f6 = 1.0F - (this.prevEquippedProgressOffHand + (this.equippedProgressOffHand - this.prevEquippedProgressOffHand) * partialTicks); -+ if(!net.minecraftforge.client.ForgeHooksClient.renderSpecificFirstPersonHand(EnumHand.OFF_HAND, partialTicks, f1, f4, f6, this.itemStackOffHand)) - this.renderItemInFirstPerson(abstractclientplayer, partialTicks, f1, EnumHand.OFF_HAND, f4, this.itemStackOffHand, f6); - } - -@@ -364,7 +366,7 @@ - this.renderArmFirstPerson(p_187457_7_, p_187457_5_, enumhandside); - } - } -- else if (stack.getItem() == Items.FILLED_MAP) -+ else if (stack.getItem() instanceof net.minecraft.item.ItemMap) - { - if (flag && this.itemStackOffHand.isEmpty()) - { -@@ -453,6 +455,7 @@ - if (this.mc.player.isEntityInsideOpaqueBlock()) - { - IBlockState iblockstate = this.mc.world.getBlockState(new BlockPos(this.mc.player)); -+ BlockPos overlayPos = new BlockPos(this.mc.player); - EntityPlayer entityplayer = this.mc.player; - - for (int i = 0; i < 8; i++) -@@ -466,11 +469,13 @@ - if (iblockstate1.causesSuffocation()) - { - iblockstate = iblockstate1; -+ overlayPos = blockpos; - } - } - - if (iblockstate.getRenderType() != EnumBlockRenderType.INVISIBLE) - { -+ if (!net.minecraftforge.event.ForgeEventFactory.renderBlockOverlay(mc.player, partialTicks, net.minecraftforge.client.event.RenderBlockOverlayEvent.OverlayType.BLOCK, iblockstate, overlayPos)) - this.renderSuffocationOverlay(this.mc.getBlockRendererDispatcher().getBlockModelShapes().getTexture(iblockstate)); - } - } -@@ -479,11 +484,13 @@ - { - if (this.mc.player.isInsideOfMaterial(Material.WATER)) - { -+ if (!net.minecraftforge.event.ForgeEventFactory.renderWaterOverlay(mc.player, partialTicks)) - this.renderWaterOverlayTexture(partialTicks); - } - - if (this.mc.player.isBurning()) - { -+ if (!net.minecraftforge.event.ForgeEventFactory.renderFireOverlay(mc.player, partialTicks)) - this.renderFireInFirstPerson(); - } - } -@@ -609,10 +616,17 @@ - else - { - float f = entityplayersp.getCooledAttackStrength(1.0F); -- this.equippedProgressMainHand = this.equippedProgressMainHand -- + MathHelper.clamp((Objects.equals(this.itemStackMainHand, itemstack) ? f * f * f : 0.0F) - this.equippedProgressMainHand, -0.4F, 0.4F); -- this.equippedProgressOffHand = this.equippedProgressOffHand -- + MathHelper.clamp((Objects.equals(this.itemStackOffHand, itemstack1) ? 1 : 0) - this.equippedProgressOffHand, -0.4F, 0.4F); -+ -+ boolean requipM = net.minecraftforge.client.ForgeHooksClient.shouldCauseReequipAnimation(this.itemStackMainHand, itemstack, entityplayersp.inventory.currentItem); -+ boolean requipO = net.minecraftforge.client.ForgeHooksClient.shouldCauseReequipAnimation(this.itemStackOffHand, itemstack1, -1); -+ -+ if (!requipM && !Objects.equals(this.itemStackMainHand, itemstack)) -+ this.itemStackMainHand = itemstack; -+ if (!requipM && !Objects.equals(this.itemStackOffHand, itemstack1)) -+ this.itemStackOffHand = itemstack1; -+ -+ this.equippedProgressMainHand += MathHelper.clamp((!requipM ? f * f * f : 0.0F) - this.equippedProgressMainHand, -0.4F, 0.4F); -+ this.equippedProgressOffHand += MathHelper.clamp((!requipO ? 1 : 0) - this.equippedProgressOffHand, -0.4F, 0.4F); - } - - if (this.equippedProgressMainHand < 0.1F) diff --git a/patches/minecraft/net/minecraft/client/renderer/OpenGlHelper.java.patch b/patches/minecraft/net/minecraft/client/renderer/OpenGlHelper.java.patch deleted file mode 100644 index 750b36a1a..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/OpenGlHelper.java.patch +++ /dev/null @@ -1,118 +0,0 @@ ---- before/net/minecraft/client/renderer/OpenGlHelper.java -+++ after/net/minecraft/client/renderer/OpenGlHelper.java -@@ -31,8 +31,8 @@ - import org.lwjgl.opengl.GL20; - import org.lwjgl.opengl.GL30; - import org.lwjgl.opengl.GLContext; --import oshi.SystemInfo; --import oshi.hardware.Processor; -+import oshi.ffm.SystemInfo; -+import oshi.hardware.CentralProcessor; - - @SideOnly(Side.CLIENT) - public class OpenGlHelper -@@ -93,6 +93,10 @@ - public static int GL_ARRAY_BUFFER; - public static int GL_STATIC_DRAW; - -+ /* Stores the last values sent into setLightmapTextureCoords */ -+ public static float lastBrightnessX = 0.0f; -+ public static float lastBrightnessY = 0.0f; -+ - public static void initializeTextures() - { - ContextCapabilities contextcapabilities = GLContext.getCapabilities(); -@@ -296,8 +300,8 @@ - - try - { -- Processor[] aprocessor = new SystemInfo().getHardware().getProcessors(); -- cpu = String.format("%dx %s", aprocessor.length, aprocessor[0]).replaceAll("\\s+", " "); -+ CentralProcessor aprocessor = (new SystemInfo()).getHardware().getProcessor(); -+ cpu = String.format("%dx %s", aprocessor.getLogicalProcessorCount(), aprocessor.getProcessorIdentifier().getName()).replaceAll("\\s+", " "); - } - catch (Throwable throwable) - { -@@ -854,6 +858,12 @@ - { - GL13.glMultiTexCoord2f(target, x, y); - } -+ -+ if (target == lightmapTexUnit) -+ { -+ lastBrightnessX = x; -+ lastBrightnessY = y; -+ } - } - - public static void glBlendFunc(int sFactorRGB, int dFactorRGB, int sfactorAlpha, int dfactorAlpha) -@@ -916,54 +926,23 @@ - - public static void openFile(File fileIn) - { -- String s = fileIn.getAbsolutePath(); -- -- if (Util.getOSType() == Util.EnumOS.OSX) -- { -- try -- { -- LOGGER.info(s); -- Runtime.getRuntime().exec(new String[] {"/usr/bin/open", s}); -- return; -- } -- catch (IOException ioexception1) -- { -- LOGGER.error("Couldn't open file", (Throwable)ioexception1); -- } -- } -- else if (Util.getOSType() == Util.EnumOS.WINDOWS) -- { -- String s1 = String.format("cmd.exe /C start \"Open file\" \"%s\"", s); -- -- try -- { -- Runtime.getRuntime().exec(s1); -- return; -- } -- catch (IOException ioexception) -- { -- LOGGER.error("Couldn't open file", (Throwable)ioexception); -- } -- } -- -- boolean flag = false; -- - try - { -- Class oclass = Class.forName("java.awt.Desktop"); -- Object object = oclass.getMethod("getDesktop").invoke(null); -- oclass.getMethod("browse", URI.class).invoke(object, fileIn.toURI()); -- } -- catch (Throwable throwable) -- { -- LOGGER.error("Couldn't open link", throwable); -- flag = true; -- } -- -- if (flag) -- { -- LOGGER.info("Opening via system class!"); -- Sys.openURL("file://" + s); -+ if (!java.awt.Desktop.isDesktopSupported()) -+ { -+ LOGGER.warn("Desktop API is not supported"); -+ return; -+ } -+ java.awt.Desktop desktop = java.awt.Desktop.getDesktop(); -+ if (!desktop.isSupported(java.awt.Desktop.Action.OPEN)) -+ { -+ LOGGER.warn("Opening files is not supported."); -+ return; -+ } -+ desktop.open(fileIn); -+ } catch (IOException e) -+ { -+ LOGGER.error("Could not open: " + fileIn.getAbsolutePath(), e); - } - } - diff --git a/patches/minecraft/net/minecraft/client/renderer/RenderGlobal.java.patch b/patches/minecraft/net/minecraft/client/renderer/RenderGlobal.java.patch deleted file mode 100644 index 6dccddcb6..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/RenderGlobal.java.patch +++ /dev/null @@ -1,174 +0,0 @@ ---- before/net/minecraft/client/renderer/RenderGlobal.java -+++ after/net/minecraft/client/renderer/RenderGlobal.java -@@ -560,8 +560,10 @@ - - public void renderEntities(Entity renderViewEntity, ICamera camera, float partialTicks) - { -+ int pass = net.minecraftforge.client.MinecraftForgeClient.getRenderPass(); - if (this.renderEntitiesStartupCounter > 0) - { -+ if (pass > 0) return; - this.renderEntitiesStartupCounter--; - } - else -@@ -588,9 +590,12 @@ - this.mc.gameSettings, - partialTicks - ); -+ if(pass == 0) -+ { - this.countEntitiesTotal = 0; - this.countEntitiesRendered = 0; - this.countEntitiesHidden = 0; -+ } - Entity entity = this.mc.getRenderViewEntity(); - double d3 = entity.lastTickPosX + (entity.posX - entity.lastTickPosX) * partialTicks; - double d4 = entity.lastTickPosY + (entity.posY - entity.lastTickPosY) * partialTicks; -@@ -602,11 +607,15 @@ - this.mc.entityRenderer.enableLightmap(); - this.world.profiler.endStartSection("global"); - List list = this.world.getLoadedEntityList(); -+ if (pass == 0) -+ { - this.countEntitiesTotal = list.size(); -+ } - - for (int i = 0; i < this.world.weatherEffects.size(); i++) - { - Entity entity1 = this.world.weatherEffects.get(i); -+ if (!entity1.shouldRenderInPass(pass)) continue; - this.countEntitiesRendered++; - - if (entity1.isInRangeToRender3d(d0, d1, d2)) -@@ -632,6 +641,7 @@ - { - for (Entity entity2 : classinheritancemultimap) - { -+ if(!entity2.shouldRenderInPass(pass)) continue; - boolean flag = this.renderManager.shouldRender(entity2, camera, d0, d1, d2) || entity2.isRidingOrBeingRiddenBy(this.mc.player); - - if (flag) -@@ -675,6 +685,7 @@ - } - } - -+ if(pass == 0) - if (this.isRenderEntityOutlines() && (!list1.isEmpty() || this.entityOutlinesRendered)) - { - this.world.profiler.endStartSection("entityOutlines"); -@@ -714,6 +725,7 @@ - this.world.profiler.endStartSection("blockentities"); - RenderHelper.enableStandardItemLighting(); - -+ TileEntityRendererDispatcher.instance.preDrawBatch(); - for (RenderGlobal.ContainerLocalRenderInformation renderglobal$containerlocalrenderinformation1 : this.renderInfos) - { - List list3 = renderglobal$containerlocalrenderinformation1.renderChunk.getCompiledChunk().getTileEntities(); -@@ -722,6 +734,7 @@ - { - for (TileEntity tileentity2 : list3) - { -+ if (!tileentity2.shouldRenderInPass(pass) || !camera.isBoundingBoxInFrustum(tileentity2.getRenderBoundingBox())) continue; - TileEntityRendererDispatcher.instance.render(tileentity2, partialTicks, -1); - } - } -@@ -731,9 +744,11 @@ - { - for (TileEntity tileentity : this.setTileEntities) - { -+ if (!tileentity.shouldRenderInPass(pass) || !camera.isBoundingBoxInFrustum(tileentity.getRenderBoundingBox())) continue; - TileEntityRendererDispatcher.instance.render(tileentity, partialTicks, -1); - } - } -+ TileEntityRendererDispatcher.instance.drawBatch(pass); - - this.preRenderDamagedBlocks(); - -@@ -951,7 +966,7 @@ - { - RenderChunk renderchunk1 = this.viewFrustum.getRenderChunk(new BlockPos((j << 4) + 8, i, (k << 4) + 8)); - -- if (renderchunk1 != null && camera.isBoundingBoxInFrustum(renderchunk1.boundingBox)) -+ if (renderchunk1 != null && camera.isBoundingBoxInFrustum(renderchunk1.boundingBox.expand(0.0, blockpos1.getY() > 0 ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY, 0.0))) // Forge: fix MC-73139 - { - renderchunk1.setFrameIndex(frameCount); - queue.add(new RenderGlobal.ContainerLocalRenderInformation(renderchunk1, null, 0)); -@@ -1013,7 +1028,7 @@ - BlockPos blockpos2 = renderchunk4.getPosition().add(8, 8, 8); - boolean flag3 = blockpos2.distanceSq(blockpos1) < 768.0; - -- if (!renderchunk4.needsImmediateUpdate() && !flag3) -+ if (net.minecraftforge.common.ForgeModContainer.alwaysSetupTerrainOffThread || (!renderchunk4.needsImmediateUpdate() && !flag3)) - { - this.chunksToUpdate.add(renderchunk4); - } -@@ -1316,6 +1331,13 @@ - - public void renderSky(float partialTicks, int pass) - { -+ net.minecraftforge.client.IRenderHandler renderer = this.world.provider.getSkyRenderer(); -+ if (renderer != null) -+ { -+ renderer.render(partialTicks, world, mc); -+ return; -+ } -+ - if (this.mc.world.provider.getDimensionType().getId() == 1) - { - this.renderSkyEnd(); -@@ -1542,6 +1564,7 @@ - - public void renderClouds(float partialTicks, int pass, double x, double y, double z) - { -+ if (net.minecraftforge.fml.client.FMLClientHandler.instance().renderClouds(this.cloudTickCounter, partialTicks)) return; - if (this.mc.world.provider.isSurfaceWorld()) - { - if (this.mc.gameSettings.shouldRenderClouds() == 2) -@@ -2046,7 +2069,7 @@ - ); - GlStateManager.enableBlend(); - GlStateManager.color(1.0F, 1.0F, 1.0F, 0.5F); -- GlStateManager.doPolygonOffset(-3.0F, -3.0F); -+ GlStateManager.doPolygonOffset(-1.0F, -10.0F); // FORGE: Fix MC-234 - GlStateManager.enablePolygonOffset(); - GlStateManager.alphaFunc(516, 0.1F); - GlStateManager.enableAlpha(); -@@ -2086,8 +2109,13 @@ - double d4 = blockpos.getY() - d1; - double d5 = blockpos.getZ() - d2; - Block block = this.world.getBlockState(blockpos).getBlock(); -+ TileEntity te = this.world.getTileEntity(blockpos); -+ boolean hasBreak = block instanceof BlockChest || block instanceof BlockEnderChest || block instanceof BlockSign || block instanceof BlockSkull; -+ if (!hasBreak) { -+ hasBreak = te != null && te.canRenderBreaking(); -+ } - -- if (!(block instanceof BlockChest) && !(block instanceof BlockEnderChest) && !(block instanceof BlockSign) && !(block instanceof BlockSkull)) -+ if (!hasBreak) - { - if (d3 * d3 + d4 * d4 + d5 * d5 > 1024.0) - { -@@ -2313,12 +2341,14 @@ - int j = pos.getY(); - int k = pos.getZ(); - this.markBlocksForUpdate(i - 1, j - 1, k - 1, i + 1, j + 1, k + 1, (flags & 8) != 0); -+ com.cleanroommc.kirino.KirinoClientCore.RenderGlobal$notifyBlockUpdate(i, j, k, oldState, newState); - } - - @Override - public void notifyLightSet(BlockPos pos) - { - this.setLightUpdates.add(pos.toImmutable()); -+ com.cleanroommc.kirino.KirinoClientCore.RenderGlobal$notifyLightUpdate(pos.getX(), pos.getY(), pos.getZ()); - } - - @Override -@@ -2820,7 +2850,7 @@ - - if (block.getDefaultState().getMaterial() != Material.AIR) - { -- SoundType soundtype = block.getSoundType(); -+ SoundType soundtype = block.getSoundType(Block.getStateById(data), this.world, blockPosIn, null); - this.world - .playSound( - blockPosIn, diff --git a/patches/minecraft/net/minecraft/client/renderer/RenderItem.java.patch b/patches/minecraft/net/minecraft/client/renderer/RenderItem.java.patch deleted file mode 100644 index f01a0b722..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/RenderItem.java.patch +++ /dev/null @@ -1,133 +0,0 @@ ---- before/net/minecraft/client/renderer/RenderItem.java -+++ after/net/minecraft/client/renderer/RenderItem.java -@@ -70,7 +70,7 @@ - public RenderItem(TextureManager p_i46552_1_, ModelManager p_i46552_2_, ItemColors p_i46552_3_) - { - this.textureManager = p_i46552_1_; -- this.itemModelMesher = new ItemModelMesher(p_i46552_2_); -+ this.itemModelMesher = new net.minecraftforge.client.ItemModelMesherForge(p_i46552_2_); - this.registerItems(); - this.itemColors = p_i46552_3_; - } -@@ -112,6 +112,11 @@ - - private void renderModel(IBakedModel model, int color, ItemStack stack) - { -+ if (net.minecraftforge.common.ForgeModContainer.allowEmissiveItems) -+ { -+ net.minecraftforge.client.ForgeHooksClient.renderLitItem(this, model, color, stack); -+ return; -+ } - Tessellator tessellator = Tessellator.getInstance(); - BufferBuilder bufferbuilder = tessellator.getBuffer(); - bufferbuilder.begin(7, DefaultVertexFormats.ITEM); -@@ -136,7 +141,7 @@ - { - GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); - GlStateManager.enableRescaleNormal(); -- TileEntityItemStackRenderer.instance.renderByItem(stack); -+ stack.getItem().getTileEntityItemStackRenderer().renderByItem(stack); - } - else - { -@@ -217,7 +222,7 @@ - k |= -16777216; - } - -- this.renderQuad(renderer, bakedquad, k); -+ net.minecraftforge.client.model.pipeline.LightUtil.renderQuadColor(renderer, bakedquad, k); - } - } - -@@ -239,19 +244,7 @@ - public IBakedModel getItemModelWithOverrides(ItemStack stack, @Nullable World worldIn, @Nullable EntityLivingBase entitylivingbaseIn) - { - IBakedModel ibakedmodel = this.itemModelMesher.getItemModel(stack); -- Item item = stack.getItem(); -- -- if (item != null && item.hasCustomProperties()) -- { -- ResourceLocation resourcelocation = ibakedmodel.getOverrides().applyOverride(stack, worldIn, entitylivingbaseIn); -- return resourcelocation == null -- ? ibakedmodel -- : this.itemModelMesher.getModelManager().getModel(new ModelResourceLocation(resourcelocation, "inventory")); -- } -- else -- { -- return ibakedmodel; -- } -+ return ibakedmodel.getOverrides().handleItemState(ibakedmodel, stack, worldIn, entitylivingbaseIn); - } - - public void renderItem(ItemStack stack, EntityLivingBase entitylivingbaseIn, ItemCameraTransforms.TransformType transform, boolean leftHanded) -@@ -280,13 +273,8 @@ - GlStateManager.DestFactor.ZERO - ); - GlStateManager.pushMatrix(); -- ItemCameraTransforms itemcameratransforms = bakedmodel.getItemCameraTransforms(); -- ItemCameraTransforms.applyTransformSide(itemcameratransforms.getTransform(transform), leftHanded); -- -- if (this.isThereOneNegativeScale(itemcameratransforms.getTransform(transform))) -- { -- GlStateManager.cullFace(GlStateManager.CullFace.FRONT); -- } -+ // TODO: check if negative scale is a thing -+ bakedmodel = net.minecraftforge.client.ForgeHooksClient.handleCameraTransforms(bakedmodel, transform, leftHanded); - - this.renderItem(stack, bakedmodel); - GlStateManager.cullFace(GlStateManager.CullFace.BACK); -@@ -320,7 +308,7 @@ - GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); - GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); - this.setupGuiTransform(x, y, bakedmodel.isGui3d()); -- bakedmodel.getItemCameraTransforms().applyTransform(ItemCameraTransforms.TransformType.GUI); -+ bakedmodel = net.minecraftforge.client.ForgeHooksClient.handleCameraTransforms(bakedmodel, ItemCameraTransforms.TransformType.GUI, false); - this.renderItem(stack, bakedmodel); - GlStateManager.disableAlpha(); - GlStateManager.disableRescaleNormal(); -@@ -373,6 +361,7 @@ - return String.valueOf(p_184391_2_.getItem()); - } - }); -+ crashreportcategory.addDetail("Registry Name", () -> String.valueOf(p_184391_2_.getItem().getRegistryName())); - crashreportcategory.addDetail("Item Aux", new ICrashReportDetail() - { - public String call() throws Exception -@@ -419,9 +408,12 @@ - fr.drawStringWithShadow(s, xPosition + 19 - 2 - fr.getStringWidth(s), yPosition + 6 + 3, 16777215); - GlStateManager.enableLighting(); - GlStateManager.enableDepth(); -+ // Fixes opaque cooldown overlay a bit lower -+ // TODO: check if enabled blending still screws things up down the line. -+ GlStateManager.enableBlend(); - } - -- if (stack.isItemDamaged()) -+ if (stack.getItem().showDurabilityBar(stack)) - { - GlStateManager.disableLighting(); - GlStateManager.disableDepth(); -@@ -430,11 +422,10 @@ - GlStateManager.disableBlend(); - Tessellator tessellator = Tessellator.getInstance(); - BufferBuilder bufferbuilder = tessellator.getBuffer(); -- float f = stack.getItemDamage(); -- float f1 = stack.getMaxDamage(); -- float f2 = Math.max(0.0F, (f1 - f) / f1); -- int i = Math.round(13.0F - f * 13.0F / f1); -- int j = MathHelper.hsvToRGB(f2 / 3.0F, 1.0F, 1.0F); -+ double health = stack.getItem().getDurabilityForDisplay(stack); -+ int rgbfordisplay = stack.getItem().getRGBDurabilityForDisplay(stack); -+ int i = Math.round(13.0F - (float)health * 13.0F); -+ int j = rgbfordisplay; - this.draw(bufferbuilder, xPosition + 2, yPosition + 13, 13, 2, 0, 0, 0, 255); - this.draw(bufferbuilder, xPosition + 2, yPosition + 13, i, 1, j >> 16 & 0xFF, j >> 8 & 0xFF, j & 0xFF, 255); - GlStateManager.enableBlend(); -@@ -1139,6 +1130,7 @@ - this.registerBlock(Blocks.STRUCTURE_BLOCK, TileEntityStructure.Mode.LOAD.getModeId(), "structure_block"); - this.registerBlock(Blocks.STRUCTURE_BLOCK, TileEntityStructure.Mode.CORNER.getModeId(), "structure_block"); - this.registerBlock(Blocks.STRUCTURE_BLOCK, TileEntityStructure.Mode.DATA.getModeId(), "structure_block"); -+ net.minecraftforge.client.model.ModelLoader.onRegisterItems(this.itemModelMesher); - } - - @Override diff --git a/patches/minecraft/net/minecraft/client/renderer/WorldVertexBufferUploader.java.patch b/patches/minecraft/net/minecraft/client/renderer/WorldVertexBufferUploader.java.patch deleted file mode 100644 index 00b5d06ed..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/WorldVertexBufferUploader.java.patch +++ /dev/null @@ -1,57 +0,0 @@ ---- before/net/minecraft/client/renderer/WorldVertexBufferUploader.java -+++ after/net/minecraft/client/renderer/WorldVertexBufferUploader.java -@@ -28,26 +28,8 @@ - int l = vertexformatelement.getIndex(); - ((Buffer)bytebuffer).position(vertexformat.getOffset(j)); - -- switch (vertexformatelement$enumusage) -- { -- case POSITION: -- GlStateManager.glVertexPointer(vertexformatelement.getElementCount(), k, i, bytebuffer); -- GlStateManager.glEnableClientState(32884); -- break; -- case UV: -- OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit + l); -- GlStateManager.glTexCoordPointer(vertexformatelement.getElementCount(), k, i, bytebuffer); -- GlStateManager.glEnableClientState(32888); -- OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit); -- break; -- case COLOR: -- GlStateManager.glColorPointer(vertexformatelement.getElementCount(), k, i, bytebuffer); -- GlStateManager.glEnableClientState(32886); -- break; -- case NORMAL: -- GlStateManager.glNormalPointer(k, i, bytebuffer); -- GlStateManager.glEnableClientState(32885); -- } -+ // moved to VertexFormatElement.preDraw -+ vertexformatelement.getUsage().preDraw(vertexformat, j, i, bytebuffer); - } - - GlStateManager.glDrawArrays(bufferBuilderIn.getDrawMode(), 0, bufferBuilderIn.getVertexCount()); -@@ -59,23 +41,8 @@ - VertexFormatElement.EnumUsage vertexformatelement$enumusage1 = vertexformatelement1.getUsage(); - int k1 = vertexformatelement1.getIndex(); - -- switch (vertexformatelement$enumusage1) -- { -- case POSITION: -- GlStateManager.glDisableClientState(32884); -- break; -- case UV: -- OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit + k1); -- GlStateManager.glDisableClientState(32888); -- OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit); -- break; -- case COLOR: -- GlStateManager.glDisableClientState(32886); -- GlStateManager.resetColor(); -- break; -- case NORMAL: -- GlStateManager.glDisableClientState(32885); -- } -+ // moved to VertexFormatElement.postDraw -+ vertexformatelement1.getUsage().postDraw(vertexformat, i1, i, bytebuffer); - } - } - diff --git a/patches/minecraft/net/minecraft/client/renderer/block/model/BakedQuad.java.patch b/patches/minecraft/net/minecraft/client/renderer/block/model/BakedQuad.java.patch deleted file mode 100644 index 59be2b4ed..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/block/model/BakedQuad.java.patch +++ /dev/null @@ -1,55 +0,0 @@ ---- before/net/minecraft/client/renderer/block/model/BakedQuad.java -+++ after/net/minecraft/client/renderer/block/model/BakedQuad.java -@@ -6,15 +6,26 @@ - import net.minecraftforge.fml.relauncher.SideOnly; - - @SideOnly(Side.CLIENT) --public class BakedQuad -+public class BakedQuad implements net.minecraftforge.client.model.pipeline.IVertexProducer - { - protected final int[] vertexData; - protected final int tintIndex; - protected final EnumFacing face; - protected final TextureAtlasSprite sprite; - -+ /** -+ * @deprecated Use constructor with the format argument. -+ */ -+ @Deprecated - public BakedQuad(int[] vertexDataIn, int tintIndexIn, EnumFacing faceIn, TextureAtlasSprite spriteIn) - { -+ this(vertexDataIn, tintIndexIn, faceIn, spriteIn, true, net.minecraft.client.renderer.vertex.DefaultVertexFormats.ITEM); -+ } -+ -+ public BakedQuad(int[] vertexDataIn, int tintIndexIn, EnumFacing faceIn, TextureAtlasSprite spriteIn, boolean applyDiffuseLighting, net.minecraft.client.renderer.vertex.VertexFormat format) -+ { -+ this.format = format; -+ this.applyDiffuseLighting = applyDiffuseLighting; - this.vertexData = vertexDataIn; - this.tintIndex = tintIndexIn; - this.face = faceIn; -@@ -44,5 +55,24 @@ - public EnumFacing getFace() - { - return this.face; -+ } -+ -+ protected final net.minecraft.client.renderer.vertex.VertexFormat format; -+ protected final boolean applyDiffuseLighting; -+ -+ @Override -+ public void pipe(net.minecraftforge.client.model.pipeline.IVertexConsumer consumer) -+ { -+ net.minecraftforge.client.model.pipeline.LightUtil.putBakedQuad(consumer, this); -+ } -+ -+ public net.minecraft.client.renderer.vertex.VertexFormat getFormat() -+ { -+ return format; -+ } -+ -+ public boolean shouldApplyDiffuseLighting() -+ { -+ return applyDiffuseLighting; - } - } diff --git a/patches/minecraft/net/minecraft/client/renderer/block/model/BakedQuadRetextured.java.patch b/patches/minecraft/net/minecraft/client/renderer/block/model/BakedQuadRetextured.java.patch deleted file mode 100644 index 8e68830ff..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/block/model/BakedQuadRetextured.java.patch +++ /dev/null @@ -1,39 +0,0 @@ ---- before/net/minecraft/client/renderer/block/model/BakedQuadRetextured.java -+++ after/net/minecraft/client/renderer/block/model/BakedQuadRetextured.java -@@ -16,7 +16,9 @@ - Arrays.copyOf(quad.getVertexData(), quad.getVertexData().length), - quad.tintIndex, - FaceBakery.getFacingFromVertexData(quad.getVertexData()), -- quad.getSprite() -+ quad.getSprite(), -+ quad.applyDiffuseLighting, -+ quad.format - ); - this.texture = textureIn; - this.remapQuad(); -@@ -26,13 +28,20 @@ - { - for (int i = 0; i < 4; i++) - { -- int j = 7 * i; -- this.vertexData[j + 4] = Float.floatToRawIntBits( -- this.texture.getInterpolatedU(this.sprite.getUnInterpolatedU(Float.intBitsToFloat(this.vertexData[j + 4]))) -+ int j = format.getIntegerSize() * i; -+ int uvIndex = format.getUvOffsetById(0) / 4; -+ this.vertexData[j + uvIndex] = Float.floatToRawIntBits( -+ this.texture.getInterpolatedU(this.sprite.getUnInterpolatedU(Float.intBitsToFloat(this.vertexData[j + uvIndex]))) - ); -- this.vertexData[j + 4 + 1] = Float.floatToRawIntBits( -- this.texture.getInterpolatedV(this.sprite.getUnInterpolatedV(Float.intBitsToFloat(this.vertexData[j + 4 + 1]))) -+ this.vertexData[j + uvIndex + 1] = Float.floatToRawIntBits( -+ this.texture.getInterpolatedV(this.sprite.getUnInterpolatedV(Float.intBitsToFloat(this.vertexData[j + uvIndex + 1]))) - ); - } -+ } -+ -+ @Override -+ public TextureAtlasSprite getSprite() -+ { -+ return texture; - } - } diff --git a/patches/minecraft/net/minecraft/client/renderer/block/model/FaceBakery.java.patch b/patches/minecraft/net/minecraft/client/renderer/block/model/FaceBakery.java.patch deleted file mode 100644 index 789ad935e..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/block/model/FaceBakery.java.patch +++ /dev/null @@ -1,150 +0,0 @@ ---- before/net/minecraft/client/renderer/block/model/FaceBakery.java -+++ after/net/minecraft/client/renderer/block/model/FaceBakery.java -@@ -63,15 +63,40 @@ - boolean shade - ) - { -+ return makeBakedQuad( -+ posFrom, -+ posTo, -+ face, -+ sprite, -+ facing, -+ (net.minecraftforge.common.model.ITransformation)modelRotationIn, -+ partRotation, -+ uvLocked, -+ shade -+ ); -+ } -+ -+ public BakedQuad makeBakedQuad( -+ Vector3f posFrom, -+ Vector3f posTo, -+ BlockPartFace face, -+ TextureAtlasSprite sprite, -+ EnumFacing facing, -+ net.minecraftforge.common.model.ITransformation modelRotationIn, -+ BlockPartRotation partRotation, -+ boolean uvLocked, -+ boolean shade -+ ) -+ { - BlockFaceUV blockfaceuv = face.blockFaceUV; - - if (uvLocked) - { -- blockfaceuv = this.applyUVLock(face.blockFaceUV, facing, modelRotationIn); -+ blockfaceuv = net.minecraftforge.client.ForgeHooksClient.applyUVLock(face.blockFaceUV, facing, modelRotationIn); - } - - int[] aint = this.makeQuadVertexData( -- blockfaceuv, sprite, facing, this.getPositionsDiv16(posFrom, posTo), modelRotationIn, partRotation, shade -+ blockfaceuv, sprite, facing, this.getPositionsDiv16(posFrom, posTo), modelRotationIn, partRotation, false - ); - EnumFacing enumfacing = getFacingFromVertexData(aint); - -@@ -80,7 +105,8 @@ - this.applyFacing(aint, enumfacing); - } - -- return new BakedQuad(aint, face.tintIndex, enumfacing, sprite); -+ net.minecraftforge.client.ForgeHooksClient.fillNormal(aint, enumfacing); -+ return new BakedQuad(aint, face.tintIndex, enumfacing, sprite, shade, net.minecraft.client.renderer.vertex.DefaultVertexFormats.ITEM); - } - - private BlockFaceUV applyUVLock(BlockFaceUV p_188010_1_, EnumFacing p_188010_2_, ModelRotation p_188010_3_) -@@ -98,6 +124,27 @@ - boolean shade - ) - { -+ return makeQuadVertexData( -+ uvs, -+ sprite, -+ orientation, -+ p_188012_4_, -+ (net.minecraftforge.common.model.ITransformation)rotationIn, -+ partRotation, -+ shade -+ ); -+ } -+ -+ private int[] makeQuadVertexData( -+ BlockFaceUV uvs, -+ TextureAtlasSprite sprite, -+ EnumFacing orientation, -+ float[] p_188012_4_, -+ net.minecraftforge.common.model.ITransformation rotationIn, -+ BlockPartRotation partRotation, -+ boolean shade -+ ) -+ { - int[] aint = new int[28]; - - for (int i = 0; i < 4; i++) -@@ -158,7 +205,32 @@ - boolean p_188015_9_ - ) - { -- EnumFacing enumfacing = p_188015_7_.rotateFace(p_188015_3_); -+ fillVertexData( -+ p_188015_1_, -+ p_188015_2_, -+ p_188015_3_, -+ p_188015_4_, -+ p_188015_5_, -+ p_188015_6_, -+ (net.minecraftforge.common.model.ITransformation)p_188015_7_, -+ p_188015_8_, -+ p_188015_9_ -+ ); -+ } -+ -+ private void fillVertexData( -+ int[] p_188015_1_, -+ int p_188015_2_, -+ EnumFacing p_188015_3_, -+ BlockFaceUV p_188015_4_, -+ float[] p_188015_5_, -+ TextureAtlasSprite p_188015_6_, -+ net.minecraftforge.common.model.ITransformation p_188015_7_, -+ BlockPartRotation p_188015_8_, -+ boolean p_188015_9_ -+ ) -+ { -+ EnumFacing enumfacing = p_188015_7_.rotate(p_188015_3_); - int i = p_188015_9_ ? this.getFaceShadeColor(enumfacing) : -1; - EnumFaceDirection.VertexInformation enumfacedirection$vertexinformation = EnumFaceDirection.getFacing(p_188015_3_).getVertexInformation(p_188015_2_); - Vector3f vector3f = new Vector3f( -@@ -180,8 +252,8 @@ - faceData[i + 1] = Float.floatToRawIntBits(position.y); - faceData[i + 2] = Float.floatToRawIntBits(position.z); - faceData[i + 3] = shadeColor; -- faceData[i + 4] = Float.floatToRawIntBits(sprite.getInterpolatedU(faceUV.getVertexU(vertexIndex))); -- faceData[i + 4 + 1] = Float.floatToRawIntBits(sprite.getInterpolatedV(faceUV.getVertexV(vertexIndex))); -+ faceData[i + 4] = Float.floatToRawIntBits(sprite.getInterpolatedU(faceUV.getVertexU(vertexIndex) * .999 + faceUV.getVertexU((vertexIndex + 2) % 4) * .001)); -+ faceData[i + 4 + 1] = Float.floatToRawIntBits(sprite.getInterpolatedV(faceUV.getVertexV(vertexIndex) * .999 + faceUV.getVertexV((vertexIndex + 2) % 4) * .001)); - } - - private void rotatePart(Vector3f p_178407_1_, @Nullable BlockPartRotation partRotation) -@@ -230,14 +302,19 @@ - - public int rotateVertex(Vector3f p_188011_1_, EnumFacing p_188011_2_, int p_188011_3_, ModelRotation p_188011_4_) - { -+ return rotateVertex(p_188011_1_, p_188011_2_, p_188011_3_, (net.minecraftforge.common.model.ITransformation)p_188011_4_); -+ } -+ -+ public int rotateVertex(Vector3f p_188011_1_, EnumFacing p_188011_2_, int p_188011_3_, net.minecraftforge.common.model.ITransformation p_188011_4_) -+ { - if (p_188011_4_ == ModelRotation.X0_Y0) - { - return p_188011_3_; - } - else - { -- this.rotateScale(p_188011_1_, new Vector3f(0.5F, 0.5F, 0.5F), p_188011_4_.matrix(), new Vector3f(1.0F, 1.0F, 1.0F)); -- return p_188011_4_.rotateVertex(p_188011_2_, p_188011_3_); -+ net.minecraftforge.client.ForgeHooksClient.transform(p_188011_1_, p_188011_4_.getMatrix()); -+ return p_188011_4_.rotate(p_188011_2_, p_188011_3_); - } - } - diff --git a/patches/minecraft/net/minecraft/client/renderer/block/model/IBakedModel.java.patch b/patches/minecraft/net/minecraft/client/renderer/block/model/IBakedModel.java.patch deleted file mode 100644 index 6a4c71065..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/block/model/IBakedModel.java.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- before/net/minecraft/client/renderer/block/model/IBakedModel.java -+++ after/net/minecraft/client/renderer/block/model/IBakedModel.java -@@ -21,7 +21,18 @@ - - TextureAtlasSprite getParticleTexture(); - -- ItemCameraTransforms getItemCameraTransforms(); -+ @Deprecated -+ default ItemCameraTransforms getItemCameraTransforms() { return ItemCameraTransforms.DEFAULT; } - - ItemOverrideList getOverrides(); -+ -+ default boolean isAmbientOcclusion(IBlockState state) { return isAmbientOcclusion(); } -+ -+ /* -+ * Returns the pair of the model for the given perspective, and the matrix -+ * that should be applied to the GL state before rendering it (matrix may be null). -+ */ -+ default org.apache.commons.lang3.tuple.Pair handlePerspective(ItemCameraTransforms.TransformType cameraTransformType) { -+ return net.minecraftforge.client.ForgeHooksClient.handlePerspective(this, cameraTransformType); -+ } - } diff --git a/patches/minecraft/net/minecraft/client/renderer/block/model/ItemCameraTransforms.java.patch b/patches/minecraft/net/minecraft/client/renderer/block/model/ItemCameraTransforms.java.patch deleted file mode 100644 index 81aad548e..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/block/model/ItemCameraTransforms.java.patch +++ /dev/null @@ -1,45 +0,0 @@ ---- before/net/minecraft/client/renderer/block/model/ItemCameraTransforms.java -+++ after/net/minecraft/client/renderer/block/model/ItemCameraTransforms.java -@@ -12,6 +12,9 @@ - import net.minecraftforge.fml.relauncher.SideOnly; - import org.lwjgl.util.vector.Quaternion; - -+/* -+ * @deprecated use {@link net.minecraftforge.client.model.IPerspectiveAwareModel} instead -+ */ - @SideOnly(Side.CLIENT) - public class ItemCameraTransforms - { -@@ -48,6 +51,7 @@ - ); - } - -+ @Deprecated - public ItemCameraTransforms(ItemCameraTransforms transforms) - { - this.thirdperson_left = transforms.thirdperson_left; -@@ -60,6 +64,7 @@ - this.fixed = transforms.fixed; - } - -+ @Deprecated - public ItemCameraTransforms( - ItemTransformVec3f thirdperson_leftIn, - ItemTransformVec3f thirdperson_rightIn, -@@ -125,6 +130,7 @@ - return new Quaternion(f3 * f6 * f8 + f4 * f5 * f7, f4 * f5 * f8 - f3 * f6 * f7, f3 * f5 * f8 + f4 * f6 * f7, f4 * f6 * f8 - f3 * f5 * f7); - } - -+ @Deprecated - public ItemTransformVec3f getTransform(ItemCameraTransforms.TransformType type) - { - switch (type) -@@ -202,7 +208,7 @@ - } - - @SideOnly(Side.CLIENT) -- public static enum TransformType -+ public static enum TransformType implements net.minecraftforge.common.model.IModelPart - { - NONE, - THIRD_PERSON_LEFT_HAND, diff --git a/patches/minecraft/net/minecraft/client/renderer/block/model/ItemOverrideList.java.patch b/patches/minecraft/net/minecraft/client/renderer/block/model/ItemOverrideList.java.patch deleted file mode 100644 index 52e7836c2..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/block/model/ItemOverrideList.java.patch +++ /dev/null @@ -1,34 +0,0 @@ ---- before/net/minecraft/client/renderer/block/model/ItemOverrideList.java -+++ after/net/minecraft/client/renderer/block/model/ItemOverrideList.java -@@ -29,6 +29,7 @@ - } - - @Nullable -+ @Deprecated - public ResourceLocation applyOverride(ItemStack stack, @Nullable World worldIn, @Nullable EntityLivingBase entityIn) - { - if (!this.overrides.isEmpty()) -@@ -43,5 +44,23 @@ - } - - return null; -+ } -+ -+ public IBakedModel handleItemState(IBakedModel originalModel, ItemStack stack, @Nullable World world, @Nullable EntityLivingBase entity) -+ { -+ if (!stack.isEmpty() && stack.getItem().hasCustomProperties()) -+ { -+ ResourceLocation location = applyOverride(stack, world, entity); -+ if (location != null) -+ { -+ return net.minecraft.client.Minecraft.getMinecraft().getRenderItem().getItemModelMesher().getModelManager().getModel(net.minecraftforge.client.model.ModelLoader.getInventoryVariant(location.toString())); -+ } -+ } -+ return originalModel; -+ } -+ -+ public com.google.common.collect.ImmutableList getOverrides() -+ { -+ return com.google.common.collect.ImmutableList.copyOf(overrides); - } - } diff --git a/patches/minecraft/net/minecraft/client/renderer/block/model/ItemTransformVec3f.java.patch b/patches/minecraft/net/minecraft/client/renderer/block/model/ItemTransformVec3f.java.patch deleted file mode 100644 index bca1eb3de..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/block/model/ItemTransformVec3f.java.patch +++ /dev/null @@ -1,18 +0,0 @@ ---- before/net/minecraft/client/renderer/block/model/ItemTransformVec3f.java -+++ after/net/minecraft/client/renderer/block/model/ItemTransformVec3f.java -@@ -13,9 +13,14 @@ - import net.minecraftforge.fml.relauncher.SideOnly; - import org.lwjgl.util.vector.Vector3f; - -+/* -+ * @deprecated use {@link net.minecraftforge.client.model.IModelState} and {@link net.minecraftforge.client.model.TRSRTransformation} -+ */ - @SideOnly(Side.CLIENT) --public class ItemTransformVec3f -+@Deprecated -+public class ItemTransformVec3f implements net.minecraftforge.common.model.IModelState - { -+ public java.util.Optional apply(java.util.Optional part) { return net.minecraftforge.client.ForgeHooksClient.applyTransform(this, part); } - public static final ItemTransformVec3f DEFAULT = new ItemTransformVec3f(new Vector3f(), new Vector3f(), new Vector3f(1.0F, 1.0F, 1.0F)); - public final Vector3f rotation; - public final Vector3f translation; diff --git a/patches/minecraft/net/minecraft/client/renderer/block/model/ModelBakery.java.patch b/patches/minecraft/net/minecraft/client/renderer/block/model/ModelBakery.java.patch deleted file mode 100644 index bcf9d2a12..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/block/model/ModelBakery.java.patch +++ /dev/null @@ -1,191 +0,0 @@ ---- before/net/minecraft/client/renderer/block/model/ModelBakery.java -+++ after/net/minecraft/client/renderer/block/model/ModelBakery.java -@@ -141,6 +141,21 @@ - { - try - { -+ loadBlock(blockstatemapper, block, resourcelocation); -+ } -+ catch (Exception exception) -+ { -+ LOGGER.warn((String)("Unable to load definition " + resourcelocation), (Throwable)exception); -+ } -+ } -+ } -+ } -+ -+ protected void loadBlock(BlockStateMapper blockstatemapper, Block block, final ResourceLocation resourcelocation) -+ { -+ { -+ { -+ { - ModelBlockDefinition modelblockdefinition = this.getModelBlockDefinition(resourcelocation); - Map map = blockstatemapper.getVariants(block); - -@@ -153,7 +168,6 @@ - if (collection1 == null) - { - collection1 = Lists.newArrayList(); -- this.multipartVariantMap.put(modelblockdefinition, collection1); - } - - collection1.addAll(Lists.newArrayList(Iterables.filter(collection, new Predicate() -@@ -163,6 +177,7 @@ - return resourcelocation.equals(p_apply_1_); - } - }))); -+ registerMultipartVariant(modelblockdefinition, collection1); - } - - for (Entry entry : map.entrySet()) -@@ -173,22 +188,18 @@ - { - try - { -- this.variants.put(modelresourcelocation, modelblockdefinition.getVariant(modelresourcelocation.getVariant())); -+ registerVariant(modelblockdefinition, modelresourcelocation); - } - catch (RuntimeException runtimeexception) - { - if (!modelblockdefinition.hasMultipartData()) - { -- LOGGER.warn("Unable to load variant: {} from {}", modelresourcelocation.getVariant(), modelresourcelocation); -+ LOGGER.warn("Unable to load variant: " + modelresourcelocation.getVariant() + " from " + modelresourcelocation, runtimeexception); - } - } - } - } - } -- catch (Exception exception) -- { -- LOGGER.warn("Unable to load definition {}", resourcelocation, exception); -- } - } - } - } -@@ -270,7 +281,7 @@ - try - { - inputstream = resource.getInputStream(); -- lvt_4_1_ = ModelBlockDefinition.parseFromReader(new InputStreamReader(inputstream, StandardCharsets.UTF_8)); -+ lvt_4_1_ = ModelBlockDefinition.parseFromReader(new InputStreamReader(inputstream, StandardCharsets.UTF_8), location); - } - catch (Exception exception) - { -@@ -443,6 +454,7 @@ - - protected void registerVariantNames() - { -+ this.variantNames.clear(); // FML clear this to prevent double ups. - this.variantNames - .put( - Item.getItemFromBlock(Blocks.STONE), -@@ -697,6 +709,10 @@ - this.variantNames.put(Items.OAK_DOOR, Lists.newArrayList("oak_door")); - this.variantNames.put(Items.BOAT, Lists.newArrayList("oak_boat")); - this.variantNames.put(Items.TOTEM_OF_UNDYING, Lists.newArrayList("totem")); -+ for (Entry, Set> e : customVariantNames.entrySet()) -+ { -+ this.variantNames.put(e.getKey().get(), Lists.newArrayList(e.getValue().iterator())); -+ } - } - - protected List getVariantNames(Item stack) -@@ -713,7 +729,7 @@ - - protected ResourceLocation getItemLocation(String location) - { -- ResourceLocation resourcelocation = new ResourceLocation(location); -+ ResourceLocation resourcelocation = new ResourceLocation(location.replaceAll("#.*", "")); - return new ResourceLocation(resourcelocation.getNamespace(), "item/" + resourcelocation.getPath()); - } - -@@ -818,7 +834,7 @@ - for (Entry entry : this.itemLocations.entrySet()) - { - ResourceLocation resourcelocation = entry.getValue(); -- ModelResourceLocation modelresourcelocation = new ModelResourceLocation(entry.getKey(), "inventory"); -+ ModelResourceLocation modelresourcelocation = net.minecraftforge.client.model.ModelLoader.getInventoryVariant(entry.getKey()); - ModelBlock modelblock = this.models.get(resourcelocation); - - if (modelblock == null || !modelblock.isResolved()) -@@ -905,6 +921,11 @@ - @Nullable - private IBakedModel bakeModel(ModelBlock modelBlockIn, ModelRotation modelRotationIn, boolean uvLocked) - { -+ return bakeModel(modelBlockIn, (net.minecraftforge.common.model.ITransformation)modelRotationIn, uvLocked); -+ } -+ -+ protected IBakedModel bakeModel(ModelBlock modelBlockIn, net.minecraftforge.common.model.ITransformation modelRotationIn, boolean uvLocked) -+ { - TextureAtlasSprite textureatlassprite = this.sprites.get(new ResourceLocation(modelBlockIn.resolveTextureName("particle"))); - SimpleBakedModel.Builder simplebakedmodel$builder = new SimpleBakedModel.Builder(modelBlockIn, modelBlockIn.createOverrides()) - .setTexture(textureatlassprite); -@@ -922,7 +943,7 @@ - BlockPartFace blockpartface = blockpart.mapFaces.get(enumfacing); - TextureAtlasSprite textureatlassprite1 = this.sprites.get(new ResourceLocation(modelBlockIn.resolveTextureName(blockpartface.texture))); - -- if (blockpartface.cullFace == null) -+ if (blockpartface.cullFace == null || !net.minecraftforge.common.model.TRSRTransformation.isInteger(modelRotationIn.getMatrix())) - { - simplebakedmodel$builder.addGeneralQuad( - this.makeBakedQuad(blockpart, blockpartface, textureatlassprite1, enumfacing, modelRotationIn, uvLocked) -@@ -931,7 +952,7 @@ - else - { - simplebakedmodel$builder.addFaceQuad( -- modelRotationIn.rotateFace(blockpartface.cullFace), -+ modelRotationIn.rotate(blockpartface.cullFace), - this.makeBakedQuad(blockpart, blockpartface, textureatlassprite1, enumfacing, modelRotationIn, uvLocked) - ); - } -@@ -946,18 +967,12 @@ - BlockPart blockPartt, BlockPartFace blockPartFaceIn, TextureAtlasSprite sprite, EnumFacing face, ModelRotation transform, boolean uvLocked - ) - { -- return this.faceBakery -- .makeBakedQuad( -- blockPartt.positionFrom, -- blockPartt.positionTo, -- blockPartFaceIn, -- sprite, -- face, -- transform, -- blockPartt.partRotation, -- uvLocked, -- blockPartt.shade -- ); -+ return makeBakedQuad(blockPartt, blockPartFaceIn, sprite, face, (net.minecraftforge.common.model.ITransformation)transform, uvLocked); -+ } -+ -+ protected BakedQuad makeBakedQuad(BlockPart blockPartt, BlockPartFace blockPartFaceIn, TextureAtlasSprite sprite, EnumFacing face, net.minecraftforge.common.model.ITransformation transform, boolean uvLocked) -+ { -+ return this.faceBakery.makeBakedQuad(blockPartt.positionFrom, blockPartt.positionTo, blockPartFaceIn, sprite, face, transform, blockPartt.partRotation, uvLocked, blockPartt.shade); - } - - private void loadModelsCheck() -@@ -1182,5 +1197,24 @@ - BUILT_IN_MODELS.put("missing", MISSING_MODEL_MESH); - MODEL_GENERATED.name = "generation marker"; - MODEL_ENTITY.name = "block entity marker"; -+ } -+ -+ protected void registerMultipartVariant(ModelBlockDefinition definition, Collection locations) -+ { -+ this.multipartVariantMap.put(definition, locations); -+ } -+ -+ private static Map, Set> customVariantNames = Maps.newHashMap(); -+ -+ public static void registerItemVariants(Item item, ResourceLocation... names) -+ { -+ if (!customVariantNames.containsKey(item.delegate)) -+ { -+ customVariantNames.put(item.delegate, Sets.newHashSet()); -+ } -+ for(ResourceLocation name : names) -+ { -+ customVariantNames.get(item.delegate).add(name.toString()); -+ } - } - } diff --git a/patches/minecraft/net/minecraft/client/renderer/block/model/ModelBlockDefinition.java.patch b/patches/minecraft/net/minecraft/client/renderer/block/model/ModelBlockDefinition.java.patch deleted file mode 100644 index f54fea540..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/block/model/ModelBlockDefinition.java.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- before/net/minecraft/client/renderer/block/model/ModelBlockDefinition.java -+++ after/net/minecraft/client/renderer/block/model/ModelBlockDefinition.java -@@ -40,7 +40,11 @@ - - public static ModelBlockDefinition parseFromReader(Reader reader) - { -- return JsonUtils.fromJson(GSON, reader, ModelBlockDefinition.class); -+ return parseFromReader(reader, null); -+ } -+ -+ public static ModelBlockDefinition parseFromReader(Reader reader, net.minecraft.util.ResourceLocation location) { -+ return net.minecraftforge.client.model.BlockStateLoader.load(reader, location, GSON); - } - - public ModelBlockDefinition(Map variants, Multipart multipartIn) diff --git a/patches/minecraft/net/minecraft/client/renderer/block/model/ModelManager.java.patch b/patches/minecraft/net/minecraft/client/renderer/block/model/ModelManager.java.patch deleted file mode 100644 index 2fbdd31c2..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/block/model/ModelManager.java.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- before/net/minecraft/client/renderer/block/model/ModelManager.java -+++ after/net/minecraft/client/renderer/block/model/ModelManager.java -@@ -25,9 +25,10 @@ - @Override - public void onResourceManagerReload(IResourceManager resourceManager) - { -- ModelBakery modelbakery = new ModelBakery(resourceManager, this.texMap, this.modelProvider); -+ net.minecraftforge.client.model.ModelLoader modelbakery = new net.minecraftforge.client.model.ModelLoader(resourceManager, this.texMap, this.modelProvider); - this.modelRegistry = modelbakery.setupModelRegistry(); - this.defaultModel = this.modelRegistry.getObject(ModelBakery.MODEL_MISSING); -+ net.minecraftforge.client.ForgeHooksClient.onModelBake(this, this.modelRegistry, modelbakery); - this.modelProvider.reloadModels(); - } - diff --git a/patches/minecraft/net/minecraft/client/renderer/block/model/ModelResourceLocation.java.patch b/patches/minecraft/net/minecraft/client/renderer/block/model/ModelResourceLocation.java.patch deleted file mode 100644 index f25f9dbd2..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/block/model/ModelResourceLocation.java.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- before/net/minecraft/client/renderer/block/model/ModelResourceLocation.java -+++ after/net/minecraft/client/renderer/block/model/ModelResourceLocation.java -@@ -2,11 +2,8 @@ - - import java.util.Locale; - import net.minecraft.util.ResourceLocation; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; - import org.apache.commons.lang3.StringUtils; - --@SideOnly(Side.CLIENT) - public class ModelResourceLocation extends ResourceLocation - { - private final String variant; diff --git a/patches/minecraft/net/minecraft/client/renderer/block/model/ModelRotation.java.patch b/patches/minecraft/net/minecraft/client/renderer/block/model/ModelRotation.java.patch deleted file mode 100644 index 36599d4b4..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/block/model/ModelRotation.java.patch +++ /dev/null @@ -1,21 +0,0 @@ ---- before/net/minecraft/client/renderer/block/model/ModelRotation.java -+++ after/net/minecraft/client/renderer/block/model/ModelRotation.java -@@ -10,7 +10,7 @@ - import org.lwjgl.util.vector.Vector3f; - - @SideOnly(Side.CLIENT) --public enum ModelRotation -+public enum ModelRotation implements net.minecraftforge.common.model.IModelState, net.minecraftforge.common.model.ITransformation - { - X0_Y0(0, 0), - X0_Y90(0, 90), -@@ -116,4 +116,9 @@ - MAP_ROTATIONS.put(modelrotation.combinedXY, modelrotation); - } - } -+ -+ public java.util.Optional apply(java.util.Optional part) { return net.minecraftforge.client.ForgeHooksClient.applyTransform(this, part); } -+ public javax.vecmath.Matrix4f getMatrix() { return net.minecraftforge.common.model.TRSRTransformation.from(this).getMatrix(); } -+ public EnumFacing rotate(EnumFacing facing) { return rotateFace(facing); } -+ public int rotate(EnumFacing facing, int vertexIndex) { return rotateVertex(facing, vertexIndex); } - } diff --git a/patches/minecraft/net/minecraft/client/renderer/block/model/SimpleBakedModel.java.patch b/patches/minecraft/net/minecraft/client/renderer/block/model/SimpleBakedModel.java.patch deleted file mode 100644 index f70bfc197..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/block/model/SimpleBakedModel.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/client/renderer/block/model/SimpleBakedModel.java -+++ after/net/minecraft/client/renderer/block/model/SimpleBakedModel.java -@@ -103,7 +103,7 @@ - - public Builder(IBlockState state, IBakedModel model, TextureAtlasSprite texture, BlockPos pos) - { -- this(model.isAmbientOcclusion(), model.isGui3d(), model.getItemCameraTransforms(), model.getOverrides()); -+ this(model.isAmbientOcclusion(state), model.isGui3d(), model.getItemCameraTransforms(), model.getOverrides()); - this.builderTexture = model.getParticleTexture(); - long i = MathHelper.getPositionRandom(pos); - diff --git a/patches/minecraft/net/minecraft/client/renderer/block/model/Variant.java.patch b/patches/minecraft/net/minecraft/client/renderer/block/model/Variant.java.patch deleted file mode 100644 index f849d3c88..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/block/model/Variant.java.patch +++ /dev/null @@ -1,39 +0,0 @@ ---- before/net/minecraft/client/renderer/block/model/Variant.java -+++ after/net/minecraft/client/renderer/block/model/Variant.java -@@ -12,7 +12,7 @@ - import net.minecraftforge.fml.relauncher.SideOnly; - - @SideOnly(Side.CLIENT) --public class Variant -+public class Variant implements net.minecraftforge.client.model.ISmartVariant - { - private final ResourceLocation modelLocation; - private final ModelRotation rotation; -@@ -32,11 +32,17 @@ - return this.modelLocation; - } - -+ @Deprecated - public ModelRotation getRotation() - { - return this.rotation; - } - -+ public net.minecraftforge.common.model.IModelState getState() -+ { -+ return this.rotation; -+ } -+ - public boolean isUvLock() - { - return this.uvLock; -@@ -150,4 +156,9 @@ - } - } - } -+ -+ public net.minecraftforge.client.model.IModel process(net.minecraftforge.client.model.IModel base) -+ { -+ return base.uvlock(isUvLock()); -+ } - } diff --git a/patches/minecraft/net/minecraft/client/renderer/block/model/WeightedBakedModel.java.patch b/patches/minecraft/net/minecraft/client/renderer/block/model/WeightedBakedModel.java.patch deleted file mode 100644 index 3c75b25bf..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/block/model/WeightedBakedModel.java.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- before/net/minecraft/client/renderer/block/model/WeightedBakedModel.java -+++ after/net/minecraft/client/renderer/block/model/WeightedBakedModel.java -@@ -44,6 +44,12 @@ - } - - @Override -+ public boolean isAmbientOcclusion(IBlockState state) -+ { -+ return this.baseModel.isAmbientOcclusion(state); -+ } -+ -+ @Override - public boolean isGui3d() - { - return this.baseModel.isGui3d(); diff --git a/patches/minecraft/net/minecraft/client/renderer/block/statemap/StateMap.java.patch b/patches/minecraft/net/minecraft/client/renderer/block/statemap/StateMap.java.patch deleted file mode 100644 index 51ad455ae..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/block/statemap/StateMap.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/client/renderer/block/statemap/StateMap.java -+++ after/net/minecraft/client/renderer/block/statemap/StateMap.java -@@ -39,7 +39,7 @@ - } - else - { -- s = this.removeName(this.name, map); -+ s = String.format("%s:%s", Block.REGISTRY.getNameForObject(state.getBlock()).getNamespace(), this.removeName(this.name, map)); - } - - if (this.suffix != null) diff --git a/patches/minecraft/net/minecraft/client/renderer/chunk/ChunkRenderDispatcher.java.patch b/patches/minecraft/net/minecraft/client/renderer/chunk/ChunkRenderDispatcher.java.patch deleted file mode 100644 index a2f23b7aa..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/chunk/ChunkRenderDispatcher.java.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- before/net/minecraft/client/renderer/chunk/ChunkRenderDispatcher.java -+++ after/net/minecraft/client/renderer/chunk/ChunkRenderDispatcher.java -@@ -44,9 +44,15 @@ - - public ChunkRenderDispatcher() - { -+ this(-1); -+ } -+ -+ public ChunkRenderDispatcher(int countRenderBuilders) -+ { - int i = Math.max(1, (int)(Runtime.getRuntime().maxMemory() * 0.3) / 10485760); - int j = Math.max(1, MathHelper.clamp(Runtime.getRuntime().availableProcessors(), 1, i / 5)); -- this.countRenderBuilders = MathHelper.clamp(j * 10, 1, i); -+ if(countRenderBuilders < 0) countRenderBuilders = MathHelper.clamp(j * 10, 1, i); -+ this.countRenderBuilders = countRenderBuilders; - - if (j > 1) - { diff --git a/patches/minecraft/net/minecraft/client/renderer/chunk/ChunkRenderWorker.java.patch b/patches/minecraft/net/minecraft/client/renderer/chunk/ChunkRenderWorker.java.patch deleted file mode 100644 index ccaf94950..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/chunk/ChunkRenderWorker.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/client/renderer/chunk/ChunkRenderWorker.java -+++ after/net/minecraft/client/renderer/chunk/ChunkRenderWorker.java -@@ -239,7 +239,7 @@ - Minecraft.getMinecraft().crashed(CrashReport.makeCrashReport(p_onFailure_1_, "Rendering chunk")); - } - } -- } -+ }, Runnable::run - ); - } - } diff --git a/patches/minecraft/net/minecraft/client/renderer/chunk/RenderChunk.java.patch b/patches/minecraft/net/minecraft/client/renderer/chunk/RenderChunk.java.patch deleted file mode 100644 index e8facdbba..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/chunk/RenderChunk.java.patch +++ /dev/null @@ -1,105 +0,0 @@ ---- before/net/minecraft/client/renderer/chunk/RenderChunk.java -+++ after/net/minecraft/client/renderer/chunk/RenderChunk.java -@@ -171,7 +171,7 @@ - lvt_9_1_.setOpaqueCube(blockpos$mutableblockpos); - } - -- if (block.hasTileEntity()) -+ if (block.hasTileEntity(iblockstate)) - { - TileEntity tileentity = this.worldView.getTileEntity(blockpos$mutableblockpos, Chunk.EnumCreateEntityType.CHECK); - -@@ -181,17 +181,19 @@ - - if (tileentityspecialrenderer != null) - { -- compiledchunk.addTileEntity(tileentity); - - if (tileentityspecialrenderer.isGlobalRenderer(tileentity)) - { - lvt_10_1_.add(tileentity); - } -+ else compiledchunk.addTileEntity(tileentity); // FORGE: Fix MC-112730 - } - } - } - -- BlockRenderLayer blockrenderlayer1 = block.getRenderLayer(); -+ for(BlockRenderLayer blockrenderlayer1 : BlockRenderLayer.values()) { -+ if(!block.canRenderInLayer(iblockstate, blockrenderlayer1)) continue; -+ net.minecraftforge.client.ForgeHooksClient.setRenderLayer(blockrenderlayer1); - int j = blockrenderlayer1.ordinal(); - - if (block.getDefaultState().getRenderType() != EnumBlockRenderType.INVISIBLE) -@@ -206,6 +208,8 @@ - - aboolean[j] |= blockrendererdispatcher.renderBlock(iblockstate, blockpos$mutableblockpos, this.worldView, bufferbuilder); - } -+ } -+ net.minecraftforge.client.ForgeHooksClient.setRenderLayer(null); - } - - for (BlockRenderLayer blockrenderlayer : BlockRenderLayer.values()) -@@ -289,14 +293,16 @@ - private void rebuildWorldView() - { - int i = 1; -- this.worldView = new ChunkCache(this.world, this.position.add(-1, -1, -1), this.position.add(16, 16, 16), 1); -+ ChunkCache cache = createRegionRenderCache(this.world, this.position.add(-1, -1, -1), this.position.add(16, 16, 16), 1); -+ net.minecraftforge.client.MinecraftForgeClient.onRebuildChunk(this.world, this.position, cache); -+ this.worldView = cache; - } - - @Nullable - public ChunkCompileTaskGenerator makeCompileTaskTransparency() - { - this.lockCompileTask.lock(); -- Object object; -+ ChunkCompileTaskGenerator chunkcompiletaskgenerator; - - try - { -@@ -313,14 +319,14 @@ - return this.compileTask; - } - -- object = null; -+ chunkcompiletaskgenerator = null; - } - finally - { - this.lockCompileTask.unlock(); - } - -- return (ChunkCompileTaskGenerator)object; -+ return chunkcompiletaskgenerator; - } - - protected double getDistanceSq() -@@ -438,6 +444,26 @@ - { - return this.needsUpdate && this.needsImmediateUpdate; - } -+ -+ /* ======================================== FORGE START =====================================*/ -+ /** -+ * Creates a new RegionRenderCache instance.
-+ * Extending classes can change the behavior of the cache, allowing to visually change -+ * blocks (schematics etc). -+ * -+ * @see RegionRenderCache -+ * @param world The world to cache. -+ * @param from The starting position of the chunk minus one on each axis. -+ * @param to The ending position of the chunk plus one on each axis. -+ * @param subtract Padding used internally by the RegionRenderCache constructor to make -+ * the cache a 20x20x20 cube, for a total of 8000 states in the cache. -+ * @return new RegionRenderCache instance -+ */ -+ protected ChunkCache createRegionRenderCache(World world, BlockPos from, BlockPos to, int subtract) -+ { -+ return new ChunkCache(world, from, to, subtract); -+ } -+ /* ========================================= FORGE END ======================================*/ - - public BlockPos getBlockPosOffset16(EnumFacing facing) - { diff --git a/patches/minecraft/net/minecraft/client/renderer/color/BlockColors.java.patch b/patches/minecraft/net/minecraft/client/renderer/color/BlockColors.java.patch deleted file mode 100644 index 54d94f7f1..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/color/BlockColors.java.patch +++ /dev/null @@ -1,47 +0,0 @@ ---- before/net/minecraft/client/renderer/color/BlockColors.java -+++ after/net/minecraft/client/renderer/color/BlockColors.java -@@ -27,7 +27,8 @@ - @SideOnly(Side.CLIENT) - public class BlockColors - { -- private final ObjectIntIdentityMap mapBlockColors = new ObjectIntIdentityMap<>(32); -+ // FORGE: Use RegistryDelegates as non-Vanilla block ids are not constant -+ private final java.util.Map, IBlockColor> blockColorMap = com.google.common.collect.Maps.newHashMap(); - - public static BlockColors init() - { -@@ -196,12 +197,13 @@ - return worldIn != null && pos != null ? 2129968 : 7455580; - } - }, Blocks.WATERLILY); -+ net.minecraftforge.client.ForgeHooksClient.onBlockColorsInit(blockcolors); - return blockcolors; - } - - public int getColor(IBlockState state, World p_189991_2_, BlockPos p_189991_3_) - { -- IBlockColor iblockcolor = this.mapBlockColors.getByValue(Block.getIdFromBlock(state.getBlock())); -+ IBlockColor iblockcolor = this.blockColorMap.get(state.getBlock().delegate); - - if (iblockcolor != null) - { -@@ -216,7 +218,7 @@ - - public int colorMultiplier(IBlockState state, @Nullable IBlockAccess blockAccess, @Nullable BlockPos pos, int tintIndex) - { -- IBlockColor iblockcolor = this.mapBlockColors.getByValue(Block.getIdFromBlock(state.getBlock())); -+ IBlockColor iblockcolor = this.blockColorMap.get(state.getBlock().delegate); - return iblockcolor == null ? -1 : iblockcolor.colorMultiplier(state, blockAccess, pos, tintIndex); - } - -@@ -224,7 +226,9 @@ - { - for (Block block : blocksIn) - { -- this.mapBlockColors.put(blockColor, Block.getIdFromBlock(block)); -+ if (block == null) throw new IllegalArgumentException("Block registered to block color handler cannot be null!"); -+ if (block.getRegistryName() == null) throw new IllegalArgumentException("Block must be registered before assigning color handler."); -+ this.blockColorMap.put(block.delegate, blockColor); - } - } - } diff --git a/patches/minecraft/net/minecraft/client/renderer/color/ItemColors.java.patch b/patches/minecraft/net/minecraft/client/renderer/color/ItemColors.java.patch deleted file mode 100644 index 0887625bc..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/color/ItemColors.java.patch +++ /dev/null @@ -1,49 +0,0 @@ ---- before/net/minecraft/client/renderer/color/ItemColors.java -+++ after/net/minecraft/client/renderer/color/ItemColors.java -@@ -24,7 +24,8 @@ - @SideOnly(Side.CLIENT) - public class ItemColors - { -- private final ObjectIntIdentityMap mapItemColors = new ObjectIntIdentityMap<>(32); -+ // FORGE: Use RegistryDelegates as non-Vanilla item ids are not constant -+ private final java.util.Map, IItemColor> itemColorMap = com.google.common.collect.Maps.newHashMap(); - - public static ItemColors init(final BlockColors colors) - { -@@ -149,12 +150,13 @@ - return tintIndex == 0 ? -1 : ItemMap.getColor(stack); - } - }, Items.FILLED_MAP); -+ net.minecraftforge.client.ForgeHooksClient.onItemColorsInit(itemcolors, colors); - return itemcolors; - } - - public int colorMultiplier(ItemStack stack, int tintIndex) - { -- IItemColor iitemcolor = this.mapItemColors.getByValue(Item.REGISTRY.getIDForObject(stack.getItem())); -+ IItemColor iitemcolor = this.itemColorMap.get(stack.getItem().delegate); - return iitemcolor == null ? -1 : iitemcolor.colorMultiplier(stack, tintIndex); - } - -@@ -162,7 +164,9 @@ - { - for (Block block : blocksIn) - { -- this.mapItemColors.put(itemColor, Item.getIdFromItem(Item.getItemFromBlock(block))); -+ if (block == null) throw new IllegalArgumentException("Block registered to item color handler cannot be null!"); -+ if (block.getRegistryName() == null) throw new IllegalArgumentException("Block must be registered before assigning color handler."); -+ this.itemColorMap.put(Item.getItemFromBlock(block).delegate, itemColor); - } - } - -@@ -170,7 +174,9 @@ - { - for (Item item : itemsIn) - { -- this.mapItemColors.put(itemColor, Item.getIdFromItem(item)); -+ if (item == null) throw new IllegalArgumentException("Item registered to item color handler cannot be null!"); -+ if (item.getRegistryName() == null) throw new IllegalArgumentException("Item must be registered before assigning color handler."); -+ this.itemColorMap.put(item.delegate, itemColor); - } - } - } diff --git a/patches/minecraft/net/minecraft/client/renderer/entity/RenderEntityItem.java.patch b/patches/minecraft/net/minecraft/client/renderer/entity/RenderEntityItem.java.patch deleted file mode 100644 index 5fbd10ecb..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/entity/RenderEntityItem.java.patch +++ /dev/null @@ -1,86 +0,0 @@ ---- before/net/minecraft/client/renderer/entity/RenderEntityItem.java -+++ after/net/minecraft/client/renderer/entity/RenderEntityItem.java -@@ -43,7 +43,7 @@ - boolean flag = p_177077_9_.isGui3d(); - int i = this.getModelCount(itemstack); - float f = 0.25F; -- float f1 = MathHelper.sin((itemIn.getAge() + p_177077_8_) / 10.0F + itemIn.hoverStart) * 0.1F + 0.1F; -+ float f1 = shouldBob() ? MathHelper.sin((itemIn.getAge() + p_177077_8_) / 10.0F + itemIn.hoverStart) * 0.1F + 0.1F : 0; - float f2 = p_177077_9_.getItemCameraTransforms().getTransform(ItemCameraTransforms.TransformType.GROUND).scale.y; - GlStateManager.translate((float)p_177077_2_, (float)p_177077_4_ + f1 + 0.25F * f2, (float)p_177077_6_); - -@@ -105,16 +105,13 @@ - GlStateManager.pushMatrix(); - IBakedModel ibakedmodel = this.itemRenderer.getItemModelWithOverrides(itemstack, entity.world, null); - int j = this.transformModelCount(entity, x, y, z, partialTicks, ibakedmodel); -- float f = ibakedmodel.getItemCameraTransforms().ground.scale.x; -- float f1 = ibakedmodel.getItemCameraTransforms().ground.scale.y; -- float f2 = ibakedmodel.getItemCameraTransforms().ground.scale.z; - boolean flag1 = ibakedmodel.isGui3d(); - - if (!flag1) - { -- float f3 = -0.0F * (j - 1) * 0.5F * f; -- float f4 = -0.0F * (j - 1) * 0.5F * f1; -- float f5 = -0.09375F * (j - 1) * 0.5F * f2; -+ float f3 = -0.0F * (j - 1) * 0.5F; -+ float f4 = -0.0F * (j - 1) * 0.5F; -+ float f5 = -0.09375F * (j - 1) * 0.5F; - GlStateManager.translate(f3, f4, f5); - } - -@@ -135,11 +132,11 @@ - float f7 = (this.random.nextFloat() * 2.0F - 1.0F) * 0.15F; - float f9 = (this.random.nextFloat() * 2.0F - 1.0F) * 0.15F; - float f6 = (this.random.nextFloat() * 2.0F - 1.0F) * 0.15F; -- GlStateManager.translate(f7, f9, f6); -+ GlStateManager.translate(shouldSpreadItems() ? f7 : 0, shouldSpreadItems() ? f9 : 0, f6); - } - -- ibakedmodel.getItemCameraTransforms().applyTransform(ItemCameraTransforms.TransformType.GROUND); -- this.itemRenderer.renderItem(itemstack, ibakedmodel); -+ IBakedModel transformedModel = net.minecraftforge.client.ForgeHooksClient.handleCameraTransforms(ibakedmodel, ItemCameraTransforms.TransformType.GROUND, false); -+ this.itemRenderer.renderItem(itemstack, transformedModel); - GlStateManager.popMatrix(); - } - else -@@ -153,10 +150,10 @@ - GlStateManager.translate(f8, f10, 0.0F); - } - -- ibakedmodel.getItemCameraTransforms().applyTransform(ItemCameraTransforms.TransformType.GROUND); -- this.itemRenderer.renderItem(itemstack, ibakedmodel); -+ IBakedModel transformedModel = net.minecraftforge.client.ForgeHooksClient.handleCameraTransforms(ibakedmodel, ItemCameraTransforms.TransformType.GROUND, false); -+ this.itemRenderer.renderItem(itemstack, transformedModel); - GlStateManager.popMatrix(); -- GlStateManager.translate(0.0F * f, 0.0F * f1, 0.09375F * f2); -+ GlStateManager.translate(0.0F, 0.0F, 0.09375F); - } - } - -@@ -183,4 +180,25 @@ - { - return TextureMap.LOCATION_BLOCKS_TEXTURE; - } -+ -+ /*==================================== FORGE START ===========================================*/ -+ -+ /** -+ * Items should spread out when rendered in 3d? -+ * @return -+ */ -+ public boolean shouldSpreadItems() -+ { -+ return true; -+ } -+ -+ /** -+ * Items should have a bob effect -+ * @return -+ */ -+ public boolean shouldBob() -+ { -+ return true; -+ } -+ /*==================================== FORGE END =============================================*/ - } diff --git a/patches/minecraft/net/minecraft/client/renderer/entity/RenderFish.java.patch b/patches/minecraft/net/minecraft/client/renderer/entity/RenderFish.java.patch deleted file mode 100644 index 7245522fb..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/entity/RenderFish.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/client/renderer/entity/RenderFish.java -+++ after/net/minecraft/client/renderer/entity/RenderFish.java -@@ -75,7 +75,7 @@ - int k = entityplayer.getPrimaryHand() == EnumHandSide.RIGHT ? 1 : -1; - ItemStack itemstack = entityplayer.getHeldItemMainhand(); - -- if (itemstack.getItem() != Items.FISHING_ROD) -+ if (!(itemstack.getItem() instanceof net.minecraft.item.ItemFishingRod)) - { - k = -k; - } diff --git a/patches/minecraft/net/minecraft/client/renderer/entity/RenderItemFrame.java.patch b/patches/minecraft/net/minecraft/client/renderer/entity/RenderItemFrame.java.patch deleted file mode 100644 index 98b043011..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/entity/RenderItemFrame.java.patch +++ /dev/null @@ -1,43 +0,0 @@ ---- before/net/minecraft/client/renderer/entity/RenderItemFrame.java -+++ after/net/minecraft/client/renderer/entity/RenderItemFrame.java -@@ -49,7 +49,7 @@ - ModelManager modelmanager = blockrendererdispatcher.getBlockModelShapes().getModelManager(); - IBakedModel ibakedmodel; - -- if (entity.getDisplayedItem().getItem() == Items.FILLED_MAP) -+ if (entity.getDisplayedItem().getItem() instanceof net.minecraft.item.ItemMap) - { - ibakedmodel = modelmanager.getModel(this.mapModel); - } -@@ -101,10 +101,13 @@ - { - GlStateManager.pushMatrix(); - GlStateManager.disableLighting(); -- boolean flag = itemstack.getItem() == Items.FILLED_MAP; -+ boolean flag = itemstack.getItem() instanceof net.minecraft.item.ItemMap; - int i = flag ? itemFrame.getRotation() % 4 * 2 : itemFrame.getRotation(); - GlStateManager.rotate(i * 360.0F / 8.0F, 0.0F, 0.0F, 1.0F); - -+ net.minecraftforge.client.event.RenderItemInFrameEvent event = new net.minecraftforge.client.event.RenderItemInFrameEvent(itemFrame, this); -+ if (!net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event)) -+ { - if (flag) - { - this.renderManager.renderEngine.bindTexture(MAP_BACKGROUND_TEXTURES); -@@ -112,7 +115,7 @@ - float f = 0.0078125F; - GlStateManager.scale(0.0078125F, 0.0078125F, 0.0078125F); - GlStateManager.translate(-64.0F, -64.0F, 0.0F); -- MapData mapdata = Items.FILLED_MAP.getMapData(itemstack, itemFrame.world); -+ MapData mapdata = ((net.minecraft.item.ItemMap) itemstack.getItem()).getMapData(itemstack, itemFrame.world); - GlStateManager.translate(0.0F, 0.0F, -1.0F); - - if (mapdata != null) -@@ -128,6 +131,7 @@ - this.itemRenderer.renderItem(itemstack, ItemCameraTransforms.TransformType.FIXED); - RenderHelper.disableStandardItemLighting(); - GlStateManager.popAttrib(); -+ } - } - - GlStateManager.enableLighting(); diff --git a/patches/minecraft/net/minecraft/client/renderer/entity/RenderLivingBase.java.patch b/patches/minecraft/net/minecraft/client/renderer/entity/RenderLivingBase.java.patch deleted file mode 100644 index adb1b33e8..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/entity/RenderLivingBase.java.patch +++ /dev/null @@ -1,72 +0,0 @@ ---- before/net/minecraft/client/renderer/entity/RenderLivingBase.java -+++ after/net/minecraft/client/renderer/entity/RenderLivingBase.java -@@ -33,6 +33,9 @@ - protected List> layerRenderers = Lists.newArrayList(); - protected boolean renderMarker; - -+ public static float NAME_TAG_RANGE = 64.0f; -+ public static float NAME_TAG_RANGE_SNEAK = 32.0f; -+ - public RenderLivingBase(RenderManager renderManagerIn, ModelBase modelBaseIn, float shadowSizeIn) - { - super(renderManagerIn); -@@ -73,10 +76,12 @@ - - public void doRender(T entity, double x, double y, double z, float entityYaw, float partialTicks) - { -+ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.RenderLivingEvent.Pre(entity, this, partialTicks, x, y, z))) return; - GlStateManager.pushMatrix(); - GlStateManager.disableCull(); - this.mainModel.swingProgress = this.getSwingProgress(entity, partialTicks); -- this.mainModel.isRiding = entity.isRiding(); -+ boolean shouldSit = entity.isRiding() && (entity.getRidingEntity() != null && entity.getRidingEntity().shouldRiderSit()); -+ this.mainModel.isRiding = shouldSit; - this.mainModel.isChild = entity.isChild(); - - try -@@ -85,7 +90,7 @@ - float f1 = this.interpolateRotation(entity.prevRotationYawHead, entity.rotationYawHead, partialTicks); - float f2 = f1 - f; - -- if (entity.isRiding() && entity.getRidingEntity() instanceof EntityLivingBase) -+ if (shouldSit && entity.getRidingEntity() instanceof EntityLivingBase) - { - EntityLivingBase entitylivingbase = (EntityLivingBase)entity.getRidingEntity(); - f = this.interpolateRotation(entitylivingbase.prevRenderYawOffset, entitylivingbase.renderYawOffset, partialTicks); -@@ -134,6 +139,7 @@ - { - f5 = 1.0F; - } -+ f2 = f1 - f; // Forge: Fix MC-1207 - } - - GlStateManager.enableAlpha(); -@@ -195,6 +201,7 @@ - GlStateManager.enableCull(); - GlStateManager.popMatrix(); - super.doRender(entity, x, y, z, entityYaw, partialTicks); -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.RenderLivingEvent.Post(entity, this, partialTicks, x, y, z)); - } - - public float prepareScale(T entitylivingbaseIn, float partialTicks) -@@ -459,10 +466,11 @@ - - public void renderName(T entity, double x, double y, double z) - { -+ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.RenderLivingEvent.Specials.Pre(entity, this, x, y, z))) return; - if (this.canRenderName(entity)) - { - double d0 = entity.getDistanceSq(this.renderManager.renderViewEntity); -- float f = entity.isSneaking() ? 32.0F : 64.0F; -+ float f = entity.isSneaking() ? NAME_TAG_RANGE_SNEAK : NAME_TAG_RANGE; - - if (!(d0 >= f * f)) - { -@@ -471,6 +479,7 @@ - this.renderEntityName(entity, x, y, z, s, d0); - } - } -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.RenderLivingEvent.Specials.Post(entity, this, x, y, z)); - } - - protected boolean canRenderName(T entity) diff --git a/patches/minecraft/net/minecraft/client/renderer/entity/RenderManager.java.patch b/patches/minecraft/net/minecraft/client/renderer/entity/RenderManager.java.patch deleted file mode 100644 index fec6d399a..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/entity/RenderManager.java.patch +++ /dev/null @@ -1,26 +0,0 @@ ---- before/net/minecraft/client/renderer/entity/RenderManager.java -+++ after/net/minecraft/client/renderer/entity/RenderManager.java -@@ -226,6 +226,11 @@ - this.playerRenderer = new RenderPlayer(this); - this.skinMap.put("default", this.playerRenderer); - this.skinMap.put("slim", new RenderPlayer(this, true)); -+ net.minecraftforge.fml.client.registry.RenderingRegistry.loadEntityRenderers(this, this.entityRenderMap); -+ } -+ -+ public Map getSkinMap() { -+ return (Map) java.util.Collections.unmodifiableMap(skinMap); - } - - public void setRenderPosition(double renderPosXIn, double renderPosYIn, double renderPosZIn) -@@ -276,9 +281,9 @@ - IBlockState iblockstate = worldIn.getBlockState(new BlockPos(livingPlayerIn)); - Block block = iblockstate.getBlock(); - -- if (block == Blocks.BED) -+ if (block.isBed(iblockstate, worldIn, new BlockPos(livingPlayerIn), (EntityLivingBase)livingPlayerIn)) - { -- int i = iblockstate.getValue(BlockBed.FACING).getHorizontalIndex(); -+ int i = block.getBedDirection(iblockstate, worldIn, new BlockPos(livingPlayerIn)).getHorizontalIndex(); - this.playerViewY = i * 90 + 180; - this.playerViewX = 0.0F; - } diff --git a/patches/minecraft/net/minecraft/client/renderer/entity/RenderPlayer.java.patch b/patches/minecraft/net/minecraft/client/renderer/entity/RenderPlayer.java.patch deleted file mode 100644 index f901cb6f4..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/entity/RenderPlayer.java.patch +++ /dev/null @@ -1,46 +0,0 @@ ---- before/net/minecraft/client/renderer/entity/RenderPlayer.java -+++ after/net/minecraft/client/renderer/entity/RenderPlayer.java -@@ -56,6 +56,7 @@ - - public void doRender(AbstractClientPlayer entity, double x, double y, double z, float entityYaw, float partialTicks) - { -+ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.RenderPlayerEvent.Pre(entity, this, partialTicks, x, y, z))) return; - if (!entity.isUser() || this.renderManager.renderViewEntity == entity) - { - double d0 = y; -@@ -70,6 +71,7 @@ - super.doRender(entity, x, d0, z, entityYaw, partialTicks); - GlStateManager.disableBlendProfile(GlStateManager.Profile.PLAYER_SKIN); - } -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.RenderPlayerEvent.Post(entity, this, partialTicks, x, y, z)); - } - - private void setModelVisibilities(AbstractClientPlayer clientPlayer) -@@ -128,6 +130,11 @@ - { - modelbiped$armpose1 = ModelBiped.ArmPose.BLOCK; - } -+ // FORGE: fix MC-88356 allow offhand to use bow and arrow animation -+ else if (enumaction1 == EnumAction.BOW) -+ { -+ modelbiped$armpose1 = ModelBiped.ArmPose.BOW_AND_ARROW; -+ } - } - } - -@@ -183,6 +190,7 @@ - - public void renderRightArm(AbstractClientPlayer clientPlayer) - { -+ if (net.minecraftforge.client.ForgeHooksClient.renderSpecificFirstPersonArm(this, clientPlayer, EnumHandSide.RIGHT)) return; - float f = 1.0F; - GlStateManager.color(1.0F, 1.0F, 1.0F); - float f1 = 0.0625F; -@@ -201,6 +209,7 @@ - - public void renderLeftArm(AbstractClientPlayer clientPlayer) - { -+ if (net.minecraftforge.client.ForgeHooksClient.renderSpecificFirstPersonArm(this, clientPlayer, EnumHandSide.LEFT)) return; - float f = 1.0F; - GlStateManager.color(1.0F, 1.0F, 1.0F); - float f1 = 0.0625F; diff --git a/patches/minecraft/net/minecraft/client/renderer/entity/RenderVillager.java.patch b/patches/minecraft/net/minecraft/client/renderer/entity/RenderVillager.java.patch deleted file mode 100644 index 08f4fc718..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/entity/RenderVillager.java.patch +++ /dev/null @@ -1,26 +0,0 @@ ---- before/net/minecraft/client/renderer/entity/RenderVillager.java -+++ after/net/minecraft/client/renderer/entity/RenderVillager.java -@@ -31,22 +31,7 @@ - - protected ResourceLocation getEntityTexture(EntityVillager entity) - { -- switch (entity.getProfession()) -- { -- case 0: -- return FARMER_VILLAGER_TEXTURES; -- case 1: -- return LIBRARIAN_VILLAGER_TEXTURES; -- case 2: -- return PRIEST_VILLAGER_TEXTURES; -- case 3: -- return SMITH_VILLAGER_TEXTURES; -- case 4: -- return BUTCHER_VILLAGER_TEXTURES; -- case 5: -- default: -- return VILLAGER_TEXTURES; -- } -+ return entity.getProfessionForge().getSkin(); - } - - protected void preRenderCallback(EntityVillager entitylivingbaseIn, float partialTickTime) diff --git a/patches/minecraft/net/minecraft/client/renderer/entity/RenderZombieVillager.java.patch b/patches/minecraft/net/minecraft/client/renderer/entity/RenderZombieVillager.java.patch deleted file mode 100644 index c9c78acb6..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/entity/RenderZombieVillager.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- before/net/minecraft/client/renderer/entity/RenderZombieVillager.java -+++ after/net/minecraft/client/renderer/entity/RenderZombieVillager.java -@@ -25,6 +25,7 @@ - - protected ResourceLocation getEntityTexture(EntityZombieVillager entity) - { -+ if (true) return entity.getForgeProfession().getZombieSkin(); - switch (entity.getProfession()) - { - case 0: diff --git a/patches/minecraft/net/minecraft/client/renderer/entity/layers/LayerArmorBase.java.patch b/patches/minecraft/net/minecraft/client/renderer/entity/layers/LayerArmorBase.java.patch deleted file mode 100644 index 4d27b0e76..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/entity/layers/LayerArmorBase.java.patch +++ /dev/null @@ -1,93 +0,0 @@ ---- before/net/minecraft/client/renderer/entity/layers/LayerArmorBase.java -+++ after/net/minecraft/client/renderer/entity/layers/LayerArmorBase.java -@@ -79,31 +79,29 @@ - if (itemarmor.getEquipmentSlot() == slotIn) - { - T t = this.getModelFromSlot(slotIn); -+ t = getArmorModelHook(entityLivingBaseIn, itemstack, slotIn, t); - t.setModelAttributes(this.renderer.getMainModel()); - t.setLivingAnimations(entityLivingBaseIn, limbSwing, limbSwingAmount, partialTicks); - this.setModelSlotVisible(t, slotIn); - boolean flag = this.isLegSlot(slotIn); -- this.renderer.bindTexture(this.getArmorResource(itemarmor, flag)); -+ this.renderer.bindTexture(this.getArmorResource(entityLivingBaseIn, itemstack, slotIn, null)); - -- switch (itemarmor.getArmorMaterial()) - { -- case LEATHER: -+ if (itemarmor.hasOverlay(itemstack)) // Allow this for anything, not only cloth -+ { - int i = itemarmor.getColor(itemstack); - float f = (i >> 16 & 0xFF) / 255.0F; - float f1 = (i >> 8 & 0xFF) / 255.0F; - float f2 = (i & 0xFF) / 255.0F; - GlStateManager.color(this.colorR * f, this.colorG * f1, this.colorB * f2, this.alpha); - t.render(entityLivingBaseIn, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); -- this.renderer.bindTexture(this.getArmorResource(itemarmor, flag, "overlay")); -- case CHAIN: -- case IRON: -- case GOLD: -- case DIAMOND: -+ this.renderer.bindTexture(this.getArmorResource(entityLivingBaseIn, itemstack, slotIn, "overlay")); -+ } -+ { // Non-colored - GlStateManager.color(this.colorR, this.colorG, this.colorB, this.alpha); - t.render(entityLivingBaseIn, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); -- default: -- -- if (!this.skipRenderGlint && itemstack.isItemEnchanted()) -+ } // Default -+ if (!this.skipRenderGlint && itemstack.hasEffect()) - { - renderEnchantedGlint( - this.renderer, entityLivingBaseIn, t, limbSwing, limbSwingAmount, partialTicks, ageInTicks, netHeadYaw, headPitch, scale -@@ -200,4 +198,49 @@ - protected abstract void initArmor(); - - protected abstract void setModelSlotVisible(T p_188359_1_, EntityEquipmentSlot slotIn); -+ -+ /*=================================== FORGE START =========================================*/ -+ -+ /** -+ * Hook to allow item-sensitive armor model. for LayerBipedArmor. -+ */ -+ protected T getArmorModelHook(EntityLivingBase entity, ItemStack itemStack, EntityEquipmentSlot slot, T model) -+ { -+ return model; -+ } -+ -+ /** -+ * More generic ForgeHook version of the above function, it allows for Items to have more control over what texture they provide. -+ * -+ * @param entity Entity wearing the armor -+ * @param stack ItemStack for the armor -+ * @param slot Slot ID that the item is in -+ * @param type Subtype, can be null or "overlay" -+ * @return ResourceLocation pointing at the armor's texture -+ */ -+ public ResourceLocation getArmorResource(net.minecraft.entity.Entity entity, ItemStack stack, EntityEquipmentSlot slot, String type) -+ { -+ ItemArmor item = (ItemArmor)stack.getItem(); -+ String texture = item.getArmorMaterial().getName(); -+ String domain = "minecraft"; -+ int idx = texture.indexOf(':'); -+ if (idx != -1) -+ { -+ domain = texture.substring(0, idx); -+ texture = texture.substring(idx + 1); -+ } -+ String s1 = String.format("%s:textures/models/armor/%s_layer_%d%s.png", domain, texture, (isLegSlot(slot) ? 2 : 1), type == null ? "" : String.format("_%s", type)); -+ -+ s1 = net.minecraftforge.client.ForgeHooksClient.getArmorTexture(entity, stack, s1, slot, type); -+ ResourceLocation resourcelocation = (ResourceLocation)ARMOR_TEXTURE_RES_MAP.get(s1); -+ -+ if (resourcelocation == null) -+ { -+ resourcelocation = new ResourceLocation(s1); -+ ARMOR_TEXTURE_RES_MAP.put(s1, resourcelocation); -+ } -+ -+ return resourcelocation; -+ } -+ /*=================================== FORGE END ===========================================*/ - } diff --git a/patches/minecraft/net/minecraft/client/renderer/entity/layers/LayerBipedArmor.java.patch b/patches/minecraft/net/minecraft/client/renderer/entity/layers/LayerBipedArmor.java.patch deleted file mode 100644 index ccd88c54d..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/entity/layers/LayerBipedArmor.java.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- before/net/minecraft/client/renderer/entity/layers/LayerBipedArmor.java -+++ after/net/minecraft/client/renderer/entity/layers/LayerBipedArmor.java -@@ -21,6 +21,7 @@ - this.modelArmor = new ModelBiped(1.0F); - } - -+ @SuppressWarnings("incomplete-switch") - protected void setModelSlotVisible(ModelBiped p_188359_1_, EntityEquipmentSlot slotIn) - { - this.setModelVisible(p_188359_1_); -@@ -50,5 +51,11 @@ - protected void setModelVisible(ModelBiped model) - { - model.setVisible(false); -+ } -+ -+ @Override -+ protected ModelBiped getArmorModelHook(net.minecraft.entity.EntityLivingBase entity, net.minecraft.item.ItemStack itemStack, EntityEquipmentSlot slot, ModelBiped model) -+ { -+ return net.minecraftforge.client.ForgeHooksClient.getArmorModel(entity, itemStack, slot, model); - } - } diff --git a/patches/minecraft/net/minecraft/client/renderer/entity/layers/LayerHeldItem.java.patch b/patches/minecraft/net/minecraft/client/renderer/entity/layers/LayerHeldItem.java.patch deleted file mode 100644 index aed9e1773..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/entity/layers/LayerHeldItem.java.patch +++ /dev/null @@ -1,18 +0,0 @@ ---- before/net/minecraft/client/renderer/entity/layers/LayerHeldItem.java -+++ after/net/minecraft/client/renderer/entity/layers/LayerHeldItem.java -@@ -59,13 +59,13 @@ - if (!p_188358_2_.isEmpty()) - { - GlStateManager.pushMatrix(); -- this.translateToHand(handSide); - - if (p_188358_1_.isSneaking()) - { - GlStateManager.translate(0.0F, 0.2F, 0.0F); - } -- -+ // Forge: moved this call down, fixes incorrect offset while sneaking. -+ this.translateToHand(handSide); - GlStateManager.rotate(-90.0F, 1.0F, 0.0F, 0.0F); - GlStateManager.rotate(180.0F, 0.0F, 1.0F, 0.0F); - boolean flag = handSide == EnumHandSide.LEFT; diff --git a/patches/minecraft/net/minecraft/client/renderer/entity/layers/LayerHeldItemWitch.java.patch b/patches/minecraft/net/minecraft/client/renderer/entity/layers/LayerHeldItemWitch.java.patch deleted file mode 100644 index 843974ccb..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/entity/layers/LayerHeldItemWitch.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/client/renderer/entity/layers/LayerHeldItemWitch.java -+++ after/net/minecraft/client/renderer/entity/layers/LayerHeldItemWitch.java -@@ -62,7 +62,7 @@ - float f1 = 0.375F; - GlStateManager.scale(0.375F, -0.375F, 0.375F); - } -- else if (item == Items.BOW) -+ else if (item instanceof net.minecraft.item.ItemBow) - { - GlStateManager.translate(0.0F, 0.125F, -0.125F); - GlStateManager.rotate(-45.0F, 0.0F, 1.0F, 0.0F); diff --git a/patches/minecraft/net/minecraft/client/renderer/texture/LayeredColorMaskTexture.java.patch b/patches/minecraft/net/minecraft/client/renderer/texture/LayeredColorMaskTexture.java.patch deleted file mode 100644 index 61007ad77..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/texture/LayeredColorMaskTexture.java.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- before/net/minecraft/client/renderer/texture/LayeredColorMaskTexture.java -+++ after/net/minecraft/client/renderer/texture/LayeredColorMaskTexture.java -@@ -70,9 +70,7 @@ - - if (s != null) - { -- iresource1 = resourceManager.getResource(new ResourceLocation(s)); -- BufferedImage bufferedimage2 = TextureUtil.readBufferedImage(iresource1.getInputStream()); -- -+ BufferedImage bufferedimage2 = net.minecraftforge.client.MinecraftForgeClient.getImageLayer(new ResourceLocation(s), resourceManager); - if (bufferedimage2.getWidth() == bufferedimage.getWidth() - && bufferedimage2.getHeight() == bufferedimage.getHeight() - && bufferedimage2.getType() == 6) diff --git a/patches/minecraft/net/minecraft/client/renderer/texture/Stitcher.java.patch b/patches/minecraft/net/minecraft/client/renderer/texture/Stitcher.java.patch deleted file mode 100644 index 0cefa4666..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/texture/Stitcher.java.patch +++ /dev/null @@ -1,49 +0,0 @@ ---- before/net/minecraft/client/renderer/texture/Stitcher.java -+++ after/net/minecraft/client/renderer/texture/Stitcher.java -@@ -56,9 +56,11 @@ - { - Stitcher.Holder[] astitcher$holder = this.setStitchHolders.toArray(new Stitcher.Holder[this.setStitchHolders.size()]); - Arrays.sort((Object[])astitcher$holder); -+ net.minecraftforge.fml.common.ProgressManager.ProgressBar bar = net.minecraftforge.fml.common.ProgressManager.push("Texture stitching", astitcher$holder.length); - - for (Stitcher.Holder stitcher$holder : astitcher$holder) - { -+ bar.step(stitcher$holder.getAtlasSprite().getIconName()); - if (!this.allocateSlot(stitcher$holder)) - { - String s = String.format( -@@ -67,12 +69,16 @@ - stitcher$holder.getAtlasSprite().getIconWidth(), - stitcher$holder.getAtlasSprite().getIconHeight() - ); -+ net.minecraftforge.fml.common.FMLLog.log.info(s); -+ for (Stitcher.Holder h : astitcher$holder) -+ net.minecraftforge.fml.common.FMLLog.log.info(" {}", h); - throw new StitcherException(stitcher$holder, s); - } - } - - this.currentWidth = MathHelper.smallestEncompassingPowerOfTwo(this.currentWidth); - this.currentHeight = MathHelper.smallestEncompassingPowerOfTwo(this.currentHeight); -+ net.minecraftforge.fml.common.ProgressManager.pop(bar); - } - - public List getStichSlots() -@@ -155,7 +161,7 @@ - - if (flag3 ^ flag4) - { -- flag = flag3; -+ flag = !flag3 && flag1; //Forge: Fix stitcher not expanding entire height before growing width, and {potentially} growing larger then the max size. - } - else - { -@@ -248,7 +254,7 @@ - @Override - public String toString() - { -- return "Holder{width=" + this.width + ", height=" + this.height + '}'; -+ return "Holder{width=" + this.width + ", height=" + this.height + ", name=" + this.sprite.getIconName() + '}'; - } - - public int compareTo(Stitcher.Holder p_compareTo_1_) diff --git a/patches/minecraft/net/minecraft/client/renderer/texture/TextureAtlasSprite.java.patch b/patches/minecraft/net/minecraft/client/renderer/texture/TextureAtlasSprite.java.patch deleted file mode 100644 index 09aedfed5..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/texture/TextureAtlasSprite.java.patch +++ /dev/null @@ -1,59 +0,0 @@ ---- before/net/minecraft/client/renderer/texture/TextureAtlasSprite.java -+++ after/net/minecraft/client/renderer/texture/TextureAtlasSprite.java -@@ -49,12 +49,10 @@ - this.originX = originInX; - this.originY = originInY; - this.rotated = rotatedIn; -- float f = (float)(0.01F / inX); -- float f1 = (float)(0.01F / inY); -- this.minU = originInX / (float)inX + f; -- this.maxU = (originInX + this.width) / (float)inX - f; -- this.minV = (float)originInY / inY + f1; -- this.maxV = (float)(originInY + this.height) / inY - f1; -+ this.minU = (float)originInX / (float)(inX); -+ this.maxU = (float)(originInX + this.width) / (float)(inX); -+ this.minV = (float)originInY / (float)inY; -+ this.maxV = (float)(originInY + this.height) / (float)inY; - } - - public void copyFrom(TextureAtlasSprite atlasSpirit) -@@ -421,4 +419,39 @@ - + this.maxV - + '}'; - } -+ -+ /*===================================== FORGE START =====================================*/ -+ /** -+ * The result of this function determines is the below 'load' function is called, and the -+ * default vanilla loading code is bypassed completely. -+ * @param manager Main resource manager -+ * @param location File resource location -+ * @return True to use your own custom load code and bypass vanilla loading. -+ */ -+ public boolean hasCustomLoader(net.minecraft.client.resources.IResourceManager manager, net.minecraft.util.ResourceLocation location) -+ { -+ return false; -+ } -+ -+ /** -+ * Load the specified resource as this sprite's data. -+ * Returning false from this function will prevent this icon from being stitched onto the master texture. -+ * @param manager Main resource manager -+ * @param location File resource location -+ * @param textureGetter accessor for dependencies. All of them will be loaded before this one -+ * @return False to prevent this Icon from being stitched -+ */ -+ public boolean load(net.minecraft.client.resources.IResourceManager manager, net.minecraft.util.ResourceLocation location, java.util.function.Function textureGetter) -+ { -+ return true; -+ } -+ -+ /** -+ * @return all textures that should be loaded before this texture. -+ */ -+ public java.util.Collection getDependencies() { -+ return com.google.common.collect.ImmutableList.of(); -+ } -+ -+ /*===================================== FORGE END ======================================*/ - } diff --git a/patches/minecraft/net/minecraft/client/renderer/texture/TextureManager.java.patch b/patches/minecraft/net/minecraft/client/renderer/texture/TextureManager.java.patch deleted file mode 100644 index 617e60b47..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/texture/TextureManager.java.patch +++ /dev/null @@ -1,31 +0,0 @@ ---- before/net/minecraft/client/renderer/texture/TextureManager.java -+++ after/net/minecraft/client/renderer/texture/TextureManager.java -@@ -138,6 +138,7 @@ - - if (itextureobject != null) - { -+ this.mapTextureObjects.remove(textureLocation); // Forge: fix MC-98707 - TextureUtil.deleteTexture(itextureobject.getGlTextureId()); - } - } -@@ -145,11 +146,13 @@ - @Override - public void onResourceManagerReload(IResourceManager resourceManager) - { -+ net.minecraftforge.fml.common.ProgressManager.ProgressBar bar = net.minecraftforge.fml.common.ProgressManager.push("Reloading Texture Manager", this.mapTextureObjects.keySet().size(), true); - Iterator> iterator = this.mapTextureObjects.entrySet().iterator(); - - while (iterator.hasNext()) - { - Entry entry = iterator.next(); -+ bar.step(entry.getKey().toString()); - ITextureObject itextureobject = entry.getValue(); - - if (itextureobject == TextureUtil.MISSING_TEXTURE) -@@ -161,5 +164,6 @@ - this.loadTexture(entry.getKey(), itextureobject); - } - } -+ net.minecraftforge.fml.common.ProgressManager.pop(bar); - } - } diff --git a/patches/minecraft/net/minecraft/client/renderer/texture/TextureMap.java.patch b/patches/minecraft/net/minecraft/client/renderer/texture/TextureMap.java.patch deleted file mode 100644 index 892bb3f48..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/texture/TextureMap.java.patch +++ /dev/null @@ -1,264 +0,0 @@ ---- before/net/minecraft/client/renderer/texture/TextureMap.java -+++ after/net/minecraft/client/renderer/texture/TextureMap.java -@@ -44,6 +44,16 @@ - - public TextureMap(String basePathIn, @Nullable ITextureMapPopulator iconCreatorIn) - { -+ this(basePathIn, iconCreatorIn, false); -+ } -+ -+ public TextureMap(String basePathIn, boolean skipFirst) -+ { -+ this(basePathIn, null, skipFirst); -+ } -+ -+ public TextureMap(String basePathIn, @Nullable ITextureMapPopulator iconCreatorIn, boolean skipFirst) -+ { - this.basePath = basePathIn; - this.iconCreator = iconCreatorIn; - } -@@ -70,6 +80,7 @@ - public void loadSprites(IResourceManager resourceManager, ITextureMapPopulator iconCreatorIn) - { - this.mapRegisteredSprites.clear(); -+ net.minecraftforge.client.ForgeHooksClient.onTextureStitchedPre(this); - iconCreatorIn.registerSprites(this); - this.initMissingImage(); - this.deleteGlTexture(); -@@ -84,29 +95,74 @@ - this.listAnimatedSprites.clear(); - int j = Integer.MAX_VALUE; - int k = 1 << this.mipmapLevels; -- -- for (Entry entry : this.mapRegisteredSprites.entrySet()) -- { -- TextureAtlasSprite textureatlassprite = entry.getValue(); -- ResourceLocation resourcelocation = this.getResourceLocation(textureatlassprite); -- IResource iresource = null; -- -+ net.minecraftforge.fml.common.FMLLog.log.info("Max texture size: {}", i); -+ net.minecraftforge.fml.common.ProgressManager.ProgressBar bar = net.minecraftforge.fml.common.ProgressManager.push("Texture stitching", this.mapRegisteredSprites.size()); -+ loadedSprites.clear(); -+ -+ for (Entry entry : Maps.newHashMap(this.mapRegisteredSprites).entrySet()) -+ { -+ final ResourceLocation location = new ResourceLocation(entry.getKey()); -+ bar.step(location.toString()); -+ j = loadTexture(stitcher, resourceManager, location, entry.getValue(), bar, j, k); -+ } -+ finishLoading(stitcher, bar, j, k); -+ } -+ -+ private int loadTexture(Stitcher stitcher, IResourceManager resourceManager, ResourceLocation location, TextureAtlasSprite textureatlassprite, net.minecraftforge.fml.common.ProgressManager.ProgressBar bar, int j, int k) -+ { -+ if (loadedSprites.contains(location)) { -+ return j; -+ } -+ ResourceLocation resourcelocation = this.getResourceLocation(textureatlassprite); -+ IResource iresource = null; -+ -+ for(ResourceLocation loading : loadingSprites) -+ { -+ if(location.equals(loading)) -+ { -+ final String error = "circular texture dependencies, stack: [" + com.google.common.base.Joiner.on(", ").join(loadingSprites) + "]"; -+ net.minecraftforge.fml.client.FMLClientHandler.instance().trackBrokenTexture(resourcelocation, error); -+ return j; -+ } -+ } -+ loadingSprites.addLast(location); -+ try -+ { -+ for (ResourceLocation dependency : textureatlassprite.getDependencies()) -+ { -+ if (!mapRegisteredSprites.containsKey(dependency.toString())) -+ { -+ registerSprite(dependency); -+ } -+ TextureAtlasSprite depSprite = mapRegisteredSprites.get(dependency.toString()); -+ j = loadTexture(stitcher, resourceManager, dependency, depSprite, bar, j, k); -+ } - try -+ { -+ if (textureatlassprite.hasCustomLoader(resourceManager, resourcelocation)) -+ { -+ if (textureatlassprite.load(resourceManager, resourcelocation, l -> mapRegisteredSprites.get(l.toString()))) -+ { -+ return j; -+ } -+ } -+ else - { - PngSizeInfo pngsizeinfo = PngSizeInfo.makeFromResource(resourceManager.getResource(resourcelocation)); - iresource = resourceManager.getResource(resourcelocation); - boolean flag = iresource.getMetadata("animation") != null; - textureatlassprite.loadSprite(pngsizeinfo, flag); - } -+ } - catch (RuntimeException runtimeexception) - { -- LOGGER.error("Unable to parse metadata from {}", resourcelocation, runtimeexception); -- continue; -+ net.minecraftforge.fml.client.FMLClientHandler.instance().trackBrokenTexture(resourcelocation, runtimeexception.getMessage()); -+ return j; - } - catch (IOException ioexception) - { -- LOGGER.error("Using missing texture, unable to load {}", resourcelocation, ioexception); -- continue; -+ net.minecraftforge.fml.client.FMLClientHandler.instance().trackMissingTexture(resourcelocation); -+ return j; - } - finally - { -@@ -118,23 +174,36 @@ - - if (j1 < k) - { -+ // FORGE: do not lower the mipmap level, just log the problematic textures - LOGGER.warn( -- "Texture {} with size {}x{} limits mip level from {} to {}", -+ "Texture {} with size {}x{} will have visual artifacts at mip level {}, it can only support level {}. Please report to the mod author that the texture should be some multiple of 16x16.", - resourcelocation, - textureatlassprite.getIconWidth(), - textureatlassprite.getIconHeight(), - MathHelper.log2(k), - MathHelper.log2(j1) - ); -- k = j1; -+ - } - -+ if (generateMipmaps(resourceManager, textureatlassprite)) - stitcher.addSprite(textureatlassprite); -- } -+ return j; -+ } -+ finally -+ { -+ loadingSprites.removeLast(); -+ loadedSprites.add(location); -+ } -+ } - -+ private void finishLoading(Stitcher stitcher, net.minecraftforge.fml.common.ProgressManager.ProgressBar bar, int j, int k) -+ { -+ net.minecraftforge.fml.common.ProgressManager.pop(bar); - int l = Math.min(j, k); - int i1 = MathHelper.log2(l); - -+ if (false) // FORGE: do not lower the mipmap level - if (i1 < this.mipmapLevels) - { - LOGGER.warn("{}: dropping miplevel from {} to {}, because of minimum power of two: {}", this.basePath, this.mipmapLevels, i1, l); -@@ -143,9 +212,11 @@ - - this.missingImage.generateMipmaps(this.mipmapLevels); - stitcher.addSprite(this.missingImage); -+ bar = net.minecraftforge.fml.common.ProgressManager.push("Texture creation", 2); - - try - { -+ bar.step("Stitching"); - stitcher.doStitch(); - } - catch (StitcherException stitcherexception) -@@ -154,12 +225,16 @@ - } - - LOGGER.info("Created: {}x{} {}-atlas", stitcher.getCurrentWidth(), stitcher.getCurrentHeight(), this.basePath); -+ bar.step("Allocating GL texture"); - TextureUtil.allocateTextureImpl(this.getGlTextureId(), this.mipmapLevels, stitcher.getCurrentWidth(), stitcher.getCurrentHeight()); - Map map = Maps.newHashMap(this.mapRegisteredSprites); - -+ net.minecraftforge.fml.common.ProgressManager.pop(bar); -+ bar = net.minecraftforge.fml.common.ProgressManager.push("Texture mipmap and upload", stitcher.getStichSlots().size()); -+ - for (TextureAtlasSprite textureatlassprite1 : stitcher.getStichSlots()) - { -- if (textureatlassprite1 == this.missingImage || this.generateMipmaps(resourceManager, textureatlassprite1)) -+ bar.step(textureatlassprite1.getIconName()); - { - String s = textureatlassprite1.getIconName(); - map.remove(s); -@@ -197,6 +272,8 @@ - { - textureatlassprite2.copyFrom(this.missingImage); - } -+ net.minecraftforge.client.ForgeHooksClient.onTextureStitchedPost(this); -+ net.minecraftforge.fml.common.ProgressManager.pop(bar); - } - - private boolean generateMipmaps(IResourceManager resourceManager, final TextureAtlasSprite texture) -@@ -206,7 +283,7 @@ - label45: - { - boolean lvt_6_1_; -- -+ if (texture.hasCustomLoader(resourceManager, resourcelocation)) break label45; - try - { - iresource = resourceManager.getResource(resourcelocation); -@@ -302,7 +379,7 @@ - } - else - { -- TextureAtlasSprite textureatlassprite = this.mapRegisteredSprites.get(location); -+ TextureAtlasSprite textureatlassprite = this.mapRegisteredSprites.get(location.toString()); - - if (textureatlassprite == null) - { -@@ -328,5 +405,53 @@ - public TextureAtlasSprite getMissingSprite() - { - return this.missingImage; -+ } -+ -+ //=================================================================================================== -+ // Forge Start -+ //=================================================================================================== -+ -+ private final java.util.Deque loadingSprites = new java.util.ArrayDeque<>(); -+ private final java.util.Set loadedSprites = new java.util.HashSet<>(); -+ -+ /** -+ * Grabs the registered entry for the specified name, returning null if there was not a entry. -+ * Opposed to registerIcon, this will not instantiate the entry, useful to test if a mapping exists. -+ * -+ * @param name The name of the entry to find -+ * @return The registered entry, null if nothing was registered. -+ */ -+ @Nullable -+ public TextureAtlasSprite getTextureExtry(String name) -+ { -+ return mapRegisteredSprites.get(name); -+ } -+ -+ /** -+ * Adds a texture registry entry to this map for the specified name if one does not already exist. -+ * Returns false if the map already contains a entry for the specified name. -+ * -+ * @param entry Entry instance -+ * @return True if the entry was added to the map, false otherwise. -+ */ -+ public boolean setTextureEntry(TextureAtlasSprite entry) -+ { -+ String name = entry.getIconName(); -+ if (!mapRegisteredSprites.containsKey(name)) -+ { -+ mapRegisteredSprites.put(name, entry); -+ return true; -+ } -+ return false; -+ } -+ -+ public String getBasePath() -+ { -+ return basePath; -+ } -+ -+ public int getMipmapLevels() -+ { -+ return mipmapLevels; - } - } diff --git a/patches/minecraft/net/minecraft/client/renderer/texture/TextureUtil.java.patch b/patches/minecraft/net/minecraft/client/renderer/texture/TextureUtil.java.patch deleted file mode 100644 index 5511d4edb..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/texture/TextureUtil.java.patch +++ /dev/null @@ -1,48 +0,0 @@ ---- before/net/minecraft/client/renderer/texture/TextureUtil.java -+++ after/net/minecraft/client/renderer/texture/TextureUtil.java -@@ -63,7 +63,7 @@ - { - boolean flag = false; - -- for (int i = 0; i < p_147949_2_.length; i++) -+ for (int i = 0; i < p_147949_2_[0].length; i++) - { - if (p_147949_2_[0][i] >> 24 == 0) - { -@@ -83,6 +83,7 @@ - int[] aint1 = aint[l1 - 1]; - int[] aint2 = new int[aint1.length >> 2]; - int j = p_147949_1_ >> l1; -+ if (j > 0) { // FORGE: forcing higher mipmap levels on odd textures needs this check - int k = aint2.length / j; - int l = j << 1; - -@@ -94,6 +95,7 @@ - aint2[i1 + j1 * j] = blendColors(aint1[k1 + 0], aint1[k1 + 1], aint1[k1 + 0 + l], aint1[k1 + 1 + l], flag); - } - } -+ } // end if (j > 0) - - aint[l1] = aint2; - } -@@ -170,6 +172,7 @@ - for (int i = 0; i < p_147955_0_.length; i++) - { - int[] aint = p_147955_0_[i]; -+ if ((p_147955_1_ >> i <= 0) || (p_147955_2_ >> i <= 0)) break; - uploadTextureSub(i, aint, p_147955_1_ >> i, p_147955_2_ >> i, p_147955_3_ >> i, p_147955_4_ >> i, p_147955_5_, p_147955_6_, p_147955_0_.length > 1); - } - } -@@ -215,9 +218,11 @@ - - public static void allocateTextureImpl(int glTextureId, int mipmapLevels, int width, int height) - { -+ synchronized (net.minecraftforge.fml.client.SplashProgress.class) -+ { - deleteTexture(glTextureId); - bindTexture(glTextureId); -- -+ } - if (mipmapLevels >= 0) - { - GlStateManager.glTexParameteri(3553, 33085, mipmapLevels); diff --git a/patches/minecraft/net/minecraft/client/renderer/tileentity/TileEntityItemStackRenderer.java.patch b/patches/minecraft/net/minecraft/client/renderer/tileentity/TileEntityItemStackRenderer.java.patch deleted file mode 100644 index 61dae9267..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/tileentity/TileEntityItemStackRenderer.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- before/net/minecraft/client/renderer/tileentity/TileEntityItemStackRenderer.java -+++ after/net/minecraft/client/renderer/tileentity/TileEntityItemStackRenderer.java -@@ -123,6 +123,7 @@ - TileEntityRendererDispatcher.instance - .render(SHULKER_BOXES[BlockShulkerBox.getColorFromItem(item).getMetadata()], 0.0, 0.0, 0.0, 0.0F, partialTicks); - } -+ else if (Block.getBlockFromItem(item) != Blocks.CHEST) net.minecraftforge.client.ForgeHooksClient.renderTileItem(itemStackIn.getItem(), itemStackIn.getMetadata()); - else - { - TileEntityRendererDispatcher.instance.render(this.chestBasic, 0.0, 0.0, 0.0, 0.0F, partialTicks); diff --git a/patches/minecraft/net/minecraft/client/renderer/tileentity/TileEntityPistonRenderer.java.patch b/patches/minecraft/net/minecraft/client/renderer/tileentity/TileEntityPistonRenderer.java.patch deleted file mode 100644 index c40e12832..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/tileentity/TileEntityPistonRenderer.java.patch +++ /dev/null @@ -1,17 +0,0 @@ ---- before/net/minecraft/client/renderer/tileentity/TileEntityPistonRenderer.java -+++ after/net/minecraft/client/renderer/tileentity/TileEntityPistonRenderer.java -@@ -23,12 +23,13 @@ - @SideOnly(Side.CLIENT) - public class TileEntityPistonRenderer extends TileEntitySpecialRenderer - { -- private final BlockRendererDispatcher blockRenderer = Minecraft.getMinecraft().getBlockRendererDispatcher(); -+ private BlockRendererDispatcher blockRenderer; - - public void render( - TileEntityPiston te, double x, double y, double z, float partialTicks, int destroyStage, float alpha - ) - { -+ if (blockRenderer == null) blockRenderer = Minecraft.getMinecraft().getBlockRendererDispatcher(); //Forge: Delay this from constructor to allow us to change it later - BlockPos blockpos = te.getPos(); - IBlockState iblockstate = te.getPistonState(); - Block block = iblockstate.getBlock(); diff --git a/patches/minecraft/net/minecraft/client/renderer/tileentity/TileEntityRendererDispatcher.java.patch b/patches/minecraft/net/minecraft/client/renderer/tileentity/TileEntityRendererDispatcher.java.patch deleted file mode 100644 index cf7b44062..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/tileentity/TileEntityRendererDispatcher.java.patch +++ /dev/null @@ -1,94 +0,0 @@ ---- before/net/minecraft/client/renderer/tileentity/TileEntityRendererDispatcher.java -+++ after/net/minecraft/client/renderer/tileentity/TileEntityRendererDispatcher.java -@@ -92,7 +92,7 @@ - @Nullable - public TileEntitySpecialRenderer getRenderer(@Nullable TileEntity tileEntityIn) - { -- return tileEntityIn == null ? null : this.getRenderer((Class )tileEntityIn.getClass()); -+ return tileEntityIn == null || tileEntityIn.isInvalid() ? null : this.getRenderer(tileEntityIn.getClass()); // Forge: fix MC-123363 - } - - public void prepare( -@@ -119,13 +119,17 @@ - { - if (tileentityIn.getDistanceSq(this.entityX, this.entityY, this.entityZ) < tileentityIn.getMaxRenderDistanceSquared()) - { -+ if(!drawingBatch || !tileentityIn.hasFastRenderer()) -+ { - RenderHelper.enableStandardItemLighting(); - int i = this.world.getCombinedLight(tileentityIn.getPos(), 0); - int j = i % 65536; - int k = i / 65536; - OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, j, k); - GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); -+ } - BlockPos blockpos = tileentityIn.getPos(); -+ if (this.world.isBlockLoaded(blockpos, false)) // Forge: fix MC-123363 - this.render( - tileentityIn, - blockpos.getX() - staticPlayerX, -@@ -158,6 +162,9 @@ - { - try - { -+ if(drawingBatch && tileEntityIn.hasFastRenderer()) -+ tileentityspecialrenderer.renderTileEntityFast(tileEntityIn, x, y, z, partialTicks, destroyStage, p_192854_10_, batchBuffer.getBuffer()); -+ else - tileentityspecialrenderer.render(tileEntityIn, x, y, z, partialTicks, destroyStage, p_192854_10_); - } - catch (Throwable throwable) -@@ -183,5 +190,54 @@ - public FontRenderer getFontRenderer() - { - return this.fontRenderer; -+ } -+ -+ /* ======================================== FORGE START =====================================*/ -+ /** -+ * Buffer used for batched TESRs -+ */ -+ private net.minecraft.client.renderer.Tessellator batchBuffer = new net.minecraft.client.renderer.Tessellator(0x200000); -+ private boolean drawingBatch = false; -+ -+ /** -+ * Prepare for a batched TESR rendering. -+ * You probably shouldn't call this manually. -+ */ -+ public void preDrawBatch() -+ { -+ batchBuffer.getBuffer().begin(org.lwjgl.opengl.GL11.GL_QUADS, net.minecraft.client.renderer.vertex.DefaultVertexFormats.BLOCK); -+ drawingBatch = true; -+ } -+ -+ /** -+ * Render all TESRs batched so far. -+ * You probably shouldn't call this manually. -+ */ -+ public void drawBatch(int pass) -+ { -+ renderEngine.bindTexture(net.minecraft.client.renderer.texture.TextureMap.LOCATION_BLOCKS_TEXTURE); -+ net.minecraft.client.renderer.RenderHelper.disableStandardItemLighting(); -+ GlStateManager.blendFunc(org.lwjgl.opengl.GL11.GL_SRC_ALPHA, org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA); -+ GlStateManager.enableBlend(); -+ GlStateManager.disableCull(); -+ -+ if (net.minecraft.client.Minecraft.isAmbientOcclusionEnabled()) -+ { -+ GlStateManager.shadeModel(org.lwjgl.opengl.GL11.GL_SMOOTH); -+ } -+ else -+ { -+ GlStateManager.shadeModel(org.lwjgl.opengl.GL11.GL_FLAT); -+ } -+ -+ if(pass > 0) -+ { -+ net.minecraft.util.math.Vec3d cameraPos = net.minecraft.client.renderer.ActiveRenderInfo.getCameraPosition(); -+ batchBuffer.getBuffer().sortVertexData((float)cameraPos.x, (float)cameraPos.y, (float)cameraPos.z); -+ } -+ batchBuffer.draw(); -+ -+ net.minecraft.client.renderer.RenderHelper.enableStandardItemLighting(); -+ drawingBatch = false; - } - } diff --git a/patches/minecraft/net/minecraft/client/renderer/tileentity/TileEntitySpecialRenderer.java.patch b/patches/minecraft/net/minecraft/client/renderer/tileentity/TileEntitySpecialRenderer.java.patch deleted file mode 100644 index b74268cff..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/tileentity/TileEntitySpecialRenderer.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/client/renderer/tileentity/TileEntitySpecialRenderer.java -+++ after/net/minecraft/client/renderer/tileentity/TileEntitySpecialRenderer.java -@@ -91,6 +91,8 @@ - return false; - } - -+ public void renderTileEntityFast(T te, double x, double y, double z, float partialTicks, int destroyStage, float partial, net.minecraft.client.renderer.BufferBuilder buffer) {} -+ - protected void drawNameplate(T te, String str, double x, double y, double z, int maxDistance) - { - Entity entity = this.rendererDispatcher.entity; diff --git a/patches/minecraft/net/minecraft/client/renderer/vertex/VertexFormat.java.patch b/patches/minecraft/net/minecraft/client/renderer/vertex/VertexFormat.java.patch deleted file mode 100644 index 2a0dc4cc8..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/vertex/VertexFormat.java.patch +++ /dev/null @@ -1,39 +0,0 @@ ---- before/net/minecraft/client/renderer/vertex/VertexFormat.java -+++ after/net/minecraft/client/renderer/vertex/VertexFormat.java -@@ -17,6 +17,7 @@ - private int colorElementOffset = -1; - private final List uvOffsetsById = Lists.newArrayList(); - private int normalElementOffset = -1; -+ private int hashCode; - - public VertexFormat(VertexFormat vertexFormatIn) - { -@@ -42,6 +43,7 @@ - this.uvOffsetsById.clear(); - this.normalElementOffset = -1; - this.vertexSize = 0; -+ this.hashCode = 0; - } - - @SuppressWarnings("incomplete-switch") -@@ -70,6 +72,7 @@ - } - - this.vertexSize = this.vertexSize + element.getSize(); -+ this.hashCode = 0; - return this; - } - } -@@ -198,8 +201,11 @@ - @Override - public int hashCode() - { -+ if (this.hashCode != 0) return this.hashCode; - int i = this.elements.hashCode(); - i = 31 * i + this.offsets.hashCode(); -- return 31 * i + this.vertexSize; -+ i = 31 * i + this.vertexSize; -+ this.hashCode = i; -+ return i; - } - } diff --git a/patches/minecraft/net/minecraft/client/renderer/vertex/VertexFormatElement.java.patch b/patches/minecraft/net/minecraft/client/renderer/vertex/VertexFormatElement.java.patch deleted file mode 100644 index 81037187b..000000000 --- a/patches/minecraft/net/minecraft/client/renderer/vertex/VertexFormatElement.java.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- before/net/minecraft/client/renderer/vertex/VertexFormatElement.java -+++ after/net/minecraft/client/renderer/vertex/VertexFormatElement.java -@@ -156,9 +156,16 @@ - NORMAL("Normal"), - COLOR("Vertex Color"), - UV("UV"), -+ // As of 1.8.8 - unused in vanilla; use GENERIC for now -+ @Deprecated - MATRIX("Bone Matrix"), -+ @Deprecated - BLEND_WEIGHT("Blend Weight"), -- PADDING("Padding"); -+ PADDING("Padding"), -+ GENERIC("Generic"); -+ -+ public void preDraw(VertexFormat format, int element, int stride, java.nio.ByteBuffer buffer) { net.minecraftforge.client.ForgeHooksClient.preDraw(this, format, element, stride, buffer); } -+ public void postDraw(VertexFormat format, int element, int stride, java.nio.ByteBuffer buffer) { net.minecraftforge.client.ForgeHooksClient.postDraw(this, format, element, stride, buffer); } - - private final String displayName; - diff --git a/patches/minecraft/net/minecraft/client/resources/AbstractResourcePack.java.patch b/patches/minecraft/net/minecraft/client/resources/AbstractResourcePack.java.patch deleted file mode 100644 index 6ac7a8bb8..000000000 --- a/patches/minecraft/net/minecraft/client/resources/AbstractResourcePack.java.patch +++ /dev/null @@ -1,21 +0,0 @@ ---- before/net/minecraft/client/resources/AbstractResourcePack.java -+++ after/net/minecraft/client/resources/AbstractResourcePack.java -@@ -77,7 +77,7 @@ - try - { - bufferedreader = new BufferedReader(new InputStreamReader(p_110596_1_, StandardCharsets.UTF_8)); -- jsonobject = new JsonParser().parse(bufferedreader).getAsJsonObject(); -+ jsonobject = JsonParser.parseReader(bufferedreader).getAsJsonObject(); - } - catch (RuntimeException runtimeexception) - { -@@ -101,5 +101,9 @@ - public String getPackName() - { - return this.resourcePackFile.getName(); -+ } -+ -+ public File getResourcePackFile() { -+ return resourcePackFile; - } - } diff --git a/patches/minecraft/net/minecraft/client/resources/FallbackResourceManager.java.patch b/patches/minecraft/net/minecraft/client/resources/FallbackResourceManager.java.patch deleted file mode 100644 index 97a7d0395..000000000 --- a/patches/minecraft/net/minecraft/client/resources/FallbackResourceManager.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- before/net/minecraft/client/resources/FallbackResourceManager.java -+++ after/net/minecraft/client/resources/FallbackResourceManager.java -@@ -144,6 +144,7 @@ - this.isClosed = true; - } - -+ @SuppressWarnings("removal") - @Override - protected void finalize() throws Throwable - { diff --git a/patches/minecraft/net/minecraft/client/resources/IResourceManagerReloadListener.java.patch b/patches/minecraft/net/minecraft/client/resources/IResourceManagerReloadListener.java.patch deleted file mode 100644 index fa83686bf..000000000 --- a/patches/minecraft/net/minecraft/client/resources/IResourceManagerReloadListener.java.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- before/net/minecraft/client/resources/IResourceManagerReloadListener.java -+++ after/net/minecraft/client/resources/IResourceManagerReloadListener.java -@@ -3,6 +3,11 @@ - import net.minecraftforge.fml.relauncher.Side; - import net.minecraftforge.fml.relauncher.SideOnly; - -+/** -+ * @deprecated Forge: {@link net.minecraftforge.client.resource.ISelectiveResourceReloadListener}, which selectively allows -+ * individual resource types being reloaded should rather be used where possible. -+ */ -+@Deprecated - @SideOnly(Side.CLIENT) - public interface IResourceManagerReloadListener - { diff --git a/patches/minecraft/net/minecraft/client/resources/Language.java.patch b/patches/minecraft/net/minecraft/client/resources/Language.java.patch deleted file mode 100644 index 9aa1e7bdd..000000000 --- a/patches/minecraft/net/minecraft/client/resources/Language.java.patch +++ /dev/null @@ -1,24 +0,0 @@ ---- before/net/minecraft/client/resources/Language.java -+++ after/net/minecraft/client/resources/Language.java -@@ -17,6 +17,12 @@ - this.region = regionIn; - this.name = nameIn; - this.bidirectional = bidirectionalIn; -+ String[] splitLangCode = languageCode.split("_", 2); -+ if (splitLangCode.length == 1) { // Vanilla has some languages without underscores -+ this.javaLocale = new java.util.Locale(languageCode); -+ } else { -+ this.javaLocale = new java.util.Locale(splitLangCode[0], splitLangCode[1]); -+ } - } - - public String getLanguageCode() -@@ -58,4 +64,8 @@ - { - return this.languageCode.compareTo(p_compareTo_1_.languageCode); - } -+ -+ // Forge: add access to Locale so modders can create correct string and number formatters -+ private final java.util.Locale javaLocale; -+ public java.util.Locale getJavaLocale() { return javaLocale; } - } diff --git a/patches/minecraft/net/minecraft/client/resources/LegacyV2Adapter.java.patch b/patches/minecraft/net/minecraft/client/resources/LegacyV2Adapter.java.patch deleted file mode 100644 index 68ebdb78c..000000000 --- a/patches/minecraft/net/minecraft/client/resources/LegacyV2Adapter.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/client/resources/LegacyV2Adapter.java -+++ after/net/minecraft/client/resources/LegacyV2Adapter.java -@@ -82,4 +82,8 @@ - { - return this.pack.getPackName(); - } -+ -+ public IResourcePack getUnadaptedPack() { -+ return pack; -+ } - } diff --git a/patches/minecraft/net/minecraft/client/resources/Locale.java.patch b/patches/minecraft/net/minecraft/client/resources/Locale.java.patch deleted file mode 100644 index ef5aa16a2..000000000 --- a/patches/minecraft/net/minecraft/client/resources/Locale.java.patch +++ /dev/null @@ -1,38 +0,0 @@ ---- before/net/minecraft/client/resources/Locale.java -+++ after/net/minecraft/client/resources/Locale.java -@@ -53,26 +53,6 @@ - - private void checkUnicode() - { -- this.unicode = false; -- int i = 0; -- int j = 0; -- -- for (String s : this.properties.values()) -- { -- int k = s.length(); -- j += k; -- -- for (int l = 0; l < k; l++) -- { -- if (s.charAt(l) >= 256) -- { -- i++; -- } -- } -- } -- -- float f = (float)i / j; -- this.unicode = f > 0.1; - } - - private void loadLocaleData(List resourcesList) throws IOException -@@ -94,6 +74,8 @@ - - private void loadLocaleData(InputStream inputStreamIn) throws IOException - { -+ inputStreamIn = net.minecraftforge.fml.common.FMLCommonHandler.instance().loadLanguage(properties, inputStreamIn); -+ if (inputStreamIn == null) return; - for (String s : IOUtils.readLines(inputStreamIn, StandardCharsets.UTF_8)) - { - if (!s.isEmpty() && s.charAt(0) != '#') diff --git a/patches/minecraft/net/minecraft/client/resources/ResourceIndex.java.patch b/patches/minecraft/net/minecraft/client/resources/ResourceIndex.java.patch deleted file mode 100644 index dc4999db7..000000000 --- a/patches/minecraft/net/minecraft/client/resources/ResourceIndex.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/client/resources/ResourceIndex.java -+++ after/net/minecraft/client/resources/ResourceIndex.java -@@ -41,7 +41,7 @@ - try - { - bufferedreader = Files.newReader(file2, StandardCharsets.UTF_8); -- JsonObject jsonobject = new JsonParser().parse(bufferedreader).getAsJsonObject(); -+ JsonObject jsonobject = JsonParser.parseReader(bufferedreader).getAsJsonObject(); - JsonObject jsonobject1 = JsonUtils.getJsonObject(jsonobject, "objects", null); - - if (jsonobject1 != null) diff --git a/patches/minecraft/net/minecraft/client/resources/ResourcePackRepository.java.patch b/patches/minecraft/net/minecraft/client/resources/ResourcePackRepository.java.patch deleted file mode 100644 index 243add6be..000000000 --- a/patches/minecraft/net/minecraft/client/resources/ResourcePackRepository.java.patch +++ /dev/null @@ -1,31 +0,0 @@ ---- before/net/minecraft/client/resources/ResourcePackRepository.java -+++ after/net/minecraft/client/resources/ResourcePackRepository.java -@@ -297,7 +297,7 @@ - FileUtils.deleteQuietly(file1); - settablefuture.setException(p_onFailure_1_); - } -- }); -+ }, Runnable::run); - return this.downloadingPacks; - } - finally -@@ -308,9 +308,10 @@ - - private boolean checkHash(String p_190113_1_, File p_190113_2_) - { -+ java.io.InputStream is = null; - try - { -- String s = DigestUtils.sha1Hex(new FileInputStream(p_190113_2_)); -+ String s = DigestUtils.sha1Hex(is = new FileInputStream(p_190113_2_)); - - if (p_190113_1_.isEmpty()) - { -@@ -330,6 +331,7 @@ - { - LOGGER.warn("File {} couldn't be hashed.", p_190113_2_, ioexception); - } -+ finally { IOUtils.closeQuietly(is); } // Forge: close stream after use - - return false; - } diff --git a/patches/minecraft/net/minecraft/client/resources/SimpleReloadableResourceManager.java.patch b/patches/minecraft/net/minecraft/client/resources/SimpleReloadableResourceManager.java.patch deleted file mode 100644 index c9592dc2c..000000000 --- a/patches/minecraft/net/minecraft/client/resources/SimpleReloadableResourceManager.java.patch +++ /dev/null @@ -1,45 +0,0 @@ ---- before/net/minecraft/client/resources/SimpleReloadableResourceManager.java -+++ after/net/minecraft/client/resources/SimpleReloadableResourceManager.java -@@ -96,6 +96,7 @@ - @Override - public void reloadResources(List resourcesPacksList) - { -+ net.minecraftforge.fml.common.ProgressManager.ProgressBar resReload = net.minecraftforge.fml.common.ProgressManager.push("Loading Resources", resourcesPacksList.size()+1, true); - this.clearResources(); - LOGGER.info("Reloading ResourceManager: {}", JOINER_RESOURCE_PACKS.join(Iterables.transform(resourcesPacksList, new Function() - { -@@ -107,24 +108,34 @@ - - for (IResourcePack iresourcepack : resourcesPacksList) - { -+ resReload.step(iresourcepack.getPackName()); - this.reloadResourcePack(iresourcepack); - } - -+ resReload.step("Reloading listeners"); - this.notifyReloadListeners(); -+ net.minecraftforge.fml.common.ProgressManager.pop(resReload); - } - - @Override - public void registerReloadListener(IResourceManagerReloadListener reloadListener) - { -+ net.minecraftforge.fml.common.ProgressManager.ProgressBar resReload = net.minecraftforge.fml.common.ProgressManager.push("Loading Resource", 1); -+ resReload.step(reloadListener.getClass()); - this.reloadListeners.add(reloadListener); - reloadListener.onResourceManagerReload(this); -+ net.minecraftforge.fml.common.ProgressManager.pop(resReload); - } - - private void notifyReloadListeners() - { -+ net.minecraftforge.fml.common.ProgressManager.ProgressBar resReload = net.minecraftforge.fml.common.ProgressManager.push("Reloading", this.reloadListeners.size()); - for (IResourceManagerReloadListener iresourcemanagerreloadlistener : this.reloadListeners) - { -+ resReload.step(iresourcemanagerreloadlistener.getClass()); -+ if (!net.minecraftforge.client.ForgeHooksClient.shouldUseVanillaReloadableListener(iresourcemanagerreloadlistener)) continue; // Forge: Selective reloading for vanilla listeners - iresourcemanagerreloadlistener.onResourceManagerReload(this); - } -+ net.minecraftforge.fml.common.ProgressManager.pop(resReload); - } - } diff --git a/patches/minecraft/net/minecraft/client/resources/SimpleResource.java.patch b/patches/minecraft/net/minecraft/client/resources/SimpleResource.java.patch deleted file mode 100644 index a16197b02..000000000 --- a/patches/minecraft/net/minecraft/client/resources/SimpleResource.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/client/resources/SimpleResource.java -+++ after/net/minecraft/client/resources/SimpleResource.java -@@ -75,7 +75,7 @@ - try - { - bufferedreader = new BufferedReader(new InputStreamReader(this.mcmetaInputStream, StandardCharsets.UTF_8)); -- this.mcmetaJson = new JsonParser().parse(bufferedreader).getAsJsonObject(); -+ this.mcmetaJson = JsonParser.parseReader(bufferedreader).getAsJsonObject(); - } - finally - { diff --git a/patches/minecraft/net/minecraft/client/settings/GameSettings.java.patch b/patches/minecraft/net/minecraft/client/settings/GameSettings.java.patch deleted file mode 100644 index bf9b9ebb2..000000000 --- a/patches/minecraft/net/minecraft/client/settings/GameSettings.java.patch +++ /dev/null @@ -1,160 +0,0 @@ ---- before/net/minecraft/client/settings/GameSettings.java -+++ after/net/minecraft/client/settings/GameSettings.java -@@ -69,6 +69,7 @@ - } - }; - public static final Splitter COLON_SPLITTER = Splitter.on(':'); -+ @Deprecated - private static final String[] GUISCALES = new String[] - { - "options.guiScale.auto", "options.guiScale.small", "options.guiScale.normal", "options.guiScale.large" -@@ -214,6 +215,7 @@ - - public GameSettings(Minecraft mcIn, File mcDataDir) - { -+ setForgeKeybindProperties(); - this.mc = mcIn; - this.optionsFile = new File(mcDataDir, "options.txt"); - -@@ -232,6 +234,7 @@ - - public GameSettings() - { -+ setForgeKeybindProperties(); - } - - public static String getKeyDisplayString(int key) -@@ -338,7 +341,7 @@ - this.mc.getTextureMapBlocks().setMipmapLevels(this.mipmapLevels); - this.mc.getTextureManager().bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); - this.mc.getTextureMapBlocks().setBlurMipmapDirect(false, this.mipmapLevels > 0); -- this.mc.scheduleResourcesRefresh(); -+ this.needsBlockModelRefresh = true; // FORGE: fix for MC-64581 very laggy mipmap slider - } - } - -@@ -368,7 +371,12 @@ - - if (settingsOption == GameSettings.Options.GUI_SCALE) - { -- this.guiScale = this.guiScale + value & 3; -+ int maxScale = 1; -+ while (this.mc.displayWidth / (maxScale + 1) >= 320 && this.mc.displayHeight / (maxScale + 1) >= 240) -+ { -+ maxScale++; -+ } -+ this.guiScale = (this.guiScale + value) % (maxScale + 1); - } - - if (settingsOption == GameSettings.Options.PARTICLES) -@@ -400,7 +408,7 @@ - if (settingsOption == GameSettings.Options.ANAGLYPH) - { - this.anaglyph = !this.anaglyph; -- this.mc.refreshResources(); -+ net.minecraftforge.fml.client.FMLClientHandler.instance().refreshResources(net.minecraftforge.client.resource.VanillaResourceType.TEXTURES); - } - - if (settingsOption == GameSettings.Options.GRAPHICS) -@@ -719,7 +727,7 @@ - } - else if (settingOption == GameSettings.Options.GUI_SCALE) - { -- return s + getTranslation(GUISCALES, this.guiScale); -+ return s + (this.guiScale == 0 ? I18n.format("options.guiScale.auto") : this.guiScale); - } - else if (settingOption == GameSettings.Options.CHAT_VISIBILITY) - { -@@ -767,6 +775,7 @@ - - public void loadOptions() - { -+ FileInputStream fileInputStream = null; // Forge: fix MC-151173 - try - { - if (!this.optionsFile.exists()) -@@ -775,7 +784,7 @@ - } - - this.soundLevels.clear(); -- List list = IOUtils.readLines(new FileInputStream(this.optionsFile)); -+ List list = IOUtils.readLines(fileInputStream = new FileInputStream(this.optionsFile), StandardCharsets.UTF_8); // Forge: fix MC-117449, MC-151173 - NBTTagCompound nbttagcompound = new NBTTagCompound(); - - for (String s : list) -@@ -1111,7 +1120,12 @@ - { - if (s1.equals("key_" + keybinding.getKeyDescription())) - { -- keybinding.setKeyCode(Integer.parseInt(s2)); -+ if (s2.indexOf(':') != -1) -+ { -+ String[] t = s2.split(":"); -+ keybinding.setKeyModifierAndCode(net.minecraftforge.client.settings.KeyModifier.valueFromString(t[1]), Integer.parseInt(t[0])); -+ } else -+ keybinding.setKeyModifierAndCode(net.minecraftforge.client.settings.KeyModifier.NONE, Integer.parseInt(s2)); - } - } - -@@ -1143,6 +1157,7 @@ - { - LOGGER.error("Failed to load options", (Throwable)exception2); - } -+ finally { IOUtils.closeQuietly(fileInputStream); } // Forge: fix MC-151173 - } - - private NBTTagCompound dataFix(NBTTagCompound p_189988_1_) -@@ -1174,6 +1189,7 @@ - - public void saveOptions() - { -+ if (net.minecraftforge.fml.client.FMLClientHandler.instance().isLoading()) return; - PrintWriter printwriter = null; - - try -@@ -1248,7 +1264,8 @@ - - for (KeyBinding keybinding : this.keyBindings) - { -- printwriter.println("key_" + keybinding.getKeyDescription() + ":" + keybinding.getKeyCode()); -+ String keyString = "key_" + keybinding.getKeyDescription() + ":" + keybinding.getKeyCode(); -+ printwriter.println(keybinding.getKeyModifier() != net.minecraftforge.client.settings.KeyModifier.NONE ? keyString + ":" + keybinding.getKeyModifier() : keyString); - } - - for (SoundCategory soundcategory : SoundCategory.values()) -@@ -1485,4 +1502,35 @@ - return value; - } - } -+ -+ /******* Forge Start ***********/ -+ private void setForgeKeybindProperties() { -+ net.minecraftforge.client.settings.KeyConflictContext inGame = net.minecraftforge.client.settings.KeyConflictContext.IN_GAME; -+ keyBindForward.setKeyConflictContext(inGame); -+ keyBindLeft.setKeyConflictContext(inGame); -+ keyBindBack.setKeyConflictContext(inGame); -+ keyBindRight.setKeyConflictContext(inGame); -+ keyBindJump.setKeyConflictContext(inGame); -+ keyBindSneak.setKeyConflictContext(inGame); -+ keyBindSprint.setKeyConflictContext(inGame); -+ keyBindAttack.setKeyConflictContext(inGame); -+ keyBindChat.setKeyConflictContext(inGame); -+ keyBindPlayerList.setKeyConflictContext(inGame); -+ keyBindCommand.setKeyConflictContext(inGame); -+ keyBindTogglePerspective.setKeyConflictContext(inGame); -+ keyBindSmoothCamera.setKeyConflictContext(inGame); -+ keyBindSwapHands.setKeyConflictContext(inGame); -+ } -+ -+ // FORGE: fix for MC-64581 very laggy mipmap slider -+ private boolean needsBlockModelRefresh = false; -+ public void onGuiClosed() -+ { -+ if (needsBlockModelRefresh) -+ { -+ net.minecraftforge.fml.client.FMLClientHandler.instance().scheduleResourcesRefresh(net.minecraftforge.client.resource.VanillaResourceType.MODELS); -+ this.needsBlockModelRefresh = false; -+ } -+ } -+ /******* Forge End ***********/ - } diff --git a/patches/minecraft/net/minecraft/client/settings/KeyBinding.java.patch b/patches/minecraft/net/minecraft/client/settings/KeyBinding.java.patch deleted file mode 100644 index 8da83aa2a..000000000 --- a/patches/minecraft/net/minecraft/client/settings/KeyBinding.java.patch +++ /dev/null @@ -1,205 +0,0 @@ ---- before/net/minecraft/client/settings/KeyBinding.java -+++ after/net/minecraft/client/settings/KeyBinding.java -@@ -15,7 +15,7 @@ - public class KeyBinding implements Comparable - { - private static final Map KEYBIND_ARRAY = Maps.newHashMap(); -- private static final IntHashMap HASH = new IntHashMap<>(); -+ private static final net.minecraftforge.client.settings.KeyBindingMap HASH = new net.minecraftforge.client.settings.KeyBindingMap(); - private static final Set KEYBIND_SET = Sets.newHashSet(); - private static final Map CATEGORY_ORDER = Maps.newHashMap(); - private final String keyDescription; -@@ -29,12 +29,7 @@ - { - if (keyCode != 0) - { -- KeyBinding keybinding = HASH.lookup(keyCode); -- -- if (keybinding != null) -- { -- keybinding.pressTime++; -- } -+ HASH.lookupActives(keyCode).forEach($ -> ++$.pressTime); - } - } - -@@ -42,7 +37,7 @@ - { - if (keyCode != 0) - { -- KeyBinding keybinding = HASH.lookup(keyCode); -+ for (KeyBinding keybinding : HASH.lookupAll(keyCode)) - - if (keybinding != null) - { -@@ -101,7 +96,7 @@ - - public boolean isKeyDown() - { -- return this.pressed; -+ return this.pressed && getKeyConflictContext().isActive() && getKeyModifier().isActive(getKeyConflictContext()); - } - - public String getKeyCategory() -@@ -150,15 +145,156 @@ - - public int compareTo(KeyBinding p_compareTo_1_) - { -- return this.keyCategory.equals(p_compareTo_1_.keyCategory) -- ? I18n.format(this.keyDescription).compareTo(I18n.format(p_compareTo_1_.keyDescription)) -- : CATEGORY_ORDER.get(this.keyCategory).compareTo(CATEGORY_ORDER.get(p_compareTo_1_.keyCategory)); -- } -+ if (this.keyCategory.equals(p_compareTo_1_.keyCategory)) return I18n.format(this.keyDescription).compareTo(I18n.format(p_compareTo_1_.keyDescription)); -+ Integer tCat = CATEGORY_ORDER.get(this.keyCategory); -+ Integer oCat = CATEGORY_ORDER.get(p_compareTo_1_.keyCategory); -+ if (tCat == null && oCat != null) return 1; -+ if (tCat != null && oCat == null) return -1; -+ if (tCat == null && oCat == null) return I18n.format(this.keyCategory).compareTo(I18n.format(p_compareTo_1_.keyCategory)); -+ return tCat.compareTo(oCat); -+ } -+ -+ /****************** Forge Start *****************************/ -+ private net.minecraftforge.client.settings.KeyModifier keyModifierDefault = net.minecraftforge.client.settings.KeyModifier.NONE; -+ private net.minecraftforge.client.settings.KeyModifier keyModifier = net.minecraftforge.client.settings.KeyModifier.NONE; -+ private net.minecraftforge.client.settings.IKeyConflictContext keyConflictContext = net.minecraftforge.client.settings.KeyConflictContext.UNIVERSAL; -+ -+ /** -+ * Convenience constructor for creating KeyBindings with keyConflictContext set. -+ */ -+ public KeyBinding(String description, net.minecraftforge.client.settings.IKeyConflictContext keyConflictContext, int keyCode, String category) -+ { -+ this(description, keyConflictContext, net.minecraftforge.client.settings.KeyModifier.NONE, keyCode, category); -+ } -+ -+ /** -+ * Convenience constructor for creating KeyBindings with keyConflictContext and keyModifier set. -+ */ -+ public KeyBinding(String description, net.minecraftforge.client.settings.IKeyConflictContext keyConflictContext, net.minecraftforge.client.settings.KeyModifier keyModifier, int keyCode, String category) -+ { -+ this.keyDescription = description; -+ this.keyCode = keyCode; -+ this.keyCodeDefault = keyCode; -+ this.keyCategory = category; -+ this.keyConflictContext = keyConflictContext; -+ this.keyModifier = keyModifier; -+ this.keyModifierDefault = keyModifier; -+ if (this.keyModifier.matches(keyCode)) -+ { -+ this.keyModifier = net.minecraftforge.client.settings.KeyModifier.NONE; -+ } -+ KEYBIND_ARRAY.put(description, this); -+ HASH.addKey(keyCode, this); -+ KEYBIND_SET.add(category); -+ } -+ -+ /** -+ * Checks that the key conflict context and modifier are active, and that the keyCode matches this binding. -+ */ -+ public boolean isActiveAndMatches(int keyCode) -+ { -+ return keyCode != 0 && keyCode == this.getKeyCode() && getKeyConflictContext().isActive() && getKeyModifier().isActive(getKeyConflictContext()); -+ } -+ -+ public void setKeyConflictContext(net.minecraftforge.client.settings.IKeyConflictContext keyConflictContext) -+ { -+ this.keyConflictContext = keyConflictContext; -+ } -+ -+ public net.minecraftforge.client.settings.IKeyConflictContext getKeyConflictContext() -+ { -+ return keyConflictContext; -+ } -+ -+ public net.minecraftforge.client.settings.KeyModifier getKeyModifierDefault() -+ { -+ return keyModifierDefault; -+ } -+ -+ public net.minecraftforge.client.settings.KeyModifier getKeyModifier() -+ { -+ return keyModifier; -+ } -+ -+ public void setKeyModifierAndCode(net.minecraftforge.client.settings.KeyModifier keyModifier, int keyCode) -+ { -+ this.keyCode = keyCode; -+ if (keyModifier.matches(keyCode)) -+ { -+ keyModifier = net.minecraftforge.client.settings.KeyModifier.NONE; -+ } -+ HASH.removeKey(this); -+ this.keyModifier = keyModifier; -+ HASH.addKey(keyCode, this); -+ } -+ -+ public void setToDefault() -+ { -+ setKeyModifierAndCode(getKeyModifierDefault(), getKeyCodeDefault()); -+ } -+ -+ public boolean isSetToDefaultValue() -+ { -+ return getKeyCode() == getKeyCodeDefault() && getKeyModifier() == getKeyModifierDefault(); -+ } -+ -+ /** -+ * Returns true when the other keyBinding conflicts with this one -+ */ -+ public boolean conflicts(KeyBinding other) -+ { -+ if (getKeyConflictContext().conflicts(other.getKeyConflictContext()) || other.getKeyConflictContext().conflicts(getKeyConflictContext())) -+ { -+ net.minecraftforge.client.settings.KeyModifier keyModifier = getKeyModifier(); -+ net.minecraftforge.client.settings.KeyModifier otherKeyModifier = other.getKeyModifier(); -+ if (keyModifier.matches(other.getKeyCode()) || otherKeyModifier.matches(getKeyCode())) -+ { -+ return true; -+ } -+ else if (getKeyCode() == other.getKeyCode()) -+ { -+ return keyModifier == otherKeyModifier || -+ // IN_GAME key contexts have a conflict when at least one modifier is NONE. -+ // For example: If you hold shift to crouch, you can still press E to open your inventory. This means that a Shift+E hotkey is in conflict with E. -+ // GUI and other key contexts do not have this limitation. -+ (getKeyConflictContext().conflicts(net.minecraftforge.client.settings.KeyConflictContext.IN_GAME) && -+ (keyModifier == net.minecraftforge.client.settings.KeyModifier.NONE || otherKeyModifier == net.minecraftforge.client.settings.KeyModifier.NONE)); -+ } -+ } -+ return false; -+ } -+ -+ /** -+ * Returns true when one of the bindings' key codes conflicts with the other's modifier. -+ */ -+ public boolean hasKeyCodeModifierConflict(KeyBinding other) -+ { -+ if (getKeyConflictContext().conflicts(other.getKeyConflictContext()) || other.getKeyConflictContext().conflicts(getKeyConflictContext())) -+ { -+ if (getKeyModifier().matches(other.getKeyCode()) || other.getKeyModifier().matches(getKeyCode())) -+ { -+ return true; -+ } -+ } -+ return false; -+ } -+ -+ public String getDisplayName() -+ { -+ return getKeyModifier().getLocalizedComboName(getKeyCode()); -+ } -+ /****************** Forge End *****************************/ - - public static Supplier getDisplayString(String key) - { - KeyBinding keybinding = KEYBIND_ARRAY.get(key); -- return keybinding == null ? () -> key : () -> GameSettings.getKeyDisplayString(keybinding.getKeyCode()); -+ return keybinding == null ? () -> -+ { -+ return key; -+ } : () -> -+ { -+ return keybinding.getDisplayName(); -+ }; - } - - static diff --git a/patches/minecraft/net/minecraft/client/shader/Framebuffer.java.patch b/patches/minecraft/net/minecraft/client/shader/Framebuffer.java.patch deleted file mode 100644 index db762620e..000000000 --- a/patches/minecraft/net/minecraft/client/shader/Framebuffer.java.patch +++ /dev/null @@ -1,57 +0,0 @@ ---- before/net/minecraft/client/shader/Framebuffer.java -+++ after/net/minecraft/client/shader/Framebuffer.java -@@ -117,8 +117,17 @@ - if (this.useDepth) - { - OpenGlHelper.glBindRenderbuffer(OpenGlHelper.GL_RENDERBUFFER, this.depthBuffer); -+ if (!this.stencilEnabled) -+ { - OpenGlHelper.glRenderbufferStorage(OpenGlHelper.GL_RENDERBUFFER, 33190, this.framebufferTextureWidth, this.framebufferTextureHeight); - OpenGlHelper.glFramebufferRenderbuffer(OpenGlHelper.GL_FRAMEBUFFER, OpenGlHelper.GL_DEPTH_ATTACHMENT, OpenGlHelper.GL_RENDERBUFFER, this.depthBuffer); -+ } -+ else -+ { -+ OpenGlHelper.glRenderbufferStorage(OpenGlHelper.GL_RENDERBUFFER, org.lwjgl.opengl.EXTPackedDepthStencil.GL_DEPTH24_STENCIL8_EXT, this.framebufferTextureWidth, this.framebufferTextureHeight); -+ OpenGlHelper.glFramebufferRenderbuffer(OpenGlHelper.GL_FRAMEBUFFER, org.lwjgl.opengl.EXTFramebufferObject.GL_DEPTH_ATTACHMENT_EXT, OpenGlHelper.GL_RENDERBUFFER, this.depthBuffer); -+ OpenGlHelper.glFramebufferRenderbuffer(OpenGlHelper.GL_FRAMEBUFFER, org.lwjgl.opengl.EXTFramebufferObject.GL_STENCIL_ATTACHMENT_EXT, OpenGlHelper.GL_RENDERBUFFER, this.depthBuffer); -+ } - } - - this.framebufferClear(); -@@ -278,4 +287,36 @@ - GlStateManager.clear(i); - this.unbindFramebuffer(); - } -+ -+ /*================================ FORGE START ================================================*/ -+ private boolean stencilEnabled = false; -+ /** -+ * Attempts to enabled 8 bits of stencil buffer on this FrameBuffer. -+ * Modders must call this directly to set things up. -+ * This is to prevent the default cause where graphics cards do not support stencil bits. -+ * Modders should check the below 'isStencilEnabled' to check if another modder has already enabled them. -+ * -+ * Note: -+ * As of now the only thing that is checked is if FBOs are supported entirely, in the future -+ * we may expand to check for errors. -+ * -+ * @return True if the FBO was re-initialized with stencil bits. -+ */ -+ public boolean enableStencil() -+ { -+ if (!OpenGlHelper.isFramebufferEnabled()) return false; -+ stencilEnabled = true; -+ this.createBindFramebuffer(framebufferWidth, framebufferHeight); -+ return true; //TODO: Find a way to detect if this failed? -+ } -+ -+ /** -+ * Returns wither or not this FBO has been successfully initialized with stencil bits. -+ * If not, and a modder wishes it to be, they must call enableStencil. -+ */ -+ public boolean isStencilEnabled() -+ { -+ return this.stencilEnabled; -+ } -+ /*================================ FORGE END ================================================*/ - } diff --git a/patches/minecraft/net/minecraft/client/shader/ShaderGroup.java.patch b/patches/minecraft/net/minecraft/client/shader/ShaderGroup.java.patch deleted file mode 100644 index 91b71a54e..000000000 --- a/patches/minecraft/net/minecraft/client/shader/ShaderGroup.java.patch +++ /dev/null @@ -1,27 +0,0 @@ ---- before/net/minecraft/client/shader/ShaderGroup.java -+++ after/net/minecraft/client/shader/ShaderGroup.java -@@ -55,13 +55,12 @@ - - public void parseGroup(TextureManager p_152765_1_, ResourceLocation p_152765_2_) throws JsonException, IOException, JsonSyntaxException - { -- JsonParser jsonparser = new JsonParser(); - IResource iresource = null; - - try - { - iresource = this.resourceManager.getResource(p_152765_2_); -- JsonObject jsonobject = jsonparser.parse(IOUtils.toString(iresource.getInputStream(), StandardCharsets.UTF_8)).getAsJsonObject(); -+ JsonObject jsonobject = JsonParser.parseString(IOUtils.toString(iresource.getInputStream(), StandardCharsets.UTF_8)).getAsJsonObject(); - - if (JsonUtils.isJsonArray(jsonobject, "targets")) - { -@@ -178,7 +177,8 @@ - - if (framebuffer2 == null) - { -- ResourceLocation resourcelocation = new ResourceLocation("textures/effect/" + s3 + ".png"); -+ String[] rl = ResourceLocation.splitObjectName(s3); -+ ResourceLocation resourcelocation = new ResourceLocation(rl[0], "textures/effect/" + rl[1] + ".png"); - IResource iresource = null; - - try diff --git a/patches/minecraft/net/minecraft/client/shader/ShaderLoader.java.patch b/patches/minecraft/net/minecraft/client/shader/ShaderLoader.java.patch deleted file mode 100644 index 6515b923a..000000000 --- a/patches/minecraft/net/minecraft/client/shader/ShaderLoader.java.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- before/net/minecraft/client/shader/ShaderLoader.java -+++ after/net/minecraft/client/shader/ShaderLoader.java -@@ -60,7 +60,8 @@ - - if (shaderloader == null) - { -- ResourceLocation resourcelocation = new ResourceLocation("shaders/program/" + filename + type.getShaderExtension()); -+ String[] rl = ResourceLocation.splitObjectName(filename); -+ ResourceLocation resourcelocation = new ResourceLocation(rl[0], "shaders/program/" + rl[1] + type.getShaderExtension()); - IResource iresource = resourceManager.getResource(resourcelocation); - - try diff --git a/patches/minecraft/net/minecraft/client/shader/ShaderManager.java.patch b/patches/minecraft/net/minecraft/client/shader/ShaderManager.java.patch deleted file mode 100644 index 53b62ca6a..000000000 --- a/patches/minecraft/net/minecraft/client/shader/ShaderManager.java.patch +++ /dev/null @@ -1,21 +0,0 @@ ---- before/net/minecraft/client/shader/ShaderManager.java -+++ after/net/minecraft/client/shader/ShaderManager.java -@@ -52,15 +52,15 @@ - - public ShaderManager(IResourceManager resourceManager, String programName) throws JsonException, IOException - { -- JsonParser jsonparser = new JsonParser(); -- ResourceLocation resourcelocation = new ResourceLocation("shaders/program/" + programName + ".json"); -+ String[] rl = ResourceLocation.splitObjectName(programName); -+ ResourceLocation resourcelocation = new ResourceLocation(rl[0], "shaders/program/" + rl[1] + ".json"); - this.programFilename = programName; - IResource iresource = null; - - try - { - iresource = resourceManager.getResource(resourcelocation); -- JsonObject jsonobject = jsonparser.parse(IOUtils.toString(iresource.getInputStream(), StandardCharsets.UTF_8)).getAsJsonObject(); -+ JsonObject jsonobject = JsonParser.parseString(IOUtils.toString(iresource.getInputStream(), StandardCharsets.UTF_8)).getAsJsonObject(); - String s = JsonUtils.getString(jsonobject, "vertex"); - String s1 = JsonUtils.getString(jsonobject, "fragment"); - JsonArray jsonarray = JsonUtils.getJsonArray(jsonobject, "samplers", null); diff --git a/patches/minecraft/net/minecraft/client/util/RecipeBookClient.java.patch b/patches/minecraft/net/minecraft/client/util/RecipeBookClient.java.patch deleted file mode 100644 index d94ae3a6d..000000000 --- a/patches/minecraft/net/minecraft/client/util/RecipeBookClient.java.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- before/net/minecraft/client/util/RecipeBookClient.java -+++ after/net/minecraft/client/util/RecipeBookClient.java -@@ -47,7 +47,15 @@ - - static - { -- Table table = HashBasedTable.create(); -+ rebuildTable(); -+ } -+ -+ public static void rebuildTable() -+ { -+ RECIPES_BY_TAB.clear(); -+ ALL_RECIPES.clear(); -+ -+ Table table = HashBasedTable.create(); - - for (IRecipe irecipe : CraftingManager.REGISTRY) - { diff --git a/patches/minecraft/net/minecraft/client/util/RecipeItemHelper.java.patch b/patches/minecraft/net/minecraft/client/util/RecipeItemHelper.java.patch deleted file mode 100644 index 39c6a3934..000000000 --- a/patches/minecraft/net/minecraft/client/util/RecipeItemHelper.java.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- before/net/minecraft/client/util/RecipeItemHelper.java -+++ after/net/minecraft/client/util/RecipeItemHelper.java -@@ -22,10 +22,15 @@ - - public void accountStack(ItemStack stack) - { -+ this.accountStack(stack, -1); -+ } -+ -+ public void accountStack(ItemStack stack, int forceCount) -+ { - if (!stack.isEmpty() && !stack.isItemDamaged() && !stack.isItemEnchanted() && !stack.hasDisplayName()) - { - int i = pack(stack); -- int j = stack.getCount(); -+ int j = forceCount == -1 ? stack.getCount() : forceCount; - this.increment(i, j); - } - } diff --git a/patches/minecraft/net/minecraft/command/CommandBase.java.patch b/patches/minecraft/net/minecraft/command/CommandBase.java.patch deleted file mode 100644 index ee78807af..000000000 --- a/patches/minecraft/net/minecraft/command/CommandBase.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/command/CommandBase.java -+++ after/net/minecraft/command/CommandBase.java -@@ -398,7 +398,7 @@ - itextcomponent.appendText(" "); - } - -- ITextComponent itextcomponent1 = new TextComponentString(args[i]); -+ ITextComponent itextcomponent1 = net.minecraftforge.common.ForgeHooks.newChatWithLinks(args[i]); // Forge: links for messages - - if (p_147176_3_) - { diff --git a/patches/minecraft/net/minecraft/command/CommandFill.java.patch b/patches/minecraft/net/minecraft/command/CommandFill.java.patch deleted file mode 100644 index a917235b4..000000000 --- a/patches/minecraft/net/minecraft/command/CommandFill.java.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- before/net/minecraft/command/CommandFill.java -+++ after/net/minecraft/command/CommandFill.java -@@ -96,7 +96,7 @@ - NBTTagCompound nbttagcompound = new NBTTagCompound(); - boolean flag = false; - -- if (args.length >= 10 && block.hasTileEntity()) -+ if (args.length >= 10 && block.hasTileEntity(iblockstate)) - { - String s = buildString(args, 9); - -@@ -137,7 +137,7 @@ - continue; - } - } -- else if ("replace".equals(args[8]) && !block.hasTileEntity() && args.length > 9) -+ else if ("replace".equals(args[8]) && !block.hasTileEntity(iblockstate) && args.length > 9) - { - Block block1 = CommandBase.getBlockByText(sender, args[9]); - diff --git a/patches/minecraft/net/minecraft/command/CommandGameRule.java.patch b/patches/minecraft/net/minecraft/command/CommandGameRule.java.patch deleted file mode 100644 index c812e5380..000000000 --- a/patches/minecraft/net/minecraft/command/CommandGameRule.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- before/net/minecraft/command/CommandGameRule.java -+++ after/net/minecraft/command/CommandGameRule.java -@@ -77,6 +77,7 @@ - entityplayermp.connection.sendPacket(new SPacketEntityStatus(entityplayermp, b0)); - } - } -+ net.minecraftforge.event.ForgeEventFactory.onGameRuleChange(rules, p_184898_1_, server); - } - - @Override diff --git a/patches/minecraft/net/minecraft/command/CommandHandler.java.patch b/patches/minecraft/net/minecraft/command/CommandHandler.java.patch deleted file mode 100644 index ab76c59f0..000000000 --- a/patches/minecraft/net/minecraft/command/CommandHandler.java.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- before/net/minecraft/command/CommandHandler.java -+++ after/net/minecraft/command/CommandHandler.java -@@ -51,6 +51,17 @@ - } - else if (icommand.checkPermission(this.getServer(), sender)) - { -+ net.minecraftforge.event.CommandEvent event = new net.minecraftforge.event.CommandEvent(icommand, sender, astring); -+ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event)) -+ { -+ if (event.getException() != null) -+ { -+ com.google.common.base.Throwables.throwIfUnchecked(event.getException()); -+ } -+ return 1; -+ } -+ if (event.getParameters() != null) astring = event.getParameters(); -+ - if (j > -1) - { - List list = EntitySelector.matchEntities(sender, astring[j], Entity.class); diff --git a/patches/minecraft/net/minecraft/command/EntitySelector.java.patch b/patches/minecraft/net/minecraft/command/EntitySelector.java.patch deleted file mode 100644 index ed855ca24..000000000 --- a/patches/minecraft/net/minecraft/command/EntitySelector.java.patch +++ /dev/null @@ -1,46 +0,0 @@ ---- before/net/minecraft/command/EntitySelector.java -+++ after/net/minecraft/command/EntitySelector.java -@@ -124,6 +124,11 @@ - - public static List matchEntities(ICommandSender sender, String token, Class targetClass) throws CommandException - { -+ return net.minecraftforge.common.command.SelectorHandlerManager.matchEntities(sender, token, targetClass); -+ } -+ -+ public static List matchEntitiesDefault(ICommandSender sender, String token, Class targetClass) throws CommandException -+ { - Matcher matcher = TOKEN_PATTERN.matcher(token); - - if (matcher.matches() && sender.canUseCommand(1, "@")) -@@ -156,6 +161,7 @@ - list2.addAll(getTagPredicates(map)); - list2.addAll(getRadiusPredicates(map, vec3d)); - list2.addAll(getRotationsPredicates(map)); -+ list2.addAll(net.minecraftforge.fml.common.registry.GameRegistry.createEntitySelectors(map, s, sender, vec3d)); - - if ("s".equalsIgnoreCase(s)) - { -@@ -802,6 +808,11 @@ - - public static boolean matchesMultiplePlayers(String selectorStr) throws CommandException - { -+ return net.minecraftforge.common.command.SelectorHandlerManager.matchesMultiplePlayers(selectorStr); -+ } -+ -+ public static boolean matchesMultiplePlayersDefault(String selectorStr) throws CommandException -+ { - Matcher matcher = TOKEN_PATTERN.matcher(selectorStr); - - if (!matcher.matches()) -@@ -818,6 +829,11 @@ - } - - public static boolean isSelector(String selectorStr) -+ { -+ return net.minecraftforge.common.command.SelectorHandlerManager.isSelector(selectorStr); -+ } -+ -+ public static boolean isSelectorDefault(String selectorStr) - { - return TOKEN_PATTERN.matcher(selectorStr).matches(); - } diff --git a/patches/minecraft/net/minecraft/command/server/CommandSetBlock.java.patch b/patches/minecraft/net/minecraft/command/server/CommandSetBlock.java.patch deleted file mode 100644 index e3a19171b..000000000 --- a/patches/minecraft/net/minecraft/command/server/CommandSetBlock.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/command/server/CommandSetBlock.java -+++ after/net/minecraft/command/server/CommandSetBlock.java -@@ -74,7 +74,7 @@ - NBTTagCompound nbttagcompound = new NBTTagCompound(); - boolean flag = false; - -- if (args.length >= 7 && block.hasTileEntity()) -+ if (args.length >= 7 && block.hasTileEntity(iblockstate)) - { - String s = buildString(args, 6); - diff --git a/patches/minecraft/net/minecraft/crash/CrashReport.java.patch b/patches/minecraft/net/minecraft/crash/CrashReport.java.patch deleted file mode 100644 index f5984f234..000000000 --- a/patches/minecraft/net/minecraft/crash/CrashReport.java.patch +++ /dev/null @@ -1,26 +0,0 @@ ---- before/net/minecraft/crash/CrashReport.java -+++ after/net/minecraft/crash/CrashReport.java -@@ -116,6 +116,7 @@ - return IntCache.getCacheSizes(); - } - }); -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().enhanceCrashReport(this, this.systemDetailsCategory); - } - - public String getDescription() -@@ -198,13 +199,14 @@ - IOUtils.closeQuietly((Writer)printwriter); - } - -- return s; -+ return s + com.cleanroommc.cleanmix.CleanMixHooks.addMixinMetadataToCrashReport(throwable); - } - - public String getCompleteReport() - { - StringBuilder stringbuilder = new StringBuilder(); - stringbuilder.append("---- Minecraft Crash Report ----\n"); -+ net.minecraftforge.fml.relauncher.CoreModManager.onCrash(stringbuilder); - stringbuilder.append("// "); - stringbuilder.append(getWittyComment()); - stringbuilder.append("\n\n"); diff --git a/patches/minecraft/net/minecraft/crash/CrashReportCategory.java.patch b/patches/minecraft/net/minecraft/crash/CrashReportCategory.java.patch deleted file mode 100644 index cf47515a3..000000000 --- a/patches/minecraft/net/minecraft/crash/CrashReportCategory.java.patch +++ /dev/null @@ -1,25 +0,0 @@ ---- before/net/minecraft/crash/CrashReportCategory.java -+++ after/net/minecraft/crash/CrashReportCategory.java -@@ -123,8 +123,11 @@ - } - else - { -- this.stackTrace = new StackTraceElement[astacktraceelement.length - 3 - size]; -- System.arraycopy(astacktraceelement, 3 + size, this.stackTrace, 0, this.stackTrace.length); -+ int len = astacktraceelement.length - 3 - size; -+ // Really Mojang, Still, god damn... -+ if (len <= 0) len = astacktraceelement.length; -+ this.stackTrace = new StackTraceElement[len]; -+ System.arraycopy(astacktraceelement, astacktraceelement.length - len, this.stackTrace, 0, this.stackTrace.length); - return this.stackTrace.length; - } - } -@@ -211,7 +214,7 @@ - { - try - { -- return String.format("ID #%d (%s // %s)", i, blockIn.getTranslationKey(), blockIn.getClass().getCanonicalName()); -+ return String.format("ID #%d (%s // %s // %s)", i, blockIn.getTranslationKey(), blockIn.getClass().getName(), blockIn.getRegistryName()); - } - catch (Throwable throwable) - { diff --git a/patches/minecraft/net/minecraft/creativetab/CreativeTabs.java.patch b/patches/minecraft/net/minecraft/creativetab/CreativeTabs.java.patch deleted file mode 100644 index 779b61bb1..000000000 --- a/patches/minecraft/net/minecraft/creativetab/CreativeTabs.java.patch +++ /dev/null @@ -1,98 +0,0 @@ ---- before/net/minecraft/creativetab/CreativeTabs.java -+++ after/net/minecraft/creativetab/CreativeTabs.java -@@ -157,8 +157,22 @@ - private EnumEnchantmentType[] enchantmentTypes = new EnumEnchantmentType[0]; - private ItemStack icon; - -+ public CreativeTabs(String label) -+ { -+ this(getNextID(), label); -+ } -+ - public CreativeTabs(int index, String label) - { -+ if (index >= CREATIVE_TAB_ARRAY.length) -+ { -+ CreativeTabs[] tmp = new CreativeTabs[index + 1]; -+ for (int x = 0; x < CREATIVE_TAB_ARRAY.length; x++) -+ { -+ tmp[x] = CREATIVE_TAB_ARRAY[x]; -+ } -+ CREATIVE_TAB_ARRAY = tmp; -+ } - this.index = index; - this.tabLabel = label; - this.icon = ItemStack.EMPTY; -@@ -236,12 +250,20 @@ - @SideOnly(Side.CLIENT) - public int getColumn() - { -+ if (index > 11) -+ { -+ return ((index - 12) % 10) % 5; -+ } - return this.index % 6; - } - - @SideOnly(Side.CLIENT) - public boolean isOnTopRow() - { -+ if (index > 11) -+ { -+ return ((index - 12) % 10) < 5; -+ } - return this.index < 6; - } - -@@ -285,5 +307,51 @@ - { - item.getSubItems(this, p_78018_1_); - } -+ } -+ -+ public int getTabPage() -+ { -+ if (index > 11) -+ { -+ return ((index - 12) / 10) + 1; -+ } -+ return 0; -+ } -+ -+ public static int getNextID() -+ { -+ return CREATIVE_TAB_ARRAY.length; -+ } -+ -+ /** -+ * Determines if the search bar should be shown for this tab. -+ * -+ * @return True to show the bar -+ */ -+ public boolean hasSearchBar() -+ { -+ return index == CreativeTabs.SEARCH.index; -+ } -+ -+ /** -+ * Gets the width of the search bar of the creative tab, use this if your -+ * creative tab name overflows together with a custom texture. -+ * -+ * @return The width of the search bar, 89 by default -+ */ -+ public int getSearchbarWidth() -+ { -+ return 89; -+ } -+ -+ @SideOnly(Side.CLIENT) -+ public net.minecraft.util.ResourceLocation getBackgroundImage() -+ { -+ return new net.minecraft.util.ResourceLocation("textures/gui/container/creative_inventory/tab_" + this.getBackgroundImageName()); -+ } -+ -+ public int getLabelColor() -+ { -+ return 4210752; - } - } diff --git a/patches/minecraft/net/minecraft/enchantment/Enchantment.java.patch b/patches/minecraft/net/minecraft/enchantment/Enchantment.java.patch deleted file mode 100644 index 03a35ab9d..000000000 --- a/patches/minecraft/net/minecraft/enchantment/Enchantment.java.patch +++ /dev/null @@ -1,50 +0,0 @@ ---- before/net/minecraft/enchantment/Enchantment.java -+++ after/net/minecraft/enchantment/Enchantment.java -@@ -14,9 +14,9 @@ - import net.minecraft.util.text.TextFormatting; - import net.minecraft.util.text.translation.I18n; - --public abstract class Enchantment -+public abstract class Enchantment extends net.minecraftforge.registries.IForgeRegistryEntry.Impl - { -- public static final RegistryNamespaced REGISTRY = new RegistryNamespaced<>(); -+ public static final RegistryNamespaced REGISTRY = net.minecraftforge.registries.GameData.getWrapper(Enchantment.class); - private final EntityEquipmentSlot[] applicableEquipmentTypes; - private final Enchantment.Rarity rarity; - @Nullable -@@ -134,7 +134,7 @@ - - public boolean canApply(ItemStack stack) - { -- return this.type.canEnchantItem(stack.getItem()); -+ return canApplyAtEnchantingTable(stack); - } - - public void onEntityDamaged(EntityLivingBase user, Entity target, int level) -@@ -153,6 +153,26 @@ - public boolean isCurse() - { - return false; -+ } -+ -+ /** -+ * This applies specifically to applying at the enchanting table. The other method {@link #canApply(ItemStack)} -+ * applies for all possible enchantments. -+ * @param stack -+ * @return -+ */ -+ public boolean canApplyAtEnchantingTable(ItemStack stack) -+ { -+ return stack.getItem().canApplyAtEnchantingTable(stack, this); -+ } -+ -+ /** -+ * Is this enchantment allowed to be enchanted on books via Enchantment Table -+ * @return false to disable the vanilla feature -+ */ -+ public boolean isAllowedOnBooks() -+ { -+ return true; - } - - public static void registerEnchantments() diff --git a/patches/minecraft/net/minecraft/enchantment/EnchantmentFrostWalker.java.patch b/patches/minecraft/net/minecraft/enchantment/EnchantmentFrostWalker.java.patch deleted file mode 100644 index c56f36921..000000000 --- a/patches/minecraft/net/minecraft/enchantment/EnchantmentFrostWalker.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- before/net/minecraft/enchantment/EnchantmentFrostWalker.java -+++ after/net/minecraft/enchantment/EnchantmentFrostWalker.java -@@ -67,6 +67,7 @@ - IBlockState iblockstate1 = worldIn.getBlockState(blockpos$mutableblockpos1); - - if (iblockstate1.getMaterial() == Material.WATER -+ && (iblockstate1.getBlock() == net.minecraft.init.Blocks.WATER || iblockstate1.getBlock() == net.minecraft.init.Blocks.FLOWING_WATER) - && iblockstate1.getValue(BlockLiquid.LEVEL) == 0 - && worldIn.mayPlace(Blocks.FROSTED_ICE, blockpos$mutableblockpos1, false, EnumFacing.DOWN, null)) - { diff --git a/patches/minecraft/net/minecraft/enchantment/EnchantmentHelper.java.patch b/patches/minecraft/net/minecraft/enchantment/EnchantmentHelper.java.patch deleted file mode 100644 index 8c1e1b5b8..000000000 --- a/patches/minecraft/net/minecraft/enchantment/EnchantmentHelper.java.patch +++ /dev/null @@ -1,67 +0,0 @@ ---- before/net/minecraft/enchantment/EnchantmentHelper.java -+++ after/net/minecraft/enchantment/EnchantmentHelper.java -@@ -140,6 +140,7 @@ - ENCHANTMENT_MODIFIER_DAMAGE.damageModifier = 0; - ENCHANTMENT_MODIFIER_DAMAGE.source = source; - applyEnchantmentModifierArray(ENCHANTMENT_MODIFIER_DAMAGE, stacks); -+ ENCHANTMENT_MODIFIER_DAMAGE.source = null; //Forge Fix memory leaks: https://bugs.mojang.com/browse/MC-128547 - return ENCHANTMENT_MODIFIER_DAMAGE.damageModifier; - } - -@@ -171,6 +172,9 @@ - { - applyEnchantmentModifier(ENCHANTMENT_ITERATOR_HURT, p_151384_0_.getHeldItemMainhand()); - } -+ -+ ENCHANTMENT_ITERATOR_HURT.attacker = null; //Forge Fix memory leaks: https://bugs.mojang.com/browse/MC-128547 -+ ENCHANTMENT_ITERATOR_HURT.user = null; - } - - public static void applyArthropodEnchantments(EntityLivingBase p_151385_0_, Entity p_151385_1_) -@@ -187,6 +191,9 @@ - { - applyEnchantmentModifier(ENCHANTMENT_ITERATOR_DAMAGE, p_151385_0_.getHeldItemMainhand()); - } -+ -+ ENCHANTMENT_ITERATOR_DAMAGE.user = null; //Forge Fix memory leaks: https://bugs.mojang.com/browse/MC-128547 -+ ENCHANTMENT_ITERATOR_DAMAGE.target = null; - } - - public static int getMaxEnchantmentLevel(Enchantment p_185284_0_, EntityLivingBase p_185284_1_) -@@ -302,7 +309,7 @@ - public static int calcItemStackEnchantability(Random rand, int enchantNum, int power, ItemStack stack) - { - Item item = stack.getItem(); -- int i = item.getItemEnchantability(); -+ int i = item.getItemEnchantability(stack); - - if (i <= 0) - { -@@ -357,7 +364,7 @@ - { - List list = Lists.newArrayList(); - Item item = itemStackIn.getItem(); -- int i = item.getItemEnchantability(); -+ int i = item.getItemEnchantability(itemStackIn); - - if (i <= 0) - { -@@ -407,15 +414,15 @@ - - public static List getEnchantmentDatas(int p_185291_0_, ItemStack p_185291_1_, boolean allowTreasure) - { -- List list = Lists.newArrayList(); -+ List list = Lists.newArrayList(); - Item item = p_185291_1_.getItem(); - boolean flag = p_185291_1_.getItem() == Items.BOOK; - - for (Enchantment enchantment : Enchantment.REGISTRY) - { -- if ((!enchantment.isTreasureEnchantment() || allowTreasure) && (enchantment.type.canEnchantItem(item) || flag)) -+ if ((!enchantment.isTreasureEnchantment() || allowTreasure) && (enchantment.canApplyAtEnchantingTable(p_185291_1_) || (flag && enchantment.isAllowedOnBooks()))) - { -- for (int i = enchantment.getMaxLevel(); i > enchantment.getMinLevel() - 1; i--) -+ for (int i = enchantment.getMaxLevel(); i > enchantment.getMinLevel() - 1; --i) - { - if (p_185291_0_ >= enchantment.getMinEnchantability(i) && p_185291_0_ <= enchantment.getMaxEnchantability(i)) - { diff --git a/patches/minecraft/net/minecraft/enchantment/EnchantmentThorns.java.patch b/patches/minecraft/net/minecraft/enchantment/EnchantmentThorns.java.patch deleted file mode 100644 index 2c67051b9..000000000 --- a/patches/minecraft/net/minecraft/enchantment/EnchantmentThorns.java.patch +++ /dev/null @@ -1,44 +0,0 @@ ---- before/net/minecraft/enchantment/EnchantmentThorns.java -+++ after/net/minecraft/enchantment/EnchantmentThorns.java -@@ -56,12 +56,12 @@ - - if (!itemstack.isEmpty()) - { -- itemstack.damageItem(3, user); -+ damageArmor(itemstack, 3, user); - } - } - else if (!itemstack.isEmpty()) - { -- itemstack.damageItem(1, user); -+ damageArmor(itemstack, 1, user); - } - } - -@@ -73,5 +73,26 @@ - public static int getDamage(int level, Random rnd) - { - return level > 10 ? level - 10 : 1 + rnd.nextInt(4); -+ } -+ -+ private void damageArmor(ItemStack stack, int amount, EntityLivingBase entity) -+ { -+ int slot = -1; -+ int x = 0; -+ for (ItemStack i : entity.getArmorInventoryList()) -+ { -+ if (i == stack){ -+ slot = x; -+ break; -+ } -+ x++; -+ } -+ if (slot == -1 || !(stack.getItem() instanceof net.minecraftforge.common.ISpecialArmor)) -+ { -+ stack.damageItem(1, entity); -+ return; -+ } -+ net.minecraftforge.common.ISpecialArmor armor = (net.minecraftforge.common.ISpecialArmor)stack.getItem(); -+ armor.damageArmor(entity, stack, DamageSource.causeThornsDamage(entity), amount, slot); - } - } diff --git a/patches/minecraft/net/minecraft/enchantment/EnumEnchantmentType.java.patch b/patches/minecraft/net/minecraft/enchantment/EnumEnchantmentType.java.patch deleted file mode 100644 index e54db14b4..000000000 --- a/patches/minecraft/net/minecraft/enchantment/EnumEnchantmentType.java.patch +++ /dev/null @@ -1,17 +0,0 @@ ---- before/net/minecraft/enchantment/EnumEnchantmentType.java -+++ after/net/minecraft/enchantment/EnumEnchantmentType.java -@@ -112,5 +112,13 @@ - { - } - -- public abstract boolean canEnchantItem(Item itemIn); -+ private com.google.common.base.Predicate delegate = null; -+ private EnumEnchantmentType(com.google.common.base.Predicate delegate) -+ { -+ this.delegate = delegate; -+ } -+ public boolean canEnchantItem(Item itemIn) -+ { -+ return this.delegate == null ? false : this.delegate.apply(itemIn); -+ } - } diff --git a/patches/minecraft/net/minecraft/entity/Entity.java.patch b/patches/minecraft/net/minecraft/entity/Entity.java.patch deleted file mode 100644 index ee7fde7cd..000000000 --- a/patches/minecraft/net/minecraft/entity/Entity.java.patch +++ /dev/null @@ -1,475 +0,0 @@ ---- before/net/minecraft/entity/Entity.java -+++ after/net/minecraft/entity/Entity.java -@@ -85,7 +85,7 @@ - import org.apache.logging.log4j.LogManager; - import org.apache.logging.log4j.Logger; - --public abstract class Entity implements ICommandSender -+public abstract class Entity implements ICommandSender, net.minecraftforge.common.capabilities.ICapabilitySerializable - { - private static final Logger LOGGER = LogManager.getLogger(); - private static final List EMPTY_EQUIPMENT = Collections.emptyList(); -@@ -177,6 +177,10 @@ - private boolean isPositionDirty; - private final double[] pistonDeltas; - private long pistonDeltasGameTime; -+ /** -+ * Setting this to true will prevent the world from calling {@link #onUpdate()} for this entity. -+ */ -+ public boolean updateBlocked; - - public Entity(World worldIn) - { -@@ -200,7 +204,7 @@ - - if (worldIn != null) - { -- this.dimension = worldIn.provider.getDimensionType().getId(); -+ this.dimension = worldIn.provider.getDimension(); - } - - this.dataManager = new EntityDataManager(this); -@@ -211,7 +215,15 @@ - this.dataManager.register(SILENT, false); - this.dataManager.register(NO_GRAVITY, false); - this.entityInit(); -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.EntityEvent.EntityConstructing(this)); -+ capabilities = net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(this); - } -+ -+ /** Forge: Used to store custom data for each entity. */ -+ private NBTTagCompound customEntityData; -+ public boolean captureDrops = false; -+ public java.util.ArrayList capturedDrops = new java.util.ArrayList(); -+ private net.minecraftforge.common.capabilities.CapabilityDispatcher capabilities; - - public int getEntityId() - { -@@ -357,6 +369,7 @@ - this.posX = x; - this.posY = y; - this.posZ = z; -+ if (this.isAddedToWorld() && !this.world.isRemote) this.world.updateEntityWithOptionalForce(this, false); // Forge - Process chunk registration after moving. - float f = this.width / 2.0F; - float f1 = this.height; - this.setEntityBoundingBox(new AxisAlignedBB(x - f, y, z - f, x + f, y + f1, z + f)); -@@ -1024,6 +1037,7 @@ - this.posX = (axisalignedbb.minX + axisalignedbb.maxX) / 2.0; - this.posY = axisalignedbb.minY; - this.posZ = (axisalignedbb.minZ + axisalignedbb.maxZ) / 2.0; -+ if (this.isAddedToWorld() && !this.world.isRemote) this.world.updateEntityWithOptionalForce(this, false); // Forge - Process chunk registration after moving. - } - - protected SoundEvent getSwimSound() -@@ -1086,7 +1100,7 @@ - - protected void playStepSound(BlockPos pos, Block blockIn) - { -- SoundType soundtype = blockIn.getSoundType(); -+ SoundType soundtype = blockIn.getSoundType(world.getBlockState(pos), world, pos, this); - - if (this.world.getBlockState(pos.up()).getBlock() == Blocks.SNOW_LAYER) - { -@@ -1320,6 +1334,7 @@ - BlockPos blockpos = new BlockPos(i, j, k); - IBlockState iblockstate = this.world.getBlockState(blockpos); - -+ if(!iblockstate.getBlock().addRunningEffects(iblockstate, world, blockpos, this)) - if (iblockstate.getRenderType() != EnumBlockRenderType.INVISIBLE) - { - this.world -@@ -1348,12 +1363,12 @@ - BlockPos blockpos = new BlockPos(this.posX, d0, this.posZ); - IBlockState iblockstate = this.world.getBlockState(blockpos); - -+ Boolean result = iblockstate.getBlock().isEntityInsideMaterial(this.world, blockpos, iblockstate, this, d0, materialIn, true); -+ if (result != null) return result; -+ - if (iblockstate.getMaterial() == materialIn) - { -- float f = BlockLiquid.getLiquidHeightPercent(iblockstate.getBlock().getMetaFromState(iblockstate)) - 0.11111111F; -- float f1 = blockpos.getY() + 1 - f; -- boolean flag = d0 < f1; -- return !flag && this instanceof EntityPlayer ? false : flag; -+ return net.minecraftforge.common.ForgeHooks.isInsideOfMaterial(materialIn, this, blockpos); - } - else - { -@@ -1457,6 +1472,7 @@ - this.prevRotationYaw -= 360.0F; - } - -+ if (!this.world.isRemote) this.world.getChunk((int) Math.floor(this.posX) >> 4, (int) Math.floor(this.posZ) >> 4); // Forge - ensure target chunk is loaded. - this.setPosition(this.posX, this.posY, this.posZ); - this.setRotation(yaw, pitch); - } -@@ -1783,6 +1799,7 @@ - { - compound.setBoolean("Glowing", this.glowing); - } -+ compound.setBoolean("UpdateBlocked", updateBlocked); - - if (!this.tags.isEmpty()) - { -@@ -1796,6 +1813,9 @@ - compound.setTag("Tags", nbttaglist); - } - -+ if (customEntityData != null) compound.setTag("ForgeData", customEntityData); -+ if (this.capabilities != null) compound.setTag("ForgeCaps", this.capabilities.serializeNBT()); -+ - this.writeEntityToNBT(compound); - - if (this.isBeingRidden()) -@@ -1902,6 +1922,10 @@ - this.setSilent(compound.getBoolean("Silent")); - this.setNoGravity(compound.getBoolean("NoGravity")); - this.setGlowing(compound.getBoolean("Glowing")); -+ updateBlocked = compound.getBoolean("UpdateBlocked"); -+ -+ if (compound.hasKey("ForgeData")) customEntityData = compound.getCompoundTag("ForgeData"); -+ if (this.capabilities != null && compound.hasKey("ForgeCaps")) this.capabilities.deserializeNBT(compound.getCompoundTag("ForgeCaps")); - - if (compound.hasKey("Tags", 9)) - { -@@ -1994,7 +2018,10 @@ - { - EntityItem entityitem = new EntityItem(this.world, this.posX, this.posY + offsetY, this.posZ, stack); - entityitem.setDefaultPickupDelay(); -- this.world.spawnEntity(entityitem); -+ if (captureDrops) -+ this.capturedDrops.add(entityitem); -+ else -+ this.world.spawnEntity(entityitem); - return entityitem; - } - } -@@ -2063,6 +2090,7 @@ - this.motionX = 0.0; - this.motionY = 0.0; - this.motionZ = 0.0; -+ if(!updateBlocked) - this.onUpdate(); - - if (this.isRiding()) -@@ -2110,6 +2138,7 @@ - } - } - -+ if (!net.minecraftforge.event.ForgeEventFactory.canMountEntity(this, entityIn, true)) return false; - if (force || this.canBeRidden(entityIn) && entityIn.canFitPassenger(this)) - { - if (this.isRiding()) -@@ -2145,6 +2174,7 @@ - if (this.ridingEntity != null) - { - Entity entity = this.ridingEntity; -+ if (!net.minecraftforge.event.ForgeEventFactory.canMountEntity(this, entity, false)) return; - this.ridingEntity = null; - entity.removePassenger(this); - } -@@ -2612,8 +2642,16 @@ - @Nullable - public Entity changeDimension(int dimensionIn) - { -+ if (this.world.isRemote || this.isDead) return null; -+ return changeDimension(dimensionIn, this.getServer().getWorld(dimensionIn).getDefaultTeleporter()); -+ } -+ -+ @Nullable // Forge: Entities that require custom handling should override this method, not the other -+ public Entity changeDimension(int dimensionIn, net.minecraftforge.common.util.ITeleporter teleporter) -+ { - if (!this.world.isRemote && !this.isDead) - { -+ if (!net.minecraftforge.common.ForgeHooks.onTravelToDimension(this, dimensionIn)) return null; - this.world.profiler.startSection("changeDimension"); - MinecraftServer minecraftserver = this.getServer(); - int i = this.dimension; -@@ -2621,7 +2659,7 @@ - WorldServer worldserver1 = minecraftserver.getWorld(dimensionIn); - this.dimension = dimensionIn; - -- if (i == 1 && dimensionIn == 1) -+ if (i == 1 && dimensionIn == 1 && teleporter.isVanilla()) - { - worldserver1 = minecraftserver.getWorld(0); - this.dimension = 0; -@@ -2632,17 +2670,18 @@ - this.world.profiler.startSection("reposition"); - BlockPos blockpos; - -- if (dimensionIn == 1) -+ if (dimensionIn == 1 && teleporter.isVanilla()) - { - blockpos = worldserver1.getSpawnCoordinate(); - } - else - { -- double d0 = this.posX; -- double d1 = this.posZ; -+ double moveFactor = worldserver.provider.getMovementFactor() / worldserver1.provider.getMovementFactor(); -+ double d0 = MathHelper.clamp(this.posX * moveFactor, worldserver1.getWorldBorder().minX() + 16.0, worldserver1.getWorldBorder().maxX() - 16.0); -+ double d1 = MathHelper.clamp(this.posZ * moveFactor, worldserver1.getWorldBorder().minZ() + 16.0, worldserver1.getWorldBorder().maxZ() - 16.0); - double d2 = 8.0; - -- if (dimensionIn == -1) -+ if (false && dimensionIn == -1) - { - d0 = MathHelper.clamp( - d0 / 8.0, worldserver1.getWorldBorder().minX() + 16.0, worldserver1.getWorldBorder().maxX() - 16.0 -@@ -2651,7 +2690,7 @@ - d1 / 8.0, worldserver1.getWorldBorder().minZ() + 16.0, worldserver1.getWorldBorder().maxZ() - 16.0 - ); - } -- else if (dimensionIn == 0) -+ else if (false && dimensionIn == 0) - { - d0 = MathHelper.clamp( - d0 * 8.0, worldserver1.getWorldBorder().minX() + 16.0, worldserver1.getWorldBorder().maxX() - 16.0 -@@ -2665,8 +2704,7 @@ - d1 = MathHelper.clamp((int)d1, -29999872, 29999872); - float f = this.rotationYaw; - this.setLocationAndAngles(d0, this.posY, d1, 90.0F, 0.0F); -- Teleporter teleporter = worldserver1.getDefaultTeleporter(); -- teleporter.placeInExistingPortal(this, f); -+ teleporter.placeEntity(worldserver1, this, f); - blockpos = new BlockPos(this); - } - -@@ -2678,7 +2716,7 @@ - { - entity.copyDataFromOld(this); - -- if (i == 1 && dimensionIn == 1) -+ if (i == 1 && dimensionIn == 1 && teleporter.isVanilla()) - { - BlockPos blockpos1 = worldserver1.getTopSolidOrLiquidBlock(worldserver1.getSpawnPoint()); - entity.moveToBlockPosAndAngles(blockpos1, entity.rotationYaw, entity.rotationPitch); -@@ -2715,7 +2753,7 @@ - - public float getExplosionResistance(Explosion explosionIn, World worldIn, BlockPos pos, IBlockState blockStateIn) - { -- return blockStateIn.getBlock().getExplosionResistance(this); -+ return blockStateIn.getBlock().getExplosionResistance(worldIn, pos, this, explosionIn); - } - - public boolean canExplosionDestroyBlock(Explosion explosionIn, World worldIn, BlockPos pos, IBlockState blockStateIn, float p_174816_5_) -@@ -3026,6 +3064,218 @@ - - EnchantmentHelper.applyArthropodEnchantments(entityLivingBaseIn, entityIn); - } -+ -+ /* ================================== Forge Start =====================================*/ -+ /** -+ * Internal use for keeping track of entities that are tracked by a world, to -+ * allow guarantees that entity position changes will force a chunk load, avoiding -+ * potential issues with entity desyncing and bad chunk data. -+ */ -+ private boolean isAddedToWorld; -+ -+ /** -+ * Gets whether this entity has been added to a world (for tracking). Specifically -+ * between the times when an entity is added to a world and the entity being removed -+ * from the world's tracked lists. See {@link World#onEntityAdded(Entity)} and -+ * {@link World#onEntityRemoved(Entity)}. -+ * -+ * @return True if this entity is being tracked by a world -+ */ -+ public final boolean isAddedToWorld() { return this.isAddedToWorld; } -+ -+ /** -+ * Called after the entity has been added to the world's -+ * ticking list. Can be overriden, but needs to call super -+ * to prevent MC-136995. -+ */ -+ public void onAddedToWorld() { -+ this.isAddedToWorld = true; -+ } -+ -+ /** -+ * Called after the entity has been removed to the world's -+ * ticking list. Can be overriden, but needs to call super -+ * to prevent MC-136995. -+ */ -+ public void onRemovedFromWorld() { -+ this.isAddedToWorld = false; -+ } -+ -+ /** -+ * Returns a NBTTagCompound that can be used to store custom data for this entity. -+ * It will be written, and read from disc, so it persists over world saves. -+ * @return A NBTTagCompound -+ */ -+ public NBTTagCompound getEntityData() -+ { -+ if (customEntityData == null) -+ { -+ customEntityData = new NBTTagCompound(); -+ } -+ return customEntityData; -+ } -+ -+ /** -+ * Used in model rendering to determine if the entity riding this entity should be in the 'sitting' position. -+ * @return false to prevent an entity that is mounted to this entity from displaying the 'sitting' animation. -+ */ -+ public boolean shouldRiderSit() -+ { -+ return true; -+ } -+ -+ /** -+ * Called when a user uses the creative pick block button on this entity. -+ * -+ * @param target The full target the player is looking at -+ * @return A ItemStack to add to the player's inventory, empty ItemStack if nothing should be added. -+ */ -+ public ItemStack getPickedResult(RayTraceResult target) -+ { -+ if (this instanceof net.minecraft.entity.item.EntityPainting) -+ { -+ return new ItemStack(net.minecraft.init.Items.PAINTING); -+ } -+ else if (this instanceof EntityLeashKnot) -+ { -+ return new ItemStack(net.minecraft.init.Items.LEAD); -+ } -+ else if (this instanceof net.minecraft.entity.item.EntityItemFrame) -+ { -+ ItemStack held = ((net.minecraft.entity.item.EntityItemFrame)this).getDisplayedItem(); -+ if (held.isEmpty()) -+ { -+ return new ItemStack(net.minecraft.init.Items.ITEM_FRAME); -+ } -+ else -+ { -+ return held.copy(); -+ } -+ } -+ else if (this instanceof net.minecraft.entity.item.EntityMinecart) -+ { -+ return ((net.minecraft.entity.item.EntityMinecart)this).getCartItem(); -+ } -+ else if (this instanceof net.minecraft.entity.item.EntityBoat) -+ { -+ return new ItemStack(((EntityBoat)this).getItemBoat()); -+ } -+ else if (this instanceof net.minecraft.entity.item.EntityArmorStand) -+ { -+ return new ItemStack(net.minecraft.init.Items.ARMOR_STAND); -+ } -+ else if (this instanceof net.minecraft.entity.item.EntityEnderCrystal) -+ { -+ return new ItemStack(net.minecraft.init.Items.END_CRYSTAL); -+ } -+ else -+ { -+ ResourceLocation name = EntityList.getKey(this); -+ if (name != null && EntityList.ENTITY_EGGS.containsKey(name)) -+ { -+ ItemStack stack = new ItemStack(net.minecraft.init.Items.SPAWN_EGG); -+ net.minecraft.item.ItemMonsterPlacer.applyEntityIdToItemStack(stack, name); -+ return stack; -+ } -+ } -+ return ItemStack.EMPTY; -+ } -+ -+ public UUID getPersistentID() -+ { -+ return entityUniqueID; -+ } -+ -+ /** -+ * Reset the entity ID to a new value. Not to be used from Mod code -+ */ -+ @Deprecated // TODO: remove (1.13?) -+ public final void resetEntityId() -+ { -+ this.entityId = nextEntityID++; -+ } -+ -+ public boolean shouldRenderInPass(int pass) -+ { -+ return pass == 0; -+ } -+ -+ /** -+ * Returns true if the entity is of the @link{EnumCreatureType} provided -+ * @param type The EnumCreatureType type this entity is evaluating -+ * @param forSpawnCount If this is being invoked to check spawn count caps. -+ * @return If the creature is of the type provided -+ */ -+ public boolean isCreatureType(EnumCreatureType type, boolean forSpawnCount) -+ { -+ if (forSpawnCount && (this instanceof EntityLiving) && ((EntityLiving)this).isNoDespawnRequired()) return false; -+ return type.getCreatureClass().isAssignableFrom(this.getClass()); -+ } -+ -+ /** -+ * If a rider of this entity can interact with this entity. Should return true on the -+ * ridden entity if so. -+ * -+ * @return if the entity can be interacted with from a rider -+ */ -+ public boolean canRiderInteract() -+ { -+ return false; -+ } -+ -+ /** -+ * If the rider should be dismounted from the entity when the entity goes under water -+ * -+ * @param rider The entity that is riding -+ * @return if the entity should be dismounted when under water -+ */ -+ public boolean shouldDismountInWater(Entity rider) -+ { -+ return this instanceof EntityLivingBase; -+ } -+ -+ @Override -+ public boolean hasCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable net.minecraft.util.EnumFacing facing) -+ { -+ return capabilities != null && capabilities.hasCapability(capability, facing); -+ } -+ -+ @Override -+ @Nullable -+ public T getCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable net.minecraft.util.EnumFacing facing) -+ { -+ return capabilities == null ? null : capabilities.getCapability(capability, facing); -+ } -+ -+ public void deserializeNBT(NBTTagCompound nbt) -+ { -+ this.readFromNBT(nbt); -+ } -+ -+ public NBTTagCompound serializeNBT() -+ { -+ NBTTagCompound ret = new NBTTagCompound(); -+ ret.setString("id", this.getEntityString()); -+ return this.writeToNBT(ret); -+ } -+ -+ /** -+ * Checks if this {@link Entity} can trample a {@link Block}. -+ * -+ * @param world The world in which the block will be trampled -+ * @param block The block being tested -+ * @param pos The block pos -+ * @param fallDistance The fall distance -+ * @return {@code true} if this entity can trample, {@code false} otherwise -+ */ -+ public boolean canTrample(World world, Block block, BlockPos pos, float fallDistance) -+ { -+ return world.rand.nextFloat() < fallDistance - 0.5F -+ && this instanceof EntityLivingBase -+ && (this instanceof EntityPlayer || net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(world, this)) -+ && this.width * this.width * this.height > 0.512F; -+ } -+ /* ================================== Forge End =====================================*/ - - public void addTrackingPlayer(EntityPlayerMP player) - { diff --git a/patches/minecraft/net/minecraft/entity/EntityAgeable.java.patch b/patches/minecraft/net/minecraft/entity/EntityAgeable.java.patch deleted file mode 100644 index 9faf1e3d7..000000000 --- a/patches/minecraft/net/minecraft/entity/EntityAgeable.java.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- before/net/minecraft/entity/EntityAgeable.java -+++ after/net/minecraft/entity/EntityAgeable.java -@@ -39,7 +39,7 @@ - { - if (!this.world.isRemote) - { -- Class oclass = EntityList.REGISTRY.getObject(ItemMonsterPlacer.getNamedIdFrom(itemstack)); -+ Class oclass = EntityList.getClass(ItemMonsterPlacer.getNamedIdFrom(itemstack)); - - if (oclass != null && this.getClass() == oclass) - { -@@ -80,7 +80,7 @@ - } - else - { -- Class oclass = EntityList.REGISTRY.getObject(ItemMonsterPlacer.getNamedIdFrom(stack)); -+ Class oclass = EntityList.getClass(ItemMonsterPlacer.getNamedIdFrom(stack)); - return oclass != null && entityClass == oclass; - } - } diff --git a/patches/minecraft/net/minecraft/entity/EntityFlying.java.patch b/patches/minecraft/net/minecraft/entity/EntityFlying.java.patch deleted file mode 100644 index 31872554e..000000000 --- a/patches/minecraft/net/minecraft/entity/EntityFlying.java.patch +++ /dev/null @@ -1,46 +0,0 @@ ---- before/net/minecraft/entity/EntityFlying.java -+++ after/net/minecraft/entity/EntityFlying.java -@@ -47,17 +47,14 @@ - - if (this.onGround) - { -- f = this.world -- .getBlockState( -+ BlockPos underPos = - new BlockPos( - MathHelper.floor(this.posX), - MathHelper.floor(this.getEntityBoundingBox().minY) - 1, - MathHelper.floor(this.posZ) -- ) -- ) -- .getBlock() -- .slipperiness -- * 0.91F; -+ ); -+ IBlockState underState = this.world.getBlockState(underPos); -+ f = underState.getBlock().getSlipperiness(underState, this.world, underPos, this) * 0.91F; - } - - float f1 = 0.16277136F / (f * f * f); -@@ -66,17 +63,14 @@ - - if (this.onGround) - { -- f = this.world -- .getBlockState( -+ BlockPos underPos = - new BlockPos( - MathHelper.floor(this.posX), - MathHelper.floor(this.getEntityBoundingBox().minY) - 1, - MathHelper.floor(this.posZ) -- ) -- ) -- .getBlock() -- .slipperiness -- * 0.91F; -+ ); -+ IBlockState underState = this.world.getBlockState(underPos); -+ f = underState.getBlock().getSlipperiness(underState, this.world, underPos, this) * 0.91F; - } - - this.move(MoverType.SELF, this.motionX, this.motionY, this.motionZ); diff --git a/patches/minecraft/net/minecraft/entity/EntityHanging.java.patch b/patches/minecraft/net/minecraft/entity/EntityHanging.java.patch deleted file mode 100644 index 486e78ba6..000000000 --- a/patches/minecraft/net/minecraft/entity/EntityHanging.java.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- before/net/minecraft/entity/EntityHanging.java -+++ after/net/minecraft/entity/EntityHanging.java -@@ -146,6 +146,9 @@ - blockpos$mutableblockpos.setPos(blockpos).move(enumfacing, k + i1).move(EnumFacing.UP, l + j1); - IBlockState iblockstate = this.world.getBlockState(blockpos$mutableblockpos); - -+ if (iblockstate.isSideSolid(this.world, blockpos$mutableblockpos, this.facingDirection)) -+ continue; -+ - if (!iblockstate.getMaterial().isSolid() && !BlockRedstoneDiode.isDiode(iblockstate)) - { - return false; diff --git a/patches/minecraft/net/minecraft/entity/EntityLeashKnot.java.patch b/patches/minecraft/net/minecraft/entity/EntityLeashKnot.java.patch deleted file mode 100644 index d6d4954b5..000000000 --- a/patches/minecraft/net/minecraft/entity/EntityLeashKnot.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- before/net/minecraft/entity/EntityLeashKnot.java -+++ after/net/minecraft/entity/EntityLeashKnot.java -@@ -54,6 +54,7 @@ - this.posX = this.hangingPosition.getX() + 0.5; - this.posY = this.hangingPosition.getY() + 0.5; - this.posZ = this.hangingPosition.getZ() + 0.5; -+ if (this.isAddedToWorld() && !this.world.isRemote) this.world.updateEntityWithOptionalForce(this, false); // Forge - Process chunk registration after moving. - } - - @Override diff --git a/patches/minecraft/net/minecraft/entity/EntityList.java.patch b/patches/minecraft/net/minecraft/entity/EntityList.java.patch deleted file mode 100644 index b40b31901..000000000 --- a/patches/minecraft/net/minecraft/entity/EntityList.java.patch +++ /dev/null @@ -1,180 +0,0 @@ ---- before/net/minecraft/entity/EntityList.java -+++ after/net/minecraft/entity/EntityList.java -@@ -107,10 +107,8 @@ - public static final ResourceLocation LIGHTNING_BOLT = new ResourceLocation("lightning_bolt"); - private static final ResourceLocation PLAYER = new ResourceLocation("player"); - private static final Logger LOGGER = LogManager.getLogger(); -- public static final RegistryNamespaced < ResourceLocation, Class > REGISTRY = new RegistryNamespaced<>(); - public static final Map ENTITY_EGGS = Maps.newLinkedHashMap(); -- public static final Set KNOWN_TYPES = Sets.newHashSet(); -- private static final List OLD_NAMES = Lists.newArrayList(); -+ private static final Set EXTRA_NAMES = Sets.newHashSet(); - - @Nullable - public static ResourceLocation getKey(Entity entityIn) -@@ -121,35 +119,51 @@ - @Nullable - public static ResourceLocation getKey(Class entityIn) - { -- return REGISTRY.getNameForObject(entityIn); -+ net.minecraftforge.fml.common.registry.EntityEntry entry = net.minecraftforge.fml.common.registry.EntityRegistry.getEntry(entityIn); -+ return entry == null ? null : entry.getRegistryName(); - } - - @Nullable - public static String getEntityString(Entity entityIn) - { -- int i = REGISTRY.getIDForObject((Class )entityIn.getClass()); -- return i == -1 ? null : OLD_NAMES.get(i); -+ net.minecraftforge.fml.common.registry.EntityEntry entry = net.minecraftforge.fml.common.registry.EntityRegistry.getEntry(entityIn.getClass()); -+ return entry == null ? null : entry.getName(); - } - - @Nullable - public static String getTranslationName(@Nullable ResourceLocation entityType) - { -- int i = REGISTRY.getIDForObject(REGISTRY.getObject(entityType)); -- return i == -1 ? null : OLD_NAMES.get(i); -+ net.minecraftforge.fml.common.registry.EntityEntry entry = net.minecraftforge.fml.common.registry.ForgeRegistries.ENTITIES.getValue(entityType); -+ return entry == null ? null : entry.getName(); - } - - @Nullable - @SideOnly(Side.CLIENT) - public static Class getClassFromID(int entityID) - { -- return REGISTRY.getObjectById(entityID); -+ net.minecraftforge.fml.common.registry.EntityEntry entry = net.minecraftforge.registries.GameData.getEntityRegistry().getValue(entityID); -+ return entry == null ? null : entry.getEntityClass(); - } - - @Nullable - @SideOnly(Side.CLIENT) - public static Class getClassFromName(String p_192839_0_) - { -- return REGISTRY.getObject(new ResourceLocation(p_192839_0_)); -+ net.minecraftforge.fml.common.registry.EntityEntry entry = net.minecraftforge.fml.common.registry.ForgeRegistries.ENTITIES.getValue(new ResourceLocation(p_192839_0_)); -+ return entry == null ? null : entry.getEntityClass(); -+ } -+ -+ public static int getID(Class cls) -+ { -+ net.minecraftforge.fml.common.registry.EntityEntry entry = net.minecraftforge.fml.common.registry.EntityRegistry.getEntry(cls); -+ return entry == null ? -1 : net.minecraftforge.registries.GameData.getEntityRegistry().getID(entry); -+ } -+ -+ @Nullable -+ public static Class getClass(ResourceLocation key) -+ { -+ net.minecraftforge.fml.common.registry.EntityEntry entry = net.minecraftforge.fml.common.registry.ForgeRegistries.ENTITIES.getValue(key); -+ return entry == null ? null : entry.getEntityClass(); - } - - @Nullable -@@ -163,6 +177,8 @@ - { - try - { -+ net.minecraftforge.fml.common.registry.EntityEntry entry = net.minecraftforge.fml.common.registry.EntityRegistry.getEntry(clazz); -+ if (entry != null) return entry.newInstance(worldIn); - return clazz.getConstructor(World.class).newInstance(worldIn); - } - catch (Exception exception) -@@ -177,13 +193,15 @@ - @SideOnly(Side.CLIENT) - public static Entity createEntityByID(int entityID, World worldIn) - { -- return newEntity(getClassFromID(entityID), worldIn); -+ net.minecraftforge.fml.common.registry.EntityEntry entry = net.minecraftforge.registries.GameData.getEntityRegistry().getValue(entityID); -+ return entry == null ? null : entry.newInstance(worldIn); - } - - @Nullable - public static Entity createEntityByIDFromName(ResourceLocation name, World worldIn) - { -- return newEntity(REGISTRY.getObject(name), worldIn); -+ net.minecraftforge.fml.common.registry.EntityEntry entry = net.minecraftforge.fml.common.registry.ForgeRegistries.ENTITIES.getValue(name); -+ return entry == null ? null : entry.newInstance(worldIn); - } - - @Nullable -@@ -198,7 +216,16 @@ - } - else - { -+ try -+ { - entity.readFromNBT(nbt); -+ } -+ catch (Exception e) -+ { -+ net.minecraftforge.fml.common.FMLLog.log.error("An Entity {}({}) has thrown an exception during loading, its state cannot be restored. Report this to the mod author", -+ nbt.getString("id"), entity.getName(), e); -+ entity = null; -+ } - } - - return entity; -@@ -206,7 +233,7 @@ - - public static Set getEntityNameList() - { -- return KNOWN_TYPES; -+ return Sets.union(net.minecraftforge.fml.common.registry.ForgeRegistries.ENTITIES.getKeys(), EXTRA_NAMES); - } - - public static boolean isMatchingName(Entity entityIn, ResourceLocation entityName) -@@ -373,7 +400,7 @@ - addSpawnInfo("zombie_horse", 3232308, 9945732); - addSpawnInfo("zombie_pigman", 15373203, 5009705); - addSpawnInfo("zombie_villager", 5651507, 7969893); -- KNOWN_TYPES.add(LIGHTNING_BOLT); -+ EXTRA_NAMES.add(LIGHTNING_BOLT); - } - - private static void register(int id, String name, Class clazz, String oldName) -@@ -394,22 +421,17 @@ - else - { - ResourceLocation resourcelocation = new ResourceLocation(name); -- REGISTRY.register(id, resourcelocation, clazz); -- KNOWN_TYPES.add(resourcelocation); -- -- while (OLD_NAMES.size() <= id) -- { -- OLD_NAMES.add(null); -- } -- -- OLD_NAMES.set(id, oldName); -+ net.minecraftforge.registries.GameData.registerEntity(id, resourcelocation, clazz, oldName); - } - } - - protected static EntityList.EntityEggInfo addSpawnInfo(String id, int primaryColor, int secondaryColor) - { - ResourceLocation resourcelocation = new ResourceLocation(id); -- return ENTITY_EGGS.put(resourcelocation, new EntityList.EntityEggInfo(resourcelocation, primaryColor, secondaryColor)); -+ EntityList.EntityEggInfo egg = new EntityList.EntityEggInfo(resourcelocation, primaryColor, secondaryColor); -+ net.minecraftforge.fml.common.registry.EntityEntry entry = net.minecraftforge.fml.common.registry.ForgeRegistries.ENTITIES.getValue(resourcelocation); -+ if (entry != null) entry.setEgg(egg); -+ return (EntityList.EntityEggInfo)ENTITY_EGGS.put(resourcelocation, egg); - } - - public static class EntityEggInfo -@@ -428,5 +450,16 @@ - this.killEntityStat = StatList.getStatKillEntity(this); - this.entityKilledByStat = StatList.getStatEntityKilledBy(this); - } -+ -+ // Forge start -+ public EntityEggInfo(ResourceLocation id, int primaryColor, int secondaryColor, StatBase killEntityStatistic, StatBase entityKilledByStatistic) -+ { -+ this.spawnedID = id; -+ this.primaryColor = primaryColor; -+ this.secondaryColor = secondaryColor; -+ this.killEntityStat = killEntityStatistic; -+ this.entityKilledByStat = entityKilledByStatistic; -+ } -+ // Forge end - } - } diff --git a/patches/minecraft/net/minecraft/entity/EntityLiving.java.patch b/patches/minecraft/net/minecraft/entity/EntityLiving.java.patch deleted file mode 100644 index 465cdb532..000000000 --- a/patches/minecraft/net/minecraft/entity/EntityLiving.java.patch +++ /dev/null @@ -1,88 +0,0 @@ ---- before/net/minecraft/entity/EntityLiving.java -+++ after/net/minecraft/entity/EntityLiving.java -@@ -171,6 +171,7 @@ - public void setAttackTarget(@Nullable EntityLivingBase entitylivingbaseIn) - { - this.attackTarget = entitylivingbaseIn; -+ this.attackTarget = net.minecraftforge.common.ForgeHooks.onLivingSetAttackTarget(this, entitylivingbaseIn); - } - - public boolean canAttackClass(Class cls) -@@ -601,7 +602,7 @@ - super.onLivingUpdate(); - this.world.profiler.startSection("looting"); - -- if (!this.world.isRemote && this.canPickUpLoot() && !this.dead && this.world.getGameRules().getBoolean("mobGriefing")) -+ if (!this.world.isRemote && this.canPickUpLoot() && !this.dead && net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.world, this)) - { - for (EntityItem entityitem : this.world.getEntitiesWithinAABB(EntityItem.class, this.getEntityBoundingBox().grow(1.0, 0.0, 1.0))) - { -@@ -729,10 +730,22 @@ - - protected void despawnEntity() - { -+ net.minecraftforge.fml.common.eventhandler.Event.Result result = null; - if (this.persistenceRequired) - { - this.idleTime = 0; - } -+ else if ((this.idleTime & 0x1F) == 0x1F && (result = net.minecraftforge.event.ForgeEventFactory.canEntityDespawn(this)) != net.minecraftforge.fml.common.eventhandler.Event.Result.DEFAULT) -+ { -+ if (result == net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) -+ { -+ this.idleTime = 0; -+ } -+ else -+ { -+ this.setDead(); -+ } -+ } - else - { - Entity entity = this.world.getClosestPlayerToEntity(this, -1.0); -@@ -869,7 +882,6 @@ - && this.world.checkNoEntityCollision(this.getEntityBoundingBox(), this); - } - -- @SideOnly(Side.CLIENT) - public float getRenderSizeModifier() - { - return 1.0F; -@@ -1032,6 +1044,8 @@ - - public static EntityEquipmentSlot getSlotForItemStack(ItemStack stack) - { -+ final EntityEquipmentSlot slot = stack.getItem().getEquipmentSlot(stack); -+ if (slot != null) return slot; // FORGE: Allow modders to set a non-default equipment slot for a stack; e.g. a non-armor chestplate-slot item - if (stack.getItem() == Item.getItemFromBlock(Blocks.PUMPKIN) || stack.getItem() == Items.SKULL) - { - return EntityEquipmentSlot.HEAD; -@@ -1046,7 +1060,7 @@ - } - else - { -- return stack.getItem() == Items.SHIELD ? EntityEquipmentSlot.OFFHAND : EntityEquipmentSlot.MAINHAND; -+ return stack.getItem().isShield(stack, null) ? EntityEquipmentSlot.OFFHAND : EntityEquipmentSlot.MAINHAND; - } - } - -@@ -1488,5 +1502,19 @@ - ON_GROUND, - IN_AIR, - IN_WATER; -+ -+ private final java.util.function.BiPredicate spawnPredicate; -+ -+ SpawnPlacementType() { this.spawnPredicate = null; } -+ -+ SpawnPlacementType(java.util.function.BiPredicate spawnPredicate) -+ { -+ this.spawnPredicate = spawnPredicate; -+ } -+ -+ public boolean canSpawnAt(World world, BlockPos pos) -+ { -+ return this.spawnPredicate != null ? this.spawnPredicate.test(world, pos) : net.minecraft.world.WorldEntitySpawner.canCreatureTypeSpawnBody(this, world, pos); -+ } - } - } diff --git a/patches/minecraft/net/minecraft/entity/EntityLivingBase.java.patch b/patches/minecraft/net/minecraft/entity/EntityLivingBase.java.patch deleted file mode 100644 index 765a98fc5..000000000 --- a/patches/minecraft/net/minecraft/entity/EntityLivingBase.java.patch +++ /dev/null @@ -1,541 +0,0 @@ ---- before/net/minecraft/entity/EntityLivingBase.java -+++ after/net/minecraft/entity/EntityLivingBase.java -@@ -82,6 +82,7 @@ - private static final Logger LOGGER = LogManager.getLogger(); - private static final UUID SPRINTING_SPEED_BOOST_ID = UUID.fromString("662A6B8D-DA3E-4C1C-8813-96EA6097278D"); - private static final AttributeModifier SPRINTING_SPEED_BOOST = new AttributeModifier(SPRINTING_SPEED_BOOST_ID, "Sprinting speed boost", 0.3F, 2).setSaved(false); -+ public static final net.minecraft.entity.ai.attributes.IAttribute SWIM_SPEED = new net.minecraft.entity.ai.attributes.RangedAttribute(null, "forge.swimSpeed", 1.0, 0.0, 1024.0).setShouldWatch(true); - protected static final DataParameter HAND_STATES = EntityDataManager.createKey(EntityLivingBase.class, DataSerializers.BYTE); - private static final DataParameter HEALTH = EntityDataManager.createKey(EntityLivingBase.class, DataSerializers.FLOAT); - private static final DataParameter POTION_EFFECTS = EntityDataManager.createKey(EntityLivingBase.class, DataSerializers.VARINT); -@@ -190,6 +191,7 @@ - this.getAttributeMap().registerAttribute(SharedMonsterAttributes.MOVEMENT_SPEED); - this.getAttributeMap().registerAttribute(SharedMonsterAttributes.ARMOR); - this.getAttributeMap().registerAttribute(SharedMonsterAttributes.ARMOR_TOUGHNESS); -+ this.getAttributeMap().registerAttribute(SWIM_SPEED); - } - - @Override -@@ -204,10 +206,11 @@ - { - float f = MathHelper.ceil(this.fallDistance - 3.0F); - -- if (state.getMaterial() != Material.AIR) -+ if (!state.getBlock().isAir(state, world, pos)) - { - double d0 = Math.min((double)(0.2F + f / 15.0F), 2.5); - int i = (int)(150.0 * d0); -+ if (!state.getBlock().addLandingEffects(state, (WorldServer)this.world, pos, state, this, i)) - ((WorldServer)this.world) - .spawnParticle( - EnumParticleTypes.BLOCK_DUST, -@@ -306,7 +309,7 @@ - } - } - -- if (!this.world.isRemote && this.isRiding() && this.getRidingEntity() instanceof EntityLivingBase) -+ if (!this.world.isRemote && this.isRiding() && this.getRidingEntity() != null && this.getRidingEntity().shouldDismountInWater(this)) - { - this.dismountRidingEntity(); - } -@@ -407,6 +410,7 @@ - { - int i = this.getExperiencePoints(this.attackingPlayer); - -+ i = net.minecraftforge.event.ForgeEventFactory.getExperienceDrop(this, this.attackingPlayer, i); - while (i > 0) - { - int j = EntityXPOrb.getXPSplit(i); -@@ -639,7 +643,7 @@ - - if (!potioneffect.onUpdate(this)) - { -- if (!this.world.isRemote) -+ if (!this.world.isRemote && !net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.living.PotionEvent.PotionExpiryEvent(this, potioneffect))) - { - iterator.remove(); - this.onFinishedPotionEffect(potioneffect); -@@ -715,8 +719,10 @@ - else - { - Collection collection = this.activePotionsMap.values(); -- this.dataManager.set(HIDE_PARTICLES, areAllPotionsAmbient(collection)); -- this.dataManager.set(POTION_EFFECTS, PotionUtils.getPotionColorFromEffectList(collection)); -+ net.minecraftforge.event.entity.living.PotionColorCalculationEvent event = new net.minecraftforge.event.entity.living.PotionColorCalculationEvent(this, PotionUtils.getPotionColorFromEffectList(collection), areAllPotionsAmbient(collection), collection); -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event); -+ this.dataManager.set(HIDE_PARTICLES, event.areParticlesHidden()); -+ this.dataManager.set(POTION_EFFECTS, event.getColor()); - this.setInvisible(this.isPotionActive(MobEffects.INVISIBILITY)); - } - } -@@ -748,7 +754,10 @@ - - while (iterator.hasNext()) - { -- this.onFinishedPotionEffect(iterator.next()); -+ PotionEffect effect = iterator.next(); -+ if(net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.living.PotionEvent.PotionRemoveEvent(this, effect))) continue; -+ -+ this.onFinishedPotionEffect(effect); - iterator.remove(); - } - } -@@ -781,6 +790,7 @@ - { - PotionEffect potioneffect = this.activePotionsMap.get(potioneffectIn.getPotion()); - -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.living.PotionEvent.PotionAddedEvent(this, potioneffect, potioneffectIn)); - if (potioneffect == null) - { - this.activePotionsMap.put(potioneffectIn.getPotion(), potioneffectIn); -@@ -796,6 +806,9 @@ - - public boolean isPotionApplicable(PotionEffect potioneffectIn) - { -+ net.minecraftforge.event.entity.living.PotionEvent.PotionApplicableEvent event = new net.minecraftforge.event.entity.living.PotionEvent.PotionApplicableEvent(this, potioneffectIn); -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event); -+ if (event.getResult() != net.minecraftforge.fml.common.eventhandler.Event.Result.DEFAULT) return event.getResult() == net.minecraftforge.fml.common.eventhandler.Event.Result.ALLOW; - if (this.getCreatureAttribute() == EnumCreatureAttribute.UNDEAD) - { - Potion potion = potioneffectIn.getPotion(); -@@ -822,6 +835,7 @@ - - public void removePotionEffect(Potion potionIn) - { -+ if(net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.living.PotionEvent.PotionRemoveEvent(this, potionIn))) return; - PotionEffect potioneffect = this.removeActivePotionEffect(potionIn); - - if (potioneffect != null) -@@ -864,6 +878,8 @@ - - public void heal(float healAmount) - { -+ healAmount = net.minecraftforge.event.ForgeEventFactory.onLivingHeal(this, healAmount); -+ if (healAmount <= 0) return; - float f = this.getHealth(); - - if (f > 0.0F) -@@ -885,6 +901,7 @@ - @Override - public boolean attackEntityFrom(DamageSource source, float amount) - { -+ if (!net.minecraftforge.common.ForgeHooks.onLivingAttack(this, source, amount)) return false; - if (this.isEntityInvulnerable(source)) - { - return false; -@@ -974,9 +991,9 @@ - this.recentlyHit = 100; - this.attackingPlayer = (EntityPlayer)entity1; - } -- else if (entity1 instanceof EntityWolf) -+ else if (entity1 instanceof net.minecraft.entity.passive.EntityTameable) - { -- EntityWolf entitywolf = (EntityWolf)entity1; -+ net.minecraft.entity.passive.EntityTameable entitywolf = (net.minecraft.entity.passive.EntityTameable)entity1; - - if (entitywolf.isTamed()) - { -@@ -1174,7 +1191,7 @@ - - public void renderBrokenItemStack(ItemStack stack) - { -- this.playSound(SoundEvents.ENTITY_ITEM_BREAK, 0.8F, 0.8F + this.world.rand.nextFloat() * 0.4F); -+ this.world.playSound(null, this.posX, this.posY, this.posZ, SoundEvents.ENTITY_ITEM_BREAK, this.getSoundCategory(), 0.8F, 0.8F + this.world.rand.nextFloat() * 0.4F); //Forge: Fix MC-2518 Items are not damaged on the client so client needs packet as well. - - for (int i = 0; i < 5; i++) - { -@@ -1186,7 +1203,10 @@ - vec3d1 = vec3d1.rotatePitch(-this.rotationPitch * (float)(Math.PI / 180.0)); - vec3d1 = vec3d1.rotateYaw(-this.rotationYaw * (float)(Math.PI / 180.0)); - vec3d1 = vec3d1.add(this.posX, this.posY + this.getEyeHeight(), this.posZ); -- this.world -+ if (this.world instanceof WorldServer) //Forge: Fix MC-2518 spawnParticle is nooped on server, need to use server specific variant -+ ((WorldServer)this.world).spawnParticle(EnumParticleTypes.ITEM_CRACK, vec3d1.x, vec3d1.y, vec3d1.z, 0, vec3d.x, vec3d.y + 0.05, vec3d.z, 0.0, Item.getIdFromItem(stack.getItem()), stack.getMetadata()); -+ else //Fix the fact that spawning ItemCrack uses TWO arguments. -+ this.world - .spawnParticle( - EnumParticleTypes.ITEM_CRACK, - vec3d1.x, -@@ -1195,13 +1215,16 @@ - vec3d.x, - vec3d.y + 0.05, - vec3d.z, -- Item.getIdFromItem(stack.getItem()) -+ Item.getIdFromItem(stack.getItem()), -+ stack.getMetadata() - ); -+ - } - } - - public void onDeath(DamageSource cause) - { -+ if (net.minecraftforge.common.ForgeHooks.onLivingDeath(this, cause)) return; - if (!this.dead) - { - Entity entity = cause.getTrueSource(); -@@ -1222,18 +1245,26 @@ - - if (!this.world.isRemote) - { -- int i = 0; -+ int i = net.minecraftforge.common.ForgeHooks.getLootingLevel(this, entity, cause); - -- if (entity instanceof EntityPlayer) -- { -- i = EnchantmentHelper.getLootingModifier((EntityLivingBase)entity); -- } -+ captureDrops = true; -+ capturedDrops.clear(); - - if (this.canDropLoot() && this.world.getGameRules().getBoolean("doMobLoot")) - { - boolean flag = this.recentlyHit > 0; - this.dropLoot(flag, i, cause); - } -+ -+ captureDrops = false; -+ -+ if (!net.minecraftforge.common.ForgeHooks.onLivingDrops(this, cause, capturedDrops, i, recentlyHit > 0)) -+ { -+ for (EntityItem item : capturedDrops) -+ { -+ world.spawnEntity(item); -+ } -+ } - } - - this.world.setEntityState(this, (byte)3); -@@ -1252,7 +1283,10 @@ - - public void knockBack(Entity entityIn, float strength, double xRatio, double zRatio) - { -- if (!(this.rand.nextDouble() < this.getEntityAttribute(SharedMonsterAttributes.KNOCKBACK_RESISTANCE).getAttributeValue())) -+ net.minecraftforge.event.entity.living.LivingKnockBackEvent event = net.minecraftforge.common.ForgeHooks.onLivingKnockBack(this, entityIn, strength, xRatio, zRatio); -+ if(event.isCanceled()) return; -+ strength = event.getStrength(); xRatio = event.getRatioX(); zRatio = event.getRatioZ(); -+ if (this.rand.nextDouble() >= this.getEntityAttribute(SharedMonsterAttributes.KNOCKBACK_RESISTANCE).getAttributeValue()) - { - this.isAirBorne = true; - float f = MathHelper.sqrt(xRatio * xRatio + zRatio * zRatio); -@@ -1310,9 +1344,7 @@ - BlockPos blockpos = new BlockPos(i, j, k); - IBlockState iblockstate = this.world.getBlockState(blockpos); - Block block = iblockstate.getBlock(); -- return block != Blocks.LADDER && block != Blocks.VINE -- ? block instanceof BlockTrapDoor && this.canGoThroughtTrapDoorOnLadder(blockpos, iblockstate) -- : true; -+ return net.minecraftforge.common.ForgeHooks.isLivingOnLadder(iblockstate, world, new BlockPos(i, j, k), this); - } - } - -@@ -1341,6 +1373,9 @@ - @Override - public void fall(float distance, float damageMultiplier) - { -+ float[] ret = net.minecraftforge.common.ForgeHooks.onLivingFall(this, distance, damageMultiplier); -+ if (ret == null) return; -+ distance = ret[0]; damageMultiplier = ret[1]; - super.fall(distance, damageMultiplier); - PotionEffect potioneffect = this.getActivePotionEffect(MobEffects.JUMP_BOOST); - float f = potioneffect == null ? 0.0F : potioneffect.getAmplifier() + 1; -@@ -1357,7 +1392,7 @@ - - if (iblockstate.getMaterial() != Material.AIR) - { -- SoundType soundtype = iblockstate.getBlock().getSoundType(); -+ SoundType soundtype = iblockstate.getBlock().getSoundType(iblockstate, world, new BlockPos(j, k, l), this); - this.playSound(soundtype.getFallSound(), soundtype.getVolume() * 0.5F, soundtype.getPitch() * 0.75F); - } - } -@@ -1437,16 +1472,19 @@ - { - if (!this.isEntityInvulnerable(damageSrc)) - { -+ damageAmount = net.minecraftforge.common.ForgeHooks.onLivingHurt(this, damageSrc, damageAmount); -+ if (damageAmount <= 0) return; - damageAmount = this.applyArmorCalculations(damageSrc, damageAmount); - damageAmount = this.applyPotionDamageCalculations(damageSrc, damageAmount); - float f1 = Math.max(damageAmount - this.getAbsorptionAmount(), 0.0F); - this.setAbsorptionAmount(this.getAbsorptionAmount() - (damageAmount - f1)); -+ f1 = net.minecraftforge.common.ForgeHooks.onLivingDamage(this, damageSrc, f1); - - if (f1 != 0.0F) - { - float f = this.getHealth(); -- this.setHealth(f - f1); - this.getCombatTracker().trackDamage(damageSrc, f, f1); -+ this.setHealth(f - f1); // Forge: moved to fix MC-121048 - this.setAbsorptionAmount(this.getAbsorptionAmount() - f1); - } - } -@@ -1503,6 +1541,11 @@ - - public void swingArm(EnumHand hand) - { -+ ItemStack stack = this.getHeldItem(hand); -+ if (!stack.isEmpty()) -+ { -+ if (stack.getItem().onEntitySwing(this, stack)) return; -+ } - if (!this.isSwingInProgress || this.swingProgressInt >= this.getArmSwingAnimationEnd() / 2 || this.swingProgressInt < 0) - { - this.swingProgressInt = -1; -@@ -1763,7 +1806,7 @@ - - if (!this.world.collidesWithAnyBlock(axisalignedbb1)) - { -- if (this.world.getBlockState(new BlockPos(d11, this.posY, d12)).isTopSolid()) -+ if (this.world.getBlockState(new BlockPos(d11, this.posY, d12)).isSideSolid(world, new BlockPos(d11, this.posY, d12), EnumFacing.UP)) - { - this.setPositionAndUpdate(d11, this.posY + 1.0, d12); - return; -@@ -1771,7 +1814,7 @@ - - BlockPos blockpos = new BlockPos(d11, this.posY - 1.0, d12); - -- if (this.world.getBlockState(blockpos).isTopSolid() -+ if (this.world.getBlockState(blockpos).isSideSolid(world, blockpos, EnumFacing.UP) - || this.world.getBlockState(blockpos).getMaterial() == Material.WATER) - { - d1 = d11; -@@ -1780,7 +1823,7 @@ - } - } - else if (!this.world.collidesWithAnyBlock(axisalignedbb1.offset(0.0, 1.0, 0.0)) -- && this.world.getBlockState(new BlockPos(d11, this.posY + 1.0, d12)).isTopSolid()) -+ && this.world.getBlockState(new BlockPos(d11, this.posY + 1.0, d12)).isSideSolid(world, new BlockPos(d11, this.posY + 1.0, d12), EnumFacing.UP)) - { - d1 = d11; - d13 = this.posY + 2.0; -@@ -1853,16 +1896,17 @@ - } - - this.isAirBorne = true; -+ net.minecraftforge.common.ForgeHooks.onLivingJump(this); - } - - protected void handleJumpWater() - { -- this.motionY += 0.04F; -+ this.motionY += 0.04F * this.getEntityAttribute(SWIM_SPEED).getAttributeValue(); - } - - protected void handleJumpLava() - { -- this.motionY += 0.04F; -+ this.motionY += 0.04F * this.getEntityAttribute(SWIM_SPEED).getAttributeValue(); - } - - protected float getWaterSlowDown() -@@ -1948,7 +1992,8 @@ - - if (this.onGround) - { -- f6 = this.world.getBlockState(blockpos$pooledmutableblockpos).getBlock().slipperiness * 0.91F; -+ IBlockState underState = this.world.getBlockState(blockpos$pooledmutableblockpos); -+ f6 = underState.getBlock().getSlipperiness(underState, this.world, blockpos$pooledmutableblockpos, this) * 0.91F; - } - - float f7 = 0.16277136F / (f6 * f6 * f6); -@@ -1968,12 +2013,13 @@ - - if (this.onGround) - { -- f6 = this.world -+ IBlockState underState = this.world - .getBlockState( - blockpos$pooledmutableblockpos.setPos(this.posX, this.getEntityBoundingBox().minY - 1.0, this.posZ) -- ) -+ ); -+ f6 = underState - .getBlock() -- .slipperiness -+ .getSlipperiness(underState, this.world, blockpos$pooledmutableblockpos, this) - * 0.91F; - } - -@@ -2138,6 +2184,7 @@ - @Override - public void onUpdate() - { -+ if (net.minecraftforge.common.ForgeHooks.onLivingUpdate(this)) return; - super.onUpdate(); - this.updateActiveHand(); - -@@ -2180,9 +2227,11 @@ - - if (!ItemStack.areItemStacksEqual(itemstack1, itemstack)) - { -+ if (!ItemStack.areItemStacksEqualUsingNBTShareTag(itemstack1, itemstack)) - ((WorldServer)this.world) - .getEntityTracker() - .sendToTracking(this, new SPacketEntityEquipment(this.getEntityId(), entityequipmentslot, itemstack1)); -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.living.LivingEquipmentChangeEvent(this, entityequipmentslot, itemstack, itemstack1)); - - if (!itemstack.isEmpty()) - { -@@ -2683,6 +2732,40 @@ - this.potionsNeedUpdate = true; - } - -+ /*** -+ * Removes all potion effects that have curativeItem as a curative item for its effect -+ * @param curativeItem The itemstack we are using to cure potion effects -+ */ -+ public void curePotionEffects(ItemStack curativeItem) -+ { -+ if (world.isRemote) return; -+ Iterator iterator = this.activePotionsMap.values().iterator(); -+ -+ while (iterator.hasNext()) -+ { -+ PotionEffect effect = iterator.next(); -+ -+ if (effect.isCurativeItem(curativeItem) && !net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.living.PotionEvent.PotionRemoveEvent(this, effect))) -+ { -+ onFinishedPotionEffect(effect); -+ iterator.remove(); -+ this.potionsNeedUpdate = true; -+ } -+ } -+ } -+ -+ /** -+ * Returns true if the entity's rider (EntityPlayer) should face forward when mounted. -+ * currently only used in vanilla code by pigs. -+ * -+ * @param player The player who is riding the entity. -+ * @return If the player should orient the same direction as this entity. -+ */ -+ public boolean shouldRiderFaceForward(EntityPlayer player) -+ { -+ return this instanceof net.minecraft.entity.passive.EntityPig; -+ } -+ - public abstract EnumHandSide getPrimaryHand(); - - public boolean isHandActive() -@@ -2700,15 +2783,23 @@ - if (this.isHandActive()) - { - ItemStack itemstack = this.getHeldItem(this.getActiveHand()); -+ if (net.minecraftforge.common.ForgeHooks.canContinueUsing(this.activeItemStack, itemstack)) this.activeItemStack = itemstack; - - if (itemstack == this.activeItemStack) - { -+ if (!this.activeItemStack.isEmpty()) -+ { -+ activeItemStackUseCount = net.minecraftforge.event.ForgeEventFactory.onItemUseTick(this, activeItemStack, activeItemStackUseCount); -+ if (activeItemStackUseCount > 0) -+ activeItemStack.getItem().onUsingTick(activeItemStack, this, activeItemStackUseCount); -+ } -+ - if (this.getItemInUseCount() <= 25 && this.getItemInUseCount() % 4 == 0) - { - this.updateItemUse(this.activeItemStack, 5); - } - -- if (--this.activeItemStackUseCount == 0 && !this.world.isRemote) -+ if (--this.activeItemStackUseCount <= 0 && !this.world.isRemote) - { - this.onItemUseFinish(); - } -@@ -2726,8 +2817,10 @@ - - if (!itemstack.isEmpty() && !this.isHandActive()) - { -+ int duration = net.minecraftforge.event.ForgeEventFactory.onItemUseStart(this, itemstack, itemstack.getMaxItemUseDuration()); -+ if (duration <= 0) return; - this.activeItemStack = itemstack; -- this.activeItemStackUseCount = itemstack.getMaxItemUseDuration(); -+ this.activeItemStackUseCount = duration; - - if (!this.world.isRemote) - { -@@ -2834,7 +2927,10 @@ - if (!this.activeItemStack.isEmpty() && this.isHandActive()) - { - this.updateItemUse(this.activeItemStack, 16); -- this.setHeldItem(this.getActiveHand(), this.activeItemStack.onItemUseFinish(this.world, this)); -+ ItemStack activeItemStackCopy = this.activeItemStack.copy(); -+ ItemStack itemstack = this.activeItemStack.onItemUseFinish(this.world, this); -+ itemstack = net.minecraftforge.event.ForgeEventFactory.onItemUseFinish(this, activeItemStackCopy, getItemInUseCount(), itemstack); -+ this.setHeldItem(this.getActiveHand(), itemstack); - this.resetActiveHand(); - } - } -@@ -2858,7 +2954,8 @@ - { - if (!this.activeItemStack.isEmpty()) - { -- this.activeItemStack.onPlayerStoppedUsing(this.world, this, this.getItemInUseCount()); -+ if (!net.minecraftforge.event.ForgeEventFactory.onUseItemStop(this, activeItemStack, this.getItemInUseCount())) -+ this.activeItemStack.onPlayerStoppedUsing(this.world, this, this.getItemInUseCount()); - } - - this.resetActiveHand(); -@@ -2978,6 +3075,31 @@ - return true; - } - -+ // FORGE -+ private final net.minecraftforge.items.IItemHandlerModifiable handHandler = new net.minecraftforge.items.wrapper.EntityHandsInvWrapper(this); -+ private final net.minecraftforge.items.IItemHandlerModifiable armorHandler = new net.minecraftforge.items.wrapper.EntityArmorInvWrapper(this); -+ private final net.minecraftforge.items.IItemHandler joinedHandler = new net.minecraftforge.items.wrapper.CombinedInvWrapper(armorHandler, handHandler); -+ -+ @SuppressWarnings("unchecked") -+ @Override -+ @Nullable -+ public T getCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable net.minecraft.util.EnumFacing facing) -+ { -+ if (capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) -+ { -+ if (facing == null) return (T) joinedHandler; -+ else if (facing.getAxis().isVertical()) return (T) handHandler; -+ else if (facing.getAxis().isHorizontal()) return (T) armorHandler; -+ } -+ return super.getCapability(capability, facing); -+ } -+ -+ @Override -+ public boolean hasCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable net.minecraft.util.EnumFacing facing) -+ { -+ return capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY || super.hasCapability(capability, facing); -+ } -+ - public boolean attackable() - { - return true; -@@ -2986,5 +3108,31 @@ - @SideOnly(Side.CLIENT) - public void setPartying(BlockPos pos, boolean isPartying) - { -+ } -+ -+ @Override -+ public void moveRelative(float strafe, float up, float forward, float friction) -+ { -+ float f = strafe * strafe + up * up + forward * forward; -+ if (f >= 1.0E-4F) -+ { -+ f = MathHelper.sqrt(f); -+ if (f < 1.0F) f = 1.0F; -+ f = friction / f; -+ strafe = strafe * f; -+ up = up * f; -+ forward = forward * f; -+ if(this.isInWater() || this.isInLava()) -+ { -+ strafe = strafe * (float)this.getEntityAttribute(SWIM_SPEED).getAttributeValue(); -+ up = up * (float)this.getEntityAttribute(SWIM_SPEED).getAttributeValue(); -+ forward = forward * (float)this.getEntityAttribute(SWIM_SPEED).getAttributeValue(); -+ } -+ float f1 = MathHelper.sin(this.rotationYaw * (float)(Math.PI / 180.0)); -+ float f2 = MathHelper.cos(this.rotationYaw * (float)(Math.PI / 180.0)); -+ this.motionX += (double)(strafe * f2 - forward * f1); -+ this.motionY += (double)up; -+ this.motionZ += (double)(forward * f2 + strafe * f1); -+ } - } - } diff --git a/patches/minecraft/net/minecraft/entity/EntitySpawnPlacementRegistry.java.patch b/patches/minecraft/net/minecraft/entity/EntitySpawnPlacementRegistry.java.patch deleted file mode 100644 index d1b433703..000000000 --- a/patches/minecraft/net/minecraft/entity/EntitySpawnPlacementRegistry.java.patch +++ /dev/null @@ -1,16 +0,0 @@ ---- before/net/minecraft/entity/EntitySpawnPlacementRegistry.java -+++ after/net/minecraft/entity/EntitySpawnPlacementRegistry.java -@@ -50,7 +50,12 @@ - - public static EntityLiving.SpawnPlacementType getPlacementForEntity(Class entityClass) - { -- return ENTITY_PLACEMENTS.get(entityClass); -+ return ENTITY_PLACEMENTS.getOrDefault(entityClass, EntityLiving.SpawnPlacementType.ON_GROUND); -+ } -+ -+ public static void setPlacementType(Class entityClass, EntityLiving.SpawnPlacementType placementType) -+ { -+ ENTITY_PLACEMENTS.putIfAbsent(entityClass, placementType); - } - - static diff --git a/patches/minecraft/net/minecraft/entity/EntityTracker.java.patch b/patches/minecraft/net/minecraft/entity/EntityTracker.java.patch deleted file mode 100644 index 42e00a446..000000000 --- a/patches/minecraft/net/minecraft/entity/EntityTracker.java.patch +++ /dev/null @@ -1,37 +0,0 @@ ---- before/net/minecraft/entity/EntityTracker.java -+++ after/net/minecraft/entity/EntityTracker.java -@@ -77,6 +77,8 @@ - - public void track(Entity entityIn) - { -+ if (net.minecraftforge.fml.common.registry.EntityRegistry.instance().tryTrackingEntity(this, entityIn)) return; -+ - if (entityIn instanceof EntityPlayerMP) - { - this.track(entityIn, 512, 2); -@@ -338,6 +340,25 @@ - entitytrackerentry.sendPacketToTrackedPlayers(packetIn); - } - } -+ -+ /* ======================================== FORGE START =====================================*/ -+ -+ // don't expose the EntityTrackerEntry directly so mods can't mess with the data in there as easily -+ /** -+ * Get all players tracking the given Entity. The Entity must be part of the World that this Tracker belongs to. -+ * @param entity the Entity -+ * @return all players tracking the Entity -+ */ -+ public Set getTrackingPlayers(Entity entity) -+ { -+ EntityTrackerEntry entry = (EntityTrackerEntry) trackedEntityHashTable.lookup(entity.getEntityId()); -+ if (entry == null) -+ return java.util.Collections.emptySet(); -+ else -+ return java.util.Collections.unmodifiableSet(entry.trackingPlayers); -+ } -+ -+ /* ======================================== FORGE END =====================================*/ - - public void sendToTrackingAndSelf(Entity entityIn, Packet packetIn) - { diff --git a/patches/minecraft/net/minecraft/entity/EntityTrackerEntry.java.patch b/patches/minecraft/net/minecraft/entity/EntityTrackerEntry.java.patch deleted file mode 100644 index 8fa843e54..000000000 --- a/patches/minecraft/net/minecraft/entity/EntityTrackerEntry.java.patch +++ /dev/null @@ -1,44 +0,0 @@ ---- before/net/minecraft/entity/EntityTrackerEntry.java -+++ after/net/minecraft/entity/EntityTrackerEntry.java -@@ -155,13 +155,13 @@ - - if (itemstack.getItem() instanceof ItemMap) - { -- MapData mapdata = Items.FILLED_MAP.getMapData(itemstack, this.trackedEntity.world); -+ MapData mapdata = ((ItemMap) itemstack.getItem()).getMapData(itemstack, this.trackedEntity.world); - - for (EntityPlayer entityplayer : players) - { - EntityPlayerMP entityplayermp = (EntityPlayerMP)entityplayer; - mapdata.updateVisiblePlayers(entityplayermp, itemstack); -- Packet packet = Items.FILLED_MAP.createMapDataPacket(itemstack, this.trackedEntity.world, entityplayermp); -+ Packet packet = ((ItemMap) itemstack.getItem()).createMapDataPacket(itemstack, this.trackedEntity.world, entityplayermp); - - if (packet != null) - { -@@ -476,6 +476,7 @@ - - this.trackedEntity.addTrackingPlayer(playerMP); - playerMP.addEntity(this.trackedEntity); -+ net.minecraftforge.event.ForgeEventFactory.onStartEntityTracking(trackedEntity, playerMP); - } - } - else if (this.trackingPlayers.contains(playerMP)) -@@ -483,6 +484,7 @@ - this.trackingPlayers.remove(playerMP); - this.trackedEntity.removeTrackingPlayer(playerMP); - playerMP.removeEntity(this.trackedEntity); -+ net.minecraftforge.event.ForgeEventFactory.onStopEntityTracking(trackedEntity, playerMP); - } - } - } -@@ -514,6 +516,9 @@ - { - LOGGER.warn("Fetching addPacket for removed entity"); - } -+ -+ Packet pkt = net.minecraftforge.fml.common.network.internal.FMLNetworkHandler.getEntitySpawningPacket(this.trackedEntity); -+ if (pkt != null) return pkt; - - if (this.trackedEntity instanceof EntityPlayerMP) - { diff --git a/patches/minecraft/net/minecraft/entity/NpcMerchant.java.patch b/patches/minecraft/net/minecraft/entity/NpcMerchant.java.patch deleted file mode 100644 index 3ccf43e74..000000000 --- a/patches/minecraft/net/minecraft/entity/NpcMerchant.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/entity/NpcMerchant.java -+++ after/net/minecraft/entity/NpcMerchant.java -@@ -44,7 +44,7 @@ - @Override - public MerchantRecipeList getRecipes(EntityPlayer player) - { -- return this.recipeList; -+ return net.minecraftforge.event.ForgeEventFactory.listTradeOffers(this, player, this.recipeList); - } - - @Override diff --git a/patches/minecraft/net/minecraft/entity/SharedMonsterAttributes.java.patch b/patches/minecraft/net/minecraft/entity/SharedMonsterAttributes.java.patch deleted file mode 100644 index 1d166405b..000000000 --- a/patches/minecraft/net/minecraft/entity/SharedMonsterAttributes.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/entity/SharedMonsterAttributes.java -+++ after/net/minecraft/entity/SharedMonsterAttributes.java -@@ -16,7 +16,7 @@ - public class SharedMonsterAttributes - { - private static final Logger LOGGER = LogManager.getLogger(); -- public static final IAttribute MAX_HEALTH = new RangedAttribute(null, "generic.maxHealth", 20.0, 0.0, 1024.0) -+ public static final IAttribute MAX_HEALTH = (new RangedAttribute(null, "generic.maxHealth", 20.0, Float.MIN_VALUE, 1024.0)) // Forge: set smallest max-health value to fix MC-119183. This gets rounded to float so we use the smallest positive float value. - .setDescription("Max Health") - .setShouldWatch(true); - public static final IAttribute FOLLOW_RANGE = new RangedAttribute(null, "generic.followRange", 32.0, 0.0, 2048.0).setDescription("Follow Range"); diff --git a/patches/minecraft/net/minecraft/entity/ai/EntityAIAttackMelee.java.patch b/patches/minecraft/net/minecraft/entity/ai/EntityAIAttackMelee.java.patch deleted file mode 100644 index 63aebc8ff..000000000 --- a/patches/minecraft/net/minecraft/entity/ai/EntityAIAttackMelee.java.patch +++ /dev/null @@ -1,55 +0,0 @@ ---- before/net/minecraft/entity/ai/EntityAIAttackMelee.java -+++ after/net/minecraft/entity/ai/EntityAIAttackMelee.java -@@ -21,6 +21,8 @@ - private double targetY; - private double targetZ; - protected final int attackInterval = 20; -+ private int failedPathFindingPenalty = 0; -+ private boolean canPenalize = false; - - public EntityAIAttackMelee(EntityCreature creature, double speedIn, boolean useLongMemory) - { -@@ -46,6 +48,19 @@ - } - else - { -+ if (canPenalize) -+ { -+ if (--this.delayCounter <= 0) -+ { -+ this.path = this.attacker.getNavigator().getPathToEntityLiving(entitylivingbase); -+ this.delayCounter = 4 + this.attacker.getRNG().nextInt(7); -+ return this.path != null; -+ } -+ else -+ { -+ return true; -+ } -+ } - this.path = this.attacker.getNavigator().getPathToEntityLiving(entitylivingbase); - return this.path != null - ? true -@@ -122,6 +137,23 @@ - this.targetY = entitylivingbase.getEntityBoundingBox().minY; - this.targetZ = entitylivingbase.posZ; - this.delayCounter = 4 + this.attacker.getRNG().nextInt(7); -+ -+ if (this.canPenalize) -+ { -+ this.delayCounter += failedPathFindingPenalty; -+ if (this.attacker.getNavigator().getPath() != null) -+ { -+ net.minecraft.pathfinding.PathPoint finalPathPoint = this.attacker.getNavigator().getPath().getFinalPathPoint(); -+ if (finalPathPoint != null && entitylivingbase.getDistanceSq(finalPathPoint.x, finalPathPoint.y, finalPathPoint.z) < 1) -+ failedPathFindingPenalty = 0; -+ else -+ failedPathFindingPenalty += 10; -+ } -+ else -+ { -+ failedPathFindingPenalty += 10; -+ } -+ } - - if (d0 > 1024.0) - { diff --git a/patches/minecraft/net/minecraft/entity/ai/EntityAIAttackRangedBow.java.patch b/patches/minecraft/net/minecraft/entity/ai/EntityAIAttackRangedBow.java.patch deleted file mode 100644 index 34bdcd484..000000000 --- a/patches/minecraft/net/minecraft/entity/ai/EntityAIAttackRangedBow.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/entity/ai/EntityAIAttackRangedBow.java -+++ after/net/minecraft/entity/ai/EntityAIAttackRangedBow.java -@@ -41,7 +41,7 @@ - - protected boolean isBowInMainhand() - { -- return !this.entity.getHeldItemMainhand().isEmpty() && this.entity.getHeldItemMainhand().getItem() == Items.BOW; -+ return !this.entity.getHeldItemMainhand().isEmpty() && this.entity.getHeldItemMainhand().getItem() instanceof ItemBow; - } - - @Override diff --git a/patches/minecraft/net/minecraft/entity/ai/EntityAIBreakDoor.java.patch b/patches/minecraft/net/minecraft/entity/ai/EntityAIBreakDoor.java.patch deleted file mode 100644 index 1405bccdd..000000000 --- a/patches/minecraft/net/minecraft/entity/ai/EntityAIBreakDoor.java.patch +++ /dev/null @@ -1,25 +0,0 @@ ---- before/net/minecraft/entity/ai/EntityAIBreakDoor.java -+++ after/net/minecraft/entity/ai/EntityAIBreakDoor.java -@@ -24,7 +24,21 @@ - } - else - { -- return !this.entity.world.getGameRules().getBoolean("mobGriefing") -+ return !net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.entity.world, this.entity) -+ || !this.entity.world -+ .getBlockState(this.doorPosition) -+ .getBlock() -+ .canEntityDestroy( -+ this.entity.world.getBlockState(this.doorPosition), -+ this.entity.world, -+ this.doorPosition, -+ this.entity -+ ) -+ || !net.minecraftforge.event.ForgeEventFactory.onEntityDestroyBlock( -+ this.entity, -+ this.doorPosition, -+ this.entity.world.getBlockState(this.doorPosition) -+ ) - ? false - : !BlockDoor.isOpen(this.entity.world, this.doorPosition); - } diff --git a/patches/minecraft/net/minecraft/entity/ai/EntityAIEatGrass.java.patch b/patches/minecraft/net/minecraft/entity/ai/EntityAIEatGrass.java.patch deleted file mode 100644 index 99b8f12d2..000000000 --- a/patches/minecraft/net/minecraft/entity/ai/EntityAIEatGrass.java.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- before/net/minecraft/entity/ai/EntityAIEatGrass.java -+++ after/net/minecraft/entity/ai/EntityAIEatGrass.java -@@ -78,7 +78,7 @@ - - if (IS_TALL_GRASS.apply(this.entityWorld.getBlockState(blockpos))) - { -- if (this.entityWorld.getGameRules().getBoolean("mobGriefing")) -+ if (net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.entityWorld, this.grassEaterEntity)) - { - this.entityWorld.destroyBlock(blockpos, false); - } -@@ -91,7 +91,7 @@ - - if (this.entityWorld.getBlockState(blockpos1).getBlock() == Blocks.GRASS) - { -- if (this.entityWorld.getGameRules().getBoolean("mobGriefing")) -+ if (net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.entityWorld, this.grassEaterEntity)) - { - this.entityWorld.playEvent(2001, blockpos1, Block.getIdFromBlock(Blocks.GRASS)); - this.entityWorld.setBlockState(blockpos1, Blocks.DIRT.getDefaultState(), 2); diff --git a/patches/minecraft/net/minecraft/entity/ai/EntityAIHarvestFarmland.java.patch b/patches/minecraft/net/minecraft/entity/ai/EntityAIHarvestFarmland.java.patch deleted file mode 100644 index 804427f65..000000000 --- a/patches/minecraft/net/minecraft/entity/ai/EntityAIHarvestFarmland.java.patch +++ /dev/null @@ -1,24 +0,0 @@ ---- before/net/minecraft/entity/ai/EntityAIHarvestFarmland.java -+++ after/net/minecraft/entity/ai/EntityAIHarvestFarmland.java -@@ -30,7 +30,7 @@ - { - if (this.runDelay <= 0) - { -- if (!this.villager.world.getGameRules().getBoolean("mobGriefing")) -+ if (!net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.villager.world, this.villager)) - { - return false; - } -@@ -104,6 +104,12 @@ - { - world.setBlockState(blockpos, Blocks.BEETROOTS.getDefaultState(), 3); - flag = true; -+ } -+ else if (itemstack.getItem() instanceof net.minecraftforge.common.IPlantable) { -+ if(((net.minecraftforge.common.IPlantable)itemstack.getItem()).getPlantType(world,blockpos) == net.minecraftforge.common.EnumPlantType.Crop) { -+ world.setBlockState(blockpos, ((net.minecraftforge.common.IPlantable)itemstack.getItem()).getPlant(world,blockpos),3); -+ flag = true; -+ } - } - } - diff --git a/patches/minecraft/net/minecraft/entity/ai/EntityAIMate.java.patch b/patches/minecraft/net/minecraft/entity/ai/EntityAIMate.java.patch deleted file mode 100644 index e8a07b9b7..000000000 --- a/patches/minecraft/net/minecraft/entity/ai/EntityAIMate.java.patch +++ /dev/null @@ -1,21 +0,0 @@ ---- before/net/minecraft/entity/ai/EntityAIMate.java -+++ after/net/minecraft/entity/ai/EntityAIMate.java -@@ -96,6 +96,18 @@ - { - EntityAgeable entityageable = this.animal.createChild(this.targetMate); - -+ final net.minecraftforge.event.entity.living.BabyEntitySpawnEvent event = new net.minecraftforge.event.entity.living.BabyEntitySpawnEvent(animal, targetMate, entityageable); -+ final boolean cancelled = net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event); -+ entityageable = event.getChild(); -+ if (cancelled) { -+ //Reset the "inLove" state for the animals -+ this.animal.setGrowingAge(6000); -+ this.targetMate.setGrowingAge(6000); -+ this.animal.resetInLove(); -+ this.targetMate.resetInLove(); -+ return; -+ } -+ - if (entityageable != null) - { - EntityPlayerMP entityplayermp = this.animal.getLoveCause(); diff --git a/patches/minecraft/net/minecraft/entity/ai/EntityAIRunAroundLikeCrazy.java.patch b/patches/minecraft/net/minecraft/entity/ai/EntityAIRunAroundLikeCrazy.java.patch deleted file mode 100644 index 5ba7bf9f0..000000000 --- a/patches/minecraft/net/minecraft/entity/ai/EntityAIRunAroundLikeCrazy.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/entity/ai/EntityAIRunAroundLikeCrazy.java -+++ after/net/minecraft/entity/ai/EntityAIRunAroundLikeCrazy.java -@@ -74,7 +74,7 @@ - int i = this.horseHost.getTemper(); - int j = this.horseHost.getMaxTemper(); - -- if (j > 0 && this.horseHost.getRNG().nextInt(j) < i) -+ if (j > 0 && this.horseHost.getRNG().nextInt(j) < i && !net.minecraftforge.event.ForgeEventFactory.onAnimalTame(horseHost, (EntityPlayer)entity)) - { - this.horseHost.setTamedBy((EntityPlayer)entity); - return; diff --git a/patches/minecraft/net/minecraft/entity/ai/EntityAIVillagerMate.java.patch b/patches/minecraft/net/minecraft/entity/ai/EntityAIVillagerMate.java.patch deleted file mode 100644 index 8fd8b64c8..000000000 --- a/patches/minecraft/net/minecraft/entity/ai/EntityAIVillagerMate.java.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- before/net/minecraft/entity/ai/EntityAIVillagerMate.java -+++ after/net/minecraft/entity/ai/EntityAIVillagerMate.java -@@ -119,11 +119,15 @@ - - private void giveBirth() - { -- EntityVillager entityvillager = this.villager.createChild(this.mate); -+ net.minecraft.entity.EntityAgeable entityvillager = this.villager.createChild(this.mate); - this.mate.setGrowingAge(6000); - this.villager.setGrowingAge(6000); - this.mate.setIsWillingToMate(false); - this.villager.setIsWillingToMate(false); -+ -+ final net.minecraftforge.event.entity.living.BabyEntitySpawnEvent event = new net.minecraftforge.event.entity.living.BabyEntitySpawnEvent(villager, mate, entityvillager); -+ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event) || event.getChild() == null) { return; } -+ entityvillager = event.getChild(); - entityvillager.setGrowingAge(-24000); - entityvillager.setLocationAndAngles(this.villager.posX, this.villager.posY, this.villager.posZ, 0.0F, 0.0F); - this.world.spawnEntity(entityvillager); diff --git a/patches/minecraft/net/minecraft/entity/boss/EntityDragon.java.patch b/patches/minecraft/net/minecraft/entity/boss/EntityDragon.java.patch deleted file mode 100644 index 68e4a4e69..000000000 --- a/patches/minecraft/net/minecraft/entity/boss/EntityDragon.java.patch +++ /dev/null @@ -1,25 +0,0 @@ ---- before/net/minecraft/entity/boss/EntityDragon.java -+++ after/net/minecraft/entity/boss/EntityDragon.java -@@ -565,18 +565,14 @@ - IBlockState iblockstate = this.world.getBlockState(blockpos); - Block block = iblockstate.getBlock(); - -- if (iblockstate.getMaterial() != Material.AIR && iblockstate.getMaterial() != Material.FIRE) -+ if (!block.isAir(iblockstate, this.world, blockpos) && iblockstate.getMaterial() != Material.FIRE) - { -- if (!this.world.getGameRules().getBoolean("mobGriefing")) -+ if (!net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.world, this)) - { - flag = true; - } -- else if (block == Blocks.BARRIER -- || block == Blocks.OBSIDIAN -- || block == Blocks.END_STONE -- || block == Blocks.BEDROCK -- || block == Blocks.END_PORTAL -- || block == Blocks.END_PORTAL_FRAME) -+ else if (!block.canEntityDestroy(iblockstate, this.world, blockpos, this) -+ || !net.minecraftforge.event.ForgeEventFactory.onEntityDestroyBlock(this, blockpos, iblockstate)) - { - flag = true; - } diff --git a/patches/minecraft/net/minecraft/entity/boss/EntityWither.java.patch b/patches/minecraft/net/minecraft/entity/boss/EntityWither.java.patch deleted file mode 100644 index 071e09c2a..000000000 --- a/patches/minecraft/net/minecraft/entity/boss/EntityWither.java.patch +++ /dev/null @@ -1,31 +0,0 @@ ---- before/net/minecraft/entity/boss/EntityWither.java -+++ after/net/minecraft/entity/boss/EntityWither.java -@@ -303,7 +303,7 @@ - this.posZ, - 7.0F, - false, -- this.world.getGameRules().getBoolean("mobGriefing") -+ net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.world, this) - ); - this.world.playBroadcastSound(1023, new BlockPos(this), 0); - } -@@ -407,7 +407,7 @@ - { - this.blockBreakCounter--; - -- if (this.blockBreakCounter == 0 && this.world.getGameRules().getBoolean("mobGriefing")) -+ if (this.blockBreakCounter == 0 && net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.world, this)) - { - int i1 = MathHelper.floor(this.posY); - int l1 = MathHelper.floor(this.posX); -@@ -427,7 +427,9 @@ - IBlockState iblockstate = this.world.getBlockState(blockpos); - Block block = iblockstate.getBlock(); - -- if (iblockstate.getMaterial() != Material.AIR && canDestroyBlock(block)) -+ if (!block.isAir(iblockstate, this.world, blockpos) -+ && block.canEntityDestroy(iblockstate, world, blockpos, this) -+ && net.minecraftforge.event.ForgeEventFactory.onEntityDestroyBlock(this, blockpos, iblockstate)) - { - flag = this.world.destroyBlock(blockpos, true) || flag; - } diff --git a/patches/minecraft/net/minecraft/entity/boss/dragon/phase/PhaseSittingFlaming.java.patch b/patches/minecraft/net/minecraft/entity/boss/dragon/phase/PhaseSittingFlaming.java.patch deleted file mode 100644 index 6c38b757a..000000000 --- a/patches/minecraft/net/minecraft/entity/boss/dragon/phase/PhaseSittingFlaming.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/entity/boss/dragon/phase/PhaseSittingFlaming.java -+++ after/net/minecraft/entity/boss/dragon/phase/PhaseSittingFlaming.java -@@ -91,7 +91,7 @@ - MathHelper.floor(d0), MathHelper.floor(d2), MathHelper.floor(d1) - ); - -- while (this.dragon.world.isAirBlock(blockpos$mutableblockpos)) -+ while (this.dragon.world.isAirBlock(blockpos$mutableblockpos) && d2 >= 0) //Forge: Fix infinite loop if ground is missing. - { - blockpos$mutableblockpos.setPos(MathHelper.floor(d0), MathHelper.floor(--d2), MathHelper.floor(d1)); - } diff --git a/patches/minecraft/net/minecraft/entity/effect/EntityLightningBolt.java.patch b/patches/minecraft/net/minecraft/entity/effect/EntityLightningBolt.java.patch deleted file mode 100644 index 0e7ad8fb0..000000000 --- a/patches/minecraft/net/minecraft/entity/effect/EntityLightningBolt.java.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- before/net/minecraft/entity/effect/EntityLightningBolt.java -+++ after/net/minecraft/entity/effect/EntityLightningBolt.java -@@ -144,7 +144,8 @@ - for (int i = 0; i < list.size(); i++) - { - Entity entity = list.get(i); -- entity.onStruckByLightning(this); -+ if (!net.minecraftforge.event.ForgeEventFactory.onEntityStruckByLightning(entity, this)) -+ entity.onStruckByLightning(this); - } - } - } diff --git a/patches/minecraft/net/minecraft/entity/item/EntityArmorStand.java.patch b/patches/minecraft/net/minecraft/entity/item/EntityArmorStand.java.patch deleted file mode 100644 index 0164bcd8c..000000000 --- a/patches/minecraft/net/minecraft/entity/item/EntityArmorStand.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/entity/item/EntityArmorStand.java -+++ after/net/minecraft/entity/item/EntityArmorStand.java -@@ -58,7 +58,7 @@ - { - public boolean apply(@Nullable Entity p_apply_1_) - { -- return p_apply_1_ instanceof EntityMinecart && ((EntityMinecart)p_apply_1_).getType() == EntityMinecart.Type.RIDEABLE; -+ return p_apply_1_ instanceof EntityMinecart && ((EntityMinecart)p_apply_1_).canBeRidden(); - } - }; - private final NonNullList handItems = NonNullList.withSize(2, ItemStack.EMPTY); diff --git a/patches/minecraft/net/minecraft/entity/item/EntityBoat.java.patch b/patches/minecraft/net/minecraft/entity/item/EntityBoat.java.patch deleted file mode 100644 index d3e963822..000000000 --- a/patches/minecraft/net/minecraft/entity/item/EntityBoat.java.patch +++ /dev/null @@ -1,83 +0,0 @@ ---- before/net/minecraft/entity/item/EntityBoat.java -+++ after/net/minecraft/entity/item/EntityBoat.java -@@ -475,6 +475,12 @@ - blockpos$pooledmutableblockpos.setPos(l1, k1, i2); - IBlockState iblockstate = this.world.getBlockState(blockpos$pooledmutableblockpos); - -+ Boolean result = iblockstate.getBlock().isAABBInsideMaterial(world, blockpos$pooledmutableblockpos, new AxisAlignedBB(blockpos$pooledmutableblockpos), Material.WATER); -+ if (result != null) { -+ if (!result) continue; -+ f = Math.max(f, iblockstate.getBlock().getBlockLiquidHeight(world, blockpos$pooledmutableblockpos, iblockstate, Material.WATER) + blockpos$pooledmutableblockpos.getY()); -+ } -+ - if (iblockstate.getMaterial() == Material.WATER) - { - f = Math.max(f, BlockLiquid.getBlockLiquidHeight(iblockstate, this.world, blockpos$pooledmutableblockpos)); -@@ -550,7 +556,7 @@ - - if (!list.isEmpty()) - { -- f += iblockstate.getBlock().slipperiness; -+ f += iblockstate.getBlock().getSlipperiness(iblockstate, this.world, blockpos$pooledmutableblockpos, this); - k1++; - } - -@@ -592,7 +598,16 @@ - { - blockpos$pooledmutableblockpos.setPos(k1, l1, i2); - IBlockState iblockstate = this.world.getBlockState(blockpos$pooledmutableblockpos); -+ -+ Boolean result = iblockstate.getBlock().isAABBInsideMaterial(world, blockpos$pooledmutableblockpos, axisalignedbb, Material.WATER); -+ if (result != null) { -+ if (!result) continue; - -+ float f = iblockstate.getBlock().getBlockLiquidHeight(world, blockpos$pooledmutableblockpos, iblockstate, Material.WATER) + blockpos$pooledmutableblockpos.getY(); -+ this.waterLevel = Math.max(f, this.waterLevel); -+ flag |= axisalignedbb.minY < (double)f; -+ } -+ - if (iblockstate.getMaterial() == Material.WATER) - { - float f = BlockLiquid.getLiquidHeight(iblockstate, this.world, blockpos$pooledmutableblockpos); -@@ -636,6 +651,18 @@ - blockpos$pooledmutableblockpos.setPos(k1, l1, i2); - IBlockState iblockstate = this.world.getBlockState(blockpos$pooledmutableblockpos); - -+ Boolean result = iblockstate.getBlock().isAABBInsideMaterial(world, blockpos$pooledmutableblockpos, axisalignedbb, Material.WATER); -+ if (result != null) { -+ if (!result) continue; -+ -+ if(iblockstate.getBlock().getBlockLiquidHeight(world, blockpos$pooledmutableblockpos, iblockstate, Material.WATER) > 0) -+ { -+ blockpos$pooledmutableblockpos.release(); -+ return EntityBoat.Status.UNDER_FLOWING_WATER; -+ } else -+ continue; -+ } -+ - if (iblockstate.getMaterial() == Material.WATER - && d0 < BlockLiquid.getLiquidHeight(iblockstate, this.world, blockpos$pooledmutableblockpos)) - { -@@ -967,6 +994,22 @@ - this.rightInputDown = p_184442_2_; - this.forwardInputDown = p_184442_3_; - this.backInputDown = p_184442_4_; -+ } -+ -+ // Forge: Fix MC-119811 by instantly completing lerp on board -+ @Override -+ protected void addPassenger(Entity passenger) -+ { -+ super.addPassenger(passenger); -+ if(this.canPassengerSteer() && this.lerpSteps > 0) -+ { -+ this.lerpSteps = 0; -+ this.posX = this.lerpX; -+ this.posY = this.lerpY; -+ this.posZ = this.lerpZ; -+ this.rotationYaw = (float)this.lerpYaw; -+ this.rotationPitch = (float)this.lerpPitch; -+ } - } - - public static enum Status diff --git a/patches/minecraft/net/minecraft/entity/item/EntityEnderPearl.java.patch b/patches/minecraft/net/minecraft/entity/item/EntityEnderPearl.java.patch deleted file mode 100644 index b2caa44d3..000000000 --- a/patches/minecraft/net/minecraft/entity/item/EntityEnderPearl.java.patch +++ /dev/null @@ -1,41 +0,0 @@ ---- before/net/minecraft/entity/item/EntityEnderPearl.java -+++ after/net/minecraft/entity/item/EntityEnderPearl.java -@@ -110,6 +110,9 @@ - && entityplayermp.world == this.world - && !entityplayermp.isPlayerSleeping()) - { -+ net.minecraftforge.event.entity.living.EnderTeleportEvent event = new net.minecraftforge.event.entity.living.EnderTeleportEvent(entityplayermp, this.posX, this.posY, this.posZ, 5.0F); -+ if (!net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event)) -+ { // Don't indent to lower patch size - if (this.rand.nextFloat() < 0.05F && this.world.getGameRules().getBoolean("doMobSpawning")) - { - EntityEndermite entityendermite = new EntityEndermite(this.world); -@@ -129,9 +132,10 @@ - entitylivingbase.dismountRidingEntity(); - } - -- entitylivingbase.setPositionAndUpdate(this.posX, this.posY, this.posZ); -+ entitylivingbase.setPositionAndUpdate(event.getTargetX(), event.getTargetY(), event.getTargetZ()); - entitylivingbase.fallDistance = 0.0F; -- entitylivingbase.attackEntityFrom(DamageSource.FALL, 5.0F); -+ entitylivingbase.attackEntityFrom(DamageSource.FALL, event.getAttackDamage()); -+ } - } - } - else if (entitylivingbase != null) -@@ -161,13 +165,13 @@ - - @Nullable - @Override -- public Entity changeDimension(int dimensionIn) -+ public Entity changeDimension(int dimensionIn, net.minecraftforge.common.util.ITeleporter teleporter) - { - if (this.thrower.dimension != dimensionIn) - { - this.thrower = null; - } - -- return super.changeDimension(dimensionIn); -+ return super.changeDimension(dimensionIn, teleporter); - } - } diff --git a/patches/minecraft/net/minecraft/entity/item/EntityFallingBlock.java.patch b/patches/minecraft/net/minecraft/entity/item/EntityFallingBlock.java.patch deleted file mode 100644 index daaa45b0c..000000000 --- a/patches/minecraft/net/minecraft/entity/item/EntityFallingBlock.java.patch +++ /dev/null @@ -1,28 +0,0 @@ ---- before/net/minecraft/entity/item/EntityFallingBlock.java -+++ after/net/minecraft/entity/item/EntityFallingBlock.java -@@ -177,6 +177,7 @@ - { - IBlockState iblockstate = this.world.getBlockState(blockpos1); - -+ if (this.world.isAirBlock(new BlockPos(this.posX, this.posY - 0.01F, this.posZ))) //Forge: Don't indent below. - if (!flag1 - && BlockFalling.canFallThrough( - this.world.getBlockState(new BlockPos(this.posX, this.posY - 0.01F, this.posZ)) -@@ -196,7 +197,7 @@ - - if (!this.dontSetBlock) - { -- if (this.world.mayPlace(block, blockpos1, true, EnumFacing.UP, null) -+ if (this.world.mayPlace(block, blockpos1, true, EnumFacing.UP, this) - && (flag1 || !BlockFalling.canFallThrough(this.world.getBlockState(blockpos1.down()))) - && this.world.setBlockState(blockpos1, this.fallTile, 3)) - { -@@ -205,7 +206,7 @@ - ((BlockFalling)block).onEndFalling(this.world, blockpos1, this.fallTile, iblockstate); - } - -- if (this.tileEntityData != null && block instanceof ITileEntityProvider) -+ if (this.tileEntityData != null && block.hasTileEntity(this.fallTile)) - { - TileEntity tileentity = this.world.getTileEntity(blockpos1); - diff --git a/patches/minecraft/net/minecraft/entity/item/EntityItem.java.patch b/patches/minecraft/net/minecraft/entity/item/EntityItem.java.patch deleted file mode 100644 index cf56cd5dc..000000000 --- a/patches/minecraft/net/minecraft/entity/item/EntityItem.java.patch +++ /dev/null @@ -1,151 +0,0 @@ ---- before/net/minecraft/entity/item/EntityItem.java -+++ after/net/minecraft/entity/item/EntityItem.java -@@ -38,6 +38,11 @@ - private String owner; - public float hoverStart = (float)(Math.random() * Math.PI * 2.0); - -+ /** -+ * The maximum age of this EntityItem. The item is expired once this is reached. -+ */ -+ public int lifespan = 6000; -+ - public EntityItem(World worldIn, double x, double y, double z) - { - super(worldIn); -@@ -53,6 +58,7 @@ - { - this(worldIn, x, y, z); - this.setItem(stack); -+ this.lifespan = (stack.getItem() == null ? 6000 : stack.getItem().getEntityLifespan(stack, worldIn)); - } - - @Override -@@ -77,6 +83,7 @@ - @Override - public void onUpdate() - { -+ if (getItem().getItem().onEntityItemUpdate(this)) return; - if (this.getItem().isEmpty()) - { - this.setDead(); -@@ -138,17 +145,9 @@ - - if (this.onGround) - { -- f = this.world -- .getBlockState( -- new BlockPos( -- MathHelper.floor(this.posX), -- MathHelper.floor(this.getEntityBoundingBox().minY) - 1, -- MathHelper.floor(this.posZ) -- ) -- ) -- .getBlock() -- .slipperiness -- * 0.98F; -+ BlockPos underPos = new BlockPos(MathHelper.floor(this.posX), MathHelper.floor(this.getEntityBoundingBox().minY) - 1, MathHelper.floor(this.posZ)); -+ net.minecraft.block.state.IBlockState underState = this.world.getBlockState(underPos); -+ f = underState.getBlock().getSlipperiness(underState, this.world, underPos, this) * 0.98F; - } - - this.motionX *= f; -@@ -180,7 +179,15 @@ - } - } - -- if (!this.world.isRemote && this.age >= 6000) -+ ItemStack item = this.getItem(); -+ -+ if (!this.world.isRemote && this.age >= lifespan) -+ { -+ int hook = net.minecraftforge.event.ForgeEventFactory.onItemExpire(this, item); -+ if (hook < 0) this.setDead(); -+ else this.lifespan += hook; -+ } -+ if (item.isEmpty()) - { - this.setDead(); - } -@@ -240,6 +247,10 @@ - { - return false; - } -+ else if (!itemstack.areCapsCompatible(itemstack1)) -+ { -+ return false; -+ } - else - { - itemstack1.grow(itemstack.getCount()); -@@ -295,6 +306,7 @@ - @Override - public boolean attackEntityFrom(DamageSource source, float amount) - { -+ if (this.world.isRemote || this.isDead) return false; //Forge: Fixes MC-53850 - if (this.isEntityInvulnerable(source)) - { - return false; -@@ -328,6 +340,7 @@ - compound.setShort("Health", (short)this.health); - compound.setShort("Age", (short)this.age); - compound.setShort("PickupDelay", (short)this.pickupDelay); -+ compound.setInteger("Lifespan", lifespan); - - if (this.getThrower() != null) - { -@@ -373,6 +386,7 @@ - { - this.setDead(); - } -+ if (compound.hasKey("Lifespan")) lifespan = compound.getInteger("Lifespan"); - } - - @Override -@@ -380,18 +394,23 @@ - { - if (!this.world.isRemote) - { -+ if (this.pickupDelay > 0) return; - ItemStack itemstack = this.getItem(); - Item item = itemstack.getItem(); - int i = itemstack.getCount(); - -- if (this.pickupDelay == 0 -- && (this.owner == null || 6000 - this.age <= 200 || this.owner.equals(entityIn.getName())) -- && entityIn.inventory.addItemStackToInventory(itemstack)) -+ int hook = net.minecraftforge.event.ForgeEventFactory.onItemPickup(this, entityIn); -+ if (hook < 0) return; -+ ItemStack clone = itemstack.copy(); -+ -+ if (this.pickupDelay <= 0 && (this.owner == null || lifespan - this.age <= 200 || this.owner.equals(entityIn.getName())) && (hook == 1 || i <= 0 || entityIn.inventory.addItemStackToInventory(itemstack) || clone.getCount() > this.getItem().getCount())) - { -- entityIn.onItemPickup(this, i); -+ clone.setCount(clone.getCount() - this.getItem().getCount()); -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().firePlayerItemPickupEvent(entityIn, this, clone); - - if (itemstack.isEmpty()) - { -+ entityIn.onItemPickup(this, i); - this.setDead(); - itemstack.setCount(i); - } -@@ -415,9 +434,9 @@ - - @Nullable - @Override -- public Entity changeDimension(int dimensionIn) -+ public Entity changeDimension(int dimensionIn, net.minecraftforge.common.util.ITeleporter teleporter) - { -- Entity entity = super.changeDimension(dimensionIn); -+ Entity entity = super.changeDimension(dimensionIn, teleporter); - - if (!this.world.isRemote && entity instanceof EntityItem) - { -@@ -497,6 +516,6 @@ - public void makeFakeItem() - { - this.setInfinitePickupDelay(); -- this.age = 5999; -+ this.age = getItem().getItem().getEntityLifespan(getItem(), world) - 1; - } - } diff --git a/patches/minecraft/net/minecraft/entity/item/EntityItemFrame.java.patch b/patches/minecraft/net/minecraft/entity/item/EntityItemFrame.java.patch deleted file mode 100644 index 937bb9c02..000000000 --- a/patches/minecraft/net/minecraft/entity/item/EntityItemFrame.java.patch +++ /dev/null @@ -1,18 +0,0 @@ ---- before/net/minecraft/entity/item/EntityItemFrame.java -+++ after/net/minecraft/entity/item/EntityItemFrame.java -@@ -148,13 +148,14 @@ - { - if (!stack.isEmpty()) - { -- if (stack.getItem() == Items.FILLED_MAP) -+ if (stack.getItem() instanceof net.minecraft.item.ItemMap) - { - MapData mapdata = ((ItemMap)stack.getItem()).getMapData(stack, this.world); - mapdata.mapDecorations.remove("frame-" + this.getEntityId()); - } - - stack.setItemFrame(null); -+ this.setDisplayedItem(ItemStack.EMPTY); //Forge: Fix MC-124833 Pistons duplicating Items. - } - } - diff --git a/patches/minecraft/net/minecraft/entity/item/EntityMinecart.java.patch b/patches/minecraft/net/minecraft/entity/item/EntityMinecart.java.patch deleted file mode 100644 index 1dd1e587b..000000000 --- a/patches/minecraft/net/minecraft/entity/item/EntityMinecart.java.patch +++ /dev/null @@ -1,499 +0,0 @@ ---- before/net/minecraft/entity/item/EntityMinecart.java -+++ after/net/minecraft/entity/item/EntityMinecart.java -@@ -71,6 +71,20 @@ - @SideOnly(Side.CLIENT) - private double velocityZ; - -+ /* Forge: Minecart Compatibility Layer Integration. */ -+ public static float defaultMaxSpeedAirLateral = 0.4f; -+ public static float defaultMaxSpeedAirVertical = -1f; -+ public static double defaultDragAir = 0.95; -+ protected boolean canUseRail = true; -+ protected boolean canBePushed = true; -+ private static net.minecraftforge.common.IMinecartCollisionHandler collisionHandler = null; -+ -+ /* Instance versions of the above physics properties */ -+ private float currentSpeedRail = getMaxCartSpeedOnRail(); -+ protected float maxSpeedAirLateral = defaultMaxSpeedAirLateral; -+ protected float maxSpeedAirVertical = defaultMaxSpeedAirVertical; -+ protected double dragAir = defaultDragAir; -+ - public EntityMinecart(World worldIn) - { - super(worldIn); -@@ -120,6 +134,7 @@ - @Override - public AxisAlignedBB getCollisionBox(Entity entityIn) - { -+ if (getCollisionHandler() != null) return getCollisionHandler().getCollisionBox(this, entityIn); - return entityIn.canBePushed() ? entityIn.getEntityBoundingBox() : null; - } - -@@ -127,13 +142,14 @@ - @Override - public AxisAlignedBB getCollisionBoundingBox() - { -+ if (getCollisionHandler() != null) return getCollisionHandler().getBoundingBox(this); - return null; - } - - @Override - public boolean canBePushed() - { -- return true; -+ return canBePushed; - } - - public EntityMinecart(World worldIn, double x, double y, double z) -@@ -342,7 +358,7 @@ - BlockPos blockpos = new BlockPos(k, l, i1); - IBlockState iblockstate = this.world.getBlockState(blockpos); - -- if (BlockRailBase.isRailBlock(iblockstate)) -+ if (canUseRail() && BlockRailBase.isRailBlock(iblockstate)) - { - this.moveAlongTrack(blockpos, iblockstate); - -@@ -381,10 +397,14 @@ - - this.setRotation(this.rotationYaw, this.rotationPitch); - -- if (this.getType() == EntityMinecart.Type.RIDEABLE && this.motionX * this.motionX + this.motionZ * this.motionZ > 0.01) -+ AxisAlignedBB box; -+ if (getCollisionHandler() != null) box = getCollisionHandler().getMinecartCollisionBox(this); -+ else box = this.getEntityBoundingBox().grow(0.2F, 0.0, 0.2F); -+ -+ if (canBeRidden() && this.motionX * this.motionX + this.motionZ * this.motionZ > 0.01) - { - List list = this.world -- .getEntitiesInAABBexcluding(this, this.getEntityBoundingBox().grow(0.2F, 0.0, 0.2F), EntitySelectors.getTeamCollisionPredicate(this)); -+ .getEntitiesInAABBexcluding(this, box, EntitySelectors.getTeamCollisionPredicate(this)); - - if (!list.isEmpty()) - { -@@ -409,7 +429,7 @@ - } - else - { -- for (Entity entity : this.world.getEntitiesWithinAABBExcludingEntity(this, this.getEntityBoundingBox().grow(0.2F, 0.0, 0.2F))) -+ for (Entity entity : this.world.getEntitiesWithinAABBExcludingEntity(this, box)) - { - if (!this.isPassenger(entity) && entity.canBePushed() && entity instanceof EntityMinecart) - { -@@ -419,6 +439,7 @@ - } - - this.handleWaterMovement(); -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.minecart.MinecartUpdateEvent(this, this.getCurrentRailPosition())); - } - } - -@@ -433,10 +454,21 @@ - - protected void moveDerailedMinecart() - { -- double d0 = this.getMaximumSpeed(); -+ double d0 = onGround ? this.getMaximumSpeed() : getMaxSpeedAirLateral(); - this.motionX = MathHelper.clamp(this.motionX, -d0, d0); - this.motionZ = MathHelper.clamp(this.motionZ, -d0, d0); - -+ double moveY = motionY; -+ if(getMaxSpeedAirVertical() > 0 && motionY > getMaxSpeedAirVertical()) -+ { -+ moveY = getMaxSpeedAirVertical(); -+ if(Math.abs(motionX) < 0.3f && Math.abs(motionZ) < 0.3f) -+ { -+ moveY = 0.15f; -+ motionY = moveY; -+ } -+ } -+ - if (this.onGround) - { - this.motionX *= 0.5; -@@ -444,13 +476,13 @@ - this.motionZ *= 0.5; - } - -- this.move(MoverType.SELF, this.motionX, this.motionY, this.motionZ); -+ this.move(MoverType.SELF, this.motionX, moveY, this.motionZ); - - if (!this.onGround) - { -- this.motionX *= 0.95F; -- this.motionY *= 0.95F; -- this.motionZ *= 0.95F; -+ this.motionX *= getDragAir(); -+ this.motionY *= getDragAir(); -+ this.motionZ *= getDragAir(); - } - } - -@@ -470,25 +502,25 @@ - flag1 = !flag; - } - -- double d0 = 0.0078125; -- BlockRailBase.EnumRailDirection blockrailbase$enumraildirection = state.getValue(blockrailbase.getShapeProperty()); -+ double slopeAdjustment = getSlopeAdjustment(); -+ BlockRailBase.EnumRailDirection blockrailbase$enumraildirection = blockrailbase.getRailDirection(world, pos, state, this); - - switch (blockrailbase$enumraildirection) - { - case ASCENDING_EAST: -- this.motionX -= 0.0078125; -+ this.motionX -= slopeAdjustment; - this.posY++; - break; - case ASCENDING_WEST: -- this.motionX += 0.0078125; -+ this.motionX += slopeAdjustment; - this.posY++; - break; - case ASCENDING_NORTH: -- this.motionZ += 0.0078125; -+ this.motionZ += slopeAdjustment; - this.posY++; - break; - case ASCENDING_SOUTH: -- this.motionZ -= 0.0078125; -+ this.motionZ -= slopeAdjustment; - this.posY++; - } - -@@ -534,7 +566,7 @@ - } - } - -- if (flag1) -+ if (flag1 && shouldDoRailFunctions()) - { - double d17 = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ); - -@@ -580,19 +612,7 @@ - this.posX = d18 + d1 * d10; - this.posZ = d19 + d2 * d10; - this.setPosition(this.posX, this.posY, this.posZ); -- double d22 = this.motionX; -- double d23 = this.motionZ; -- -- if (this.isBeingRidden()) -- { -- d22 *= 0.75; -- d23 *= 0.75; -- } -- -- double d13 = this.getMaximumSpeed(); -- d22 = MathHelper.clamp(d22, -d13, d13); -- d23 = MathHelper.clamp(d23, -d13, d13); -- this.move(MoverType.SELF, d22, 0.0, d23); -+ this.moveMinecartOnRail(pos); - - if (aint[0][1] != 0 - && MathHelper.floor(this.posX) - pos.getX() == aint[0][0] -@@ -634,7 +654,13 @@ - this.motionZ = d5 * (i - pos.getZ()); - } - -- if (flag) -+ -+ if(shouldDoRailFunctions()) -+ { -+ ((BlockRailBase)state.getBlock()).onMinecartPass(world, this, pos); -+ } -+ -+ if (flag && shouldDoRailFunctions()) - { - double d15 = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ); - -@@ -713,9 +739,7 @@ - - if (BlockRailBase.isRailBlock(iblockstate)) - { -- BlockRailBase.EnumRailDirection blockrailbase$enumraildirection = iblockstate.getValue( -- ((BlockRailBase)iblockstate.getBlock()).getShapeProperty() -- ); -+ BlockRailBase.EnumRailDirection blockrailbase$enumraildirection = ((BlockRailBase)iblockstate.getBlock()).getRailDirection(world, new BlockPos(i, j, k), iblockstate, this); - y = j; - - if (blockrailbase$enumraildirection.isAscending()) -@@ -765,9 +789,7 @@ - - if (BlockRailBase.isRailBlock(iblockstate)) - { -- BlockRailBase.EnumRailDirection blockrailbase$enumraildirection = iblockstate.getValue( -- ((BlockRailBase)iblockstate.getBlock()).getShapeProperty() -- ); -+ BlockRailBase.EnumRailDirection blockrailbase$enumraildirection = ((BlockRailBase)iblockstate.getBlock()).getRailDirection(world, new BlockPos(i, j, k), iblockstate, this); - int[][] aint = MATRIX[blockrailbase$enumraildirection.getMetadata()]; - double d0 = i + 0.5 + aint[0][0] * 0.5; - double d1 = j + 0.0625 + aint[0][1] * 0.5; -@@ -868,6 +890,12 @@ - @Override - public void applyEntityCollision(Entity entityIn) - { -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.minecart.MinecartCollisionEvent(this, entityIn)); -+ if (getCollisionHandler() != null) -+ { -+ getCollisionHandler().onEntityCollision(this, entityIn); -+ return; -+ } - if (!this.world.isRemote) - { - if (!entityIn.noClip && !this.noClip) -@@ -920,7 +948,7 @@ - double d7 = entityIn.motionX + this.motionX; - double d8 = entityIn.motionZ + this.motionZ; - -- if (((EntityMinecart)entityIn).getType() == EntityMinecart.Type.FURNACE && this.getType() != EntityMinecart.Type.FURNACE) -+ if (((EntityMinecart)entityIn).isPoweredCart() && !isPoweredCart()) - { - this.motionX *= 0.2F; - this.motionZ *= 0.2F; -@@ -928,8 +956,7 @@ - entityIn.motionX *= 0.95F; - entityIn.motionZ *= 0.95F; - } -- else if (((EntityMinecart)entityIn).getType() != EntityMinecart.Type.FURNACE -- && this.getType() == EntityMinecart.Type.FURNACE) -+ else if (!((EntityMinecart)entityIn).isPoweredCart() && isPoweredCart()) - { - entityIn.motionX *= 0.2F; - entityIn.motionZ *= 0.2F; -@@ -1062,6 +1089,236 @@ - { - this.getDataManager().set(SHOW_BLOCK, showBlock); - } -+ -+ @Override -+ public boolean processInitialInteract(EntityPlayer player, net.minecraft.util.EnumHand hand) -+ { -+ return net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.minecart.MinecartInteractEvent(this, player, hand)); -+ } -+ -+ /* =================================== FORGE START ===========================================*/ -+ private BlockPos getCurrentRailPosition() -+ { -+ int x = MathHelper.floor(this.posX); -+ int y = MathHelper.floor(this.posY); -+ int z = MathHelper.floor(this.posZ); -+ -+ if (BlockRailBase.isRailBlock(this.world, new BlockPos(x, y - 1, z))) y--; -+ return new BlockPos(x, y, z); -+ } -+ -+ protected double getMaxSpeed() -+ { -+ if (!canUseRail()) return getMaximumSpeed(); -+ BlockPos pos = this.getCurrentRailPosition(); -+ IBlockState state = this.world.getBlockState(pos); -+ if (!BlockRailBase.isRailBlock(state)) return getMaximumSpeed(); -+ -+ float railMaxSpeed = ((BlockRailBase)state.getBlock()).getRailMaxSpeed(world, this, pos); -+ return Math.min(railMaxSpeed, getCurrentCartSpeedCapOnRail()); -+ } -+ -+ /** -+ * Moved to allow overrides. -+ * This code handles minecart movement and speed capping when on a rail. -+ */ -+ public void moveMinecartOnRail(BlockPos pos) -+ { -+ double mX = this.motionX; -+ double mZ = this.motionZ; -+ -+ if (this.isBeingRidden()) -+ { -+ mX *= 0.75D; -+ mZ *= 0.75D; -+ } -+ -+ double max = this.getMaxSpeed(); -+ mX = MathHelper.clamp(mX, -max, max); -+ mZ = MathHelper.clamp(mZ, -max, max); -+ this.move(MoverType.SELF, mX, 0.0D, mZ); -+ } -+ -+ /** -+ * Gets the current global Minecart Collision handler if none -+ * is registered, returns null -+ * @return The collision handler or null -+ */ -+ @Nullable -+ public static net.minecraftforge.common.IMinecartCollisionHandler getCollisionHandler() -+ { -+ return collisionHandler; -+ } -+ -+ /** -+ * Sets the global Minecart Collision handler, overwrites any -+ * that is currently set. -+ * @param handler The new handler -+ */ -+ public static void setCollisionHandler(net.minecraftforge.common.IMinecartCollisionHandler handler) -+ { -+ collisionHandler = handler; -+ } -+ -+ /** -+ * This function returns an ItemStack that represents this cart. -+ * This should be an ItemStack that can be used by the player to place the cart, -+ * but is not necessary the item the cart drops when destroyed. -+ * @return An ItemStack that can be used to place the cart. -+ */ -+ public ItemStack getCartItem() -+ { -+ if (this instanceof EntityMinecartFurnace) -+ { -+ return new ItemStack(Items.FURNACE_MINECART); -+ } -+ else if (this instanceof EntityMinecartChest) -+ { -+ return new ItemStack(Items.CHEST_MINECART); -+ } -+ else if (this instanceof EntityMinecartTNT) -+ { -+ return new ItemStack(Items.TNT_MINECART); -+ } -+ else if (this instanceof EntityMinecartHopper) -+ { -+ return new ItemStack(Items.HOPPER_MINECART); -+ } -+ else if (this instanceof EntityMinecartCommandBlock) -+ { -+ return new ItemStack(Items.COMMAND_BLOCK_MINECART); -+ } -+ return new ItemStack(Items.MINECART); -+ } -+ -+ /** -+ * Returns true if this cart can currently use rails. -+ * This function is mainly used to gracefully detach a minecart from a rail. -+ * @return True if the minecart can use rails. -+ */ -+ public boolean canUseRail() -+ { -+ return canUseRail; -+ } -+ -+ /** -+ * Set whether the minecart can use rails. -+ * This function is mainly used to gracefully detach a minecart from a rail. -+ * @param use Whether the minecart can currently use rails. -+ */ -+ public void setCanUseRail(boolean use) -+ { -+ canUseRail = use; -+ } -+ -+ /** -+ * Return false if this cart should not call onMinecartPass() and should ignore Powered Rails. -+ * @return True if this cart should call onMinecartPass(). -+ */ -+ public boolean shouldDoRailFunctions() -+ { -+ return true; -+ } -+ -+ /** -+ * Returns true if this cart is self propelled. -+ * @return True if powered. -+ */ -+ public boolean isPoweredCart() -+ { -+ return getType() == EntityMinecart.Type.FURNACE; -+ } -+ -+ /** -+ * Returns true if this cart can be ridden by an Entity. -+ * @return True if this cart can be ridden. -+ */ -+ public boolean canBeRidden() -+ { -+ return this.getType() == EntityMinecart.Type.RIDEABLE; -+ } -+ -+ /** -+ * Getters/setters for physics variables -+ */ -+ -+ /** -+ * Returns the carts max speed when traveling on rails. Carts going faster -+ * than 1.1 cause issues with chunk loading. Carts cant traverse slopes or -+ * corners at greater than 0.5 - 0.6. This value is compared with the rails -+ * max speed and the carts current speed cap to determine the carts current -+ * max speed. A normal rail's max speed is 0.4. -+ * -+ * @return Carts max speed. -+ */ -+ public float getMaxCartSpeedOnRail() -+ { -+ return 1.2f; -+ } -+ -+ /** -+ * Returns the current speed cap for the cart when traveling on rails. This -+ * functions differs from getMaxCartSpeedOnRail() in that it controls -+ * current movement and cannot be overridden. The value however can never be -+ * higher than getMaxCartSpeedOnRail(). -+ * -+ * @return -+ */ -+ public final float getCurrentCartSpeedCapOnRail() -+ { -+ return currentSpeedRail; -+ } -+ -+ public final void setCurrentCartSpeedCapOnRail(float value) -+ { -+ value = Math.min(value, getMaxCartSpeedOnRail()); -+ currentSpeedRail = value; -+ } -+ -+ public float getMaxSpeedAirLateral() -+ { -+ return maxSpeedAirLateral; -+ } -+ -+ public void setMaxSpeedAirLateral(float value) -+ { -+ maxSpeedAirLateral = value; -+ } -+ -+ public float getMaxSpeedAirVertical() -+ { -+ return maxSpeedAirVertical; -+ } -+ -+ public void setMaxSpeedAirVertical(float value) -+ { -+ maxSpeedAirVertical = value; -+ } -+ -+ public double getDragAir() -+ { -+ return dragAir; -+ } -+ -+ public void setDragAir(double value) -+ { -+ dragAir = value; -+ } -+ -+ public double getSlopeAdjustment() -+ { -+ return 0.0078125D; -+ } -+ -+ /** -+ * Called from Detector Rails to retrieve a redstone power level for comparators. -+ */ -+ public int getComparatorLevel() -+ { -+ return -1; -+ } -+ -+ /* =================================== FORGE END ===========================================*/ - - public static enum Type - { diff --git a/patches/minecraft/net/minecraft/entity/item/EntityMinecartCommandBlock.java.patch b/patches/minecraft/net/minecraft/entity/item/EntityMinecartCommandBlock.java.patch deleted file mode 100644 index b32809c27..000000000 --- a/patches/minecraft/net/minecraft/entity/item/EntityMinecartCommandBlock.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- before/net/minecraft/entity/item/EntityMinecartCommandBlock.java -+++ after/net/minecraft/entity/item/EntityMinecartCommandBlock.java -@@ -169,6 +169,7 @@ - @Override - public boolean processInitialInteract(EntityPlayer player, EnumHand hand) - { -+ if (super.processInitialInteract(player, hand)) return true; - this.commandBlockLogic.tryOpenEditCommandBlock(player); - return false; - } diff --git a/patches/minecraft/net/minecraft/entity/item/EntityMinecartContainer.java.patch b/patches/minecraft/net/minecraft/entity/item/EntityMinecartContainer.java.patch deleted file mode 100644 index a950439b7..000000000 --- a/patches/minecraft/net/minecraft/entity/item/EntityMinecartContainer.java.patch +++ /dev/null @@ -1,61 +0,0 @@ ---- before/net/minecraft/entity/item/EntityMinecartContainer.java -+++ after/net/minecraft/entity/item/EntityMinecartContainer.java -@@ -144,10 +144,10 @@ - - @Nullable - @Override -- public Entity changeDimension(int dimensionIn) -+ public Entity changeDimension(int dimensionIn, net.minecraftforge.common.util.ITeleporter teleporter) - { - this.dropContentsWhenDead = false; -- return super.changeDimension(dimensionIn); -+ return super.changeDimension(dimensionIn, teleporter); - } - - @Override -@@ -213,6 +213,7 @@ - @Override - public boolean processInitialInteract(EntityPlayer player, EnumHand hand) - { -+ if (super.processInitialInteract(player, hand)) return true; - if (!this.world.isRemote) - { - player.displayGUIChest(this); -@@ -288,15 +289,35 @@ - random = new Random(this.lootTableSeed); - } - -- LootContext.Builder lootcontext$builder = new LootContext.Builder((WorldServer)this.world); -+ LootContext.Builder lootcontext$builder = new LootContext.Builder((WorldServer)this.world).withLootedEntity(this); // Forge: add looted entity to LootContext - - if (player != null) - { -- lootcontext$builder.withLuck(player.getLuck()); -+ lootcontext$builder.withLuck(player.getLuck()).withPlayer(player); // Forge: add player to LootContext - } - - loottable.fillInventory(this, random, lootcontext$builder.build()); - } -+ } -+ -+ public net.minecraftforge.items.IItemHandler itemHandler = new net.minecraftforge.items.wrapper.InvWrapper(this); -+ -+ @SuppressWarnings("unchecked") -+ @Override -+ @Nullable -+ public T getCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable net.minecraft.util.EnumFacing facing) -+ { -+ if (capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) -+ { -+ return (T) itemHandler; -+ } -+ return super.getCapability(capability, facing); -+ } -+ -+ @Override -+ public boolean hasCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable net.minecraft.util.EnumFacing facing) -+ { -+ return capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY || super.hasCapability(capability, facing); - } - - @Override diff --git a/patches/minecraft/net/minecraft/entity/item/EntityMinecartEmpty.java.patch b/patches/minecraft/net/minecraft/entity/item/EntityMinecartEmpty.java.patch deleted file mode 100644 index 1c179b0f4..000000000 --- a/patches/minecraft/net/minecraft/entity/item/EntityMinecartEmpty.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/entity/item/EntityMinecartEmpty.java -+++ after/net/minecraft/entity/item/EntityMinecartEmpty.java -@@ -25,6 +25,8 @@ - @Override - public boolean processInitialInteract(EntityPlayer player, EnumHand hand) - { -+ if (super.processInitialInteract(player, hand)) return true; -+ - if (player.isSneaking()) - { - return false; diff --git a/patches/minecraft/net/minecraft/entity/item/EntityMinecartFurnace.java.patch b/patches/minecraft/net/minecraft/entity/item/EntityMinecartFurnace.java.patch deleted file mode 100644 index 6a6e9d1fc..000000000 --- a/patches/minecraft/net/minecraft/entity/item/EntityMinecartFurnace.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/entity/item/EntityMinecartFurnace.java -+++ after/net/minecraft/entity/item/EntityMinecartFurnace.java -@@ -152,6 +152,8 @@ - public boolean processInitialInteract(EntityPlayer player, EnumHand hand) - { - ItemStack itemstack = player.getHeldItem(hand); -+ -+ if (super.processInitialInteract(player, hand)) return true; - - if (itemstack.getItem() == Items.COAL && this.fuel + 3600 <= 32000) - { diff --git a/patches/minecraft/net/minecraft/entity/item/EntityMinecartHopper.java.patch b/patches/minecraft/net/minecraft/entity/item/EntityMinecartHopper.java.patch deleted file mode 100644 index bc11067f3..000000000 --- a/patches/minecraft/net/minecraft/entity/item/EntityMinecartHopper.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- before/net/minecraft/entity/item/EntityMinecartHopper.java -+++ after/net/minecraft/entity/item/EntityMinecartHopper.java -@@ -61,6 +61,7 @@ - @Override - public boolean processInitialInteract(EntityPlayer player, EnumHand hand) - { -+ if (super.processInitialInteract(player, hand)) return true; - if (!this.world.isRemote) - { - player.displayGUIChest(this); diff --git a/patches/minecraft/net/minecraft/entity/item/EntityMinecartMobSpawner.java.patch b/patches/minecraft/net/minecraft/entity/item/EntityMinecartMobSpawner.java.patch deleted file mode 100644 index 71a3bef2c..000000000 --- a/patches/minecraft/net/minecraft/entity/item/EntityMinecartMobSpawner.java.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- before/net/minecraft/entity/item/EntityMinecartMobSpawner.java -+++ after/net/minecraft/entity/item/EntityMinecartMobSpawner.java -@@ -36,6 +36,10 @@ - { - return new BlockPos(EntityMinecartMobSpawner.this); - } -+ @Override -+ public net.minecraft.entity.Entity getSpawnerEntity() { -+ return EntityMinecartMobSpawner.this; -+ } - }; - - public EntityMinecartMobSpawner(World worldIn) diff --git a/patches/minecraft/net/minecraft/entity/item/EntityXPOrb.java.patch b/patches/minecraft/net/minecraft/entity/item/EntityXPOrb.java.patch deleted file mode 100644 index a02751902..000000000 --- a/patches/minecraft/net/minecraft/entity/item/EntityXPOrb.java.patch +++ /dev/null @@ -1,60 +0,0 @@ ---- before/net/minecraft/entity/item/EntityXPOrb.java -+++ after/net/minecraft/entity/item/EntityXPOrb.java -@@ -141,17 +141,9 @@ - - if (this.onGround) - { -- f = this.world -- .getBlockState( -- new BlockPos( -- MathHelper.floor(this.posX), -- MathHelper.floor(this.getEntityBoundingBox().minY) - 1, -- MathHelper.floor(this.posZ) -- ) -- ) -- .getBlock() -- .slipperiness -- * 0.98F; -+ BlockPos underPos = new BlockPos(MathHelper.floor(this.posX), MathHelper.floor(this.getEntityBoundingBox().minY) - 1, MathHelper.floor(this.posZ)); -+ net.minecraft.block.state.IBlockState underState = this.world.getBlockState(underPos); -+ f = underState.getBlock().getSlipperiness(underState, this.world, underPos, this) * 0.98F; - } - - this.motionX *= f; -@@ -187,6 +179,7 @@ - @Override - public boolean attackEntityFrom(DamageSource source, float amount) - { -+ if (this.world.isRemote || this.isDead) return false; //Forge: Fixes MC-53850 - if (this.isEntityInvulnerable(source)) - { - return false; -@@ -228,13 +221,15 @@ - { - if (this.delayBeforeCanPickup == 0 && entityIn.xpCooldown == 0) - { -+ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.player.PlayerPickupXpEvent(entityIn, this))) return; - entityIn.xpCooldown = 2; - entityIn.onItemPickup(this, 1); - ItemStack itemstack = EnchantmentHelper.getEnchantedItem(Enchantments.MENDING, entityIn); - - if (!itemstack.isEmpty() && itemstack.isItemDamaged()) - { -- int i = Math.min(this.xpToDurability(this.xpValue), itemstack.getItemDamage()); -+ float ratio = itemstack.getItem().getXpRepairRatio(itemstack); -+ int i = Math.min(roundAverage(this.xpValue * ratio), itemstack.getItemDamage()); - this.xpValue = this.xpValue - this.durabilityToXp(i); - itemstack.setItemDamage(itemstack.getItemDamage() - i); - } -@@ -357,5 +352,11 @@ - public boolean canBeAttackedWithItem() - { - return false; -+ } -+ -+ private static int roundAverage(float value) -+ { -+ double floor = Math.floor(value); -+ return (int) floor + (Math.random() < value - floor ? 1 : 0); - } - } diff --git a/patches/minecraft/net/minecraft/entity/monster/AbstractSkeleton.java.patch b/patches/minecraft/net/minecraft/entity/monster/AbstractSkeleton.java.patch deleted file mode 100644 index eb0d4d0e8..000000000 --- a/patches/minecraft/net/minecraft/entity/monster/AbstractSkeleton.java.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- before/net/minecraft/entity/monster/AbstractSkeleton.java -+++ after/net/minecraft/entity/monster/AbstractSkeleton.java -@@ -205,7 +205,7 @@ - this.tasks.removeTask(this.aiArrowAttack); - ItemStack itemstack = this.getHeldItemMainhand(); - -- if (itemstack.getItem() == Items.BOW) -+ if (itemstack.getItem() instanceof net.minecraft.item.ItemBow) - { - int i = 20; - -@@ -228,6 +228,8 @@ - public void attackEntityWithRangedAttack(EntityLivingBase target, float distanceFactor) - { - EntityArrow entityarrow = this.getArrow(distanceFactor); -+ if (this.getHeldItemMainhand().getItem() instanceof net.minecraft.item.ItemBow) -+ entityarrow = ((net.minecraft.item.ItemBow) this.getHeldItemMainhand().getItem()).customizeArrow(entityarrow); - double d0 = target.posX - this.posX; - double d1 = target.getEntityBoundingBox().minY + target.height / 3.0F - entityarrow.posY; - double d2 = target.posZ - this.posZ; diff --git a/patches/minecraft/net/minecraft/entity/monster/EntityCreeper.java.patch b/patches/minecraft/net/minecraft/entity/monster/EntityCreeper.java.patch deleted file mode 100644 index 152b99302..000000000 --- a/patches/minecraft/net/minecraft/entity/monster/EntityCreeper.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/entity/monster/EntityCreeper.java -+++ after/net/minecraft/entity/monster/EntityCreeper.java -@@ -293,7 +293,7 @@ - { - if (!this.world.isRemote) - { -- boolean flag = this.world.getGameRules().getBoolean("mobGriefing"); -+ boolean flag = net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.world, this); - float f = this.getPowered() ? 2.0F : 1.0F; - this.dead = true; - this.world.createExplosion(this, this.posX, this.posY, this.posZ, this.explosionRadius * f, flag); diff --git a/patches/minecraft/net/minecraft/entity/monster/EntityEnderman.java.patch b/patches/minecraft/net/minecraft/entity/monster/EntityEnderman.java.patch deleted file mode 100644 index 633f4d572..000000000 --- a/patches/minecraft/net/minecraft/entity/monster/EntityEnderman.java.patch +++ /dev/null @@ -1,68 +0,0 @@ ---- before/net/minecraft/entity/monster/EntityEnderman.java -+++ after/net/minecraft/entity/monster/EntityEnderman.java -@@ -306,7 +306,9 @@ - - private boolean teleportTo(double x, double y, double z) - { -- boolean flag = this.attemptTeleport(x, y, z); -+ net.minecraftforge.event.entity.living.EnderTeleportEvent event = new net.minecraftforge.event.entity.living.EnderTeleportEvent(this, x, y, z, 0); -+ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event)) return false; -+ boolean flag = this.attemptTeleport(event.getTargetX(), event.getTargetY(), event.getTargetZ()); - - if (flag) - { -@@ -400,6 +402,18 @@ - } - } - -+ /*===================================== Forge Start ==============================*/ -+ public static void setCarriable(Block block, boolean canCarry) -+ { -+ if (canCarry) CARRIABLE_BLOCKS.add(block); -+ else CARRIABLE_BLOCKS.remove(block); -+ } -+ public static boolean getCarriable(Block block) -+ { -+ return CARRIABLE_BLOCKS.contains(block); -+ } -+ /*===================================== Forge End ==============================*/ -+ - public boolean isScreaming() - { - return this.dataManager.get(SCREAMING); -@@ -552,7 +566,7 @@ - } - else - { -- return !this.enderman.world.getGameRules().getBoolean("mobGriefing") -+ return !net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.enderman.world, this.enderman) - ? false - : this.enderman.getRNG().nextInt(2000) == 0; - } -@@ -571,7 +585,16 @@ - IBlockState iblockstate1 = world.getBlockState(blockpos.down()); - IBlockState iblockstate2 = this.enderman.getHeldBlockState(); - -- if (iblockstate2 != null && this.canPlaceBlock(world, blockpos, iblockstate2.getBlock(), iblockstate, iblockstate1)) -+ if (iblockstate2 != null && this.canPlaceBlock(world, blockpos, iblockstate2.getBlock(), iblockstate, iblockstate1) -+ && net.minecraftforge.event.ForgeEventFactory.onBlockPlace( -+ enderman, -+ new net.minecraftforge.common.util.BlockSnapshot( -+ world, -+ blockpos, -+ iblockstate2 -+ ), -+ net.minecraft.util.EnumFacing.UP -+ ).isCanceled()) - { - world.setBlockState(blockpos, iblockstate2, 3); - this.enderman.setHeldBlockState(null); -@@ -613,7 +636,7 @@ - } - else - { -- return !this.enderman.world.getGameRules().getBoolean("mobGriefing") ? false : this.enderman.getRNG().nextInt(20) == 0; -+ return !net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.enderman.world, this.enderman) ? false : this.enderman.getRNG().nextInt(20) == 0; - } - } - diff --git a/patches/minecraft/net/minecraft/entity/monster/EntityEvoker.java.patch b/patches/minecraft/net/minecraft/entity/monster/EntityEvoker.java.patch deleted file mode 100644 index 5eeea5b2a..000000000 --- a/patches/minecraft/net/minecraft/entity/monster/EntityEvoker.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/entity/monster/EntityEvoker.java -+++ after/net/minecraft/entity/monster/EntityEvoker.java -@@ -409,7 +409,7 @@ - { - return false; - } -- else if (!EntityEvoker.this.world.getGameRules().getBoolean("mobGriefing")) -+ else if (!net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(EntityEvoker.this.world, EntityEvoker.this)) - { - return false; - } diff --git a/patches/minecraft/net/minecraft/entity/monster/EntityIllusionIllager.java.patch b/patches/minecraft/net/minecraft/entity/monster/EntityIllusionIllager.java.patch deleted file mode 100644 index 6c721ef95..000000000 --- a/patches/minecraft/net/minecraft/entity/monster/EntityIllusionIllager.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/entity/monster/EntityIllusionIllager.java -+++ after/net/minecraft/entity/monster/EntityIllusionIllager.java -@@ -236,6 +236,8 @@ - public void attackEntityWithRangedAttack(EntityLivingBase target, float distanceFactor) - { - EntityArrow entityarrow = this.createArrowEntity(distanceFactor); -+ if (this.getHeldItemMainhand().getItem() instanceof net.minecraft.item.ItemBow) -+ entityarrow = ((net.minecraft.item.ItemBow) this.getHeldItemMainhand().getItem()).customizeArrow(entityarrow); - double d0 = target.posX - this.posX; - double d1 = target.getEntityBoundingBox().minY + target.height / 3.0F - entityarrow.posY; - double d2 = target.posZ - this.posZ; diff --git a/patches/minecraft/net/minecraft/entity/monster/EntityIronGolem.java.patch b/patches/minecraft/net/minecraft/entity/monster/EntityIronGolem.java.patch deleted file mode 100644 index 394016825..000000000 --- a/patches/minecraft/net/minecraft/entity/monster/EntityIronGolem.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/entity/monster/EntityIronGolem.java -+++ after/net/minecraft/entity/monster/EntityIronGolem.java -@@ -321,7 +321,7 @@ - { - if (!this.isPlayerCreated() && this.attackingPlayer != null && this.village != null) - { -- this.village.modifyPlayerReputation(this.attackingPlayer.getName(), -5); -+ this.village.modifyPlayerReputation(this.attackingPlayer.getUniqueID(), -5); - } - - super.onDeath(cause); diff --git a/patches/minecraft/net/minecraft/entity/monster/EntityMagmaCube.java.patch b/patches/minecraft/net/minecraft/entity/monster/EntityMagmaCube.java.patch deleted file mode 100644 index 06b2be059..000000000 --- a/patches/minecraft/net/minecraft/entity/monster/EntityMagmaCube.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- before/net/minecraft/entity/monster/EntityMagmaCube.java -+++ after/net/minecraft/entity/monster/EntityMagmaCube.java -@@ -111,6 +111,7 @@ - { - this.motionY = 0.42F + this.getSlimeSize() * 0.1F; - this.isAirBorne = true; -+ net.minecraftforge.common.ForgeHooks.onLivingJump(this); - } - - @Override diff --git a/patches/minecraft/net/minecraft/entity/monster/EntityMob.java.patch b/patches/minecraft/net/minecraft/entity/monster/EntityMob.java.patch deleted file mode 100644 index fc415a05e..000000000 --- a/patches/minecraft/net/minecraft/entity/monster/EntityMob.java.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- before/net/minecraft/entity/monster/EntityMob.java -+++ after/net/minecraft/entity/monster/EntityMob.java -@@ -138,14 +138,14 @@ - - if (!itemstack.isEmpty() - && !itemstack1.isEmpty() -- && itemstack.getItem() instanceof ItemAxe -- && itemstack1.getItem() == Items.SHIELD) -+ && itemstack.getItem().canDisableShield(itemstack, itemstack1, entityplayer, this) -+ && itemstack1.getItem().isShield(itemstack1, entityplayer)) - { - float f1 = 0.25F + EnchantmentHelper.getEfficiencyModifier(this) * 0.05F; - - if (this.rand.nextFloat() < f1) - { -- entityplayer.getCooldownTracker().setCooldown(Items.SHIELD, 100); -+ entityplayer.getCooldownTracker().setCooldown(itemstack1.getItem(), 100); - this.world.setEntityState(entityplayer, (byte)30); - } - } diff --git a/patches/minecraft/net/minecraft/entity/monster/EntityShulker.java.patch b/patches/minecraft/net/minecraft/entity/monster/EntityShulker.java.patch deleted file mode 100644 index dd889aa9e..000000000 --- a/patches/minecraft/net/minecraft/entity/monster/EntityShulker.java.patch +++ /dev/null @@ -1,24 +0,0 @@ ---- before/net/minecraft/entity/monster/EntityShulker.java -+++ after/net/minecraft/entity/monster/EntityShulker.java -@@ -503,6 +503,13 @@ - - if (flag) - { -+ net.minecraftforge.event.entity.living.EnderTeleportEvent event = new net.minecraftforge.event.entity.living.EnderTeleportEvent(this, blockpos1.getX(), blockpos1.getY(), blockpos1.getZ(), 0); -+ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event)) flag = false; -+ blockpos1 = new BlockPos(event.getTargetX(), event.getTargetY(), event.getTargetZ()); -+ } -+ -+ if (flag) -+ { - this.playSound(SoundEvents.ENTITY_SHULKER_TELEPORT, 1.0F, 1.0F); - this.dataManager.set(ATTACHED_BLOCK_POS, Optional.of(blockpos1)); - this.dataManager.set(PEEK_TICK, (byte)0); -@@ -553,6 +560,7 @@ - this.posX = blockpos.getX() + 0.5; - this.posY = blockpos.getY(); - this.posZ = blockpos.getZ() + 0.5; -+ if (this.isAddedToWorld() && !this.world.isRemote) this.world.updateEntityWithOptionalForce(this, false); // Forge - Process chunk registration after moving. - this.prevPosX = this.posX; - this.prevPosY = this.posY; - this.prevPosZ = this.posZ; diff --git a/patches/minecraft/net/minecraft/entity/monster/EntitySilverfish.java.patch b/patches/minecraft/net/minecraft/entity/monster/EntitySilverfish.java.patch deleted file mode 100644 index f9194a401..000000000 --- a/patches/minecraft/net/minecraft/entity/monster/EntitySilverfish.java.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- before/net/minecraft/entity/monster/EntitySilverfish.java -+++ after/net/minecraft/entity/monster/EntitySilverfish.java -@@ -202,7 +202,7 @@ - { - Random random = this.entity.getRNG(); - -- if (this.entity.world.getGameRules().getBoolean("mobGriefing") && random.nextInt(10) == 0) -+ if (net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.entity.world, this.entity) && random.nextInt(10) == 0) - { - this.facing = EnumFacing.random(random); - BlockPos blockpos = new BlockPos(this.entity.posX, this.entity.posY + 0.5, this.entity.posZ) -@@ -301,7 +301,7 @@ - - if (iblockstate.getBlock() == Blocks.MONSTER_EGG) - { -- if (world.getGameRules().getBoolean("mobGriefing")) -+ if (net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(world, this.silverfish)) - { - world.destroyBlock(blockpos1, true); - } diff --git a/patches/minecraft/net/minecraft/entity/monster/EntitySlime.java.patch b/patches/minecraft/net/minecraft/entity/monster/EntitySlime.java.patch deleted file mode 100644 index d76f371dd..000000000 --- a/patches/minecraft/net/minecraft/entity/monster/EntitySlime.java.patch +++ /dev/null @@ -1,43 +0,0 @@ ---- before/net/minecraft/entity/monster/EntitySlime.java -+++ after/net/minecraft/entity/monster/EntitySlime.java -@@ -142,7 +142,7 @@ - if (this.onGround && !this.wasOnGround) - { - int i = this.getSlimeSize(); -- -+ if (spawnCustomParticles()) { i = 0; } // don't spawn particles if it's handled by the implementation itself - for (int j = 0; j < i * 8; j++) - { - float f = this.rand.nextFloat() * (float)(Math.PI * 2); -@@ -323,7 +323,7 @@ - BlockPos blockpos = new BlockPos(MathHelper.floor(this.posX), 0, MathHelper.floor(this.posZ)); - Chunk chunk = this.world.getChunk(blockpos); - -- if (this.world.getWorldInfo().getTerrainType() == WorldType.FLAT && this.rand.nextInt(4) != 1) -+ if (this.world.getWorldInfo().getTerrainType().handleSlimeSpawnReduction(rand, world)) - { - return false; - } -@@ -375,6 +375,7 @@ - { - this.motionY = 0.42F; - this.isAirBorne = true; -+ net.minecraftforge.common.ForgeHooks.onLivingJump(this); - } - - @Nullable -@@ -397,6 +398,14 @@ - { - return this.isSmallSlime() ? SoundEvents.ENTITY_SMALL_SLIME_JUMP : SoundEvents.ENTITY_SLIME_JUMP; - } -+ -+ /* ======================================== FORGE START =====================================*/ -+ /** -+ * Called when the slime spawns particles on landing, see onUpdate. -+ * Return true to prevent the spawning of the default particles. -+ */ -+ protected boolean spawnCustomParticles() { return false; } -+ /* ======================================== FORGE END =====================================*/ - - static class AISlimeAttack extends EntityAIBase - { diff --git a/patches/minecraft/net/minecraft/entity/monster/EntitySnowman.java.patch b/patches/minecraft/net/minecraft/entity/monster/EntitySnowman.java.patch deleted file mode 100644 index f0aab8b4a..000000000 --- a/patches/minecraft/net/minecraft/entity/monster/EntitySnowman.java.patch +++ /dev/null @@ -1,49 +0,0 @@ ---- before/net/minecraft/entity/monster/EntitySnowman.java -+++ after/net/minecraft/entity/monster/EntitySnowman.java -@@ -31,7 +31,7 @@ - import net.minecraft.world.World; - import net.minecraft.world.storage.loot.LootTableList; - --public class EntitySnowman extends EntityGolem implements IRangedAttackMob -+public class EntitySnowman extends EntityGolem implements IRangedAttackMob, net.minecraftforge.common.IShearable - { - private static final DataParameter PUMPKIN_EQUIPPED = EntityDataManager.createKey(EntitySnowman.class, DataSerializers.BYTE); - -@@ -110,7 +110,7 @@ - this.attackEntityFrom(DamageSource.ON_FIRE, 1.0F); - } - -- if (!this.world.getGameRules().getBoolean("mobGriefing")) -+ if (!net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.world, this)) - { - return; - } -@@ -164,7 +164,7 @@ - { - ItemStack itemstack = player.getHeldItem(hand); - -- if (itemstack.getItem() == Items.SHEARS && this.isPumpkinEquipped() && !this.world.isRemote) -+ if (false && itemstack.getItem() == Items.SHEARS && this.isPumpkinEquipped() && !this.world.isRemote) //Forge: Moved to onSheared - { - this.setPumpkinEquipped(false); - itemstack.damageItem(1, player); -@@ -211,6 +211,19 @@ - protected SoundEvent getDeathSound() - { - return SoundEvents.ENTITY_SNOWMAN_DEATH; -+ } -+ -+ @Override -+ public boolean isShearable(ItemStack item, net.minecraft.world.IBlockAccess world, BlockPos pos) -+ { -+ return this.isPumpkinEquipped(); -+ } -+ -+ @Override -+ public java.util.List onSheared(ItemStack item, net.minecraft.world.IBlockAccess world, BlockPos pos, int fortune) -+ { -+ this.setPumpkinEquipped(false); -+ return com.google.common.collect.Lists.newArrayList(); - } - - @Override diff --git a/patches/minecraft/net/minecraft/entity/monster/EntitySpider.java.patch b/patches/minecraft/net/minecraft/entity/monster/EntitySpider.java.patch deleted file mode 100644 index 1f8ff48ea..000000000 --- a/patches/minecraft/net/minecraft/entity/monster/EntitySpider.java.patch +++ /dev/null @@ -1,17 +0,0 @@ ---- before/net/minecraft/entity/monster/EntitySpider.java -+++ after/net/minecraft/entity/monster/EntitySpider.java -@@ -154,7 +154,13 @@ - @Override - public boolean isPotionApplicable(PotionEffect potioneffectIn) - { -- return potioneffectIn.getPotion() == MobEffects.POISON ? false : super.isPotionApplicable(potioneffectIn); -+ if(potioneffectIn.getPotion() == MobEffects.POISON) -+ { -+ net.minecraftforge.event.entity.living.PotionEvent.PotionApplicableEvent event = new net.minecraftforge.event.entity.living.PotionEvent.PotionApplicableEvent(this, potioneffectIn); -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event); -+ return event.getResult() == net.minecraftforge.fml.common.eventhandler.Event.Result.ALLOW; -+ } -+ return super.isPotionApplicable(potioneffectIn); - } - - public boolean isBesideClimbableBlock() diff --git a/patches/minecraft/net/minecraft/entity/monster/EntityZombie.java.patch b/patches/minecraft/net/minecraft/entity/monster/EntityZombie.java.patch deleted file mode 100644 index b4fa8113c..000000000 --- a/patches/minecraft/net/minecraft/entity/monster/EntityZombie.java.patch +++ /dev/null @@ -1,75 +0,0 @@ ---- before/net/minecraft/entity/monster/EntityZombie.java -+++ after/net/minecraft/entity/monster/EntityZombie.java -@@ -101,7 +101,7 @@ - this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.23F); - this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(3.0); - this.getEntityAttribute(SharedMonsterAttributes.ARMOR).setBaseValue(2.0); -- this.getAttributeMap().registerAttribute(SPAWN_REINFORCEMENTS_CHANCE).setBaseValue(this.rand.nextDouble() * 0.1F); -+ this.getAttributeMap().registerAttribute(SPAWN_REINFORCEMENTS_CHANCE).setBaseValue(this.rand.nextDouble() * net.minecraftforge.common.ForgeModContainer.zombieSummonBaseChance); - } - - @Override -@@ -250,15 +250,31 @@ - entitylivingbase = (EntityLivingBase)source.getTrueSource(); - } - -- if (entitylivingbase != null -+ int i = MathHelper.floor(this.posX); -+ int j = MathHelper.floor(this.posY); -+ int k = MathHelper.floor(this.posZ); -+ net.minecraftforge.event.entity.living.ZombieEvent.SummonAidEvent summonAid -+ = net.minecraftforge.event.ForgeEventFactory.fireZombieSummonAid( -+ this, world, i, j, k, entitylivingbase, this.getEntityAttribute(SPAWN_REINFORCEMENTS_CHANCE).getAttributeValue() -+ ); -+ if (summonAid.getResult() == net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) return true; -+ -+ if (summonAid.getResult() == net.minecraftforge.fml.common.eventhandler.Event.Result.ALLOW -+ || entitylivingbase != null - && this.world.getDifficulty() == EnumDifficulty.HARD - && this.rand.nextFloat() < this.getEntityAttribute(SPAWN_REINFORCEMENTS_CHANCE).getAttributeValue() - && this.world.getGameRules().getBoolean("doMobSpawning")) - { -- int i = MathHelper.floor(this.posX); -- int j = MathHelper.floor(this.posY); -- int k = MathHelper.floor(this.posZ); -- EntityZombie entityzombie = new EntityZombie(this.world); -+ EntityZombie entityzombie; -+ if (summonAid.getCustomSummonedAid() != null -+ && summonAid.getResult() == net.minecraftforge.fml.common.eventhandler.Event.Result.ALLOW) -+ { -+ entityzombie = summonAid.getCustomSummonedAid(); -+ } -+ else -+ { -+ entityzombie = new EntityZombie(this.world); -+ } - - for (int l = 0; l < 50; l++) - { -@@ -266,7 +282,7 @@ - int j1 = j + MathHelper.getInt(this.rand, 7, 40) * MathHelper.getInt(this.rand, -1, 1); - int k1 = k + MathHelper.getInt(this.rand, 7, 40) * MathHelper.getInt(this.rand, -1, 1); - -- if (this.world.getBlockState(new BlockPos(i1, j1 - 1, k1)).isTopSolid() -+ if (this.world.getBlockState(new BlockPos(i1, j1 - 1, k1)).isSideSolid(this.world, new BlockPos(i1, j1 - 1, k1), net.minecraft.util.EnumFacing.UP) - && this.world.getLightFromNeighbors(new BlockPos(i1, j1, k1)) < 10) - { - entityzombie.setPosition(i1, j1, k1); -@@ -277,7 +293,7 @@ - && !this.world.containsAnyLiquid(entityzombie.getEntityBoundingBox())) - { - this.world.spawnEntity(entityzombie); -- entityzombie.setAttackTarget(entitylivingbase); -+ if (entitylivingbase != null) entityzombie.setAttackTarget(entitylivingbase); - entityzombie.onInitialSpawn(this.world.getDifficultyForLocation(new BlockPos(entityzombie)), null); - this.getEntityAttribute(SPAWN_REINFORCEMENTS_CHANCE).applyModifier(new AttributeModifier("Zombie reinforcement caller charge", -0.05F, 0)); - entityzombie.getEntityAttribute(SPAWN_REINFORCEMENTS_CHANCE).applyModifier(new AttributeModifier("Zombie reinforcement callee charge", -0.05F, 0)); -@@ -468,7 +484,7 @@ - - if (livingdata == null) - { -- livingdata = new EntityZombie.GroupData(this.world.rand.nextFloat() < 0.05F); -+ livingdata = new EntityZombie.GroupData(this.world.rand.nextFloat() < net.minecraftforge.common.ForgeModContainer.zombieBabyChance); - } - - if (livingdata instanceof EntityZombie.GroupData) diff --git a/patches/minecraft/net/minecraft/entity/monster/EntityZombieVillager.java.patch b/patches/minecraft/net/minecraft/entity/monster/EntityZombieVillager.java.patch deleted file mode 100644 index 9775a8c82..000000000 --- a/patches/minecraft/net/minecraft/entity/monster/EntityZombieVillager.java.patch +++ /dev/null @@ -1,95 +0,0 @@ ---- before/net/minecraft/entity/monster/EntityZombieVillager.java -+++ after/net/minecraft/entity/monster/EntityZombieVillager.java -@@ -54,11 +54,14 @@ - public void setProfession(int profession) - { - this.dataManager.set(PROFESSION, profession); -+ net.minecraftforge.fml.common.registry.VillagerRegistry.onSetProfession(this, profession); - } - -+ //Use Forge Variant below -+ @Deprecated - public int getProfession() - { -- return Math.max(this.dataManager.get(PROFESSION) % 6, 0); -+ return Math.max(this.dataManager.get(PROFESSION), 0); - } - - public static void registerFixesZombieVillager(DataFixer fixer) -@@ -71,6 +74,7 @@ - { - super.writeEntityToNBT(compound); - compound.setInteger("Profession", this.getProfession()); -+ compound.setString("ProfessionName", this.getForgeProfession().getRegistryName().toString()); - compound.setInteger("ConversionTime", this.isConverting() ? this.conversionTime : -1); - - if (this.converstionStarter != null) -@@ -84,6 +88,12 @@ - { - super.readEntityFromNBT(compound); - this.setProfession(compound.getInteger("Profession")); -+ if (compound.hasKey("ProfessionName")) -+ { -+ net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession p = net.minecraftforge.fml.common.registry.ForgeRegistries.VILLAGER_PROFESSIONS.getValue(new net.minecraft.util.ResourceLocation(compound.getString("ProfessionName"))); -+ if (p == null) p = net.minecraftforge.fml.common.registry.VillagerRegistry.FARMER; -+ this.setForgeProfession(p); -+ } - - if (compound.hasKey("ConversionTime", 99) && compound.getInteger("ConversionTime") > -1) - { -@@ -97,7 +107,7 @@ - @Override - public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, @Nullable IEntityLivingData livingdata) - { -- this.setProfession(this.world.rand.nextInt(6)); -+ net.minecraftforge.fml.common.registry.VillagerRegistry.setRandomProfession(this, this.world.rand); - return super.onInitialSpawn(difficulty, livingdata); - } - -@@ -195,7 +205,7 @@ - { - EntityVillager entityvillager = new EntityVillager(this.world); - entityvillager.copyLocationAndAnglesFrom(this); -- entityvillager.setProfession(this.getProfession()); -+ entityvillager.setProfession(this.getForgeProfession()); - entityvillager.finalizeMobSpawn(this.world.getDifficultyForLocation(new BlockPos(entityvillager)), null, false); - entityvillager.setLookingForHome(); - -@@ -307,4 +317,37 @@ - { - return ItemStack.EMPTY; - } -+ -+ /* ======================================== FORGE START =====================================*/ -+ -+ @Nullable -+ private net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession prof; -+ public void setForgeProfession(net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession prof) -+ { -+ this.prof = prof; -+ this.setProfession(net.minecraftforge.fml.common.registry.VillagerRegistry.getId(prof)); -+ } -+ -+ public net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession getForgeProfession() -+ { -+ if (this.prof == null) -+ { -+ this.prof = net.minecraftforge.fml.common.registry.VillagerRegistry.getById(this.getProfession()); -+ if (this.prof == null) -+ return net.minecraftforge.fml.common.registry.VillagerRegistry.FARMER; -+ } -+ return this.prof; -+ } -+ -+ @Override -+ public void notifyDataManagerChange(DataParameter key) -+ { -+ super.notifyDataManagerChange(key); -+ if (key.equals(PROFESSION)) -+ { -+ net.minecraftforge.fml.common.registry.VillagerRegistry.onSetProfession(this, this.dataManager.get(PROFESSION)); -+ } -+ } -+ -+ /* ======================================== FORGE END =====================================*/ - } diff --git a/patches/minecraft/net/minecraft/entity/passive/AbstractHorse.java.patch b/patches/minecraft/net/minecraft/entity/passive/AbstractHorse.java.patch deleted file mode 100644 index 0af3f23fb..000000000 --- a/patches/minecraft/net/minecraft/entity/passive/AbstractHorse.java.patch +++ /dev/null @@ -1,34 +0,0 @@ ---- before/net/minecraft/entity/passive/AbstractHorse.java -+++ after/net/minecraft/entity/passive/AbstractHorse.java -@@ -343,6 +343,7 @@ - - this.horseChest.addInventoryChangeListener(this); - this.updateHorseSlots(); -+ this.itemHandler = new net.minecraftforge.items.wrapper.InvWrapper(this.horseChest); - } - - protected void updateHorseSlots() -@@ -1331,5 +1332,23 @@ - } - - return livingdata; -+ } -+ -+ // FORGE -+ private net.minecraftforge.items.IItemHandler itemHandler = null; // Initialized by initHorseChest above. -+ -+ @SuppressWarnings("unchecked") -+ @Override -+ @Nullable -+ public T getCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable net.minecraft.util.EnumFacing facing) -+ { -+ if (capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return (T) itemHandler; -+ return super.getCapability(capability, facing); -+ } -+ -+ @Override -+ public boolean hasCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable net.minecraft.util.EnumFacing facing) -+ { -+ return capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY || super.hasCapability(capability, facing); - } - } diff --git a/patches/minecraft/net/minecraft/entity/passive/EntityHorse.java.patch b/patches/minecraft/net/minecraft/entity/passive/EntityHorse.java.patch deleted file mode 100644 index 9975f1ecb..000000000 --- a/patches/minecraft/net/minecraft/entity/passive/EntityHorse.java.patch +++ /dev/null @@ -1,80 +0,0 @@ ---- before/net/minecraft/entity/passive/EntityHorse.java -+++ after/net/minecraft/entity/passive/EntityHorse.java -@@ -34,6 +34,7 @@ - private static final UUID ARMOR_MODIFIER_UUID = UUID.fromString("556E1665-8B10-40C8-8F9D-CF9B1667F295"); - private static final DataParameter HORSE_VARIANT = EntityDataManager.createKey(EntityHorse.class, DataSerializers.VARINT); - private static final DataParameter HORSE_ARMOR = EntityDataManager.createKey(EntityHorse.class, DataSerializers.VARINT); -+ private static final DataParameter HORSE_ARMOR_STACK = EntityDataManager.createKey(EntityHorse.class, DataSerializers.ITEM_STACK); - private static final String[] HORSE_TEXTURES = new String[] - { - "textures/entity/horse/horse_white.png", -@@ -68,6 +69,7 @@ - super.entityInit(); - this.dataManager.register(HORSE_VARIANT, 0); - this.dataManager.register(HORSE_ARMOR, HorseArmorType.NONE.getOrdinal()); -+ this.dataManager.register(HORSE_ARMOR_STACK, ItemStack.EMPTY); - } - - public static void registerFixesHorse(DataFixer fixer) -@@ -98,7 +100,7 @@ - { - ItemStack itemstack = new ItemStack(compound.getCompoundTag("ArmorItem")); - -- if (!itemstack.isEmpty() && HorseArmorType.isHorseArmor(itemstack.getItem())) -+ if (!itemstack.isEmpty() && isArmor(itemstack)) - { - this.horseChest.setInventorySlotContents(1, itemstack); - } -@@ -129,11 +131,12 @@ - int i = this.getHorseVariant(); - int j = (i & 0xFF) % 7; - int k = ((i & 0xFF00) >> 8) % 5; -- HorseArmorType horsearmortype = this.getHorseArmorType(); -+ ItemStack armorStack = this.dataManager.get(HORSE_ARMOR_STACK); -+ String texture = !armorStack.isEmpty() ? armorStack.getItem().getHorseArmorTexture(this, armorStack) : HorseArmorType.getByOrdinal(this.dataManager.get(HORSE_ARMOR)).getTextureName(); //If armorStack is empty, the server is vanilla so the texture should be determined the vanilla way - this.horseTexturesArray[0] = HORSE_TEXTURES[j]; - this.horseTexturesArray[1] = HORSE_MARKING_TEXTURES[k]; -- this.horseTexturesArray[2] = horsearmortype.getTextureName(); -- this.texturePrefix = "horse/" + HORSE_TEXTURES_ABBR[j] + HORSE_MARKING_TEXTURES_ABBR[k] + horsearmortype.getHash(); -+ this.horseTexturesArray[2] = texture; -+ this.texturePrefix = "horse/" + HORSE_TEXTURES_ABBR[j] + HORSE_MARKING_TEXTURES_ABBR[k] + texture; - } - - @SideOnly(Side.CLIENT) -@@ -169,6 +172,7 @@ - { - HorseArmorType horsearmortype = HorseArmorType.getByItemStack(itemStackIn); - this.dataManager.set(HORSE_ARMOR, horsearmortype.getOrdinal()); -+ this.dataManager.set(HORSE_ARMOR_STACK, itemStackIn); - this.resetTexturePrefix(); - - if (!this.world.isRemote) -@@ -186,7 +190,9 @@ - - public HorseArmorType getHorseArmorType() - { -- return HorseArmorType.getByOrdinal(this.dataManager.get(HORSE_ARMOR)); -+ HorseArmorType armor = HorseArmorType.getByItemStack(this.dataManager.get(HORSE_ARMOR_STACK)); //First check the Forge armor DataParameter -+ if (armor == HorseArmorType.NONE) armor = HorseArmorType.getByOrdinal(this.dataManager.get(HORSE_ARMOR)); //If the Forge armor DataParameter returns NONE, fallback to the vanilla armor DataParameter. This is necessary to prevent issues with Forge clients connected to vanilla servers. -+ return armor; - } - - @Override -@@ -232,6 +238,8 @@ - this.dataManager.setClean(); - this.resetTexturePrefix(); - } -+ ItemStack armor = this.horseChest.getStackInSlot(1); -+ if (isArmor(armor)) armor.getItem().onHorseArmorTick(world, this, armor); - } - - @Override -@@ -414,7 +422,7 @@ - @Override - public boolean isArmor(ItemStack stack) - { -- return HorseArmorType.isHorseArmor(stack.getItem()); -+ return HorseArmorType.isHorseArmor(stack); - } - - @Nullable diff --git a/patches/minecraft/net/minecraft/entity/passive/EntityLlama.java.patch b/patches/minecraft/net/minecraft/entity/passive/EntityLlama.java.patch deleted file mode 100644 index 8ef6a7f74..000000000 --- a/patches/minecraft/net/minecraft/entity/passive/EntityLlama.java.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- before/net/minecraft/entity/passive/EntityLlama.java -+++ after/net/minecraft/entity/passive/EntityLlama.java -@@ -486,6 +486,9 @@ - @Override - public void fall(float distance, float damageMultiplier) - { -+ float[] ret = net.minecraftforge.common.ForgeHooks.onLivingFall(this, distance, damageMultiplier); -+ if (ret == null) return; -+ distance = ret[0]; damageMultiplier = ret[1]; - int i = MathHelper.ceil((distance * 0.5F - 3.0F) * damageMultiplier); - - if (i > 0) diff --git a/patches/minecraft/net/minecraft/entity/passive/EntityMooshroom.java.patch b/patches/minecraft/net/minecraft/entity/passive/EntityMooshroom.java.patch deleted file mode 100644 index b0bc72e74..000000000 --- a/patches/minecraft/net/minecraft/entity/passive/EntityMooshroom.java.patch +++ /dev/null @@ -1,56 +0,0 @@ ---- before/net/minecraft/entity/passive/EntityMooshroom.java -+++ after/net/minecraft/entity/passive/EntityMooshroom.java -@@ -16,7 +16,7 @@ - import net.minecraft.world.World; - import net.minecraft.world.storage.loot.LootTableList; - --public class EntityMooshroom extends EntityCow -+public class EntityMooshroom extends EntityCow implements net.minecraftforge.common.IShearable - { - public EntityMooshroom(World worldIn) - { -@@ -50,7 +50,7 @@ - - return true; - } -- else if (itemstack.getItem() == Items.SHEARS && this.getGrowingAge() >= 0) -+ else if (false && itemstack.getItem() == Items.SHEARS && this.getGrowingAge() >= 0) //Forge Disable, Moved to onSheared - { - this.setDead(); - this.world -@@ -101,6 +101,35 @@ - public EntityMooshroom createChild(EntityAgeable ageable) - { - return new EntityMooshroom(this.world); -+ } -+ -+ @Override public boolean isShearable(ItemStack item, net.minecraft.world.IBlockAccess world, net.minecraft.util.math.BlockPos pos){ return getGrowingAge() >= 0; } -+ @Override -+ public java.util.List onSheared(ItemStack item, net.minecraft.world.IBlockAccess world, net.minecraft.util.math.BlockPos pos, int fortune) -+ { -+ this.setDead(); -+ ((net.minecraft.world.WorldServer)this.world).spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, false, this.posX, this.posY + (double)(this.height / 2.0F), this.posZ, 1, 0.0D, 0.0D, 0.0D, 0.0D); -+ -+ EntityCow entitycow = new EntityCow(this.world); -+ entitycow.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, this.rotationPitch); -+ entitycow.setHealth(this.getHealth()); -+ entitycow.renderYawOffset = this.renderYawOffset; -+ -+ if (this.hasCustomName()) -+ { -+ entitycow.setCustomNameTag(this.getCustomNameTag()); -+ } -+ -+ this.world.spawnEntity(entitycow); -+ -+ java.util.List ret = new java.util.ArrayList(); -+ for (int i = 0; i < 5; ++i) -+ { -+ ret.add(new ItemStack(Blocks.RED_MUSHROOM)); -+ } -+ -+ this.playSound(SoundEvents.ENTITY_MOOSHROOM_SHEAR, 1.0F, 1.0F); -+ return ret; - } - - @Nullable diff --git a/patches/minecraft/net/minecraft/entity/passive/EntityOcelot.java.patch b/patches/minecraft/net/minecraft/entity/passive/EntityOcelot.java.patch deleted file mode 100644 index 503848ce2..000000000 --- a/patches/minecraft/net/minecraft/entity/passive/EntityOcelot.java.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- before/net/minecraft/entity/passive/EntityOcelot.java -+++ after/net/minecraft/entity/passive/EntityOcelot.java -@@ -239,7 +239,7 @@ - - if (!this.world.isRemote) - { -- if (this.rand.nextInt(3) == 0) -+ if (this.rand.nextInt(3) == 0 && !net.minecraftforge.event.ForgeEventFactory.onAnimalTame(this, player)) - { - this.setTamedBy(player); - this.setTameSkin(1 + this.world.rand.nextInt(3)); -@@ -335,7 +335,7 @@ - IBlockState iblockstate = this.world.getBlockState(blockpos.down()); - Block block = iblockstate.getBlock(); - -- if (block == Blocks.GRASS || iblockstate.getMaterial() == Material.LEAVES) -+ if (block == Blocks.GRASS || block.isLeaves(iblockstate, this.world, blockpos.down())) - { - return true; - } diff --git a/patches/minecraft/net/minecraft/entity/passive/EntityParrot.java.patch b/patches/minecraft/net/minecraft/entity/passive/EntityParrot.java.patch deleted file mode 100644 index 1cf5dcb64..000000000 --- a/patches/minecraft/net/minecraft/entity/passive/EntityParrot.java.patch +++ /dev/null @@ -1,134 +0,0 @@ ---- before/net/minecraft/entity/passive/EntityParrot.java -+++ after/net/minecraft/entity/passive/EntityParrot.java -@@ -1,6 +1,7 @@ - package net.minecraft.entity.passive; - - import com.google.common.base.Predicate; -+import com.google.common.collect.Maps; - import com.google.common.collect.Sets; - import it.unimi.dsi.fastutil.ints.Int2ObjectMap; - import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; -@@ -90,12 +91,12 @@ - public boolean apply(@Nullable EntityLiving p_apply_1_) - { - return p_apply_1_ != null -- && EntityParrot.IMITATION_SOUND_EVENTS.containsKey(EntityList.REGISTRY.getIDForObject((Class )p_apply_1_.getClass())); -+ && EntityParrot.MIMIC_SOUNDS.containsKey(p_apply_1_.getClass()); - } - }; - private static final Item DEADLY_ITEM = Items.COOKIE; - private static final Set TAME_ITEMS = Sets.newHashSet(Items.WHEAT_SEEDS, Items.MELON_SEEDS, Items.PUMPKIN_SEEDS, Items.BEETROOT_SEEDS); -- private static final Int2ObjectMap IMITATION_SOUND_EVENTS = new Int2ObjectOpenHashMap<>(32); -+ private static final java.util.Map, SoundEvent> MIMIC_SOUNDS = Maps.newHashMapWithExpectedSize(32); - public float flap; - public float flapSpeed; - public float oFlapSpeed; -@@ -224,7 +225,7 @@ - - if (!entityliving.isSilent()) - { -- SoundEvent soundevent = getImitatedSound(EntityList.REGISTRY.getIDForObject((Class )entityliving.getClass())); -+ SoundEvent soundevent = MIMIC_SOUNDS.get(entityliving.getClass()); - worldIn.playSound( - null, - parrotIn.posX, -@@ -276,7 +277,7 @@ - - if (!this.world.isRemote) - { -- if (this.rand.nextInt(10) == 0) -+ if (this.rand.nextInt(10) == 0 && !net.minecraftforge.event.ForgeEventFactory.onAnimalTame(this, player)) - { - this.setTamedBy(player); - this.playTameEffect(true); -@@ -395,8 +396,9 @@ - { - if (random.nextInt(1000) == 0) - { -- List list = new ArrayList<>(IMITATION_SOUND_EVENTS.keySet()); -- return getImitatedSound(list.get(random.nextInt(list.size()))); -+ List list = new ArrayList(MIMIC_SOUNDS.values()); -+ SoundEvent ret = list.get(random.nextInt(list.size())); -+ return ret == null ? SoundEvents.ENTITY_PARROT_AMBIENT : ret; - } - else - { -@@ -404,11 +406,6 @@ - } - } - -- public static SoundEvent getImitatedSound(int p_191999_0_) -- { -- return IMITATION_SOUND_EVENTS.containsKey(p_191999_0_) ? IMITATION_SOUND_EVENTS.get(p_191999_0_) : SoundEvents.ENTITY_PARROT_AMBIENT; -- } -- - @Override - protected SoundEvent getHurtSound(DamageSource damageSourceIn) - { -@@ -535,33 +532,38 @@ - - static - { -- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityBlaze.class), SoundEvents.E_PARROT_IM_BLAZE); -- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityCaveSpider.class), SoundEvents.E_PARROT_IM_SPIDER); -- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityCreeper.class), SoundEvents.E_PARROT_IM_CREEPER); -- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityElderGuardian.class), SoundEvents.E_PARROT_IM_ELDER_GUARDIAN); -- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityDragon.class), SoundEvents.E_PARROT_IM_ENDERDRAGON); -- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityEnderman.class), SoundEvents.E_PARROT_IM_ENDERMAN); -- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityEndermite.class), SoundEvents.E_PARROT_IM_ENDERMITE); -- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityEvoker.class), SoundEvents.E_PARROT_IM_EVOCATION_ILLAGER); -- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityGhast.class), SoundEvents.E_PARROT_IM_GHAST); -- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityHusk.class), SoundEvents.E_PARROT_IM_HUSK); -- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityIllusionIllager.class), SoundEvents.E_PARROT_IM_ILLUSION_ILLAGER); -- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityMagmaCube.class), SoundEvents.E_PARROT_IM_MAGMACUBE); -- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityPigZombie.class), SoundEvents.E_PARROT_IM_ZOMBIE_PIGMAN); -- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityPolarBear.class), SoundEvents.E_PARROT_IM_POLAR_BEAR); -- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityShulker.class), SoundEvents.E_PARROT_IM_SHULKER); -- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntitySilverfish.class), SoundEvents.E_PARROT_IM_SILVERFISH); -- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntitySkeleton.class), SoundEvents.E_PARROT_IM_SKELETON); -- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntitySlime.class), SoundEvents.E_PARROT_IM_SLIME); -- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntitySpider.class), SoundEvents.E_PARROT_IM_SPIDER); -- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityStray.class), SoundEvents.E_PARROT_IM_STRAY); -- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityVex.class), SoundEvents.E_PARROT_IM_VEX); -- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityVindicator.class), SoundEvents.E_PARROT_IM_VINDICATION_ILLAGER); -- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityWitch.class), SoundEvents.E_PARROT_IM_WITCH); -- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityWither.class), SoundEvents.E_PARROT_IM_WITHER); -- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityWitherSkeleton.class), SoundEvents.E_PARROT_IM_WITHER_SKELETON); -- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityWolf.class), SoundEvents.E_PARROT_IM_WOLF); -- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityZombie.class), SoundEvents.E_PARROT_IM_ZOMBIE); -- IMITATION_SOUND_EVENTS.put(EntityList.REGISTRY.getIDForObject(EntityZombieVillager.class), SoundEvents.E_PARROT_IM_ZOMBIE_VILLAGER); -+ registerMimicSound(EntityBlaze.class, SoundEvents.E_PARROT_IM_BLAZE); -+ registerMimicSound(EntityCaveSpider.class, SoundEvents.E_PARROT_IM_SPIDER); -+ registerMimicSound(EntityCreeper.class, SoundEvents.E_PARROT_IM_CREEPER); -+ registerMimicSound(EntityElderGuardian.class, SoundEvents.E_PARROT_IM_ELDER_GUARDIAN); -+ registerMimicSound(EntityDragon.class, SoundEvents.E_PARROT_IM_ENDERDRAGON); -+ registerMimicSound(EntityEnderman.class, SoundEvents.E_PARROT_IM_ENDERMAN); -+ registerMimicSound(EntityEndermite.class, SoundEvents.E_PARROT_IM_ENDERMITE); -+ registerMimicSound(EntityEvoker.class, SoundEvents.E_PARROT_IM_EVOCATION_ILLAGER); -+ registerMimicSound(EntityGhast.class, SoundEvents.E_PARROT_IM_GHAST); -+ registerMimicSound(EntityHusk.class, SoundEvents.E_PARROT_IM_HUSK); -+ registerMimicSound(EntityIllusionIllager.class, SoundEvents.E_PARROT_IM_ILLUSION_ILLAGER); -+ registerMimicSound(EntityMagmaCube.class, SoundEvents.E_PARROT_IM_MAGMACUBE); -+ registerMimicSound(EntityPigZombie.class, SoundEvents.E_PARROT_IM_ZOMBIE_PIGMAN); -+ registerMimicSound(EntityPolarBear.class, SoundEvents.E_PARROT_IM_POLAR_BEAR); -+ registerMimicSound(EntityShulker.class, SoundEvents.E_PARROT_IM_SHULKER); -+ registerMimicSound(EntitySilverfish.class, SoundEvents.E_PARROT_IM_SILVERFISH); -+ registerMimicSound(EntitySkeleton.class, SoundEvents.E_PARROT_IM_SKELETON); -+ registerMimicSound(EntitySlime.class, SoundEvents.E_PARROT_IM_SLIME); -+ registerMimicSound(EntitySpider.class, SoundEvents.E_PARROT_IM_SPIDER); -+ registerMimicSound(EntityStray.class, SoundEvents.E_PARROT_IM_STRAY); -+ registerMimicSound(EntityVex.class, SoundEvents.E_PARROT_IM_VEX); -+ registerMimicSound(EntityVindicator.class, SoundEvents.E_PARROT_IM_VINDICATION_ILLAGER); -+ registerMimicSound(EntityWitch.class, SoundEvents.E_PARROT_IM_WITCH); -+ registerMimicSound(EntityWither.class, SoundEvents.E_PARROT_IM_WITHER); -+ registerMimicSound(EntityWitherSkeleton.class, SoundEvents.E_PARROT_IM_WITHER_SKELETON); -+ registerMimicSound(EntityWolf.class, SoundEvents.E_PARROT_IM_WOLF); -+ registerMimicSound(EntityZombie.class, SoundEvents.E_PARROT_IM_ZOMBIE); -+ registerMimicSound(EntityZombieVillager.class, SoundEvents.E_PARROT_IM_ZOMBIE_VILLAGER); -+ } -+ -+ public static void registerMimicSound(Class cls, SoundEvent sound) -+ { -+ MIMIC_SOUNDS.put(cls, sound); - } - } diff --git a/patches/minecraft/net/minecraft/entity/passive/EntityRabbit.java.patch b/patches/minecraft/net/minecraft/entity/passive/EntityRabbit.java.patch deleted file mode 100644 index 67c4a7d30..000000000 --- a/patches/minecraft/net/minecraft/entity/passive/EntityRabbit.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/entity/passive/EntityRabbit.java -+++ after/net/minecraft/entity/passive/EntityRabbit.java -@@ -592,7 +592,7 @@ - { - if (this.runDelay <= 0) - { -- if (!this.rabbit.world.getGameRules().getBoolean("mobGriefing")) -+ if (!net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.rabbit.world, this.rabbit)) - { - return false; - } diff --git a/patches/minecraft/net/minecraft/entity/passive/EntitySheep.java.patch b/patches/minecraft/net/minecraft/entity/passive/EntitySheep.java.patch deleted file mode 100644 index f7267bf81..000000000 --- a/patches/minecraft/net/minecraft/entity/passive/EntitySheep.java.patch +++ /dev/null @@ -1,47 +0,0 @@ ---- before/net/minecraft/entity/passive/EntitySheep.java -+++ after/net/minecraft/entity/passive/EntitySheep.java -@@ -46,7 +46,7 @@ - import net.minecraftforge.fml.relauncher.Side; - import net.minecraftforge.fml.relauncher.SideOnly; - --public class EntitySheep extends EntityAnimal -+public class EntitySheep extends EntityAnimal implements net.minecraftforge.common.IShearable - { - private static final DataParameter DYE_COLOR = EntityDataManager.createKey(EntitySheep.class, DataSerializers.BYTE); - private final InventoryCrafting inventoryCrafting = new InventoryCrafting(new Container() -@@ -229,7 +229,7 @@ - { - ItemStack itemstack = player.getHeldItem(hand); - -- if (itemstack.getItem() == Items.SHEARS && !this.getSheared() && !this.isChild()) -+ if (false && itemstack.getItem() == Items.SHEARS && !this.getSheared() && !this.isChild()) //Forge: Moved to onSheared - { - if (!this.world.isRemote) - { -@@ -381,6 +381,26 @@ - livingdata = super.onInitialSpawn(difficulty, livingdata); - this.setFleeceColor(getRandomSheepColor(this.world.rand)); - return livingdata; -+ } -+ -+ @Override -+ public boolean isShearable(ItemStack item, net.minecraft.world.IBlockAccess world, BlockPos pos) -+ { -+ return !this.getSheared() && !this.isChild(); -+ } -+ -+ @Override -+ public java.util.List onSheared(ItemStack item, net.minecraft.world.IBlockAccess world, BlockPos pos, int fortune) -+ { -+ this.setSheared(true); -+ int i = 1 + this.rand.nextInt(3); -+ -+ java.util.List ret = new java.util.ArrayList(); -+ for (int j = 0; j < i; ++j) -+ ret.add(new ItemStack(Item.getItemFromBlock(Blocks.WOOL), 1, this.getFleeceColor().getMetadata())); -+ -+ this.playSound(SoundEvents.ENTITY_SHEEP_SHEAR, 1.0F, 1.0F); -+ return ret; - } - - private EnumDyeColor getDyeColorMixFromParents(EntityAnimal father, EntityAnimal mother) diff --git a/patches/minecraft/net/minecraft/entity/passive/EntityVillager.java.patch b/patches/minecraft/net/minecraft/entity/passive/EntityVillager.java.patch deleted file mode 100644 index c5903d344..000000000 --- a/patches/minecraft/net/minecraft/entity/passive/EntityVillager.java.patch +++ /dev/null @@ -1,219 +0,0 @@ ---- before/net/minecraft/entity/passive/EntityVillager.java -+++ after/net/minecraft/entity/passive/EntityVillager.java -@@ -109,7 +109,7 @@ - private boolean needsInitilization; - private boolean isWillingToMate; - private int wealth; -- private String lastBuyingPlayer; -+ private java.util.UUID lastBuyingPlayer; - private int careerId; - private int careerLevel; - private boolean isLookingForHome; -@@ -487,7 +487,8 @@ - else if (!this.holdingSpawnEggOfClass(itemstack, (Class )this.getClass()) - && this.isEntityAlive() - && !this.isTrading() -- && !this.isChild()) -+ && !this.isChild() -+ && !player.isSneaking()) - { - if (this.buyingList == null) - { -@@ -566,6 +567,7 @@ - { - super.writeEntityToNBT(compound); - compound.setInteger("Profession", this.getProfession()); -+ compound.setString("ProfessionName", this.getProfessionForge().getRegistryName().toString()); - compound.setInteger("Riches", this.wealth); - compound.setInteger("Career", this.careerId); - compound.setInteger("CareerLevel", this.careerLevel); -@@ -596,6 +598,14 @@ - { - super.readEntityFromNBT(compound); - this.setProfession(compound.getInteger("Profession")); -+ if (compound.hasKey("ProfessionName")) -+ { -+ net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession p = -+ net.minecraftforge.fml.common.registry.ForgeRegistries.VILLAGER_PROFESSIONS.getValue(new net.minecraft.util.ResourceLocation(compound.getString("ProfessionName"))); -+ if (p == null) -+ p = net.minecraftforge.fml.common.registry.ForgeRegistries.VILLAGER_PROFESSIONS.getValue(new net.minecraft.util.ResourceLocation("minecraft:farmer")); -+ this.setProfession(p); -+ } - this.wealth = compound.getInteger("Riches"); - this.careerId = compound.getInteger("Career"); - this.careerLevel = compound.getInteger("CareerLevel"); -@@ -656,12 +666,42 @@ - - public void setProfession(int professionId) - { -- this.dataManager.set(PROFESSION, professionId); -+ this.dataManager.set(PROFESSION, Integer.valueOf(professionId)); -+ net.minecraftforge.fml.common.registry.VillagerRegistry.onSetProfession(this, professionId); - } - -+ @Deprecated //Use Forge Variant below - public int getProfession() - { -- return Math.max(this.dataManager.get(PROFESSION) % 6, 0); -+ return Math.max(((Integer)this.dataManager.get(PROFESSION)).intValue(), 0); -+ } -+ -+ private net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession prof; -+ public void setProfession(net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession prof) -+ { -+ this.prof = prof; -+ this.setProfession(net.minecraftforge.fml.common.registry.VillagerRegistry.getId(prof)); -+ } -+ -+ public net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession getProfessionForge() -+ { -+ if (this.prof == null) -+ { -+ this.prof = net.minecraftforge.fml.common.registry.VillagerRegistry.getById(this.getProfession()); -+ if (this.prof == null) -+ return net.minecraftforge.fml.common.registry.VillagerRegistry.getById(0); //Farmer -+ } -+ return this.prof; -+ } -+ -+ @Override -+ public void notifyDataManagerChange(DataParameter key) -+ { -+ super.notifyDataManagerChange(key); -+ if (key.equals(PROFESSION)) -+ { -+ net.minecraftforge.fml.common.registry.VillagerRegistry.onSetProfession(this, this.dataManager.get(PROFESSION)); -+ } - } - - public boolean isMating() -@@ -702,7 +742,7 @@ - i = -3; - } - -- this.village.modifyPlayerReputation(livingBase.getName(), i); -+ this.village.modifyPlayerReputation(livingBase.getUniqueID(), i); - - if (this.isEntityAlive()) - { -@@ -723,7 +763,7 @@ - { - if (entity instanceof EntityPlayer) - { -- this.village.modifyPlayerReputation(entity.getName(), -2); -+ this.village.modifyPlayerReputation(entity.getUniqueID(), -2); - } - else if (entity instanceof IMob) - { -@@ -820,7 +860,7 @@ - - if (this.buyingPlayer != null) - { -- this.lastBuyingPlayer = this.buyingPlayer.getName(); -+ this.lastBuyingPlayer = this.buyingPlayer.getUniqueID(); - } - else - { -@@ -865,20 +905,18 @@ - this.populateBuyingList(); - } - -- return this.buyingList; -+ return net.minecraftforge.event.ForgeEventFactory.listTradeOffers(this, player, buyingList); - } - - private void populateBuyingList() - { -- EntityVillager.ITradeList[][][] aentityvillager$itradelist = DEFAULT_TRADE_LIST_MAP[this.getProfession()]; -- - if (this.careerId != 0 && this.careerLevel != 0) - { - this.careerLevel++; - } - else - { -- this.careerId = this.rand.nextInt(aentityvillager$itradelist.length) + 1; -+ this.careerId = this.getProfessionForge().getRandomCareer(this.rand) + 1; - this.careerLevel = 1; - } - -@@ -889,19 +927,13 @@ - - int i = this.careerId - 1; - int j = this.careerLevel - 1; -+ java.util.List trades = this.getProfessionForge().getCareer(i).getTrades(j); - -- if (i >= 0 && i < aentityvillager$itradelist.length) -+ if (trades != null) - { -- EntityVillager.ITradeList[][] aentityvillager$itradelist1 = aentityvillager$itradelist[i]; -- -- if (j >= 0 && j < aentityvillager$itradelist1.length) -+ for (EntityVillager.ITradeList entityvillager$itradelist : trades) - { -- EntityVillager.ITradeList[] aentityvillager$itradelist2 = aentityvillager$itradelist1[j]; -- -- for (EntityVillager.ITradeList entityvillager$itradelist : aentityvillager$itradelist2) -- { -- entityvillager$itradelist.addMerchantRecipe(this, this.buyingList, this.rand); -- } -+ entityvillager$itradelist.addMerchantRecipe(this, this.buyingList, this.rand); - } - } - } -@@ -1015,7 +1047,7 @@ - s1 = "nitwit"; - } - -- if (s1 != null) -+ s1 = this.getProfessionForge().getCareer(this.careerId-1).getName(); - { - ITextComponent itextcomponent = new TextComponentTranslation("entity.Villager." + s1); - itextcomponent.getStyle().setHoverEvent(this.getHoverEvent()); -@@ -1028,10 +1060,6 @@ - - return itextcomponent; - } -- else -- { -- return super.getDisplayName(); -- } - } - } - -@@ -1097,7 +1125,7 @@ - - if (p_190672_3_) - { -- this.setProfession(this.world.rand.nextInt(6)); -+ net.minecraftforge.fml.common.registry.VillagerRegistry.setRandomProfession(this, this.world.rand); - } - - this.setAdditionalAItasks(); -@@ -1194,7 +1222,15 @@ - public boolean wantsMoreFood() - { - boolean flag = this.getProfession() == 0; -- return flag ? !this.hasEnoughItems(5) : !this.hasEnoughItems(1); -+ -+ if (flag) -+ { -+ return !this.hasEnoughItems(5); -+ } -+ else -+ { -+ return !this.hasEnoughItems(1); -+ } - } - - private boolean hasEnoughItems(int multiplier) -@@ -1381,6 +1417,9 @@ - recipeList.add(new MerchantRecipe(itemstack, itemstack1)); - } - } -+ //MODDERS DO NOT USE OR EDIT THIS IN ANY WAY IT WILL HAVE NO EFFECT, THIS IS JUST IN HERE TO ALLOW FORGE TO ACCESS IT -+ @Deprecated -+ public static ITradeList[][][][] GET_TRADES_DONT_USE(){ return DEFAULT_TRADE_LIST_MAP; } - - public static class ListItemForEmeralds implements EntityVillager.ITradeList - { diff --git a/patches/minecraft/net/minecraft/entity/passive/EntityWolf.java.patch b/patches/minecraft/net/minecraft/entity/passive/EntityWolf.java.patch deleted file mode 100644 index 718e09add..000000000 --- a/patches/minecraft/net/minecraft/entity/passive/EntityWolf.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/entity/passive/EntityWolf.java -+++ after/net/minecraft/entity/passive/EntityWolf.java -@@ -466,7 +466,7 @@ - - if (!this.world.isRemote) - { -- if (this.rand.nextInt(3) == 0) -+ if (this.rand.nextInt(3) == 0 && !net.minecraftforge.event.ForgeEventFactory.onAnimalTame(this, player)) - { - this.setTamedBy(player); - this.navigator.clearPath(); diff --git a/patches/minecraft/net/minecraft/entity/passive/HorseArmorType.java.patch b/patches/minecraft/net/minecraft/entity/passive/HorseArmorType.java.patch deleted file mode 100644 index 88855e569..000000000 --- a/patches/minecraft/net/minecraft/entity/passive/HorseArmorType.java.patch +++ /dev/null @@ -1,53 +0,0 @@ ---- before/net/minecraft/entity/passive/HorseArmorType.java -+++ after/net/minecraft/entity/passive/HorseArmorType.java -@@ -55,6 +55,7 @@ - return this.textureName; - } - -+ @Deprecated /**Forge: Use getByName. Ordinals of mod-added enum constants are dependent on load order, unlike names.**/ - public static HorseArmorType getByOrdinal(int ordinal) - { - return values()[ordinal]; -@@ -62,9 +63,10 @@ - - public static HorseArmorType getByItemStack(ItemStack stack) - { -- return stack.isEmpty() ? NONE : getByItem(stack.getItem()); -+ return stack.getItem().getHorseArmorType(stack); - } - -+ @Deprecated //Forge: Use getByItemStack - public static HorseArmorType getByItem(Item itemIn) - { - if (itemIn == Items.IRON_HORSE_ARMOR) -@@ -81,8 +83,30 @@ - } - } - -+ @Deprecated //Forge: Use ItemStack sensitive overload - public static boolean isHorseArmor(Item itemIn) - { - return getByItem(itemIn) != NONE; - } -+ -+ /* ======================================== FORGE START ======================================== */ -+ //Allows for textures located outside the vanilla horse armor folder -+ private HorseArmorType(String defaultTextureLocation, int armorStrengthIn) -+ { -+ this.protection = armorStrengthIn; -+ this.textureName = defaultTextureLocation; -+ this.hash = "forge"; -+ } -+ -+ public static HorseArmorType getByName(String name) -+ { -+ HorseArmorType type = HorseArmorType.valueOf(name); -+ return type != null ? type : NONE; -+ } -+ -+ public static boolean isHorseArmor(ItemStack stack) -+ { -+ return getByItemStack(stack) != NONE; -+ } -+ /* ======================================== FORGE END ======================================== */ - } diff --git a/patches/minecraft/net/minecraft/entity/player/EntityPlayer.java.patch b/patches/minecraft/net/minecraft/entity/player/EntityPlayer.java.patch deleted file mode 100644 index 75ab207eb..000000000 --- a/patches/minecraft/net/minecraft/entity/player/EntityPlayer.java.patch +++ /dev/null @@ -1,675 +0,0 @@ ---- before/net/minecraft/entity/player/EntityPlayer.java -+++ after/net/minecraft/entity/player/EntityPlayer.java -@@ -96,6 +96,12 @@ - @SuppressWarnings("incomplete-switch") - public abstract class EntityPlayer extends EntityLivingBase - { -+ public static final String PERSISTED_NBT_TAG = "PlayerPersisted"; -+ protected java.util.HashMap spawnChunkMap = new java.util.HashMap<>(); -+ protected java.util.HashMap spawnForcedMap = new java.util.HashMap<>(); -+ public float eyeHeight = this.getDefaultEyeHeight(); -+ public static final net.minecraft.entity.ai.attributes.IAttribute REACH_DISTANCE = new net.minecraft.entity.ai.attributes.RangedAttribute(null, "generic.reachDistance", 5.0D, 0.0D, 1024.0D).setShouldWatch(true); -+ - private static final DataParameter ABSORPTION = EntityDataManager.createKey(EntityPlayer.class, DataSerializers.FLOAT); - private static final DataParameter PLAYER_SCORE = EntityDataManager.createKey(EntityPlayer.class, DataSerializers.VARINT); - protected static final DataParameter PLAYER_MODEL_FLAG = EntityDataManager.createKey(EntityPlayer.class, DataSerializers.BYTE); -@@ -166,6 +172,7 @@ - this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.1F); - this.getAttributeMap().registerAttribute(SharedMonsterAttributes.ATTACK_SPEED); - this.getAttributeMap().registerAttribute(SharedMonsterAttributes.LUCK); -+ this.getAttributeMap().registerAttribute(REACH_DISTANCE); - } - - @Override -@@ -183,6 +190,7 @@ - @Override - public void onUpdate() - { -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().onPlayerPreTick(this); - this.noClip = this.isSpectator(); - - if (this.isSpectator()) -@@ -210,7 +218,7 @@ - { - this.wakeUpPlayer(true, true, false); - } -- else if (this.world.isDaytime()) -+ else if (!net.minecraftforge.event.ForgeEventFactory.fireSleepingTimeCheck(this, this.bedLocation)) - { - this.wakeUpPlayer(false, true, true); - } -@@ -377,6 +385,7 @@ - this.setSize(f, f1); - } - } -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().onPlayerPostTick(this); - } - - @Override -@@ -475,11 +484,11 @@ - this.cameraYaw = 0.0F; - this.addMountedMovementStat(this.posX - d0, this.posY - d1, this.posZ - d2); - -- if (this.getRidingEntity() instanceof EntityPig) -+ if (this.getRidingEntity() instanceof EntityLivingBase && ((EntityLivingBase)this.getRidingEntity()).shouldRiderFaceForward(this)) - { - this.rotationPitch = f1; - this.rotationYaw = f; -- this.renderYawOffset = ((EntityPig)this.getRidingEntity()).renderYawOffset; -+ this.renderYawOffset = ((EntityLivingBase)this.getRidingEntity()).renderYawOffset; - } - } - } -@@ -635,11 +644,15 @@ - @Override - public void onDeath(DamageSource cause) - { -+ if (net.minecraftforge.common.ForgeHooks.onLivingDeath(this, cause)) return; - super.onDeath(cause); - this.setSize(0.2F, 0.2F); - this.setPosition(this.posX, this.posY, this.posZ); - this.motionY = 0.1F; - -+ captureDrops = true; -+ capturedDrops.clear(); -+ - if ("Notch".equals(this.getName())) - { - this.dropItem(new ItemStack(Items.APPLE, 1), true, false); -@@ -651,6 +664,9 @@ - this.inventory.dropAllItems(); - } - -+ captureDrops = false; -+ if (!world.isRemote) net.minecraftforge.event.ForgeEventFactory.onPlayerDrops(this, cause, capturedDrops, recentlyHit > 0); -+ - if (cause != null) - { - this.motionX = -MathHelper.cos((this.attackedAtYaw + this.rotationYaw) * (float)(Math.PI / 180.0)) * 0.1F; -@@ -703,21 +719,24 @@ - @Nullable - public EntityItem dropItem(boolean dropAll) - { -- return this.dropItem( -- this.inventory -- .decrStackSize( -- this.inventory.currentItem, -- dropAll && !this.inventory.getCurrentItem().isEmpty() ? this.inventory.getCurrentItem().getCount() : 1 -- ), -- false, -- true -- ); -+ ItemStack stack = inventory.getCurrentItem(); -+ -+ if (stack.isEmpty()) -+ { -+ return null; -+ } -+ if (stack.getItem().onDroppedByPlayer(stack, this)) -+ { -+ int count = dropAll ? this.inventory.getCurrentItem().getCount() : 1; -+ return net.minecraftforge.common.ForgeHooks.onPlayerTossEvent(this, inventory.decrStackSize(inventory.currentItem, count), true); -+ } -+ return null; - } - - @Nullable - public EntityItem dropItem(ItemStack itemStackIn, boolean unused) - { -- return this.dropItem(itemStackIn, false, unused); -+ return net.minecraftforge.common.ForgeHooks.onPlayerTossEvent(this, itemStackIn, false); - } - - @Nullable -@@ -781,12 +800,20 @@ - - public ItemStack dropItemAndGetStack(EntityItem p_184816_1_) - { -+ if (captureDrops) capturedDrops.add(p_184816_1_); -+ else // Forge: Don't indent to keep patch smaller. - this.world.spawnEntity(p_184816_1_); - return p_184816_1_.getItem(); - } - -+ @Deprecated //Use location sensitive version below - public float getDigSpeed(IBlockState state) - { -+ return getDigSpeed(state, null); -+ } -+ -+ public float getDigSpeed(IBlockState state, BlockPos pos) -+ { - float f = this.inventory.getDestroySpeed(state); - - if (f > 1.0F) -@@ -838,12 +865,13 @@ - f /= 5.0F; - } - -- return f; -+ f = net.minecraftforge.event.ForgeEventFactory.getBreakSpeed(this, state, f, pos); -+ return (f < 0 ? 0 : f); - } - - public boolean canHarvestBlock(IBlockState state) - { -- return this.inventory.canHarvestBlock(state); -+ return net.minecraftforge.event.ForgeEventFactory.doPlayerHarvestCheck(this, state, this.inventory.canHarvestBlock(state)); - } - - public static void registerFixesPlayer(DataFixer fixer) -@@ -912,6 +940,17 @@ - this.spawnForced = compound.getBoolean("SpawnForced"); - } - -+ NBTTagList spawnlist = null; -+ spawnlist = compound.getTagList("Spawns", 10); -+ for (int i = 0; i < spawnlist.tagCount(); i++) -+ { -+ NBTTagCompound spawndata = (NBTTagCompound)spawnlist.getCompoundTagAt(i); -+ int spawndim = spawndata.getInteger("Dim"); -+ this.spawnChunkMap.put(spawndim, new BlockPos(spawndata.getInteger("SpawnX"), spawndata.getInteger("SpawnY"), spawndata.getInteger("SpawnZ"))); -+ this.spawnForcedMap.put(spawndim, spawndata.getBoolean("SpawnForced")); -+ } -+ this.spawnDimension = compound.getBoolean("HasSpawnDimensionSet") ? compound.getInteger("SpawnDimension") : null; -+ - this.foodStats.readNBT(compound); - this.capabilities.readCapabilitiesFromNBT(compound); - -@@ -946,6 +985,7 @@ - compound.setInteger("XpTotal", this.experienceTotal); - compound.setInteger("XpSeed", this.xpSeed); - compound.setInteger("Score", this.getScore()); -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().getDataFixer().writeVersionData(compound); //Moved down so it doesn't keep missing every MC update. - - if (this.spawnPos != null) - { -@@ -955,6 +995,27 @@ - compound.setBoolean("SpawnForced", this.spawnForced); - } - -+ NBTTagList spawnlist = new NBTTagList(); -+ for (java.util.Map.Entry entry : this.spawnChunkMap.entrySet()) -+ { -+ BlockPos spawn = entry.getValue(); -+ if (spawn == null) continue; -+ Boolean forced = spawnForcedMap.get(entry.getKey()); -+ if (forced == null) forced = false; -+ NBTTagCompound spawndata = new NBTTagCompound(); -+ spawndata.setInteger("Dim", entry.getKey()); -+ spawndata.setInteger("SpawnX", spawn.getX()); -+ spawndata.setInteger("SpawnY", spawn.getY()); -+ spawndata.setInteger("SpawnZ", spawn.getZ()); -+ spawndata.setBoolean("SpawnForced", forced); -+ spawnlist.appendTag(spawndata); -+ } -+ compound.setTag("Spawns", spawnlist); -+ -+ compound.setBoolean("HasSpawnDimensionSet", this.hasSpawnDimension()); -+ if (this.hasSpawnDimension()) -+ compound.setInteger("SpawnDimension", this.getSpawnDimension()); -+ - this.foodStats.writeNBT(compound); - this.capabilities.writeCapabilitiesToNBT(compound); - compound.setTag("EnderItems", this.enderChest.saveInventoryToNBT()); -@@ -973,6 +1034,7 @@ - @Override - public boolean attackEntityFrom(DamageSource source, float amount) - { -+ if (!net.minecraftforge.common.ForgeHooks.onPlayerAttack(this, source, amount)) return false; - if (this.isEntityInvulnerable(source)) - { - return false; -@@ -1026,7 +1088,7 @@ - { - super.blockUsingShield(p_190629_1_); - -- if (p_190629_1_.getHeldItemMainhand().getItem() instanceof ItemAxe) -+ if (p_190629_1_.getHeldItemMainhand().getItem().canDisableShield(p_190629_1_.getHeldItemMainhand(), this.getActiveItemStack(), this, p_190629_1_)) - { - this.disableShield(true); - } -@@ -1056,14 +1118,16 @@ - @Override - protected void damageShield(float damage) - { -- if (damage >= 3.0F && this.activeItemStack.getItem() == Items.SHIELD) -+ if (damage >= 3.0F && this.activeItemStack.getItem().isShield(this.activeItemStack, this)) - { -+ ItemStack copyBeforeUse = this.activeItemStack.copy(); - int i = 1 + MathHelper.floor(damage); - this.activeItemStack.damageItem(i, this); - - if (this.activeItemStack.isEmpty()) - { - EnumHand enumhand = this.getActiveHand(); -+ net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(this, copyBeforeUse, enumhand); - - if (enumhand == EnumHand.MAIN_HAND) - { -@@ -1100,10 +1164,14 @@ - { - if (!this.isEntityInvulnerable(damageSrc)) - { -- damageAmount = this.applyArmorCalculations(damageSrc, damageAmount); -+ damageAmount = net.minecraftforge.common.ForgeHooks.onLivingHurt(this, damageSrc, damageAmount); -+ if (damageAmount <= 0) return; -+ damageAmount = net.minecraftforge.common.ISpecialArmor.ArmorProperties.applyArmor(this, inventory.armorInventory, damageSrc, damageAmount); -+ if (damageAmount <= 0) return; - damageAmount = this.applyPotionDamageCalculations(damageSrc, damageAmount); - float f1 = Math.max(damageAmount - this.getAbsorptionAmount(), 0.0F); - this.setAbsorptionAmount(this.getAbsorptionAmount() - (damageAmount - f1)); -+ f1 = net.minecraftforge.common.ForgeHooks.onLivingDamage(this, damageSrc, f1); - - if (f1 != 0.0F) - { -@@ -1169,6 +1237,8 @@ - } - else - { -+ EnumActionResult cancelResult = net.minecraftforge.common.ForgeHooks.onInteractEntity(this, entityToInteractOn, hand); -+ if (cancelResult != null) return cancelResult; - ItemStack itemstack = this.getHeldItem(hand); - ItemStack itemstack1 = itemstack.isEmpty() ? ItemStack.EMPTY : itemstack.copy(); - -@@ -1178,7 +1248,10 @@ - { - itemstack.setCount(itemstack1.getCount()); - } -- -+ if (!this.capabilities.isCreativeMode && itemstack.isEmpty()) -+ { -+ net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(this, itemstack1, hand); -+ } - return EnumActionResult.SUCCESS; - } - else -@@ -1194,6 +1267,7 @@ - { - if (itemstack.isEmpty() && !this.capabilities.isCreativeMode) - { -+ net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(this, itemstack1, hand); - this.setHeldItem(hand, ItemStack.EMPTY); - } - -@@ -1221,6 +1295,7 @@ - - public void attackTargetEntityWithCurrentItem(Entity targetEntity) - { -+ if (!net.minecraftforge.common.ForgeHooks.onPlayerAttackTarget(this, targetEntity)) return; - if (targetEntity.canBeAttackedWithItem()) - { - if (!targetEntity.hitByEntity(this)) -@@ -1269,9 +1344,11 @@ - && targetEntity instanceof EntityLivingBase; - flag2 = flag2 && !this.isSprinting(); - -+ net.minecraftforge.event.entity.player.CriticalHitEvent hitResult = net.minecraftforge.common.ForgeHooks.getCriticalHit(this, targetEntity, flag2, flag2 ? 1.5F : 1.0F); -+ flag2 = hitResult != null; - if (flag2) - { -- f *= 1.5F; -+ f *= hitResult.getDamageModifier(); - } - - f += f1; -@@ -1429,10 +1506,12 @@ - - if (!itemstack1.isEmpty() && entity instanceof EntityLivingBase) - { -+ ItemStack beforeHitCopy = itemstack1.copy(); - itemstack1.hitEntity((EntityLivingBase)entity, this); - - if (itemstack1.isEmpty()) - { -+ net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(this, beforeHitCopy, EnumHand.MAIN_HAND); - this.setHeldItem(EnumHand.MAIN_HAND, ItemStack.EMPTY); - } - } -@@ -1495,7 +1574,7 @@ - - if (this.rand.nextFloat() < f) - { -- this.getCooldownTracker().setCooldown(Items.SHIELD, 100); -+ this.getCooldownTracker().setCooldown(this.getActiveItemStack().getItem(), 100); - this.resetActiveHand(); - this.world.setEntityState(this, (byte)30); - } -@@ -1566,7 +1645,11 @@ - - public EntityPlayer.SleepResult trySleep(BlockPos bedLocation) - { -- EnumFacing enumfacing = this.world.getBlockState(bedLocation).getValue(BlockHorizontal.FACING); -+ EntityPlayer.SleepResult ret = net.minecraftforge.event.ForgeEventFactory.onPlayerSleepInBed(this, bedLocation); -+ if (ret != null) return ret; -+ final IBlockState state = this.world.isBlockLoaded(bedLocation) ? this.world.getBlockState(bedLocation) : null; -+ final boolean isBed = state != null && state.getBlock().isBed(state, this.world, bedLocation, this); -+ final EnumFacing enumfacing = isBed && state.getBlock() instanceof BlockHorizontal ? (EnumFacing)state.getValue(BlockHorizontal.FACING) : null; - - if (!this.world.isRemote) - { -@@ -1580,7 +1663,7 @@ - return EntityPlayer.SleepResult.NOT_POSSIBLE_HERE; - } - -- if (this.world.isDaytime()) -+ if (!net.minecraftforge.event.ForgeEventFactory.fireSleepingTimeCheck(this, bedLocation)) - { - return EntityPlayer.SleepResult.NOT_POSSIBLE_NOW; - } -@@ -1620,7 +1703,7 @@ - this.spawnShoulderEntities(); - this.setSize(0.2F, 0.2F); - -- if (this.world.isBlockLoaded(bedLocation)) -+ if (enumfacing != null) - { - float f1 = 0.5F + enumfacing.getXOffset() * 0.4F; - float f = 0.5F + enumfacing.getZOffset() * 0.4F; -@@ -1655,6 +1738,7 @@ - { - return true; - } -+ else if (p_190774_2_ == null) return false; - else - { - BlockPos blockpos = p_190774_1_.offset(p_190774_2_.getOpposite()); -@@ -1672,13 +1756,14 @@ - - public void wakeUpPlayer(boolean immediately, boolean updateWorldFlag, boolean setSpawn) - { -+ net.minecraftforge.event.ForgeEventFactory.onPlayerWakeup(this, immediately, updateWorldFlag, setSpawn); - this.setSize(0.6F, 1.8F); -- IBlockState iblockstate = this.world.getBlockState(this.bedLocation); -+ IBlockState iblockstate = this.bedLocation == null ? null : this.world.getBlockState(this.bedLocation); - -- if (this.bedLocation != null && iblockstate.getBlock() == Blocks.BED) -+ if (this.bedLocation != null && iblockstate.getBlock().isBed(iblockstate, world, bedLocation, this)) - { -- this.world.setBlockState(this.bedLocation, iblockstate.withProperty(BlockBed.OCCUPIED, false), 4); -- BlockPos blockpos = BlockBed.getSafeExitLocation(this.world, this.bedLocation, 0); -+ iblockstate.getBlock().setBedOccupied(world, bedLocation, this, false); -+ BlockPos blockpos = iblockstate.getBlock().getBedSpawnPosition(iblockstate, world, bedLocation, this); - - if (blockpos == null) - { -@@ -1687,6 +1772,10 @@ - - this.setPosition(blockpos.getX() + 0.5F, blockpos.getY() + 0.1F, blockpos.getZ() + 0.5F); - } -+ else -+ { -+ setSpawn = false; -+ } - - this.sleeping = false; - -@@ -1705,15 +1794,16 @@ - - private boolean isInBed() - { -- return this.world.getBlockState(this.bedLocation).getBlock() == Blocks.BED; -+ return net.minecraftforge.event.ForgeEventFactory.fireSleepingLocationCheck(this, this.bedLocation); - } - - @Nullable - public static BlockPos getBedSpawnLocation(World worldIn, BlockPos bedLocation, boolean forceSpawn) - { -- Block block = worldIn.getBlockState(bedLocation).getBlock(); -+ IBlockState state = worldIn.getBlockState(bedLocation); -+ Block block = state.getBlock(); - -- if (block != Blocks.BED) -+ if (!block.isBed(state, worldIn, bedLocation, null)) - { - if (!forceSpawn) - { -@@ -1728,16 +1818,17 @@ - } - else - { -- return BlockBed.getSafeExitLocation(worldIn, bedLocation, 0); -+ return block.getBedSpawnPosition(state, worldIn, bedLocation, null); - } - } - - @SideOnly(Side.CLIENT) - public float getBedOrientationInDegrees() - { -- if (this.bedLocation != null) -+ IBlockState state = this.bedLocation == null ? null : this.world.getBlockState(bedLocation); -+ if (state != null && state.getBlock().isBed(state, world, bedLocation, this)) - { -- EnumFacing enumfacing = this.world.getBlockState(this.bedLocation).getValue(BlockHorizontal.FACING); -+ EnumFacing enumfacing = state.getBlock().getBedDirection(state, world, bedLocation); - - switch (enumfacing) - { -@@ -1778,16 +1869,24 @@ - - public BlockPos getBedLocation() - { -- return this.spawnPos; -+ return getBedLocation(this.dimension); - } - -+ @Deprecated // Use dimension-sensitive version. - public boolean isSpawnForced() - { -- return this.spawnForced; -+ return isSpawnForced(this.dimension); - } - - public void setSpawnPoint(BlockPos pos, boolean forced) - { -+ if(net.minecraftforge.event.ForgeEventFactory.onPlayerSpawnSet(this, pos, forced)) return; -+ if (this.dimension != 0) -+ { -+ setSpawnChunk(pos, forced, this.dimension); -+ return; -+ } -+ - if (pos != null) - { - this.spawnPos = pos; -@@ -1984,6 +2083,10 @@ - - super.fall(distance, damageMultiplier); - } -+ else -+ { -+ net.minecraftforge.event.ForgeEventFactory.onPlayerFall(this, distance, damageMultiplier); -+ } - } - - @Override -@@ -2340,7 +2443,10 @@ - @Override - public ITextComponent getDisplayName() - { -- ITextComponent itextcomponent = new TextComponentString(ScorePlayerTeam.formatPlayerName(this.getTeam(), this.getName())); -+ ITextComponent itextcomponent = new TextComponentString(""); -+ if (!prefixes.isEmpty()) for (ITextComponent prefix : prefixes) itextcomponent.appendSibling(prefix); -+ itextcomponent.appendSibling(new TextComponentString(ScorePlayerTeam.formatPlayerName(this.getTeam(), this.getDisplayNameString()))); -+ if (!suffixes.isEmpty()) for (ITextComponent suffix : suffixes) itextcomponent.appendSibling(suffix); - itextcomponent.getStyle().setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/msg " + this.getName() + " ")); - itextcomponent.getStyle().setHoverEvent(this.getHoverEvent()); - itextcomponent.getStyle().setInsertion(this.getName()); -@@ -2350,7 +2456,7 @@ - @Override - public float getEyeHeight() - { -- float f = 1.62F; -+ float f = eyeHeight; - - if (this.isPlayerSleeping()) - { -@@ -2588,6 +2694,168 @@ - { - return this.capabilities.isCreativeMode && this.canUseCommand(2, ""); - } -+ -+ /** -+ * Opens a GUI with this player, uses FML's IGuiHandler system. -+ * Allows for extension by modders. -+ * -+ * @param mod The mod trying to open a GUI -+ * @param modGuiId GUI ID -+ * @param world Current World -+ * @param x Passed directly to IGuiHandler, data meaningless Typically world X position -+ * @param y Passed directly to IGuiHandler, data meaningless Typically world Y position -+ * @param z Passed directly to IGuiHandler, data meaningless Typically world Z position -+ */ -+ public void openGui(Object mod, int modGuiId, World world, int x, int y, int z) -+ { -+ net.minecraftforge.fml.common.network.internal.FMLNetworkHandler.openGui(this, mod, modGuiId, world, x, y, z); -+ } -+ -+ -+ /* ======================================== FORGE START =====================================*/ -+ /** -+ * A dimension aware version of getBedLocation. -+ * @param dimension The dimension to get the bed spawn for -+ * @return The player specific spawn location for the dimension. May be null. -+ */ -+ public BlockPos getBedLocation(int dimension) -+ { -+ return dimension == 0 ? spawnPos : spawnChunkMap.get(dimension); -+ } -+ -+ /** -+ * A dimension aware version of isSpawnForced. -+ * Noramally isSpawnForced is used to determine if the respawn system should check for a bed or not. -+ * This just extends that to be dimension aware. -+ * @param dimension The dimension to get whether to check for a bed before spawning for -+ * @return The player specific spawn location for the dimension. May be null. -+ */ -+ public boolean isSpawnForced(int dimension) -+ { -+ if (dimension == 0) return this.spawnForced; -+ Boolean forced = this.spawnForcedMap.get(dimension); -+ return forced == null ? false : forced; -+ } -+ -+ /** -+ * A dimension aware version of setSpawnChunk. -+ * This functions identically, but allows you to specify which dimension to affect, rather than affecting the player's current dimension. -+ * @param pos The spawn point to set as the player-specific spawn point for the dimension -+ * @param forced Whether or not the respawn code should check for a bed at this location (true means it won't check for a bed) -+ * @param dimension Which dimension to apply the player-specific respawn point to -+ */ -+ public void setSpawnChunk(BlockPos pos, boolean forced, int dimension) -+ { -+ if (dimension == 0) -+ { -+ if (pos != null) -+ { -+ spawnPos = pos; -+ spawnForced = forced; -+ } -+ else -+ { -+ spawnPos = null; -+ spawnForced = false; -+ } -+ return; -+ } -+ -+ if (pos != null) -+ { -+ spawnChunkMap.put(dimension, pos); -+ spawnForcedMap.put(dimension, forced); -+ } -+ else -+ { -+ spawnChunkMap.remove(dimension); -+ spawnForcedMap.remove(dimension); -+ } -+ } -+ -+ private String displayname; -+ -+ /** -+ * Returns the default eye height of the player -+ * @return player default eye height -+ */ -+ public float getDefaultEyeHeight() -+ { -+ return 1.62F; -+ } -+ -+ /** -+ * Get the currently computed display name, cached for efficiency. -+ * @return the current display name -+ */ -+ public String getDisplayNameString() -+ { -+ if(this.displayname == null) -+ { -+ this.displayname = net.minecraftforge.event.ForgeEventFactory.getPlayerDisplayName(this, this.getName()); -+ } -+ return this.displayname; -+ } -+ -+ /** -+ * Force the displayed name to refresh -+ */ -+ public void refreshDisplayName() -+ { -+ this.displayname = net.minecraftforge.event.ForgeEventFactory.getPlayerDisplayName(this, this.getName()); -+ } -+ -+ private final java.util.Collection prefixes = new java.util.LinkedList(); -+ private final java.util.Collection suffixes = new java.util.LinkedList(); -+ -+ /** -+ * Add a prefix to the player's username in chat -+ * @param prefix The prefix -+ */ -+ public void addPrefix(ITextComponent prefix) { prefixes.add(prefix); } -+ -+ /** -+ * Add a suffix to the player's username in chat -+ * @param suffix The suffix -+ */ -+ public void addSuffix(ITextComponent suffix) { suffixes.add(suffix); } -+ -+ public java.util.Collection getPrefixes() { return this.prefixes; } -+ public java.util.Collection getSuffixes() { return this.suffixes; } -+ -+ private final net.minecraftforge.items.IItemHandler playerMainHandler = new net.minecraftforge.items.wrapper.PlayerMainInvWrapper(inventory); -+ private final net.minecraftforge.items.IItemHandler playerEquipmentHandler = new net.minecraftforge.items.wrapper.CombinedInvWrapper( -+ new net.minecraftforge.items.wrapper.PlayerArmorInvWrapper(inventory), -+ new net.minecraftforge.items.wrapper.PlayerOffhandInvWrapper(inventory)); -+ private final net.minecraftforge.items.IItemHandler playerJoinedHandler = new net.minecraftforge.items.wrapper.PlayerInvWrapper(inventory); -+ -+ @SuppressWarnings("unchecked") -+ @Override -+ @Nullable -+ public T getCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable net.minecraft.util.EnumFacing facing) -+ { -+ if (capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) -+ { -+ if (facing == null) return (T) playerJoinedHandler; -+ else if (facing.getAxis().isVertical()) return (T) playerMainHandler; -+ else if (facing.getAxis().isHorizontal()) return (T) playerEquipmentHandler; -+ } -+ return super.getCapability(capability, facing); -+ } -+ -+ @Override -+ public boolean hasCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable net.minecraft.util.EnumFacing facing) -+ { -+ return capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY || super.hasCapability(capability, facing); -+ } -+ -+ @Nullable -+ private Integer spawnDimension; -+ public boolean hasSpawnDimension() { return spawnDimension != null; } -+ public int getSpawnDimension() { return spawnDimension != null ? spawnDimension : 0; } -+ public void setSpawnDimension(@Nullable Integer dimension) { this.spawnDimension = dimension; } -+ -+ /* ======================================== FORGE END =====================================*/ - - public static enum EnumChatVisibility - { diff --git a/patches/minecraft/net/minecraft/entity/player/EntityPlayerMP.java.patch b/patches/minecraft/net/minecraft/entity/player/EntityPlayerMP.java.patch deleted file mode 100644 index af80313e7..000000000 --- a/patches/minecraft/net/minecraft/entity/player/EntityPlayerMP.java.patch +++ /dev/null @@ -1,146 +0,0 @@ ---- before/net/minecraft/entity/player/EntityPlayerMP.java -+++ after/net/minecraft/entity/player/EntityPlayerMP.java -@@ -158,9 +158,9 @@ - super(worldIn, profile); - interactionManagerIn.player = this; - this.interactionManager = interactionManagerIn; -- BlockPos blockpos = worldIn.getSpawnPoint(); -+ BlockPos blockpos = worldIn.provider.getRandomizedSpawnPoint(); - -- if (worldIn.provider.hasSkyLight() && worldIn.getWorldInfo().getGameType() != GameType.ADVENTURE) -+ if (false && worldIn.provider.hasSkyLight() && worldIn.getWorldInfo().getGameType() != GameType.ADVENTURE) - { - int i = Math.max(0, server.getSpawnRadius(worldIn)); - int j = MathHelper.floor(worldIn.getWorldBorder().getClosestDistance(blockpos.getX(), blockpos.getZ())); -@@ -333,7 +333,7 @@ - - this.openContainer.detectAndSendChanges(); - -- if (!this.world.isRemote && !this.openContainer.canInteractWith(this)) -+ if (!this.world.isRemote && this.openContainer != null && !this.openContainer.canInteractWith(this)) - { - this.closeScreen(); - this.openContainer = this.inventoryContainer; -@@ -485,6 +485,7 @@ - @Override - public void onDeath(DamageSource cause) - { -+ if (net.minecraftforge.common.ForgeHooks.onLivingDeath(this, cause)) return; - boolean flag = this.world.getGameRules().getBoolean("showDeathMessages"); - this.connection.sendPacket(new SPacketCombatEvent(this.getCombatTracker(), SPacketCombatEvent.Event.ENTITY_DIED, flag)); - -@@ -510,8 +511,20 @@ - - if (!this.world.getGameRules().getBoolean("keepInventory") && !this.isSpectator()) - { -+ captureDrops = true; -+ capturedDrops.clear(); - this.destroyVanishingCursedItems(); - this.inventory.dropAllItems(); -+ -+ captureDrops = false; -+ net.minecraftforge.event.entity.player.PlayerDropsEvent event = new net.minecraftforge.event.entity.player.PlayerDropsEvent(this, cause, capturedDrops, recentlyHit > 0); -+ if (!net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event)) -+ { -+ for (net.minecraft.entity.item.EntityItem item : capturedDrops) -+ { -+ this.world.spawnEntity(item); -+ } -+ } - } - - for (ScoreObjective scoreobjective : this.world.getScoreboard().getObjectivesFromCriteria(IScoreCriteria.DEATH_COUNT)) -@@ -660,8 +673,9 @@ - - @Nullable - @Override -- public Entity changeDimension(int dimensionIn) -+ public Entity changeDimension(int dimensionIn, net.minecraftforge.common.util.ITeleporter teleporter) - { -+ if (!net.minecraftforge.common.ForgeHooks.onTravelToDimension(this, dimensionIn)) return this; - this.invulnerableDimensionChange = true; - - if (this.dimension == 0 && dimensionIn == -1) -@@ -673,7 +687,7 @@ - this.enteredNetherPosition = null; - } - -- if (this.dimension == 1 && dimensionIn == 1) -+ if (this.dimension == 1 && dimensionIn == 1 && teleporter.isVanilla()) - { - this.world.removeEntity(this); - -@@ -693,7 +707,7 @@ - dimensionIn = 1; - } - -- this.server.getPlayerList().changePlayerDimension(this, dimensionIn); -+ this.server.getPlayerList().transferPlayerToDimension(this, dimensionIn, teleporter); - this.connection.sendPacket(new SPacketEffect(1032, BlockPos.ORIGIN, 0, false)); - this.lastExperience = -1; - this.lastHealth = -1.0F; -@@ -832,7 +846,7 @@ - BlockPos blockpos = new BlockPos(i, j, k); - IBlockState iblockstate = this.world.getBlockState(blockpos); - -- if (iblockstate.getMaterial() == Material.AIR) -+ if (iblockstate.getBlock().isAir(iblockstate, this.world, blockpos)) - { - BlockPos blockpos1 = blockpos.down(); - IBlockState iblockstate1 = this.world.getBlockState(blockpos1); -@@ -874,6 +888,7 @@ - this.openContainer = guiOwner.createContainer(this.inventory, this); - this.openContainer.windowId = this.currentWindowId; - this.openContainer.addListener(this); -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.player.PlayerContainerEvent.Open(this, this.openContainer)); - } - } - -@@ -930,6 +945,7 @@ - - this.openContainer.windowId = this.currentWindowId; - this.openContainer.addListener(this); -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.player.PlayerContainerEvent.Open(this, this.openContainer)); - } - } - -@@ -940,6 +956,7 @@ - this.openContainer = new ContainerMerchant(this.inventory, villager, this.world); - this.openContainer.windowId = this.currentWindowId; - this.openContainer.addListener(this); -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.player.PlayerContainerEvent.Open(this, this.openContainer)); - IInventory iinventory = ((ContainerMerchant)this.openContainer).getMerchantInventory(); - ITextComponent itextcomponent = villager.getDisplayName(); - this.connection.sendPacket(new SPacketOpenWindow(this.currentWindowId, "minecraft:villager", itextcomponent, iinventory.getSizeInventory())); -@@ -1054,6 +1071,7 @@ - public void closeContainer() - { - this.openContainer.onContainerClosed(this); -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.player.PlayerContainerEvent.Close(this, this.openContainer)); - this.openContainer = this.inventoryContainer; - } - -@@ -1202,6 +1220,23 @@ - this.enteredNetherPosition = that.enteredNetherPosition; - this.setLeftShoulderEntity(that.getLeftShoulderEntity()); - this.setRightShoulderEntity(that.getRightShoulderEntity()); -+ -+ this.spawnChunkMap = that.spawnChunkMap; -+ this.spawnForcedMap = that.spawnForcedMap; -+ if(that.dimension != 0) -+ { -+ this.spawnPos = that.spawnPos; -+ this.spawnForced = that.spawnForced; -+ } -+ -+ //Copy over a section of the Entity Data from the old player. -+ //Allows mods to specify data that persists after players respawn. -+ NBTTagCompound old = that.getEntityData(); -+ if (old.hasKey(PERSISTED_NBT_TAG)) -+ { -+ getEntityData().setTag(PERSISTED_NBT_TAG, old.getCompoundTag(PERSISTED_NBT_TAG)); -+ } -+ net.minecraftforge.event.ForgeEventFactory.onPlayerClone(this, that, !keepEverything); - } - - @Override diff --git a/patches/minecraft/net/minecraft/entity/player/InventoryPlayer.java.patch b/patches/minecraft/net/minecraft/entity/player/InventoryPlayer.java.patch deleted file mode 100644 index 8c47a8749..000000000 --- a/patches/minecraft/net/minecraft/entity/player/InventoryPlayer.java.patch +++ /dev/null @@ -1,35 +0,0 @@ ---- before/net/minecraft/entity/player/InventoryPlayer.java -+++ after/net/minecraft/entity/player/InventoryPlayer.java -@@ -304,7 +304,8 @@ - - if (itemstack.isEmpty()) - { -- itemstack = new ItemStack(item, 0, p_191973_2_.getMetadata()); -+ itemstack = p_191973_2_.copy(); // Forge: Replace Item clone above to preserve item capabilities when picking the item up. -+ itemstack.setCount(0); - - if (p_191973_2_.hasTagCompound()) - { -@@ -375,6 +376,13 @@ - } - } - } -+ for (ItemStack is : armorInventory) // FORGE: Tick armor on animation ticks -+ { -+ if (!is.isEmpty()) -+ { -+ is.getItem().onArmorTick(player.world, player, is); -+ } -+ } - } - - public boolean addItemStackToInventory(ItemStack itemStackIn) -@@ -452,6 +460,8 @@ - CrashReportCategory crashreportcategory = crashreport.makeCategory("Item being added"); - crashreportcategory.addCrashSection("Item ID", Item.getIdFromItem(p_191971_2_.getItem())); - crashreportcategory.addCrashSection("Item data", p_191971_2_.getMetadata()); -+ crashreportcategory.addDetail("Registry Name", () -> String.valueOf(p_191971_2_.getItem().getRegistryName())); -+ crashreportcategory.addDetail("Item Class", () -> p_191971_2_.getItem().getClass().getName()); - crashreportcategory.addDetail("Item name", new ICrashReportDetail() - { - public String call() throws Exception diff --git a/patches/minecraft/net/minecraft/entity/projectile/EntityArrow.java.patch b/patches/minecraft/net/minecraft/entity/projectile/EntityArrow.java.patch deleted file mode 100644 index ce1d34f22..000000000 --- a/patches/minecraft/net/minecraft/entity/projectile/EntityArrow.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/entity/projectile/EntityArrow.java -+++ after/net/minecraft/entity/projectile/EntityArrow.java -@@ -270,7 +270,7 @@ - } - } - -- if (raytraceresult != null) -+ if (raytraceresult != null && !net.minecraftforge.event.ForgeEventFactory.onProjectileImpact(this, raytraceresult)) - { - this.onHit(raytraceresult); - } diff --git a/patches/minecraft/net/minecraft/entity/projectile/EntityFireball.java.patch b/patches/minecraft/net/minecraft/entity/projectile/EntityFireball.java.patch deleted file mode 100644 index d1ec8b5bb..000000000 --- a/patches/minecraft/net/minecraft/entity/projectile/EntityFireball.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/entity/projectile/EntityFireball.java -+++ after/net/minecraft/entity/projectile/EntityFireball.java -@@ -97,7 +97,7 @@ - this.ticksInAir++; - RayTraceResult raytraceresult = ProjectileHelper.forwardsRaycast(this, true, this.ticksInAir >= 25, this.shootingEntity); - -- if (raytraceresult != null) -+ if (raytraceresult != null && !net.minecraftforge.event.ForgeEventFactory.onProjectileImpact(this, raytraceresult)) - { - this.onImpact(raytraceresult); - } diff --git a/patches/minecraft/net/minecraft/entity/projectile/EntityFishHook.java.patch b/patches/minecraft/net/minecraft/entity/projectile/EntityFishHook.java.patch deleted file mode 100644 index eb7a7af48..000000000 --- a/patches/minecraft/net/minecraft/entity/projectile/EntityFishHook.java.patch +++ /dev/null @@ -1,77 +0,0 @@ ---- before/net/minecraft/entity/projectile/EntityFishHook.java -+++ after/net/minecraft/entity/projectile/EntityFishHook.java -@@ -280,8 +280,8 @@ - { - ItemStack itemstack = this.angler.getHeldItemMainhand(); - ItemStack itemstack1 = this.angler.getHeldItemOffhand(); -- boolean flag = itemstack.getItem() == Items.FISHING_ROD; -- boolean flag1 = itemstack1.getItem() == Items.FISHING_ROD; -+ boolean flag = itemstack.getItem() instanceof net.minecraft.item.ItemFishingRod; -+ boolean flag1 = itemstack1.getItem() instanceof net.minecraft.item.ItemFishingRod; - - if (!this.angler.isDead && this.angler.isEntityAlive() && (flag || flag1) && !(this.getDistanceSq(this.angler) > 1024.0)) - { -@@ -429,9 +429,9 @@ - double d0 = this.posX + f1 * this.ticksCatchableDelay * 0.1F; - double d1 = MathHelper.floor(this.getEntityBoundingBox().minY) + 1.0F; - double d2 = this.posZ + f2 * this.ticksCatchableDelay * 0.1F; -- Block block = worldserver.getBlockState(new BlockPos(d0, d1 - 1.0, d2)).getBlock(); -+ IBlockState state = worldserver.getBlockState(new BlockPos(d0, d1 - 1.0, d2)); - -- if (block == Blocks.WATER || block == Blocks.FLOWING_WATER) -+ if (state.getMaterial() == Material.WATER) - { - if (this.rand.nextFloat() < 0.15F) - { -@@ -499,9 +499,9 @@ - double d4 = this.posX + MathHelper.sin(f6) * f7 * 0.1F; - double d5 = MathHelper.floor(this.getEntityBoundingBox().minY) + 1.0F; - double d6 = this.posZ + MathHelper.cos(f6) * f7 * 0.1F; -- Block block1 = worldserver.getBlockState(new BlockPos((int)d4, (int)d5 - 1, (int)d6)).getBlock(); -+ IBlockState state = worldserver.getBlockState(new BlockPos((int) d4, (int) d5 - 1, (int) d6)); - -- if (block1 == Blocks.WATER || block1 == Blocks.FLOWING_WATER) -+ if (state.getMaterial() == Material.WATER) - { - worldserver.spawnParticle(EnumParticleTypes.WATER_SPLASH, d4, d5, d6, 2 + this.rand.nextInt(2), 0.1F, 0.0, 0.1F, 0.0); - } -@@ -541,6 +541,7 @@ - { - int i = 0; - -+ net.minecraftforge.event.entity.player.ItemFishedEvent event = null; - if (this.caughtEntity != null) - { - this.bringInHookedEntity(); -@@ -550,12 +551,17 @@ - else if (this.ticksCatchable > 0) - { - LootContext.Builder lootcontext$builder = new LootContext.Builder((WorldServer)this.world); -- lootcontext$builder.withLuck(this.luck + this.angler.getLuck()); -+ lootcontext$builder.withLuck((float)this.luck + this.angler.getLuck()).withPlayer(this.angler).withLootedEntity(this); // Forge: add player & looted entity to LootContext -+ List result = this.world.getLootTableManager().getLootTableFromLocation(LootTableList.GAMEPLAY_FISHING).generateLootForPools(this.rand, lootcontext$builder.build()); -+ event = new net.minecraftforge.event.entity.player.ItemFishedEvent(result, this.inGround ? 2 : 1, this); -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event); -+ if (event.isCanceled()) -+ { -+ this.setDead(); -+ return event.getRodDamage(); -+ } - -- for (ItemStack itemstack : this.world -- .getLootTableManager() -- .getLootTableFromLocation(LootTableList.GAMEPLAY_FISHING) -- .generateLootForPools(this.rand, lootcontext$builder.build())) -+ for (ItemStack itemstack : result) - { - EntityItem entityitem = new EntityItem(this.world, this.posX, this.posY, this.posZ, itemstack); - double d0 = this.angler.posX - this.posX; -@@ -595,7 +601,7 @@ - } - - this.setDead(); -- return i; -+ return event == null ? i : event.getRodDamage(); - } - else - { diff --git a/patches/minecraft/net/minecraft/entity/projectile/EntityLargeFireball.java.patch b/patches/minecraft/net/minecraft/entity/projectile/EntityLargeFireball.java.patch deleted file mode 100644 index a3144fd85..000000000 --- a/patches/minecraft/net/minecraft/entity/projectile/EntityLargeFireball.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/entity/projectile/EntityLargeFireball.java -+++ after/net/minecraft/entity/projectile/EntityLargeFireball.java -@@ -42,7 +42,7 @@ - this.applyEnchantments(this.shootingEntity, result.entityHit); - } - -- boolean flag = this.world.getGameRules().getBoolean("mobGriefing"); -+ boolean flag = net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.world, this.shootingEntity); - this.world.newExplosion(null, this.posX, this.posY, this.posZ, this.explosionPower, flag, flag); - this.setDead(); - } diff --git a/patches/minecraft/net/minecraft/entity/projectile/EntityLlamaSpit.java.patch b/patches/minecraft/net/minecraft/entity/projectile/EntityLlamaSpit.java.patch deleted file mode 100644 index c66218fae..000000000 --- a/patches/minecraft/net/minecraft/entity/projectile/EntityLlamaSpit.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/entity/projectile/EntityLlamaSpit.java -+++ after/net/minecraft/entity/projectile/EntityLlamaSpit.java -@@ -87,7 +87,7 @@ - raytraceresult = new RayTraceResult(entity); - } - -- if (raytraceresult != null) -+ if (raytraceresult != null && !net.minecraftforge.event.ForgeEventFactory.onProjectileImpact(this, raytraceresult)) - { - this.onHit(raytraceresult); - } diff --git a/patches/minecraft/net/minecraft/entity/projectile/EntityShulkerBullet.java.patch b/patches/minecraft/net/minecraft/entity/projectile/EntityShulkerBullet.java.patch deleted file mode 100644 index 4e066f706..000000000 --- a/patches/minecraft/net/minecraft/entity/projectile/EntityShulkerBullet.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/entity/projectile/EntityShulkerBullet.java -+++ after/net/minecraft/entity/projectile/EntityShulkerBullet.java -@@ -325,7 +325,7 @@ - - RayTraceResult raytraceresult = ProjectileHelper.forwardsRaycast(this, true, false, this.owner); - -- if (raytraceresult != null) -+ if (raytraceresult != null && !net.minecraftforge.event.ForgeEventFactory.onProjectileImpact(this, raytraceresult)) - { - this.bulletHit(raytraceresult); - } diff --git a/patches/minecraft/net/minecraft/entity/projectile/EntitySmallFireball.java.patch b/patches/minecraft/net/minecraft/entity/projectile/EntitySmallFireball.java.patch deleted file mode 100644 index 3bb7268cb..000000000 --- a/patches/minecraft/net/minecraft/entity/projectile/EntitySmallFireball.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/entity/projectile/EntitySmallFireball.java -+++ after/net/minecraft/entity/projectile/EntitySmallFireball.java -@@ -60,7 +60,7 @@ - - if (this.shootingEntity != null && this.shootingEntity instanceof EntityLiving) - { -- flag1 = this.world.getGameRules().getBoolean("mobGriefing"); -+ flag1 = net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.world, this.shootingEntity); - } - - if (flag1) diff --git a/patches/minecraft/net/minecraft/entity/projectile/EntityThrowable.java.patch b/patches/minecraft/net/minecraft/entity/projectile/EntityThrowable.java.patch deleted file mode 100644 index c1d9aa6ae..000000000 --- a/patches/minecraft/net/minecraft/entity/projectile/EntityThrowable.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/entity/projectile/EntityThrowable.java -+++ after/net/minecraft/entity/projectile/EntityThrowable.java -@@ -249,7 +249,7 @@ - { - this.setPortal(raytraceresult.getBlockPos()); - } -- else -+ else if (!net.minecraftforge.event.ForgeEventFactory.onProjectileImpact(this, raytraceresult)) - { - this.onImpact(raytraceresult); - } diff --git a/patches/minecraft/net/minecraft/entity/projectile/EntityWitherSkull.java.patch b/patches/minecraft/net/minecraft/entity/projectile/EntityWitherSkull.java.patch deleted file mode 100644 index 03df4af09..000000000 --- a/patches/minecraft/net/minecraft/entity/projectile/EntityWitherSkull.java.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- before/net/minecraft/entity/projectile/EntityWitherSkull.java -+++ after/net/minecraft/entity/projectile/EntityWitherSkull.java -@@ -67,7 +67,7 @@ - float f = super.getExplosionResistance(explosionIn, worldIn, pos, blockStateIn); - Block block = blockStateIn.getBlock(); - -- if (this.isInvulnerable() && EntityWither.canDestroyBlock(block)) -+ if (this.isInvulnerable() && block.canEntityDestroy(blockStateIn, worldIn, pos, this) && net.minecraftforge.event.ForgeEventFactory.onEntityDestroyBlock(this.shootingEntity, pos, blockStateIn)) - { - f = Math.min(0.8F, f); - } -@@ -123,7 +123,7 @@ - - this.world - .newExplosion( -- this, this.posX, this.posY, this.posZ, 1.0F, false, this.world.getGameRules().getBoolean("mobGriefing") -+ this, this.posX, this.posY, this.posZ, 1.0F, false, net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.world, this.shootingEntity) - ); - this.setDead(); - } diff --git a/patches/minecraft/net/minecraft/init/Bootstrap.java.patch b/patches/minecraft/net/minecraft/init/Bootstrap.java.patch deleted file mode 100644 index 3ca25181b..000000000 --- a/patches/minecraft/net/minecraft/init/Bootstrap.java.patch +++ /dev/null @@ -1,28 +0,0 @@ ---- before/net/minecraft/init/Bootstrap.java -+++ after/net/minecraft/init/Bootstrap.java -@@ -310,6 +310,9 @@ - }; - BlockDispenser.DISPENSE_BEHAVIOR_REGISTRY.putObject(Items.LAVA_BUCKET, ibehaviordispenseitem); - BlockDispenser.DISPENSE_BEHAVIOR_REGISTRY.putObject(Items.WATER_BUCKET, ibehaviordispenseitem); -+ BlockDispenser.DISPENSE_BEHAVIOR_REGISTRY.putObject(Items.MILK_BUCKET, net.minecraftforge.fluids.DispenseFluidContainer.getInstance()); -+ BlockDispenser.DISPENSE_BEHAVIOR_REGISTRY.putObject(Items.BUCKET, net.minecraftforge.fluids.DispenseFluidContainer.getInstance()); -+ if (false) - BlockDispenser.DISPENSE_BEHAVIOR_REGISTRY.putObject(Items.BUCKET, new BehaviorDefaultDispenseItem() - { - private final BehaviorDefaultDispenseItem dispenseBehavior = new BehaviorDefaultDispenseItem(); -@@ -557,6 +560,7 @@ - if (!alreadyRegistered) - { - alreadyRegistered = true; -+ if (false) // skip redirectOutputToLog, Forge already redirects stdout and stderr output to log so that they print with more context - redirectOutputToLog(); - SoundEvent.registerSounds(); - Block.registerBlocks(); -@@ -592,6 +596,7 @@ - LOGGER.error("Errors with built-in loot tables"); - } - } -+ net.minecraftforge.registries.GameData.vanillaSnapshot(); - } - } - diff --git a/patches/minecraft/net/minecraft/inventory/Container.java.patch b/patches/minecraft/net/minecraft/inventory/Container.java.patch deleted file mode 100644 index 1954c2450..000000000 --- a/patches/minecraft/net/minecraft/inventory/Container.java.patch +++ /dev/null @@ -1,47 +0,0 @@ ---- before/net/minecraft/inventory/Container.java -+++ after/net/minecraft/inventory/Container.java -@@ -81,9 +81,11 @@ - - if (!ItemStack.areItemStacksEqual(itemstack1, itemstack)) - { -+ boolean clientStackChanged = !ItemStack.areItemStacksEqualUsingNBTShareTag(itemstack1, itemstack); - itemstack1 = itemstack.isEmpty() ? ItemStack.EMPTY : itemstack.copy(); - this.inventoryItemStacks.set(i, itemstack1); - -+ if (clientStackChanged) - for (int j = 0; j < this.listeners.size(); j++) - { - this.listeners.get(j).sendSlotContents(this, i, itemstack1); -@@ -600,18 +602,19 @@ - && ItemStack.areItemStackTagsEqual(stack, itemstack)) - { - int j = itemstack.getCount() + stack.getCount(); -+ int maxSize = Math.min(slot.getSlotStackLimit(), stack.getMaxStackSize()); - -- if (j <= stack.getMaxStackSize()) -+ if (j <= maxSize) - { - stack.setCount(0); - itemstack.setCount(j); - slot.onSlotChanged(); - flag = true; - } -- else if (itemstack.getCount() < stack.getMaxStackSize()) -+ else if (itemstack.getCount() < maxSize) - { -- stack.shrink(stack.getMaxStackSize() - itemstack.getCount()); -- itemstack.setCount(stack.getMaxStackSize()); -+ stack.shrink(maxSize - itemstack.getCount()); -+ itemstack.setCount(maxSize); - slot.onSlotChanged(); - flag = true; - } -@@ -727,7 +730,7 @@ - stack.setCount(1); - break; - case 2: -- stack.setCount(stack.getItem().getItemStackLimit()); -+ stack.setCount(stack.getMaxStackSize()); - } - - stack.grow(slotStackSize); diff --git a/patches/minecraft/net/minecraft/inventory/ContainerBeacon.java.patch b/patches/minecraft/net/minecraft/inventory/ContainerBeacon.java.patch deleted file mode 100644 index 7d8530328..000000000 --- a/patches/minecraft/net/minecraft/inventory/ContainerBeacon.java.patch +++ /dev/null @@ -1,27 +0,0 @@ ---- before/net/minecraft/inventory/ContainerBeacon.java -+++ after/net/minecraft/inventory/ContainerBeacon.java -@@ -95,12 +95,9 @@ - - slot.onSlotChange(itemstack1, itemstack); - } -- else if (!this.beaconSlot.getHasStack() && this.beaconSlot.isItemValid(itemstack1) && itemstack1.getCount() == 1) -+ else if (this.mergeItemStack(itemstack1, 0, 1, false)) //Forge Fix Shift Clicking in beacons with stacks larger then 1. - { -- if (!this.mergeItemStack(itemstack1, 0, 1, false)) -- { -- return ItemStack.EMPTY; -- } -+ return ItemStack.EMPTY; - } - else if (index >= 1 && index < 28) - { -@@ -151,8 +148,7 @@ - @Override - public boolean isItemValid(ItemStack stack) - { -- Item item = stack.getItem(); -- return item == Items.EMERALD || item == Items.DIAMOND || item == Items.GOLD_INGOT || item == Items.IRON_INGOT; -+ return stack.getItem().isBeaconPayment(stack); - } - - @Override diff --git a/patches/minecraft/net/minecraft/inventory/ContainerBrewingStand.java.patch b/patches/minecraft/net/minecraft/inventory/ContainerBrewingStand.java.patch deleted file mode 100644 index 7082c4548..000000000 --- a/patches/minecraft/net/minecraft/inventory/ContainerBrewingStand.java.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- before/net/minecraft/inventory/ContainerBrewingStand.java -+++ after/net/minecraft/inventory/ContainerBrewingStand.java -@@ -205,7 +205,7 @@ - @Override - public boolean isItemValid(ItemStack stack) - { -- return PotionHelper.isReagent(stack); -+ return net.minecraftforge.common.brewing.BrewingRecipeRegistry.isValidIngredient(stack); - } - - @Override -@@ -241,6 +241,7 @@ - - if (thePlayer instanceof EntityPlayerMP) - { -+ net.minecraftforge.event.ForgeEventFactory.onPlayerBrewedPotion(thePlayer, stack); - CriteriaTriggers.BREWED_POTION.trigger((EntityPlayerMP)thePlayer, potiontype); - } - -@@ -250,8 +251,7 @@ - - public static boolean canHoldPotion(ItemStack stack) - { -- Item item = stack.getItem(); -- return item == Items.POTIONITEM || item == Items.SPLASH_POTION || item == Items.LINGERING_POTION || item == Items.GLASS_BOTTLE; -+ return net.minecraftforge.common.brewing.BrewingRecipeRegistry.isValidInput(stack); - } - } - } diff --git a/patches/minecraft/net/minecraft/inventory/ContainerEnchantment.java.patch b/patches/minecraft/net/minecraft/inventory/ContainerEnchantment.java.patch deleted file mode 100644 index a5168d0b7..000000000 --- a/patches/minecraft/net/minecraft/inventory/ContainerEnchantment.java.patch +++ /dev/null @@ -1,99 +0,0 @@ ---- before/net/minecraft/inventory/ContainerEnchantment.java -+++ after/net/minecraft/inventory/ContainerEnchantment.java -@@ -72,10 +72,13 @@ - }); - this.addSlotToContainer(new Slot(this.tableInventory, 1, 35, 47) - { -+ java.util.List ores = net.minecraftforge.oredict.OreDictionary.getOres("gemLapis"); - @Override - public boolean isItemValid(ItemStack stack) - { -- return stack.getItem() == Items.DYE && EnumDyeColor.byDyeDamage(stack.getMetadata()) == EnumDyeColor.BLUE; -+ for (ItemStack ore : ores) -+ if (net.minecraftforge.oredict.OreDictionary.itemMatches(ore, stack, false)) return true; -+ return false; - } - }); - -@@ -164,6 +167,7 @@ - if (!this.world.isRemote) - { - int l = 0; -+ float power = 0; - - for (int j = -1; j <= 1; j++) - { -@@ -173,37 +177,14 @@ - && this.world.isAirBlock(this.position.add(k, 0, j)) - && this.world.isAirBlock(this.position.add(k, 1, j))) - { -- if (this.world.getBlockState(this.position.add(k * 2, 0, j * 2)).getBlock() == Blocks.BOOKSHELF) -- { -- l++; -- } -- -- if (this.world.getBlockState(this.position.add(k * 2, 1, j * 2)).getBlock() == Blocks.BOOKSHELF) -- { -- l++; -- } -- -+ power += net.minecraftforge.common.ForgeHooks.getEnchantPower(world, position.add(k * 2, 0, j * 2)); -+ power += net.minecraftforge.common.ForgeHooks.getEnchantPower(world, position.add(k * 2, 1, j * 2)); - if (k != 0 && j != 0) - { -- if (this.world.getBlockState(this.position.add(k * 2, 0, j)).getBlock() == Blocks.BOOKSHELF) -- { -- l++; -- } -- -- if (this.world.getBlockState(this.position.add(k * 2, 1, j)).getBlock() == Blocks.BOOKSHELF) -- { -- l++; -- } -- -- if (this.world.getBlockState(this.position.add(k, 0, j * 2)).getBlock() == Blocks.BOOKSHELF) -- { -- l++; -- } -- -- if (this.world.getBlockState(this.position.add(k, 1, j * 2)).getBlock() == Blocks.BOOKSHELF) -- { -- l++; -- } -+ power += net.minecraftforge.common.ForgeHooks.getEnchantPower(world, position.add(k * 2, 0, j)); -+ power += net.minecraftforge.common.ForgeHooks.getEnchantPower(world, position.add(k * 2, 1, j)); -+ power += net.minecraftforge.common.ForgeHooks.getEnchantPower(world, position.add(k, 0, j * 2)); -+ power += net.minecraftforge.common.ForgeHooks.getEnchantPower(world, position.add(k, 1, j * 2)); - } - } - } -@@ -213,7 +194,7 @@ - - for (int i1 = 0; i1 < 3; i1++) - { -- this.enchantLevels[i1] = EnchantmentHelper.calcItemStackEnchantability(this.rand, i1, l, itemstack); -+ this.enchantLevels[i1] = EnchantmentHelper.calcItemStackEnchantability(this.rand, i1, (int)power, itemstack); - this.enchantClue[i1] = -1; - this.worldClue[i1] = -1; - -@@ -221,6 +202,7 @@ - { - this.enchantLevels[i1] = 0; - } -+ this.enchantLevels[i1] = net.minecraftforge.event.ForgeEventFactory.onEnchantmentLevelSet(world, position, i1, (int)power, itemstack, enchantLevels[i1]); - } - - for (int j1 = 0; j1 < 3; j1++) -@@ -420,10 +402,9 @@ - return ItemStack.EMPTY; - } - -- if (itemstack1.hasTagCompound() && itemstack1.getCount() == 1) -+ if (itemstack1.hasTagCompound())// Forge: Fix MC-17431 - { -- this.inventorySlots.get(0).putStack(itemstack1.copy()); -- itemstack1.setCount(0); -+ this.inventorySlots.get(0).putStack(itemstack1.splitStack(1)); - } - else if (!itemstack1.isEmpty()) - { diff --git a/patches/minecraft/net/minecraft/inventory/ContainerPlayer.java.patch b/patches/minecraft/net/minecraft/inventory/ContainerPlayer.java.patch deleted file mode 100644 index c5068bc73..000000000 --- a/patches/minecraft/net/minecraft/inventory/ContainerPlayer.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/inventory/ContainerPlayer.java -+++ after/net/minecraft/inventory/ContainerPlayer.java -@@ -49,7 +49,7 @@ - @Override - public boolean isItemValid(ItemStack stack) - { -- return entityequipmentslot == EntityLiving.getSlotForItemStack(stack); -+ return stack.getItem().isValidArmor(stack, entityequipmentslot, player); - } - @Override - public boolean canTakeStack(EntityPlayer playerIn) diff --git a/patches/minecraft/net/minecraft/inventory/ContainerRepair.java.patch b/patches/minecraft/net/minecraft/inventory/ContainerRepair.java.patch deleted file mode 100644 index d38585d15..000000000 --- a/patches/minecraft/net/minecraft/inventory/ContainerRepair.java.patch +++ /dev/null @@ -1,51 +0,0 @@ ---- before/net/minecraft/inventory/ContainerRepair.java -+++ after/net/minecraft/inventory/ContainerRepair.java -@@ -75,6 +75,8 @@ - thePlayer.addExperienceLevel(-ContainerRepair.this.maximumCost); - } - -+ float breakChance = net.minecraftforge.common.ForgeHooks.onAnvilRepair(thePlayer, stack, ContainerRepair.this.inputSlots.getStackInSlot(0), ContainerRepair.this.inputSlots.getStackInSlot(1)); -+ - ContainerRepair.this.inputSlots.setInventorySlotContents(0, ItemStack.EMPTY); - - if (ContainerRepair.this.materialCost > 0) -@@ -102,7 +104,7 @@ - if (!thePlayer.capabilities.isCreativeMode - && !worldIn.isRemote - && iblockstate.getBlock() == Blocks.ANVIL -- && thePlayer.getRNG().nextFloat() < 0.12F) -+ && thePlayer.getRNG().nextFloat() < breakChance) - { - int l = iblockstate.getValue(BlockAnvil.DAMAGE); - -@@ -172,10 +174,12 @@ - Map map = EnchantmentHelper.getEnchantments(itemstack1); - j += itemstack.getRepairCost() + (itemstack2.isEmpty() ? 0 : itemstack2.getRepairCost()); - this.materialCost = 0; -+ boolean flag = false; - - if (!itemstack2.isEmpty()) - { -- boolean flag = itemstack2.getItem() == Items.ENCHANTED_BOOK && !ItemEnchantedBook.getEnchantments(itemstack2).isEmpty(); -+ if (!net.minecraftforge.common.ForgeHooks.onAnvilChange(this, itemstack, itemstack2, outputSlot, repairedItemName, j, player)) return; -+ flag = itemstack2.getItem() == Items.ENCHANTED_BOOK && !ItemEnchantedBook.getEnchantments(itemstack2).isEmpty(); - - if (itemstack1.isItemStackDamageable() && itemstack1.getItem().getIsRepairable(itemstack, itemstack2)) - { -@@ -222,7 +226,7 @@ - l1 = 0; - } - -- if (l1 < itemstack1.getMetadata()) -+ if (l1 < itemstack1.getItemDamage()) // vanilla uses metadata here instead of damage. - { - itemstack1.setItemDamage(l1); - i += 2; -@@ -326,6 +330,7 @@ - i += k; - itemstack1.setStackDisplayName(this.repairedItemName); - } -+ if (flag && !itemstack1.getItem().isBookEnchantable(itemstack1, itemstack2)) itemstack1 = ItemStack.EMPTY; - - this.maximumCost = j + i; - diff --git a/patches/minecraft/net/minecraft/inventory/Slot.java.patch b/patches/minecraft/net/minecraft/inventory/Slot.java.patch deleted file mode 100644 index aa2779a06..000000000 --- a/patches/minecraft/net/minecraft/inventory/Slot.java.patch +++ /dev/null @@ -1,86 +0,0 @@ ---- before/net/minecraft/inventory/Slot.java -+++ after/net/minecraft/inventory/Slot.java -@@ -90,7 +90,7 @@ - @SideOnly(Side.CLIENT) - public String getSlotTexture() - { -- return null; -+ return backgroundName; - } - - public ItemStack decrStackSize(int amount) -@@ -113,4 +113,74 @@ - { - return true; - } -+ -+ /*========================================= FORGE START =====================================*/ -+ protected String backgroundName = null; -+ protected net.minecraft.util.ResourceLocation backgroundLocation = null; -+ protected Object backgroundMap; -+ /** -+ * Gets the path of the texture file to use for the background image of this slot when drawing the GUI. -+ * @return The resource location for the background image -+ */ -+ @SideOnly(Side.CLIENT) -+ public net.minecraft.util.ResourceLocation getBackgroundLocation() -+ { -+ return (backgroundLocation == null ? net.minecraft.client.renderer.texture.TextureMap.LOCATION_BLOCKS_TEXTURE : backgroundLocation); -+ } -+ -+ /** -+ * Sets the texture file to use for the background image of the slot when it's empty. -+ * @param texture the resourcelocation for the texture -+ */ -+ @SideOnly(Side.CLIENT) -+ public void setBackgroundLocation(net.minecraft.util.ResourceLocation texture) -+ { -+ this.backgroundLocation = texture; -+ } -+ -+ /** -+ * Sets which icon index to use as the background image of the slot when it's empty. -+ * @param name The icon to use, null for none -+ */ -+ public void setBackgroundName(@Nullable String name) -+ { -+ this.backgroundName = name; -+ } -+ -+ @Nullable -+ @SideOnly(Side.CLIENT) -+ public net.minecraft.client.renderer.texture.TextureAtlasSprite getBackgroundSprite() -+ { -+ String name = getSlotTexture(); -+ return name == null ? null : getBackgroundMap().getAtlasSprite(name); -+ } -+ -+ @SideOnly(Side.CLIENT) -+ protected net.minecraft.client.renderer.texture.TextureMap getBackgroundMap() -+ { -+ if (backgroundMap == null) backgroundMap = net.minecraft.client.Minecraft.getMinecraft().getTextureMapBlocks(); -+ return (net.minecraft.client.renderer.texture.TextureMap)backgroundMap; -+ } -+ -+ /** -+ * Retrieves the index in the inventory for this slot, this value should typically not -+ * be used, but can be useful for some occasions. -+ * -+ * @return Index in associated inventory for this slot. -+ */ -+ public int getSlotIndex() -+ { -+ return slotIndex; -+ } -+ -+ /** -+ * Checks if the other slot is in the same inventory, by comparing the inventory reference. -+ * @param other -+ * @return true if the other slot is in the same inventory -+ */ -+ public boolean isSameInventory(Slot other) -+ { -+ return this.inventory == other.inventory; -+ } -+ /*========================================= FORGE END =====================================*/ - } diff --git a/patches/minecraft/net/minecraft/inventory/SlotCrafting.java.patch b/patches/minecraft/net/minecraft/inventory/SlotCrafting.java.patch deleted file mode 100644 index 283bd4aa4..000000000 --- a/patches/minecraft/net/minecraft/inventory/SlotCrafting.java.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- before/net/minecraft/inventory/SlotCrafting.java -+++ after/net/minecraft/inventory/SlotCrafting.java -@@ -56,6 +56,7 @@ - if (this.amountCrafted > 0) - { - stack.onCrafting(this.player.world, this.player, this.amountCrafted); -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().firePlayerCraftingEvent(this.player, stack, craftMatrix); - } - - this.amountCrafted = 0; -@@ -73,7 +74,9 @@ - public ItemStack onTake(EntityPlayer thePlayer, ItemStack stack) - { - this.onCrafting(stack); -+ net.minecraftforge.common.ForgeHooks.setCraftingPlayer(thePlayer); - NonNullList nonnulllist = CraftingManager.getRemainingItems(this.craftMatrix, thePlayer.world); -+ net.minecraftforge.common.ForgeHooks.setCraftingPlayer(null); - - for (int i = 0; i < nonnulllist.size(); i++) - { diff --git a/patches/minecraft/net/minecraft/inventory/SlotFurnaceOutput.java.patch b/patches/minecraft/net/minecraft/inventory/SlotFurnaceOutput.java.patch deleted file mode 100644 index f6ddd378b..000000000 --- a/patches/minecraft/net/minecraft/inventory/SlotFurnaceOutput.java.patch +++ /dev/null @@ -1,9 +0,0 @@ ---- before/net/minecraft/inventory/SlotFurnaceOutput.java -+++ after/net/minecraft/inventory/SlotFurnaceOutput.java -@@ -94,5 +94,6 @@ - } - - this.removeCount = 0; -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().firePlayerSmeltedEvent(player, stack); - } - } diff --git a/patches/minecraft/net/minecraft/item/EnumRarity.java.patch b/patches/minecraft/net/minecraft/item/EnumRarity.java.patch deleted file mode 100644 index 6360bd802..000000000 --- a/patches/minecraft/net/minecraft/item/EnumRarity.java.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- before/net/minecraft/item/EnumRarity.java -+++ after/net/minecraft/item/EnumRarity.java -@@ -2,7 +2,7 @@ - - import net.minecraft.util.text.TextFormatting; - --public enum EnumRarity -+public enum EnumRarity implements net.minecraftforge.common.IRarity - { - COMMON(TextFormatting.WHITE, "Common"), - UNCOMMON(TextFormatting.YELLOW, "Uncommon"), -@@ -16,5 +16,17 @@ - { - this.color = color; - this.rarityName = name; -+ } -+ -+ @Override -+ public TextFormatting getColor() -+ { -+ return this.color; -+ } -+ -+ @Override -+ public String getName() -+ { -+ return this.rarityName; - } - } diff --git a/patches/minecraft/net/minecraft/item/Item.java.patch b/patches/minecraft/net/minecraft/item/Item.java.patch deleted file mode 100644 index 7f4bc46b8..000000000 --- a/patches/minecraft/net/minecraft/item/Item.java.patch +++ /dev/null @@ -1,903 +0,0 @@ ---- before/net/minecraft/item/Item.java -+++ after/net/minecraft/item/Item.java -@@ -58,10 +58,10 @@ - import net.minecraftforge.fml.relauncher.Side; - import net.minecraftforge.fml.relauncher.SideOnly; - --public class Item -+public class Item extends net.minecraftforge.registries.IForgeRegistryEntry.Impl - { -- public static final RegistryNamespaced REGISTRY = new RegistryNamespaced<>(); -- private static final Map BLOCK_TO_ITEM = Maps.newHashMap(); -+ public static final RegistryNamespaced REGISTRY = net.minecraftforge.registries.GameData.getWrapper(Item.class); -+ private static final Map BLOCK_TO_ITEM = net.minecraftforge.registries.GameData.getBlockItemMap(); - private static final IItemPropertyGetter DAMAGED_GETTER = new IItemPropertyGetter() - { - @SideOnly(Side.CLIENT) -@@ -209,6 +209,7 @@ - return stack; - } - -+ @Deprecated // Use ItemStack sensitive version below. - public int getItemStackLimit() - { - return this.maxStackSize; -@@ -230,6 +231,7 @@ - return this; - } - -+ @Deprecated - public int getMaxDamage() - { - return this.maxDamage; -@@ -329,6 +331,7 @@ - return this.containerItem; - } - -+ @Deprecated // Use ItemStack sensitive version below. - public boolean hasContainerItem() - { - return this.containerItem != null; -@@ -377,6 +380,7 @@ - return stack.isItemEnchanted(); - } - -+ @Deprecated // use Forge version - public EnumRarity getRarity(ItemStack stack) - { - return stack.isItemEnchanted() ? EnumRarity.RARE : EnumRarity.COMMON; -@@ -384,7 +388,7 @@ - - public boolean isEnchantable(ItemStack stack) - { -- return this.getItemStackLimit() == 1 && this.isDamageable(); -+ return this.getItemStackLimit(stack) == 1 && this.isDamageable(); - } - - protected RayTraceResult rayTrace(World worldIn, EntityPlayer playerIn, boolean useLiquids) -@@ -401,8 +405,8 @@ - float f5 = MathHelper.sin(-f * (float)(Math.PI / 180.0)); - float f6 = f3 * f4; - float f7 = f2 * f4; -- double d3 = 5.0; -- Vec3d vec3d1 = vec3d.add(f6 * 5.0, f5 * 5.0, f7 * 5.0); -+ double d3 = playerIn.getEntityAttribute(EntityPlayer.REACH_DISTANCE).getAttributeValue(); -+ Vec3d vec3d1 = vec3d.add(f6 * d3, f5 * d3, f7 * d3); - return worldIn.rayTraceBlocks(vec3d, vec3d1, useLiquids, !useLiquids, false); - } - -@@ -421,6 +425,9 @@ - - protected boolean isInCreativeTab(CreativeTabs targetTab) - { -+ for (CreativeTabs tab : this.getCreativeTabs()) -+ if (tab == targetTab) -+ return true; - CreativeTabs creativetabs = this.getCreativeTab(); - return creativetabs != null && (targetTab == CreativeTabs.SEARCH || targetTab == creativetabs); - } -@@ -447,11 +454,784 @@ - return false; - } - -+ @Deprecated // Use ItemStack sensitive version below. - public Multimap getItemAttributeModifiers(EntityEquipmentSlot equipmentSlot) - { - return HashMultimap.create(); - } - -+ /* ======================================== FORGE START =====================================*/ -+ /** -+ * ItemStack sensitive version of getItemAttributeModifiers -+ */ -+ public Multimap getAttributeModifiers(EntityEquipmentSlot slot, ItemStack stack) -+ { -+ return this.getItemAttributeModifiers(slot); -+ } -+ -+ /** -+ * Called when a player drops the item into the world, -+ * returning false from this will prevent the item from -+ * being removed from the players inventory and spawning -+ * in the world -+ * -+ * @param player The player that dropped the item -+ * @param item The item stack, before the item is removed. -+ */ -+ public boolean onDroppedByPlayer(ItemStack item, EntityPlayer player) -+ { -+ return true; -+ } -+ -+ /** -+ * Allow the item one last chance to modify its name used for the -+ * tool highlight useful for adding something extra that can't be removed -+ * by a user in the displayed name, such as a mode of operation. -+ * -+ * @param item the ItemStack for the item. -+ * @param displayName the name that will be displayed unless it is changed in this method. -+ */ -+ public String getHighlightTip( ItemStack item, String displayName ) -+ { -+ return displayName; -+ } -+ -+ /** -+ * This is called when the item is used, before the block is activated. -+ * @param stack The Item Stack -+ * @param player The Player that used the item -+ * @param world The Current World -+ * @param pos Target position -+ * @param side The side of the target hit -+ * @param hand Which hand the item is being held in. -+ * @return Return PASS to allow vanilla handling, any other to skip normal code. -+ */ -+ public EnumActionResult onItemUseFirst(EntityPlayer player, World world, BlockPos pos, EnumFacing side, float hitX, float hitY, float hitZ, EnumHand hand) -+ { -+ return EnumActionResult.PASS; -+ } -+ -+ protected boolean canRepair = true; -+ /** -+ * Called by CraftingManager to determine if an item is reparable. -+ * @return True if reparable -+ */ -+ public boolean isRepairable() -+ { -+ return canRepair && isDamageable(); -+ } -+ -+ /** -+ * Call to disable repair recipes. -+ * @return The current Item instance -+ */ -+ public Item setNoRepair() -+ { -+ canRepair = false; -+ return this; -+ } -+ -+ /** -+ * Determines the amount of durability the mending enchantment -+ * will repair, on average, per point of experience. -+ */ -+ public float getXpRepairRatio(ItemStack stack) -+ { -+ return 2f; -+ } -+ -+ /** -+ * Override this method to change the NBT data being sent to the client. -+ * You should ONLY override this when you have no other choice, as this might change behavior client side! -+ * -+ * Note that this will sometimes be applied multiple times, the following MUST be supported: -+ * Item item = stack.getItem(); -+ * NBTTagCompound nbtShare1 = item.getNBTShareTag(stack); -+ * stack.setTagCompound(nbtShare1); -+ * NBTTagCompound nbtShare2 = item.getNBTShareTag(stack); -+ * assert nbtShare1.equals(nbtShare2); -+ * -+ * @param stack The stack to send the NBT tag for -+ * @return The NBT tag -+ */ -+ @Nullable -+ public NBTTagCompound getNBTShareTag(ItemStack stack) -+ { -+ return stack.getTagCompound(); -+ } -+ -+ /** -+ * Override this method to decide what to do with the NBT data received from getNBTShareTag(). -+ * -+ * @param stack The stack that received NBT -+ * @param nbt Received NBT, can be null -+ */ -+ public void readNBTShareTag(ItemStack stack, @Nullable NBTTagCompound nbt) -+ { -+ stack.setTagCompound(nbt); -+ } -+ -+ /** -+ * Called before a block is broken. Return true to prevent default block harvesting. -+ * -+ * Note: In SMP, this is called on both client and server sides! -+ * -+ * @param itemstack The current ItemStack -+ * @param pos Block's position in world -+ * @param player The Player that is wielding the item -+ * @return True to prevent harvesting, false to continue as normal -+ */ -+ public boolean onBlockStartBreak(ItemStack itemstack, BlockPos pos, EntityPlayer player) -+ { -+ return false; -+ } -+ -+ /** -+ * Called each tick while using an item. -+ * @param stack The Item being used -+ * @param player The Player using the item -+ * @param count The amount of time in tick the item has been used for continuously -+ */ -+ public void onUsingTick(ItemStack stack, EntityLivingBase player, int count) -+ { -+ } -+ -+ /** -+ * Called when the player Left Clicks (attacks) an entity. -+ * Processed before damage is done, if return value is true further processing is canceled -+ * and the entity is not attacked. -+ * -+ * @param stack The Item being used -+ * @param player The player that is attacking -+ * @param entity The entity being attacked -+ * @return True to cancel the rest of the interaction. -+ */ -+ public boolean onLeftClickEntity(ItemStack stack, EntityPlayer player, Entity entity) -+ { -+ return false; -+ } -+ -+ /** -+ * ItemStack sensitive version of getContainerItem. -+ * Returns a full ItemStack instance of the result. -+ * -+ * @param itemStack The current ItemStack -+ * @return The resulting ItemStack -+ */ -+ public ItemStack getContainerItem(ItemStack itemStack) -+ { -+ if (!hasContainerItem(itemStack)) -+ { -+ return ItemStack.EMPTY; -+ } -+ return new ItemStack(getContainerItem()); -+ } -+ -+ /** -+ * ItemStack sensitive version of hasContainerItem -+ * @param stack The current item stack -+ * @return True if this item has a 'container' -+ */ -+ public boolean hasContainerItem(ItemStack stack) -+ { -+ return hasContainerItem(); -+ } -+ -+ /** -+ * Retrieves the normal 'lifespan' of this item when it is dropped on the ground as a EntityItem. -+ * This is in ticks, standard result is 6000, or 5 mins. -+ * -+ * @param itemStack The current ItemStack -+ * @param world The world the entity is in -+ * @return The normal lifespan in ticks. -+ */ -+ public int getEntityLifespan(ItemStack itemStack, World world) -+ { -+ return 6000; -+ } -+ -+ /** -+ * Determines if this Item has a special entity for when they are in the world. -+ * Is called when a EntityItem is spawned in the world, if true and Item#createCustomEntity -+ * returns non null, the EntityItem will be destroyed and the new Entity will be added to the world. -+ * -+ * @param stack The current item stack -+ * @return True of the item has a custom entity, If true, Item#createCustomEntity will be called -+ */ -+ public boolean hasCustomEntity(ItemStack stack) -+ { -+ return false; -+ } -+ -+ /** -+ * This function should return a new entity to replace the dropped item. -+ * Returning null here will not kill the EntityItem and will leave it to function normally. -+ * Called when the item it placed in a world. -+ * -+ * @param world The world object -+ * @param location The EntityItem object, useful for getting the position of the entity -+ * @param itemstack The current item stack -+ * @return A new Entity object to spawn or null -+ */ -+ @Nullable -+ public Entity createEntity(World world, Entity location, ItemStack itemstack) -+ { -+ return null; -+ } -+ -+ /** -+ * Called by the default implemetation of EntityItem's onUpdate method, allowing for cleaner -+ * control over the update of the item without having to write a subclass. -+ * -+ * @param entityItem The entity Item -+ * @return Return true to skip any further update code. -+ */ -+ public boolean onEntityItemUpdate(net.minecraft.entity.item.EntityItem entityItem) -+ { -+ return false; -+ } -+ -+ /** -+ * Gets a list of tabs that items belonging to this class can display on, -+ * combined properly with getSubItems allows for a single item to span -+ * many sub-items across many tabs. -+ * -+ * @return A list of all tabs that this item could possibly be one. -+ */ -+ public CreativeTabs[] getCreativeTabs() -+ { -+ return new CreativeTabs[]{ getCreativeTab() }; -+ } -+ -+ /** -+ * Determines the base experience for a player when they remove this item from a furnace slot. -+ * This number must be between 0 and 1 for it to be valid. -+ * This number will be multiplied by the stack size to get the total experience. -+ * -+ * @param item The item stack the player is picking up. -+ * @return The amount to award for each item. -+ */ -+ public float getSmeltingExperience(ItemStack item) -+ { -+ return -1; //-1 will default to the old lookups. -+ } -+ -+ /** -+ * -+ * Should this item, when held, allow sneak-clicks to pass through to the underlying block? -+ * -+ * @param world The world -+ * @param pos Block position in world -+ * @param player The Player that is wielding the item -+ * @return -+ */ -+ public boolean doesSneakBypassUse(ItemStack stack, net.minecraft.world.IBlockAccess world, BlockPos pos, EntityPlayer player) -+ { -+ return false; -+ } -+ -+ /** -+ * Called to tick armor in the armor slot. Override to do something -+ */ -+ public void onArmorTick(World world, EntityPlayer player, ItemStack itemStack){} -+ -+ /** -+ * Determines if the specific ItemStack can be placed in the specified armor slot, for the entity. -+ * -+ * TODO: Change name to canEquip in 1.13? -+ * -+ * @param stack The ItemStack -+ * @param armorType Armor slot to be verified. -+ * @param entity The entity trying to equip the armor -+ * @return True if the given ItemStack can be inserted in the slot -+ */ -+ public boolean isValidArmor(ItemStack stack, EntityEquipmentSlot armorType, Entity entity) -+ { -+ return net.minecraft.entity.EntityLiving.getSlotForItemStack(stack) == armorType; -+ } -+ -+ /** -+ * Override this to set a non-default armor slot for an ItemStack, but -+ * do not use this to get the armor slot of said stack; for that, use -+ * {@link net.minecraft.entity.EntityLiving#getSlotForItemStack(ItemStack)}. -+ * -+ * @param stack the ItemStack -+ * @return the armor slot of the ItemStack, or {@code null} to let the default -+ * vanilla logic as per {@code EntityLiving.getSlotForItemStack(stack)} decide -+ */ -+ @Nullable -+ public EntityEquipmentSlot getEquipmentSlot(ItemStack stack) -+ { -+ return null; -+ } -+ -+ /** -+ * Allow or forbid the specific book/item combination as an anvil enchant -+ * -+ * @param stack The item -+ * @param book The book -+ * @return if the enchantment is allowed -+ */ -+ public boolean isBookEnchantable(ItemStack stack, ItemStack book) -+ { -+ return true; -+ } -+ -+ /** -+ * Called by RenderBiped and RenderPlayer to determine the armor texture that -+ * should be use for the currently equipped item. -+ * This will only be called on instances of ItemArmor. -+ * -+ * Returning null from this function will use the default value. -+ * -+ * @param stack ItemStack for the equipped armor -+ * @param entity The entity wearing the armor -+ * @param slot The slot the armor is in -+ * @param type The subtype, can be null or "overlay" -+ * @return Path of texture to bind, or null to use default -+ */ -+ @Nullable -+ public String getArmorTexture(ItemStack stack, Entity entity, EntityEquipmentSlot slot, String type) -+ { -+ return null; -+ } -+ -+ /** -+ * Returns the font renderer used to render tooltips and overlays for this item. -+ * Returning null will use the standard font renderer. -+ * -+ * @param stack The current item stack -+ * @return A instance of FontRenderer or null to use default -+ */ -+ @SideOnly(Side.CLIENT) -+ @Nullable -+ public net.minecraft.client.gui.FontRenderer getFontRenderer(ItemStack stack) -+ { -+ return null; -+ } -+ -+ /** -+ * Override this method to have an item handle its own armor rendering. -+ * -+ * @param entityLiving The entity wearing the armor -+ * @param itemStack The itemStack to render the model of -+ * @param armorSlot The slot the armor is in -+ * @param _default Original armor model. Will have attributes set. -+ * @return A ModelBiped to render instead of the default -+ */ -+ @SideOnly(Side.CLIENT) -+ @Nullable -+ public net.minecraft.client.model.ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack itemStack, EntityEquipmentSlot armorSlot, net.minecraft.client.model.ModelBiped _default) -+ { -+ return null; -+ } -+ -+ /** -+ * Called when a entity tries to play the 'swing' animation. -+ * -+ * @param entityLiving The entity swinging the item. -+ * @param stack The Item stack -+ * @return True to cancel any further processing by EntityLiving -+ */ -+ public boolean onEntitySwing(EntityLivingBase entityLiving, ItemStack stack) -+ { -+ return false; -+ } -+ -+ /** -+ * Called when the client starts rendering the HUD, for whatever item the player currently has as a helmet. -+ * This is where pumpkins would render there overlay. -+ * -+ * @param stack The ItemStack that is equipped -+ * @param player Reference to the current client entity -+ * @param resolution Resolution information about the current viewport and configured GUI Scale -+ * @param partialTicks Partial ticks for the renderer, useful for interpolation -+ */ -+ @SideOnly(Side.CLIENT) -+ public void renderHelmetOverlay(ItemStack stack, EntityPlayer player, net.minecraft.client.gui.ScaledResolution resolution, float partialTicks){} -+ -+ /** -+ * Return the itemDamage represented by this ItemStack. Defaults to the itemDamage field on ItemStack, but can be overridden here for other sources such as NBT. -+ * -+ * @param stack The itemstack that is damaged -+ * @return the damage value -+ */ -+ public int getDamage(ItemStack stack) -+ { -+ return stack.itemDamage; -+ } -+ -+ /** -+ * This used to be 'display damage' but its really just 'aux' data in the ItemStack, usually shares the same variable as damage. -+ * @param stack -+ * @return -+ */ -+ public int getMetadata(ItemStack stack) -+ { -+ return stack.itemDamage; -+ } -+ -+ /** -+ * Determines if the durability bar should be rendered for this item. -+ * Defaults to vanilla stack.isDamaged behavior. -+ * But modders can use this for any data they wish. -+ * -+ * @param stack The current Item Stack -+ * @return True if it should render the 'durability' bar. -+ */ -+ public boolean showDurabilityBar(ItemStack stack) -+ { -+ return stack.isItemDamaged(); -+ } -+ -+ /** -+ * Queries the percentage of the 'Durability' bar that should be drawn. -+ * -+ * @param stack The current ItemStack -+ * @return 0.0 for 100% (no damage / full bar), 1.0 for 0% (fully damaged / empty bar) -+ */ -+ public double getDurabilityForDisplay(ItemStack stack) -+ { -+ return (double)stack.getItemDamage() / (double)stack.getMaxDamage(); -+ } -+ -+ /** -+ * Returns the packed int RGB value used to render the durability bar in the GUI. -+ * Defaults to a value based on the hue scaled based on {@link #getDurabilityForDisplay}, but can be overriden. -+ * -+ * @param stack Stack to get durability from -+ * @return A packed RGB value for the durability colour (0x00RRGGBB) -+ */ -+ public int getRGBDurabilityForDisplay(ItemStack stack) -+ { -+ return MathHelper.hsvToRGB(Math.max(0.0F, (float) (1.0F - getDurabilityForDisplay(stack))) / 3.0F, 1.0F, 1.0F); -+ } -+ /** -+ * Return the maxDamage for this ItemStack. Defaults to the maxDamage field in this item, -+ * but can be overridden here for other sources such as NBT. -+ * -+ * @param stack The itemstack that is damaged -+ * @return the damage value -+ */ -+ public int getMaxDamage(ItemStack stack) -+ { -+ return getMaxDamage(); -+ } -+ -+ /** -+ * Return if this itemstack is damaged. Note only called if {@link #isDamageable()} is true. -+ * @param stack the stack -+ * @return if the stack is damaged -+ */ -+ public boolean isDamaged(ItemStack stack) -+ { -+ return stack.itemDamage > 0; -+ } -+ -+ /** -+ * Set the damage for this itemstack. Note, this method is responsible for zero checking. -+ * @param stack the stack -+ * @param damage the new damage value -+ */ -+ public void setDamage(ItemStack stack, int damage) -+ { -+ stack.itemDamage = damage; -+ -+ if (stack.itemDamage < 0) -+ { -+ stack.itemDamage = 0; -+ } -+ } -+ -+ /** -+ * Checked from {@link net.minecraft.client.multiplayer.PlayerControllerMP#onPlayerDestroyBlock(BlockPos pos) PlayerControllerMP.onPlayerDestroyBlock()} -+ * when a creative player left-clicks a block with this item. -+ * Also checked from {@link net.minecraftforge.common.ForgeHooks#onBlockBreakEvent(World, GameType, EntityPlayerMP, BlockPos) ForgeHooks.onBlockBreakEvent()} -+ * to prevent sending an event. -+ * @return true if the given player can destroy specified block in creative mode with this item -+ */ -+ public boolean canDestroyBlockInCreative(World world, BlockPos pos, ItemStack stack, EntityPlayer player) -+ { -+ return !(this instanceof ItemSword); -+ } -+ -+ /** -+ * ItemStack sensitive version of {@link #canHarvestBlock(IBlockState)} -+ * @param state The block trying to harvest -+ * @param stack The itemstack used to harvest the block -+ * @return true if can harvest the block -+ */ -+ public boolean canHarvestBlock(IBlockState state, ItemStack stack) -+ { -+ return canHarvestBlock(state); -+ } -+ -+ /** -+ * Gets the maximum number of items that this stack should be able to hold. -+ * This is a ItemStack (and thus NBT) sensitive version of Item.getItemStackLimit() -+ * -+ * @param stack The ItemStack -+ * @return The maximum number this item can be stacked to -+ */ -+ public int getItemStackLimit(ItemStack stack) -+ { -+ return this.getItemStackLimit(); -+ } -+ -+ private java.util.Map toolClasses = new java.util.HashMap(); -+ /** -+ * Sets or removes the harvest level for the specified tool class. -+ * -+ * @param toolClass Class -+ * @param level Harvest level: -+ * Wood: 0 -+ * Stone: 1 -+ * Iron: 2 -+ * Diamond: 3 -+ * Gold: 0 -+ */ -+ public void setHarvestLevel(String toolClass, int level) -+ { -+ if (level < 0) -+ toolClasses.remove(toolClass); -+ else -+ toolClasses.put(toolClass, level); -+ } -+ -+ public java.util.Set getToolClasses(ItemStack stack) -+ { -+ return toolClasses.keySet(); -+ } -+ -+ /** -+ * Queries the harvest level of this item stack for the specified tool class, -+ * Returns -1 if this tool is not of the specified type -+ * -+ * @param stack This item stack instance -+ * @param toolClass Tool Class -+ * @param player The player trying to harvest the given blockstate -+ * @param blockState The block to harvest -+ * @return Harvest level, or -1 if not the specified tool type. -+ */ -+ public int getHarvestLevel(ItemStack stack, String toolClass, @Nullable EntityPlayer player, @Nullable IBlockState blockState) -+ { -+ Integer ret = toolClasses.get(toolClass); -+ return ret == null ? -1 : ret; -+ } -+ -+ /** -+ * ItemStack sensitive version of getItemEnchantability -+ * -+ * @param stack The ItemStack -+ * @return the item echantability value -+ */ -+ public int getItemEnchantability(ItemStack stack) -+ { -+ return getItemEnchantability(); -+ } -+ -+ /** -+ * Checks whether an item can be enchanted with a certain enchantment. This applies specifically to enchanting an item in the enchanting table and is called when retrieving the list of possible enchantments for an item. -+ * Enchantments may additionally (or exclusively) be doing their own checks in {@link net.minecraft.enchantment.Enchantment#canApplyAtEnchantingTable(ItemStack)}; check the individual implementation for reference. -+ * By default this will check if the enchantment type is valid for this item type. -+ * @param stack the item stack to be enchanted -+ * @param enchantment the enchantment to be applied -+ * @return true if the enchantment can be applied to this item -+ */ -+ public boolean canApplyAtEnchantingTable(ItemStack stack, net.minecraft.enchantment.Enchantment enchantment) -+ { -+ return enchantment.type.canEnchantItem(stack.getItem()); -+ } -+ -+ /** -+ * Whether this Item can be used as a payment to activate the vanilla beacon. -+ * @param stack the ItemStack -+ * @return true if this Item can be used -+ */ -+ public boolean isBeaconPayment(ItemStack stack) -+ { -+ return this == Items.EMERALD || this == Items.DIAMOND || this == Items.GOLD_INGOT || this == Items.IRON_INGOT; -+ } -+ -+ /** -+ * Determine if the player switching between these two item stacks -+ * @param oldStack The old stack that was equipped -+ * @param newStack The new stack -+ * @param slotChanged If the current equipped slot was changed, -+ * Vanilla does not play the animation if you switch between two -+ * slots that hold the exact same item. -+ * @return True to play the item change animation -+ */ -+ public boolean shouldCauseReequipAnimation(ItemStack oldStack, ItemStack newStack, boolean slotChanged) -+ { -+ return !oldStack.equals(newStack); //!ItemStack.areItemStacksEqual(oldStack, newStack); -+ } -+ -+ /** -+ * Called when the player is mining a block and the item in his hand changes. -+ * Allows to not reset blockbreaking if only NBT or similar changes. -+ * @param oldStack The old stack that was used for mining. Item in players main hand -+ * @param newStack The new stack -+ * @return True to reset block break progress -+ */ -+ public boolean shouldCauseBlockBreakReset(ItemStack oldStack, ItemStack newStack) -+ { -+ return !(newStack.getItem() == oldStack.getItem() && ItemStack.areItemStackTagsEqual(newStack, oldStack) && (newStack.isItemStackDamageable() || newStack.getMetadata() == oldStack.getMetadata())); -+ } -+ -+ /** -+ * Called while an item is in 'active' use to determine if usage should continue. -+ * Allows items to continue being used while sustaining damage, for example. -+ * -+ * @param oldStack the previous 'active' stack -+ * @param newStack the stack currently in the active hand -+ * @return true to set the new stack to active and continue using it -+ */ -+ public boolean canContinueUsing(ItemStack oldStack, ItemStack newStack) -+ { -+ return oldStack.equals(newStack); -+ } -+ -+ /** -+ * Called to get the Mod ID of the mod that *created* the ItemStack, -+ * instead of the real Mod ID that *registered* it. -+ * -+ * For example the Forge Universal Bucket creates a subitem for each modded fluid, -+ * and it returns the modded fluid's Mod ID here. -+ * -+ * Mods that register subitems for other mods can override this. -+ * Informational mods can call it to show the mod that created the item. -+ * -+ * @param itemStack the ItemStack to check -+ * @return the Mod ID for the ItemStack, or -+ * null when there is no specially associated mod and {@link #getRegistryName()} would return null. -+ */ -+ @Nullable -+ public String getCreatorModId(ItemStack itemStack) -+ { -+ return net.minecraftforge.common.ForgeHooks.getDefaultCreatorModId(itemStack); -+ } -+ -+ /** -+ * Called from ItemStack.setItem, will hold extra data for the life of this ItemStack. -+ * Can be retrieved from stack.getCapabilities() -+ * The NBT can be null if this is not called from readNBT or if the item the stack is -+ * changing FROM is different then this item, or the previous item had no capabilities. -+ * -+ * This is called BEFORE the stacks item is set so you can use stack.getItem() to see the OLD item. -+ * Remember that getItem CAN return null. -+ * -+ * @param stack The ItemStack -+ * @param nbt NBT of this item serialized, or null. -+ * @return A holder instance associated with this ItemStack where you can hold capabilities for the life of this item. -+ */ -+ @Nullable -+ public net.minecraftforge.common.capabilities.ICapabilityProvider initCapabilities(ItemStack stack, @Nullable NBTTagCompound nbt) -+ { -+ return null; -+ } -+ -+ public com.google.common.collect.ImmutableMap getAnimationParameters(final ItemStack stack, final World world, final EntityLivingBase entity) -+ { -+ com.google.common.collect.ImmutableMap.Builder builder = com.google.common.collect.ImmutableMap.builder(); -+ for(ResourceLocation location : properties.getKeys()) -+ { -+ final IItemPropertyGetter parameter = properties.getObject(location); -+ builder.put(location.toString(), new net.minecraftforge.common.animation.ITimeValue() -+ { -+ public float apply(float input) -+ { -+ return parameter.apply(stack, world, entity); -+ } -+ }); -+ } -+ return builder.build(); -+ } -+ -+ /** -+ * Can this Item disable a shield -+ * @param stack The ItemStack -+ * @param shield The shield in question -+ * @param entity The EntityLivingBase holding the shield -+ * @param attacker The EntityLivingBase holding the ItemStack -+ * @retrun True if this ItemStack can disable the shield in question. -+ */ -+ public boolean canDisableShield(ItemStack stack, ItemStack shield, EntityLivingBase entity, EntityLivingBase attacker) -+ { -+ return this instanceof ItemAxe; -+ } -+ -+ /** -+ * Is this Item a shield -+ * @param stack The ItemStack -+ * @param entity The Entity holding the ItemStack -+ * @return True if the ItemStack is considered a shield -+ */ -+ public boolean isShield(ItemStack stack, @Nullable EntityLivingBase entity) -+ { -+ return stack.getItem() == Items.SHIELD; -+ } -+ -+ /** -+ * @return the fuel burn time for this itemStack in a furnace. -+ * Return 0 to make it not act as a fuel. -+ * Return -1 to let the default vanilla logic decide. -+ */ -+ public int getItemBurnTime(ItemStack itemStack) -+ { -+ return -1; -+ } -+ -+ /** -+ * Returns an enum constant of type {@code HorseArmorType}. -+ * The returned enum constant will be used to determine the armor value and texture of this item when equipped. -+ * @param stack the armor stack -+ * @return an enum constant of type {@code HorseArmorType}. Return HorseArmorType.NONE if this is not horse armor -+ */ -+ public net.minecraft.entity.passive.HorseArmorType getHorseArmorType(ItemStack stack) -+ { -+ return net.minecraft.entity.passive.HorseArmorType.getByItem(stack.getItem()); -+ } -+ -+ public String getHorseArmorTexture(net.minecraft.entity.EntityLiving wearer, ItemStack stack) -+ { -+ return getHorseArmorType(stack).getTextureName(); -+ } -+ -+ /** -+ * Called every tick from {@link EntityHorse#onUpdate()} on the item in the armor slot. -+ * @param world the world the horse is in -+ * @param horse the horse wearing this armor -+ * @param armor the armor itemstack -+ */ -+ public void onHorseArmorTick(World world, net.minecraft.entity.EntityLiving horse, ItemStack armor) {} -+ -+ @SideOnly(Side.CLIENT) -+ @Nullable -+ private net.minecraft.client.renderer.tileentity.TileEntityItemStackRenderer teisr; -+ -+ /** -+ * @return This Item's renderer, or the default instance if it does not have one. -+ */ -+ @SideOnly(Side.CLIENT) -+ public final net.minecraft.client.renderer.tileentity.TileEntityItemStackRenderer getTileEntityItemStackRenderer() -+ { -+ return teisr != null ? teisr : net.minecraft.client.renderer.tileentity.TileEntityItemStackRenderer.instance; -+ } -+ -+ @SideOnly(Side.CLIENT) -+ public void setTileEntityItemStackRenderer(@Nullable net.minecraft.client.renderer.tileentity.TileEntityItemStackRenderer teisr) -+ { -+ this.teisr = teisr; -+ } -+ -+ public net.minecraftforge.common.IRarity getForgeRarity(ItemStack stack) -+ { -+ return this.getRarity(stack); -+ } -+ -+ /* ======================================== FORGE END =====================================*/ -+ - public static void registerItems() - { - registerItemBlock(Blocks.AIR, new ItemAir(Blocks.AIR)); -@@ -1041,6 +1821,8 @@ - private final float efficiency; - private final float attackDamage; - private final int enchantability; -+ //Added by forge for custom Tool materials. -+ private ItemStack repairMaterial = ItemStack.EMPTY; - - private ToolMaterial(int harvestLevel, int maxUses, float efficiency, float damageVsEntity, int enchantability) - { -@@ -1076,6 +1858,7 @@ - return this.enchantability; - } - -+ @Deprecated // Use getRepairItemStack below - public Item getRepairItem() - { - if (this == WOOD) -@@ -1098,6 +1881,22 @@ - { - return this == DIAMOND ? Items.DIAMOND : null; - } -+ } -+ -+ public ToolMaterial setRepairItem(ItemStack stack) -+ { -+ if (!this.repairMaterial.isEmpty()) throw new RuntimeException("Repair material has already been set"); -+ if (this == WOOD || this == STONE || this == GOLD || this == IRON || this == DIAMOND) throw new RuntimeException("Can not change vanilla tool repair materials"); -+ this.repairMaterial = stack; -+ return this; -+ } -+ -+ public ItemStack getRepairItemStack() -+ { -+ if (!repairMaterial.isEmpty()) return repairMaterial; -+ Item ret = this.getRepairItem(); -+ if (ret != null) repairMaterial = new ItemStack(ret, 1, net.minecraftforge.oredict.OreDictionary.WILDCARD_VALUE); -+ return repairMaterial; - } - } - } diff --git a/patches/minecraft/net/minecraft/item/ItemArmor.java.patch b/patches/minecraft/net/minecraft/item/ItemArmor.java.patch deleted file mode 100644 index a5dafd7fa..000000000 --- a/patches/minecraft/net/minecraft/item/ItemArmor.java.patch +++ /dev/null @@ -1,73 +0,0 @@ ---- before/net/minecraft/item/ItemArmor.java -+++ after/net/minecraft/item/ItemArmor.java -@@ -206,7 +206,9 @@ - @Override - public boolean getIsRepairable(ItemStack toRepair, ItemStack repair) - { -- return this.material.getRepairItem() == repair.getItem() ? true : super.getIsRepairable(toRepair, repair); -+ ItemStack mat = this.material.getRepairItemStack(); -+ if (!mat.isEmpty() && net.minecraftforge.oredict.OreDictionary.itemMatches(mat,repair,false)) return true; -+ return super.getIsRepairable(toRepair, repair); - } - - @Override -@@ -248,6 +250,19 @@ - return multimap; - } - -+ /** -+ * Determines if this armor will be rendered with the secondary 'overlay' texture. -+ * If this is true, the first texture will be rendered using a tint of the color -+ * specified by getColor(ItemStack) -+ * -+ * @param stack The stack -+ * @return true/false -+ */ -+ public boolean hasOverlay(ItemStack stack) -+ { -+ return this.material == ItemArmor.ArmorMaterial.LEATHER || getColor(stack) != 0x00FFFFFF; -+ } -+ - public static enum ArmorMaterial - { - LEATHER("leather", 5, new int[]{1, 2, 3, 1}, 15, SoundEvents.ITEM_ARMOR_EQUIP_LEATHER, 0.0F), -@@ -262,6 +277,8 @@ - private final int enchantability; - private final SoundEvent soundEvent; - private final float toughness; -+ //Added by forge for custom Armor materials. -+ public ItemStack repairMaterial = ItemStack.EMPTY; - - private ArmorMaterial(String nameIn, int maxDamageFactorIn, int[] damageReductionAmountArrayIn, int enchantabilityIn, SoundEvent soundEventIn, float toughnessIn) - { -@@ -293,6 +310,7 @@ - return this.soundEvent; - } - -+ @Deprecated // Use getRepairItemStack below - public Item getRepairItem() - { - if (this == LEATHER) -@@ -326,6 +344,22 @@ - public float getToughness() - { - return this.toughness; -+ } -+ -+ public ArmorMaterial setRepairItem(ItemStack stack) -+ { -+ if (!this.repairMaterial.isEmpty()) throw new RuntimeException("Repair material has already been set"); -+ if (this == LEATHER || this == CHAIN || this == GOLD || this == IRON || this == DIAMOND) throw new RuntimeException("Can not change vanilla armor repair materials"); -+ this.repairMaterial = stack; -+ return this; -+ } -+ -+ public ItemStack getRepairItemStack() -+ { -+ if (!repairMaterial.isEmpty()) return repairMaterial; -+ Item ret = this.getRepairItem(); -+ if (ret != null) repairMaterial = new ItemStack(ret,1,net.minecraftforge.oredict.OreDictionary.WILDCARD_VALUE); -+ return repairMaterial; - } - } - } diff --git a/patches/minecraft/net/minecraft/item/ItemArrow.java.patch b/patches/minecraft/net/minecraft/item/ItemArrow.java.patch deleted file mode 100644 index 7cad9ccb0..000000000 --- a/patches/minecraft/net/minecraft/item/ItemArrow.java.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- before/net/minecraft/item/ItemArrow.java -+++ after/net/minecraft/item/ItemArrow.java -@@ -19,4 +19,10 @@ - entitytippedarrow.setPotionEffect(stack); - return entitytippedarrow; - } -+ -+ public boolean isInfinite(ItemStack stack, ItemStack bow, net.minecraft.entity.player.EntityPlayer player) -+ { -+ int enchant = net.minecraft.enchantment.EnchantmentHelper.getEnchantmentLevel(net.minecraft.init.Enchantments.INFINITY, bow); -+ return enchant <= 0 ? false : this.getClass() == ItemArrow.class; -+ } - } diff --git a/patches/minecraft/net/minecraft/item/ItemAxe.java.patch b/patches/minecraft/net/minecraft/item/ItemAxe.java.patch deleted file mode 100644 index 17dec4aa4..000000000 --- a/patches/minecraft/net/minecraft/item/ItemAxe.java.patch +++ /dev/null @@ -1,16 +0,0 @@ ---- before/net/minecraft/item/ItemAxe.java -+++ after/net/minecraft/item/ItemAxe.java -@@ -32,6 +32,13 @@ - this.attackSpeed = ATTACK_SPEEDS[material.ordinal()]; - } - -+ protected ItemAxe(Item.ToolMaterial material, float damage, float speed) -+ { -+ super(material, EFFECTIVE_ON); -+ this.attackDamage = damage; -+ this.attackSpeed = speed; -+ } -+ - @Override - public float getDestroySpeed(ItemStack stack, IBlockState state) - { diff --git a/patches/minecraft/net/minecraft/item/ItemBed.java.patch b/patches/minecraft/net/minecraft/item/ItemBed.java.patch deleted file mode 100644 index b605e5089..000000000 --- a/patches/minecraft/net/minecraft/item/ItemBed.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/item/ItemBed.java -+++ after/net/minecraft/item/ItemBed.java -@@ -84,7 +84,7 @@ - .withProperty(BlockBed.PART, BlockBed.EnumPartType.FOOT); - worldIn.setBlockState(pos, iblockstate2, 10); - worldIn.setBlockState(blockpos, iblockstate2.withProperty(BlockBed.PART, BlockBed.EnumPartType.HEAD), 10); -- SoundType soundtype = iblockstate2.getBlock().getSoundType(); -+ SoundType soundtype = iblockstate2.getBlock().getSoundType(iblockstate2, worldIn, pos, player); - worldIn.playSound( - null, - pos, diff --git a/patches/minecraft/net/minecraft/item/ItemBlock.java.patch b/patches/minecraft/net/minecraft/item/ItemBlock.java.patch deleted file mode 100644 index a4ac03a25..000000000 --- a/patches/minecraft/net/minecraft/item/ItemBlock.java.patch +++ /dev/null @@ -1,90 +0,0 @@ ---- before/net/minecraft/item/ItemBlock.java -+++ after/net/minecraft/item/ItemBlock.java -@@ -57,28 +57,16 @@ - - if (!itemstack.isEmpty() - && player.canPlayerEdit(pos, facing, itemstack) -- && worldIn.mayPlace(this.block, pos, false, facing, null)) -+ && worldIn.mayPlace(this.block, pos, false, facing, player)) - { - int i = this.getMetadata(itemstack.getMetadata()); - IBlockState iblockstate1 = this.block -- .getStateForPlacement(worldIn, pos, facing, hitX, hitY, hitZ, i, player); -+ .getStateForPlacement(worldIn, pos, facing, hitX, hitY, hitZ, i, player, hand); - -- if (worldIn.setBlockState(pos, iblockstate1, 11)) -+ if (placeBlockAt(itemstack, player, worldIn, pos, facing, hitX, hitY, hitZ, iblockstate1)) - { - iblockstate1 = worldIn.getBlockState(pos); -- -- if (iblockstate1.getBlock() == this.block) -- { -- setTileEntityNBT(worldIn, player, pos, itemstack); -- this.block.onBlockPlacedBy(worldIn, pos, iblockstate1, player, itemstack); -- -- if (player instanceof EntityPlayerMP) -- { -- CriteriaTriggers.PLACED_BLOCK.trigger((EntityPlayerMP)player, pos, itemstack); -- } -- } -- -- SoundType soundtype = this.block.getSoundType(); -+ SoundType soundtype = iblockstate1.getBlock().getSoundType(iblockstate1, worldIn, pos, player); - worldIn.playSound( - player, - pos, -@@ -146,7 +134,7 @@ - { - Block block = worldIn.getBlockState(pos).getBlock(); - -- if (block == Blocks.SNOW_LAYER) -+ if (block == Blocks.SNOW_LAYER && block.isReplaceable(worldIn, pos)) - { - side = EnumFacing.UP; - } -@@ -155,7 +143,7 @@ - pos = pos.offset(side); - } - -- return worldIn.mayPlace(this.block, pos, false, side, null); -+ return worldIn.mayPlace(this.block, pos, false, side, player); - } - - @Override -@@ -195,6 +183,36 @@ - - public Block getBlock() - { -+ return this.getBlockRaw() == null ? null : this.getBlockRaw().delegate.get(); -+ } -+ -+ private Block getBlockRaw() -+ { - return this.block; -+ } -+ -+ /** -+ * Called to actually place the block, after the location is determined -+ * and all permission checks have been made. -+ * -+ * @param stack The item stack that was used to place the block. This can be changed inside the method. -+ * @param player The player who is placing the block. Can be null if the block is not being placed by a player. -+ * @param side The side the player (or machine) right-clicked on. -+ */ -+ public boolean placeBlockAt(ItemStack stack, EntityPlayer player, World world, BlockPos pos, EnumFacing side, float hitX, float hitY, float hitZ, IBlockState newState) -+ { -+ if (!world.setBlockState(pos, newState, 11)) return false; -+ -+ IBlockState state = world.getBlockState(pos); -+ if (state.getBlock() == this.block) -+ { -+ setTileEntityNBT(world, player, pos, stack); -+ this.block.onBlockPlacedBy(world, pos, state, player, stack); -+ -+ if (player instanceof EntityPlayerMP) -+ CriteriaTriggers.PLACED_BLOCK.trigger((EntityPlayerMP)player, pos, stack); -+ } -+ -+ return true; - } - } diff --git a/patches/minecraft/net/minecraft/item/ItemBlockSpecial.java.patch b/patches/minecraft/net/minecraft/item/ItemBlockSpecial.java.patch deleted file mode 100644 index b21a6a07a..000000000 --- a/patches/minecraft/net/minecraft/item/ItemBlockSpecial.java.patch +++ /dev/null @@ -1,40 +0,0 @@ ---- before/net/minecraft/item/ItemBlockSpecial.java -+++ after/net/minecraft/item/ItemBlockSpecial.java -@@ -52,10 +52,10 @@ - - if (!itemstack.isEmpty() - && player.canPlayerEdit(pos, facing, itemstack) -- && worldIn.mayPlace(this.block, pos, false, facing, null)) -+ && worldIn.mayPlace(this.block, pos, false, facing, player)) - { - IBlockState iblockstate1 = this.block -- .getStateForPlacement(worldIn, pos, facing, hitX, hitY, hitZ, 0, player); -+ .getStateForPlacement(worldIn, pos, facing, hitX, hitY, hitZ, 0, player, hand); - - if (!worldIn.setBlockState(pos, iblockstate1, 11)) - { -@@ -76,7 +76,7 @@ - } - } - -- SoundType soundtype = this.block.getSoundType(); -+ SoundType soundtype = iblockstate1.getBlock().getSoundType(iblockstate1, worldIn, pos, player); - worldIn.playSound( - player, - pos, -@@ -93,5 +93,15 @@ - { - return EnumActionResult.FAIL; - } -+ } -+ -+ public Block getBlock() -+ { -+ return this.getBlockRaw() == null ? null : this.getBlockRaw().delegate.get(); -+ } -+ -+ private Block getBlockRaw() -+ { -+ return this.block; - } - } diff --git a/patches/minecraft/net/minecraft/item/ItemBow.java.patch b/patches/minecraft/net/minecraft/item/ItemBow.java.patch deleted file mode 100644 index 2e6c43161..000000000 --- a/patches/minecraft/net/minecraft/item/ItemBow.java.patch +++ /dev/null @@ -1,63 +0,0 @@ ---- before/net/minecraft/item/ItemBow.java -+++ after/net/minecraft/item/ItemBow.java -@@ -40,7 +40,7 @@ - } - else - { -- return entityIn.getActiveItemStack().getItem() != Items.BOW -+ return !(entityIn.getActiveItemStack().getItem() instanceof ItemBow) - ? 0.0F - : (stack.getMaxItemUseDuration() - entityIn.getItemInUseCount()) / 20.0F; - } -@@ -98,6 +98,10 @@ - boolean flag = entityplayer.capabilities.isCreativeMode || EnchantmentHelper.getEnchantmentLevel(Enchantments.INFINITY, stack) > 0; - ItemStack itemstack = this.findAmmo(entityplayer); - -+ int i = this.getMaxItemUseDuration(stack) - timeLeft; -+ i = net.minecraftforge.event.ForgeEventFactory.onArrowLoose(stack, worldIn, entityplayer, i, !itemstack.isEmpty() || flag); -+ if (i < 0) return; -+ - if (!itemstack.isEmpty() || flag) - { - if (itemstack.isEmpty()) -@@ -105,17 +109,17 @@ - itemstack = new ItemStack(Items.ARROW); - } - -- int i = this.getMaxItemUseDuration(stack) - timeLeft; - float f = getArrowVelocity(i); - - if (!(f < 0.1)) - { -- boolean flag1 = flag && itemstack.getItem() == Items.ARROW; -+ boolean flag1 = entityplayer.capabilities.isCreativeMode || (itemstack.getItem() instanceof ItemArrow && ((ItemArrow) itemstack.getItem()).isInfinite(itemstack, stack, entityplayer)); - - if (!worldIn.isRemote) - { - ItemArrow itemarrow = (ItemArrow)(itemstack.getItem() instanceof ItemArrow ? itemstack.getItem() : Items.ARROW); - EntityArrow entityarrow = itemarrow.createArrow(worldIn, itemstack, entityplayer); -+ entityarrow = this.customizeArrow(entityarrow); - entityarrow.shoot(entityplayer, entityplayer.rotationPitch, entityplayer.rotationYaw, 0.0F, f * 3.0F, 1.0F); - - if (f == 1.0F) -@@ -212,6 +216,9 @@ - ItemStack itemstack = playerIn.getHeldItem(handIn); - boolean flag = !this.findAmmo(playerIn).isEmpty(); - -+ ActionResult ret = net.minecraftforge.event.ForgeEventFactory.onArrowNock(itemstack, worldIn, playerIn, handIn, flag); -+ if (ret != null) return ret; -+ - if (playerIn.capabilities.isCreativeMode || flag) - { - playerIn.setActiveHand(handIn); -@@ -227,5 +234,10 @@ - public int getItemEnchantability() - { - return 1; -+ } -+ -+ public EntityArrow customizeArrow(EntityArrow arrow) -+ { -+ return arrow; - } - } diff --git a/patches/minecraft/net/minecraft/item/ItemBucket.java.patch b/patches/minecraft/net/minecraft/item/ItemBucket.java.patch deleted file mode 100644 index 4570c8b1d..000000000 --- a/patches/minecraft/net/minecraft/item/ItemBucket.java.patch +++ /dev/null @@ -1,30 +0,0 @@ ---- before/net/minecraft/item/ItemBucket.java -+++ after/net/minecraft/item/ItemBucket.java -@@ -41,6 +41,8 @@ - boolean flag = this.containedBlock == Blocks.AIR; - ItemStack itemstack = playerIn.getHeldItem(handIn); - RayTraceResult raytraceresult = this.rayTrace(worldIn, playerIn, flag); -+ ActionResult ret = net.minecraftforge.event.ForgeEventFactory.onBucketUse(playerIn, worldIn, itemstack, raytraceresult); -+ if (ret != null) return ret; - - if (raytraceresult == null) - { -@@ -196,6 +198,18 @@ - - return true; - } -+ } -+ } -+ -+ @Override -+ public net.minecraftforge.common.capabilities.ICapabilityProvider initCapabilities(ItemStack stack, @Nullable net.minecraft.nbt.NBTTagCompound nbt) { -+ if (this.getClass() == ItemBucket.class) -+ { -+ return new net.minecraftforge.fluids.capability.wrappers.FluidBucketWrapper(stack); -+ } -+ else -+ { -+ return super.initCapabilities(stack, nbt); - } - } - } diff --git a/patches/minecraft/net/minecraft/item/ItemBucketMilk.java.patch b/patches/minecraft/net/minecraft/item/ItemBucketMilk.java.patch deleted file mode 100644 index a3ccb7534..000000000 --- a/patches/minecraft/net/minecraft/item/ItemBucketMilk.java.patch +++ /dev/null @@ -1,33 +0,0 @@ ---- before/net/minecraft/item/ItemBucketMilk.java -+++ after/net/minecraft/item/ItemBucketMilk.java -@@ -23,6 +23,7 @@ - @Override - public ItemStack onItemUseFinish(ItemStack stack, World worldIn, EntityLivingBase entityLiving) - { -+ if (!worldIn.isRemote) entityLiving.curePotionEffects(stack); // FORGE - move up so stack.shrink does not turn stack into air - if (entityLiving instanceof EntityPlayerMP) - { - EntityPlayerMP entityplayermp = (EntityPlayerMP)entityLiving; -@@ -35,11 +36,6 @@ - stack.shrink(1); - } - -- if (!worldIn.isRemote) -- { -- entityLiving.clearActivePotions(); -- } -- - return stack.isEmpty() ? new ItemStack(Items.BUCKET) : stack; - } - -@@ -56,6 +52,10 @@ - } - - @Override -+ public net.minecraftforge.common.capabilities.ICapabilityProvider initCapabilities(ItemStack stack, net.minecraft.nbt.NBTTagCompound nbt) { -+ return new net.minecraftforge.fluids.capability.wrappers.FluidBucketWrapper(stack); -+ } -+ - public ActionResult onItemRightClick(World worldIn, EntityPlayer playerIn, EnumHand handIn) - { - playerIn.setActiveHand(handIn); diff --git a/patches/minecraft/net/minecraft/item/ItemDoor.java.patch b/patches/minecraft/net/minecraft/item/ItemDoor.java.patch deleted file mode 100644 index 172dc2bd1..000000000 --- a/patches/minecraft/net/minecraft/item/ItemDoor.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/item/ItemDoor.java -+++ after/net/minecraft/item/ItemDoor.java -@@ -58,7 +58,7 @@ - int j = enumfacing.getZOffset(); - boolean flag = i < 0 && hitZ < 0.5F || i > 0 && hitZ > 0.5F || j < 0 && hitX > 0.5F || j > 0 && hitX < 0.5F; - placeDoor(worldIn, pos, enumfacing, this.block, flag); -- SoundType soundtype = this.block.getSoundType(); -+ SoundType soundtype = worldIn.getBlockState(pos).getBlock().getSoundType(worldIn.getBlockState(pos), worldIn, pos, player); - worldIn.playSound( - player, - pos, diff --git a/patches/minecraft/net/minecraft/item/ItemDye.java.patch b/patches/minecraft/net/minecraft/item/ItemDye.java.patch deleted file mode 100644 index d9d8fe625..000000000 --- a/patches/minecraft/net/minecraft/item/ItemDye.java.patch +++ /dev/null @@ -1,64 +0,0 @@ ---- before/net/minecraft/item/ItemDye.java -+++ after/net/minecraft/item/ItemDye.java -@@ -66,7 +66,7 @@ - - if (enumdyecolor == EnumDyeColor.WHITE) - { -- if (applyBonemeal(itemstack, worldIn, pos)) -+ if (applyBonemeal(itemstack, worldIn, pos, player, hand)) - { - if (!worldIn.isRemote) - { -@@ -93,7 +93,7 @@ - if (worldIn.isAirBlock(pos)) - { - IBlockState iblockstate1 = Blocks.COCOA -- .getStateForPlacement(worldIn, pos, facing, hitX, hitY, hitZ, 0, player); -+ .getStateForPlacement(worldIn, pos, facing, hitX, hitY, hitZ, 0, player, hand); - worldIn.setBlockState(pos, iblockstate1, 10); - - if (!player.capabilities.isCreativeMode) -@@ -114,8 +114,18 @@ - - public static boolean applyBonemeal(ItemStack stack, World worldIn, BlockPos target) - { -+ if (worldIn instanceof net.minecraft.world.WorldServer) -+ return applyBonemeal(stack, worldIn, target, net.minecraftforge.common.util.FakePlayerFactory.getMinecraft((net.minecraft.world.WorldServer)worldIn), null); -+ return false; -+ } -+ -+ public static boolean applyBonemeal(ItemStack stack, World worldIn, BlockPos target, EntityPlayer player, @javax.annotation.Nullable EnumHand hand) -+ { - IBlockState iblockstate = worldIn.getBlockState(target); - -+ int hook = net.minecraftforge.event.ForgeEventFactory.onApplyBonemeal(player, worldIn, target, iblockstate, stack, hand); -+ if (hook != 0) return hook > 0; -+ - if (iblockstate.getBlock() instanceof IGrowable) - { - IGrowable igrowable = (IGrowable)iblockstate.getBlock(); -@@ -160,6 +170,24 @@ - EnumParticleTypes.VILLAGER_HAPPY, - pos.getX() + itemRand.nextFloat(), - pos.getY() + itemRand.nextFloat() * iblockstate.getBoundingBox(worldIn, pos).maxY, -+ pos.getZ() + itemRand.nextFloat(), -+ d0, -+ d1, -+ d2 -+ ); -+ } -+ } -+ else -+ { -+ for (int i1 = 0; i1 < amount; ++i1) -+ { -+ double d0 = itemRand.nextGaussian() * 0.02; -+ double d1 = itemRand.nextGaussian() * 0.02; -+ double d2 = itemRand.nextGaussian() * 0.02; -+ worldIn.spawnParticle( -+ EnumParticleTypes.VILLAGER_HAPPY, -+ pos.getX() + itemRand.nextFloat(), -+ pos.getY() + itemRand.nextFloat() * 1.0f, - pos.getZ() + itemRand.nextFloat(), - d0, - d1, diff --git a/patches/minecraft/net/minecraft/item/ItemFlintAndSteel.java.patch b/patches/minecraft/net/minecraft/item/ItemFlintAndSteel.java.patch deleted file mode 100644 index ef148df37..000000000 --- a/patches/minecraft/net/minecraft/item/ItemFlintAndSteel.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/item/ItemFlintAndSteel.java -+++ after/net/minecraft/item/ItemFlintAndSteel.java -@@ -44,7 +44,7 @@ - } - else - { -- if (worldIn.getBlockState(pos).getMaterial() == Material.AIR) -+ if (worldIn.isAirBlock(pos)) - { - worldIn.playSound( - player, pos, SoundEvents.ITEM_FLINTANDSTEEL_USE, SoundCategory.BLOCKS, 1.0F, itemRand.nextFloat() * 0.4F + 0.8F diff --git a/patches/minecraft/net/minecraft/item/ItemHoe.java.patch b/patches/minecraft/net/minecraft/item/ItemHoe.java.patch deleted file mode 100644 index 5728753c9..000000000 --- a/patches/minecraft/net/minecraft/item/ItemHoe.java.patch +++ /dev/null @@ -1,17 +0,0 @@ ---- before/net/minecraft/item/ItemHoe.java -+++ after/net/minecraft/item/ItemHoe.java -@@ -57,10 +57,13 @@ - } - else - { -+ int hook = net.minecraftforge.event.ForgeEventFactory.onHoeUse(itemstack, player, worldIn, pos); -+ if (hook != 0) return hook > 0 ? EnumActionResult.SUCCESS : EnumActionResult.FAIL; -+ - IBlockState iblockstate = worldIn.getBlockState(pos); - Block block = iblockstate.getBlock(); - -- if (facing != EnumFacing.DOWN && worldIn.getBlockState(pos.up()).getMaterial() == Material.AIR) -+ if (facing != EnumFacing.DOWN && worldIn.isAirBlock(pos.up())) - { - if (block == Blocks.GRASS || block == Blocks.GRASS_PATH) - { diff --git a/patches/minecraft/net/minecraft/item/ItemLilyPad.java.patch b/patches/minecraft/net/minecraft/item/ItemLilyPad.java.patch deleted file mode 100644 index 85d19319d..000000000 --- a/patches/minecraft/net/minecraft/item/ItemLilyPad.java.patch +++ /dev/null @@ -1,18 +0,0 @@ ---- before/net/minecraft/item/ItemLilyPad.java -+++ after/net/minecraft/item/ItemLilyPad.java -@@ -54,6 +54,15 @@ - && iblockstate.getValue(BlockLiquid.LEVEL) == 0 - && worldIn.isAirBlock(blockpos1)) - { -+ // special case for handling block placement with water lilies -+ net.minecraftforge.common.util.BlockSnapshot blocksnapshot = net.minecraftforge.common.util.BlockSnapshot.getBlockSnapshot(worldIn, blockpos1); -+ worldIn.setBlockState(blockpos1, Blocks.WATERLILY.getDefaultState()); -+ if (net.minecraftforge.event.ForgeEventFactory.onPlayerBlockPlace(playerIn, blocksnapshot, net.minecraft.util.EnumFacing.UP, handIn).isCanceled()) -+ { -+ blocksnapshot.restore(true, false); -+ return new ActionResult(EnumActionResult.FAIL, itemstack); -+ } -+ - worldIn.setBlockState(blockpos1, Blocks.WATERLILY.getDefaultState(), 11); - - if (playerIn instanceof EntityPlayerMP) diff --git a/patches/minecraft/net/minecraft/item/ItemMap.java.patch b/patches/minecraft/net/minecraft/item/ItemMap.java.patch deleted file mode 100644 index ab9d72fb9..000000000 --- a/patches/minecraft/net/minecraft/item/ItemMap.java.patch +++ /dev/null @@ -1,46 +0,0 @@ ---- before/net/minecraft/item/ItemMap.java -+++ after/net/minecraft/item/ItemMap.java -@@ -42,7 +42,7 @@ - worldIn.setData(s, mapdata); - mapdata.scale = scale; - mapdata.calculateMapCenter(worldX, worldZ, mapdata.scale); -- mapdata.dimension = (byte)worldIn.provider.getDimensionType().getId(); -+ mapdata.dimension = worldIn.provider.getDimension(); - mapdata.trackingPosition = trackingPosition; - mapdata.unlimitedTracking = unlimitedTracking; - mapdata.markDirty(); -@@ -70,7 +70,7 @@ - mapdata = new MapData(s); - mapdata.scale = 3; - mapdata.calculateMapCenter(worldIn.getWorldInfo().getSpawnX(), worldIn.getWorldInfo().getSpawnZ(), mapdata.scale); -- mapdata.dimension = (byte)worldIn.provider.getDimensionType().getId(); -+ mapdata.dimension = worldIn.provider.getDimension(); - mapdata.markDirty(); - worldIn.setData(s, mapdata); - } -@@ -80,7 +80,7 @@ - - public void updateMapData(World worldIn, Entity viewer, MapData data) - { -- if (worldIn.provider.getDimensionType().getId() == data.dimension && viewer instanceof EntityPlayer) -+ if (worldIn.provider.getDimension() == data.dimension && viewer instanceof EntityPlayer) - { - int i = 1 << data.scale; - int j = data.xCenter; -@@ -252,13 +252,13 @@ - - public static void renderBiomePreviewMap(World worldIn, ItemStack map) - { -- if (map.getItem() == Items.FILLED_MAP) -+ if (map.getItem() instanceof ItemMap) - { -- MapData mapdata = Items.FILLED_MAP.getMapData(map, worldIn); -+ MapData mapdata = ((ItemMap) map.getItem()).getMapData(map, worldIn); - - if (mapdata != null) - { -- if (worldIn.provider.getDimensionType().getId() == mapdata.dimension) -+ if (worldIn.provider.getDimension() == mapdata.dimension) - { - int i = 1 << mapdata.scale; - int j = mapdata.xCenter; diff --git a/patches/minecraft/net/minecraft/item/ItemMinecart.java.patch b/patches/minecraft/net/minecraft/item/ItemMinecart.java.patch deleted file mode 100644 index a7deeded4..000000000 --- a/patches/minecraft/net/minecraft/item/ItemMinecart.java.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- before/net/minecraft/item/ItemMinecart.java -+++ after/net/minecraft/item/ItemMinecart.java -@@ -32,7 +32,7 @@ - BlockPos blockpos = source.getBlockPos().offset(enumfacing); - IBlockState iblockstate = world.getBlockState(blockpos); - BlockRailBase.EnumRailDirection blockrailbase$enumraildirection = iblockstate.getBlock() instanceof BlockRailBase -- ? iblockstate.getValue(((BlockRailBase)iblockstate.getBlock()).getShapeProperty()) -+ ? ((BlockRailBase)iblockstate.getBlock()).getRailDirection(world, blockpos, iblockstate, null) - : BlockRailBase.EnumRailDirection.NORTH_SOUTH; - double d3; - -@@ -56,7 +56,7 @@ - - IBlockState iblockstate1 = world.getBlockState(blockpos.down()); - BlockRailBase.EnumRailDirection blockrailbase$enumraildirection1 = iblockstate1.getBlock() instanceof BlockRailBase -- ? iblockstate1.getValue(((BlockRailBase)iblockstate1.getBlock()).getShapeProperty()) -+ ? ((BlockRailBase)iblockstate1.getBlock()).getRailDirection(world, blockpos.down(), iblockstate1, null) - : BlockRailBase.EnumRailDirection.NORTH_SOUTH; - - if (enumfacing != EnumFacing.DOWN && blockrailbase$enumraildirection1.isAscending()) -@@ -121,7 +121,7 @@ - if (!worldIn.isRemote) - { - BlockRailBase.EnumRailDirection blockrailbase$enumraildirection = iblockstate.getBlock() instanceof BlockRailBase -- ? iblockstate.getValue(((BlockRailBase)iblockstate.getBlock()).getShapeProperty()) -+ ? ((BlockRailBase)iblockstate.getBlock()).getRailDirection(worldIn, pos, iblockstate, null) - : BlockRailBase.EnumRailDirection.NORTH_SOUTH; - double d0 = 0.0; - diff --git a/patches/minecraft/net/minecraft/item/ItemMonsterPlacer.java.patch b/patches/minecraft/net/minecraft/item/ItemMonsterPlacer.java.patch deleted file mode 100644 index a6a7b342d..000000000 --- a/patches/minecraft/net/minecraft/item/ItemMonsterPlacer.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- before/net/minecraft/item/ItemMonsterPlacer.java -+++ after/net/minecraft/item/ItemMonsterPlacer.java -@@ -251,6 +251,7 @@ - entity.setLocationAndAngles(x, y, z, MathHelper.wrapDegrees(worldIn.rand.nextFloat() * 360.0F), 0.0F); - entityliving.rotationYawHead = entityliving.rotationYaw; - entityliving.renderYawOffset = entityliving.rotationYaw; -+ if (net.minecraftforge.event.ForgeEventFactory.doSpecialSpawn(entityliving, worldIn, (float) x, (float) y, (float) z, null)) return null; - entityliving.onInitialSpawn(worldIn.getDifficultyForLocation(new BlockPos(entityliving)), null); - worldIn.spawnEntity(entity); - entityliving.playLivingSound(); diff --git a/patches/minecraft/net/minecraft/item/ItemRedstone.java.patch b/patches/minecraft/net/minecraft/item/ItemRedstone.java.patch deleted file mode 100644 index a24f850a3..000000000 --- a/patches/minecraft/net/minecraft/item/ItemRedstone.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/item/ItemRedstone.java -+++ after/net/minecraft/item/ItemRedstone.java -@@ -35,7 +35,7 @@ - ItemStack itemstack = player.getHeldItem(hand); - - if (player.canPlayerEdit(blockpos, facing, itemstack) -- && worldIn.mayPlace(worldIn.getBlockState(blockpos).getBlock(), blockpos, false, facing, null) -+ && worldIn.mayPlace(worldIn.getBlockState(blockpos).getBlock(), blockpos, false, facing, player) - && Blocks.REDSTONE_WIRE.canPlaceBlockAt(worldIn, blockpos)) - { - worldIn.setBlockState(blockpos, Blocks.REDSTONE_WIRE.getDefaultState()); diff --git a/patches/minecraft/net/minecraft/item/ItemSeedFood.java.patch b/patches/minecraft/net/minecraft/item/ItemSeedFood.java.patch deleted file mode 100644 index f7ab5efc9..000000000 --- a/patches/minecraft/net/minecraft/item/ItemSeedFood.java.patch +++ /dev/null @@ -1,41 +0,0 @@ ---- before/net/minecraft/item/ItemSeedFood.java -+++ after/net/minecraft/item/ItemSeedFood.java -@@ -8,7 +8,7 @@ - import net.minecraft.util.math.BlockPos; - import net.minecraft.world.World; - --public class ItemSeedFood extends ItemFood -+public class ItemSeedFood extends ItemFood implements net.minecraftforge.common.IPlantable - { - private final Block crops; - private final Block soilId; -@@ -34,9 +34,10 @@ - { - ItemStack itemstack = player.getHeldItem(hand); - -+ net.minecraft.block.state.IBlockState state = worldIn.getBlockState(pos); - if (facing == EnumFacing.UP - && player.canPlayerEdit(pos.offset(facing), facing, itemstack) -- && worldIn.getBlockState(pos).getBlock() == this.soilId -+ && state.getBlock().canSustainPlant(state, worldIn, pos, EnumFacing.UP, this) - && worldIn.isAirBlock(pos.up())) - { - worldIn.setBlockState(pos.up(), this.crops.getDefaultState(), 11); -@@ -47,5 +48,17 @@ - { - return EnumActionResult.FAIL; - } -+ } -+ -+ @Override -+ public net.minecraftforge.common.EnumPlantType getPlantType(net.minecraft.world.IBlockAccess world, BlockPos pos) -+ { -+ return net.minecraftforge.common.EnumPlantType.Crop; -+ } -+ -+ @Override -+ public net.minecraft.block.state.IBlockState getPlant(net.minecraft.world.IBlockAccess world, BlockPos pos) -+ { -+ return this.crops.getDefaultState(); - } - } diff --git a/patches/minecraft/net/minecraft/item/ItemSeeds.java.patch b/patches/minecraft/net/minecraft/item/ItemSeeds.java.patch deleted file mode 100644 index f9693fa57..000000000 --- a/patches/minecraft/net/minecraft/item/ItemSeeds.java.patch +++ /dev/null @@ -1,41 +0,0 @@ ---- before/net/minecraft/item/ItemSeeds.java -+++ after/net/minecraft/item/ItemSeeds.java -@@ -11,7 +11,7 @@ - import net.minecraft.util.math.BlockPos; - import net.minecraft.world.World; - --public class ItemSeeds extends Item -+public class ItemSeeds extends Item implements net.minecraftforge.common.IPlantable - { - private final Block crops; - private final Block soilBlockID; -@@ -37,9 +37,10 @@ - { - ItemStack itemstack = player.getHeldItem(hand); - -+ net.minecraft.block.state.IBlockState state = worldIn.getBlockState(pos); - if (facing == EnumFacing.UP - && player.canPlayerEdit(pos.offset(facing), facing, itemstack) -- && worldIn.getBlockState(pos).getBlock() == this.soilBlockID -+ && state.getBlock().canSustainPlant(state, worldIn, pos, EnumFacing.UP, this) - && worldIn.isAirBlock(pos.up())) - { - worldIn.setBlockState(pos.up(), this.crops.getDefaultState()); -@@ -56,5 +57,17 @@ - { - return EnumActionResult.FAIL; - } -+ } -+ -+ @Override -+ public net.minecraftforge.common.EnumPlantType getPlantType(net.minecraft.world.IBlockAccess world, BlockPos pos) -+ { -+ return this.crops == net.minecraft.init.Blocks.NETHER_WART ? net.minecraftforge.common.EnumPlantType.Nether : net.minecraftforge.common.EnumPlantType.Crop; -+ } -+ -+ @Override -+ public net.minecraft.block.state.IBlockState getPlant(net.minecraft.world.IBlockAccess world, BlockPos pos) -+ { -+ return this.crops.getDefaultState(); - } - } diff --git a/patches/minecraft/net/minecraft/item/ItemShears.java.patch b/patches/minecraft/net/minecraft/item/ItemShears.java.patch deleted file mode 100644 index ff86ba7e5..000000000 --- a/patches/minecraft/net/minecraft/item/ItemShears.java.patch +++ /dev/null @@ -1,84 +0,0 @@ ---- before/net/minecraft/item/ItemShears.java -+++ after/net/minecraft/item/ItemShears.java -@@ -27,6 +27,7 @@ - } - - Block block = state.getBlock(); -+ if (block instanceof net.minecraftforge.common.IShearable) return true; - return state.getMaterial() != Material.LEAVES - && block != Blocks.WEB - && block != Blocks.TALLGRASS -@@ -45,6 +46,73 @@ - } - - @Override -+ public boolean itemInteractionForEntity(ItemStack itemstack, net.minecraft.entity.player.EntityPlayer player, EntityLivingBase entity, net.minecraft.util.EnumHand hand) -+ { -+ if (entity.world.isRemote) -+ { -+ return false; -+ } -+ if (entity instanceof net.minecraftforge.common.IShearable) -+ { -+ net.minecraftforge.common.IShearable target = (net.minecraftforge.common.IShearable)entity; -+ BlockPos pos = new BlockPos(entity.posX, entity.posY, entity.posZ); -+ if (target.isShearable(itemstack, entity.world, pos)) -+ { -+ java.util.List drops = target.onSheared(itemstack, entity.world, pos, -+ net.minecraft.enchantment.EnchantmentHelper.getEnchantmentLevel(net.minecraft.init.Enchantments.FORTUNE, itemstack)); -+ -+ java.util.Random rand = new java.util.Random(); -+ for(ItemStack stack : drops) -+ { -+ net.minecraft.entity.item.EntityItem ent = entity.entityDropItem(stack, 1.0F); -+ ent.motionY += rand.nextFloat() * 0.05F; -+ ent.motionX += (rand.nextFloat() - rand.nextFloat()) * 0.1F; -+ ent.motionZ += (rand.nextFloat() - rand.nextFloat()) * 0.1F; -+ } -+ itemstack.damageItem(1, entity); -+ } -+ return true; -+ } -+ return false; -+ } -+ -+ @Override -+ public boolean onBlockStartBreak(ItemStack itemstack, BlockPos pos, net.minecraft.entity.player.EntityPlayer player) -+ { -+ if (player.world.isRemote || player.capabilities.isCreativeMode) -+ { -+ return false; -+ } -+ Block block = player.world.getBlockState(pos).getBlock(); -+ if (block instanceof net.minecraftforge.common.IShearable) -+ { -+ net.minecraftforge.common.IShearable target = (net.minecraftforge.common.IShearable)block; -+ if (target.isShearable(itemstack, player.world, pos)) -+ { -+ java.util.List drops = target.onSheared(itemstack, player.world, pos, -+ net.minecraft.enchantment.EnchantmentHelper.getEnchantmentLevel(net.minecraft.init.Enchantments.FORTUNE, itemstack)); -+ java.util.Random rand = new java.util.Random(); -+ -+ for (ItemStack stack : drops) -+ { -+ float f = 0.7F; -+ double d = (rand.nextFloat() * f) + (1.0F - f) * 0.5D; -+ double d1 = (rand.nextFloat() * f) + (1.0F - f) * 0.5D; -+ double d2 = (rand.nextFloat() * f) + (1.0F - f) * 0.5D; -+ net.minecraft.entity.item.EntityItem entityitem = new net.minecraft.entity.item.EntityItem(player.world, pos.getX() + d, pos.getY() + d1, pos.getZ() + d2, stack); -+ entityitem.setDefaultPickupDelay(); -+ player.world.spawnEntity(entityitem); -+ } -+ -+ itemstack.damageItem(1, player); -+ player.addStat(net.minecraft.stats.StatList.getBlockStats(block)); -+ player.world.setBlockState(pos, Blocks.AIR.getDefaultState(), 11); //TODO: Move to IShearable implementors in 1.12+ -+ return true; -+ } -+ } -+ return false; -+ } -+ - public float getDestroySpeed(ItemStack stack, IBlockState state) - { - Block block = state.getBlock(); diff --git a/patches/minecraft/net/minecraft/item/ItemSkull.java.patch b/patches/minecraft/net/minecraft/item/ItemSkull.java.patch deleted file mode 100644 index ac58359a8..000000000 --- a/patches/minecraft/net/minecraft/item/ItemSkull.java.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- before/net/minecraft/item/ItemSkull.java -+++ after/net/minecraft/item/ItemSkull.java -@@ -52,13 +52,18 @@ - } - else - { -+ if (worldIn.getBlockState(pos).getBlock().isReplaceable(worldIn, pos)) -+ { -+ facing = EnumFacing.UP; -+ pos = pos.down(); -+ } - IBlockState iblockstate = worldIn.getBlockState(pos); - Block block = iblockstate.getBlock(); - boolean flag = block.isReplaceable(worldIn, pos); - - if (!flag) - { -- if (!worldIn.getBlockState(pos).getMaterial().isSolid()) -+ if (!worldIn.getBlockState(pos).getMaterial().isSolid() && !worldIn.isSideSolid(pos, facing, true)) - { - return EnumActionResult.FAIL; - } diff --git a/patches/minecraft/net/minecraft/item/ItemSlab.java.patch b/patches/minecraft/net/minecraft/item/ItemSlab.java.patch deleted file mode 100644 index 37562a8ae..000000000 --- a/patches/minecraft/net/minecraft/item/ItemSlab.java.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- before/net/minecraft/item/ItemSlab.java -+++ after/net/minecraft/item/ItemSlab.java -@@ -82,7 +82,7 @@ - && worldIn.checkNoEntityCollision(axisalignedbb.offset(pos)) - && worldIn.setBlockState(pos, iblockstate1, 11)) - { -- SoundType soundtype = this.doubleSlab.getSoundType(); -+ SoundType soundtype = this.doubleSlab.getSoundType(iblockstate1, worldIn, pos, player); - worldIn.playSound( - player, - pos, -@@ -155,7 +155,7 @@ - && worldIn.checkNoEntityCollision(axisalignedbb.offset(pos)) - && worldIn.setBlockState(pos, iblockstate1, 11)) - { -- SoundType soundtype = this.doubleSlab.getSoundType(); -+ SoundType soundtype = this.doubleSlab.getSoundType(iblockstate1, worldIn, pos, player); - worldIn.playSound( - player, - pos, diff --git a/patches/minecraft/net/minecraft/item/ItemSnow.java.patch b/patches/minecraft/net/minecraft/item/ItemSnow.java.patch deleted file mode 100644 index 670ac3171..000000000 --- a/patches/minecraft/net/minecraft/item/ItemSnow.java.patch +++ /dev/null @@ -1,24 +0,0 @@ ---- before/net/minecraft/item/ItemSnow.java -+++ after/net/minecraft/item/ItemSnow.java -@@ -63,7 +63,7 @@ - && worldIn.checkNoEntityCollision(axisalignedbb.offset(blockpos)) - && worldIn.setBlockState(blockpos, iblockstate1, 10)) - { -- SoundType soundtype = this.block.getSoundType(); -+ SoundType soundtype = this.block.getSoundType(iblockstate1, worldIn, pos, player); - worldIn.playSound( - player, - blockpos, -@@ -96,5 +96,12 @@ - public int getMetadata(int damage) - { - return damage; -+ } -+ -+ @Override -+ public boolean canPlaceBlockOnSide(World world, BlockPos pos, EnumFacing side, EntityPlayer player, ItemStack stack) -+ { -+ IBlockState state = world.getBlockState(pos); -+ return state.getBlock() == net.minecraft.init.Blocks.SNOW_LAYER && state.getValue(BlockSnow.LAYERS) <= 7 || super.canPlaceBlockOnSide(world, pos, side, player, stack); - } - } diff --git a/patches/minecraft/net/minecraft/item/ItemStack.java.patch b/patches/minecraft/net/minecraft/item/ItemStack.java.patch deleted file mode 100644 index d54dc1bfe..000000000 --- a/patches/minecraft/net/minecraft/item/ItemStack.java.patch +++ /dev/null @@ -1,432 +0,0 @@ ---- before/net/minecraft/item/ItemStack.java -+++ after/net/minecraft/item/ItemStack.java -@@ -50,7 +50,7 @@ - import net.minecraftforge.fml.relauncher.Side; - import net.minecraftforge.fml.relauncher.SideOnly; - --public final class ItemStack -+public final class ItemStack implements net.minecraftforge.common.capabilities.ICapabilitySerializable - { - public static final ItemStack EMPTY = new ItemStack((Item)null); - public static final DecimalFormat DECIMALFORMAT = new DecimalFormat("#.##"); -@@ -66,6 +66,10 @@ - private Block canPlaceOnCacheBlock; - private boolean canPlaceOnCacheResult; - -+ private net.minecraftforge.registries.IRegistryDelegate delegate; -+ private net.minecraftforge.common.capabilities.CapabilityDispatcher capabilities; -+ private NBTTagCompound capNBT; -+ - public ItemStack(Block blockIn) - { - this(blockIn, 1); -@@ -91,8 +95,10 @@ - this(itemIn, amount, 0); - } - -- public ItemStack(Item itemIn, int amount, int meta) -+ public ItemStack(Item itemIn, int amount, int meta){ this(itemIn, amount, meta, null); } -+ public ItemStack(Item itemIn, int amount, int meta, @Nullable NBTTagCompound capNBT) - { -+ this.capNBT = capNBT; - this.item = itemIn; - this.itemDamage = meta; - this.stackSize = amount; -@@ -103,6 +109,7 @@ - } - - this.updateEmptyState(); -+ this.forgeInit(); - } - - private void updateEmptyState() -@@ -112,7 +119,8 @@ - - public ItemStack(NBTTagCompound compound) - { -- this.item = Item.getByNameOrId(compound.getString("id")); -+ this.capNBT = compound.hasKey("ForgeCaps") ? compound.getCompoundTag("ForgeCaps") : null; -+ this.item = compound.hasKey("id", 8) ? Item.getByNameOrId(compound.getString("id")) : Items.AIR; //Forge fix tons of NumberFormatExceptions that are caused by deserializing EMPTY ItemStacks. - this.stackSize = compound.getByte("Count"); - this.itemDamage = Math.max(0, compound.getShort("Damage")); - -@@ -127,6 +135,11 @@ - } - - this.updateEmptyState(); -+ this.forgeInit(); -+ } -+ -+ private ItemStack(Item item, Object unused) { -+ this.item = item; - } - - public boolean isEmpty() -@@ -135,7 +148,7 @@ - { - return true; - } -- else if (this.item == null || this.item == Item.getItemFromBlock(Blocks.AIR)) -+ else if (this.getItemRaw() == null || this.getItemRaw() == Items.AIR) - { - return true; - } -@@ -162,7 +175,7 @@ - - public Item getItem() - { -- return this.isEmpty ? Item.getItemFromBlock(Blocks.AIR) : this.item; -+ return this.isEmpty || this.delegate == null ? Items.AIR : this.delegate.get(); - } - - public EnumActionResult onItemUse( -@@ -176,6 +189,7 @@ - float hitZ - ) - { -+ if (!worldIn.isRemote) return net.minecraftforge.common.ForgeHooks.onPlaceItemIntoWorld(this, playerIn, worldIn, pos, side, hitX, hitY, hitZ, hand); - EnumActionResult enumactionresult = this.getItem() - .onItemUse(playerIn, worldIn, pos, hand, side, hitX, hitY, hitZ); - -@@ -187,6 +201,28 @@ - return enumactionresult; - } - -+ public EnumActionResult onItemUseFirst( -+ EntityPlayer playerIn, -+ World worldIn, -+ BlockPos pos, -+ EnumHand hand, -+ EnumFacing side, -+ float hitX, -+ float hitY, -+ float hitZ -+ ) -+ { -+ // copy of onitemuse but for onitemusefirst -+ EnumActionResult enumactionresult = this.getItem().onItemUseFirst(playerIn, worldIn, pos, side, hitX, hitY, hitZ, hand); -+ -+ if (enumactionresult == EnumActionResult.SUCCESS) -+ { -+ playerIn.addStat(StatList.getObjectUseStats(this.item)); -+ } -+ -+ return enumactionresult; -+ } -+ - public float getDestroySpeed(IBlockState blockIn) - { - return this.getItem().getDestroySpeed(this, blockIn); -@@ -214,12 +250,18 @@ - nbt.setTag("tag", this.stackTagCompound); - } - -+ if (this.capabilities != null) -+ { -+ NBTTagCompound cnbt = this.capabilities.serializeNBT(); -+ if (!cnbt.isEmpty()) nbt.setTag("ForgeCaps", cnbt); -+ } -+ - return nbt; - } - - public int getMaxStackSize() - { -- return this.getItem().getItemStackLimit(); -+ return this.getItem().getItemStackLimit(this); - } - - public boolean isStackable() -@@ -235,7 +277,7 @@ - } - else - { -- return this.item.getMaxDamage() <= 0 ? false : !this.hasTagCompound() || !this.getTagCompound().getBoolean("Unbreakable"); -+ return this.item.getMaxDamage(this) <= 0 ? false : !this.hasTagCompound() || !this.getTagCompound().getBoolean("Unbreakable"); - } - } - -@@ -246,32 +288,27 @@ - - public boolean isItemDamaged() - { -- return this.isItemStackDamageable() && this.itemDamage > 0; -+ return this.isItemStackDamageable() && getItem().isDamaged(this); - } - - public int getItemDamage() - { -- return this.itemDamage; -+ return getItem().getDamage(this); - } - - public int getMetadata() - { -- return this.itemDamage; -+ return getItem().getMetadata(this); - } - - public void setItemDamage(int meta) - { -- this.itemDamage = meta; -- -- if (this.itemDamage < 0) -- { -- this.itemDamage = 0; -- } -+ getItem().setDamage(this, meta); - } - - public int getMaxDamage() - { -- return this.getItem().getMaxDamage(); -+ return this.getItem().getMaxDamage(this); - } - - public boolean attemptDamageItem(int amount, Random rand, @Nullable EntityPlayerMP damager) -@@ -308,8 +345,8 @@ - CriteriaTriggers.ITEM_DURABILITY_CHANGED.trigger(damager, this, this.itemDamage + amount); - } - -- this.itemDamage += amount; -- return this.itemDamage > this.getMaxDamage(); -+ setItemDamage(getItemDamage() + amount); //Redirect through Item's callback if applicable. -+ return getItemDamage() > getMaxDamage(); - } - } - -@@ -358,7 +395,7 @@ - - public boolean canHarvestBlock(IBlockState blockIn) - { -- return this.getItem().canHarvestBlock(blockIn); -+ return this.getItem().canHarvestBlock(blockIn, this); - } - - public boolean interactWithEntity(EntityPlayer playerIn, EntityLivingBase entityIn, EnumHand hand) -@@ -368,15 +405,30 @@ - - public ItemStack copy() - { -- ItemStack itemstack = new ItemStack(this.item, this.stackSize, this.itemDamage); -- itemstack.setAnimationsToGo(this.getAnimationsToGo()); -- -+ if (this.isEmpty()) -+ { -+ return EMPTY; -+ } -+ ItemStack copy = new ItemStack(this.item, null); -+ copy.stackSize = this.stackSize; -+ copy.itemDamage = this.itemDamage; -+ copy.animationsToGo = this.animationsToGo; - if (this.stackTagCompound != null) - { -- itemstack.stackTagCompound = this.stackTagCompound.copy(); -+ copy.stackTagCompound = this.stackTagCompound.copy(); -+ } -+ if (this.capabilities != null) -+ { -+ copy.capNBT = this.capabilities.serializeNBT(); -+ } -+ copy.delegate = this.delegate; -+ net.minecraftforge.common.capabilities.ICapabilityProvider provider = copy.item.initCapabilities(copy, copy.capNBT); -+ copy.capabilities = net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(copy, provider); -+ if (copy.capNBT != null && copy.capabilities != null) { -+ copy.capabilities.deserializeNBT(copy.capNBT); - } - -- return itemstack; -+ return copy; - } - - public static boolean areItemStackTagsEqual(ItemStack stackA, ItemStack stackB) -@@ -393,7 +445,7 @@ - { - return stackA.stackTagCompound == null && stackB.stackTagCompound != null - ? false -- : stackA.stackTagCompound == null || stackA.stackTagCompound.equals(stackB.stackTagCompound); -+ : stackA.stackTagCompound == null || stackA.stackTagCompound.equals(stackB.stackTagCompound) && stackA.areCapsCompatible(stackB); - } - } - -@@ -427,7 +479,7 @@ - { - return this.stackTagCompound == null && other.stackTagCompound != null - ? false -- : this.stackTagCompound == null || this.stackTagCompound.equals(other.stackTagCompound); -+ : this.stackTagCompound == null || this.stackTagCompound.equals(other.stackTagCompound) && this.areCapsCompatible(other); - } - } - -@@ -796,6 +848,7 @@ - I18n.translateToLocal("attribute.name." + entry.getKey()) - ) - ); -+ list.add(" " + I18n.translateToLocalFormatted("attribute.modifier.equals." + attributemodifier.getOperation(), DECIMALFORMAT.format(d1), I18n.translateToLocal("attribute.name." + (String)entry.getKey()))); - } - } - } -@@ -871,6 +924,7 @@ - } - } - -+ net.minecraftforge.event.ForgeEventFactory.onItemTooltip(this, playerIn, list, advanced); - return list; - } - -@@ -880,6 +934,7 @@ - return this.getItem().hasEffect(this); - } - -+ @Deprecated // use Forge version on item - public EnumRarity getRarity() - { - return this.getItem().getRarity(this); -@@ -985,7 +1040,7 @@ - } - else - { -- multimap = this.getItem().getItemAttributeModifiers(equipmentSlot); -+ multimap = this.getItem().getAttributeModifiers(equipmentSlot, this); - } - - return multimap; -@@ -1030,7 +1085,7 @@ - { - NBTTagCompound nbttagcompound = this.writeToNBT(new NBTTagCompound()); - itextcomponent.getStyle().setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_ITEM, new TextComponentString(nbttagcompound.toString()))); -- itextcomponent.getStyle().setColor(this.getRarity().color); -+ itextcomponent.getStyle().setColor(this.getItem().getForgeRarity(this).getColor()); - } - - return itextcomponent; -@@ -1127,5 +1182,129 @@ - public void shrink(int quantity) - { - this.grow(-quantity); -+ } -+ -+ @Override -+ public boolean hasCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable net.minecraft.util.EnumFacing facing) -+ { -+ return this.isEmpty || this.capabilities == null ? false : this.capabilities.hasCapability(capability, facing); -+ } -+ -+ @Override -+ @Nullable -+ public T getCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable net.minecraft.util.EnumFacing facing) -+ { -+ return this.isEmpty || this.capabilities == null ? null : this.capabilities.getCapability(capability, facing); -+ } -+ -+ public void deserializeNBT(NBTTagCompound nbt) -+ { -+ // TODO do this better while respecting new rules -+ final ItemStack itemStack = new ItemStack(nbt); -+ this.stackTagCompound = itemStack.stackTagCompound; -+ this.capNBT = itemStack.capNBT; -+ } -+ -+ public NBTTagCompound serializeNBT() -+ { -+ NBTTagCompound ret = new NBTTagCompound(); -+ this.writeToNBT(ret); -+ return ret; -+ } -+ -+ public boolean areCapsCompatible(ItemStack other) -+ { -+ if (this.capabilities == null) -+ { -+ if (other.capabilities == null) -+ { -+ return true; -+ } -+ else -+ { -+ return other.capabilities.areCompatible(null); -+ } -+ } -+ else -+ { -+ return this.capabilities.areCompatible(other.capabilities); -+ } -+ } -+ -+ /** -+ * Set up forge's ItemStack additions. -+ */ -+ private void forgeInit() -+ { -+ Item item = getItemRaw(); -+ if (item != null) -+ { -+ this.delegate = item.delegate; -+ net.minecraftforge.common.capabilities.ICapabilityProvider provider = item.initCapabilities(this, this.capNBT); -+ this.capabilities = net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(this, provider); -+ if (this.capNBT != null && this.capabilities != null) this.capabilities.deserializeNBT(this.capNBT); -+ } -+ } -+ -+ /** -+ * Internal call to get the actual item, not the delegate. -+ * In all other methods, FML replaces calls to this.item with the item delegate. -+ */ -+ @Nullable -+ private Item getItemRaw() -+ { -+ return this.item; -+ } -+ -+ /** -+ * Modeled after ItemStack.areItemStacksEqual -+ * Uses Item.getNBTShareTag for comparison instead of NBT and capabilities. -+ * Only used for comparing itemStacks that were transferred from server to client using Item.getNBTShareTag. -+ */ -+ public static boolean areItemStacksEqualUsingNBTShareTag(ItemStack stackA, ItemStack stackB) -+ { -+ if (stackA.isEmpty()) -+ return stackB.isEmpty(); -+ else -+ return !stackB.isEmpty() && stackA.isItemStackEqualUsingNBTShareTag(stackB); -+ } -+ -+ /** -+ * Modeled after ItemStack.isItemStackEqual -+ * Uses Item.getNBTShareTag for comparison instead of NBT and capabilities. -+ * Only used for comparing itemStacks that were transferred from server to client using Item.getNBTShareTag. -+ */ -+ private boolean isItemStackEqualUsingNBTShareTag(ItemStack other) -+ { -+ return this.stackSize == other.stackSize && this.getItem() == other.getItem() && this.itemDamage == other.itemDamage && areItemStackShareTagsEqual(this, other); -+ } -+ -+ /** -+ * Modeled after ItemStack.areItemStackTagsEqual -+ * Uses Item.getNBTShareTag for comparison instead of NBT and capabilities. -+ * Only used for comparing itemStacks that were transferred from server to client using Item.getNBTShareTag. -+ */ -+ public static boolean areItemStackShareTagsEqual(ItemStack stackA, ItemStack stackB) -+ { -+ NBTTagCompound shareTagA = stackA.getItem().getNBTShareTag(stackA); -+ NBTTagCompound shareTagB = stackB.getItem().getNBTShareTag(stackB); -+ if (shareTagA == null) -+ return shareTagB == null; -+ else -+ return shareTagB != null && shareTagA.equals(shareTagB); -+ } -+ -+ /** -+ * -+ * Should this item, when held, allow sneak-clicks to pass through to the underlying block? -+ * -+ * @param world The world -+ * @param pos Block position in world -+ * @param player The Player that is wielding the item -+ * @return -+ */ -+ public boolean doesSneakBypassUse(net.minecraft.world.IBlockAccess world, BlockPos pos, EntityPlayer player) -+ { -+ return this.isEmpty() || this.getItem().doesSneakBypassUse(this, world, pos, player); - } - } diff --git a/patches/minecraft/net/minecraft/item/ItemSword.java.patch b/patches/minecraft/net/minecraft/item/ItemSword.java.patch deleted file mode 100644 index 787c3d18c..000000000 --- a/patches/minecraft/net/minecraft/item/ItemSword.java.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- before/net/minecraft/item/ItemSword.java -+++ after/net/minecraft/item/ItemSword.java -@@ -101,7 +101,9 @@ - @Override - public boolean getIsRepairable(ItemStack toRepair, ItemStack repair) - { -- return this.material.getRepairItem() == repair.getItem() ? true : super.getIsRepairable(toRepair, repair); -+ ItemStack mat = this.material.getRepairItemStack(); -+ if (!mat.isEmpty() && net.minecraftforge.oredict.OreDictionary.itemMatches(mat, repair, false)) return true; -+ return super.getIsRepairable(toRepair, repair); - } - - @Override diff --git a/patches/minecraft/net/minecraft/item/ItemTool.java.patch b/patches/minecraft/net/minecraft/item/ItemTool.java.patch deleted file mode 100644 index 91aa46e91..000000000 --- a/patches/minecraft/net/minecraft/item/ItemTool.java.patch +++ /dev/null @@ -1,73 +0,0 @@ ---- before/net/minecraft/item/ItemTool.java -+++ after/net/minecraft/item/ItemTool.java -@@ -32,6 +32,18 @@ - this.attackDamage = attackDamageIn + materialIn.getAttackDamage(); - this.attackSpeed = attackSpeedIn; - this.setCreativeTab(CreativeTabs.TOOLS); -+ if (this instanceof ItemPickaxe) -+ { -+ toolClass = "pickaxe"; -+ } -+ else if (this instanceof ItemAxe) -+ { -+ toolClass = "axe"; -+ } -+ else if (this instanceof ItemSpade) -+ { -+ toolClass = "shovel"; -+ } - } - - protected ItemTool(Item.ToolMaterial materialIn, Set effectiveBlocksIn) -@@ -42,6 +54,11 @@ - @Override - public float getDestroySpeed(ItemStack stack, IBlockState state) - { -+ for (String type : getToolClasses(stack)) -+ { -+ if (state.getBlock().isToolEffective(type, state)) -+ return efficiency; -+ } - return this.effectiveBlocks.contains(state.getBlock()) ? this.efficiency : 1.0F; - } - -@@ -84,7 +101,9 @@ - @Override - public boolean getIsRepairable(ItemStack toRepair, ItemStack repair) - { -- return this.toolMaterial.getRepairItem() == repair.getItem() ? true : super.getIsRepairable(toRepair, repair); -+ ItemStack mat = this.toolMaterial.getRepairItemStack(); -+ if (!mat.isEmpty() && net.minecraftforge.oredict.OreDictionary.itemMatches(mat, repair, false)) return true; -+ return super.getIsRepairable(toRepair, repair); - } - - @Override -@@ -100,4 +119,28 @@ - - return multimap; - } -+ -+ /*===================================== FORGE START =================================*/ -+ @javax.annotation.Nullable -+ private String toolClass; -+ @Override -+ public int getHarvestLevel(ItemStack stack, String toolClass, @javax.annotation.Nullable net.minecraft.entity.player.EntityPlayer player, @javax.annotation.Nullable IBlockState blockState) -+ { -+ int level = super.getHarvestLevel(stack, toolClass, player, blockState); -+ if (level == -1 && toolClass.equals(this.toolClass)) -+ { -+ return this.toolMaterial.getHarvestLevel(); -+ } -+ else -+ { -+ return level; -+ } -+ } -+ -+ @Override -+ public Set getToolClasses(ItemStack stack) -+ { -+ return toolClass != null ? com.google.common.collect.ImmutableSet.of(toolClass) : super.getToolClasses(stack); -+ } -+ /*===================================== FORGE END =================================*/ - } diff --git a/patches/minecraft/net/minecraft/item/crafting/CraftingManager.java.patch b/patches/minecraft/net/minecraft/item/crafting/CraftingManager.java.patch deleted file mode 100644 index 022a799b1..000000000 --- a/patches/minecraft/net/minecraft/item/crafting/CraftingManager.java.patch +++ /dev/null @@ -1,42 +0,0 @@ ---- before/net/minecraft/item/crafting/CraftingManager.java -+++ after/net/minecraft/item/crafting/CraftingManager.java -@@ -35,7 +35,7 @@ - { - private static final Logger LOGGER = LogManager.getLogger(); - private static int nextAvailableId; -- public static final RegistryNamespaced REGISTRY = new RegistryNamespaced<>(); -+ public static final RegistryNamespaced REGISTRY = net.minecraftforge.registries.GameData.getWrapper(IRecipe.class); - - public static boolean init() - { -@@ -162,12 +162,14 @@ - } - } - -- public static void register(String name, IRecipe recipe) -+ //Forge: Made private use GameData/Registry events! -+ private static void register(String name, IRecipe recipe) - { - register(new ResourceLocation(name), recipe); - } - -- public static void register(ResourceLocation name, IRecipe recipe) -+ //Forge: Made private use GameData/Registry events! -+ private static void register(ResourceLocation name, IRecipe recipe) - { - if (REGISTRY.containsKey(name)) - { -@@ -232,11 +234,13 @@ - return REGISTRY.getObject(name); - } - -+ @Deprecated //DO NOT USE THIS - public static int getIDForRecipe(IRecipe recipe) - { - return REGISTRY.getIDForObject(recipe); - } - -+ @Deprecated //DO NOT USE THIS - @Nullable - public static IRecipe getRecipeById(int id) - { diff --git a/patches/minecraft/net/minecraft/item/crafting/FurnaceRecipes.java.patch b/patches/minecraft/net/minecraft/item/crafting/FurnaceRecipes.java.patch deleted file mode 100644 index 06a7035ad..000000000 --- a/patches/minecraft/net/minecraft/item/crafting/FurnaceRecipes.java.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- before/net/minecraft/item/crafting/FurnaceRecipes.java -+++ after/net/minecraft/item/crafting/FurnaceRecipes.java -@@ -121,6 +121,7 @@ - - public void addSmeltingRecipe(ItemStack input, ItemStack stack, float experience) - { -+ if (getSmeltingResult(input) != ItemStack.EMPTY) { net.minecraftforge.fml.common.FMLLog.log.info("Ignored smelting recipe with conflicting input: {} = {}", input, stack); return; } - this.smeltingList.put(input, stack); - this.experienceList.put(stack, experience); - } -@@ -151,6 +152,9 @@ - - public float getSmeltingExperience(ItemStack stack) - { -+ float ret = stack.getItem().getSmeltingExperience(stack); -+ if (ret != -1) return ret; -+ - for (Entry entry : this.experienceList.entrySet()) - { - if (this.compareItemStacks(stack, entry.getKey())) diff --git a/patches/minecraft/net/minecraft/item/crafting/IRecipe.java.patch b/patches/minecraft/net/minecraft/item/crafting/IRecipe.java.patch deleted file mode 100644 index 5f0c5c674..000000000 --- a/patches/minecraft/net/minecraft/item/crafting/IRecipe.java.patch +++ /dev/null @@ -1,37 +0,0 @@ ---- before/net/minecraft/item/crafting/IRecipe.java -+++ after/net/minecraft/item/crafting/IRecipe.java -@@ -4,21 +4,21 @@ - import net.minecraft.item.ItemStack; - import net.minecraft.util.NonNullList; - import net.minecraft.world.World; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; - --public interface IRecipe -+public interface IRecipe extends net.minecraftforge.registries.IForgeRegistryEntry - { - boolean matches(InventoryCrafting inv, World worldIn); - - ItemStack getCraftingResult(InventoryCrafting inv); - -- @SideOnly(Side.CLIENT) - boolean canFit(int width, int height); - - ItemStack getRecipeOutput(); - -- NonNullList getRemainingItems(InventoryCrafting inv); -+ default NonNullList getRemainingItems(InventoryCrafting inv) -+ { -+ return net.minecraftforge.common.ForgeHooks.defaultRecipeGetRemainingItems(inv); -+ } - - default NonNullList getIngredients() - { -@@ -30,7 +30,6 @@ - return false; - } - -- @SideOnly(Side.CLIENT) - default String getGroup() - { - return ""; diff --git a/patches/minecraft/net/minecraft/item/crafting/Ingredient.java.patch b/patches/minecraft/net/minecraft/item/crafting/Ingredient.java.patch deleted file mode 100644 index ed21625b0..000000000 --- a/patches/minecraft/net/minecraft/item/crafting/Ingredient.java.patch +++ /dev/null @@ -1,113 +0,0 @@ ---- before/net/minecraft/item/crafting/Ingredient.java -+++ after/net/minecraft/item/crafting/Ingredient.java -@@ -8,11 +8,11 @@ - import net.minecraft.client.util.RecipeItemHelper; - import net.minecraft.item.Item; - import net.minecraft.item.ItemStack; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; - - public class Ingredient implements Predicate - { -+ //Because Mojang caches things... we need to invalidate them.. so... here we go.. -+ private static final java.util.Set INSTANCES = java.util.Collections.newSetFromMap(new java.util.WeakHashMap()); - public static final Ingredient EMPTY = new Ingredient() - { - @Override -@@ -22,17 +22,39 @@ - } - }; - private final ItemStack[] matchingStacks; -+ private final ItemStack[] matchingStacksExploded; - private IntList matchingStacksPacked; -+ private final boolean isSimple; -+ -+ protected Ingredient(int size) -+ { -+ this(new ItemStack[size]); -+ } - - protected Ingredient(ItemStack... p_i47503_1_) - { -+ boolean simple = true; - this.matchingStacks = p_i47503_1_; -+ net.minecraft.util.NonNullList lst = net.minecraft.util.NonNullList.create(); -+ for (ItemStack s : p_i47503_1_) -+ { -+ if (s.isEmpty()) -+ continue; -+ if (s.getItem().isDamageable()) -+ simple = false; -+ if (s.getMetadata() == net.minecraftforge.oredict.OreDictionary.WILDCARD_VALUE) -+ s.getItem().getSubItems(net.minecraft.creativetab.CreativeTabs.SEARCH, lst); -+ else -+ lst.add(s); -+ } -+ this.matchingStacksExploded = lst.toArray(new ItemStack[lst.size()]); -+ this.isSimple = simple && this.matchingStacksExploded.length > 0; -+ Ingredient.INSTANCES.add(this); - } - -- @SideOnly(Side.CLIENT) - public ItemStack[] getMatchingStacks() - { -- return this.matchingStacks; -+ return this.matchingStacksExploded; - } - - public boolean apply(@Nullable ItemStack p_apply_1_) -@@ -64,9 +86,9 @@ - { - if (this.matchingStacksPacked == null) - { -- this.matchingStacksPacked = new IntArrayList(this.matchingStacks.length); -+ this.matchingStacksPacked = new IntArrayList(this.matchingStacksExploded.length); - -- for (ItemStack itemstack : this.matchingStacks) -+ for (ItemStack itemstack : this.matchingStacksExploded) - { - this.matchingStacksPacked.add(RecipeItemHelper.pack(itemstack)); - } -@@ -77,6 +99,18 @@ - return this.matchingStacksPacked; - } - -+ public static void invalidateAll() -+ { -+ for (Ingredient ing : INSTANCES) -+ if (ing != null) -+ ing.invalidate(); -+ } -+ -+ protected void invalidate() -+ { -+ this.matchingStacksPacked = null; -+ } -+ - public static Ingredient fromItem(Item p_193367_0_) - { - return fromStacks(new ItemStack(p_193367_0_, 1, 32767)); -@@ -108,5 +142,23 @@ - } - - return EMPTY; -+ } -+ -+ // Merges several vanilla Ingredients together. As a qwerk of how the json is structured, we can't tell if its a single Ingredient type or multiple so we split per item and remerge here. -+ //Only public for internal use, so we can access a private field in here. -+ public static Ingredient merge(java.util.Collection parts) -+ { -+ net.minecraft.util.NonNullList lst = net.minecraft.util.NonNullList.create(); -+ for (Ingredient part : parts) -+ { -+ for (ItemStack stack : part.matchingStacks) -+ lst.add(stack); -+ } -+ return new Ingredient(lst.toArray(new ItemStack[lst.size()])); -+ } -+ -+ public boolean isSimple() -+ { -+ return isSimple || this == EMPTY; - } - } diff --git a/patches/minecraft/net/minecraft/item/crafting/RecipeBookCloning.java.patch b/patches/minecraft/net/minecraft/item/crafting/RecipeBookCloning.java.patch deleted file mode 100644 index 94ef79aec..000000000 --- a/patches/minecraft/net/minecraft/item/crafting/RecipeBookCloning.java.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- before/net/minecraft/item/crafting/RecipeBookCloning.java -+++ after/net/minecraft/item/crafting/RecipeBookCloning.java -@@ -6,10 +6,8 @@ - import net.minecraft.item.ItemWrittenBook; - import net.minecraft.util.NonNullList; - import net.minecraft.world.World; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; - --public class RecipeBookCloning implements IRecipe -+public class RecipeBookCloning extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe - { - @Override - public boolean matches(InventoryCrafting inv, World worldIn) -@@ -132,7 +130,6 @@ - return true; - } - -- @SideOnly(Side.CLIENT) - @Override - public boolean canFit(int width, int height) - { diff --git a/patches/minecraft/net/minecraft/item/crafting/RecipeFireworks.java.patch b/patches/minecraft/net/minecraft/item/crafting/RecipeFireworks.java.patch deleted file mode 100644 index 2fc051baf..000000000 --- a/patches/minecraft/net/minecraft/item/crafting/RecipeFireworks.java.patch +++ /dev/null @@ -1,67 +0,0 @@ ---- before/net/minecraft/item/crafting/RecipeFireworks.java -+++ after/net/minecraft/item/crafting/RecipeFireworks.java -@@ -10,10 +10,8 @@ - import net.minecraft.nbt.NBTTagList; - import net.minecraft.util.NonNullList; - import net.minecraft.world.World; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; - --public class RecipeFireworks implements IRecipe -+public class RecipeFireworks extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe - { - private ItemStack resultItem = ItemStack.EMPTY; - -@@ -42,7 +40,7 @@ - { - l++; - } -- else if (itemstack.getItem() == Items.DYE) -+ else if (net.minecraftforge.oredict.DyeUtils.isDye(itemstack)) - { - k++; - } -@@ -130,9 +128,9 @@ - - if (!itemstack2.isEmpty()) - { -- if (itemstack2.getItem() == Items.DYE) -+ if (net.minecraftforge.oredict.DyeUtils.isDye(itemstack2)) - { -- list.add(ItemDye.DYE_COLORS[itemstack2.getMetadata() & 15]); -+ list.add(ItemDye.DYE_COLORS[net.minecraftforge.oredict.DyeUtils.rawDyeDamageFromStack(itemstack2) & 15]); - } - else if (itemstack2.getItem() == Items.GLOWSTONE_DUST) - { -@@ -184,9 +182,9 @@ - - if (!itemstack1.isEmpty()) - { -- if (itemstack1.getItem() == Items.DYE) -+ if (net.minecraftforge.oredict.DyeUtils.isDye(itemstack1)) - { -- list1.add(ItemDye.DYE_COLORS[itemstack1.getMetadata() & 15]); -+ list1.add(ItemDye.DYE_COLORS[net.minecraftforge.oredict.DyeUtils.rawDyeDamageFromStack(itemstack1) & 15]); - } - else if (itemstack1.getItem() == Items.FIREWORK_CHARGE) - { -@@ -249,10 +247,7 @@ - { - ItemStack itemstack = inv.getStackInSlot(i); - -- if (itemstack.getItem().hasContainerItem()) -- { -- nonnulllist.set(i, new ItemStack(itemstack.getItem().getContainerItem())); -- } -+ nonnulllist.set(i, net.minecraftforge.common.ForgeHooks.getContainerItem(itemstack)); - } - - return nonnulllist; -@@ -264,7 +259,6 @@ - return true; - } - -- @SideOnly(Side.CLIENT) - @Override - public boolean canFit(int width, int height) - { diff --git a/patches/minecraft/net/minecraft/item/crafting/RecipeRepairItem.java.patch b/patches/minecraft/net/minecraft/item/crafting/RecipeRepairItem.java.patch deleted file mode 100644 index 5a3348a66..000000000 --- a/patches/minecraft/net/minecraft/item/crafting/RecipeRepairItem.java.patch +++ /dev/null @@ -1,73 +0,0 @@ ---- before/net/minecraft/item/crafting/RecipeRepairItem.java -+++ after/net/minecraft/item/crafting/RecipeRepairItem.java -@@ -7,10 +7,8 @@ - import net.minecraft.item.ItemStack; - import net.minecraft.util.NonNullList; - import net.minecraft.world.World; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; - --public class RecipeRepairItem implements IRecipe -+public class RecipeRepairItem extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe - { - @Override - public boolean matches(InventoryCrafting inv, World worldIn) -@@ -32,7 +30,7 @@ - if (itemstack.getItem() != itemstack1.getItem() - || itemstack1.getCount() != 1 - || itemstack.getCount() != 1 -- || !itemstack1.getItem().isDamageable()) -+ || !itemstack1.getItem().isRepairable()) - { - return false; - } -@@ -63,7 +61,7 @@ - if (itemstack.getItem() != itemstack1.getItem() - || itemstack1.getCount() != 1 - || itemstack.getCount() != 1 -- || !itemstack1.getItem().isDamageable()) -+ || !itemstack1.getItem().isRepairable()) - { - return ItemStack.EMPTY; - } -@@ -79,13 +77,13 @@ - if (itemstack2.getItem() == itemstack3.getItem() - && itemstack2.getCount() == 1 - && itemstack3.getCount() == 1 -- && itemstack2.getItem().isDamageable()) -+ && itemstack2.getItem().isRepairable()) - { -- Item item = itemstack2.getItem(); -- int j = item.getMaxDamage() - itemstack2.getItemDamage(); -- int k = item.getMaxDamage() - itemstack3.getItemDamage(); -- int l = j + k + item.getMaxDamage() * 5 / 100; -- int i1 = item.getMaxDamage() - l; -+ // FORGE: Make itemstack sensitive // Item item = itemstack2.getItem(); -+ int j = itemstack2.getMaxDamage() - itemstack2.getItemDamage(); -+ int k = itemstack2.getMaxDamage() - itemstack3.getItemDamage(); -+ int l = j + k + itemstack2.getMaxDamage() * 5 / 100; -+ int i1 = itemstack2.getMaxDamage() - l; - - if (i1 < 0) - { -@@ -113,11 +111,7 @@ - for (int i = 0; i < nonnulllist.size(); i++) - { - ItemStack itemstack = inv.getStackInSlot(i); -- -- if (itemstack.getItem().hasContainerItem()) -- { -- nonnulllist.set(i, new ItemStack(itemstack.getItem().getContainerItem())); -- } -+ nonnulllist.set(i, net.minecraftforge.common.ForgeHooks.getContainerItem(itemstack)); - } - - return nonnulllist; -@@ -129,7 +123,6 @@ - return true; - } - -- @SideOnly(Side.CLIENT) - @Override - public boolean canFit(int width, int height) - { diff --git a/patches/minecraft/net/minecraft/item/crafting/RecipeTippedArrow.java.patch b/patches/minecraft/net/minecraft/item/crafting/RecipeTippedArrow.java.patch deleted file mode 100644 index 947dc31e8..000000000 --- a/patches/minecraft/net/minecraft/item/crafting/RecipeTippedArrow.java.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- before/net/minecraft/item/crafting/RecipeTippedArrow.java -+++ after/net/minecraft/item/crafting/RecipeTippedArrow.java -@@ -7,10 +7,8 @@ - import net.minecraft.potion.PotionUtils; - import net.minecraft.util.NonNullList; - import net.minecraft.world.World; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; - --public class RecipeTippedArrow implements IRecipe -+public class RecipeTippedArrow extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe - { - @Override - public boolean matches(InventoryCrafting inv, World worldIn) -@@ -88,7 +86,6 @@ - return true; - } - -- @SideOnly(Side.CLIENT) - @Override - public boolean canFit(int width, int height) - { diff --git a/patches/minecraft/net/minecraft/item/crafting/RecipesArmorDyes.java.patch b/patches/minecraft/net/minecraft/item/crafting/RecipesArmorDyes.java.patch deleted file mode 100644 index a3fd2b6f2..000000000 --- a/patches/minecraft/net/minecraft/item/crafting/RecipesArmorDyes.java.patch +++ /dev/null @@ -1,59 +0,0 @@ ---- before/net/minecraft/item/crafting/RecipesArmorDyes.java -+++ after/net/minecraft/item/crafting/RecipesArmorDyes.java -@@ -9,10 +9,8 @@ - import net.minecraft.item.ItemStack; - import net.minecraft.util.NonNullList; - import net.minecraft.world.World; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; - --public class RecipesArmorDyes implements IRecipe -+public class RecipesArmorDyes extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe - { - @Override - public boolean matches(InventoryCrafting inv, World worldIn) -@@ -39,7 +37,7 @@ - } - else - { -- if (itemstack1.getItem() != Items.DYE) -+ if (!net.minecraftforge.oredict.DyeUtils.isDye(itemstack1)) - { - return false; - } -@@ -94,12 +92,12 @@ - } - else - { -- if (itemstack1.getItem() != Items.DYE) -+ if (!net.minecraftforge.oredict.DyeUtils.isDye(itemstack1)) - { - return ItemStack.EMPTY; - } - -- float[] afloat = EnumDyeColor.byDyeDamage(itemstack1.getMetadata()).getColorComponentValues(); -+ float[] afloat = net.minecraftforge.oredict.DyeUtils.colorFromStack(itemstack1).get().getColorComponentValues(); - int l1 = (int)(afloat[0] * 255.0F); - int i2 = (int)(afloat[1] * 255.0F); - int j2 = (int)(afloat[2] * 255.0F); -@@ -147,11 +145,7 @@ - for (int i = 0; i < nonnulllist.size(); i++) - { - ItemStack itemstack = inv.getStackInSlot(i); -- -- if (itemstack.getItem().hasContainerItem()) -- { -- nonnulllist.set(i, new ItemStack(itemstack.getItem().getContainerItem())); -- } -+ nonnulllist.set(i, net.minecraftforge.common.ForgeHooks.getContainerItem(itemstack)); - } - - return nonnulllist; -@@ -163,7 +157,6 @@ - return true; - } - -- @SideOnly(Side.CLIENT) - @Override - public boolean canFit(int width, int height) - { diff --git a/patches/minecraft/net/minecraft/item/crafting/RecipesBanners.java.patch b/patches/minecraft/net/minecraft/item/crafting/RecipesBanners.java.patch deleted file mode 100644 index 5b117a1fe..000000000 --- a/patches/minecraft/net/minecraft/item/crafting/RecipesBanners.java.patch +++ /dev/null @@ -1,97 +0,0 @@ ---- before/net/minecraft/item/crafting/RecipesBanners.java -+++ after/net/minecraft/item/crafting/RecipesBanners.java -@@ -12,12 +12,10 @@ - import net.minecraft.tileentity.TileEntityBanner; - import net.minecraft.util.NonNullList; - import net.minecraft.world.World; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; - - public class RecipesBanners - { -- public static class RecipeAddPattern implements IRecipe -+ public static class RecipeAddPattern extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe - { - @Override - public boolean matches(InventoryCrafting inv, World worldIn) -@@ -74,9 +72,10 @@ - { - ItemStack itemstack2 = inv.getStackInSlot(j); - -- if (itemstack2.getItem() == Items.DYE) -+ int color = net.minecraftforge.oredict.DyeUtils.rawDyeDamageFromStack(itemstack2); -+ if (color != -1) - { -- k = itemstack2.getMetadata(); -+ k = color; - break; - } - } -@@ -117,11 +116,7 @@ - for (int i = 0; i < nonnulllist.size(); i++) - { - ItemStack itemstack = inv.getStackInSlot(i); -- -- if (itemstack.getItem().hasContainerItem()) -- { -- nonnulllist.set(i, new ItemStack(itemstack.getItem().getContainerItem())); -- } -+ nonnulllist.set(i, net.minecraftforge.common.ForgeHooks.getContainerItem(itemstack)); - } - - return nonnulllist; -@@ -147,7 +142,7 @@ - - if (!itemstack.isEmpty() && itemstack.getItem() != Items.BANNER) - { -- if (itemstack.getItem() == Items.DYE) -+ if (net.minecraftforge.oredict.DyeUtils.isDye(itemstack)) - { - if (flag2) - { -@@ -187,7 +182,7 @@ - - if (!itemstack1.isEmpty() && itemstack1.getItem() != Items.BANNER) - { -- if (itemstack1.getItem() != Items.DYE) -+ if (!net.minecraftforge.oredict.DyeUtils.isDye(itemstack1)) - { - flag = false; - break; -@@ -235,7 +230,6 @@ - return true; - } - -- @SideOnly(Side.CLIENT) - @Override - public boolean canFit(int width, int height) - { -@@ -243,7 +237,7 @@ - } - } - -- public static class RecipeDuplicatePattern implements IRecipe -+ public static class RecipeDuplicatePattern extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe - { - @Override - public boolean matches(InventoryCrafting inv, World worldIn) -@@ -347,9 +341,9 @@ - - if (!itemstack.isEmpty()) - { -- if (itemstack.getItem().hasContainerItem()) -+ if (itemstack.getItem().hasContainerItem(itemstack)) - { -- nonnulllist.set(i, new ItemStack(itemstack.getItem().getContainerItem())); -+ nonnulllist.set(i, net.minecraftforge.common.ForgeHooks.getContainerItem(itemstack)); - } - else if (itemstack.hasTagCompound() && TileEntityBanner.getPatterns(itemstack) > 0) - { -@@ -369,7 +363,6 @@ - return true; - } - -- @SideOnly(Side.CLIENT) - @Override - public boolean canFit(int width, int height) - { diff --git a/patches/minecraft/net/minecraft/item/crafting/RecipesMapCloning.java.patch b/patches/minecraft/net/minecraft/item/crafting/RecipesMapCloning.java.patch deleted file mode 100644 index 53cbe625c..000000000 --- a/patches/minecraft/net/minecraft/item/crafting/RecipesMapCloning.java.patch +++ /dev/null @@ -1,35 +0,0 @@ ---- before/net/minecraft/item/crafting/RecipesMapCloning.java -+++ after/net/minecraft/item/crafting/RecipesMapCloning.java -@@ -5,10 +5,8 @@ - import net.minecraft.item.ItemStack; - import net.minecraft.util.NonNullList; - import net.minecraft.world.World; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; - --public class RecipesMapCloning implements IRecipe -+public class RecipesMapCloning extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe - { - @Override - public boolean matches(InventoryCrafting inv, World worldIn) -@@ -115,11 +113,7 @@ - for (int i = 0; i < nonnulllist.size(); i++) - { - ItemStack itemstack = inv.getStackInSlot(i); -- -- if (itemstack.getItem().hasContainerItem()) -- { -- nonnulllist.set(i, new ItemStack(itemstack.getItem().getContainerItem())); -- } -+ nonnulllist.set(i, net.minecraftforge.common.ForgeHooks.getContainerItem(itemstack)); - } - - return nonnulllist; -@@ -131,7 +125,6 @@ - return true; - } - -- @SideOnly(Side.CLIENT) - @Override - public boolean canFit(int width, int height) - { diff --git a/patches/minecraft/net/minecraft/item/crafting/ShapedRecipes.java.patch b/patches/minecraft/net/minecraft/item/crafting/ShapedRecipes.java.patch deleted file mode 100644 index 05f13c995..000000000 --- a/patches/minecraft/net/minecraft/item/crafting/ShapedRecipes.java.patch +++ /dev/null @@ -1,84 +0,0 @@ ---- before/net/minecraft/item/crafting/ShapedRecipes.java -+++ after/net/minecraft/item/crafting/ShapedRecipes.java -@@ -19,10 +19,8 @@ - import net.minecraft.util.NonNullList; - import net.minecraft.util.ResourceLocation; - import net.minecraft.world.World; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; - --public class ShapedRecipes implements IRecipe -+public class ShapedRecipes extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements net.minecraftforge.common.crafting.IShapedRecipe - { - public final int recipeWidth; - public final int recipeHeight; -@@ -39,7 +37,6 @@ - this.recipeOutput = result; - } - -- @SideOnly(Side.CLIENT) - @Override - public String getGroup() - { -@@ -61,10 +58,7 @@ - { - ItemStack itemstack = inv.getStackInSlot(i); - -- if (itemstack.getItem().hasContainerItem()) -- { -- nonnulllist.set(i, new ItemStack(itemstack.getItem().getContainerItem())); -- } -+ nonnulllist.set(i, net.minecraftforge.common.ForgeHooks.getContainerItem(itemstack)); - } - - return nonnulllist; -@@ -76,7 +70,6 @@ - return this.recipeItems; - } - -- @SideOnly(Side.CLIENT) - @Override - public boolean canFit(int width, int height) - { -@@ -86,9 +79,9 @@ - @Override - public boolean matches(InventoryCrafting inv, World worldIn) - { -- for (int i = 0; i <= 3 - this.recipeWidth; i++) -+ for (int i = 0; i <= inv.getWidth() - this.recipeWidth; ++i) - { -- for (int j = 0; j <= 3 - this.recipeHeight; j++) -+ for (int j = 0; j <= inv.getHeight() - this.recipeHeight; ++j) - { - if (this.checkMatch(inv, i, j, true)) - { -@@ -107,9 +100,9 @@ - - private boolean checkMatch(InventoryCrafting craftingInventory, int p_77573_2_, int p_77573_3_, boolean p_77573_4_) - { -- for (int i = 0; i < 3; i++) -+ for (int i = 0; i < craftingInventory.getWidth(); ++i) - { -- for (int j = 0; j < 3; j++) -+ for (int j = 0; j < craftingInventory.getHeight(); ++j) - { - int k = i - p_77573_2_; - int l = j - p_77573_3_; -@@ -382,5 +375,17 @@ - int j = useCount ? JsonUtils.getInt(json, "count", 1) : 1; - return new ItemStack(item, j, i); - } -+ } -+ -+ //================================================ FORGE START ================================================ -+ @Override -+ public int getRecipeWidth() -+ { -+ return this.getWidth(); -+ } -+ @Override -+ public int getRecipeHeight() -+ { -+ return this.getHeight(); - } - } diff --git a/patches/minecraft/net/minecraft/item/crafting/ShapelessRecipes.java.patch b/patches/minecraft/net/minecraft/item/crafting/ShapelessRecipes.java.patch deleted file mode 100644 index fd72397db..000000000 --- a/patches/minecraft/net/minecraft/item/crafting/ShapelessRecipes.java.patch +++ /dev/null @@ -1,103 +0,0 @@ ---- before/net/minecraft/item/crafting/ShapelessRecipes.java -+++ after/net/minecraft/item/crafting/ShapelessRecipes.java -@@ -10,23 +10,25 @@ - import net.minecraft.util.JsonUtils; - import net.minecraft.util.NonNullList; - import net.minecraft.world.World; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; - --public class ShapelessRecipes implements IRecipe -+public class ShapelessRecipes extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe - { - private final ItemStack recipeOutput; - public final NonNullList recipeItems; - private final String group; -+ private final boolean isSimple; - - public ShapelessRecipes(String group, ItemStack output, NonNullList ingredients) - { - this.group = group; - this.recipeOutput = output; - this.recipeItems = ingredients; -+ boolean simple = true; -+ for (Ingredient i : ingredients) -+ simple &= i.isSimple(); -+ this.isSimple = simple; - } - -- @SideOnly(Side.CLIENT) - @Override - public String getGroup() - { -@@ -54,10 +56,7 @@ - { - ItemStack itemstack = inv.getStackInSlot(i); - -- if (itemstack.getItem().hasContainerItem()) -- { -- nonnulllist.set(i, new ItemStack(itemstack.getItem().getContainerItem())); -- } -+ nonnulllist.set(i, net.minecraftforge.common.ForgeHooks.getContainerItem(itemstack)); - } - - return nonnulllist; -@@ -66,7 +65,9 @@ - @Override - public boolean matches(InventoryCrafting inv, World worldIn) - { -- List list = Lists.newArrayList(this.recipeItems); -+ int ingredientCount = 0; -+ net.minecraft.client.util.RecipeItemHelper recipeItemHelper = new net.minecraft.client.util.RecipeItemHelper(); -+ List inputs = Lists.newArrayList(); - - for (int i = 0; i < inv.getHeight(); i++) - { -@@ -76,27 +77,22 @@ - - if (!itemstack.isEmpty()) - { -- boolean flag = false; -- -- for (Ingredient ingredient : list) -- { -- if (ingredient.apply(itemstack)) -- { -- flag = true; -- list.remove(ingredient); -- break; -- } -- } -- -- if (!flag) -- { -- return false; -- } -+ ++ingredientCount; -+ if (this.isSimple) -+ recipeItemHelper.accountStack(itemstack, 1); -+ else -+ inputs.add(itemstack); - } - } - } - -- return list.isEmpty(); -+ if (ingredientCount != this.recipeItems.size()) -+ return false; -+ -+ if (this.isSimple) -+ return recipeItemHelper.canCraft(this, null); -+ -+ return net.minecraftforge.common.util.RecipeMatcher.findMatches(inputs, this.recipeItems) != null; - } - - @Override -@@ -142,7 +138,6 @@ - return nonnulllist; - } - -- @SideOnly(Side.CLIENT) - @Override - public boolean canFit(int width, int height) - { diff --git a/patches/minecraft/net/minecraft/item/crafting/ShieldRecipes.java.patch b/patches/minecraft/net/minecraft/item/crafting/ShieldRecipes.java.patch deleted file mode 100644 index 3e025d7de..000000000 --- a/patches/minecraft/net/minecraft/item/crafting/ShieldRecipes.java.patch +++ /dev/null @@ -1,24 +0,0 @@ ---- before/net/minecraft/item/crafting/ShieldRecipes.java -+++ after/net/minecraft/item/crafting/ShieldRecipes.java -@@ -6,12 +6,10 @@ - import net.minecraft.nbt.NBTTagCompound; - import net.minecraft.util.NonNullList; - import net.minecraft.world.World; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; - - public class ShieldRecipes - { -- public static class Decoration implements IRecipe -+ public static class Decoration extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe - { - @Override - public boolean matches(InventoryCrafting inv, World worldIn) -@@ -126,7 +124,6 @@ - return true; - } - -- @SideOnly(Side.CLIENT) - @Override - public boolean canFit(int width, int height) - { diff --git a/patches/minecraft/net/minecraft/item/crafting/ShulkerBoxRecipes.java.patch b/patches/minecraft/net/minecraft/item/crafting/ShulkerBoxRecipes.java.patch deleted file mode 100644 index 553d67508..000000000 --- a/patches/minecraft/net/minecraft/item/crafting/ShulkerBoxRecipes.java.patch +++ /dev/null @@ -1,50 +0,0 @@ ---- before/net/minecraft/item/crafting/ShulkerBoxRecipes.java -+++ after/net/minecraft/item/crafting/ShulkerBoxRecipes.java -@@ -8,12 +8,10 @@ - import net.minecraft.item.ItemStack; - import net.minecraft.util.NonNullList; - import net.minecraft.world.World; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; - - public class ShulkerBoxRecipes - { -- public static class ShulkerBoxColoring implements IRecipe -+ public static class ShulkerBoxColoring extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe - { - @Override - public boolean matches(InventoryCrafting inv, World worldIn) -@@ -33,7 +31,7 @@ - } - else - { -- if (itemstack.getItem() != Items.DYE) -+ if (!net.minecraftforge.oredict.DyeUtils.isDye(itemstack)) - { - return false; - } -@@ -67,14 +65,14 @@ - { - itemstack = itemstack2; - } -- else if (itemstack2.getItem() == Items.DYE) -+ else if (net.minecraftforge.oredict.DyeUtils.isDye(itemstack2)) - { - itemstack1 = itemstack2; - } - } - } - -- ItemStack itemstack3 = BlockShulkerBox.getColoredItemStack(EnumDyeColor.byDyeDamage(itemstack1.getMetadata())); -+ ItemStack itemstack3 = BlockShulkerBox.getColoredItemStack(net.minecraftforge.oredict.DyeUtils.colorFromStack(itemstack1).get()); - - if (itemstack.hasTagCompound()) - { -@@ -114,7 +112,6 @@ - return true; - } - -- @SideOnly(Side.CLIENT) - @Override - public boolean canFit(int width, int height) - { diff --git a/patches/minecraft/net/minecraft/nbt/CompressedStreamTools.java.patch b/patches/minecraft/net/minecraft/nbt/CompressedStreamTools.java.patch deleted file mode 100644 index 56bec8d0d..000000000 --- a/patches/minecraft/net/minecraft/nbt/CompressedStreamTools.java.patch +++ /dev/null @@ -1,53 +0,0 @@ ---- before/net/minecraft/nbt/CompressedStreamTools.java -+++ after/net/minecraft/nbt/CompressedStreamTools.java -@@ -18,8 +18,6 @@ - import net.minecraft.crash.CrashReport; - import net.minecraft.crash.CrashReportCategory; - import net.minecraft.util.ReportedException; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; - - public class CompressedStreamTools - { -@@ -54,7 +52,6 @@ - } - } - -- @SideOnly(Side.CLIENT) - public static void safeWrite(NBTTagCompound compound, File fileIn) throws IOException - { - File file1 = new File(fileIn.getAbsolutePath() + "_tmp"); -@@ -81,7 +78,6 @@ - } - } - -- @SideOnly(Side.CLIENT) - public static void write(NBTTagCompound compound, File fileIn) throws IOException - { - DataOutputStream dataoutputstream = new DataOutputStream(new FileOutputStream(fileIn)); -@@ -97,7 +93,6 @@ - } - - @Nullable -- @SideOnly(Side.CLIENT) - public static NBTTagCompound read(File fileIn) throws IOException - { - if (!fileIn.exists()) -@@ -160,6 +155,7 @@ - private static NBTBase read(DataInput input, int depth, NBTSizeTracker accounter) throws IOException - { - byte b0 = input.readByte(); -+ accounter.read(8); // Forge: Count everything! - - if (b0 == 0) - { -@@ -167,7 +163,8 @@ - } - else - { -- input.readUTF(); -+ NBTSizeTracker.readUTF(accounter, input.readUTF()); //Forge: Count this string. -+ accounter.read(32); //Forge: 4 extra bytes for the object allocation. - NBTBase nbtbase = NBTBase.create(b0); - - try diff --git a/patches/minecraft/net/minecraft/nbt/NBTSizeTracker.java.patch b/patches/minecraft/net/minecraft/nbt/NBTSizeTracker.java.patch deleted file mode 100644 index a4921f86c..000000000 --- a/patches/minecraft/net/minecraft/nbt/NBTSizeTracker.java.patch +++ /dev/null @@ -1,37 +0,0 @@ ---- before/net/minecraft/nbt/NBTSizeTracker.java -+++ after/net/minecraft/nbt/NBTSizeTracker.java -@@ -28,4 +28,34 @@ - ); - } - } -+ -+ /* -+ * UTF8 is not a simple encoding system, each character can be either -+ * 1, 2, or 3 bytes. Depending on where it's numerical value falls. -+ * We have to count up each character individually to see the true -+ * length of the data. -+ * -+ * Basic concept is that it uses the MSB of each byte as a 'read more' signal. -+ * So it has to shift each 7-bit segment. -+ * -+ * This will accurately count the correct byte length to encode this string, plus the 2 bytes for it's length prefix. -+ */ -+ public static void readUTF(NBTSizeTracker tracker, String data) -+ { -+ tracker.read(16); //Header length -+ if (data == null) -+ return; -+ -+ int len = data.length(); -+ int utflen = 0; -+ -+ for (int i = 0; i < len; i++) -+ { -+ int c = data.charAt(i); -+ if ((c >= 0x0001) && (c <= 0x007F)) utflen += 1; -+ else if (c > 0x07FF) utflen += 3; -+ else utflen += 2; -+ } -+ tracker.read(8 * utflen); -+ } - } diff --git a/patches/minecraft/net/minecraft/nbt/NBTTagCompound.java.patch b/patches/minecraft/net/minecraft/nbt/NBTTagCompound.java.patch deleted file mode 100644 index 8299097f5..000000000 --- a/patches/minecraft/net/minecraft/nbt/NBTTagCompound.java.patch +++ /dev/null @@ -1,26 +0,0 @@ ---- before/net/minecraft/nbt/NBTTagCompound.java -+++ after/net/minecraft/nbt/NBTTagCompound.java -@@ -85,6 +85,7 @@ - - public void setTag(String key, NBTBase value) - { -+ if (value == null) throw new IllegalArgumentException("Invalid null NBT value with key " + key); - this.tagMap.put(key, value); - } - -@@ -473,6 +474,7 @@ - - private static byte readType(DataInput input, NBTSizeTracker sizeTracker) throws IOException - { -+ sizeTracker.read(8); - return input.readByte(); - } - -@@ -483,6 +485,7 @@ - - static NBTBase readNBT(byte id, String key, DataInput input, int depth, NBTSizeTracker sizeTracker) throws IOException - { -+ sizeTracker.read(32); //Forge: 4 extra bytes for the object allocation. - NBTBase nbtbase = NBTBase.create(id); - - try diff --git a/patches/minecraft/net/minecraft/nbt/NBTTagList.java.patch b/patches/minecraft/net/minecraft/nbt/NBTTagList.java.patch deleted file mode 100644 index 33172f3a4..000000000 --- a/patches/minecraft/net/minecraft/nbt/NBTTagList.java.patch +++ /dev/null @@ -1,17 +0,0 @@ ---- before/net/minecraft/nbt/NBTTagList.java -+++ after/net/minecraft/nbt/NBTTagList.java -@@ -9,7 +9,7 @@ - import org.apache.logging.log4j.LogManager; - import org.apache.logging.log4j.Logger; - --public class NBTTagList extends NBTBase -+public class NBTTagList extends NBTBase implements java.lang.Iterable - { - private static final Logger LOGGER = LogManager.getLogger(); - private List tagList = Lists.newArrayList(); -@@ -288,4 +288,5 @@ - { - return this.tagType; - } -+ @Override public java.util.Iterator iterator() {return tagList.iterator();} - } diff --git a/patches/minecraft/net/minecraft/nbt/NBTTagString.java.patch b/patches/minecraft/net/minecraft/nbt/NBTTagString.java.patch deleted file mode 100644 index c9bb6b57c..000000000 --- a/patches/minecraft/net/minecraft/nbt/NBTTagString.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/nbt/NBTTagString.java -+++ after/net/minecraft/nbt/NBTTagString.java -@@ -31,7 +31,7 @@ - { - sizeTracker.read(288L); - this.data = input.readUTF(); -- sizeTracker.read(16 * this.data.length()); -+ NBTSizeTracker.readUTF(sizeTracker, data); // Forge: Correctly read String length including header. - } - - @Override diff --git a/patches/minecraft/net/minecraft/network/NetHandlerPlayServer.java.patch b/patches/minecraft/net/minecraft/network/NetHandlerPlayServer.java.patch deleted file mode 100644 index bc05a253b..000000000 --- a/patches/minecraft/net/minecraft/network/NetHandlerPlayServer.java.patch +++ /dev/null @@ -1,144 +0,0 @@ ---- before/net/minecraft/network/NetHandlerPlayServer.java -+++ after/net/minecraft/network/NetHandlerPlayServer.java -@@ -370,6 +370,7 @@ - d7 = d4 - this.lowestRiddenY1 - 1.0E-6; - d8 = d5 - this.lowestRiddenZ1; - entity.move(MoverType.PLAYER, d6, d7, d8); -+ double d11 = d7; - d6 = d3 - entity.posX; - d7 = d4 - entity.posY; - -@@ -389,11 +390,13 @@ - } - - entity.setPositionAndRotation(d3, d4, d5, f, f1); -+ this.player.setPositionAndRotation(d3, d4, d5, this.player.rotationYaw, this.player.rotationPitch); // Forge - Resync player position on vehicle moving - boolean flag2 = worldserver.getCollisionBoxes(entity, entity.getEntityBoundingBox().shrink(0.0625)).isEmpty(); - - if (flag && (flag1 || !flag2)) - { - entity.setPositionAndRotation(d0, d1, d2, f, f1); -+ this.player.setPositionAndRotation(d0, d1, d2, this.player.rotationYaw, this.player.rotationPitch); // Forge - Resync player position on vehicle moving - this.netManager.sendPacket(new SPacketMoveVehicle(entity)); - return; - } -@@ -401,7 +404,7 @@ - this.server.getPlayerList().serverUpdateMovingPlayer(this.player); - this.player - .addMovementStat(this.player.posX - d0, this.player.posY - d1, this.player.posZ - d2); -- this.vehicleFloating = d7 >= -0.03125 -+ this.vehicleFloating = d11 >= -0.03125 - && !this.server.isFlightAllowed() - && !worldserver.checkBlockCollision(entity.getEntityBoundingBox().grow(0.0625).expand(0.0, -0.55, 0.0)); - this.lowestRiddenX1 = entity.posX; -@@ -600,6 +603,7 @@ - - this.player.move(MoverType.PLAYER, d7, d8, d9); - this.player.onGround = packetIn.isOnGround(); -+ double d12 = d8; - d7 = d4 - this.player.posX; - d8 = d5 - this.player.posY; - -@@ -637,7 +641,7 @@ - } - } - -- this.floating = d8 >= -0.03125; -+ this.floating = d12 >= -0.03125; - this.floating = this.floating & (!this.server.isFlightAllowed() && !this.player.capabilities.allowFlying); - this.floating = this.floating - & ( -@@ -743,7 +747,10 @@ - double d2 = this.player.posZ - (blockpos.getZ() + 0.5); - double d3 = d0 * d0 + d1 * d1 + d2 * d2; - -- if (d3 > 36.0) -+ double dist = player.getEntityAttribute(EntityPlayer.REACH_DISTANCE).getAttributeValue() + 1; -+ dist *= dist; -+ -+ if (d3 > dist) - { - return; - } -@@ -803,8 +810,10 @@ - if (blockpos.getY() < this.server.getBuildLimit() - 1 - || enumfacing != EnumFacing.UP && blockpos.getY() < this.server.getBuildLimit()) - { -+ double dist = player.getEntityAttribute(EntityPlayer.REACH_DISTANCE).getAttributeValue() + 3; -+ dist *= dist; - if (this.targetPos == null -- && this.player.getDistanceSq(blockpos.getX() + 0.5, blockpos.getY() + 0.5, blockpos.getZ() + 0.5) < 64.0 -+ && this.player.getDistanceSq(blockpos.getX() + 0.5, blockpos.getY() + 0.5, blockpos.getZ() + 0.5) < dist - && !this.server.isBlockProtected(worldserver, blockpos, this.player) - && worldserver.getWorldBorder().contains(blockpos)) - { -@@ -880,19 +889,20 @@ - { - this.player.setPositionAndUpdate(entity.posX, entity.posY, entity.posZ); - } -- else -+ else if (net.minecraftforge.common.ForgeHooks.onTravelToDimension(this.player, entity.dimension)) - { -+ int prevDimension = this.player.dimension; - WorldServer worldserver1 = this.player.getServerWorld(); - WorldServer worldserver2 = (WorldServer)entity.world; - this.player.dimension = entity.dimension; - this.sendPacket( - new SPacketRespawn( - this.player.dimension, -- worldserver1.getDifficulty(), -- worldserver1.getWorldInfo().getTerrainType(), -+ worldserver2.getDifficulty(), -+ worldserver2.getWorldInfo().getTerrainType(), - this.player.interactionManager.getGameType() - ) -- ); -+ ); // Forge: Use new dimensions information - this.server.getPlayerList().updatePermissionLevel(this.player); - worldserver1.removeEntityDangerously(this.player); - this.player.isDead = false; -@@ -911,6 +921,7 @@ - this.player.interactionManager.setWorld(worldserver2); - this.server.getPlayerList().updateTimeAndWeatherForPlayer(this.player, worldserver2); - this.server.getPlayerList().syncPlayerInventory(this.player); -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().firePlayerChangedDimensionEvent(this.player, prevDimension, this.player.dimension); - } - } - } -@@ -1036,7 +1047,9 @@ - } - else - { -- ITextComponent itextcomponent = new TextComponentTranslation("chat.type.text", this.player.getDisplayName(), s); -+ ITextComponent itextcomponent = new TextComponentTranslation("chat.type.text", this.player.getDisplayName(), net.minecraftforge.common.ForgeHooks.newChatWithLinks(s)); -+ itextcomponent = net.minecraftforge.common.ForgeHooks.onServerChatEvent(this, s, itextcomponent); -+ if (itextcomponent == null) return; - this.server.getPlayerList().sendMessage(itextcomponent, false); - } - -@@ -1175,6 +1188,7 @@ - else if (packetIn.getAction() == CPacketUseEntity.Action.INTERACT_AT) - { - EnumHand enumhand1 = packetIn.getHand(); -+ if(net.minecraftforge.common.ForgeHooks.onInteractEntityAt(player, entity, packetIn.getHitVec(), enumhand1) != null) return; - entity.applyPlayerInteraction(this.player, packetIn.getHitVec(), enumhand1); - } - else if (packetIn.getAction() == CPacketUseEntity.Action.ATTACK) -@@ -1216,7 +1230,7 @@ - return; - } - -- this.player = this.server.getPlayerList().recreatePlayerEntity(this.player, 0, false); -+ this.player = this.server.getPlayerList().recreatePlayerEntity(this.player, player.dimension, false); - - if (this.server.isHardcore()) - { -@@ -1264,7 +1278,7 @@ - .openContainer - .slotClick(packetIn.getSlotId(), packetIn.getUsedButton(), packetIn.getClickType(), this.player); - -- if (ItemStack.areItemStacksEqual(packetIn.getClickedItem(), itemstack2)) -+ if (ItemStack.areItemStacksEqualUsingNBTShareTag(packetIn.getClickedItem(), itemstack2)) - { - this.player.connection.sendPacket(new SPacketConfirmTransaction(packetIn.getWindowId(), packetIn.getActionNumber(), true)); - this.player.isChangingQuantityOnly = true; diff --git a/patches/minecraft/net/minecraft/network/NettyPacketEncoder.java.patch b/patches/minecraft/net/minecraft/network/NettyPacketEncoder.java.patch deleted file mode 100644 index 9972241b4..000000000 --- a/patches/minecraft/net/minecraft/network/NettyPacketEncoder.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/network/NettyPacketEncoder.java -+++ after/net/minecraft/network/NettyPacketEncoder.java -@@ -54,7 +54,7 @@ - } - catch (Throwable throwable) - { -- LOGGER.error(throwable); -+ throw throwable; // Forge: throw this instead of logging it, to prevent corrupt packets from being sent to the client where they are much harder to debug. - } - } - } diff --git a/patches/minecraft/net/minecraft/network/NetworkManager.java.patch b/patches/minecraft/net/minecraft/network/NetworkManager.java.patch deleted file mode 100644 index 33d587bff..000000000 --- a/patches/minecraft/net/minecraft/network/NetworkManager.java.patch +++ /dev/null @@ -1,61 +0,0 @@ ---- before/net/minecraft/network/NetworkManager.java -+++ after/net/minecraft/network/NetworkManager.java -@@ -88,6 +88,11 @@ - this.direction = packetDirection; - } - -+ public EnumPacketDirection getDirection() -+ { -+ return this.direction; -+ } -+ - @Override - public void channelActive(ChannelHandlerContext p_channelActive_1_) throws Exception - { -@@ -210,7 +215,7 @@ - final EnumConnectionState enumconnectionstate = EnumConnectionState.getFromPacket(inPacket); - final EnumConnectionState enumconnectionstate1 = this.channel.attr(PROTOCOL_ATTRIBUTE_KEY).get(); - -- if (enumconnectionstate1 != enumconnectionstate) -+ if (enumconnectionstate1 != enumconnectionstate && !( inPacket instanceof net.minecraftforge.fml.common.network.internal.FMLProxyPacket)) - { - LOGGER.debug("Disabled auto read"); - this.channel.config().setAutoRead(false); -@@ -218,7 +223,7 @@ - - if (this.channel.eventLoop().inEventLoop()) - { -- if (enumconnectionstate != enumconnectionstate1) -+ if (enumconnectionstate != enumconnectionstate1 && !( inPacket instanceof net.minecraftforge.fml.common.network.internal.FMLProxyPacket)) - { - this.setConnectionState(enumconnectionstate); - } -@@ -239,7 +244,7 @@ - @Override - public void run() - { -- if (enumconnectionstate != enumconnectionstate1) -+ if (enumconnectionstate != enumconnectionstate1 && !( inPacket instanceof net.minecraftforge.fml.common.network.internal.FMLProxyPacket)) - { - NetworkManager.this.setConnectionState(enumconnectionstate); - } -@@ -317,6 +322,7 @@ - @SideOnly(Side.CLIENT) - public static NetworkManager createNetworkManagerAndConnect(InetAddress address, int serverPort, boolean useNativeTransport) - { -+ if (address instanceof java.net.Inet6Address) System.setProperty("java.net.preferIPv4Stack", "false"); - final NetworkManager networkmanager = new NetworkManager(EnumPacketDirection.CLIENTBOUND); - Class oclass; - LazyLoadBase lazyloadbase; -@@ -475,6 +481,11 @@ - } - } - } -+ } -+ -+ public Channel channel() -+ { -+ return channel; - } - - static class InboundHandlerTuplePacketListener diff --git a/patches/minecraft/net/minecraft/network/NetworkSystem.java.patch b/patches/minecraft/net/minecraft/network/NetworkSystem.java.patch deleted file mode 100644 index b052fb855..000000000 --- a/patches/minecraft/net/minecraft/network/NetworkSystem.java.patch +++ /dev/null @@ -1,61 +0,0 @@ ---- before/net/minecraft/network/NetworkSystem.java -+++ after/net/minecraft/network/NetworkSystem.java -@@ -37,6 +37,7 @@ - import net.minecraft.util.LazyLoadBase; - import net.minecraft.util.ReportedException; - import net.minecraft.util.text.TextComponentString; -+import net.minecraftforge.fml.common.thread.SidedThreadGroups; - import net.minecraftforge.fml.relauncher.Side; - import net.minecraftforge.fml.relauncher.SideOnly; - import org.apache.logging.log4j.LogManager; -@@ -49,21 +50,21 @@ - { - protected NioEventLoopGroup load() - { -- return new NioEventLoopGroup(0, new ThreadFactoryBuilder().setNameFormat("Netty Server IO #%d").setDaemon(true).build()); -+ return new NioEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Server IO #%d").setDaemon(true).setThreadFactory(net.minecraftforge.fml.common.thread.SidedThreadGroups.SERVER).build()); - } - }; - public static final LazyLoadBase SERVER_EPOLL_EVENTLOOP = new LazyLoadBase() - { - protected EpollEventLoopGroup load() - { -- return new EpollEventLoopGroup(0, new ThreadFactoryBuilder().setNameFormat("Netty Epoll Server IO #%d").setDaemon(true).build()); -+ return new EpollEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Epoll Server IO #%d").setDaemon(true).setThreadFactory(net.minecraftforge.fml.common.thread.SidedThreadGroups.SERVER).build()); - } - }; - public static final LazyLoadBase SERVER_LOCAL_EVENTLOOP = new LazyLoadBase() - { - protected LocalEventLoopGroup load() - { -- return new LocalEventLoopGroup(0, new ThreadFactoryBuilder().setNameFormat("Netty Local Server IO #%d").setDaemon(true).build()); -+ return new LocalEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Local Server IO #%d").setDaemon(true).setThreadFactory(SidedThreadGroups.SERVER).build()); - } - }; - private final MinecraftServer server; -@@ -79,6 +80,7 @@ - - public void addEndpoint(InetAddress address, int port) throws IOException - { -+ if (address instanceof java.net.Inet6Address) System.setProperty("java.net.preferIPv4Stack", "false"); - synchronized (this.endpoints) - { - Class oclass; -@@ -116,7 +118,7 @@ - } - - p_initChannel_1_.pipeline() -- .addLast("timeout", new ReadTimeoutHandler(30)) -+ .addLast("timeout", new ReadTimeoutHandler(net.minecraftforge.fml.common.network.internal.FMLNetworkHandler.READ_TIMEOUT)) - .addLast("legacy_query", new LegacyPingHandler(NetworkSystem.this)) - .addLast("splitter", new NettyVarint21FrameDecoder()) - .addLast("decoder", new NettyPacketDecoder(EnumPacketDirection.SERVERBOUND)) -@@ -154,7 +156,7 @@ - NetworkSystem.this.networkManagers.add(networkmanager); - p_initChannel_1_.pipeline().addLast("packet_handler", networkmanager); - } -- }).group(SERVER_NIO_EVENTLOOP.getValue()).localAddress(LocalAddress.ANY).bind().syncUninterruptibly(); -+ }).group(SERVER_LOCAL_EVENTLOOP.getValue()).localAddress(LocalAddress.ANY).bind().syncUninterruptibly(); - this.endpoints.add(channelfuture); - } - diff --git a/patches/minecraft/net/minecraft/network/PacketBuffer.java.patch b/patches/minecraft/net/minecraft/network/PacketBuffer.java.patch deleted file mode 100644 index 6884b157f..000000000 --- a/patches/minecraft/net/minecraft/network/PacketBuffer.java.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- before/net/minecraft/network/PacketBuffer.java -+++ after/net/minecraft/network/PacketBuffer.java -@@ -330,7 +330,7 @@ - - if (stack.getItem().isDamageable() || stack.getItem().getShareTag()) - { -- nbttagcompound = stack.getTagCompound(); -+ nbttagcompound = stack.getItem().getNBTShareTag(stack); - } - - this.writeCompoundTag(nbttagcompound); -@@ -352,7 +352,7 @@ - int j = this.readByte(); - int k = this.readShort(); - ItemStack itemstack = new ItemStack(Item.getItemById(i), j, k); -- itemstack.setTagCompound(this.readCompoundTag()); -+ itemstack.getItem().readNBTShareTag(itemstack, this.readCompoundTag()); - return itemstack; - } - } diff --git a/patches/minecraft/net/minecraft/network/ServerStatusResponse.java.patch b/patches/minecraft/net/minecraft/network/ServerStatusResponse.java.patch deleted file mode 100644 index b109f23c8..000000000 --- a/patches/minecraft/net/minecraft/network/ServerStatusResponse.java.patch +++ /dev/null @@ -1,90 +0,0 @@ ---- before/net/minecraft/network/ServerStatusResponse.java -+++ after/net/minecraft/network/ServerStatusResponse.java -@@ -29,6 +29,7 @@ - public void setServerDescription(ITextComponent descriptionIn) - { - this.description = descriptionIn; -+ invalidateJson(); - } - - public ServerStatusResponse.Players getPlayers() -@@ -39,6 +40,7 @@ - public void setPlayers(ServerStatusResponse.Players playersIn) - { - this.players = playersIn; -+ invalidateJson(); - } - - public ServerStatusResponse.Version getVersion() -@@ -49,11 +51,13 @@ - public void setVersion(ServerStatusResponse.Version versionIn) - { - this.version = versionIn; -+ invalidateJson(); - } - - public void setFavicon(String faviconBlob) - { - this.favicon = faviconBlob; -+ invalidateJson(); - } - - public String getFavicon() -@@ -178,6 +182,7 @@ - serverstatusresponse.setFavicon(JsonUtils.getString(jsonobject, "favicon")); - } - -+ net.minecraftforge.fml.client.FMLClientHandler.instance().captureAdditionalData(serverstatusresponse, jsonobject); - return serverstatusresponse; - } - -@@ -205,9 +210,49 @@ - jsonobject.addProperty("favicon", p_serialize_1_.getFavicon()); - } - -+ net.minecraftforge.fml.common.network.internal.FMLNetworkHandler.enhanceStatusQuery(jsonobject); - return jsonobject; - } - } -+ -+ private java.util.concurrent.Semaphore mutex = new java.util.concurrent.Semaphore(1); -+ private String json = null; -+ /** -+ * Returns this object as a Json string. -+ * Converting to JSON if a cached version is not available. -+ * -+ * Also to prevent potentially large memory allocations on the server -+ * this is moved from the S00PacketServerInfo writePacket function -+ * -+ * As this method is called from the network threads thread safety is important! -+ * -+ * @return -+ */ -+ public String getJson() -+ { -+ String ret = this.json; -+ if (ret == null) -+ { -+ mutex.acquireUninterruptibly(); -+ ret = this.json; -+ if (ret == null) -+ { -+ ret = net.minecraft.network.status.server.SPacketServerInfo.GSON.toJson(this); -+ this.json = ret; -+ } -+ mutex.release(); -+ } -+ return ret; -+ } -+ -+ /** -+ * Invalidates the cached json, causing the next call to getJson to rebuild it. -+ * This is needed externally because PlayerCountData.setPlayer's is public. -+ */ -+ public void invalidateJson() -+ { -+ this.json = null; -+ } - - public static class Version - { diff --git a/patches/minecraft/net/minecraft/network/datasync/DataSerializers.java.patch b/patches/minecraft/net/minecraft/network/datasync/DataSerializers.java.patch deleted file mode 100644 index 35f0fa8ad..000000000 --- a/patches/minecraft/net/minecraft/network/datasync/DataSerializers.java.patch +++ /dev/null @@ -1,27 +0,0 @@ ---- before/net/minecraft/network/datasync/DataSerializers.java -+++ after/net/minecraft/network/datasync/DataSerializers.java -@@ -319,20 +319,21 @@ - } - }; - -+ @Deprecated // Forge: ONLY FOR VANILLA - mods should use the Forge registry - public static void registerSerializer(DataSerializer serializer) - { -- REGISTRY.add(serializer); -+ if (REGISTRY.add(serializer) >= 256) throw new RuntimeException("Vanilla DataSerializer ID limit exceeded"); - } - - @Nullable - public static DataSerializer getSerializer(int id) - { -- return REGISTRY.get(id); -+ return net.minecraftforge.common.ForgeHooks.getSerializer(id, REGISTRY); - } - - public static int getSerializerId(DataSerializer serializer) - { -- return REGISTRY.getId(serializer); -+ return net.minecraftforge.common.ForgeHooks.getSerializerId(serializer, REGISTRY); - } - - static diff --git a/patches/minecraft/net/minecraft/network/datasync/EntityDataManager.java.patch b/patches/minecraft/net/minecraft/network/datasync/EntityDataManager.java.patch deleted file mode 100644 index d06adf45f..000000000 --- a/patches/minecraft/net/minecraft/network/datasync/EntityDataManager.java.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- before/net/minecraft/network/datasync/EntityDataManager.java -+++ after/net/minecraft/network/datasync/EntityDataManager.java -@@ -38,7 +38,7 @@ - - public static DataParameter createKey(Class clazz, DataSerializer serializer) - { -- if (LOGGER.isDebugEnabled()) -+ if (true || LOGGER.isDebugEnabled()) //Forge: This is very useful for mods that register keys on classes that are not their own - { - try - { -@@ -46,7 +46,9 @@ - - if (!oclass.equals(clazz)) - { -- LOGGER.debug("defineId called for: {} from {}", clazz, oclass, new RuntimeException()); -+ //Forge: log at warn, mods should not add to classes that they don't own, and only add stacktrace when in debug is enabled as it is mostly not needed and consumes time -+ if (LOGGER.isDebugEnabled()) LOGGER.warn("defineId called for: {} from {}", clazz, oclass, new RuntimeException()); -+ else LOGGER.warn("defineId called for: {} from {}", clazz, oclass); - } - } - catch (ClassNotFoundException classnotfoundexception) diff --git a/patches/minecraft/net/minecraft/network/handshake/client/C00Handshake.java.patch b/patches/minecraft/net/minecraft/network/handshake/client/C00Handshake.java.patch deleted file mode 100644 index d8d2c4a66..000000000 --- a/patches/minecraft/net/minecraft/network/handshake/client/C00Handshake.java.patch +++ /dev/null @@ -1,51 +0,0 @@ ---- before/net/minecraft/network/handshake/client/C00Handshake.java -+++ after/net/minecraft/network/handshake/client/C00Handshake.java -@@ -14,6 +14,7 @@ - private String ip; - private int port; - private EnumConnectionState requestedState; -+ private boolean hasFMLMarker = false; - - public C00Handshake() - { -@@ -28,6 +29,12 @@ - this.requestedState = p_i47613_3_; - } - -+ public C00Handshake(String address, int port, EnumConnectionState state, boolean addFMLMarker) -+ { -+ this(address, port, state); -+ this.hasFMLMarker = addFMLMarker; -+ } -+ - @Override - public void readPacketData(PacketBuffer buf) throws IOException - { -@@ -35,13 +42,15 @@ - this.ip = buf.readString(255); - this.port = buf.readUnsignedShort(); - this.requestedState = EnumConnectionState.getById(buf.readVarInt()); -+ this.hasFMLMarker = this.ip.contains("\0FML\0"); -+ this.ip = this.ip.split("\0")[0]; - } - - @Override - public void writePacketData(PacketBuffer buf) throws IOException - { - buf.writeVarInt(this.protocolVersion); -- buf.writeString(this.ip); -+ buf.writeString(this.ip + "\0FML\0"); - buf.writeShort(this.port); - buf.writeVarInt(this.requestedState.getId()); - } -@@ -59,5 +68,10 @@ - public int getProtocolVersion() - { - return this.protocolVersion; -+ } -+ -+ public boolean hasFMLMarker() -+ { -+ return this.hasFMLMarker; - } - } diff --git a/patches/minecraft/net/minecraft/network/login/server/SPacketLoginSuccess.java.patch b/patches/minecraft/net/minecraft/network/login/server/SPacketLoginSuccess.java.patch deleted file mode 100644 index 766427e1d..000000000 --- a/patches/minecraft/net/minecraft/network/login/server/SPacketLoginSuccess.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/network/login/server/SPacketLoginSuccess.java -+++ after/net/minecraft/network/login/server/SPacketLoginSuccess.java -@@ -27,7 +27,7 @@ - { - String s = buf.readString(36); - String s1 = buf.readString(16); -- UUID uuid = UUID.fromString(s); -+ UUID uuid = s.length() > 0 ? UUID.fromString(s) : null; - this.profile = new GameProfile(uuid, s1); - } - diff --git a/patches/minecraft/net/minecraft/network/play/client/CPacketClickWindow.java.patch b/patches/minecraft/net/minecraft/network/play/client/CPacketClickWindow.java.patch deleted file mode 100644 index d57cda075..000000000 --- a/patches/minecraft/net/minecraft/network/play/client/CPacketClickWindow.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/network/play/client/CPacketClickWindow.java -+++ after/net/minecraft/network/play/client/CPacketClickWindow.java -@@ -57,7 +57,7 @@ - buf.writeByte(this.packedClickData); - buf.writeShort(this.actionNumber); - buf.writeEnumValue(this.mode); -- buf.writeItemStack(this.clickedItem); -+ net.minecraftforge.common.util.PacketUtil.writeItemStackFromClientToServer(buf, this.clickedItem); - } - - public int getWindowId() diff --git a/patches/minecraft/net/minecraft/network/play/client/CPacketCreativeInventoryAction.java.patch b/patches/minecraft/net/minecraft/network/play/client/CPacketCreativeInventoryAction.java.patch deleted file mode 100644 index 27eba6f03..000000000 --- a/patches/minecraft/net/minecraft/network/play/client/CPacketCreativeInventoryAction.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/network/play/client/CPacketCreativeInventoryAction.java -+++ after/net/minecraft/network/play/client/CPacketCreativeInventoryAction.java -@@ -40,7 +40,7 @@ - public void writePacketData(PacketBuffer buf) throws IOException - { - buf.writeShort(this.slotId); -- buf.writeItemStack(this.stack); -+ net.minecraftforge.common.util.PacketUtil.writeItemStackFromClientToServer(buf, this.stack); - } - - public int getSlotId() diff --git a/patches/minecraft/net/minecraft/network/play/client/CPacketCustomPayload.java.patch b/patches/minecraft/net/minecraft/network/play/client/CPacketCustomPayload.java.patch deleted file mode 100644 index 02ac041e3..000000000 --- a/patches/minecraft/net/minecraft/network/play/client/CPacketCustomPayload.java.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- before/net/minecraft/network/play/client/CPacketCustomPayload.java -+++ after/net/minecraft/network/play/client/CPacketCustomPayload.java -@@ -48,7 +48,11 @@ - public void writePacketData(PacketBuffer buf) throws IOException - { - buf.writeString(this.channel); -+ synchronized(this.data) { //This may be access multiple times, from multiple threads, lets be safe. -+ this.data.markReaderIndex(); - buf.writeBytes(this.data); -+ this.data.resetReaderIndex(); -+ } - } - - public void processPacket(INetHandlerPlayServer handler) diff --git a/patches/minecraft/net/minecraft/network/play/server/SPacketCustomPayload.java.patch b/patches/minecraft/net/minecraft/network/play/server/SPacketCustomPayload.java.patch deleted file mode 100644 index 09379dffa..000000000 --- a/patches/minecraft/net/minecraft/network/play/server/SPacketCustomPayload.java.patch +++ /dev/null @@ -1,21 +0,0 @@ ---- before/net/minecraft/network/play/server/SPacketCustomPayload.java -+++ after/net/minecraft/network/play/server/SPacketCustomPayload.java -@@ -47,12 +47,18 @@ - public void writePacketData(PacketBuffer buf) throws IOException - { - buf.writeString(this.channel); -+ synchronized(this.data) { //This may be access multiple times, from multiple threads, lets be safe. -+ this.data.markReaderIndex(); - buf.writeBytes(this.data); -+ this.data.resetReaderIndex(); -+ } - } - - public void processPacket(INetHandlerPlayClient handler) - { - handler.handleCustomPayload(this); -+ // Forge: fix network buffer leaks (MC-121884) -+ if (this.data != null) this.data.release(); - } - - @SideOnly(Side.CLIENT) diff --git a/patches/minecraft/net/minecraft/network/play/server/SPacketSpawnMob.java.patch b/patches/minecraft/net/minecraft/network/play/server/SPacketSpawnMob.java.patch deleted file mode 100644 index e9bfd1a7a..000000000 --- a/patches/minecraft/net/minecraft/network/play/server/SPacketSpawnMob.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/network/play/server/SPacketSpawnMob.java -+++ after/net/minecraft/network/play/server/SPacketSpawnMob.java -@@ -39,7 +39,7 @@ - { - this.entityId = entityIn.getEntityId(); - this.uniqueId = entityIn.getUniqueID(); -- this.type = EntityList.REGISTRY.getIDForObject((Class )entityIn.getClass()); -+ this.type = EntityList.getID(entityIn.getClass()); - this.x = entityIn.posX; - this.y = entityIn.posY; - this.z = entityIn.posZ; diff --git a/patches/minecraft/net/minecraft/pathfinding/FlyingNodeProcessor.java.patch b/patches/minecraft/net/minecraft/pathfinding/FlyingNodeProcessor.java.patch deleted file mode 100644 index 290eeca66..000000000 --- a/patches/minecraft/net/minecraft/pathfinding/FlyingNodeProcessor.java.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- before/net/minecraft/pathfinding/FlyingNodeProcessor.java -+++ after/net/minecraft/pathfinding/FlyingNodeProcessor.java -@@ -296,9 +296,11 @@ - EnumSet enumset = EnumSet.noneOf(PathNodeType.class); - PathNodeType pathnodetype = PathNodeType.BLOCKED; - BlockPos blockpos = new BlockPos(entitylivingIn); -+ this.currentEntity = entitylivingIn; - pathnodetype = this.getPathNodeType( - blockaccessIn, x, y, z, xSize, ySize, zSize, canBreakDoorsIn, canEnterDoorsIn, enumset, pathnodetype, blockpos - ); -+ this.currentEntity = null; - - if (enumset.contains(PathNodeType.FENCE)) - { -@@ -343,6 +345,7 @@ - { - pathnodetype = PathNodeType.DAMAGE_CACTUS; - } -+ else if (pathnodetype1 == PathNodeType.DAMAGE_OTHER) pathnodetype = PathNodeType.DAMAGE_OTHER; - else - { - pathnodetype = pathnodetype1 != PathNodeType.WALKABLE && pathnodetype1 != PathNodeType.OPEN && pathnodetype1 != PathNodeType.WATER diff --git a/patches/minecraft/net/minecraft/pathfinding/PathNavigateClimber.java.patch b/patches/minecraft/net/minecraft/pathfinding/PathNavigateClimber.java.patch deleted file mode 100644 index 30c6c7520..000000000 --- a/patches/minecraft/net/minecraft/pathfinding/PathNavigateClimber.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/pathfinding/PathNavigateClimber.java -+++ after/net/minecraft/pathfinding/PathNavigateClimber.java -@@ -57,7 +57,7 @@ - { - if (this.targetPosition != null) - { -- double d0 = this.entity.width * this.entity.width; -+ double d0 = Math.max((this.entity.width * this.entity.width), 1.0); - - if (!(this.entity.getDistanceSqToCenter(this.targetPosition) < d0) - && ( diff --git a/patches/minecraft/net/minecraft/pathfinding/WalkNodeProcessor.java.patch b/patches/minecraft/net/minecraft/pathfinding/WalkNodeProcessor.java.patch deleted file mode 100644 index d997cd2db..000000000 --- a/patches/minecraft/net/minecraft/pathfinding/WalkNodeProcessor.java.patch +++ /dev/null @@ -1,65 +0,0 @@ ---- before/net/minecraft/pathfinding/WalkNodeProcessor.java -+++ after/net/minecraft/pathfinding/WalkNodeProcessor.java -@@ -23,6 +23,7 @@ - public class WalkNodeProcessor extends NodeProcessor - { - protected float avoidsWater; -+ protected EntityLiving currentEntity; - - @Override - public void init(IBlockAccess sourceIn, EntityLiving mob) -@@ -343,9 +344,11 @@ - PathNodeType pathnodetype = PathNodeType.BLOCKED; - double d0 = entitylivingIn.width / 2.0; - BlockPos blockpos = new BlockPos(entitylivingIn); -+ this.currentEntity = entitylivingIn; - pathnodetype = this.getPathNodeType( - blockaccessIn, x, y, z, xSize, ySize, zSize, canBreakDoorsIn, canEnterDoorsIn, enumset, pathnodetype, blockpos - ); -+ this.currentEntity = null; - - if (enumset.contains(PathNodeType.FENCE)) - { -@@ -474,6 +477,8 @@ - { - pathnodetype = PathNodeType.DAMAGE_CACTUS; - } -+ -+ if (pathnodetype1 == PathNodeType.DAMAGE_OTHER) pathnodetype = PathNodeType.DAMAGE_OTHER; - } - - return this.checkNeighborBlocks(blockaccessIn, x, y, z, pathnodetype); -@@ -491,17 +496,19 @@ - { - if (i != 0 || j != 0) - { -- Block block = p_193578_1_.getBlockState(blockpos$pooledmutableblockpos.setPos(i + p_193578_2_, p_193578_3_, j + p_193578_4_)) -- .getBlock(); -+ IBlockState state = p_193578_1_.getBlockState(blockpos$pooledmutableblockpos.setPos(i + p_193578_2_, p_193578_3_, j + p_193578_4_)); -+ Block block = state.getBlock(); -+ PathNodeType type = block.getAiPathNodeType(state, p_193578_1_, blockpos$pooledmutableblockpos, this.currentEntity); - -- if (block == Blocks.CACTUS) -+ if (block == Blocks.CACTUS || type == PathNodeType.DAMAGE_CACTUS) - { - p_193578_5_ = PathNodeType.DANGER_CACTUS; - } -- else if (block == Blocks.FIRE) -+ else if (block == Blocks.FIRE || type == PathNodeType.DAMAGE_FIRE) - { - p_193578_5_ = PathNodeType.DANGER_FIRE; - } -+ else if (type == PathNodeType.DAMAGE_OTHER) p_193578_5_ = PathNodeType.DANGER_OTHER; - } - } - } -@@ -517,6 +524,9 @@ - IBlockState iblockstate = p_189553_1_.getBlockState(blockpos); - Block block = iblockstate.getBlock(); - Material material = iblockstate.getMaterial(); -+ -+ PathNodeType type = block.getAiPathNodeType(iblockstate, p_189553_1_, blockpos, this.currentEntity); -+ if (type != null) return type; - - if (material == Material.AIR) - { diff --git a/patches/minecraft/net/minecraft/potion/Potion.java.patch b/patches/minecraft/net/minecraft/potion/Potion.java.patch deleted file mode 100644 index 796cd2ebf..000000000 --- a/patches/minecraft/net/minecraft/potion/Potion.java.patch +++ /dev/null @@ -1,144 +0,0 @@ ---- before/net/minecraft/potion/Potion.java -+++ after/net/minecraft/potion/Potion.java -@@ -22,9 +22,9 @@ - import net.minecraftforge.fml.relauncher.Side; - import net.minecraftforge.fml.relauncher.SideOnly; - --public class Potion -+public class Potion extends net.minecraftforge.registries.IForgeRegistryEntry.Impl - { -- public static final RegistryNamespaced REGISTRY = new RegistryNamespaced<>(); -+ public static final RegistryNamespaced REGISTRY = net.minecraftforge.registries.GameData.getWrapper(Potion.class); - private final Map attributeModifierMap = Maps.newHashMap(); - private final boolean isBadEffect; - private final int liquidColor; -@@ -192,7 +192,6 @@ - return this.statusIconIndex; - } - -- @SideOnly(Side.CLIENT) - public boolean isBadEffect() - { - return this.isBadEffect; -@@ -275,6 +274,121 @@ - { - return modifier.getAmount() * (amplifier + 1); - } -+ -+ /* ======================================== FORGE START =====================================*/ -+ -+ /** -+ * If the Potion effect should be displayed in the players inventory -+ * @param effect the active PotionEffect -+ * @return true to display it (default), false to hide it. -+ */ -+ public boolean shouldRender(PotionEffect effect) { return true; } -+ -+ /** -+ * If the standard PotionEffect text (name and duration) should be drawn when this potion is active. -+ * @param effect the active PotionEffect -+ * @return true to draw the standard text -+ */ -+ public boolean shouldRenderInvText(PotionEffect effect) -+ { -+ return true; -+ } -+ -+ /** -+ * If the Potion effect should be displayed in the player's ingame HUD -+ * @param effect the active PotionEffect -+ * @return true to display it (default), false to hide it. -+ */ -+ public boolean shouldRenderHUD(PotionEffect effect) -+ { -+ return true; -+ } -+ -+ /** -+ * Called to draw the this Potion onto the player's inventory when it's active. -+ * This can be used to e.g. render Potion icons from your own texture. -+ * @param x the x coordinate -+ * @param y the y coordinate -+ * @param effect the active PotionEffect -+ * @param mc the Minecraft instance, for convenience -+ * @deprecated use {@link #renderInventoryEffect(PotionEffect, net.minecraft.client.gui.Gui, int, int, float)} -+ */ -+ @SideOnly(Side.CLIENT) -+ @Deprecated // TODO: remove -+ public void renderInventoryEffect(int x, int y, PotionEffect effect, net.minecraft.client.Minecraft mc) { } -+ -+ /** -+ * Called to draw the this Potion onto the player's inventory when it's active. -+ * This can be used to e.g. render Potion icons from your own texture. -+ * -+ * @param effect the active PotionEffect -+ * @param gui the gui instance -+ * @param x the x coordinate -+ * @param y the y coordinate -+ * @param z the z level -+ */ -+ @SideOnly(Side.CLIENT) -+ public void renderInventoryEffect(PotionEffect effect, net.minecraft.client.gui.Gui gui, int x, int y, float z) -+ { -+ renderInventoryEffect(x, y, effect, net.minecraft.client.Minecraft.getMinecraft()); -+ } -+ -+ /** -+ * Called to draw the this Potion onto the player's ingame HUD when it's active. -+ * This can be used to e.g. render Potion icons from your own texture. -+ * @param x the x coordinate -+ * @param y the y coordinate -+ * @param effect the active PotionEffect -+ * @param mc the Minecraft instance, for convenience -+ * @param alpha the alpha value, blinks when the potion is about to run out -+ * @deprecated use {@link #renderHUDEffect(PotionEffect, net.minecraft.client.gui.Gui, int, int, float, float)} -+ */ -+ @SideOnly(Side.CLIENT) -+ @Deprecated // TODO: remove -+ public void renderHUDEffect(int x, int y, PotionEffect effect, net.minecraft.client.Minecraft mc, float alpha) { } -+ -+ /** -+ * Called to draw the this Potion onto the player's ingame HUD when it's active. -+ * This can be used to e.g. render Potion icons from your own texture. -+ * -+ * @param effect the active PotionEffect -+ * @param gui the gui instance -+ * @param x the x coordinate -+ * @param y the y coordinate -+ * @param z the z level -+ * @param alpha the alpha value, blinks when the potion is about to run out -+ */ -+ @SideOnly(Side.CLIENT) -+ public void renderHUDEffect(PotionEffect effect, net.minecraft.client.gui.Gui gui, int x, int y, float z, float alpha) -+ { -+ renderHUDEffect(x, y, effect, net.minecraft.client.Minecraft.getMinecraft(), alpha); -+ } -+ -+ /** -+ * Get a fresh list of items that can cure this Potion. -+ * All new PotionEffects created from this Potion will call this to initialize the default curative items -+ * @see PotionEffect#getCurativeItems -+ * @return A list of items that can cure this Potion -+ */ -+ public java.util.List getCurativeItems() -+ { -+ java.util.ArrayList ret = new java.util.ArrayList(); -+ ret.add(new net.minecraft.item.ItemStack(net.minecraft.init.Items.MILK_BUCKET)); -+ return ret; -+ } -+ -+ /** -+ * Used for determining {@code PotionEffect} sort order in GUIs. -+ * Defaults to the {@code PotionEffect}'s liquid color. -+ * @param potionEffect the {@code PotionEffect} instance containing the potion -+ * @return a value used to sort {@code PotionEffect}s in GUIs -+ */ -+ public int getGuiSortColor(PotionEffect potionEffect) -+ { -+ return this.getLiquidColor(); -+ } -+ -+ /* ======================================== FORGE END =====================================*/ - - @SideOnly(Side.CLIENT) - public boolean isBeneficial() diff --git a/patches/minecraft/net/minecraft/potion/PotionEffect.java.patch b/patches/minecraft/net/minecraft/potion/PotionEffect.java.patch deleted file mode 100644 index 2800e94b2..000000000 --- a/patches/minecraft/net/minecraft/potion/PotionEffect.java.patch +++ /dev/null @@ -1,150 +0,0 @@ ---- before/net/minecraft/potion/PotionEffect.java -+++ after/net/minecraft/potion/PotionEffect.java -@@ -19,6 +19,8 @@ - @SideOnly(Side.CLIENT) - private boolean isPotionDurationMax; - private boolean showParticles; -+ /** List of ItemStack that can cure the potion effect **/ -+ private java.util.List curativeItems; - - public PotionEffect(Potion potionIn) - { -@@ -51,6 +53,7 @@ - this.amplifier = other.amplifier; - this.isAmbient = other.isAmbient; - this.showParticles = other.showParticles; -+ this.curativeItems = other.curativeItems == null ? null : new java.util.ArrayList(other.curativeItems); - } - - public void combine(PotionEffect other) -@@ -79,6 +82,11 @@ - - public Potion getPotion() - { -+ return this.getPotionRaw() == null ? null : this.getPotionRaw().delegate.get(); -+ } -+ -+ private Potion getPotionRaw() -+ { - return this.potion; - } - -@@ -201,12 +209,13 @@ - nbt.setInteger("Duration", this.getDuration()); - nbt.setBoolean("Ambient", this.getIsAmbient()); - nbt.setBoolean("ShowParticles", this.doesShowParticles()); -+ writeCurativeItems(nbt); - return nbt; - } - - public static PotionEffect readCustomPotionEffectFromNBT(NBTTagCompound nbt) - { -- int i = nbt.getByte("Id"); -+ int i = nbt.getByte("Id") & 0xFF; - Potion potion = Potion.getPotionById(i); - - if (potion == null) -@@ -225,7 +234,7 @@ - flag1 = nbt.getBoolean("ShowParticles"); - } - -- return new PotionEffect(potion, k, j < 0 ? 0 : j, flag, flag1); -+ return readCurativeItems(new PotionEffect(potion, k, j < 0 ? 0 : j, flag, flag1), nbt); - } - } - -@@ -248,11 +257,92 @@ - ? ComparisonChain.start() - .compare(this.getIsAmbient(), p_compareTo_1_.getIsAmbient()) - .compare(this.getDuration(), p_compareTo_1_.getDuration()) -- .compare(this.getPotion().getLiquidColor(), p_compareTo_1_.getPotion().getLiquidColor()) -+ .compare(this.getPotion().getGuiSortColor(this), p_compareTo_1_.getPotion().getGuiSortColor(p_compareTo_1_)) - .result() - : ComparisonChain.start() - .compare(this.getIsAmbient(), p_compareTo_1_.getIsAmbient()) -- .compare(this.getPotion().getLiquidColor(), p_compareTo_1_.getPotion().getLiquidColor()) -+ .compare(this.getPotion().getGuiSortColor(this), p_compareTo_1_.getPotion().getGuiSortColor(p_compareTo_1_)) - .result(); -+ } -+ -+ /* ======================================== FORGE START =====================================*/ -+ /*** -+ * Returns a list of curative items for the potion effect -+ * By default, this list is initialized using {@link Potion#getCurativeItems} -+ * -+ * @return The list (ItemStack) of curative items for the potion effect -+ */ -+ public java.util.List getCurativeItems() -+ { -+ if (this.curativeItems == null) //Lazy load this so that we don't create a circular dep on Items. -+ { -+ this.curativeItems = getPotion().getCurativeItems(); -+ } -+ return this.curativeItems; -+ } -+ -+ /*** -+ * Checks the given ItemStack to see if it is in the list of curative items for the potion effect -+ * @param stack The ItemStack being checked against the list of curative items for this PotionEffect -+ * @return true if the given ItemStack is in the list of curative items for this PotionEffect, false otherwise -+ */ -+ public boolean isCurativeItem(net.minecraft.item.ItemStack stack) -+ { -+ for (net.minecraft.item.ItemStack curativeItem : this.getCurativeItems()) -+ { -+ if (curativeItem.isItemEqual(stack)) -+ { -+ return true; -+ } -+ } -+ -+ return false; -+ } -+ -+ /*** -+ * Sets the list of curative items for this potion effect, overwriting any already present -+ * @param curativeItems The list of ItemStacks being set to the potion effect -+ */ -+ public void setCurativeItems(java.util.List curativeItems) -+ { -+ this.curativeItems = curativeItems; -+ } -+ -+ /*** -+ * Adds the given stack to the list of curative items for this PotionEffect -+ * @param stack The ItemStack being added to the curative item list -+ */ -+ public void addCurativeItem(net.minecraft.item.ItemStack stack) -+ { -+ if (!this.isCurativeItem(stack)) -+ { -+ this.getCurativeItems().add(stack); -+ } -+ } -+ -+ private void writeCurativeItems(NBTTagCompound nbt) -+ { -+ net.minecraft.nbt.NBTTagList list = new net.minecraft.nbt.NBTTagList(); -+ for (net.minecraft.item.ItemStack stack : getCurativeItems()) -+ { -+ list.appendTag(stack.writeToNBT(new NBTTagCompound())); -+ } -+ nbt.setTag("CurativeItems", list); -+ } -+ -+ private static PotionEffect readCurativeItems(PotionEffect effect, NBTTagCompound nbt) -+ { -+ if (nbt.hasKey("CurativeItems", net.minecraftforge.common.util.Constants.NBT.TAG_LIST)) -+ { -+ java.util.List items = new java.util.ArrayList(); -+ net.minecraft.nbt.NBTTagList list = nbt.getTagList("CurativeItems", net.minecraftforge.common.util.Constants.NBT.TAG_COMPOUND); -+ for (int i = 0; i < list.tagCount(); i++) -+ { -+ items.add(new net.minecraft.item.ItemStack(list.getCompoundTagAt(i))); -+ } -+ effect.setCurativeItems(items); -+ } -+ -+ return effect; - } - } diff --git a/patches/minecraft/net/minecraft/potion/PotionHelper.java.patch b/patches/minecraft/net/minecraft/potion/PotionHelper.java.patch deleted file mode 100644 index 4765db790..000000000 --- a/patches/minecraft/net/minecraft/potion/PotionHelper.java.patch +++ /dev/null @@ -1,67 +0,0 @@ ---- before/net/minecraft/potion/PotionHelper.java -+++ after/net/minecraft/potion/PotionHelper.java -@@ -81,7 +81,7 @@ - { - PotionHelper.MixPredicate mixpredicate = POTION_ITEM_CONVERSIONS.get(i); - -- if (mixpredicate.input == item && mixpredicate.reagent.apply(reagent)) -+ if (mixpredicate.input.get() == item && mixpredicate.reagent.apply(reagent)) - { - return true; - } -@@ -99,7 +99,7 @@ - { - PotionHelper.MixPredicate mixpredicate = POTION_TYPE_CONVERSIONS.get(i); - -- if (mixpredicate.input == potiontype && mixpredicate.reagent.apply(reagent)) -+ if (mixpredicate.input.get() == potiontype && mixpredicate.reagent.apply(reagent)) - { - return true; - } -@@ -120,9 +120,9 @@ - { - PotionHelper.MixPredicate mixpredicate = POTION_ITEM_CONVERSIONS.get(i); - -- if (mixpredicate.input == item && mixpredicate.reagent.apply(reagent)) -+ if (mixpredicate.input.get() == item && mixpredicate.reagent.apply(reagent)) - { -- return PotionUtils.addPotionToItemStack(new ItemStack(mixpredicate.output), potiontype); -+ return PotionUtils.addPotionToItemStack(new ItemStack(mixpredicate.output.get()), potiontype); - } - } - -@@ -132,9 +132,9 @@ - { - PotionHelper.MixPredicate mixpredicate1 = POTION_TYPE_CONVERSIONS.get(i); - -- if (mixpredicate1.input == potiontype && mixpredicate1.reagent.apply(reagent)) -+ if (mixpredicate1.input.get() == potiontype && mixpredicate1.reagent.apply(reagent)) - { -- return PotionUtils.addPotionToItemStack(new ItemStack(item), mixpredicate1.output); -+ return PotionUtils.addPotionToItemStack(new ItemStack(item), mixpredicate1.output.get()); - } - } - } -@@ -224,17 +224,17 @@ - POTION_TYPE_CONVERSIONS.add(new PotionHelper.MixPredicate<>(p_193356_0_, p_193356_1_, p_193356_2_)); - } - -- static class MixPredicate -+ static class MixPredicate> - { -- final T input; -+ final net.minecraftforge.registries.IRegistryDelegate input; - final Ingredient reagent; -- final T output; -+ final net.minecraftforge.registries.IRegistryDelegate output; - - public MixPredicate(T p_i47570_1_, Ingredient p_i47570_2_, T p_i47570_3_) - { -- this.input = p_i47570_1_; -+ this.input = p_i47570_1_.delegate; - this.reagent = p_i47570_2_; -- this.output = p_i47570_3_; -+ this.output = p_i47570_3_.delegate; - } - } - } diff --git a/patches/minecraft/net/minecraft/potion/PotionType.java.patch b/patches/minecraft/net/minecraft/potion/PotionType.java.patch deleted file mode 100644 index d4e852f5a..000000000 --- a/patches/minecraft/net/minecraft/potion/PotionType.java.patch +++ /dev/null @@ -1,16 +0,0 @@ ---- before/net/minecraft/potion/PotionType.java -+++ after/net/minecraft/potion/PotionType.java -@@ -7,10 +7,11 @@ - import net.minecraft.util.ResourceLocation; - import net.minecraft.util.registry.RegistryNamespacedDefaultedByKey; - --public class PotionType -+public class PotionType extends net.minecraftforge.registries.IForgeRegistryEntry.Impl - { -+ @Deprecated // unused - private static final ResourceLocation EMPTY = new ResourceLocation("empty"); -- public static final RegistryNamespacedDefaultedByKey REGISTRY = new RegistryNamespacedDefaultedByKey<>(EMPTY); -+ public static final RegistryNamespacedDefaultedByKey REGISTRY = net.minecraftforge.registries.GameData.getWrapperDefaulted(PotionType.class); - private static int nextPotionTypeId; - private final String baseName; - private final ImmutableList effects; diff --git a/patches/minecraft/net/minecraft/profiler/Profiler.java.patch b/patches/minecraft/net/minecraft/profiler/Profiler.java.patch deleted file mode 100644 index f0909951d..000000000 --- a/patches/minecraft/net/minecraft/profiler/Profiler.java.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- before/net/minecraft/profiler/Profiler.java -+++ after/net/minecraft/profiler/Profiler.java -@@ -194,4 +194,16 @@ - return (this.profilerName.hashCode() & 11184810) + 4473924; - } - } -+ -+ /** -+ * Forge: Fix for MC-117087, World.updateEntities is wasting time calling Class.getSimpleName() when the profiler is not active -+ */ -+ @Deprecated // TODO: remove (1.13) -+ public void startSection(Class profiledClass) -+ { -+ if (this.profilingEnabled) -+ { -+ startSection(profiledClass.getSimpleName()); -+ } -+ } - } diff --git a/patches/minecraft/net/minecraft/realms/RealmsConnect.java.patch b/patches/minecraft/net/minecraft/realms/RealmsConnect.java.patch deleted file mode 100644 index 6569e65f7..000000000 --- a/patches/minecraft/net/minecraft/realms/RealmsConnect.java.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- before/net/minecraft/realms/RealmsConnect.java -+++ after/net/minecraft/realms/RealmsConnect.java -@@ -39,6 +39,7 @@ - - try - { -+ net.minecraftforge.fml.client.FMLClientHandler.instance().connectToRealmsServer(p_connect_1_, p_connect_2_); - inetaddress = InetAddress.getByName(p_connect_1_); - - if (RealmsConnect.this.aborted) -@@ -65,7 +66,7 @@ - return; - } - -- RealmsConnect.this.connection.sendPacket(new C00Handshake(p_connect_1_, p_connect_2_, EnumConnectionState.LOGIN)); -+ RealmsConnect.this.connection.sendPacket(new C00Handshake(p_connect_1_, p_connect_2_, EnumConnectionState.LOGIN, true)); - - if (RealmsConnect.this.aborted) - { diff --git a/patches/minecraft/net/minecraft/server/MinecraftServer.java.patch b/patches/minecraft/net/minecraft/server/MinecraftServer.java.patch deleted file mode 100644 index 6144dde67..000000000 --- a/patches/minecraft/net/minecraft/server/MinecraftServer.java.patch +++ /dev/null @@ -1,342 +0,0 @@ ---- before/net/minecraft/server/MinecraftServer.java -+++ after/net/minecraft/server/MinecraftServer.java -@@ -103,7 +103,7 @@ - @SideOnly(Side.SERVER) - private String hostname; - private int serverPort = -1; -- public WorldServer[] worlds; -+ public WorldServer[] worlds = new WorldServer[0]; - private PlayerList playerList; - private boolean serverRunning = true; - private boolean serverStopped; -@@ -121,7 +121,8 @@ - private int buildLimit; - private int maxPlayerIdleMinutes; - public final long[] tickTimeArray = new long[100]; -- public long[][] timeOfLastDimensionTick; -+ //public long[][] timeOfLastDimensionTick; -+ public java.util.Hashtable worldTickTimes = new java.util.Hashtable<>(); - private KeyPair serverKeyPair; - private String serverOwner; - private String folderName; -@@ -184,7 +185,7 @@ - this.setUserMessage("menu.convertingLevel"); - this.getActiveAnvilConverter().convertMapFormat(worldNameIn, new IProgressUpdate() - { -- private long startTime = MinecraftServer.getCurrentTimeMillis(); -+ private long startTime = System.currentTimeMillis(); - @Override - public void displaySavingString(String message) - { -@@ -197,9 +198,9 @@ - @Override - public void setLoadingProgress(int progress) - { -- if (MinecraftServer.getCurrentTimeMillis() - this.startTime >= 1000L) -+ if (System.currentTimeMillis() - this.startTime >= 1000L) - { -- this.startTime = MinecraftServer.getCurrentTimeMillis(); -+ this.startTime = System.currentTimeMillis(); - MinecraftServer.LOGGER.info("Converting... {}%", progress); - } - } -@@ -233,8 +234,6 @@ - { - this.convertMapIfNeeded(saveName); - this.setUserMessage("menu.loadingLevel"); -- this.worlds = new WorldServer[3]; -- this.timeOfLastDimensionTick = new long[this.worlds.length][100]; - ISaveHandler isavehandler = this.anvilConverterForAnvilFile.getSaveLoader(saveName, true); - this.setResourcePackFromWorld(this.getFolderName(), isavehandler); - WorldInfo worldinfo = isavehandler.loadWorldInfo(); -@@ -265,6 +264,7 @@ - worldsettings = new WorldSettings(worldinfo); - } - -+ if (false) { //Forge Dead code, reimplemented below - for (int i = 0; i < this.worlds.length; i++) - { - int j = 0; -@@ -304,8 +304,23 @@ - this.worlds[i].getWorldInfo().setGameType(this.getGameType()); - } - } -- -- this.playerList.setPlayerManager(this.worlds); -+ } //Forge: End dead code -+ -+ WorldServer overWorld = (WorldServer)(isDemo() ? new WorldServerDemo(this, isavehandler, worldinfo, 0, profiler).init() : new WorldServer(this, isavehandler, worldinfo, 0, profiler).init()); -+ overWorld.initialize(worldsettings); -+ for (int dim : net.minecraftforge.common.DimensionManager.getStaticDimensionIDs()) -+ { -+ WorldServer world = (dim == 0 ? overWorld : (WorldServer)new WorldServerMulti(this, isavehandler, dim, overWorld, profiler).init()); -+ world.addEventListener(new ServerWorldEventHandler(this, world)); -+ -+ if (!this.isSinglePlayer()) -+ { -+ world.getWorldInfo().setGameType(this.getGameType()); -+ } -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.WorldEvent.Load(world)); -+ } -+ -+ this.playerList.setPlayerManager(new WorldServer[]{ overWorld }); - this.setDifficultyForAllWorlds(this.getDifficulty()); - this.initialWorldChunkLoad(); - } -@@ -320,7 +335,7 @@ - this.setUserMessage("menu.generatingTerrain"); - int j1 = 0; - LOGGER.info("Preparing start region for level 0"); -- WorldServer worldserver = this.worlds[0]; -+ WorldServer worldserver = net.minecraftforge.common.DimensionManager.getWorld(j1); - BlockPos blockpos = worldserver.getSpawnPoint(); - long k1 = getCurrentTimeMillis(); - -@@ -447,15 +462,24 @@ - { - if (worldserver1 != null) - { -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.WorldEvent.Unload(worldserver1)); - worldserver1.flush(); - } - } -+ -+ WorldServer[] tmp = worlds; -+ for (WorldServer world : tmp) -+ { -+ net.minecraftforge.common.DimensionManager.setWorld(world.provider.getDimension(), null, this); -+ } - } - - if (this.usageSnooper.isSnooperRunning()) - { - this.usageSnooper.stopSnooper(); - } -+ -+ CommandBase.setCommandListener(null); // Forge: fix MC-128561 - } - - @SideOnly(Side.SERVER) -@@ -487,6 +511,7 @@ - { - if (this.init()) - { -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().handleServerStarted(); - this.currentTime = getCurrentTimeMillis(); - long i = 0L; - this.statusResponse.setServerDescription(new TextComponentString(this.motd)); -@@ -533,12 +558,20 @@ - Thread.sleep(Math.max(1L, 50L - i)); - this.serverIsRunning = true; - } -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().handleServerStopping(); -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().expectServerStopped(); // has to come before finalTick to avoid race conditions - } - else - { -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().expectServerStopped(); // has to come before finalTick to avoid race conditions - this.finalTick(null); - } - } -+ catch (net.minecraftforge.fml.common.StartupQuery.AbortedException e) -+ { -+ // ignore silently -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().expectServerStopped(); // has to come before finalTick to avoid race conditions -+ } - catch (Throwable throwable1) - { - LOGGER.error("Encountered an unexpected exception", throwable1); -@@ -566,13 +599,13 @@ - LOGGER.error("We were unable to save this crash report to disk."); - } - -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().expectServerStopped(); // has to come before finalTick to avoid race conditions - this.finalTick(crashreport); - } - finally - { - try - { -- this.serverStopped = true; - this.stopServer(); - } - catch (Throwable throwable) -@@ -581,6 +614,8 @@ - } - finally - { -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().handleServerStopped(); -+ this.serverStopped = true; - this.systemExitNow(); - } - } -@@ -607,6 +642,7 @@ - ImageIO.write(bufferedimage, "PNG", new ByteBufOutputStream(bytebuf)); - ByteBuf bytebuf1 = Base64.encode(bytebuf); - response.setFavicon("data:image/png;base64," + bytebuf1.toString(StandardCharsets.UTF_8)); -+ bytebuf1.release(); // Forge: fix MC-122085 - } - catch (Exception exception) - { -@@ -648,6 +684,7 @@ - public void tick() - { - long i = System.nanoTime(); -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().onPreServerTick(); - this.tickCounter++; - - if (this.startProfiling) -@@ -674,6 +711,7 @@ - - Collections.shuffle(Arrays.asList(agameprofile)); - this.statusResponse.getPlayers().setPlayers(agameprofile); -+ this.statusResponse.invalidateJson(); - } - - if (this.tickCounter % 900 == 0) -@@ -701,6 +739,7 @@ - - this.profiler.endSection(); - this.profiler.endSection(); -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().onPostServerTick(); - } - - public void updateTimeLightAndEntities() -@@ -716,28 +755,31 @@ - } - - this.profiler.endStartSection("levels"); -+ net.minecraftforge.common.chunkio.ChunkIOExecutor.tick(); - -- for (int j = 0; j < this.worlds.length; j++) -+ Integer[] ids = net.minecraftforge.common.DimensionManager.getIDs(this.tickCounter % 200 == 0); -+ for (int x = 0; x < ids.length; x++) - { -+ int id = ids[x]; - long i = System.nanoTime(); - -- if (j == 0 || this.getAllowNether()) -+ if (id == 0 || this.getAllowNether()) - { -- WorldServer worldserver = this.worlds[j]; -+ WorldServer worldserver = net.minecraftforge.common.DimensionManager.getWorld(id); - this.profiler.func_194340_a(() -> worldserver.getWorldInfo().getWorldName()); - - if (this.tickCounter % 20 == 0) - { - this.profiler.startSection("timeSync"); -- this.playerList -- .sendPacketToAllPlayersInDimension( -- new SPacketTimeUpdate(worldserver.getTotalWorldTime(), worldserver.getWorldTime(), worldserver.getGameRules().getBoolean("doDaylightCycle")), -- worldserver.provider.getDimensionType().getId() -+ this.playerList.sendPacketToAllPlayersInDimension( -+ new SPacketTimeUpdate(worldserver.getTotalWorldTime(), worldserver.getWorldTime(), -+ worldserver.getGameRules().getBoolean("doDaylightCycle")), worldserver.provider.getDimension() - ); - this.profiler.endSection(); - } - - this.profiler.startSection("tick"); -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().onPreWorldTick(worldserver); - - try - { -@@ -761,6 +803,7 @@ - throw new ReportedException(crashreport1); - } - -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().onPostWorldTick(worldserver); - this.profiler.endSection(); - this.profiler.startSection("tracker"); - worldserver.getEntityTracker().tick(); -@@ -768,9 +811,11 @@ - this.profiler.endSection(); - } - -- this.timeOfLastDimensionTick[j][this.tickCounter % 100] = System.nanoTime() - i; -+ worldTickTimes.get(id)[this.tickCounter % 100] = System.nanoTime() - i; - } - -+ this.profiler.endStartSection("dim_unloading"); -+ net.minecraftforge.common.DimensionManager.unloadWorlds(worldTickTimes); - this.profiler.endStartSection("connection"); - this.getNetworkSystem().networkTick(); - this.profiler.endStartSection("players"); -@@ -801,6 +846,16 @@ - @SideOnly(Side.SERVER) - public static void main(String[] p_main_0_) - { -+ //Forge: Copied from DedicatedServer.init as to run as early as possible, Old code left in place intentionally. -+ //Done in good faith with permission: https://github.com/MinecraftForge/MinecraftForge/issues/3659#issuecomment-390467028 -+ ServerEula eula = new ServerEula(new File("eula.txt")); -+ if (!eula.hasAcceptedEULA()) -+ { -+ LOGGER.info("You need to agree to the EULA in order to run the server. Go to eula.txt for more info."); -+ eula.createEULAFile(); -+ return; -+ } -+ - Bootstrap.register(); - - try -@@ -921,7 +976,8 @@ - - public void startServerThread() - { -- this.serverThread = new Thread(this, "Server thread"); -+ net.minecraftforge.fml.common.StartupQuery.reset(); -+ this.serverThread = new Thread(net.minecraftforge.fml.common.thread.SidedThreadGroups.SERVER, this, "Server thread"); - this.serverThread.start(); - } - -@@ -943,14 +999,13 @@ - - public WorldServer getWorld(int dimension) - { -- if (dimension == -1) -- { -- return this.worlds[1]; -- } -- else -- { -- return dimension == 1 ? this.worlds[2] : this.worlds[0]; -- } -+ WorldServer ret = net.minecraftforge.common.DimensionManager.getWorld(dimension, true); -+ if (ret == null) -+ { -+ net.minecraftforge.common.DimensionManager.initDimension(dimension); -+ ret = net.minecraftforge.common.DimensionManager.getWorld(dimension); -+ } -+ return ret; - } - - public String getMinecraftVersion() -@@ -1001,7 +1056,7 @@ - - public String getServerModName() - { -- return "vanilla"; -+ return net.minecraftforge.fml.common.FMLCommonHandler.instance().getModName(); - } - - public CrashReport addServerInfoToCrashReport(CrashReport report) -@@ -1570,7 +1625,7 @@ - } - catch (Exception exception) - { -- return Futures.immediateFailedCheckedFuture(exception); -+ return Futures.immediateFailedFuture(exception); - } - } - } -@@ -1634,5 +1689,10 @@ - { - this.addScheduledTask(this::reload); - } -+ } -+ -+ public DataFixer getDataFixer() -+ { -+ return this.dataFixer; - } - } diff --git a/patches/minecraft/net/minecraft/server/dedicated/DedicatedServer.java.patch b/patches/minecraft/net/minecraft/server/dedicated/DedicatedServer.java.patch deleted file mode 100644 index 5b110c3ae..000000000 --- a/patches/minecraft/net/minecraft/server/dedicated/DedicatedServer.java.patch +++ /dev/null @@ -1,92 +0,0 @@ ---- before/net/minecraft/server/dedicated/DedicatedServer.java -+++ after/net/minecraft/server/dedicated/DedicatedServer.java -@@ -62,6 +62,7 @@ - private boolean canSpawnStructures; - private GameType gameType; - private boolean guiIsEnabled; -+ public static boolean allowPlayerLogins = false; - - public DedicatedServer( - File anvilFileIn, -@@ -73,10 +74,12 @@ - ) - { - super(anvilFileIn, Proxy.NO_PROXY, dataFixerIn, authServiceIn, sessionServiceIn, profileRepoIn, profileCacheIn); -- new Thread("Server Infinisleeper") -+ if (!org.apache.commons.lang3.SystemUtils.IS_OS_WINDOWS) return; -+ Thread thread = new Thread("Server Infinisleeper") - { - { - this.setDaemon(true); -+ this.setPriority(Thread.MIN_PRIORITY); - this.start(); - } - @Override -@@ -104,6 +107,7 @@ - @Override - public void run() - { -+ if (net.minecraftforge.server.console.TerminalHandler.handleCommands(DedicatedServer.this)) return; - BufferedReader bufferedreader = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8)); - String s4; - -@@ -129,6 +133,8 @@ - LOGGER.warn("To start the server with more ram, launch it as \"java -Xmx1024M -Xms1024M -jar minecraft_server.jar\""); - } - -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().onServerStart(this); -+ - LOGGER.info("Loading properties"); - this.settings = new PropertyManager(new File("server.properties")); - this.eula = new ServerEula(new File("eula.txt")); -@@ -223,6 +229,7 @@ - } - else - { -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().onServerStarted(); - this.setPlayerList(new DedicatedPlayerList(this)); - long j = System.nanoTime(); - -@@ -271,11 +278,13 @@ - TileEntitySkull.setProfileCache(this.getPlayerProfileCache()); - TileEntitySkull.setSessionService(this.getMinecraftSessionService()); - PlayerProfileCache.setOnlineMode(this.isServerInOnlineMode()); -+ if (!net.minecraftforge.fml.common.FMLCommonHandler.instance().handleServerAboutToStart(this)) return false; - LOGGER.info("Preparing level \"{}\"", this.getFolderName()); - this.loadAllWorlds(this.getFolderName(), this.getFolderName(), k, worldtype, s2); - long i1 = System.nanoTime() - j; - String s3 = String.format("%.3fs", i1 / 1.0E9); - LOGGER.info("Done ({})! For help, type \"help\" or \"?\"", s3); -+ this.currentTime = getCurrentTimeMillis(); - - if (this.settings.hasProperty("announce-player-achievements")) - { -@@ -309,7 +318,8 @@ - } - - Items.AIR.getSubItems(CreativeTabs.SEARCH, NonNullList.create()); -- return true; -+ // <3 you Grum for this, saves us ~30 patch files! --^ -+ return net.minecraftforge.fml.common.FMLCommonHandler.instance().handleServerStarting(this); - } - } - } -@@ -557,7 +567,7 @@ - @Override - public boolean isBlockProtected(World worldIn, BlockPos pos, EntityPlayer playerIn) - { -- if (worldIn.provider.getDimensionType().getId() != 0) -+ if (worldIn.provider.getDimension() != 0) - { - return false; - } -@@ -631,6 +641,9 @@ - { - return this.settings.getIntProperty("network-compression-threshold", super.getNetworkCompressionThreshold()); - } -+ -+ //Forge: Enable formated text for colors in console. -+ @Override public void sendMessage(net.minecraft.util.text.ITextComponent message) { LOGGER.info(message.getFormattedText()); } - - protected boolean convertFiles() throws IOException - { diff --git a/patches/minecraft/net/minecraft/server/dedicated/ServerHangWatchdog.java.patch b/patches/minecraft/net/minecraft/server/dedicated/ServerHangWatchdog.java.patch deleted file mode 100644 index e501247f5..000000000 --- a/patches/minecraft/net/minecraft/server/dedicated/ServerHangWatchdog.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/server/dedicated/ServerHangWatchdog.java -+++ after/net/minecraft/server/dedicated/ServerHangWatchdog.java -@@ -47,7 +47,7 @@ - ThreadMXBean threadmxbean = ManagementFactory.getThreadMXBean(); - ThreadInfo[] athreadinfo = threadmxbean.dumpAllThreads(true, true); - StringBuilder stringbuilder = new StringBuilder(); -- Error error = new Error(); -+ Error error = new Error(String.format("ServerHangWatchdog detected that a single server tick took %.2f seconds (should be max 0.05)", k / 1000F)); // Forge: don't just make a crash report with a seemingly-inexplicable Error - - for (ThreadInfo threadinfo : athreadinfo) - { diff --git a/patches/minecraft/net/minecraft/server/gui/MinecraftServerGui.java.patch b/patches/minecraft/net/minecraft/server/gui/MinecraftServerGui.java.patch deleted file mode 100644 index b3c53bacc..000000000 --- a/patches/minecraft/net/minecraft/server/gui/MinecraftServerGui.java.patch +++ /dev/null @@ -1,24 +0,0 @@ ---- before/net/minecraft/server/gui/MinecraftServerGui.java -+++ after/net/minecraft/server/gui/MinecraftServerGui.java -@@ -75,6 +75,7 @@ - System.exit(0); - } - }); -+ minecraftservergui.latch.countDown(); - } - - public MinecraftServerGui(DedicatedServer serverIn) -@@ -162,8 +163,13 @@ - return jpanel; - } - -+ private java.util.concurrent.CountDownLatch latch = new java.util.concurrent.CountDownLatch(1); - public void appendLine(final JTextArea textArea, final JScrollPane scrollPane, final String line) - { -+ try -+ { -+ latch.await(); -+ } catch (InterruptedException e){} //Prevent logging until after constructor has ended. - if (!SwingUtilities.isEventDispatchThread()) - { - SwingUtilities.invokeLater(new Runnable() diff --git a/patches/minecraft/net/minecraft/server/integrated/IntegratedServer.java.patch b/patches/minecraft/net/minecraft/server/integrated/IntegratedServer.java.patch deleted file mode 100644 index 3418550d2..000000000 --- a/patches/minecraft/net/minecraft/server/integrated/IntegratedServer.java.patch +++ /dev/null @@ -1,79 +0,0 @@ ---- before/net/minecraft/server/integrated/IntegratedServer.java -+++ after/net/minecraft/server/integrated/IntegratedServer.java -@@ -86,8 +86,6 @@ - public void loadAllWorlds(String saveName, String worldNameIn, long seed, WorldType type, String generatorOptions) - { - this.convertMapIfNeeded(saveName); -- this.worlds = new WorldServer[3]; -- this.timeOfLastDimensionTick = new long[this.worlds.length][100]; - ISaveHandler isavehandler = this.getActiveAnvilConverter().getSaveLoader(saveName, true); - this.setResourcePackFromWorld(this.getFolderName(), isavehandler); - WorldInfo worldinfo = isavehandler.loadWorldInfo(); -@@ -101,6 +99,7 @@ - worldinfo.setWorldName(worldNameIn); - } - -+ if (false) { //Forge: Dead Code, implement below. - for (int i = 0; i < this.worlds.length; i++) - { - int j = 0; -@@ -135,10 +134,25 @@ - - this.worlds[i].addEventListener(new ServerWorldEventHandler(this, this.worlds[i])); - } -- -- this.getPlayerList().setPlayerManager(this.worlds); -- -- if (this.worlds[0].getWorldInfo().getDifficulty() == null) -+ }// Forge: End Dead Code -+ -+ WorldServer overWorld = (isDemo() ? (WorldServer)(new WorldServerDemo(this, isavehandler, worldinfo, 0, this.profiler)).init() : -+ (WorldServer)(new WorldServer(this, isavehandler, worldinfo, 0, this.profiler)).init()); -+ overWorld.initialize(this.worldSettings); -+ for (int dim : net.minecraftforge.common.DimensionManager.getStaticDimensionIDs()) -+ { -+ WorldServer world = (dim == 0 ? overWorld : (WorldServer)(new WorldServerMulti(this, isavehandler, dim, overWorld, this.profiler)).init()); -+ world.addEventListener(new ServerWorldEventHandler(this, world)); -+ if (!this.isSinglePlayer()) -+ { -+ world.getWorldInfo().setGameType(getGameType()); -+ } -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.WorldEvent.Load(world)); -+ } -+ -+ this.getPlayerList().setPlayerManager(new WorldServer[]{ overWorld }); -+ -+ if (overWorld.getWorldInfo().getDifficulty() == null) - { - this.setDifficultyForAllWorlds(this.mc.gameSettings.difficulty); - } -@@ -157,11 +171,12 @@ - this.setAllowFlight(true); - LOGGER.info("Generating keypair"); - this.setKeyPair(CryptManager.generateKeyPair()); -+ if (!net.minecraftforge.fml.common.FMLCommonHandler.instance().handleServerAboutToStart(this)) return false; - this.loadAllWorlds( - this.getFolderName(), this.getWorldName(), this.worldSettings.getSeed(), this.worldSettings.getTerrainType(), this.worldSettings.getGeneratorOptions() - ); - this.setMOTD(this.getServerOwner() + " - " + this.worlds[0].getWorldInfo().getWorldName()); -- return true; -+ return net.minecraftforge.fml.common.FMLCommonHandler.instance().handleServerStarting(this); - } - - @Override -@@ -238,6 +253,7 @@ - @Override - public EnumDifficulty getDifficulty() - { -+ if (this.mc.world == null) return this.mc.gameSettings.difficulty; // Fix NPE just in case. - return this.mc.world.getWorldInfo().getDifficulty(); - } - -@@ -409,6 +425,7 @@ - @Override - public void initiateShutdown() - { -+ if (isServerRunning()) - Futures.getUnchecked(this.addScheduledTask(new Runnable() - { - @Override diff --git a/patches/minecraft/net/minecraft/server/management/PlayerChunkMapEntry.java.patch b/patches/minecraft/net/minecraft/server/management/PlayerChunkMapEntry.java.patch deleted file mode 100644 index bcaa76610..000000000 --- a/patches/minecraft/net/minecraft/server/management/PlayerChunkMapEntry.java.patch +++ /dev/null @@ -1,162 +0,0 @@ ---- before/net/minecraft/server/management/PlayerChunkMapEntry.java -+++ after/net/minecraft/server/management/PlayerChunkMapEntry.java -@@ -32,12 +32,21 @@ - private int changedSectionFilter; - private long lastUpdateInhabitedTime; - private boolean sentToPlayers; -+ private Runnable loadedRunnable = new Runnable() -+ { -+ public void run() -+ { -+ PlayerChunkMapEntry.this.chunk = PlayerChunkMapEntry.this.playerChunkMap.getWorldServer().getChunkProvider().loadChunk(PlayerChunkMapEntry.this.pos.x, PlayerChunkMapEntry.this.pos.z); -+ PlayerChunkMapEntry.this.loading = false; -+ } -+ }; -+ private boolean loading = true; - - public PlayerChunkMapEntry(PlayerChunkMap mapIn, int chunkX, int chunkZ) - { - this.playerChunkMap = mapIn; - this.pos = new ChunkPos(chunkX, chunkZ); -- this.chunk = mapIn.getWorldServer().getChunkProvider().loadChunk(chunkX, chunkZ); -+ mapIn.getWorldServer().getChunkProvider().loadChunk(chunkX, chunkZ, this.loadedRunnable); - } - - public ChunkPos getPos() -@@ -65,6 +74,8 @@ - if (this.sentToPlayers) - { - this.sendToPlayer(player); -+ // chunk watch event - the chunk is ready -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.ChunkWatchEvent.Watch(this.chunk, player)); - } - } - } -@@ -73,6 +84,20 @@ - { - if (this.players.contains(player)) - { -+ // If we haven't loaded yet don't load the chunk just so we can clean it up -+ if (this.chunk == null) -+ { -+ this.players.remove(player); -+ -+ if (this.players.isEmpty()) -+ { -+ if (this.loading) net.minecraftforge.common.chunkio.ChunkIOExecutor.dropQueuedChunkLoad(this.playerChunkMap.getWorldServer(), this.pos.x, this.pos.z, this.loadedRunnable); -+ this.playerChunkMap.removeEntry(this); -+ } -+ -+ return; -+ } -+ - if (this.sentToPlayers) - { - player.connection.sendPacket(new SPacketUnloadChunk(this.pos.x, this.pos.z)); -@@ -80,6 +105,8 @@ - - this.players.remove(player); - -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.ChunkWatchEvent.UnWatch(this.chunk, player)); -+ - if (this.players.isEmpty()) - { - this.playerChunkMap.removeEntry(this); -@@ -89,6 +116,7 @@ - - public boolean providePlayerChunk(boolean canGenerate) - { -+ if (this.loading) return false; - if (this.chunk != null) - { - return true; -@@ -133,12 +161,15 @@ - this.changes = 0; - this.changedSectionFilter = 0; - this.sentToPlayers = true; -+ if (this.players.isEmpty()) return true; // Forge: fix MC-120780 - Packet packet = new SPacketChunkData(this.chunk, 65535); - - for (EntityPlayerMP entityplayermp : this.players) - { - entityplayermp.connection.sendPacket(packet); - this.playerChunkMap.getWorldServer().getEntityTracker().sendLeashedEntitiesInChunk(entityplayermp, this.chunk); -+ // chunk watch event - delayed to here as the chunk wasn't ready in addPlayer -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.ChunkWatchEvent.Watch(this.chunk, entityplayermp)); - } - - return true; -@@ -177,7 +208,7 @@ - - this.changedSectionFilter |= 1 << (y >> 4); - -- if (this.changes < 64) -+ //Forge; Cache everything, so always run - { - short short1 = (short)(x << 12 | z << 8 | y); - -@@ -189,6 +220,8 @@ - } - } - -+ if (this.changes == this.changedBlocks.length) -+ this.changedBlocks = java.util.Arrays.copyOf(this.changedBlocks, this.changedBlocks.length << 1); - this.changedBlocks[this.changes++] = short1; - } - } -@@ -205,6 +238,7 @@ - } - } - -+ @SuppressWarnings("unused") - public void update() - { - if (this.sentToPlayers && this.chunk != null) -@@ -218,28 +252,33 @@ - int k = (this.changedBlocks[0] >> 8 & 15) + this.pos.z * 16; - BlockPos blockpos = new BlockPos(i, j, k); - this.sendPacket(new SPacketBlockChange(this.playerChunkMap.getWorldServer(), blockpos)); -+ net.minecraft.block.state.IBlockState state = this.playerChunkMap.getWorldServer().getBlockState(blockpos); - -- if (this.playerChunkMap.getWorldServer().getBlockState(blockpos).getBlock().hasTileEntity()) -+ if (state.getBlock().hasTileEntity(state)) - { - this.sendBlockEntity(this.playerChunkMap.getWorldServer().getTileEntity(blockpos)); - } - } -- else if (this.changes == 64) -+ else if (this.changes >= net.minecraftforge.common.ForgeModContainer.clumpingThreshold) - { - this.sendPacket(new SPacketChunkData(this.chunk, this.changedSectionFilter)); -+ //TODO: FDix Mojang's fuckup to modded by combining all TE data into the chunk data packet... seriously... packet size explosion! - } - else - { - this.sendPacket(new SPacketMultiBlockChange(this.changes, this.changedBlocks, this.chunk)); - -+ //} Keep this in the else until we figure out a fix for mojang's derpitude on the data packet so we don't double send crap. -+ //{// Forge: Send only the tile entities that are updated, Adding this brace lets us keep the indent and the patch small - for (int l = 0; l < this.changes; l++) - { - int i1 = (this.changedBlocks[l] >> 12 & 15) + this.pos.x * 16; - int j1 = this.changedBlocks[l] & 255; - int k1 = (this.changedBlocks[l] >> 8 & 15) + this.pos.z * 16; - BlockPos blockpos1 = new BlockPos(i1, j1, k1); -+ net.minecraft.block.state.IBlockState state = this.playerChunkMap.getWorldServer().getBlockState(blockpos1); - -- if (this.playerChunkMap.getWorldServer().getBlockState(blockpos1).getBlock().hasTileEntity()) -+ if (state.getBlock().hasTileEntity(state)) - { - this.sendBlockEntity(this.playerChunkMap.getWorldServer().getTileEntity(blockpos1)); - } -@@ -318,5 +357,10 @@ - } - - return d0; -+ } -+ -+ public List getWatchingPlayers() -+ { -+ return isSentToPlayers() ? java.util.Collections.unmodifiableList(players) : java.util.Collections.emptyList(); - } - } diff --git a/patches/minecraft/net/minecraft/server/management/PlayerInteractionManager.java.patch b/patches/minecraft/net/minecraft/server/management/PlayerInteractionManager.java.patch deleted file mode 100644 index e282e6b09..000000000 --- a/patches/minecraft/net/minecraft/server/management/PlayerInteractionManager.java.patch +++ /dev/null @@ -1,291 +0,0 @@ ---- before/net/minecraft/server/management/PlayerInteractionManager.java -+++ after/net/minecraft/server/management/PlayerInteractionManager.java -@@ -91,7 +91,7 @@ - int i = this.curblockDamage - this.initialBlockDamage; - IBlockState iblockstate = this.world.getBlockState(this.delayedDestroyPos); - -- if (iblockstate.getMaterial() == Material.AIR) -+ if (iblockstate.getBlock().isAir(iblockstate, world, delayedDestroyPos)) - { - this.receivedFinishDiggingPacket = false; - } -@@ -117,7 +117,7 @@ - { - IBlockState iblockstate1 = this.world.getBlockState(this.destroyPos); - -- if (iblockstate1.getMaterial() == Material.AIR) -+ if (iblockstate1.getBlock().isAir(iblockstate1, world, destroyPos)) - { - this.world.sendBlockBreakProgress(this.player.getEntityId(), this.destroyPos, -1); - this.durabilityRemainingOnBlock = -1; -@@ -126,7 +126,7 @@ - else - { - int k = this.curblockDamage - this.initialDamage; -- float f1 = iblockstate1.getPlayerRelativeBlockHardness(this.player, this.player.world, this.delayedDestroyPos) * (k + 1); -+ float f1 = iblockstate1.getPlayerRelativeBlockHardness(this.player, this.player.world, this.destroyPos) * (k + 1); // Forge: Fix network break progress using wrong position - int l = (int)(f1 * 10.0F); - - if (l != this.durabilityRemainingOnBlock) -@@ -140,6 +140,16 @@ - - public void onBlockClicked(BlockPos pos, EnumFacing side) - { -+ double reachDist = player.getEntityAttribute(EntityPlayer.REACH_DISTANCE).getAttributeValue(); -+ net.minecraftforge.event.entity.player.PlayerInteractEvent.LeftClickBlock event = net.minecraftforge.common.ForgeHooks.onLeftClickBlock(player, pos, side, net.minecraftforge.common.ForgeHooks.rayTraceEyeHitVec(player, reachDist + 1)); -+ if (event.isCanceled()) -+ { -+ // Restore block and te data -+ player.connection.sendPacket(new SPacketBlockChange(world, pos)); -+ world.notifyBlockUpdate(pos, world.getBlockState(pos), world.getBlockState(pos), 3); -+ return; -+ } -+ - if (this.isCreative()) - { - if (!this.world.extinguishFire(null, pos, side)) -@@ -175,17 +185,36 @@ - } - } - -- this.world.extinguishFire(null, pos, side); - this.initialDamage = this.curblockDamage; - float f = 1.0F; - -- if (iblockstate.getMaterial() != Material.AIR) -+ if (!iblockstate.getBlock().isAir(iblockstate, world, pos)) - { -- block.onBlockClicked(this.world, pos, this.player); -+ if (event.getUseBlock() != net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) -+ { -+ block.onBlockClicked(this.world, pos, this.player); -+ this.world.extinguishFire(null, pos, side); -+ } -+ else -+ { -+ // Restore block and te data -+ player.connection.sendPacket(new SPacketBlockChange(world, pos)); -+ world.notifyBlockUpdate(pos, world.getBlockState(pos), world.getBlockState(pos), 3); -+ } - f = iblockstate.getPlayerRelativeBlockHardness(this.player, this.player.world, pos); - } -+ if (event.getUseItem() == net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) -+ { -+ if (f >= 1.0F) -+ { -+ // Restore block and te data -+ player.connection.sendPacket(new SPacketBlockChange(world, pos)); -+ world.notifyBlockUpdate(pos, world.getBlockState(pos), world.getBlockState(pos), 3); -+ } -+ return; -+ } - -- if (iblockstate.getMaterial() != Material.AIR && f >= 1.0F) -+ if (!iblockstate.getBlock().isAir(iblockstate, world, pos) && f >= 1.0F) - { - this.tryHarvestBlock(pos); - } -@@ -207,9 +236,9 @@ - int i = this.curblockDamage - this.initialDamage; - IBlockState iblockstate = this.world.getBlockState(pos); - -- if (iblockstate.getMaterial() != Material.AIR) -+ if (!iblockstate.getBlock().isAir(iblockstate, world, pos)) - { -- float f = iblockstate.getPlayerRelativeBlockHardness(this.player, this.player.world, pos) * (i + 1); -+ float f = iblockstate.getPlayerRelativeBlockHardness(this.player, this.player.world, pos) * (float)(i + 1); - - if (f >= 0.7F) - { -@@ -236,9 +265,13 @@ - - private boolean removeBlock(BlockPos pos) - { -+ return removeBlock(pos, false); -+ } -+ -+ private boolean removeBlock(BlockPos pos, boolean canHarvest) -+ { - IBlockState iblockstate = this.world.getBlockState(pos); -- iblockstate.getBlock().onBlockHarvested(this.world, pos, iblockstate, this.player); -- boolean flag = this.world.setBlockToAir(pos); -+ boolean flag = iblockstate.getBlock().removedByPlayer(iblockstate, world, pos, player, canHarvest); - - if (flag) - { -@@ -250,9 +283,8 @@ - - public boolean tryHarvestBlock(BlockPos pos) - { -- if (this.gameType.isCreative() -- && !this.player.getHeldItemMainhand().isEmpty() -- && this.player.getHeldItemMainhand().getItem() instanceof ItemSword) -+ int exp = net.minecraftforge.common.ForgeHooks.onBlockBreakEvent(world, gameType, player, pos); -+ if (exp == -1) - { - return false; - } -@@ -269,53 +301,41 @@ - } - else - { -- if (this.gameType.hasLimitedInteractions()) -- { -- if (this.gameType == GameType.SPECTATOR) -- { -- return false; -- } -- -- if (!this.player.isAllowEdit()) -- { -- ItemStack itemstack = this.player.getHeldItemMainhand(); -- -- if (itemstack.isEmpty()) -- { -- return false; -- } -- -- if (!itemstack.canDestroy(block)) -- { -- return false; -- } -- } -- } -+ ItemStack stack = player.getHeldItemMainhand(); -+ if (!stack.isEmpty() && stack.getItem().onBlockStartBreak(stack, pos, player)) return false; - - this.world.playEvent(this.player, 2001, pos, Block.getStateId(iblockstate)); -- boolean flag1 = this.removeBlock(pos); -+ boolean flag1 = false; - - if (this.isCreative()) - { -+ flag1 = this.removeBlock(pos); - this.player.connection.sendPacket(new SPacketBlockChange(this.world, pos)); - } - else - { - ItemStack itemstack1 = this.player.getHeldItemMainhand(); - ItemStack itemstack2 = itemstack1.isEmpty() ? ItemStack.EMPTY : itemstack1.copy(); -- boolean flag = this.player.canHarvestBlock(iblockstate); -+ boolean flag = iblockstate.getBlock().canHarvestBlock(world, pos, player); - - if (!itemstack1.isEmpty()) - { - itemstack1.onBlockDestroyed(this.world, iblockstate, pos, this.player); -+ if (itemstack1.isEmpty()) net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(this.player, itemstack2, EnumHand.MAIN_HAND); - } - -+ flag1 = this.removeBlock(pos, flag); - if (flag1 && flag) - { - iblockstate.getBlock().harvestBlock(this.world, this.player, pos, iblockstate, tileentity, itemstack2); - } - } - -+ // Drop experience -+ if (!this.isCreative() && flag1 && exp > 0) -+ { -+ iblockstate.getBlock().dropXpOnBlockBreak(world, pos, exp); -+ } - return flag1; - } - } -@@ -333,8 +353,11 @@ - } - else - { -+ EnumActionResult cancelResult = net.minecraftforge.common.ForgeHooks.onItemRightClick(player, hand); -+ if (cancelResult != null) return cancelResult; - int i = stack.getCount(); - int j = stack.getMetadata(); -+ ItemStack copyBeforeUse = stack.copy(); - ActionResult actionresult = stack.useItemRightClick(worldIn, player, hand); - ItemStack itemstack = actionresult.getResult(); - -@@ -362,6 +385,7 @@ - - if (itemstack.isEmpty()) - { -+ net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(player, copyBeforeUse, hand); - player.setHeldItem(hand, ItemStack.EMPTY); - } - -@@ -417,14 +441,27 @@ - } - else - { -- if (!player.isSneaking() || player.getHeldItemMainhand().isEmpty() && player.getHeldItemOffhand().isEmpty()) -+ double reachDist = player.getEntityAttribute(EntityPlayer.REACH_DISTANCE).getAttributeValue(); -+ net.minecraftforge.event.entity.player.PlayerInteractEvent.RightClickBlock event = net.minecraftforge.common.ForgeHooks -+ .onRightClickBlock(player, hand, pos, facing, net.minecraftforge.common.ForgeHooks.rayTraceEyeHitVec(player, reachDist + 1)); -+ if (event.isCanceled()) return event.getCancellationResult(); -+ -+ EnumActionResult result = EnumActionResult.PASS; -+ if (event.getUseItem() != net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) -+ { -+ result = stack.onItemUseFirst(player, worldIn, pos, hand, facing, hitX, hitY, hitZ); -+ if (result != EnumActionResult.PASS) return result ; -+ } -+ -+ boolean bypass = player.getHeldItemMainhand().doesSneakBypassUse(worldIn, pos, player) && player.getHeldItemOffhand().doesSneakBypassUse(worldIn, pos, player); -+ -+ if (!player.isSneaking() || bypass || event.getUseBlock() == net.minecraftforge.fml.common.eventhandler.Event.Result.ALLOW) - { - IBlockState iblockstate = worldIn.getBlockState(pos); -- -- if (iblockstate.getBlock() -- .onBlockActivated(worldIn, pos, iblockstate, player, hand, facing, hitX, hitY, hitZ)) -+ if(event.getUseBlock() != net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) -+ if (iblockstate.getBlock().onBlockActivated(worldIn, pos, iblockstate, player, hand, facing, hitX, hitY, hitZ)) - { -- return EnumActionResult.SUCCESS; -+ result = EnumActionResult.SUCCESS; - } - } - -@@ -452,16 +489,22 @@ - { - int j = stack.getMetadata(); - int i = stack.getCount(); -- EnumActionResult enumactionresult = stack.onItemUse( -- player, worldIn, pos, hand, facing, hitX, hitY, hitZ -- ); -+ if (result != EnumActionResult.SUCCESS && event.getUseItem() != net.minecraftforge.fml.common.eventhandler.Event.Result.DENY -+ || result == EnumActionResult.SUCCESS && event.getUseItem() == net.minecraftforge.fml.common.eventhandler.Event.Result.ALLOW) { -+ EnumActionResult enumactionresult = stack.onItemUse(player, worldIn, pos, hand, facing, hitX, hitY, hitZ); - stack.setItemDamage(j); - stack.setCount(i); - return enumactionresult; -+ } else return result; - } - else - { -- return stack.onItemUse(player, worldIn, pos, hand, facing, hitX, hitY, hitZ); -+ if (result != EnumActionResult.SUCCESS && event.getUseItem() != net.minecraftforge.fml.common.eventhandler.Event.Result.DENY -+ || result == EnumActionResult.SUCCESS && event.getUseItem() == net.minecraftforge.fml.common.eventhandler.Event.Result.ALLOW) { -+ ItemStack copyBeforeUse = stack.copy(); -+ result = stack.onItemUse(player, worldIn, pos, hand, facing, hitX, hitY, hitZ); -+ if (stack.isEmpty()) net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(player, copyBeforeUse, hand); -+ } return result; - } - } - } -@@ -470,5 +513,17 @@ - public void setWorld(WorldServer serverWorld) - { - this.world = serverWorld; -+ } -+ -+ @Deprecated // use the attribute directly -+ public double getBlockReachDistance() -+ { -+ return player.getEntityAttribute(EntityPlayer.REACH_DISTANCE).getAttributeValue(); -+ } -+ -+ @Deprecated // use an attribute modifier -+ public void setBlockReachDistance(double distance) -+ { -+ player.getEntityAttribute(EntityPlayer.REACH_DISTANCE).setBaseValue(distance); - } - } diff --git a/patches/minecraft/net/minecraft/server/management/PlayerList.java.patch b/patches/minecraft/net/minecraft/server/management/PlayerList.java.patch deleted file mode 100644 index 2b93cc6bb..000000000 --- a/patches/minecraft/net/minecraft/server/management/PlayerList.java.patch +++ /dev/null @@ -1,267 +0,0 @@ ---- before/net/minecraft/server/management/PlayerList.java -+++ after/net/minecraft/server/management/PlayerList.java -@@ -100,7 +100,7 @@ - this.maxPlayers = 8; - } - -- public void initializeConnectionToPlayer(NetworkManager netManager, EntityPlayerMP playerIn) -+ public void initializeConnectionToPlayer(NetworkManager netManager, EntityPlayerMP playerIn, NetHandlerPlayServer nethandlerplayserver) - { - GameProfile gameprofile = playerIn.getGameProfile(); - PlayerProfileCache playerprofilecache = this.server.getPlayerProfileCache(); -@@ -109,6 +109,17 @@ - playerprofilecache.addEntry(gameprofile); - NBTTagCompound nbttagcompound = this.readPlayerDataFromFile(playerIn); - playerIn.setWorld(this.server.getWorld(playerIn.dimension)); -+ -+ World playerWorld = this.server.getWorld(playerIn.dimension); -+ if (playerWorld == null) -+ { -+ playerIn.dimension = 0; -+ playerWorld = this.server.getWorld(0); -+ BlockPos spawnPoint = playerWorld.provider.getRandomizedSpawnPoint(); -+ playerIn.setPosition(spawnPoint.getX(), spawnPoint.getY(), spawnPoint.getZ()); -+ } -+ -+ playerIn.setWorld(playerWorld); - playerIn.interactionManager.setWorld((WorldServer)playerIn.world); - String s1 = "local"; - -@@ -129,13 +140,14 @@ - WorldServer worldserver = this.server.getWorld(playerIn.dimension); - WorldInfo worldinfo = worldserver.getWorldInfo(); - this.setPlayerGameTypeBasedOnOther(playerIn, null, worldserver); -- NetHandlerPlayServer nethandlerplayserver = new NetHandlerPlayServer(this.server, netManager, playerIn); -+ playerIn.connection = nethandlerplayserver; -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().fireServerConnectionEvent(netManager); - nethandlerplayserver.sendPacket( - new SPacketJoinGame( - playerIn.getEntityId(), - playerIn.interactionManager.getGameType(), - worldinfo.isHardcoreModeEnabled(), -- worldserver.provider.getDimensionType().getId(), -+ worldserver.provider.getDimension(), - worldserver.getDifficulty(), - this.getMaxPlayers(), - worldinfo.getTerrainType(), -@@ -221,6 +233,7 @@ - } - - playerIn.addSelfToInternalCraftingInventory(); -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().firePlayerLoggedIn(playerIn); - } - - protected void sendScoreboard(ServerScoreboard scoreboardIn, EntityPlayerMP playerIn) -@@ -330,6 +343,7 @@ - nbttagcompound1 = nbttagcompound; - playerIn.readFromNBT(nbttagcompound); - LOGGER.debug("loading single player"); -+ net.minecraftforge.event.ForgeEventFactory.firePlayerLoadingEvent(playerIn, this.playerDataManager, playerIn.getUniqueID().toString()); - } - else - { -@@ -339,8 +353,24 @@ - return nbttagcompound1; - } - -+ public NBTTagCompound getPlayerNBT(EntityPlayerMP player) -+ { -+ // Hacky method to allow loading the NBT for a player prior to login -+ NBTTagCompound nbttagcompound = this.server.worlds[0].getWorldInfo().getPlayerNBTTagCompound(); -+ if (player.getName().equals(this.server.getServerOwner()) && nbttagcompound != null) -+ { -+ return nbttagcompound; -+ } -+ else -+ { -+ return ((net.minecraft.world.storage.SaveHandler)this.playerDataManager).getPlayerNBT(player); -+ } -+ } -+ - protected void writePlayerData(EntityPlayerMP playerIn) - { -+ if (playerIn.connection == null) return; -+ - this.playerDataManager.writePlayerData(playerIn); - StatisticsManagerServer statisticsmanagerserver = this.playerStatFiles.get(playerIn.getUniqueID()); - -@@ -369,6 +399,7 @@ - playerIn.connection.sendPacket(new SPacketPlayerListItem(SPacketPlayerListItem.Action.ADD_PLAYER, this.playerEntityList.get(i))); - } - -+ net.minecraftforge.common.chunkio.ChunkIOExecutor.adjustPoolSize(this.getCurrentPlayerCount()); - worldserver.spawnEntity(playerIn); - this.preparePlayer(playerIn, null); - } -@@ -380,6 +411,7 @@ - - public void playerLoggedOut(EntityPlayerMP playerIn) - { -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().firePlayerLoggedOut(playerIn); - WorldServer worldserver = playerIn.getServerWorld(); - playerIn.addStat(StatList.LEAVE_GAME); - this.writePlayerData(playerIn); -@@ -402,6 +434,7 @@ - worldserver.getChunk(playerIn.chunkCoordX, playerIn.chunkCoordZ).markDirty(); - } - } -+ net.minecraftforge.common.chunkio.ChunkIOExecutor.adjustPoolSize(this.getCurrentPlayerCount()); - - worldserver.removeEntity(playerIn); - worldserver.getPlayerChunkMap().removePlayer(playerIn); -@@ -499,13 +532,24 @@ - - public EntityPlayerMP recreatePlayerEntity(EntityPlayerMP playerIn, int dimension, boolean conqueredEnd) - { -+ World world = server.getWorld(dimension); -+ if (world == null) -+ { -+ dimension = playerIn.getSpawnDimension(); -+ } -+ else if (!world.provider.canRespawnHere()) -+ { -+ dimension = world.provider.getRespawnDimension(playerIn); -+ } -+ if (server.getWorld(dimension) == null) dimension = 0; -+ - playerIn.getServerWorld().getEntityTracker().removePlayerFromTrackers(playerIn); - playerIn.getServerWorld().getEntityTracker().untrack(playerIn); - playerIn.getServerWorld().getPlayerChunkMap().removePlayer(playerIn); - this.playerEntityList.remove(playerIn); - this.server.getWorld(playerIn.dimension).removeEntityDangerously(playerIn); -- BlockPos blockpos = playerIn.getBedLocation(); -- boolean flag = playerIn.isSpawnForced(); -+ BlockPos blockpos = playerIn.getBedLocation(dimension); -+ boolean flag = playerIn.isSpawnForced(dimension); - playerIn.dimension = dimension; - PlayerInteractionManager playerinteractionmanager; - -@@ -523,6 +567,7 @@ - ); - entityplayermp.connection = playerIn.connection; - entityplayermp.copyFrom(playerIn, conqueredEnd); -+ entityplayermp.dimension = dimension; - entityplayermp.setEntityId(playerIn.getEntityId()); - entityplayermp.setCommandStats(playerIn); - entityplayermp.setPrimaryHand(playerIn.getPrimaryHand()); -@@ -586,6 +631,7 @@ - this.uuidToPlayerMap.put(entityplayermp.getUniqueID(), entityplayermp); - entityplayermp.addSelfToInternalCraftingInventory(); - entityplayermp.setHealth(entityplayermp.getHealth()); -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().firePlayerRespawnEvent(entityplayermp, conqueredEnd); - return entityplayermp; - } - -@@ -600,6 +646,17 @@ - - public void changePlayerDimension(EntityPlayerMP player, int dimensionIn) - { -+ transferPlayerToDimension(player, dimensionIn, server.getWorld(dimensionIn).getDefaultTeleporter()); -+ } -+ -+ // TODO: Remove (1.13) -+ public void transferPlayerToDimension(EntityPlayerMP player, int dimensionIn, net.minecraft.world.Teleporter teleporter) -+ { -+ transferPlayerToDimension(player, dimensionIn, (net.minecraftforge.common.util.ITeleporter) teleporter); -+ } -+ -+ public void transferPlayerToDimension(EntityPlayerMP player, int dimensionIn, net.minecraftforge.common.util.ITeleporter teleporter) -+ { - int i = player.dimension; - WorldServer worldserver = this.server.getWorld(player.dimension); - player.dimension = dimensionIn; -@@ -608,15 +665,15 @@ - .sendPacket( - new SPacketRespawn( - player.dimension, -- player.world.getDifficulty(), -- player.world.getWorldInfo().getTerrainType(), -+ worldserver1.getDifficulty(), -+ worldserver1.getWorldInfo().getTerrainType(), - player.interactionManager.getGameType() - ) -- ); -+ ); // Forge: Use new dimensions information - this.updatePermissionLevel(player); - worldserver.removeEntityDangerously(player); - player.isDead = false; -- this.transferEntityToWorld(player, i, worldserver, worldserver1); -+ this.transferEntityToWorld(player, i, worldserver, worldserver1, teleporter); - this.preparePlayer(player, worldserver); - player.connection - .setPlayerLocation(player.posX, player.posY, player.posZ, player.rotationYaw, player.rotationPitch); -@@ -629,17 +686,34 @@ - { - player.connection.sendPacket(new SPacketEntityEffect(player.getEntityId(), potioneffect)); - } -+ // Fix MC-88179: on non-death SPacketRespawn, also resend attributes -+ net.minecraft.entity.ai.attributes.AttributeMap attributemap = (net.minecraft.entity.ai.attributes.AttributeMap) player.getAttributeMap(); -+ java.util.Collection watchedAttribs = attributemap.getWatchedAttributes(); -+ if (!watchedAttribs.isEmpty()) player.connection.sendPacket(new net.minecraft.network.play.server.SPacketEntityProperties(player.getEntityId(), watchedAttribs)); -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().firePlayerChangedDimensionEvent(player, i, dimensionIn); - } - - public void transferEntityToWorld(Entity entityIn, int lastDimension, WorldServer oldWorldIn, WorldServer toWorldIn) - { -- double d0 = entityIn.posX; -- double d1 = entityIn.posZ; -+ transferEntityToWorld(entityIn, lastDimension, oldWorldIn, toWorldIn, toWorldIn.getDefaultTeleporter()); -+ } -+ -+ // TODO: Remove (1.13) -+ public void transferEntityToWorld(Entity entityIn, int lastDimension, WorldServer oldWorldIn, WorldServer toWorldIn, net.minecraft.world.Teleporter teleporter) -+ { -+ transferEntityToWorld(entityIn, lastDimension, oldWorldIn, toWorldIn, (net.minecraftforge.common.util.ITeleporter) teleporter); -+ } -+ -+ public void transferEntityToWorld(Entity entityIn, int lastDimension, WorldServer oldWorldIn, WorldServer toWorldIn, net.minecraftforge.common.util.ITeleporter teleporter) -+ { -+ double moveFactor = oldWorldIn.provider.getMovementFactor() / toWorldIn.provider.getMovementFactor(); -+ double d0 = MathHelper.clamp(entityIn.posX * moveFactor, toWorldIn.getWorldBorder().minX() + 16.0, toWorldIn.getWorldBorder().maxX() - 16.0); -+ double d1 = MathHelper.clamp(entityIn.posZ * moveFactor, toWorldIn.getWorldBorder().minZ() + 16.0, toWorldIn.getWorldBorder().maxZ() - 16.0); - double d2 = 8.0; - float f = entityIn.rotationYaw; - oldWorldIn.profiler.startSection("moving"); - -- if (entityIn.dimension == -1) -+ if (false && entityIn.dimension == -1) - { - d0 = MathHelper.clamp(d0 / 8.0, toWorldIn.getWorldBorder().minX() + 16.0, toWorldIn.getWorldBorder().maxX() - 16.0); - d1 = MathHelper.clamp(d1 / 8.0, toWorldIn.getWorldBorder().minZ() + 16.0, toWorldIn.getWorldBorder().maxZ() - 16.0); -@@ -650,7 +724,7 @@ - oldWorldIn.updateEntityWithOptionalForce(entityIn, false); - } - } -- else if (entityIn.dimension == 0) -+ else if (false && entityIn.dimension == 0) - { - d0 = MathHelper.clamp(d0 * 8.0, toWorldIn.getWorldBorder().minX() + 16.0, toWorldIn.getWorldBorder().maxX() - 16.0); - d1 = MathHelper.clamp(d1 * 8.0, toWorldIn.getWorldBorder().minZ() + 16.0, toWorldIn.getWorldBorder().maxZ() - 16.0); -@@ -661,7 +735,7 @@ - oldWorldIn.updateEntityWithOptionalForce(entityIn, false); - } - } -- else -+ if (entityIn.dimension == 1 && teleporter.isVanilla()) - { - BlockPos blockpos; - -@@ -687,7 +761,7 @@ - - oldWorldIn.profiler.endSection(); - -- if (lastDimension != 1) -+ if (lastDimension != 1 || !teleporter.isVanilla()) - { - oldWorldIn.profiler.startSection("placing"); - d0 = MathHelper.clamp((int)d0, -29999872, 29999872); -@@ -696,7 +770,8 @@ - if (entityIn.isEntityAlive()) - { - entityIn.setLocationAndAngles(d0, entityIn.posY, d1, entityIn.rotationYaw, entityIn.rotationPitch); -- toWorldIn.getDefaultTeleporter().placeInPortal(entityIn, f); -+ oldWorldIn.updateEntityWithOptionalForce(entityIn, false); -+ teleporter.placeEntity(toWorldIn, entityIn, f); - toWorldIn.spawnEntity(entityIn); - toWorldIn.updateEntityWithOptionalForce(entityIn, false); - } diff --git a/patches/minecraft/net/minecraft/server/network/NetHandlerHandshakeTCP.java.patch b/patches/minecraft/net/minecraft/server/network/NetHandlerHandshakeTCP.java.patch deleted file mode 100644 index 4a4c55bee..000000000 --- a/patches/minecraft/net/minecraft/server/network/NetHandlerHandshakeTCP.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/server/network/NetHandlerHandshakeTCP.java -+++ after/net/minecraft/server/network/NetHandlerHandshakeTCP.java -@@ -23,6 +23,8 @@ - @Override - public void processHandshake(C00Handshake packetIn) - { -+ if (!net.minecraftforge.fml.common.FMLCommonHandler.instance().handleServerHandshake(packetIn, this.networkManager)) return; -+ - switch (packetIn.getRequestedState()) - { - case LOGIN: diff --git a/patches/minecraft/net/minecraft/server/network/NetHandlerLoginServer.java.patch b/patches/minecraft/net/minecraft/server/network/NetHandlerLoginServer.java.patch deleted file mode 100644 index dd4252ea1..000000000 --- a/patches/minecraft/net/minecraft/server/network/NetHandlerLoginServer.java.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- before/net/minecraft/server/network/NetHandlerLoginServer.java -+++ after/net/minecraft/server/network/NetHandlerLoginServer.java -@@ -70,7 +70,7 @@ - if (entityplayermp == null) - { - this.currentLoginState = NetHandlerLoginServer.LoginState.READY_TO_ACCEPT; -- this.server.getPlayerList().initializeConnectionToPlayer(this.networkManager, this.player); -+ net.minecraftforge.fml.common.network.internal.FMLNetworkHandler.fmlServerHandshake(this.server.getPlayerList(), this.networkManager, this.player); - this.player = null; - } - } -@@ -133,7 +133,7 @@ - } - else - { -- this.server.getPlayerList().initializeConnectionToPlayer(this.networkManager, this.server.getPlayerList().createPlayerForUser(this.loginGameProfile)); -+ net.minecraftforge.fml.common.network.internal.FMLNetworkHandler.fmlServerHandshake(this.server.getPlayerList(), this.networkManager, this.server.getPlayerList().createPlayerForUser(this.loginGameProfile)); - } - } - } -@@ -183,7 +183,7 @@ - this.secretKey = packetIn.getSecretKey(privatekey); - this.currentLoginState = NetHandlerLoginServer.LoginState.AUTHENTICATING; - this.networkManager.enableEncryption(this.secretKey); -- (new Thread("User Authenticator #" + AUTHENTICATOR_THREAD_ID.incrementAndGet()) -+ (new Thread(net.minecraftforge.fml.common.thread.SidedThreadGroups.SERVER, "User Authenticator #" + AUTHENTICATOR_THREAD_ID.incrementAndGet()) - { - @Override - public void run() diff --git a/patches/minecraft/net/minecraft/stats/RecipeBook.java.patch b/patches/minecraft/net/minecraft/stats/RecipeBook.java.patch deleted file mode 100644 index 3b7c9be68..000000000 --- a/patches/minecraft/net/minecraft/stats/RecipeBook.java.patch +++ /dev/null @@ -1,21 +0,0 @@ ---- before/net/minecraft/stats/RecipeBook.java -+++ after/net/minecraft/stats/RecipeBook.java -@@ -42,9 +42,17 @@ - this.newRecipes.clear(i); - } - -+ @Deprecated //DO NOT USE - protected static int getRecipeId(@Nullable IRecipe recipe) - { -- return CraftingManager.REGISTRY.getIDForObject(recipe); -+ int ret = CraftingManager.REGISTRY.getIDForObject(recipe); -+ if (ret == -1) -+ { -+ ret = ((net.minecraftforge.registries.ForgeRegistry)net.minecraftforge.fml.common.registry.ForgeRegistries.RECIPES).getID(recipe.getRegistryName()); -+ if (ret == -1) -+ throw new IllegalArgumentException(String.format("Attempted to get the ID for a unknown recipe: %s Name: %s", recipe, recipe.getRegistryName())); -+ } -+ return ret; - } - - @SideOnly(Side.CLIENT) diff --git a/patches/minecraft/net/minecraft/stats/RecipeBookServer.java.patch b/patches/minecraft/net/minecraft/stats/RecipeBookServer.java.patch deleted file mode 100644 index 2912f7c1f..000000000 --- a/patches/minecraft/net/minecraft/stats/RecipeBookServer.java.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- before/net/minecraft/stats/RecipeBookServer.java -+++ after/net/minecraft/stats/RecipeBookServer.java -@@ -55,8 +55,7 @@ - - private void sendPacket(SPacketRecipeBook.State state, EntityPlayerMP player, List recipesIn) - { -- player.connection -- .sendPacket(new SPacketRecipeBook(state, recipesIn, Collections.emptyList(), this.isGuiOpen, this.isFilteringCraftable)); -+ net.minecraftforge.common.ForgeHooks.sendRecipeBook(player.connection, state, recipesIn, Collections.emptyList(), this.isGuiOpen, this.isFilteringCraftable); - } - - public NBTTagCompound write() -@@ -148,9 +147,6 @@ - - public void init(EntityPlayerMP player) - { -- player.connection -- .sendPacket( -- new SPacketRecipeBook(SPacketRecipeBook.State.INIT, this.getRecipes(), this.getDisplayedRecipes(), this.isGuiOpen, this.isFilteringCraftable) -- ); -+ net.minecraftforge.common.ForgeHooks.sendRecipeBook(player.connection, SPacketRecipeBook.State.INIT, this.getRecipes(), this.getDisplayedRecipes(), this.isGuiOpen, this.isFilteringCraftable); - } - } diff --git a/patches/minecraft/net/minecraft/stats/StatList.java.patch b/patches/minecraft/net/minecraft/stats/StatList.java.patch deleted file mode 100644 index fb801cd1f..000000000 --- a/patches/minecraft/net/minecraft/stats/StatList.java.patch +++ /dev/null @@ -1,139 +0,0 @@ ---- before/net/minecraft/stats/StatList.java -+++ after/net/minecraft/stats/StatList.java -@@ -207,7 +207,7 @@ - } - } - -- replaceAllSimilarBlocks(CRAFTS_STATS); -+ replaceAllSimilarBlocks(CRAFTS_STATS, true); - } - - private static void initMiningStats() -@@ -232,7 +232,7 @@ - } - } - -- replaceAllSimilarBlocks(BLOCKS_STATS); -+ replaceAllSimilarBlocks(BLOCKS_STATS, false); - } - - private static void initStats() -@@ -257,7 +257,7 @@ - } - } - -- replaceAllSimilarBlocks(OBJECT_USE_STATS); -+ replaceAllSimilarBlocks(OBJECT_USE_STATS, true); - } - - private static void initItemDepleteStats() -@@ -279,7 +279,7 @@ - } - } - -- replaceAllSimilarBlocks(OBJECT_BREAK_STATS); -+ replaceAllSimilarBlocks(OBJECT_BREAK_STATS, true); - } - - private static void initPickedUpAndDroppedStats() -@@ -301,7 +301,7 @@ - } - } - -- replaceAllSimilarBlocks(OBJECT_BREAK_STATS); -+ replaceAllSimilarBlocks(OBJECT_BREAK_STATS, true); - } - - private static String getItemName(Item itemIn) -@@ -310,28 +310,35 @@ - return resourcelocation != null ? resourcelocation.toString().replace(':', '.') : null; - } - -- private static void replaceAllSimilarBlocks(StatBase[] stat) -+ private static void replaceAllSimilarBlocks(StatBase[] stat, boolean useItemIds) - { -- mergeStatBases(stat, Blocks.WATER, Blocks.FLOWING_WATER); -- mergeStatBases(stat, Blocks.LAVA, Blocks.FLOWING_LAVA); -- mergeStatBases(stat, Blocks.LIT_PUMPKIN, Blocks.PUMPKIN); -- mergeStatBases(stat, Blocks.LIT_FURNACE, Blocks.FURNACE); -- mergeStatBases(stat, Blocks.LIT_REDSTONE_ORE, Blocks.REDSTONE_ORE); -- mergeStatBases(stat, Blocks.POWERED_REPEATER, Blocks.UNPOWERED_REPEATER); -- mergeStatBases(stat, Blocks.POWERED_COMPARATOR, Blocks.UNPOWERED_COMPARATOR); -- mergeStatBases(stat, Blocks.REDSTONE_TORCH, Blocks.UNLIT_REDSTONE_TORCH); -- mergeStatBases(stat, Blocks.LIT_REDSTONE_LAMP, Blocks.REDSTONE_LAMP); -- mergeStatBases(stat, Blocks.DOUBLE_STONE_SLAB, Blocks.STONE_SLAB); -- mergeStatBases(stat, Blocks.DOUBLE_WOODEN_SLAB, Blocks.WOODEN_SLAB); -- mergeStatBases(stat, Blocks.DOUBLE_STONE_SLAB2, Blocks.STONE_SLAB2); -- mergeStatBases(stat, Blocks.GRASS, Blocks.DIRT); -- mergeStatBases(stat, Blocks.FARMLAND, Blocks.DIRT); -+ mergeStatBases(stat, Blocks.WATER, Blocks.FLOWING_WATER, useItemIds); -+ mergeStatBases(stat, Blocks.LAVA, Blocks.FLOWING_LAVA, useItemIds); -+ mergeStatBases(stat, Blocks.LIT_PUMPKIN, Blocks.PUMPKIN, useItemIds); -+ mergeStatBases(stat, Blocks.LIT_FURNACE, Blocks.FURNACE, useItemIds); -+ mergeStatBases(stat, Blocks.LIT_REDSTONE_ORE, Blocks.REDSTONE_ORE, useItemIds); -+ mergeStatBases(stat, Blocks.POWERED_REPEATER, Blocks.UNPOWERED_REPEATER, useItemIds); -+ mergeStatBases(stat, Blocks.POWERED_COMPARATOR, Blocks.UNPOWERED_COMPARATOR, useItemIds); -+ mergeStatBases(stat, Blocks.REDSTONE_TORCH, Blocks.UNLIT_REDSTONE_TORCH, useItemIds); -+ mergeStatBases(stat, Blocks.LIT_REDSTONE_LAMP, Blocks.REDSTONE_LAMP, useItemIds); -+ mergeStatBases(stat, Blocks.DOUBLE_STONE_SLAB, Blocks.STONE_SLAB, useItemIds); -+ mergeStatBases(stat, Blocks.DOUBLE_WOODEN_SLAB, Blocks.WOODEN_SLAB, useItemIds); -+ mergeStatBases(stat, Blocks.DOUBLE_STONE_SLAB2, Blocks.STONE_SLAB2, useItemIds); -+ mergeStatBases(stat, Blocks.GRASS, Blocks.DIRT, useItemIds); -+ mergeStatBases(stat, Blocks.FARMLAND, Blocks.DIRT, useItemIds); - } - -- private static void mergeStatBases(StatBase[] statBaseIn, Block block1, Block block2) -+ private static void mergeStatBases(StatBase[] statBaseIn, Block block1, Block block2, boolean useItemIds) - { -- int i = Block.getIdFromBlock(block1); -- int j = Block.getIdFromBlock(block2); -+ int i; -+ int j; -+ if (useItemIds) { -+ i = Item.getIdFromItem(Item.getItemFromBlock(block1)); -+ j = Item.getIdFromItem(Item.getItemFromBlock(block2)); -+ } else { -+ i = Block.getIdFromBlock(block1); -+ j = Block.getIdFromBlock(block2); -+ } - - if (statBaseIn[i] != null && statBaseIn[j] == null) - { -@@ -368,5 +375,37 @@ - public static StatBase getOneShotStat(String statName) - { - return ID_TO_STAT_MAP.get(statName); -+ } -+ -+ @Deprecated //MODDER DO NOT CALL THIS ITS JUST A EVENT CALLBACK FOR FORGE -+ public static void reinit() -+ { -+ ID_TO_STAT_MAP.clear(); -+ BASIC_STATS.clear(); -+ USE_ITEM_STATS.clear(); -+ MINE_BLOCK_STATS.clear(); -+ -+ for (StatBase[] sb : new StatBase[][]{BLOCKS_STATS, CRAFTS_STATS, OBJECT_USE_STATS, OBJECT_BREAK_STATS, OBJECTS_PICKED_UP_STATS, OBJECTS_DROPPED_STATS}) -+ { -+ for (int x = 0; x < sb.length; x++) -+ { -+ if (sb[x] != null) -+ { -+ ALL_STATS.remove(sb[x]); -+ sb[x] = null; -+ } -+ } -+ } -+ List unknown = Lists.newArrayList(ALL_STATS); -+ ALL_STATS.clear(); -+ -+ for (StatBase b : unknown) -+ b.registerStat(); -+ -+ initMiningStats(); -+ initStats(); -+ initItemDepleteStats(); -+ initCraftableStats(); -+ initPickedUpAndDroppedStats(); - } - } diff --git a/patches/minecraft/net/minecraft/stats/StatisticsManagerServer.java.patch b/patches/minecraft/net/minecraft/stats/StatisticsManagerServer.java.patch deleted file mode 100644 index 70a348e65..000000000 --- a/patches/minecraft/net/minecraft/stats/StatisticsManagerServer.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/stats/StatisticsManagerServer.java -+++ after/net/minecraft/stats/StatisticsManagerServer.java -@@ -84,7 +84,7 @@ - - public Map parseJson(String p_150881_1_) - { -- JsonElement jsonelement = new JsonParser().parse(p_150881_1_); -+ JsonElement jsonelement = JsonParser.parseString(p_150881_1_); - - if (!jsonelement.isJsonObject()) - { diff --git a/patches/minecraft/net/minecraft/tileentity/MobSpawnerBaseLogic.java.patch b/patches/minecraft/net/minecraft/tileentity/MobSpawnerBaseLogic.java.patch deleted file mode 100644 index 671665a65..000000000 --- a/patches/minecraft/net/minecraft/tileentity/MobSpawnerBaseLogic.java.patch +++ /dev/null @@ -1,25 +0,0 @@ ---- before/net/minecraft/tileentity/MobSpawnerBaseLogic.java -+++ after/net/minecraft/tileentity/MobSpawnerBaseLogic.java -@@ -140,12 +140,13 @@ - EntityLiving entityliving = entity instanceof EntityLiving ? (EntityLiving)entity : null; - entity.setLocationAndAngles(entity.posX, entity.posY, entity.posZ, world.rand.nextFloat() * 360.0F, 0.0F); - -- if (entityliving == null || entityliving.getCanSpawnHere() && entityliving.isNotColliding()) -+ if (entityliving == null || net.minecraftforge.event.ForgeEventFactory.canEntitySpawnSpawner(entityliving, getSpawnerWorld(), (float)entity.posX, (float)entity.posY, (float)entity.posZ, this)) - { - if (this.spawnData.getNbt().getSize() == 1 - && this.spawnData.getNbt().hasKey("id", 8) - && entity instanceof EntityLiving) - { -+ if (!net.minecraftforge.event.ForgeEventFactory.doSpecialSpawn(entityliving, this.getSpawnerWorld(), (float)entity.posX, (float)entity.posY, (float)entity.posZ, this)) - ((EntityLiving)entity).onInitialSpawn(world.getDifficultyForLocation(new BlockPos(entity)), null); - } - -@@ -326,4 +327,7 @@ - { - return this.prevMobRotation; - } -+ -+ /* ======================================== FORGE START =====================================*/ -+ @Nullable public Entity getSpawnerEntity() { return null; } - } diff --git a/patches/minecraft/net/minecraft/tileentity/TileEntity.java.patch b/patches/minecraft/net/minecraft/tileentity/TileEntity.java.patch deleted file mode 100644 index 8834d2f8d..000000000 --- a/patches/minecraft/net/minecraft/tileentity/TileEntity.java.patch +++ /dev/null @@ -1,285 +0,0 @@ ---- before/net/minecraft/tileentity/TileEntity.java -+++ after/net/minecraft/tileentity/TileEntity.java -@@ -21,7 +21,7 @@ - import org.apache.logging.log4j.LogManager; - import org.apache.logging.log4j.Logger; - --public abstract class TileEntity -+public abstract class TileEntity implements net.minecraftforge.common.capabilities.ICapabilitySerializable - { - private static final Logger LOGGER = LogManager.getLogger(); - private static final RegistryNamespaced < ResourceLocation, Class > REGISTRY = new RegistryNamespaced<>(); -@@ -60,6 +60,8 @@ - public void readFromNBT(NBTTagCompound compound) - { - this.pos = new BlockPos(compound.getInteger("x"), compound.getInteger("y"), compound.getInteger("z")); -+ if (compound.hasKey("ForgeData")) this.customTileData = compound.getCompoundTag("ForgeData"); -+ if (this.capabilities != null && compound.hasKey("ForgeCaps")) this.capabilities.deserializeNBT(compound.getCompoundTag("ForgeCaps")); - } - - public NBTTagCompound writeToNBT(NBTTagCompound compound) -@@ -81,6 +83,8 @@ - compound.setInteger("x", this.pos.getX()); - compound.setInteger("y", this.pos.getY()); - compound.setInteger("z", this.pos.getZ()); -+ if (this.customTileData != null) compound.setTag("ForgeData", this.customTileData); -+ if (this.capabilities != null) compound.setTag("ForgeCaps", this.capabilities.serializeNBT()); - return compound; - } - } -@@ -90,19 +94,22 @@ - { - TileEntity tileentity = null; - String s = compound.getString("id"); -+ Class oclass = null; - - try - { -- Class oclass = REGISTRY.getObject(new ResourceLocation(s)); -+ oclass = REGISTRY.getObject(new ResourceLocation(s)); - - if (oclass != null) - { -- tileentity = oclass.newInstance(); -+ tileentity = oclass.getConstructor().newInstance(); - } - } - catch (Throwable throwable1) - { - LOGGER.error("Failed to create block entity {}", s, throwable1); -+ net.minecraftforge.fml.common.FMLLog.log.error("A TileEntity {}({}) has thrown an exception during loading, its state cannot be restored. Report this to the mod author", -+ s, oclass == null ? null : oclass.getName(), throwable1); - } - - if (tileentity != null) -@@ -115,6 +122,8 @@ - catch (Throwable throwable) - { - LOGGER.error("Failed to load data for block entity {}", s, throwable); -+ net.minecraftforge.fml.common.FMLLog.log.error("A TileEntity {}({}) has thrown an exception during loading, its state cannot be restored. Report this to the mod author", -+ s, oclass.getName(), throwable); - tileentity = null; - } - } -@@ -156,7 +165,6 @@ - } - } - -- @SideOnly(Side.CLIENT) - public double getDistanceSq(double x, double y, double z) - { - double d0 = this.pos.getX() + 0.5 - x; -@@ -249,7 +257,7 @@ - - try - { -- return String.format("ID #%d (%s // %s)", i, Block.getBlockById(i).getTranslationKey(), Block.getBlockById(i).getClass().getCanonicalName()); -+ return String.format("ID #%d (%s // %s // %s)", i, Block.getBlockById(i).getTranslationKey(), Block.getBlockById(i).getClass().getName(), Block.getBlockById(i).getRegistryName()); - } - catch (Throwable throwable) - { -@@ -300,6 +308,204 @@ - - public void mirror(Mirror mirrorIn) - { -+ } -+ -+ // -- BEGIN FORGE PATCHES -- -+ /** -+ * Called when you receive a TileEntityData packet for the location this -+ * TileEntity is currently in. On the client, the NetworkManager will always -+ * be the remote server. On the server, it will be whomever is responsible for -+ * sending the packet. -+ * -+ * @param net The NetworkManager the packet originated from -+ * @param pkt The data packet -+ */ -+ public void onDataPacket(net.minecraft.network.NetworkManager net, net.minecraft.network.play.server.SPacketUpdateTileEntity pkt) -+ { -+ } -+ -+ /** -+ * Called when the chunk's TE update tag, gotten from {@link #getUpdateTag()}, is received on the client. -+ *

-+ * Used to handle this tag in a special way. By default this simply calls {@link #readFromNBT(NBTTagCompound)}. -+ * -+ * @param tag The {@link NBTTagCompound} sent from {@link #getUpdateTag()} -+ */ -+ public void handleUpdateTag(NBTTagCompound tag) -+ { -+ this.readFromNBT(tag); -+ } -+ -+ /** -+ * Called when the chunk this TileEntity is on is Unloaded. -+ */ -+ public void onChunkUnload() -+ { -+ } -+ -+ private boolean isVanilla = getClass().getName().startsWith("net.minecraft."); -+ /** -+ * Called from Chunk.setBlockIDWithMetadata and Chunk.fillChunk, determines if this tile entity should be re-created when the ID, or Metadata changes. -+ * Use with caution as this will leave straggler TileEntities, or create conflicts with other TileEntities if not used properly. -+ * -+ * @param world Current world -+ * @param pos Tile's world position -+ * @param oldState The old ID of the block -+ * @param newState The new ID of the block (May be the same) -+ * @return true forcing the invalidation of the existing TE, false not to invalidate the existing TE -+ */ -+ public boolean shouldRefresh(World world, BlockPos pos, IBlockState oldState, IBlockState newSate) -+ { -+ return isVanilla ? (oldState.getBlock() != newSate.getBlock()) : oldState != newSate; -+ } -+ -+ public boolean shouldRenderInPass(int pass) -+ { -+ return pass == 0; -+ } -+ -+ /** -+ * Sometimes default render bounding box: infinite in scope. Used to control rendering on {@link TileEntitySpecialRenderer}. -+ */ -+ public static final net.minecraft.util.math.AxisAlignedBB INFINITE_EXTENT_AABB = new net.minecraft.util.math.AxisAlignedBB(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY); -+ /** -+ * Return an {@link AxisAlignedBB} that controls the visible scope of a {@link TileEntitySpecialRenderer} associated with this {@link TileEntity} -+ * Defaults to the collision bounding box {@link Block#getCollisionBoundingBoxFromPool(World, int, int, int)} associated with the block -+ * at this location. -+ * -+ * @return an appropriately size {@link AxisAlignedBB} for the {@link TileEntity} -+ */ -+ @SideOnly(Side.CLIENT) -+ public net.minecraft.util.math.AxisAlignedBB getRenderBoundingBox() -+ { -+ net.minecraft.util.math.AxisAlignedBB bb = INFINITE_EXTENT_AABB; -+ Block type = getBlockType(); -+ BlockPos pos = getPos(); -+ if (type == Blocks.ENCHANTING_TABLE) -+ { -+ bb = new net.minecraft.util.math.AxisAlignedBB(pos, pos.add(1, 1, 1)); -+ } -+ else if (type == Blocks.CHEST || type == Blocks.TRAPPED_CHEST) -+ { -+ bb = new net.minecraft.util.math.AxisAlignedBB(pos.add(-1, 0, -1), pos.add(2, 2, 2)); -+ } -+ else if (type == Blocks.STRUCTURE_BLOCK) -+ { -+ bb = INFINITE_EXTENT_AABB; -+ } -+ else if (type != null && type != Blocks.BEACON) -+ { -+ net.minecraft.util.math.AxisAlignedBB cbb = null; -+ try -+ { -+ cbb = world.getBlockState(getPos()).getCollisionBoundingBox(world, pos).offset(pos); -+ } -+ catch (Exception e) -+ { -+ // We have to capture any exceptions that may occur here because BUKKIT servers like to send -+ // the tile entity data BEFORE the chunk data, you know, the OPPOSITE of what vanilla does! -+ // So we can not GARENTEE that the world state is the real state for the block... -+ // So, once again in the long line of US having to accommodate BUKKIT breaking things, -+ // here it is, assume that the TE is only 1 cubic block. Problem with this is that it may -+ // cause the TileEntity renderer to error further down the line! But alas, nothing we can do. -+ cbb = new net.minecraft.util.math.AxisAlignedBB(getPos().add(-1, 0, -1), getPos().add(1, 1, 1)); -+ } -+ if (cbb != null) bb = cbb; -+ } -+ return bb; -+ } -+ -+ /** -+ * Checks if this tile entity knows how to render its 'breaking' overlay effect. -+ * If this returns true, The TileEntitySpecialRenderer will be called again with break progress set. -+ * @return True to re-render tile with breaking effect. -+ */ -+ public boolean canRenderBreaking() -+ { -+ Block block = this.getBlockType(); -+ return (block instanceof net.minecraft.block.BlockChest || -+ block instanceof net.minecraft.block.BlockEnderChest || -+ block instanceof net.minecraft.block.BlockSign || -+ block instanceof net.minecraft.block.BlockSkull); -+ } -+ -+ private NBTTagCompound customTileData; -+ -+ /** -+ * Gets a {@link NBTTagCompound} that can be used to store custom data for this tile entity. -+ * It will be written, and read from disc, so it persists over world saves. -+ * -+ * @return A compound tag for custom data -+ */ -+ public NBTTagCompound getTileData() -+ { -+ if (this.customTileData == null) -+ { -+ this.customTileData = new NBTTagCompound(); -+ } -+ return this.customTileData; -+ } -+ -+ /** -+ * Determines if the player can overwrite the NBT data of this tile entity while they place it using a ItemStack. -+ * Added as a fix for MC-75630 - Exploit with signs and command blocks -+ * @return True to prevent NBT copy, false to allow. -+ */ -+ public boolean restrictNBTCopy() -+ { -+ return this instanceof TileEntityCommandBlock || -+ this instanceof TileEntityMobSpawner || -+ this instanceof TileEntitySign; -+ } -+ -+ -+ /** -+ * Called when this is first added to the world (by {@link World#addTileEntity(TileEntity)}). -+ * Override instead of adding {@code if (firstTick)} stuff in update. -+ */ -+ public void onLoad() -+ { -+ // NOOP -+ } -+ -+ /** -+ * If the TileEntitySpecialRenderer associated with this TileEntity can be batched in with another renderers, and won't access the GL state. -+ * If TileEntity returns true, then TESR should have the same functionality as (and probably extend) the FastTESR class. -+ */ -+ public boolean hasFastRenderer() -+ { -+ return false; -+ } -+ -+ private net.minecraftforge.common.capabilities.CapabilityDispatcher capabilities; -+ public TileEntity() -+ { -+ capabilities = net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(this); -+ } -+ -+ @Override -+ public boolean hasCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable net.minecraft.util.EnumFacing facing) -+ { -+ return capabilities == null ? false : capabilities.hasCapability(capability, facing); -+ } -+ -+ @Override -+ @Nullable -+ public T getCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable net.minecraft.util.EnumFacing facing) -+ { -+ return capabilities == null ? null : capabilities.getCapability(capability, facing); -+ } -+ -+ public void deserializeNBT(NBTTagCompound nbt) -+ { -+ this.readFromNBT(nbt); -+ } -+ -+ public NBTTagCompound serializeNBT() -+ { -+ NBTTagCompound ret = new NBTTagCompound(); -+ this.writeToNBT(ret); -+ return ret; - } - - static diff --git a/patches/minecraft/net/minecraft/tileentity/TileEntityBeacon.java.patch b/patches/minecraft/net/minecraft/tileentity/TileEntityBeacon.java.patch deleted file mode 100644 index d19254e84..000000000 --- a/patches/minecraft/net/minecraft/tileentity/TileEntityBeacon.java.patch +++ /dev/null @@ -1,48 +0,0 @@ ---- before/net/minecraft/tileentity/TileEntityBeacon.java -+++ after/net/minecraft/tileentity/TileEntityBeacon.java -@@ -139,17 +139,23 @@ - { - if (iblockstate.getBlock() != Blocks.STAINED_GLASS_PANE) - { -- if (iblockstate.getLightOpacity() >= 15 && iblockstate.getBlock() != Blocks.BEDROCK) -+ if (iblockstate.getLightOpacity(world, blockpos$mutableblockpos) >= 15 && iblockstate.getBlock() != Blocks.BEDROCK) - { - this.isComplete = false; - this.beamSegments.clear(); - break; - } - -+ float[] customColor = iblockstate.getBlock().getBeaconColorMultiplier(iblockstate, this.world, blockpos$mutableblockpos, getPos()); -+ if (customColor != null) -+ afloat = customColor; -+ else { - tileentitybeacon$beamsegment.incrementHeight(); - continue; -+ } - } - -+ else - afloat = iblockstate.getValue(BlockStainedGlassPane.COLOR).getColorComponentValues(); - } - -@@ -195,7 +201,7 @@ - { - Block block = this.world.getBlockState(new BlockPos(j1, i2, k1)).getBlock(); - -- if (block != Blocks.EMERALD_BLOCK && block != Blocks.GOLD_BLOCK && block != Blocks.DIAMOND_BLOCK && block != Blocks.IRON_BLOCK) -+ if (!block.isBeaconBase(this.world, new BlockPos(j1, i2, k1), getPos())) - { - flag1 = false; - break; -@@ -425,10 +431,7 @@ - @Override - public boolean isItemValidForSlot(int index, ItemStack stack) - { -- return stack.getItem() == Items.EMERALD -- || stack.getItem() == Items.DIAMOND -- || stack.getItem() == Items.GOLD_INGOT -- || stack.getItem() == Items.IRON_INGOT; -+ return stack.getItem() != null && stack.getItem().isBeaconPayment(stack); - } - - @Override diff --git a/patches/minecraft/net/minecraft/tileentity/TileEntityBrewingStand.java.patch b/patches/minecraft/net/minecraft/tileentity/TileEntityBrewingStand.java.patch deleted file mode 100644 index f2c70a8a5..000000000 --- a/patches/minecraft/net/minecraft/tileentity/TileEntityBrewingStand.java.patch +++ /dev/null @@ -1,87 +0,0 @@ ---- before/net/minecraft/tileentity/TileEntityBrewingStand.java -+++ after/net/minecraft/tileentity/TileEntityBrewingStand.java -@@ -158,6 +158,7 @@ - - private boolean canBrew() - { -+ if (1 == 1) return net.minecraftforge.common.brewing.BrewingRecipeRegistry.canBrew(brewingItemStacks, brewingItemStacks.get(3), OUTPUT_SLOTS); // divert to VanillaBrewingRegistry - ItemStack itemstack = this.brewingItemStacks.get(3); - - if (itemstack.isEmpty()) -@@ -186,19 +187,17 @@ - - private void brewPotions() - { -+ if (net.minecraftforge.event.ForgeEventFactory.onPotionAttemptBrew(brewingItemStacks)) return; - ItemStack itemstack = this.brewingItemStacks.get(3); - -- for (int i = 0; i < 3; i++) -- { -- this.brewingItemStacks.set(i, PotionHelper.doReaction(itemstack, this.brewingItemStacks.get(i))); -- } -+ net.minecraftforge.common.brewing.BrewingRecipeRegistry.brewPotions(brewingItemStacks, brewingItemStacks.get(3), OUTPUT_SLOTS); - - itemstack.shrink(1); - BlockPos blockpos = this.getPos(); - -- if (itemstack.getItem().hasContainerItem()) -+ if (itemstack.getItem().hasContainerItem(itemstack)) - { -- ItemStack itemstack1 = new ItemStack(itemstack.getItem().getContainerItem()); -+ ItemStack itemstack1 = itemstack.getItem().getContainerItem(itemstack); - - if (itemstack.isEmpty()) - { -@@ -212,6 +211,7 @@ - - this.brewingItemStacks.set(3, itemstack); - this.world.playEvent(1035, blockpos, 0); -+ net.minecraftforge.event.ForgeEventFactory.onPotionBrewed(brewingItemStacks); - } - - public static void registerFixesBrewingStand(DataFixer fixer) -@@ -312,14 +312,14 @@ - { - if (index == 3) - { -- return PotionHelper.isReagent(stack); -+ return net.minecraftforge.common.brewing.BrewingRecipeRegistry.isValidIngredient(stack); - } - else - { - Item item = stack.getItem(); - return index == 4 - ? item == Items.BLAZE_POWDER -- : (item == Items.POTIONITEM || item == Items.SPLASH_POTION || item == Items.LINGERING_POTION || item == Items.GLASS_BOTTLE) -+ : net.minecraftforge.common.brewing.BrewingRecipeRegistry.isValidInput(stack) - && this.getStackInSlot(index).isEmpty(); - } - } -@@ -386,6 +386,27 @@ - case 1: - this.fuel = value; - } -+ } -+ -+ net.minecraftforge.items.IItemHandler handlerInput = new net.minecraftforge.items.wrapper.SidedInvWrapper(this, net.minecraft.util.EnumFacing.UP); -+ net.minecraftforge.items.IItemHandler handlerOutput = new net.minecraftforge.items.wrapper.SidedInvWrapper(this, net.minecraft.util.EnumFacing.DOWN); -+ net.minecraftforge.items.IItemHandler handlerSides = new net.minecraftforge.items.wrapper.SidedInvWrapper(this, net.minecraft.util.EnumFacing.NORTH); -+ -+ @SuppressWarnings("unchecked") -+ @Override -+ @javax.annotation.Nullable -+ public T getCapability(net.minecraftforge.common.capabilities.Capability capability, @javax.annotation.Nullable net.minecraft.util.EnumFacing facing) -+ { -+ if (facing != null && capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) -+ { -+ if (facing == EnumFacing.UP) -+ return (T) handlerInput; -+ else if (facing == EnumFacing.DOWN) -+ return (T) handlerOutput; -+ else -+ return (T) handlerSides; -+ } -+ return super.getCapability(capability, facing); - } - - @Override diff --git a/patches/minecraft/net/minecraft/tileentity/TileEntityChest.java.patch b/patches/minecraft/net/minecraft/tileentity/TileEntityChest.java.patch deleted file mode 100644 index a19024f8f..000000000 --- a/patches/minecraft/net/minecraft/tileentity/TileEntityChest.java.patch +++ /dev/null @@ -1,47 +0,0 @@ ---- before/net/minecraft/tileentity/TileEntityChest.java -+++ after/net/minecraft/tileentity/TileEntityChest.java -@@ -123,6 +123,7 @@ - { - super.updateContainingBlockInfo(); - this.adjacentChestChecked = false; -+ doubleChestHandler = null; - } - - @SuppressWarnings("incomplete-switch") -@@ -174,6 +175,7 @@ - { - if (!this.adjacentChestChecked) - { -+ if (this.world == null || !this.world.isAreaLoaded(this.pos, 1)) return; // Forge: prevent loading unloaded chunks when checking neighbors - this.adjacentChestChecked = true; - this.adjacentChestXNeg = this.getAdjacentChest(EnumFacing.WEST); - this.adjacentChestXPos = this.getAdjacentChest(EnumFacing.EAST); -@@ -365,6 +367,28 @@ - this.world.notifyNeighborsOfStateChange(this.pos.down(), this.getBlockType(), false); - } - } -+ } -+ -+ public net.minecraftforge.items.VanillaDoubleChestItemHandler doubleChestHandler; -+ -+ @SuppressWarnings("unchecked") -+ @Override -+ @Nullable -+ public T getCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable net.minecraft.util.EnumFacing facing) -+ { -+ if (capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) -+ { -+ if(doubleChestHandler == null || doubleChestHandler.needsRefresh()) -+ doubleChestHandler = net.minecraftforge.items.VanillaDoubleChestItemHandler.get(this); -+ if (doubleChestHandler != null && doubleChestHandler != net.minecraftforge.items.VanillaDoubleChestItemHandler.NO_ADJACENT_CHESTS_INSTANCE) -+ return (T) doubleChestHandler; -+ } -+ return super.getCapability(capability, facing); -+ } -+ -+ public net.minecraftforge.items.IItemHandler getSingleChestHandler() -+ { -+ return super.getCapability(net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null); - } - - @Override diff --git a/patches/minecraft/net/minecraft/tileentity/TileEntityFurnace.java.patch b/patches/minecraft/net/minecraft/tileentity/TileEntityFurnace.java.patch deleted file mode 100644 index 545984e1c..000000000 --- a/patches/minecraft/net/minecraft/tileentity/TileEntityFurnace.java.patch +++ /dev/null @@ -1,99 +0,0 @@ ---- before/net/minecraft/tileentity/TileEntityFurnace.java -+++ after/net/minecraft/tileentity/TileEntityFurnace.java -@@ -130,9 +130,9 @@ - super.readFromNBT(compound); - this.furnaceItemStacks = NonNullList.withSize(this.getSizeInventory(), ItemStack.EMPTY); - ItemStackHelper.loadAllItems(compound, this.furnaceItemStacks); -- this.furnaceBurnTime = compound.getShort("BurnTime"); -- this.cookTime = compound.getShort("CookTime"); -- this.totalCookTime = compound.getShort("CookTimeTotal"); -+ this.furnaceBurnTime = compound.getInteger("BurnTime"); -+ this.cookTime = compound.getInteger("CookTime"); -+ this.totalCookTime = compound.getInteger("CookTimeTotal"); - this.currentItemBurnTime = getItemBurnTime(this.furnaceItemStacks.get(1)); - - if (compound.hasKey("CustomName", 8)) -@@ -145,9 +145,9 @@ - public NBTTagCompound writeToNBT(NBTTagCompound compound) - { - super.writeToNBT(compound); -- compound.setShort("BurnTime", (short)this.furnaceBurnTime); -- compound.setShort("CookTime", (short)this.cookTime); -- compound.setShort("CookTimeTotal", (short)this.totalCookTime); -+ compound.setInteger("BurnTime", (short)this.furnaceBurnTime); -+ compound.setInteger("CookTime", (short)this.cookTime); -+ compound.setInteger("CookTimeTotal", (short)this.totalCookTime); - ItemStackHelper.saveAllItems(compound, this.furnaceItemStacks); - - if (this.hasCustomName()) -@@ -208,8 +208,8 @@ - - if (itemstack.isEmpty()) - { -- Item item1 = item.getContainerItem(); -- this.furnaceItemStacks.set(1, item1 == null ? ItemStack.EMPTY : new ItemStack(item1)); -+ ItemStack item1 = item.getContainerItem(itemstack); -+ this.furnaceItemStacks.set(1, item1); - } - } - } -@@ -281,11 +281,13 @@ - { - return false; - } -+ else if (itemstack1.getCount() + itemstack.getCount() <= this.getInventoryStackLimit() && itemstack1.getCount() + itemstack.getCount() <= itemstack1.getMaxStackSize()) // Forge fix: make furnace respect stack sizes in furnace recipes -+ { -+ return true; -+ } - else - { -- return itemstack1.getCount() < this.getInventoryStackLimit() && itemstack1.getCount() < itemstack1.getMaxStackSize() -- ? true -- : itemstack1.getCount() < itemstack.getMaxStackSize(); -+ return itemstack1.getCount() + itemstack.getCount() <= itemstack.getMaxStackSize(); // Forge fix: make furnace respect stack sizes in furnace recipes - } - } - } -@@ -305,7 +307,7 @@ - } - else if (itemstack2.getItem() == itemstack1.getItem()) - { -- itemstack2.grow(1); -+ itemstack2.grow(itemstack1.getCount()); - } - - if (itemstack.getItem() == Item.getItemFromBlock(Blocks.SPONGE) -@@ -328,6 +330,8 @@ - } - else - { -+ int burnTime = net.minecraftforge.event.ForgeEventFactory.getItemBurnTime(stack); -+ if (burnTime >= 0) return burnTime; - Item item = stack.getItem(); - - if (item == Item.getItemFromBlock(Blocks.WOODEN_SLAB)) -@@ -549,5 +553,24 @@ - public void clear() - { - this.furnaceItemStacks.clear(); -+ } -+ -+ net.minecraftforge.items.IItemHandler handlerTop = new net.minecraftforge.items.wrapper.SidedInvWrapper(this, net.minecraft.util.EnumFacing.UP); -+ net.minecraftforge.items.IItemHandler handlerBottom = new net.minecraftforge.items.wrapper.SidedInvWrapper(this, net.minecraft.util.EnumFacing.DOWN); -+ net.minecraftforge.items.IItemHandler handlerSide = new net.minecraftforge.items.wrapper.SidedInvWrapper(this, net.minecraft.util.EnumFacing.WEST); -+ -+ @SuppressWarnings("unchecked") -+ @Override -+ @javax.annotation.Nullable -+ public T getCapability(net.minecraftforge.common.capabilities.Capability capability, @javax.annotation.Nullable net.minecraft.util.EnumFacing facing) -+ { -+ if (facing != null && capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) -+ if (facing == EnumFacing.DOWN) -+ return (T) handlerBottom; -+ else if (facing == EnumFacing.UP) -+ return (T) handlerTop; -+ else -+ return (T) handlerSide; -+ return super.getCapability(capability, facing); - } - } diff --git a/patches/minecraft/net/minecraft/tileentity/TileEntityHopper.java.patch b/patches/minecraft/net/minecraft/tileentity/TileEntityHopper.java.patch deleted file mode 100644 index 8bfa7d154..000000000 --- a/patches/minecraft/net/minecraft/tileentity/TileEntityHopper.java.patch +++ /dev/null @@ -1,62 +0,0 @@ ---- before/net/minecraft/tileentity/TileEntityHopper.java -+++ after/net/minecraft/tileentity/TileEntityHopper.java -@@ -88,7 +88,8 @@ - public ItemStack decrStackSize(int index, int count) - { - this.fillWithLoot(null); -- return ItemStackHelper.getAndSplit(this.getItems(), index, count); -+ ItemStack itemstack = ItemStackHelper.getAndSplit(this.getItems(), index, count); -+ return itemstack; - } - - @Override -@@ -199,6 +200,7 @@ - - private boolean transferItemsOut() - { -+ if (net.minecraftforge.items.VanillaInventoryCodeHooks.insertHook(this)) { return true; } - IInventory iinventory = this.getInventoryForHopperTransfer(); - - if (iinventory == null) -@@ -305,6 +307,8 @@ - - public static boolean pullItems(IHopper hopper) - { -+ Boolean ret = net.minecraftforge.items.VanillaInventoryCodeHooks.extractHook(hopper); -+ if (ret != null) return ret; - IInventory iinventory = getSourceInventory(hopper); - - if (iinventory != null) -@@ -406,6 +410,12 @@ - } - } - -+ -+ protected net.minecraftforge.items.IItemHandler createUnSidedHandler() -+ { -+ return new net.minecraftforge.items.VanillaHopperItemHandler(this); -+ } -+ - public static ItemStack putStackInInventoryAllSlots(IInventory source, IInventory destination, ItemStack stack, @Nullable EnumFacing direction) - { - if (destination instanceof ISidedInventory && direction != null) -@@ -530,9 +540,10 @@ - int j = MathHelper.floor(y); - int k = MathHelper.floor(z); - BlockPos blockpos = new BlockPos(i, j, k); -- Block block = worldIn.getBlockState(blockpos).getBlock(); -+ net.minecraft.block.state.IBlockState state = worldIn.getBlockState(blockpos); -+ Block block = state.getBlock(); - -- if (block.hasTileEntity()) -+ if (block.hasTileEntity(state)) - { - TileEntity tileentity = worldIn.getTileEntity(blockpos); - -@@ -631,4 +642,6 @@ - { - return this.inventory; - } -+ -+ public long getLastUpdateTime() { return tickedGameTime; } // Forge - } diff --git a/patches/minecraft/net/minecraft/tileentity/TileEntityLockable.java.patch b/patches/minecraft/net/minecraft/tileentity/TileEntityLockable.java.patch deleted file mode 100644 index ff17b6e47..000000000 --- a/patches/minecraft/net/minecraft/tileentity/TileEntityLockable.java.patch +++ /dev/null @@ -1,30 +0,0 @@ ---- before/net/minecraft/tileentity/TileEntityLockable.java -+++ after/net/minecraft/tileentity/TileEntityLockable.java -@@ -54,4 +54,27 @@ - { - return (ITextComponent)(this.hasCustomName() ? new TextComponentString(this.getName()) : new TextComponentTranslation(this.getName())); - } -+ -+ private net.minecraftforge.items.IItemHandler itemHandler; -+ -+ protected net.minecraftforge.items.IItemHandler createUnSidedHandler() -+ { -+ return new net.minecraftforge.items.wrapper.InvWrapper(this); -+ } -+ -+ @SuppressWarnings("unchecked") -+ @Override -+ @javax.annotation.Nullable -+ public T getCapability(net.minecraftforge.common.capabilities.Capability capability, @javax.annotation.Nullable net.minecraft.util.EnumFacing facing) -+ { -+ if (capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) -+ return (T) (itemHandler == null ? (itemHandler = createUnSidedHandler()) : itemHandler); -+ return super.getCapability(capability, facing); -+ } -+ -+ @Override -+ public boolean hasCapability(net.minecraftforge.common.capabilities.Capability capability, @javax.annotation.Nullable net.minecraft.util.EnumFacing facing) -+ { -+ return capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY || super.hasCapability(capability, facing); -+ } - } diff --git a/patches/minecraft/net/minecraft/tileentity/TileEntityLockableLoot.java.patch b/patches/minecraft/net/minecraft/tileentity/TileEntityLockableLoot.java.patch deleted file mode 100644 index 7ae0407ff..000000000 --- a/patches/minecraft/net/minecraft/tileentity/TileEntityLockableLoot.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/tileentity/TileEntityLockableLoot.java -+++ after/net/minecraft/tileentity/TileEntityLockableLoot.java -@@ -73,7 +73,7 @@ - - if (player != null) - { -- lootcontext$builder.withLuck(player.getLuck()); -+ lootcontext$builder.withLuck(player.getLuck()).withPlayer(player); // Forge: add player to LootContext - } - - loottable.fillInventory(this, random, lootcontext$builder.build()); diff --git a/patches/minecraft/net/minecraft/tileentity/TileEntityNote.java.patch b/patches/minecraft/net/minecraft/tileentity/TileEntityNote.java.patch deleted file mode 100644 index b90632bf3..000000000 --- a/patches/minecraft/net/minecraft/tileentity/TileEntityNote.java.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- before/net/minecraft/tileentity/TileEntityNote.java -+++ after/net/minecraft/tileentity/TileEntityNote.java -@@ -34,7 +34,9 @@ - - public void changePitch() - { -+ byte old = note; - this.note = (byte)((this.note + 1) % 25); -+ if (!net.minecraftforge.common.ForgeHooks.onNoteChange(this, old)) return; - this.markDirty(); - } - diff --git a/patches/minecraft/net/minecraft/tileentity/TileEntityPiston.java.patch b/patches/minecraft/net/minecraft/tileentity/TileEntityPiston.java.patch deleted file mode 100644 index 22979fa2b..000000000 --- a/patches/minecraft/net/minecraft/tileentity/TileEntityPiston.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/tileentity/TileEntityPiston.java -+++ after/net/minecraft/tileentity/TileEntityPiston.java -@@ -162,7 +162,7 @@ - - if (!list1.isEmpty()) - { -- boolean flag = this.pistonState.getBlock() == Blocks.SLIME_BLOCK; -+ boolean flag = this.pistonState.getBlock().isStickyBlock(this.pistonState); - - for (int i = 0; i < list1.size(); i++) - { diff --git a/patches/minecraft/net/minecraft/tileentity/TileEntityShulkerBox.java.patch b/patches/minecraft/net/minecraft/tileentity/TileEntityShulkerBox.java.patch deleted file mode 100644 index a1eeaa170..000000000 --- a/patches/minecraft/net/minecraft/tileentity/TileEntityShulkerBox.java.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- before/net/minecraft/tileentity/TileEntityShulkerBox.java -+++ after/net/minecraft/tileentity/TileEntityShulkerBox.java -@@ -461,4 +461,9 @@ - OPENED, - CLOSING; - } -+ -+ protected net.minecraftforge.items.IItemHandler createUnSidedHandler() -+ { -+ return new net.minecraftforge.items.wrapper.SidedInvWrapper(this, EnumFacing.UP); -+ } - } diff --git a/patches/minecraft/net/minecraft/tileentity/TileEntitySign.java.patch b/patches/minecraft/net/minecraft/tileentity/TileEntitySign.java.patch deleted file mode 100644 index e6c9f32c3..000000000 --- a/patches/minecraft/net/minecraft/tileentity/TileEntitySign.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/tileentity/TileEntitySign.java -+++ after/net/minecraft/tileentity/TileEntitySign.java -@@ -67,7 +67,7 @@ - @Override - public boolean canUseCommand(int permLevel, String commandName) - { -- return true; -+ return permLevel <= 2; //Forge: Fixes MC-75630 - Exploit with signs and command blocks - } - @Override - public BlockPos getPosition() diff --git a/patches/minecraft/net/minecraft/util/ActionResult.java.patch b/patches/minecraft/net/minecraft/util/ActionResult.java.patch deleted file mode 100644 index ed9539146..000000000 --- a/patches/minecraft/net/minecraft/util/ActionResult.java.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- before/net/minecraft/util/ActionResult.java -+++ after/net/minecraft/util/ActionResult.java -@@ -20,4 +20,10 @@ - { - return this.result; - } -+ -+ //Just a generic helper function to make typecasing easier... -+ public static ActionResult newResult(EnumActionResult result, T value) -+ { -+ return new ActionResult(result, value); -+ } - } diff --git a/patches/minecraft/net/minecraft/util/BlockRenderLayer.java.patch b/patches/minecraft/net/minecraft/util/BlockRenderLayer.java.patch deleted file mode 100644 index 0a088790b..000000000 --- a/patches/minecraft/net/minecraft/util/BlockRenderLayer.java.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- before/net/minecraft/util/BlockRenderLayer.java -+++ after/net/minecraft/util/BlockRenderLayer.java -@@ -1,9 +1,5 @@ - package net.minecraft.util; - --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; -- --@SideOnly(Side.CLIENT) - public enum BlockRenderLayer - { - SOLID("Solid"), diff --git a/patches/minecraft/net/minecraft/util/ChatAllowedCharacters.java.patch b/patches/minecraft/net/minecraft/util/ChatAllowedCharacters.java.patch deleted file mode 100644 index 71550fea4..000000000 --- a/patches/minecraft/net/minecraft/util/ChatAllowedCharacters.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- before/net/minecraft/util/ChatAllowedCharacters.java -+++ after/net/minecraft/util/ChatAllowedCharacters.java -@@ -31,6 +31,7 @@ - - static - { -+ if (System.getProperty("io.netty.leakDetection.level") == null) // Forge: allow level to be manually specified - ResourceLeakDetector.setLevel(NETTY_LEAK_DETECTION); - } - } diff --git a/patches/minecraft/net/minecraft/util/ClassInheritanceMultiMap.java.patch b/patches/minecraft/net/minecraft/util/ClassInheritanceMultiMap.java.patch deleted file mode 100644 index 57aaf6b5e..000000000 --- a/patches/minecraft/net/minecraft/util/ClassInheritanceMultiMap.java.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- before/net/minecraft/util/ClassInheritanceMultiMap.java -+++ after/net/minecraft/util/ClassInheritanceMultiMap.java -@@ -13,7 +13,8 @@ - - public class ClassInheritanceMultiMap extends AbstractSet - { -- private static final Set < Class> ALL_KNOWN = Sets.newHashSet(); -+ // Forge: Use concurrent collection to allow creating chunks from multiple threads safely -+ private static final Set < Class> ALL_KNOWN = java.util.Collections.newSetFromMap(new java.util.concurrent.ConcurrentHashMap<>()); - private final Map < Class, List> map = Maps.newHashMap(); - private final Set < Class> knownKeys = Sets.newIdentityHashSet(); - private final Class baseClass; diff --git a/patches/minecraft/net/minecraft/util/EnumFacing.java.patch b/patches/minecraft/net/minecraft/util/EnumFacing.java.patch deleted file mode 100644 index 231311aa7..000000000 --- a/patches/minecraft/net/minecraft/util/EnumFacing.java.patch +++ /dev/null @@ -1,67 +0,0 @@ ---- before/net/minecraft/util/EnumFacing.java -+++ after/net/minecraft/util/EnumFacing.java -@@ -12,8 +12,6 @@ - import net.minecraft.util.math.BlockPos; - import net.minecraft.util.math.MathHelper; - import net.minecraft.util.math.Vec3i; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; - - public enum EnumFacing implements IStringSerializable - { -@@ -74,7 +72,6 @@ - return byIndex(this.opposite); - } - -- @SideOnly(Side.CLIENT) - public EnumFacing rotateAround(EnumFacing.Axis axis) - { - switch (axis) -@@ -125,7 +122,6 @@ - } - } - -- @SideOnly(Side.CLIENT) - private EnumFacing rotateX() - { - switch (this) -@@ -145,7 +141,6 @@ - } - } - -- @SideOnly(Side.CLIENT) - private EnumFacing rotateZ() - { - switch (this) -@@ -207,7 +202,6 @@ - } - - @Nullable -- @SideOnly(Side.CLIENT) - public static EnumFacing byName(String name) - { - return name == null ? null : NAME_LOOKUP.get(name.toLowerCase(Locale.ROOT)); -@@ -238,7 +232,6 @@ - return values()[rand.nextInt(values().length)]; - } - -- @SideOnly(Side.CLIENT) - public static EnumFacing getFacingFromVector(float x, float y, float z) - { - EnumFacing enumfacing = NORTH; -@@ -306,7 +299,6 @@ - return placer.getHorizontalFacing().getOpposite(); - } - -- @SideOnly(Side.CLIENT) - public Vec3i getDirectionVec() - { - return this.directionVec; -@@ -343,7 +335,6 @@ - } - - @Nullable -- @SideOnly(Side.CLIENT) - public static EnumFacing.Axis byName(String name) - { - return name == null ? null : NAME_LOOKUP.get(name.toLowerCase(Locale.ROOT)); diff --git a/patches/minecraft/net/minecraft/util/IntIdentityHashBiMap.java.patch b/patches/minecraft/net/minecraft/util/IntIdentityHashBiMap.java.patch deleted file mode 100644 index b318cc51a..000000000 --- a/patches/minecraft/net/minecraft/util/IntIdentityHashBiMap.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- before/net/minecraft/util/IntIdentityHashBiMap.java -+++ after/net/minecraft/util/IntIdentityHashBiMap.java -@@ -169,7 +169,6 @@ - return Iterators.filter(Iterators.forArray(this.byId), Predicates.notNull()); - } - -- @SideOnly(Side.CLIENT) - public void clear() - { - Arrays.fill(this.values, null); diff --git a/patches/minecraft/net/minecraft/util/MouseHelper.java.patch b/patches/minecraft/net/minecraft/util/MouseHelper.java.patch deleted file mode 100644 index 8fbcf56fb..000000000 --- a/patches/minecraft/net/minecraft/util/MouseHelper.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- before/net/minecraft/util/MouseHelper.java -+++ after/net/minecraft/util/MouseHelper.java -@@ -13,6 +13,7 @@ - - public void grabMouseCursor() - { -+ if (Boolean.parseBoolean(System.getProperty("fml.noGrab","false"))) return; - Mouse.setGrabbed(true); - this.deltaX = 0; - this.deltaY = 0; diff --git a/patches/minecraft/net/minecraft/util/ScreenShotHelper.java.patch b/patches/minecraft/net/minecraft/util/ScreenShotHelper.java.patch deleted file mode 100644 index 181fba5f6..000000000 --- a/patches/minecraft/net/minecraft/util/ScreenShotHelper.java.patch +++ /dev/null @@ -1,17 +0,0 @@ ---- before/net/minecraft/util/ScreenShotHelper.java -+++ after/net/minecraft/util/ScreenShotHelper.java -@@ -54,10 +54,14 @@ - file2 = new File(file1, screenshotName); - } - -+ file2 = file2.getCanonicalFile(); // FORGE: Fix errors on Windows with paths that include \.\ -+ net.minecraftforge.client.event.ScreenshotEvent event = net.minecraftforge.client.ForgeHooksClient.onScreenshot(bufferedimage, file2); -+ if (event.isCanceled()) return event.getCancelMessage(); else file2 = event.getScreenshotFile(); - ImageIO.write(bufferedimage, "png", file2); - ITextComponent itextcomponent = new TextComponentString(file2.getName()); - itextcomponent.getStyle().setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_FILE, file2.getAbsolutePath())); - itextcomponent.getStyle().setUnderlined(true); -+ if (event.getResultMessage() != null) return event.getResultMessage(); - return new TextComponentTranslation("screenshot.success", itextcomponent); - } - catch (Exception exception) diff --git a/patches/minecraft/net/minecraft/util/ServerRecipeBookHelper.java.patch b/patches/minecraft/net/minecraft/util/ServerRecipeBookHelper.java.patch deleted file mode 100644 index 0061abcf5..000000000 --- a/patches/minecraft/net/minecraft/util/ServerRecipeBookHelper.java.patch +++ /dev/null @@ -1,30 +0,0 @@ ---- before/net/minecraft/util/ServerRecipeBookHelper.java -+++ after/net/minecraft/util/ServerRecipeBookHelper.java -@@ -54,6 +54,11 @@ - this.field_194335_f = ((ContainerPlayer)container).craftResult; - this.field_194336_g = ((ContainerPlayer)container).craftMatrix; - } -+ else if (container instanceof net.minecraftforge.common.crafting.IRecipeContainer) -+ { -+ this.field_194335_f = ((net.minecraftforge.common.crafting.IRecipeContainer)container).getCraftResult(); -+ this.field_194336_g = ((net.minecraftforge.common.crafting.IRecipeContainer)container).getCraftMatrix(); -+ } - - if (this.field_194335_f != null && this.field_194336_g != null) - { -@@ -196,11 +201,11 @@ - int i = this.field_194336_g.getWidth(); - int j = this.field_194336_g.getHeight(); - -- if (this.field_194333_d instanceof ShapedRecipes) -+ if (this.field_194333_d instanceof net.minecraftforge.common.crafting.IShapedRecipe) - { -- ShapedRecipes shapedrecipes = (ShapedRecipes)this.field_194333_d; -- i = shapedrecipes.getWidth(); -- j = shapedrecipes.getHeight(); -+ net.minecraftforge.common.crafting.IShapedRecipe shapedrecipes = (net.minecraftforge.common.crafting.IShapedRecipe)this.field_194333_d; -+ i = shapedrecipes.getRecipeWidth(); -+ j = shapedrecipes.getRecipeHeight(); - } - - int j1 = 1; diff --git a/patches/minecraft/net/minecraft/util/Session.java.patch b/patches/minecraft/net/minecraft/util/Session.java.patch deleted file mode 100644 index 63fd5d2e5..000000000 --- a/patches/minecraft/net/minecraft/util/Session.java.patch +++ /dev/null @@ -1,59 +0,0 @@ ---- before/net/minecraft/util/Session.java -+++ after/net/minecraft/util/Session.java -@@ -17,9 +17,25 @@ - private final String playerID; - private final String token; - private final Session.Type sessionType; -+ /** Forge: Cache of the local session's GameProfile properties. */ -+ private com.mojang.authlib.properties.PropertyMap properties; - - public Session(String usernameIn, String playerIDIn, String tokenIn, String sessionTypeIn) - { -+ if (usernameIn == null || usernameIn.isEmpty()) -+ { -+ usernameIn = "MissingName"; -+ playerIDIn = tokenIn = "NotValid"; -+ org.apache.logging.log4j.Logger logger = net.minecraftforge.fml.common.FMLLog.log; -+ logger.log(org.apache.logging.log4j.Level.WARN, "========================================================="); -+ logger.log(org.apache.logging.log4j.Level.WARN, "WARNING!! the username was not set for this session, typically"); -+ logger.log(org.apache.logging.log4j.Level.WARN, "this means you installed Forge incorrectly. We have set your"); -+ logger.log(org.apache.logging.log4j.Level.WARN, "name to \"MissingName\" and your session to nothing. Please"); -+ logger.log(org.apache.logging.log4j.Level.WARN, "check your installation and post a console log from the launcher"); -+ logger.log(org.apache.logging.log4j.Level.WARN, "when asking for help!"); -+ logger.log(org.apache.logging.log4j.Level.WARN, "========================================================="); -+ } -+ - this.username = usernameIn; - this.playerID = playerIDIn; - this.token = tokenIn; -@@ -51,13 +67,28 @@ - try - { - UUID uuid = UUIDTypeAdapter.fromString(this.getPlayerID()); -- return new GameProfile(uuid, this.getUsername()); -+ GameProfile ret = new GameProfile(uuid, this.getUsername()); //Forge: Adds cached GameProfile properties to returned GameProfile. -+ if (properties != null) ret.getProperties().putAll(properties); // Helps to cut down on calls to the session service, -+ return ret; // which helps to fix MC-52974. - } - catch (IllegalArgumentException illegalargumentexception) - { -- return new GameProfile(null, this.getUsername()); -+ return new GameProfile(net.minecraft.entity.player.EntityPlayer.getUUID(new GameProfile((UUID)null, this.getUsername())), this.getUsername()); - } - } -+ -+ /* ======================================== FORGE START ===================================== */ -+ //For internal use only. Modders should never need to use this. -+ public void setProperties(com.mojang.authlib.properties.PropertyMap properties) -+ { -+ if(this.properties == null) this.properties = properties; -+ } -+ -+ public boolean hasCachedProperties() -+ { -+ return properties != null; -+ } -+ /* ========================================= FORGE END ====================================== */ - - @SideOnly(Side.CLIENT) - public static enum Type diff --git a/patches/minecraft/net/minecraft/util/SoundEvent.java.patch b/patches/minecraft/net/minecraft/util/SoundEvent.java.patch deleted file mode 100644 index 07ac09cd5..000000000 --- a/patches/minecraft/net/minecraft/util/SoundEvent.java.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- before/net/minecraft/util/SoundEvent.java -+++ after/net/minecraft/util/SoundEvent.java -@@ -4,9 +4,9 @@ - import net.minecraftforge.fml.relauncher.Side; - import net.minecraftforge.fml.relauncher.SideOnly; - --public class SoundEvent -+public class SoundEvent extends net.minecraftforge.registries.IForgeRegistryEntry.Impl - { -- public static final RegistryNamespaced REGISTRY = new RegistryNamespaced<>(); -+ public static final RegistryNamespaced REGISTRY = net.minecraftforge.registries.GameData.getWrapper(SoundEvent.class); - private final ResourceLocation soundName; - private static int soundEventId; - diff --git a/patches/minecraft/net/minecraft/util/TabCompleter.java.patch b/patches/minecraft/net/minecraft/util/TabCompleter.java.patch deleted file mode 100644 index 190f692d7..000000000 --- a/patches/minecraft/net/minecraft/util/TabCompleter.java.patch +++ /dev/null @@ -1,39 +0,0 @@ ---- before/net/minecraft/util/TabCompleter.java -+++ after/net/minecraft/util/TabCompleter.java -@@ -56,13 +56,14 @@ - this.textField.deleteFromCursor(i - this.textField.getCursorPosition()); - } - -- this.textField.writeText(this.completions.get(this.completionIdx++)); -+ this.textField.writeText(net.minecraft.util.text.TextFormatting.getTextWithoutFormattingCodes(this.completions.get(this.completionIdx++))); - } - - private void requestCompletions(String prefix) - { - if (prefix.length() >= 1) - { -+ net.minecraftforge.client.ClientCommandHandler.instance.autoComplete(prefix); - Minecraft.getMinecraft().player.connection.sendPacket(new CPacketTabComplete(prefix, this.getTargetBlockPos(), this.hasTargetBlock)); - this.requestedCompletions = true; - } -@@ -78,6 +79,12 @@ - this.didComplete = false; - this.completions.clear(); - -+ String[] complete = net.minecraftforge.client.ClientCommandHandler.instance.latestAutoComplete; -+ if (complete != null) -+ { -+ newCompl = com.google.common.collect.ObjectArrays.concat(complete, newCompl, String.class); -+ } -+ - for (String s : newCompl) - { - if (!s.isEmpty()) -@@ -88,6 +95,7 @@ - - String s1 = this.textField.getText().substring(this.textField.getNthWordFromPosWS(-1, this.textField.getCursorPosition(), false)); - String s2 = org.apache.commons.lang3.StringUtils.getCommonPrefix(newCompl); -+ s2 = net.minecraft.util.text.TextFormatting.getTextWithoutFormattingCodes(s2); - - if (!s2.isEmpty() && !s1.equalsIgnoreCase(s2)) - { diff --git a/patches/minecraft/net/minecraft/util/datafix/DataFixesManager.java.patch b/patches/minecraft/net/minecraft/util/datafix/DataFixesManager.java.patch deleted file mode 100644 index 15bb522de..000000000 --- a/patches/minecraft/net/minecraft/util/datafix/DataFixesManager.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- before/net/minecraft/util/datafix/DataFixesManager.java -+++ after/net/minecraft/util/datafix/DataFixesManager.java -@@ -165,6 +165,7 @@ - public static DataFixer createFixer() - { - DataFixer datafixer = new DataFixer(1343); -+ datafixer = new net.minecraftforge.common.util.CompoundDataFixer(datafixer); - WorldInfo.registerFixes(datafixer); - EntityPlayerMP.registerFixesPlayerMP(datafixer); - EntityPlayer.registerFixesPlayer(datafixer); diff --git a/patches/minecraft/net/minecraft/util/math/ChunkPos.java.patch b/patches/minecraft/net/minecraft/util/math/ChunkPos.java.patch deleted file mode 100644 index d2e359c04..000000000 --- a/patches/minecraft/net/minecraft/util/math/ChunkPos.java.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- before/net/minecraft/util/math/ChunkPos.java -+++ after/net/minecraft/util/math/ChunkPos.java -@@ -24,6 +24,16 @@ - return x & 4294967295L | (z & 4294967295L) << 32; - } - -+ public static int getX(long key) -+ { -+ return (int) (key & 0xFFFFFFFFL); -+ } -+ -+ public static int getZ(long key) -+ { -+ return (int) ((key >>> 32) & 0xFFFFFFFFL); -+ } -+ - @Override - public int hashCode() - { diff --git a/patches/minecraft/net/minecraft/util/math/RayTraceResult.java.patch b/patches/minecraft/net/minecraft/util/math/RayTraceResult.java.patch deleted file mode 100644 index 9f6304985..000000000 --- a/patches/minecraft/net/minecraft/util/math/RayTraceResult.java.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- before/net/minecraft/util/math/RayTraceResult.java -+++ after/net/minecraft/util/math/RayTraceResult.java -@@ -5,6 +5,12 @@ - - public class RayTraceResult - { -+ /** Used to determine what sub-segment is hit */ -+ public int subHit = -1; -+ -+ /** Used to add extra hit info */ -+ public Object hitInfo = null; -+ - private BlockPos blockPos; - public RayTraceResult.Type typeOfHit; - public EnumFacing sideHit; diff --git a/patches/minecraft/net/minecraft/util/math/Vec2f.java.patch b/patches/minecraft/net/minecraft/util/math/Vec2f.java.patch deleted file mode 100644 index e18d928d8..000000000 --- a/patches/minecraft/net/minecraft/util/math/Vec2f.java.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- before/net/minecraft/util/math/Vec2f.java -+++ after/net/minecraft/util/math/Vec2f.java -@@ -1,9 +1,5 @@ - package net.minecraft.util.math; - --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; -- --@SideOnly(Side.CLIENT) - public class Vec2f - { - public static final Vec2f ZERO = new Vec2f(0.0F, 0.0F); diff --git a/patches/minecraft/net/minecraft/util/math/Vec3d.java.patch b/patches/minecraft/net/minecraft/util/math/Vec3d.java.patch deleted file mode 100644 index 31210a656..000000000 --- a/patches/minecraft/net/minecraft/util/math/Vec3d.java.patch +++ /dev/null @@ -1,42 +0,0 @@ ---- before/net/minecraft/util/math/Vec3d.java -+++ after/net/minecraft/util/math/Vec3d.java -@@ -1,9 +1,6 @@ - package net.minecraft.util.math; - - import javax.annotation.Nullable; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; -- - public class Vec3d - { - public static final Vec3d ZERO = new Vec3d(0.0, 0.0, 0.0); -@@ -58,7 +55,6 @@ - return this.x * vec.x + this.y * vec.y + this.z * vec.z; - } - -- @SideOnly(Side.CLIENT) - public Vec3d crossProduct(Vec3d vec) - { - return new Vec3d( -@@ -124,7 +120,6 @@ - ); - } - -- @SideOnly(Side.CLIENT) - public double lengthSquared() - { - return this.x * this.x + this.y * this.y + this.z * this.z; -@@ -247,13 +242,11 @@ - return new Vec3d(d0, d1, d2); - } - -- @SideOnly(Side.CLIENT) - public static Vec3d fromPitchYaw(Vec2f p_189984_0_) - { - return fromPitchYaw(p_189984_0_.x, p_189984_0_.y); - } - -- @SideOnly(Side.CLIENT) - public static Vec3d fromPitchYaw(float p_189986_0_, float p_189986_1_) - { - float f = MathHelper.cos(-p_189986_1_ * (float)(Math.PI / 180.0) - (float) Math.PI); diff --git a/patches/minecraft/net/minecraft/util/text/ITextComponent.java.patch b/patches/minecraft/net/minecraft/util/text/ITextComponent.java.patch deleted file mode 100644 index 2a3bbc84d..000000000 --- a/patches/minecraft/net/minecraft/util/text/ITextComponent.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- before/net/minecraft/util/text/ITextComponent.java -+++ after/net/minecraft/util/text/ITextComponent.java -@@ -34,7 +34,6 @@ - - String getUnformattedText(); - -- @SideOnly(Side.CLIENT) - String getFormattedText(); - - List getSiblings(); diff --git a/patches/minecraft/net/minecraft/util/text/Style.java.patch b/patches/minecraft/net/minecraft/util/text/Style.java.patch deleted file mode 100644 index e0f6f24ed..000000000 --- a/patches/minecraft/net/minecraft/util/text/Style.java.patch +++ /dev/null @@ -1,18 +0,0 @@ ---- before/net/minecraft/util/text/Style.java -+++ after/net/minecraft/util/text/Style.java -@@ -138,7 +138,6 @@ - { - return this; - } -- @SideOnly(Side.CLIENT) - @Override - public String getFormattingCode() - { -@@ -268,7 +267,6 @@ - return this; - } - -- @SideOnly(Side.CLIENT) - public String getFormattingCode() - { - if (this.isEmpty()) diff --git a/patches/minecraft/net/minecraft/util/text/TextComponentBase.java.patch b/patches/minecraft/net/minecraft/util/text/TextComponentBase.java.patch deleted file mode 100644 index 2070921af..000000000 --- a/patches/minecraft/net/minecraft/util/text/TextComponentBase.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- before/net/minecraft/util/text/TextComponentBase.java -+++ after/net/minecraft/util/text/TextComponentBase.java -@@ -82,7 +82,6 @@ - return stringbuilder.toString(); - } - -- @SideOnly(Side.CLIENT) - @Override - public final String getFormattedText() - { diff --git a/patches/minecraft/net/minecraft/util/text/translation/LanguageMap.java.patch b/patches/minecraft/net/minecraft/util/text/translation/LanguageMap.java.patch deleted file mode 100644 index 6ece41d91..000000000 --- a/patches/minecraft/net/minecraft/util/text/translation/LanguageMap.java.patch +++ /dev/null @@ -1,61 +0,0 @@ ---- before/net/minecraft/util/text/translation/LanguageMap.java -+++ after/net/minecraft/util/text/translation/LanguageMap.java -@@ -23,9 +23,36 @@ - - public LanguageMap() - { -- try -- { - InputStream inputstream = LanguageMap.class.getResourceAsStream("/assets/minecraft/lang/en_us.lang"); -+ try -+ { -+ inject(this, inputstream); -+ } -+ finally -+ { -+ IOUtils.closeQuietly(inputstream); // Forge: close stream after use (MC-153470) -+ } -+ } -+ -+ public static void inject(InputStream inputstream) -+ { -+ inject(instance, inputstream); -+ } -+ -+ private static void inject(LanguageMap inst, InputStream inputstream) -+ { -+ Map map = parseLangFile(inputstream); -+ inst.languageList.putAll(map); -+ inst.lastUpdateTimeInMilliseconds = System.currentTimeMillis(); -+ } -+ -+ public static Map parseLangFile(InputStream inputstream) -+ { -+ Map table = Maps.newHashMap(); -+ try -+ { -+ inputstream = net.minecraftforge.fml.common.FMLCommonHandler.instance().loadLanguage(table, inputstream); -+ if (inputstream == null) return table; - - for (String s : IOUtils.readLines(inputstream, StandardCharsets.UTF_8)) - { -@@ -37,16 +64,17 @@ - { - String s1 = astring[0]; - String s2 = NUMERIC_VARIABLE_PATTERN.matcher(astring[1]).replaceAll("%$1s"); -- this.languageList.put(s1, s2); -+ table.put(s1, s2); - } - } - } - -- this.lastUpdateTimeInMilliseconds = System.currentTimeMillis(); - } - catch (IOException ioexception) - { - } -+ catch (Exception ex) {} -+ return table; - } - - static LanguageMap getInstance() diff --git a/patches/minecraft/net/minecraft/village/Village.java.patch b/patches/minecraft/net/minecraft/village/Village.java.patch deleted file mode 100644 index 60485abe6..000000000 --- a/patches/minecraft/net/minecraft/village/Village.java.patch +++ /dev/null @@ -1,202 +0,0 @@ ---- before/net/minecraft/village/Village.java -+++ after/net/minecraft/village/Village.java -@@ -26,7 +26,7 @@ - import net.minecraft.util.math.Vec3d; - import net.minecraft.world.World; - --public class Village -+public class Village implements net.minecraftforge.common.capabilities.ICapabilitySerializable - { - private World world; - private final List villageDoorInfoList = Lists.newArrayList(); -@@ -37,17 +37,19 @@ - private int tickCounter; - private int numVillagers; - private int noBreedTicks; -- private final Map playerReputation = Maps.newHashMap(); -+ private final Map playerReputation = Maps.newHashMap(); - private final List villageAgressors = Lists.newArrayList(); - private int numIronGolems; - - public Village() - { -+ this.capabilities = net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(this); - } - - public Village(World worldIn) - { - this.world = worldIn; -+ this.capabilities = net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(this); - } - - public void setWorld(World worldIn) -@@ -351,11 +353,11 @@ - double d0 = Double.MAX_VALUE; - EntityPlayer entityplayer = null; - -- for (String s : this.playerReputation.keySet()) -+ for (UUID s : this.playerReputation.keySet()) - { - if (this.isPlayerReputationTooLow(s)) - { -- EntityPlayer entityplayer1 = this.world.getPlayerEntityByName(s); -+ EntityPlayer entityplayer1 = this.world.getPlayerEntityByUUID(s); - - if (entityplayer1 != null) - { -@@ -403,6 +405,7 @@ - villagedoorinfo.resetDoorOpeningRestrictionCounter(); - } - -+ if (world.isBlockLoaded(villagedoorinfo.getDoorBlockPos())) // Forge: check that the door block is loaded to avoid loading chunks - if (!this.isWoodDoor(villagedoorinfo.getDoorBlockPos()) || Math.abs(this.tickCounter - villagedoorinfo.getLastActivityTimestamp()) > 1200) - { - this.centerHelper = this.centerHelper.subtract(villagedoorinfo.getDoorBlockPos()); -@@ -450,23 +453,49 @@ - } - } - -+ @Deprecated //Hasn't worked since 1.9, use UUID version below. - public int getPlayerReputation(String playerName) - { -+ return this.getPlayerReputation(findUUID(playerName)); -+ } -+ -+ public int getPlayerReputation(UUID playerName) -+ { - Integer integer = this.playerReputation.get(playerName); - return integer == null ? 0 : integer; - } - -+ private UUID findUUID(String name) -+ { -+ if (this.world == null || this.world.getMinecraftServer() == null) -+ return EntityPlayer.getOfflineUUID(name); -+ GameProfile profile = this.world.getMinecraftServer().getPlayerProfileCache().getGameProfileForUsername(name); -+ return profile == null ? EntityPlayer.getOfflineUUID(name) : profile.getId(); -+ } -+ -+ @Deprecated //Hasn't worked since 1.9, use UUID version below. - public int modifyPlayerReputation(String playerName, int reputation) - { -+ return this.modifyPlayerReputation(findUUID(playerName), reputation); -+ } -+ -+ public int modifyPlayerReputation(UUID playerName, int reputation) -+ { - int i = this.getPlayerReputation(playerName); - int j = MathHelper.clamp(i + reputation, -30, 10); - this.playerReputation.put(playerName, j); - return j; - } - -+ @Deprecated //Hasn't worked since 1.9, use UUID version below. - public boolean isPlayerReputationTooLow(String playerName) - { -- return this.getPlayerReputation(playerName) <= -15; -+ return this.isPlayerReputationTooLow(findUUID(playerName)); -+ } -+ -+ public boolean isPlayerReputationTooLow(UUID uuid) -+ { -+ return this.getPlayerReputation(uuid) <= -15; - } - - public void readVillageDataFromNBT(NBTTagCompound compound) -@@ -499,21 +528,17 @@ - { - NBTTagCompound nbttagcompound1 = nbttaglist1.getCompoundTagAt(j); - -- if (nbttagcompound1.hasKey("UUID") && this.world != null && this.world.getMinecraftServer() != null) -+ if (nbttagcompound1.hasKey("UUID")) - { -- PlayerProfileCache playerprofilecache = this.world.getMinecraftServer().getPlayerProfileCache(); -- GameProfile gameprofile = playerprofilecache.getProfileByUUID(UUID.fromString(nbttagcompound1.getString("UUID"))); -- -- if (gameprofile != null) -- { -- this.playerReputation.put(gameprofile.getName(), nbttagcompound1.getInteger("S")); -- } -+ this.playerReputation.put(UUID.fromString(nbttagcompound1.getString("UUID")), nbttagcompound1.getInteger("S")); - } - else - { -- this.playerReputation.put(nbttagcompound1.getString("Name"), nbttagcompound1.getInteger("S")); -+ //World is never set here, so this will always be offline UUIDs, sadly there is no way to convert this. -+ this.playerReputation.put(findUUID(nbttagcompound1.getString("Name")), nbttagcompound1.getInteger("S")); - } - } -+ if (this.capabilities != null && compound.hasKey("ForgeCaps")) this.capabilities.deserializeNBT(compound.getCompoundTag("ForgeCaps")); - } - - public void writeVillageDataToNBT(NBTTagCompound compound) -@@ -547,18 +572,14 @@ - compound.setTag("Doors", nbttaglist); - NBTTagList nbttaglist1 = new NBTTagList(); - -- for (String s : this.playerReputation.keySet()) -+ for (UUID s : this.playerReputation.keySet()) - { - NBTTagCompound nbttagcompound1 = new NBTTagCompound(); -- PlayerProfileCache playerprofilecache = this.world.getMinecraftServer().getPlayerProfileCache(); - - try - { -- GameProfile gameprofile = playerprofilecache.getGameProfileForUsername(s); -- -- if (gameprofile != null) - { -- nbttagcompound1.setString("UUID", gameprofile.getId().toString()); -+ nbttagcompound1.setString("UUID", s.toString()); - nbttagcompound1.setInteger("S", this.playerReputation.get(s)); - nbttaglist1.appendTag(nbttagcompound1); - } -@@ -569,6 +590,7 @@ - } - - compound.setTag("Players", nbttaglist1); -+ if (this.capabilities != null) compound.setTag("ForgeCaps", this.capabilities.serializeNBT()); - } - - public void endMatingSeason() -@@ -583,7 +605,7 @@ - - public void setDefaultPlayerReputation(int defaultReputation) - { -- for (String s : this.playerReputation.keySet()) -+ for (UUID s : this.playerReputation.keySet()) - { - this.modifyPlayerReputation(s, defaultReputation); - } -@@ -600,4 +622,31 @@ - this.agressionTime = agressionTimeIn; - } - } -+ -+ /* ======================================== FORGE START =====================================*/ -+ private net.minecraftforge.common.capabilities.CapabilityDispatcher capabilities; -+ public boolean hasCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable net.minecraft.util.EnumFacing facing) -+ { -+ return capabilities == null ? false : capabilities.hasCapability(capability, facing); -+ } -+ -+ @Nullable -+ public T getCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable net.minecraft.util.EnumFacing facing) -+ { -+ return capabilities == null ? null : capabilities.getCapability(capability, facing); -+ } -+ -+ public void deserializeNBT(NBTTagCompound nbt) -+ { -+ this.readVillageDataFromNBT(nbt);; -+ } -+ -+ public NBTTagCompound serializeNBT() -+ { -+ NBTTagCompound ret = new NBTTagCompound(); -+ this.writeVillageDataToNBT(ret); -+ return ret; -+ } -+ -+ /* ========================================= FORGE END ======================================*/ - } diff --git a/patches/minecraft/net/minecraft/village/VillageCollection.java.patch b/patches/minecraft/net/minecraft/village/VillageCollection.java.patch deleted file mode 100644 index 2b0128812..000000000 --- a/patches/minecraft/net/minecraft/village/VillageCollection.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- before/net/minecraft/village/VillageCollection.java -+++ after/net/minecraft/village/VillageCollection.java -@@ -151,6 +151,7 @@ - - private void addDoorsAround(BlockPos central) - { -+ if (!this.world.isAreaLoaded(central, 16)) return; // Forge: prevent loading unloaded chunks when checking for doors - int i = 16; - int j = 4; - int k = 16; diff --git a/patches/minecraft/net/minecraft/village/VillageSiege.java.patch b/patches/minecraft/net/minecraft/village/VillageSiege.java.patch deleted file mode 100644 index a7f6578bf..000000000 --- a/patches/minecraft/net/minecraft/village/VillageSiege.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- before/net/minecraft/village/VillageSiege.java -+++ after/net/minecraft/village/VillageSiege.java -@@ -136,6 +136,7 @@ - - if (vec3d != null) - { -+ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.village.VillageSiegeEvent(this, world, entityplayer, village, vec3d))) return false; - this.nextSpawnTime = 0; - this.siegeCount = 20; - return true; diff --git a/patches/minecraft/net/minecraft/world/BossInfo.java.patch b/patches/minecraft/net/minecraft/world/BossInfo.java.patch deleted file mode 100644 index f7c29fc22..000000000 --- a/patches/minecraft/net/minecraft/world/BossInfo.java.patch +++ /dev/null @@ -1,27 +0,0 @@ ---- before/net/minecraft/world/BossInfo.java -+++ after/net/minecraft/world/BossInfo.java -@@ -2,8 +2,6 @@ - - import java.util.UUID; - import net.minecraft.util.text.ITextComponent; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; - - public abstract class BossInfo - { -@@ -55,7 +53,6 @@ - return this.color; - } - -- @SideOnly(Side.CLIENT) - public void setColor(BossInfo.Color colorIn) - { - this.color = colorIn; -@@ -66,7 +63,6 @@ - return this.overlay; - } - -- @SideOnly(Side.CLIENT) - public void setOverlay(BossInfo.Overlay overlayIn) - { - this.overlay = overlayIn; diff --git a/patches/minecraft/net/minecraft/world/BossInfoServer.java.patch b/patches/minecraft/net/minecraft/world/BossInfoServer.java.patch deleted file mode 100644 index bee547211..000000000 --- a/patches/minecraft/net/minecraft/world/BossInfoServer.java.patch +++ /dev/null @@ -1,27 +0,0 @@ ---- before/net/minecraft/world/BossInfoServer.java -+++ after/net/minecraft/world/BossInfoServer.java -@@ -9,8 +9,6 @@ - import net.minecraft.network.play.server.SPacketUpdateBossInfo; - import net.minecraft.util.math.MathHelper; - import net.minecraft.util.text.ITextComponent; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; - - public class BossInfoServer extends BossInfo - { -@@ -33,7 +31,6 @@ - } - } - -- @SideOnly(Side.CLIENT) - @Override - public void setColor(BossInfo.Color colorIn) - { -@@ -44,7 +41,6 @@ - } - } - -- @SideOnly(Side.CLIENT) - @Override - public void setOverlay(BossInfo.Overlay overlayIn) - { diff --git a/patches/minecraft/net/minecraft/world/ChunkCache.java.patch b/patches/minecraft/net/minecraft/world/ChunkCache.java.patch deleted file mode 100644 index f35fe4709..000000000 --- a/patches/minecraft/net/minecraft/world/ChunkCache.java.patch +++ /dev/null @@ -1,76 +0,0 @@ ---- before/net/minecraft/world/ChunkCache.java -+++ after/net/minecraft/world/ChunkCache.java -@@ -62,7 +62,7 @@ - @Override - public TileEntity getTileEntity(BlockPos pos) - { -- return this.getTileEntity(pos, Chunk.EnumCreateEntityType.IMMEDIATE); -+ return this.getTileEntity(pos, Chunk.EnumCreateEntityType.CHECK); // Forge: don't modify world from other threads - } - - @Nullable -@@ -70,6 +70,7 @@ - { - int i = (pos.getX() >> 4) - this.chunkX; - int j = (pos.getZ() >> 4) - this.chunkZ; -+ if (!withinBounds(i, j)) return null; - return this.chunkArray[i][j].getTileEntity(pos, createType); - } - -@@ -116,6 +117,7 @@ - { - int i = (pos.getX() >> 4) - this.chunkX; - int j = (pos.getZ() >> 4) - this.chunkZ; -+ if (!withinBounds(i, j)) return net.minecraft.init.Biomes.PLAINS; - return this.chunkArray[i][j].getBiome(pos, this.world.getBiomeProvider()); - } - -@@ -153,6 +155,7 @@ - { - int i = (pos.getX() >> 4) - this.chunkX; - int j = (pos.getZ() >> 4) - this.chunkZ; -+ if (!withinBounds(i, j)) return type.defaultLightValue; - return this.chunkArray[i][j].getLightFor(type, pos); - } - } -@@ -165,7 +168,8 @@ - @Override - public boolean isAirBlock(BlockPos pos) - { -- return this.getBlockState(pos).getMaterial() == Material.AIR; -+ IBlockState state = this.getBlockState(pos); -+ return state.getBlock().isAir(state, this, pos); - } - - @SideOnly(Side.CLIENT) -@@ -175,6 +179,7 @@ - { - int i = (pos.getX() >> 4) - this.chunkX; - int j = (pos.getZ() >> 4) - this.chunkZ; -+ if (!withinBounds(i, j)) return type.defaultLightValue; - return this.chunkArray[i][j].getLightFor(type, pos); - } - else -@@ -194,5 +199,22 @@ - public WorldType getWorldType() - { - return this.world.getWorldType(); -+ } -+ -+ @Override -+ public boolean isSideSolid(BlockPos pos, EnumFacing side, boolean _default) -+ { -+ int x = (pos.getX() >> 4) - this.chunkX; -+ int z = (pos.getZ() >> 4) - this.chunkZ; -+ if (pos.getY() < 0 || pos.getY() >= 256) return _default; -+ if (!withinBounds(x, z)) return _default; -+ -+ IBlockState state = getBlockState(pos); -+ return state.getBlock().isSideSolid(state, this, pos, side); -+ } -+ -+ private boolean withinBounds(int x, int z) -+ { -+ return x >= 0 && x < chunkArray.length && z >= 0 && z < chunkArray[x].length && chunkArray[x][z] != null; - } - } diff --git a/patches/minecraft/net/minecraft/world/DimensionType.java.patch b/patches/minecraft/net/minecraft/world/DimensionType.java.patch deleted file mode 100644 index bfc9da692..000000000 --- a/patches/minecraft/net/minecraft/world/DimensionType.java.patch +++ /dev/null @@ -1,39 +0,0 @@ ---- before/net/minecraft/world/DimensionType.java -+++ after/net/minecraft/world/DimensionType.java -@@ -13,6 +13,7 @@ - private final String name; - private final String suffix; - private final Class clazz; -+ private boolean shouldLoadSpawn = false; - - private DimensionType(int idIn, String nameIn, String suffixIn, Class clazzIn) - { -@@ -20,6 +21,7 @@ - this.name = nameIn; - this.suffix = suffixIn; - this.clazz = clazzIn; -+ this.shouldLoadSpawn = idIn == 0; - } - - public int getId() -@@ -74,6 +76,20 @@ - - throw new IllegalArgumentException("Invalid dimension id " + id); - } -+ -+ public boolean shouldLoadSpawn(){ return this.shouldLoadSpawn; } -+ public DimensionType setLoadSpawn(boolean value) { this.shouldLoadSpawn = value; return this; } -+ -+ private static Class[] ENUM_ARGS = {int.class, String.class, String.class, Class.class}; -+ static { net.minecraftforge.common.util.EnumHelper.testEnum(DimensionType.class, ENUM_ARGS); } -+ public static DimensionType register(String name, String suffix, int id, Class provider, boolean keepLoaded) -+ { -+ String enum_name = name.replace(" ", "_").toLowerCase(); -+ DimensionType ret = net.minecraftforge.common.util.EnumHelper.addEnum(DimensionType.class, enum_name, ENUM_ARGS, -+ id, name, suffix, provider); -+ return ret.setLoadSpawn(keepLoaded); -+ } -+ //TODO: Unregister? There is no way to really delete a enum value... - - public static DimensionType byName(String nameIn) - { diff --git a/patches/minecraft/net/minecraft/world/Explosion.java.patch b/patches/minecraft/net/minecraft/world/Explosion.java.patch deleted file mode 100644 index a0b2e46a4..000000000 --- a/patches/minecraft/net/minecraft/world/Explosion.java.patch +++ /dev/null @@ -1,52 +0,0 @@ ---- before/net/minecraft/world/Explosion.java -+++ after/net/minecraft/world/Explosion.java -@@ -41,6 +41,7 @@ - private final float size; - private final List affectedBlockPositions = Lists.newArrayList(); - private final Map playerKnockbackMap = Maps.newHashMap(); -+ private final Vec3d position; - - @SideOnly(Side.CLIENT) - public Explosion( -@@ -86,6 +87,7 @@ - this.z = z; - this.causesFire = causesFire; - this.damagesTerrain = damagesTerrain; -+ position = new Vec3d(this.x, this.y, this.z); - } - - public void doExplosionA() -@@ -122,7 +124,7 @@ - { - float f2 = this.exploder != null - ? this.exploder.getExplosionResistance(this, this.world, blockpos, iblockstate) -- : iblockstate.getBlock().getExplosionResistance(null); -+ : iblockstate.getBlock().getExplosionResistance(world, blockpos, null, this); - f -= (f2 + 0.3F) * 0.3F; - } - -@@ -149,6 +151,7 @@ - int j2 = MathHelper.floor(this.z - f3 - 1.0); - int j1 = MathHelper.floor(this.z + f3 + 1.0); - List list = this.world.getEntitiesWithinAABBExcludingEntity(this.exploder, new AxisAlignedBB(k1, i2, j2, l1, i1, j1)); -+ net.minecraftforge.event.ForgeEventFactory.onExplosionDetonate(this.world, this, list, f3); - Vec3d vec3d = new Vec3d(this.x, this.y, this.z); - - for (int k2 = 0; k2 < list.size(); k2++) -@@ -267,8 +270,7 @@ - block.dropBlockAsItemWithChance(this.world, blockpos, this.world.getBlockState(blockpos), 1.0F / this.size, 0); - } - -- this.world.setBlockState(blockpos, Blocks.AIR.getDefaultState(), 3); -- block.onExplosionDestroy(this.world, blockpos, this); -+ block.onBlockExploded(this.world, blockpos, this); - } - } - } -@@ -318,4 +320,6 @@ - { - return this.affectedBlockPositions; - } -+ -+ public Vec3d getPosition(){ return this.position; } - } diff --git a/patches/minecraft/net/minecraft/world/IBlockAccess.java.patch b/patches/minecraft/net/minecraft/world/IBlockAccess.java.patch deleted file mode 100644 index fadb9d3fd..000000000 --- a/patches/minecraft/net/minecraft/world/IBlockAccess.java.patch +++ /dev/null @@ -1,17 +0,0 @@ ---- before/net/minecraft/world/IBlockAccess.java -+++ after/net/minecraft/world/IBlockAccess.java -@@ -28,4 +28,14 @@ - - @SideOnly(Side.CLIENT) - WorldType getWorldType(); -+ -+ /** -+ * FORGE: isSideSolid, pulled up from {@link World} -+ * -+ * @param pos Position -+ * @param side Side -+ * @param _default default return value -+ * @return if the block is solid on the side -+ */ -+ boolean isSideSolid(BlockPos pos, EnumFacing side, boolean _default); - } diff --git a/patches/minecraft/net/minecraft/world/ServerWorldEventHandler.java.patch b/patches/minecraft/net/minecraft/world/ServerWorldEventHandler.java.patch deleted file mode 100644 index 8ec9419d2..000000000 --- a/patches/minecraft/net/minecraft/world/ServerWorldEventHandler.java.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- before/net/minecraft/world/ServerWorldEventHandler.java -+++ after/net/minecraft/world/ServerWorldEventHandler.java -@@ -98,7 +98,7 @@ - y, - z, - volume > 1.0F ? 16.0F * volume : 16.0, -- this.world.provider.getDimensionType().getId(), -+ this.world.provider.getDimension(), - new SPacketSoundEffect(soundIn, category, x, y, z, volume, pitch) - ); - } -@@ -135,7 +135,7 @@ - blockPosIn.getY(), - blockPosIn.getZ(), - 64.0, -- this.world.provider.getDimensionType().getId(), -+ this.world.provider.getDimension(), - new SPacketEffect(type, blockPosIn, data, false) - ); - } diff --git a/patches/minecraft/net/minecraft/world/Teleporter.java.patch b/patches/minecraft/net/minecraft/world/Teleporter.java.patch deleted file mode 100644 index 1e594d84f..000000000 --- a/patches/minecraft/net/minecraft/world/Teleporter.java.patch +++ /dev/null @@ -1,26 +0,0 @@ ---- before/net/minecraft/world/Teleporter.java -+++ after/net/minecraft/world/Teleporter.java -@@ -15,7 +15,7 @@ - import net.minecraft.util.math.ChunkPos; - import net.minecraft.util.math.MathHelper; - --public class Teleporter -+public class Teleporter implements net.minecraftforge.common.util.ITeleporter - { - protected final WorldServer world; - protected final Random random; -@@ -449,5 +449,14 @@ - super(pos.getX(), pos.getY(), pos.getZ()); - this.lastUpdateTime = lastUpdate; - } -+ } -+ -+ @Override -+ public void placeEntity(World world, Entity entity, float yaw) -+ { -+ if (entity instanceof EntityPlayerMP) -+ placeInPortal(entity, yaw); -+ else -+ placeInExistingPortal(entity, yaw); - } - } diff --git a/patches/minecraft/net/minecraft/world/World.java.patch b/patches/minecraft/net/minecraft/world/World.java.patch deleted file mode 100644 index 3198ca843..000000000 --- a/patches/minecraft/net/minecraft/world/World.java.patch +++ /dev/null @@ -1,1290 +0,0 @@ ---- before/net/minecraft/world/World.java -+++ after/net/minecraft/world/World.java -@@ -62,8 +62,15 @@ - import net.minecraftforge.fml.relauncher.Side; - import net.minecraftforge.fml.relauncher.SideOnly; - --public abstract class World implements IBlockAccess -+public abstract class World implements IBlockAccess, net.minecraftforge.common.capabilities.ICapabilityProvider - { -+ /** -+ * Used in the getEntitiesWithinAABB functions to expand the search area for entities. -+ * Modders should change this variable to a higher value if it is less then the radius -+ * of one of there entities. -+ */ -+ public static double MAX_ENTITY_RADIUS = 2.0D; -+ - private int seaLevel = 63; - protected boolean scheduledUpdatesAreImmediate; - public final List loadedEntityList = Lists.newArrayList(); -@@ -107,6 +114,12 @@ - private final WorldBorder worldBorder; - int[] lightUpdateBlockList = new int[32768]; - -+ public boolean restoringBlockSnapshots = false; -+ public boolean captureBlockSnapshots = false; -+ public java.util.ArrayList capturedBlockSnapshots = new java.util.ArrayList(); -+ private net.minecraftforge.common.capabilities.CapabilityDispatcher capabilities; -+ private net.minecraftforge.common.util.WorldCapabilityData capabilityData; -+ - protected World(ISaveHandler saveHandlerIn, WorldInfo info, WorldProvider providerIn, Profiler profilerIn, boolean client) - { - this.saveHandler = saveHandlerIn; -@@ -115,6 +128,7 @@ - this.provider = providerIn; - this.isRemote = client; - this.worldBorder = providerIn.createWorldBorder(); -+ perWorldStorage = new MapStorage(null); - } - - public World init() -@@ -125,6 +139,11 @@ - @Override - public Biome getBiome(final BlockPos pos) - { -+ return this.provider.getBiomeForCoords(pos); -+ } -+ -+ public Biome getBiomeForCoordsBody(final BlockPos pos) -+ { - if (this.isBlockLoaded(pos)) - { - Chunk chunk = this.getChunk(pos); -@@ -206,7 +225,7 @@ - @Override - public boolean isAirBlock(BlockPos pos) - { -- return this.getBlockState(pos).getMaterial() == Material.AIR; -+ return this.getBlockState(pos).getBlock().isAir(this.getBlockState(pos), this, pos); - } - - public boolean isBlockLoaded(BlockPos pos) -@@ -331,23 +350,50 @@ - else - { - Chunk chunk = this.getChunk(pos); -- Block block = newState.getBlock(); -+ -+ pos = pos.toImmutable(); // Forge - prevent mutable BlockPos leaks -+ net.minecraftforge.common.util.BlockSnapshot blockSnapshot = null; -+ if (this.captureBlockSnapshots && !this.isRemote) -+ { -+ blockSnapshot = net.minecraftforge.common.util.BlockSnapshot.getBlockSnapshot(this, pos, flags); -+ this.capturedBlockSnapshots.add(blockSnapshot); -+ } -+ IBlockState oldState = getBlockState(pos); -+ int oldLight = oldState.getLightValue(this, pos); -+ int oldOpacity = oldState.getLightOpacity(this, pos); -+ - IBlockState iblockstate = chunk.setBlockState(pos, newState); - - if (iblockstate == null) - { -+ if (blockSnapshot != null) this.capturedBlockSnapshots.remove(blockSnapshot); - return false; - } - else - { -- if (newState.getLightOpacity() != iblockstate.getLightOpacity() || newState.getLightValue() != iblockstate.getLightValue()) -+ if (newState.getLightOpacity(this, pos) != oldOpacity || newState.getLightValue(this, pos) != oldLight) - { - this.profiler.startSection("checkLight"); - this.checkLight(pos); - this.profiler.endSection(); - } - -- if ((flags & 2) != 0 && (!this.isRemote || (flags & 4) == 0) && chunk.isPopulated()) -+ if (blockSnapshot == null) // Don't notify clients or update physics while capturing blockstates -+ { -+ this.markAndNotifyBlock(pos, chunk, iblockstate, newState, flags); -+ } -+ return true; -+ } -+ } -+ } -+ -+ // Split off from original setBlockState(BlockPos, IBlockState, int) method in order to directly send client and physic updates -+ public void markAndNotifyBlock(BlockPos pos, @Nullable Chunk chunk, IBlockState iblockstate, IBlockState newState, int flags) -+ { -+ Block block = newState.getBlock(); -+ { -+ { -+ if ((flags & 2) != 0 && (!this.isRemote || (flags & 4) == 0) && (chunk == null || chunk.isPopulated())) - { - this.notifyBlockUpdate(pos, iblockstate, newState, flags); - } -@@ -365,8 +411,6 @@ - { - this.updateObservingBlocksAt(pos, block); - } -- -- return true; - } - } - } -@@ -381,7 +425,7 @@ - IBlockState iblockstate = this.getBlockState(pos); - Block block = iblockstate.getBlock(); - -- if (iblockstate.getMaterial() == Material.AIR) -+ if (block.isAir(iblockstate, this, pos)) - { - return false; - } -@@ -471,6 +515,9 @@ - - public void notifyNeighborsOfStateChange(BlockPos pos, Block blockType, boolean updateObservers) - { -+ if(net.minecraftforge.event.ForgeEventFactory.onNeighborNotify(this, pos, this.getBlockState(pos), java.util.EnumSet.allOf(EnumFacing.class), updateObservers).isCanceled()) -+ return; -+ - this.neighborChanged(pos.west(), blockType, pos); - this.neighborChanged(pos.east(), blockType, pos); - this.neighborChanged(pos.down(), blockType, pos); -@@ -486,6 +533,11 @@ - - public void notifyNeighborsOfStateExcept(BlockPos pos, Block blockType, EnumFacing skipSide) - { -+ java.util.EnumSet directions = java.util.EnumSet.allOf(EnumFacing.class); -+ directions.remove(skipSide); -+ if(net.minecraftforge.event.ForgeEventFactory.onNeighborNotify(this, pos, this.getBlockState(pos), directions, false).isCanceled()) -+ return; -+ - if (skipSide != EnumFacing.WEST) - { - this.neighborChanged(pos.west(), blockType, pos); -@@ -540,7 +592,7 @@ - try - { - return String.format( -- "ID #%d (%s // %s)", Block.getIdFromBlock(blockIn), blockIn.getTranslationKey(), blockIn.getClass().getCanonicalName() -+ "ID #%d (%s // %s // %s)", Block.getIdFromBlock(blockIn), blockIn.getTranslationKey(), blockIn.getClass().getName(), blockIn.getRegistryName() - ); - } - catch (Throwable throwable1) -@@ -562,11 +614,11 @@ - { - IBlockState iblockstate = this.getBlockState(pos); - -- if (iblockstate.getBlock() == Blocks.OBSERVER) -+ if (true) - { - try - { -- ((BlockObserver)iblockstate.getBlock()).observedNeighborChanged(iblockstate, this, pos, changedBlock, changedBlockPos); -+ iblockstate.getBlock().observedNeighborChange(iblockstate, this, pos, changedBlock, changedBlockPos); - } - catch (Throwable throwable) - { -@@ -581,7 +633,7 @@ - try - { - return String.format( -- "ID #%d (%s // %s)", Block.getIdFromBlock(changedBlock), changedBlock.getTranslationKey(), changedBlock.getClass().getCanonicalName() -+ "ID #%d (%s // %s // %s)", Block.getIdFromBlock(changedBlock), changedBlock.getTranslationKey(), changedBlock.getClass().getName(), changedBlock.getRegistryName() - ); - } - catch (Throwable throwable1) -@@ -628,7 +680,7 @@ - { - IBlockState iblockstate = this.getBlockState(blockpos1); - -- if (iblockstate.getLightOpacity() > 0 && !iblockstate.getMaterial().isLiquid()) -+ if (iblockstate.getBlock().getLightOpacity(iblockstate, this, blockpos) > 0 && !iblockstate.getMaterial().isLiquid()) - { - return false; - } -@@ -906,7 +958,7 @@ - - public boolean isDaytime() - { -- return this.skylightSubtracted < 4; -+ return this.provider.isDaytime(); - } - - @Nullable -@@ -1126,6 +1178,13 @@ - float pitch - ) - { -+ net.minecraftforge.event.entity.PlaySoundAtEntityEvent event = net.minecraftforge.event.ForgeEventFactory.onPlaySoundAtEntity(player, soundIn, category, volume, pitch); -+ if (event.isCanceled() || event.getSound() == null) return; -+ soundIn = event.getSound(); -+ category = event.getCategory(); -+ volume = event.getVolume(); -+ pitch = event.getPitch(); -+ - for (int i = 0; i < this.eventListeners.size(); i++) - { - this.eventListeners.get(i).playSoundToAllNearExcept(player, soundIn, category, x, y, z, volume, pitch); -@@ -1236,12 +1295,18 @@ - - public boolean addWeatherEffect(Entity entityIn) - { -+ if(net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.EntityJoinWorldEvent(entityIn, this))) -+ return false; -+ - this.weatherEffects.add(entityIn); - return true; - } - - public boolean spawnEntity(Entity entityIn) - { -+ // do not drop any items while restoring blocksnapshots. Prevents dupes -+ if (!this.isRemote && (entityIn == null || (entityIn instanceof net.minecraft.entity.item.EntityItem && this.restoringBlockSnapshots))) return false; -+ - int i = MathHelper.floor(entityIn.posX / 16.0); - int j = MathHelper.floor(entityIn.posZ / 16.0); - boolean flag = entityIn.forceSpawn; -@@ -1264,6 +1329,8 @@ - this.updateAllPlayersSleepingFlag(); - } - -+ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.EntityJoinWorldEvent(entityIn, this)) && !flag) return false; -+ - this.getChunk(i, j).addEntity(entityIn); - this.loadedEntityList.add(entityIn); - this.onEntityAdded(entityIn); -@@ -1277,6 +1344,7 @@ - { - this.eventListeners.get(i).onEntityAdded(entityIn); - } -+ entityIn.onAddedToWorld(); - } - - public void onEntityRemoved(Entity entityIn) -@@ -1285,6 +1353,7 @@ - { - this.eventListeners.get(i).onEntityRemoved(entityIn); - } -+ entityIn.onRemovedFromWorld(); - } - - public void removeEntity(Entity entityIn) -@@ -1337,7 +1406,6 @@ - this.eventListeners.add(listener); - } - -- @SideOnly(Side.CLIENT) - public void removeEventListener(IWorldEventListener listener) - { - this.eventListeners.remove(listener); -@@ -1357,6 +1425,7 @@ - IBlockState iblockstate = Blocks.STONE.getDefaultState(); - BlockPos.PooledMutableBlockPos blockpos$pooledmutableblockpos = BlockPos.PooledMutableBlockPos.retain(); - -+ if (p_191504_3_ && !net.minecraftforge.event.ForgeEventFactory.gatherCollisionBoxes(this, entityIn, aabb, outList)) return true; - try - { - for (int k1 = i; k1 < j; k1++) -@@ -1398,7 +1467,7 @@ - - iblockstate1.addCollisionBoxToList(this, blockpos$pooledmutableblockpos, aabb, outList, entityIn, false); - -- if (p_191504_3_ && !outList.isEmpty()) -+ if (p_191504_3_ && !net.minecraftforge.event.ForgeEventFactory.gatherCollisionBoxes(this, entityIn, aabb, outList)) - { - return true; - } -@@ -1447,7 +1516,7 @@ - } - } - } -- -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.GetCollisionBoxesEvent(this, entityIn, aabb, list)); - return list; - } - -@@ -1483,19 +1552,38 @@ - - public int calculateSkylightSubtracted(float partialTicks) - { -+ float f = provider.getSunBrightnessFactor(partialTicks); -+ f = 1 - f; -+ return (int)(f * 11); -+ } -+ -+ /** -+ * The current sun brightness factor for this dimension. -+ * 0.0f means no light at all, and 1.0f means maximum sunlight. -+ * Highly recommended for sunlight detection like solar panel. -+ * -+ * @return The current brightness factor -+ * */ -+ public float getSunBrightnessFactor(float partialTicks) -+ { - float f = this.getCelestialAngle(partialTicks); - float f1 = 1.0F - (MathHelper.cos(f * (float)(Math.PI * 2)) * 2.0F + 0.5F); - f1 = MathHelper.clamp(f1, 0.0F, 1.0F); - f1 = 1.0F - f1; - f1 = (float)(f1 * (1.0 - this.getRainStrength(partialTicks) * 5.0F / 16.0)); - f1 = (float)(f1 * (1.0 - this.getThunderStrength(partialTicks) * 5.0F / 16.0)); -- f1 = 1.0F - f1; -- return (int)(f1 * 11.0F); -+ return f1; - } - - @SideOnly(Side.CLIENT) - public float getSunBrightness(float partialTicks) - { -+ return this.provider.getSunBrightness(partialTicks); -+ } -+ -+ @SideOnly(Side.CLIENT) -+ public float getSunBrightnessBody(float partialTicks) -+ { - float f = this.getCelestialAngle(partialTicks); - float f1 = 1.0F - (MathHelper.cos(f * (float)(Math.PI * 2)) * 2.0F + 0.2F); - f1 = MathHelper.clamp(f1, 0.0F, 1.0F); -@@ -1508,6 +1596,12 @@ - @SideOnly(Side.CLIENT) - public Vec3d getSkyColor(Entity entityIn, float partialTicks) - { -+ return this.provider.getSkyColor(entityIn, partialTicks); -+ } -+ -+ @SideOnly(Side.CLIENT) -+ public Vec3d getSkyColorBody(Entity entityIn, float partialTicks) -+ { - float f = this.getCelestialAngle(partialTicks); - float f1 = MathHelper.cos(f * (float)(Math.PI * 2)) * 2.0F + 0.5F; - f1 = MathHelper.clamp(f1, 0.0F, 1.0F); -@@ -1515,9 +1609,7 @@ - int j = MathHelper.floor(entityIn.posY); - int k = MathHelper.floor(entityIn.posZ); - BlockPos blockpos = new BlockPos(i, j, k); -- Biome biome = this.getBiome(blockpos); -- float f2 = biome.getTemperature(blockpos); -- int l = biome.getSkyColorByTemp(f2); -+ int l = net.minecraftforge.client.ForgeHooksClient.getSkyBlendColour(this, blockpos); - float f3 = (l >> 16 & 0xFF) / 255.0F; - float f4 = (l >> 8 & 0xFF) / 255.0F; - float f5 = (l & 0xFF) / 255.0F; -@@ -1566,18 +1658,23 @@ - - public float getCelestialAngle(float partialTicks) - { -- return this.provider.calculateCelestialAngle(this.worldInfo.getWorldTime(), partialTicks); -+ return this.provider.calculateCelestialAngle(this.getWorldTime(), partialTicks); - } - - @SideOnly(Side.CLIENT) - public int getMoonPhase() - { -- return this.provider.getMoonPhase(this.worldInfo.getWorldTime()); -+ return this.provider.getMoonPhase(this.getWorldTime()); - } - - public float getCurrentMoonPhaseFactor() - { -- return WorldProvider.MOON_PHASE_FACTORS[this.provider.getMoonPhase(this.worldInfo.getWorldTime())]; -+ return provider.getCurrentMoonPhaseFactor(); -+ } -+ -+ public float getCurrentMoonPhaseFactorBody() -+ { -+ return WorldProvider.MOON_PHASE_FACTORS[this.provider.getMoonPhase(this.getWorldTime())]; - } - - public float getCelestialAngleRadians(float partialTicks) -@@ -1589,6 +1686,12 @@ - @SideOnly(Side.CLIENT) - public Vec3d getCloudColour(float partialTicks) - { -+ return this.provider.getCloudColor(partialTicks); -+ } -+ -+ @SideOnly(Side.CLIENT) -+ public Vec3d getCloudColorBody(float partialTicks) -+ { - float f = this.getCelestialAngle(partialTicks); - float f1 = MathHelper.cos(f * (float)(Math.PI * 2)) * 2.0F + 0.5F; - f1 = MathHelper.clamp(f1, 0.0F, 1.0F); -@@ -1643,9 +1746,9 @@ - while (blockpos.getY() >= 0) - { - BlockPos blockpos1 = blockpos.down(); -- Material material = chunk.getBlockState(blockpos1).getMaterial(); -+ IBlockState state = chunk.getBlockState(blockpos1); - -- if (material.blocksMovement() && material != Material.LEAVES) -+ if (state.getMaterial().blocksMovement() && !state.getBlock().isLeaves(state, this, blockpos1) && !state.getBlock().isFoliage(this, blockpos1)) - { - break; - } -@@ -1659,6 +1762,12 @@ - @SideOnly(Side.CLIENT) - public float getStarBrightness(float partialTicks) - { -+ return this.provider.getStarBrightness(partialTicks); -+ } -+ -+ @SideOnly(Side.CLIENT) -+ public float getStarBrightnessBody(float partialTicks) -+ { - float f = this.getCelestialAngle(partialTicks); - float f1 = 1.0F - (MathHelper.cos(f * (float)(Math.PI * 2)) * 2.0F + 0.25F); - f1 = MathHelper.clamp(f1, 0.0F, 1.0F); -@@ -1693,6 +1802,7 @@ - - try - { -+ if(entity.updateBlocked) continue; - entity.ticksExisted++; - entity.onUpdate(); - } -@@ -1710,6 +1820,12 @@ - entity.addEntityCrashInfo(crashreportcategory); - } - -+ if (net.minecraftforge.common.ForgeModContainer.removeErroringEntities) -+ { -+ net.minecraftforge.fml.common.FMLLog.log.fatal("{}", crashreport.getCompleteReport()); -+ removeEntity(entity); -+ } -+ else - throw new ReportedException(crashreport); - } - -@@ -1764,13 +1880,21 @@ - { - try - { -+ net.minecraftforge.server.timings.TimeTracker.ENTITY_UPDATE.trackStart(entity2); - this.updateEntity(entity2); -+ net.minecraftforge.server.timings.TimeTracker.ENTITY_UPDATE.trackEnd(entity2); - } - catch (Throwable throwable1) - { - CrashReport crashreport1 = CrashReport.makeCrashReport(throwable1, "Ticking entity"); - CrashReportCategory crashreportcategory1 = crashreport1.makeCategory("Entity being ticked"); - entity2.addEntityCrashInfo(crashreportcategory1); -+ if (net.minecraftforge.common.ForgeModContainer.removeErroringEntities) -+ { -+ net.minecraftforge.fml.common.FMLLog.log.fatal("{}", crashreport1.getCompleteReport()); -+ removeEntity(entity2); -+ } -+ else - throw new ReportedException(crashreport1); - } - } -@@ -1797,14 +1921,23 @@ - - this.profiler.endStartSection("blockEntities"); - -+ this.processingLoadedTiles = true; //FML Move above remove to prevent CMEs -+ - if (!this.tileEntitiesToBeRemoved.isEmpty()) - { -- this.tickableTileEntities.removeAll(this.tileEntitiesToBeRemoved); -- this.loadedTileEntityList.removeAll(this.tileEntitiesToBeRemoved); -+ for (Object tile : tileEntitiesToBeRemoved) -+ { -+ ((TileEntity)tile).onChunkUnload(); -+ } -+ -+ // forge: faster "contains" makes this removal much more efficient -+ java.util.Set remove = java.util.Collections.newSetFromMap(new java.util.IdentityHashMap<>()); -+ remove.addAll(tileEntitiesToBeRemoved); -+ this.tickableTileEntities.removeAll(remove); -+ this.loadedTileEntityList.removeAll(remove); - this.tileEntitiesToBeRemoved.clear(); - } - -- this.processingLoadedTiles = true; - Iterator iterator = this.tickableTileEntities.iterator(); - - while (iterator.hasNext()) -@@ -1815,12 +1948,14 @@ - { - BlockPos blockpos = tileentity.getPos(); - -- if (this.isBlockLoaded(blockpos) && this.worldBorder.contains(blockpos)) -+ if (this.isBlockLoaded(blockpos, false) && this.worldBorder.contains(blockpos)) //Forge: Fix TE's getting an extra tick on the client side.... - { - try - { -- this.profiler.func_194340_a(() -> String.valueOf(TileEntity.getKey((Class )tileentity.getClass()))); -+ this.profiler.func_194340_a(() -> String.valueOf(TileEntity.getKey(tileentity.getClass()))); -+ net.minecraftforge.server.timings.TimeTracker.TILE_ENTITY_UPDATE.trackStart(tileentity); - ((ITickable)tileentity).update(); -+ net.minecraftforge.server.timings.TimeTracker.TILE_ENTITY_UPDATE.trackEnd(tileentity); - this.profiler.endSection(); - } - catch (Throwable throwable) -@@ -1828,6 +1963,13 @@ - CrashReport crashreport2 = CrashReport.makeCrashReport(throwable, "Ticking block entity"); - CrashReportCategory crashreportcategory2 = crashreport2.makeCategory("Block entity being ticked"); - tileentity.addInfoToCrashReport(crashreportcategory2); -+ if (net.minecraftforge.common.ForgeModContainer.removeErroringTileEntities) -+ { -+ net.minecraftforge.fml.common.FMLLog.log.fatal("{}", crashreport2.getCompleteReport()); -+ tileentity.invalidate(); -+ this.removeTileEntity(tileentity.getPos()); -+ } -+ else - throw new ReportedException(crashreport2); - } - } -@@ -1840,7 +1982,10 @@ - - if (this.isBlockLoaded(tileentity.getPos())) - { -- this.getChunk(tileentity.getPos()).removeTileEntity(tileentity.getPos()); -+ //Forge: Bugfix: If we set the tile entity it immediately sets it in the chunk, so we could be desyned -+ Chunk chunk = this.getChunk(tileentity.getPos()); -+ if (chunk.getTileEntity(tileentity.getPos(), net.minecraft.world.chunk.Chunk.EnumCreateEntityType.CHECK) == tileentity) -+ chunk.removeTileEntity(tileentity.getPos()); - } - } - } -@@ -1884,12 +2029,18 @@ - - public boolean addTileEntity(TileEntity tile) - { -+ // Forge - set the world early as vanilla doesn't set it until next tick -+ if (tile.getWorld() != this) tile.setWorld(this); -+ // Forge: wait to add new TE if we're currently processing existing ones -+ if (processingLoadedTiles) return addedTileEntityList.add(tile); -+ - boolean flag = this.loadedTileEntityList.add(tile); - - if (flag && tile instanceof ITickable) - { - this.tickableTileEntities.add(tile); - } -+ tile.onLoad(); - - if (this.isRemote) - { -@@ -1905,6 +2056,11 @@ - { - if (this.processingLoadedTiles) - { -+ for (TileEntity te : tileEntityCollection) -+ { -+ if (te.getWorld() != this) // Forge - set the world early as vanilla doesn't set it until next tick -+ te.setWorld(this); -+ } - this.addedTileEntityList.addAll(tileEntityCollection); - } - else -@@ -1927,9 +2083,13 @@ - { - int i = MathHelper.floor(entityIn.posX); - int j = MathHelper.floor(entityIn.posZ); -- int k = 32; -- -- if (forceUpdate && !this.isAreaLoaded(i - 32, 0, j - 32, i + 32, 0, j + 32, true)) -+ -+ boolean isForced = !this.isRemote && getPersistentChunks().containsKey(new net.minecraft.util.math.ChunkPos(i >> 4, j >> 4)); -+ int range = isForced ? 0 : 32; -+ boolean canUpdate = !forceUpdate || this.isAreaLoaded(i - range, 0, j - range, i + range, 0, j + range, true); -+ if (!canUpdate) canUpdate = net.minecraftforge.event.ForgeEventFactory.canEntityUpdate(entityIn); -+ -+ if (!canUpdate) - { - return; - } -@@ -1951,6 +2111,7 @@ - } - else - { -+ if(!entityIn.updateBlocked) - entityIn.onUpdate(); - } - } -@@ -2034,7 +2195,7 @@ - { - Entity entity = list.get(i); - -- if (!entity.isDead && entity.preventEntitySpawning && entity != entityIn && (entityIn == null || entity.isRidingSameEntity(entityIn))) -+ if (!entity.isDead && entity.preventEntitySpawning && entity != entityIn && (entityIn == null || !entity.isRidingSameEntity(entityIn))) // Forge: fix MC-103516 - { - return false; - } -@@ -2092,6 +2253,12 @@ - { - IBlockState iblockstate = this.getBlockState(blockpos$pooledmutableblockpos.setPos(k1, l1, i2)); - -+ Boolean result = iblockstate.getBlock().isAABBInsideLiquid(this, blockpos$pooledmutableblockpos, bb); -+ if (result != null) { -+ if (!result) continue; -+ blockpos$pooledmutableblockpos.release(); -+ return true; -+ } - if (iblockstate.getMaterial().isLiquid()) - { - blockpos$pooledmutableblockpos.release(); -@@ -2131,6 +2298,11 @@ - blockpos$pooledmutableblockpos.release(); - return true; - } -+ else if (block.isBurning(this, new BlockPos(k1, l1, i2))) -+ { -+ blockpos$pooledmutableblockpos.release(); -+ return true; -+ } - } - } - } -@@ -2170,6 +2342,16 @@ - IBlockState iblockstate = this.getBlockState(blockpos$pooledmutableblockpos); - Block block = iblockstate.getBlock(); - -+ Boolean result = block.isEntityInsideMaterial(this, blockpos$pooledmutableblockpos, iblockstate, entityIn, (double)l, materialIn, false); -+ if (result != null && result == true) -+ { -+ // Forge: When requested call blocks modifyAcceleration method, and more importantly cause this method to return true, which results in an entity being "inWater" -+ flag = true; -+ vec3d = block.modifyAcceleration(this, blockpos$pooledmutableblockpos, entityIn, vec3d); -+ continue; -+ } -+ else if (result != null && result == false) continue; -+ - if (iblockstate.getMaterial() == materialIn) - { - double d0 = l1 + 1 - BlockLiquid.getLiquidHeightPercent(iblockstate.getValue(BlockLiquid.LEVEL)); -@@ -2215,7 +2397,14 @@ - { - for (int i2 = i1; i2 < j1; i2++) - { -- if (this.getBlockState(blockpos$pooledmutableblockpos.setPos(k1, l1, i2)).getMaterial() == materialIn) -+ IBlockState iblockstate1 = this.getBlockState(blockpos$pooledmutableblockpos.setPos(k1, l1, i2)); -+ Boolean result = iblockstate1.getBlock().isAABBInsideMaterial(this, blockpos$pooledmutableblockpos, bb, materialIn); -+ if (result != null) { -+ if (!result) continue; -+ blockpos$pooledmutableblockpos.release(); -+ return true; -+ } -+ if (iblockstate1.getMaterial() == materialIn) - { - blockpos$pooledmutableblockpos.release(); - return true; -@@ -2238,6 +2427,7 @@ - ) - { - Explosion explosion = new Explosion(this, entityIn, x, y, z, strength, causesFire, damagesTerrain); -+ if (net.minecraftforge.event.ForgeEventFactory.onExplosionStart(this, explosion)) return explosion; - explosion.doExplosionA(); - explosion.doExplosionB(true); - return explosion; -@@ -2361,6 +2551,7 @@ - - public void setTileEntity(BlockPos pos, @Nullable TileEntity tileEntityIn) - { -+ pos = pos.toImmutable(); // Forge - prevent mutable BlockPos leaks - if (!this.isOutsideBuildHeight(pos)) - { - if (tileEntityIn != null && !tileEntityIn.isInvalid()) -@@ -2368,7 +2559,10 @@ - if (this.processingLoadedTiles) - { - tileEntityIn.setPos(pos); -+ if (tileEntityIn.getWorld() != this) -+ tileEntityIn.setWorld(this); // Forge - set the world early as vanilla doesn't set it until next tick - Iterator iterator = this.addedTileEntityList.iterator(); -+ List toInvalidate = Lists.newArrayList(); - - while (iterator.hasNext()) - { -@@ -2376,16 +2570,18 @@ - - if (tileentity.getPos().equals(pos)) - { -- tileentity.invalidate(); -+ toInvalidate.add(tileentity); // Forge - don't call invalidate while iterating - iterator.remove(); - } - } - -+ toInvalidate.forEach(TileEntity::invalidate); - this.addedTileEntityList.add(tileEntityIn); - } - else - { -- this.getChunk(pos).addTileEntity(pos, tileEntityIn); -+ Chunk chunk = this.getChunk(pos); -+ if (chunk != null) chunk.addTileEntity(pos, tileEntityIn); - this.addTileEntity(tileEntityIn); - } - } -@@ -2400,6 +2596,8 @@ - { - tileentity.invalidate(); - this.addedTileEntityList.remove(tileentity); -+ if (!(tileentity instanceof ITickable)) //Forge: If they are not tickable they wont be removed in the update loop. -+ this.loadedTileEntityList.remove(tileentity); - } - else - { -@@ -2412,6 +2610,7 @@ - - this.getChunk(pos).removeTileEntity(pos); - } -+ this.updateComparatorOutputLevel(pos, getBlockState(pos).getBlock()); //Notify neighbors of changes - } - - public void markTileEntityForRemoval(TileEntity tileEntityIn) -@@ -2438,7 +2637,7 @@ - if (chunk != null && !chunk.isEmpty()) - { - IBlockState iblockstate = this.getBlockState(pos); -- return iblockstate.getMaterial().isOpaque() && iblockstate.isFullCube(); -+ return iblockstate.getBlock().isNormalCube(iblockstate, this, pos); - } - else - { -@@ -2461,6 +2660,7 @@ - { - this.spawnHostileMobs = hostile; - this.spawnPeacefulMobs = peaceful; -+ this.provider.setAllowedSpawnTypes(hostile, peaceful); - } - - public void tick() -@@ -2470,6 +2670,11 @@ - - protected void calculateInitialWeather() - { -+ this.provider.calculateInitialWeather(); -+ } -+ -+ public void calculateInitialWeatherBody() -+ { - if (this.worldInfo.isRaining()) - { - this.rainingStrength = 1.0F; -@@ -2483,6 +2688,11 @@ - - protected void updateWeather() - { -+ this.provider.updateWeather(); -+ } -+ -+ public void updateWeatherBody() -+ { - if (this.provider.hasSkyLight()) - { - if (!this.isRemote) -@@ -2604,6 +2814,11 @@ - - public boolean canBlockFreeze(BlockPos pos, boolean noWaterAdj) - { -+ return this.provider.canBlockFreeze(pos, noWaterAdj); -+ } -+ -+ public boolean canBlockFreezeBody(BlockPos pos, boolean noWaterAdj) -+ { - Biome biome = this.getBiome(pos); - float f = biome.getTemperature(pos); - -@@ -2648,6 +2863,11 @@ - - public boolean canSnowAt(BlockPos pos, boolean checkLight) - { -+ return this.provider.canSnowAt(pos, checkLight); -+ } -+ -+ public boolean canSnowAtBody(BlockPos pos, boolean checkLight) -+ { - Biome biome = this.getBiome(pos); - float f = biome.getTemperature(pos); - -@@ -2665,7 +2885,7 @@ - { - IBlockState iblockstate = this.getBlockState(pos); - -- if (iblockstate.getMaterial() == Material.AIR && Blocks.SNOW_LAYER.canPlaceBlockAt(this, pos)) -+ if (iblockstate.getBlock().isAir(iblockstate, this, pos) && Blocks.SNOW_LAYER.canPlaceBlockAt(this, pos)) - { - return true; - } -@@ -2696,10 +2916,10 @@ - else - { - IBlockState iblockstate = this.getBlockState(pos); -- int i = lightType == EnumSkyBlock.SKY ? 0 : iblockstate.getLightValue(); -- int j = iblockstate.getLightOpacity(); -+ int i = lightType == EnumSkyBlock.SKY ? 0 : iblockstate.getBlock().getLightValue(iblockstate, this, pos); -+ int j = iblockstate.getBlock().getLightOpacity(iblockstate, this, pos); - -- if (j >= 15 && iblockstate.getLightValue() > 0) -+ if (false) // Forge: fix MC-119932 - { - j = 1; - } -@@ -2711,7 +2931,7 @@ - - if (j >= 15) - { -- return 0; -+ return i; // Forge: fix MC-119932 - } - else if (i >= 14) - { -@@ -2751,12 +2971,13 @@ - - public boolean checkLightFor(EnumSkyBlock lightType, BlockPos pos) - { -- if (!this.isAreaLoaded(pos, 17, false)) -+ if (!this.isAreaLoaded(pos, 16, false)) - { - return false; - } - else - { -+ int updateRange = this.isAreaLoaded(pos, 18, false) ? 17 : 15; - int i = 0; - int j = 0; - this.profiler.startSection("getBrightness"); -@@ -2794,7 +3015,7 @@ - int k3 = MathHelper.abs(j2 - j1); - int l3 = MathHelper.abs(k2 - k1); - -- if (j3 + k3 + l3 < 17) -+ if (j3 + k3 + l3 < updateRange) - { - BlockPos.PooledMutableBlockPos blockpos$pooledmutableblockpos = BlockPos.PooledMutableBlockPos.retain(); - -@@ -2804,7 +3025,8 @@ - int j4 = j2 + enumfacing.getYOffset(); - int k4 = k2 + enumfacing.getZOffset(); - blockpos$pooledmutableblockpos.setPos(i4, j4, k4); -- int l4 = Math.max(1, this.getBlockState(blockpos$pooledmutableblockpos).getLightOpacity()); -+ IBlockState bs = this.getBlockState(blockpos$pooledmutableblockpos); -+ int l4 = Math.max(1, bs.getBlock().getLightOpacity(bs, this, blockpos$pooledmutableblockpos)); - i3 = this.getLightFor(lightType, blockpos$pooledmutableblockpos); - - if (i3 == l2 - l4 && j < this.lightUpdateBlockList.length) -@@ -2827,55 +3049,55 @@ - - while (i < j) - { -- int i5 = this.lightUpdateBlockList[i++]; -- int j5 = (i5 & 63) - 32 + i1; -- int k5 = (i5 >> 6 & 63) - 32 + j1; -- int l5 = (i5 >> 12 & 63) - 32 + k1; -- BlockPos blockpos1 = new BlockPos(j5, k5, l5); -- int i6 = this.getLightFor(lightType, blockpos1); -- int j6 = this.getRawLight(blockpos1, lightType); -+ int j7 = this.lightUpdateBlockList[i++]; -+ int k7 = (j7 & 63) - 32 + i1; -+ int l7 = (j7 >> 6 & 63) - 32 + j1; -+ int i8 = (j7 >> 12 & 63) - 32 + k1; -+ BlockPos blockpos2 = new BlockPos(k7, l7, i8); -+ int j8 = this.getLightFor(lightType, blockpos2); -+ int k8 = this.getRawLight(blockpos2, lightType); - -- if (j6 != i6) -+ if (k8 != j8) - { -- this.setLightFor(lightType, blockpos1, j6); -+ this.setLightFor(lightType, blockpos2, k8); - -- if (j6 > i6) -+ if (k8 > j8) - { -- int k6 = Math.abs(j5 - i1); -- int l6 = Math.abs(k5 - j1); -- int i7 = Math.abs(l5 - k1); -+ int l8 = Math.abs(k7 - i1); -+ int i9 = Math.abs(l7 - j1); -+ int j9 = Math.abs(i8 - k1); - boolean flag = j < this.lightUpdateBlockList.length - 6; - -- if (k6 + l6 + i7 < 17 && flag) -+ if (l8 + i9 + j9 < updateRange && flag) - { -- if (this.getLightFor(lightType, blockpos1.west()) < j6) -- { -- this.lightUpdateBlockList[j++] = j5 - 1 - i1 + 32 + (k5 - j1 + 32 << 6) + (l5 - k1 + 32 << 12); -- } -- -- if (this.getLightFor(lightType, blockpos1.east()) < j6) -- { -- this.lightUpdateBlockList[j++] = j5 + 1 - i1 + 32 + (k5 - j1 + 32 << 6) + (l5 - k1 + 32 << 12); -- } -- -- if (this.getLightFor(lightType, blockpos1.down()) < j6) -- { -- this.lightUpdateBlockList[j++] = j5 - i1 + 32 + (k5 - 1 - j1 + 32 << 6) + (l5 - k1 + 32 << 12); -- } -- -- if (this.getLightFor(lightType, blockpos1.up()) < j6) -- { -- this.lightUpdateBlockList[j++] = j5 - i1 + 32 + (k5 + 1 - j1 + 32 << 6) + (l5 - k1 + 32 << 12); -- } -- -- if (this.getLightFor(lightType, blockpos1.north()) < j6) -- { -- this.lightUpdateBlockList[j++] = j5 - i1 + 32 + (k5 - j1 + 32 << 6) + (l5 - 1 - k1 + 32 << 12); -- } -- -- if (this.getLightFor(lightType, blockpos1.south()) < j6) -- { -- this.lightUpdateBlockList[j++] = j5 - i1 + 32 + (k5 - j1 + 32 << 6) + (l5 + 1 - k1 + 32 << 12); -+ if (this.getLightFor(lightType, blockpos2.west()) < k8) -+ { -+ this.lightUpdateBlockList[j++] = k7 - 1 - i1 + 32 + (l7 - j1 + 32 << 6) + (i8 - k1 + 32 << 12); -+ } -+ -+ if (this.getLightFor(lightType, blockpos2.east()) < k8) -+ { -+ this.lightUpdateBlockList[j++] = k7 + 1 - i1 + 32 + (l7 - j1 + 32 << 6) + (i8 - k1 + 32 << 12); -+ } -+ -+ if (this.getLightFor(lightType, blockpos2.down()) < k8) -+ { -+ this.lightUpdateBlockList[j++] = k7 - i1 + 32 + (l7 - 1 - j1 + 32 << 6) + (i8 - k1 + 32 << 12); -+ } -+ -+ if (this.getLightFor(lightType, blockpos2.up()) < k8) -+ { -+ this.lightUpdateBlockList[j++] = k7 - i1 + 32 + (l7 + 1 - j1 + 32 << 6) + (i8 - k1 + 32 << 12); -+ } -+ -+ if (this.getLightFor(lightType, blockpos2.north()) < k8) -+ { -+ this.lightUpdateBlockList[j++] = k7 - i1 + 32 + (l7 - j1 + 32 << 6) + (i8 - 1 - k1 + 32 << 12); -+ } -+ -+ if (this.getLightFor(lightType, blockpos2.south()) < k8) -+ { -+ this.lightUpdateBlockList[j++] = k7 - i1 + 32 + (l7 - j1 + 32 << 6) + (i8 + 1 - k1 + 32 << 12); - } - } - } -@@ -2912,10 +3134,10 @@ - public List getEntitiesInAABBexcluding(@Nullable Entity entityIn, AxisAlignedBB boundingBox, @Nullable Predicate predicate) - { - List list = Lists.newArrayList(); -- int i = MathHelper.floor((boundingBox.minX - 2.0) / 16.0); -- int j = MathHelper.floor((boundingBox.maxX + 2.0) / 16.0); -- int k = MathHelper.floor((boundingBox.minZ - 2.0) / 16.0); -- int l = MathHelper.floor((boundingBox.maxZ + 2.0) / 16.0); -+ int i = MathHelper.floor((boundingBox.minX - MAX_ENTITY_RADIUS) / 16.0); -+ int j = MathHelper.floor((boundingBox.maxX + MAX_ENTITY_RADIUS) / 16.0); -+ int k = MathHelper.floor((boundingBox.minZ - MAX_ENTITY_RADIUS) / 16.0); -+ int l = MathHelper.floor((boundingBox.maxZ + MAX_ENTITY_RADIUS) / 16.0); - - for (int i1 = i; i1 <= j; i1++) - { -@@ -2968,10 +3190,10 @@ - - public List getEntitiesWithinAABB(Class clazz, AxisAlignedBB aabb, @Nullable Predicate filter) - { -- int i = MathHelper.floor((aabb.minX - 2.0) / 16.0); -- int j = MathHelper.ceil((aabb.maxX + 2.0) / 16.0); -- int k = MathHelper.floor((aabb.minZ - 2.0) / 16.0); -- int l = MathHelper.ceil((aabb.maxZ + 2.0) / 16.0); -+ int i = MathHelper.floor((aabb.minX - MAX_ENTITY_RADIUS) / 16.0); -+ int j = MathHelper.ceil((aabb.maxX + MAX_ENTITY_RADIUS) / 16.0); -+ int k = MathHelper.floor((aabb.minZ - MAX_ENTITY_RADIUS) / 16.0); -+ int l = MathHelper.ceil((aabb.maxZ + MAX_ENTITY_RADIUS) / 16.0); - List list = Lists.newArrayList(); - - for (int i1 = i; i1 < j; i1++) -@@ -3051,11 +3273,13 @@ - - public void loadEntities(Collection entityCollection) - { -- this.loadedEntityList.addAll(entityCollection); -- - for (Entity entity : entityCollection) - { -- this.onEntityAdded(entity); -+ if (!net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.EntityJoinWorldEvent(entity, this))) -+ { -+ loadedEntityList.add(entity); -+ this.onEntityAdded(entity); -+ } - } - } - -@@ -3069,7 +3293,8 @@ - IBlockState iblockstate = this.getBlockState(pos); - AxisAlignedBB axisalignedbb = skipCollisionCheck ? null : blockIn.getDefaultState().getCollisionBoundingBox(this, pos); - -- if (axisalignedbb != Block.NULL_AABB && !this.checkNoEntityCollision(axisalignedbb.offset(pos), placer)) -+ if (!((placer instanceof EntityPlayer) || !net.minecraftforge.event.ForgeEventFactory.onBlockPlace(placer, new net.minecraftforge.common.util.BlockSnapshot(this, pos, blockIn.getDefaultState()), sidePlacedOn).isCanceled())) return false; -+ if (axisalignedbb != Block.NULL_AABB && !this.checkNoEntityCollision(axisalignedbb.offset(pos))) // Forge: Remove second parameter, we patch placer to be non-null, passing it here skips collision checks for the placer - { - return false; - } -@@ -3077,7 +3302,7 @@ - { - return iblockstate.getMaterial() == Material.CIRCUITS && blockIn == Blocks.ANVIL - ? true -- : iblockstate.getMaterial().isReplaceable() && blockIn.canPlaceBlockOnSide(this, pos, sidePlacedOn); -+ : iblockstate.getBlock().isReplaceable(this, pos) && blockIn.canPlaceBlockOnSide(this, pos, sidePlacedOn); - } - } - -@@ -3163,7 +3388,7 @@ - public int getRedstonePower(BlockPos pos, EnumFacing facing) - { - IBlockState iblockstate = this.getBlockState(pos); -- return iblockstate.isNormalCube() ? this.getStrongPower(pos) : iblockstate.getWeakPower(this, pos, facing); -+ return iblockstate.getBlock().shouldCheckWeakPower(iblockstate, this, pos, facing) ? this.getStrongPower(pos) : iblockstate.getWeakPower(this, pos, facing); - } - - public boolean isBlockPowered(BlockPos pos) -@@ -3340,6 +3565,8 @@ - d2 *= MoreObjects.firstNonNull(playerToDouble.apply(entityplayer1), 1.0); - } - -+ d2 = net.minecraftforge.common.ForgeHooks.getPlayerVisibilityDistance(entityplayer1, d2, maxYDistance); -+ - if ((maxYDistance < 0.0 || Math.abs(entityplayer1.posY - posY) < maxYDistance * maxYDistance) - && (maxXZDistance < 0.0 || d1 < d2 * d2) - && (d0 == -1.0 || d1 < d0)) -@@ -3403,7 +3630,7 @@ - - public long getSeed() - { -- return this.worldInfo.getSeed(); -+ return this.provider.getSeed(); - } - - public long getTotalWorldTime() -@@ -3413,17 +3640,17 @@ - - public long getWorldTime() - { -- return this.worldInfo.getWorldTime(); -+ return this.provider.getWorldTime(); - } - - public void setWorldTime(long time) - { -- this.worldInfo.setWorldTime(time); -+ this.provider.setWorldTime(time); - } - - public BlockPos getSpawnPoint() - { -- BlockPos blockpos = new BlockPos(this.worldInfo.getSpawnX(), this.worldInfo.getSpawnY(), this.worldInfo.getSpawnZ()); -+ BlockPos blockpos = this.provider.getSpawnPoint(); - - if (!this.getWorldBorder().contains(blockpos)) - { -@@ -3435,7 +3662,7 @@ - - public void setSpawnPoint(BlockPos pos) - { -- this.worldInfo.setSpawn(pos); -+ this.provider.setSpawnPoint(pos); - } - - @SideOnly(Side.CLIENT) -@@ -3455,12 +3682,18 @@ - - if (!this.loadedEntityList.contains(entityIn)) - { -+ if (!net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.EntityJoinWorldEvent(entityIn, this))) - this.loadedEntityList.add(entityIn); - } - } - - public boolean isBlockModifiable(EntityPlayer player, BlockPos pos) - { -+ return this.provider.canMineBlock(player, pos); -+ } -+ -+ public boolean canMineBlockBody(EntityPlayer player, BlockPos pos) -+ { - return true; - } - -@@ -3562,8 +3795,7 @@ - - public boolean isBlockinHighHumidity(BlockPos pos) - { -- Biome biome = this.getBiome(pos); -- return biome.isHighHumidity(); -+ return this.provider.isBlockHighHumidity(pos); - } - - @Nullable -@@ -3624,12 +3856,12 @@ - - public int getHeight() - { -- return 256; -+ return this.provider.getHeight(); - } - - public int getActualHeight() - { -- return this.provider.isNether() ? 128 : 256; -+ return this.provider.getActualHeight(); - } - - public Random setRandomSeed(int seedX, int seedY, int seedZ) -@@ -3642,7 +3874,7 @@ - @SideOnly(Side.CLIENT) - public double getHorizon() - { -- return this.worldInfo.getTerrainType() == WorldType.FLAT ? 0.0 : 63.0; -+ return provider.getHorizon(); - } - - public CrashReportCategory addWorldInfoToCrashReport(CrashReport report) -@@ -3709,7 +3941,7 @@ - - public void updateComparatorOutputLevel(BlockPos pos, Block blockIn) - { -- for (EnumFacing enumfacing : EnumFacing.Plane.HORIZONTAL) -+ for (EnumFacing enumfacing : EnumFacing.VALUES) - { - BlockPos blockpos = pos.offset(enumfacing); - -@@ -3717,18 +3949,15 @@ - { - IBlockState iblockstate = this.getBlockState(blockpos); - -- if (Blocks.UNPOWERED_COMPARATOR.isSameDiode(iblockstate)) -- { -- iblockstate.neighborChanged(this, blockpos, blockIn, pos); -- } -- else if (iblockstate.isNormalCube()) -+ iblockstate.getBlock().onNeighborChange(this, blockpos, pos); -+ if (iblockstate.getBlock().isNormalCube(iblockstate, this, blockpos)) - { - blockpos = blockpos.offset(enumfacing); - iblockstate = this.getBlockState(blockpos); - -- if (Blocks.UNPOWERED_COMPARATOR.isSameDiode(iblockstate)) -+ if (iblockstate.getBlock().getWeakChanges(this, blockpos)) - { -- iblockstate.neighborChanged(this, blockpos, blockIn, pos); -+ iblockstate.getBlock().onNeighborChange(this, blockpos, pos); - } - } - } -@@ -3792,6 +4021,124 @@ - int j = z * 16 + 8 - blockpos.getZ(); - int k = 128; - return i >= -128 && i <= 128 && j >= -128 && j <= 128; -+ } -+ -+ /* ======================================== FORGE START =====================================*/ -+ /** -+ * Determine if the given block is considered solid on the -+ * specified side. Used by placement logic. -+ * -+ * @param pos Block Position -+ * @param side The Side in question -+ * @return True if the side is solid -+ */ -+ public boolean isSideSolid(BlockPos pos, EnumFacing side) -+ { -+ return isSideSolid(pos, side, false); -+ } -+ -+ /** -+ * Determine if the given block is considered solid on the -+ * specified side. Used by placement logic. -+ * -+ * @param pos Block Position -+ * @param side The Side in question -+ * @param _default The default to return if the block doesn't exist. -+ * @return True if the side is solid -+ */ -+ @Override -+ public boolean isSideSolid(BlockPos pos, EnumFacing side, boolean _default) -+ { -+ if (!this.isValid(pos)) return _default; -+ -+ Chunk chunk = getChunk(pos); -+ if (chunk == null || chunk.isEmpty()) return _default; -+ return getBlockState(pos).isSideSolid(this, pos, side); -+ } -+ -+ /** -+ * Get the persistent chunks for this world -+ * -+ * @return -+ */ -+ public com.google.common.collect.ImmutableSetMultimap getPersistentChunks() -+ { -+ return net.minecraftforge.common.ForgeChunkManager.getPersistentChunksFor(this); -+ } -+ -+ public Iterator getPersistentChunkIterable(Iterator chunkIterator) -+ { -+ return net.minecraftforge.common.ForgeChunkManager.getPersistentChunksIterableFor(this, chunkIterator); -+ } -+ /** -+ * Readded as it was removed, very useful helper function -+ * -+ * @param pos Block position -+ * @return The blocks light opacity -+ */ -+ public int getBlockLightOpacity(BlockPos pos) -+ { -+ if (!this.isValid(pos)) return 0; -+ return getChunk(pos).getBlockLightOpacity(pos); -+ } -+ -+ /** -+ * Returns a count of entities that classify themselves as the specified creature type. -+ */ -+ public int countEntities(net.minecraft.entity.EnumCreatureType type, boolean forSpawnCount) -+ { -+ int count = 0; -+ for (int x = 0; x < loadedEntityList.size(); x++) -+ { -+ if (((Entity)loadedEntityList.get(x)).isCreatureType(type, forSpawnCount)) -+ { -+ count++; -+ } -+ } -+ return count; -+ } -+ -+ @Deprecated // remove in 1.13 -+ public void markTileEntitiesInChunkForRemoval(Chunk chunk) -+ { -+ for (TileEntity tileentity : chunk.getTileEntityMap().values()) -+ { -+ markTileEntityForRemoval(tileentity); -+ } -+ } -+ -+ protected void initCapabilities() -+ { -+ net.minecraftforge.common.capabilities.ICapabilityProvider parent = provider.initCapabilities(); -+ capabilities = net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(this, parent); -+ net.minecraftforge.common.util.WorldCapabilityData data = (net.minecraftforge.common.util.WorldCapabilityData)perWorldStorage.getOrLoadData(net.minecraftforge.common.util.WorldCapabilityData.class, net.minecraftforge.common.util.WorldCapabilityData.ID); -+ if (data == null) -+ { -+ capabilityData = new net.minecraftforge.common.util.WorldCapabilityData(capabilities); -+ perWorldStorage.setData(capabilityData.mapName, capabilityData); -+ } -+ else -+ { -+ capabilityData = data; -+ capabilityData.setCapabilities(provider, capabilities); -+ } -+ } -+ @Override -+ public boolean hasCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable EnumFacing facing) -+ { -+ return capabilities == null ? false : capabilities.hasCapability(capability, facing); -+ } -+ @Override -+ @Nullable -+ public T getCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable EnumFacing facing) -+ { -+ return capabilities == null ? null : capabilities.getCapability(capability, facing); -+ } -+ -+ protected MapStorage perWorldStorage; //Moved to a getter to simulate final without being final so we can load in subclasses. -+ public MapStorage getPerWorldStorage() -+ { -+ return perWorldStorage; - } - - public void sendPacketToServer(Packet packetIn) diff --git a/patches/minecraft/net/minecraft/world/WorldEntitySpawner.java.patch b/patches/minecraft/net/minecraft/world/WorldEntitySpawner.java.patch deleted file mode 100644 index d91a4c997..000000000 --- a/patches/minecraft/net/minecraft/world/WorldEntitySpawner.java.patch +++ /dev/null @@ -1,109 +0,0 @@ ---- before/net/minecraft/world/WorldEntitySpawner.java -+++ after/net/minecraft/world/WorldEntitySpawner.java -@@ -81,15 +81,17 @@ - && (enumcreaturetype.getPeacefulCreature() || spawnHostileMobs) - && (!enumcreaturetype.getAnimal() || spawnOnSetTickRate)) - { -- int k4 = worldServerIn.countEntities(enumcreaturetype.getCreatureClass()); -+ int k4 = worldServerIn.countEntities(enumcreaturetype, true); - int l4 = enumcreaturetype.getMaxNumberOfCreature() * i / MOB_COUNT_DIV; - - if (k4 <= l4) - { -+ java.util.ArrayList shuffled = com.google.common.collect.Lists.newArrayList(this.eligibleChunksForSpawning); -+ java.util.Collections.shuffle(shuffled); - BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos(); - label134: - -- for (ChunkPos chunkpos1 : this.eligibleChunksForSpawning) -+ for (ChunkPos chunkpos1 : shuffled) - { - BlockPos blockpos = getRandomChunkPosition(worldServerIn, chunkpos1.x, chunkpos1.z); - int k1 = blockpos.getX(); -@@ -141,7 +143,7 @@ - - try - { -- entityliving = biome$spawnlistentry.entityClass.getConstructor(World.class).newInstance(worldServerIn); -+ entityliving = biome$spawnlistentry.newInstance(worldServerIn); - } - catch (Exception exception) - { -@@ -151,8 +153,10 @@ - - entityliving.setLocationAndAngles(f, i3, f1, worldServerIn.rand.nextFloat() * 360.0F, 0.0F); - -- if (entityliving.getCanSpawnHere() && entityliving.isNotColliding()) -+ net.minecraftforge.fml.common.eventhandler.Event.Result canSpawn = net.minecraftforge.event.ForgeEventFactory.canEntitySpawn(entityliving, worldServerIn, f, i3, f1, false); -+ if (canSpawn == net.minecraftforge.fml.common.eventhandler.Event.Result.ALLOW || (canSpawn == net.minecraftforge.fml.common.eventhandler.Event.Result.DEFAULT && (entityliving.getCanSpawnHere() && entityliving.isNotColliding()))) - { -+ if (!net.minecraftforge.event.ForgeEventFactory.doSpecialSpawn(entityliving, worldServerIn, f, i3, f1)) - ientitylivingdata = entityliving.onInitialSpawn(worldServerIn.getDifficultyForLocation(new BlockPos(entityliving)), ientitylivingdata); - - if (entityliving.isNotColliding()) -@@ -165,7 +169,7 @@ - entityliving.setDead(); - } - -- if (j2 >= entityliving.getMaxSpawnedInChunk()) -+ if (j2 >= net.minecraftforge.event.ForgeEventFactory.getMaxSpawnPackSize(entityliving)) - { - continue label134; - } -@@ -206,9 +210,13 @@ - { - return false; - } -+ else if (state.getMaterial().isLiquid()) -+ { -+ return false; -+ } - else - { -- return state.getMaterial().isLiquid() ? false : !BlockRailBase.isRailBlock(state); -+ return !BlockRailBase.isRailBlock(state); - } - } - -@@ -220,6 +228,13 @@ - } - else - { -+ return spawnPlacementTypeIn.canSpawnAt(worldIn, pos); -+ } -+ } -+ -+ public static boolean canCreatureTypeSpawnBody(EntityLiving.SpawnPlacementType spawnPlacementTypeIn, World worldIn, BlockPos pos) -+ { -+ { - IBlockState iblockstate = worldIn.getBlockState(pos); - - if (spawnPlacementTypeIn == EntityLiving.SpawnPlacementType.IN_WATER) -@@ -231,8 +246,9 @@ - else - { - BlockPos blockpos = pos.down(); -+ IBlockState state = worldIn.getBlockState(blockpos); - -- if (!worldIn.getBlockState(blockpos).isTopSolid()) -+ if (!state.getBlock().canCreatureSpawn(state, worldIn, blockpos, spawnPlacementTypeIn)) - { - return false; - } -@@ -276,7 +292,7 @@ - - try - { -- entityliving = biome$spawnlistentry.entityClass.getConstructor(World.class).newInstance(worldIn); -+ entityliving = biome$spawnlistentry.newInstance(worldIn); - } - catch (Exception exception) - { -@@ -284,6 +300,7 @@ - continue; - } - -+ if (net.minecraftforge.event.ForgeEventFactory.canEntitySpawn(entityliving, worldIn, j + 0.5f, (float) blockpos.getY(), k +0.5f, false) == net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) continue; - entityliving.setLocationAndAngles(j + 0.5F, blockpos.getY(), k + 0.5F, randomIn.nextFloat() * 360.0F, 0.0F); - worldIn.spawnEntity(entityliving); - ientitylivingdata = entityliving.onInitialSpawn(worldIn.getDifficultyForLocation(new BlockPos(entityliving)), ientitylivingdata); diff --git a/patches/minecraft/net/minecraft/world/WorldProvider.java.patch b/patches/minecraft/net/minecraft/world/WorldProvider.java.patch deleted file mode 100644 index ce483757c..000000000 --- a/patches/minecraft/net/minecraft/world/WorldProvider.java.patch +++ /dev/null @@ -1,447 +0,0 @@ ---- before/net/minecraft/world/WorldProvider.java -+++ after/net/minecraft/world/WorldProvider.java -@@ -55,45 +55,12 @@ - protected void init() - { - this.hasSkyLight = true; -- WorldType worldtype = this.world.getWorldInfo().getTerrainType(); -- -- if (worldtype == WorldType.FLAT) -- { -- FlatGeneratorInfo flatgeneratorinfo = FlatGeneratorInfo.createFlatGeneratorFromString(this.world.getWorldInfo().getGeneratorOptions()); -- this.biomeProvider = new BiomeProviderSingle(Biome.getBiome(flatgeneratorinfo.getBiome(), Biomes.DEFAULT)); -- } -- else if (worldtype == WorldType.DEBUG_ALL_BLOCK_STATES) -- { -- this.biomeProvider = new BiomeProviderSingle(Biomes.PLAINS); -- } -- else -- { -- this.biomeProvider = new BiomeProvider(this.world.getWorldInfo()); -- } -+ this.biomeProvider = this.terrainType.getBiomeProvider(world); - } - - public IChunkGenerator createChunkGenerator() - { -- if (this.terrainType == WorldType.FLAT) -- { -- return new ChunkGeneratorFlat( -- this.world, this.world.getSeed(), this.world.getWorldInfo().isMapFeaturesEnabled(), this.generatorSettings -- ); -- } -- else if (this.terrainType == WorldType.DEBUG_ALL_BLOCK_STATES) -- { -- return new ChunkGeneratorDebug(this.world); -- } -- else -- { -- return this.terrainType == WorldType.CUSTOMIZED -- ? new ChunkGeneratorOverworld( -- this.world, this.world.getSeed(), this.world.getWorldInfo().isMapFeaturesEnabled(), this.generatorSettings -- ) -- : new ChunkGeneratorOverworld( -- this.world, this.world.getSeed(), this.world.getWorldInfo().isMapFeaturesEnabled(), this.generatorSettings -- ); -- } -+ return this.terrainType.getChunkGenerator(world, generatorSettings); - } - - public boolean canCoordinateBeSpawn(int x, int z) -@@ -180,7 +147,7 @@ - @SideOnly(Side.CLIENT) - public float getCloudHeight() - { -- return 128.0F; -+ return this.terrainType.getCloudHeight(); - } - - @SideOnly(Side.CLIENT) -@@ -197,13 +164,13 @@ - - public int getAverageGroundLevel() - { -- return this.terrainType == WorldType.FLAT ? 4 : this.world.getSeaLevel() + 1; -+ return this.terrainType.getMinimumSpawnHeight(this.world); - } - - @SideOnly(Side.CLIENT) - public double getVoidFogYFactor() - { -- return this.terrainType == WorldType.FLAT ? 1.0 : 0.03125; -+ return this.terrainType.voidFadeMagnitude(); - } - - @SideOnly(Side.CLIENT) -@@ -240,6 +207,371 @@ - public WorldBorder createWorldBorder() - { - return new WorldBorder(); -+ } -+ -+ /*======================================= Forge Start =========================================*/ -+ private net.minecraftforge.client.IRenderHandler skyRenderer = null; -+ private net.minecraftforge.client.IRenderHandler cloudRenderer = null; -+ private net.minecraftforge.client.IRenderHandler weatherRenderer = null; -+ private int dimensionId; -+ -+ /** -+ * Sets the providers current dimension ID, used in default getSaveFolder() -+ * Added to allow default providers to be registered for multiple dimensions. -+ * This is to denote the exact dimension ID opposed to the 'type' in WorldType -+ * -+ * @param dim Dimension ID -+ */ -+ public void setDimension(int dim) -+ { -+ this.dimensionId = dim; -+ } -+ public int getDimension() -+ { -+ return this.dimensionId; -+ } -+ -+ /** -+ * Returns the sub-folder of the world folder that this WorldProvider saves to. -+ * EXA: DIM1, DIM-1 -+ * @return The sub-folder name to save this world's chunks to. -+ */ -+ @Nullable -+ public String getSaveFolder() -+ { -+ return (dimensionId == 0 ? null : "DIM" + dimensionId); -+ } -+ -+ /** -+ * The dimension's movement factor. -+ * Whenever a player or entity changes dimension from world A to world B, their coordinates are multiplied by -+ * worldA.provider.getMovementFactor() / worldB.provider.getMovementFactor() -+ * Example: Overworld factor is 1, nether factor is 8. Traveling from overworld to nether multiplies coordinates by 1/8. -+ * @return The movement factor -+ */ -+ public double getMovementFactor() -+ { -+ if (this instanceof WorldProviderHell) -+ { -+ return 8.0; -+ } -+ return 1.0; -+ } -+ -+ /** -+ * If this method returns true, then chunks received by the client will -+ * have {@link net.minecraft.world.chunk.Chunk#resetRelightChecks} called -+ * on them, queuing lighting checks for all air blocks in the chunk (and -+ * any adjacent light-emitting blocks). -+ * -+ * Returning true here is recommended if the chunk generator used also -+ * does this for newly generated chunks. -+ * -+ * @return true if lighting checks should be performed -+ */ -+ public boolean shouldClientCheckLighting() -+ { -+ return !(this instanceof WorldProviderSurface); -+ } -+ -+ @Nullable -+ @SideOnly(Side.CLIENT) -+ public net.minecraftforge.client.IRenderHandler getSkyRenderer() -+ { -+ return this.skyRenderer; -+ } -+ -+ @SideOnly(Side.CLIENT) -+ public void setSkyRenderer(net.minecraftforge.client.IRenderHandler skyRenderer) -+ { -+ this.skyRenderer = skyRenderer; -+ } -+ -+ @Nullable -+ @SideOnly(Side.CLIENT) -+ public net.minecraftforge.client.IRenderHandler getCloudRenderer() -+ { -+ return cloudRenderer; -+ } -+ -+ @SideOnly(Side.CLIENT) -+ public void setCloudRenderer(net.minecraftforge.client.IRenderHandler renderer) -+ { -+ cloudRenderer = renderer; -+ } -+ -+ @Nullable -+ @SideOnly(Side.CLIENT) -+ public net.minecraftforge.client.IRenderHandler getWeatherRenderer() -+ { -+ return weatherRenderer; -+ } -+ -+ @SideOnly(Side.CLIENT) -+ public void setWeatherRenderer(net.minecraftforge.client.IRenderHandler renderer) -+ { -+ weatherRenderer = renderer; -+ } -+ -+ /** -+ * Allows for manipulating the coloring of the lightmap texture. -+ * Will be called for each 16*16 combination of sky/block light values. -+ * -+ * @param partialTicks Progress between ticks. -+ * @param sunBrightness Current sun brightness. -+ * @param skyLight Sky light brightness factor. -+ * @param blockLight Block light brightness factor. -+ * @param colors The color values that will be used: [r, g, b]. -+ * -+ * @see net.minecraft.client.renderer.EntityRenderer#updateLightmap(float) -+ */ -+ public void getLightmapColors(float partialTicks, float sunBrightness, float skyLight, float blockLight, float[] colors) {} -+ -+ public BlockPos getRandomizedSpawnPoint() -+ { -+ BlockPos ret = this.world.getSpawnPoint(); -+ -+ boolean isAdventure = world.getWorldInfo().getGameType() == GameType.ADVENTURE; -+ int spawnFuzz = this.world instanceof WorldServer ? terrainType.getSpawnFuzz((WorldServer)this.world, this.world.getMinecraftServer()) : 1; -+ int border = MathHelper.floor(world.getWorldBorder().getClosestDistance(ret.getX(), ret.getZ())); -+ if (border < spawnFuzz) spawnFuzz = border; -+ -+ if (!isNether() && !isAdventure && spawnFuzz != 0) -+ { -+ if (spawnFuzz < 2) spawnFuzz = 2; -+ int spawnFuzzHalf = spawnFuzz / 2; -+ ret = world.getTopSolidOrLiquidBlock(ret.add(spawnFuzzHalf - world.rand.nextInt(spawnFuzz), 0, spawnFuzzHalf - world.rand.nextInt(spawnFuzz))); -+ } -+ -+ return ret; -+ } -+ /** -+ * Determine if the cursor on the map should 'spin' when rendered, like it does for the player in the nether. -+ * -+ * @param entity The entity holding the map, playername, or frame-ENTITYID -+ * @param x X Position -+ * @param z Z Position -+ * @param rotation the regular rotation of the marker -+ * @return True to 'spin' the cursor -+ */ -+ public boolean shouldMapSpin(String entity, double x, double z, double rotation) -+ { -+ return dimensionId < 0; -+ } -+ -+ /** -+ * Determines the dimension the player will be respawned in, typically this brings them back to the overworld. -+ * -+ * @param player The player that is respawning -+ * @return The dimension to respawn the player in -+ */ -+ public int getRespawnDimension(net.minecraft.entity.player.EntityPlayerMP player) -+ { -+ return player.getSpawnDimension(); -+ } -+ -+ /** -+ * Called from {@link World#initCapabilities()}, to gather capabilities for this world. -+ * It's safe to access world here since this is called after world is registered. -+ * -+ * On server, called directly after mapStorage and world data such as Scoreboard and VillageCollection are initialized. -+ * On client, called when world is constructed, just before world load event is called. -+ * Note that this method is always called before the world load event. -+ * @return initial holder for capabilities on the world -+ */ -+ @Nullable -+ public net.minecraftforge.common.capabilities.ICapabilityProvider initCapabilities() { -+ return null; -+ } -+ -+ /** -+ * Called on the client to get the music type to play when in this world type. -+ * At the time of calling, the client player and world are guaranteed to be non-null -+ * @return null to use vanilla logic, otherwise a MusicType to play in this world -+ */ -+ @Nullable -+ @SideOnly(Side.CLIENT) -+ public net.minecraft.client.audio.MusicTicker.MusicType getMusicType() -+ { -+ return null; -+ } -+ -+ /** -+ * Determines if the player can sleep in this world (or if the bed should explode for example). -+ * -+ * @param player The player that is attempting to sleep -+ * @param pos The location where the player tries to sleep at (the position of the clicked on bed for example) -+ * @return the result of a player trying to sleep at the given location -+ */ -+ public WorldSleepResult canSleepAt(net.minecraft.entity.player.EntityPlayer player, BlockPos pos) -+ { -+ return (this.canRespawnHere() && this.world.getBiome(pos) != net.minecraft.init.Biomes.HELL) ? WorldSleepResult.ALLOW : WorldSleepResult.BED_EXPLODES; -+ } -+ -+ public static enum WorldSleepResult -+ { -+ ALLOW, -+ DENY, -+ BED_EXPLODES; -+ } -+ -+ /*======================================= Start Moved From World =========================================*/ -+ -+ public Biome getBiomeForCoords(BlockPos pos) -+ { -+ return world.getBiomeForCoordsBody(pos); -+ } -+ -+ public boolean isDaytime() -+ { -+ return world.getSkylightSubtracted() < 4; -+ } -+ -+ /** -+ * The current sun brightness factor for this dimension. -+ * 0.0f means no light at all, and 1.0f means maximum sunlight. -+ * This will be used for the "calculateSkylightSubtracted" -+ * which is for Sky light value calculation. -+ * -+ * @return The current brightness factor -+ * */ -+ public float getSunBrightnessFactor(float par1) -+ { -+ return world.getSunBrightnessFactor(par1); -+ } -+ -+ /** -+ * Calculates the current moon phase factor. -+ * This factor is effective for slimes. -+ * (This method do not affect the moon rendering) -+ * */ -+ public float getCurrentMoonPhaseFactor() -+ { -+ return world.getCurrentMoonPhaseFactorBody(); -+ } -+ -+ @SideOnly(Side.CLIENT) -+ public Vec3d getSkyColor(net.minecraft.entity.Entity cameraEntity, float partialTicks) -+ { -+ return world.getSkyColorBody(cameraEntity, partialTicks); -+ } -+ -+ @SideOnly(Side.CLIENT) -+ public Vec3d getCloudColor(float partialTicks) -+ { -+ return world.getCloudColorBody(partialTicks); -+ } -+ -+ /** -+ * Gets the Sun Brightness for rendering sky. -+ * */ -+ @SideOnly(Side.CLIENT) -+ public float getSunBrightness(float par1) -+ { -+ return world.getSunBrightnessBody(par1); -+ } -+ -+ /** -+ * Gets the Star Brightness for rendering sky. -+ * */ -+ @SideOnly(Side.CLIENT) -+ public float getStarBrightness(float par1) -+ { -+ return world.getStarBrightnessBody(par1); -+ } -+ -+ public void setAllowedSpawnTypes(boolean allowHostile, boolean allowPeaceful) -+ { -+ world.spawnHostileMobs = allowHostile; -+ world.spawnPeacefulMobs = allowPeaceful; -+ } -+ -+ public void calculateInitialWeather() -+ { -+ world.calculateInitialWeatherBody(); -+ } -+ -+ public void updateWeather() -+ { -+ world.updateWeatherBody(); -+ } -+ -+ public boolean canBlockFreeze(BlockPos pos, boolean byWater) -+ { -+ return world.canBlockFreezeBody(pos, byWater); -+ } -+ -+ public boolean canSnowAt(BlockPos pos, boolean checkLight) -+ { -+ return world.canSnowAtBody(pos, checkLight); -+ } -+ public void setWorldTime(long time) -+ { -+ world.worldInfo.setWorldTime(time); -+ } -+ -+ public long getSeed() -+ { -+ return world.worldInfo.getSeed(); -+ } -+ -+ public long getWorldTime() -+ { -+ return world.worldInfo.getWorldTime(); -+ } -+ -+ public BlockPos getSpawnPoint() -+ { -+ net.minecraft.world.storage.WorldInfo info = world.worldInfo; -+ return new BlockPos(info.getSpawnX(), info.getSpawnY(), info.getSpawnZ()); -+ } -+ -+ public void setSpawnPoint(BlockPos pos) -+ { -+ world.worldInfo.setSpawn(pos); -+ } -+ -+ public boolean canMineBlock(net.minecraft.entity.player.EntityPlayer player, BlockPos pos) -+ { -+ return world.canMineBlockBody(player, pos); -+ } -+ -+ public boolean isBlockHighHumidity(BlockPos pos) -+ { -+ return world.getBiome(pos).isHighHumidity(); -+ } -+ -+ public int getHeight() -+ { -+ return 256; -+ } -+ -+ public int getActualHeight() -+ { -+ return nether ? 128 : 256; -+ } -+ -+ public double getHorizon() -+ { -+ return world.worldInfo.getTerrainType().getHorizon(world); -+ } -+ -+ public void resetRainAndThunder() -+ { -+ world.worldInfo.setRainTime(0); -+ world.worldInfo.setRaining(false); -+ world.worldInfo.setThunderTime(0); -+ world.worldInfo.setThundering(false); -+ } -+ -+ public boolean canDoLightning(net.minecraft.world.chunk.Chunk chunk) -+ { -+ return true; -+ } -+ -+ public boolean canDoRainSnowIce(net.minecraft.world.chunk.Chunk chunk) -+ { -+ return true; - } - - public void onPlayerAdded(EntityPlayerMP player) diff --git a/patches/minecraft/net/minecraft/world/WorldProviderEnd.java.patch b/patches/minecraft/net/minecraft/world/WorldProviderEnd.java.patch deleted file mode 100644 index 6ee673e2d..000000000 --- a/patches/minecraft/net/minecraft/world/WorldProviderEnd.java.patch +++ /dev/null @@ -1,44 +0,0 @@ ---- before/net/minecraft/world/WorldProviderEnd.java -+++ after/net/minecraft/world/WorldProviderEnd.java -@@ -21,7 +21,7 @@ - public void init() - { - this.biomeProvider = new BiomeProviderSingle(Biomes.SKY); -- NBTTagCompound nbttagcompound = this.world.getWorldInfo().getDimensionData(DimensionType.THE_END); -+ NBTTagCompound nbttagcompound = this.world.getWorldInfo().getDimensionData(this.world.provider.getDimension()); - this.dragonFightManager = this.world instanceof WorldServer - ? new DragonFightManager((WorldServer)this.world, nbttagcompound.getCompoundTag("DragonFight")) - : null; -@@ -132,7 +132,7 @@ - nbttagcompound.setTag("DragonFight", this.dragonFightManager.getCompound()); - } - -- this.world.getWorldInfo().setDimensionData(DimensionType.THE_END, nbttagcompound); -+ this.world.getWorldInfo().setDimensionData(this.world.provider.getDimension(), nbttagcompound); - } - - @Override -@@ -148,5 +148,23 @@ - public DragonFightManager getDragonFightManager() - { - return this.dragonFightManager; -+ } -+ -+ @Override -+ public void onPlayerAdded(net.minecraft.entity.player.EntityPlayerMP player) -+ { -+ if (this.dragonFightManager != null) -+ { -+ this.dragonFightManager.addPlayer(player); -+ } -+ } -+ -+ @Override -+ public void onPlayerRemoved(net.minecraft.entity.player.EntityPlayerMP player) -+ { -+ if (this.dragonFightManager != null) -+ { -+ this.dragonFightManager.removePlayer(player); -+ } - } - } diff --git a/patches/minecraft/net/minecraft/world/WorldProviderSurface.java.patch b/patches/minecraft/net/minecraft/world/WorldProviderSurface.java.patch deleted file mode 100644 index 56752d016..000000000 --- a/patches/minecraft/net/minecraft/world/WorldProviderSurface.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- before/net/minecraft/world/WorldProviderSurface.java -+++ after/net/minecraft/world/WorldProviderSurface.java -@@ -11,6 +11,6 @@ - @Override - public boolean canDropChunk(int x, int z) - { -- return !this.world.isSpawnChunk(x, z); -+ return !this.world.isSpawnChunk(x, z) || !this.world.provider.getDimensionType().shouldLoadSpawn(); - } - } diff --git a/patches/minecraft/net/minecraft/world/WorldServer.java.patch b/patches/minecraft/net/minecraft/world/WorldServer.java.patch deleted file mode 100644 index d43db3346..000000000 --- a/patches/minecraft/net/minecraft/world/WorldServer.java.patch +++ /dev/null @@ -1,307 +0,0 @@ ---- before/net/minecraft/world/WorldServer.java -+++ after/net/minecraft/world/WorldServer.java -@@ -103,18 +103,27 @@ - private int blockEventCacheIndex; - private final List pendingTickListEntriesThisTick = Lists.newArrayList(); - -+ /** Stores the recently processed (lighting) chunks */ -+ protected Set doneChunks = new java.util.HashSet<>(); -+ public List customTeleporters = new ArrayList<>(); -+ - public WorldServer(MinecraftServer server, ISaveHandler saveHandlerIn, WorldInfo info, int dimensionId, Profiler profilerIn) - { -- super(saveHandlerIn, info, DimensionType.getById(dimensionId).createDimension(), profilerIn, false); -+ super(saveHandlerIn, info, net.minecraftforge.common.DimensionManager.createProviderFor(dimensionId), profilerIn, false); - this.server = server; - this.entityTracker = new EntityTracker(this); - this.playerChunkMap = new PlayerChunkMap(this); -+ // Guarantee the dimension ID was not reset by the provider -+ int providerDim = this.provider.getDimension(); - this.provider.setWorld(this); -+ this.provider.setDimension(providerDim); - this.chunkProvider = this.createChunkProvider(); -+ perWorldStorage = new MapStorage(new net.minecraftforge.common.WorldSpecificSaveHandler(this, saveHandlerIn)); - this.worldTeleporter = new Teleporter(this); - this.calculateInitialSkylight(); - this.calculateInitialWeather(); - this.getWorldBorder().setSize(server.getMaxWorldSize()); -+ net.minecraftforge.common.DimensionManager.setWorld(dimensionId, this, server); - } - - @Override -@@ -122,12 +131,12 @@ - { - this.mapStorage = new MapStorage(this.saveHandler); - String s = VillageCollection.fileNameForProvider(this.provider); -- VillageCollection villagecollection = (VillageCollection)this.mapStorage.getOrLoadData(VillageCollection.class, s); -+ VillageCollection villagecollection = (VillageCollection)this.perWorldStorage.getOrLoadData(VillageCollection.class, s); - - if (villagecollection == null) - { - this.villageCollection = new VillageCollection(this); -- this.mapStorage.setData(s, this.villageCollection); -+ this.perWorldStorage.setData(s, this.villageCollection); - } - else - { -@@ -164,6 +173,7 @@ - this.getWorldBorder().setTransition(this.worldInfo.getBorderSize()); - } - -+ this.initCapabilities(); - return this; - } - -@@ -183,8 +193,8 @@ - { - if (this.getGameRules().getBoolean("doDaylightCycle")) - { -- long i = this.worldInfo.getWorldTime() + 24000L; -- this.worldInfo.setWorldTime(i - i % 24000L); -+ long i = this.getWorldTime() + 24000L; -+ this.setWorldTime(i - i % 24000L); - } - - this.wakeAllPlayers(); -@@ -210,7 +220,7 @@ - - if (this.getGameRules().getBoolean("doDaylightCycle")) - { -- this.worldInfo.setWorldTime(this.worldInfo.getWorldTime() + 1L); -+ this.setWorldTime(this.getWorldTime() + 1L); - } - - this.profiler.endStartSection("tickPending"); -@@ -224,6 +234,10 @@ - this.villageSiege.tick(); - this.profiler.endStartSection("portalForcer"); - this.worldTeleporter.removeStalePortalLocations(this.getTotalWorldTime()); -+ for (Teleporter tele : customTeleporters) -+ { -+ tele.removeStalePortalLocations(getTotalWorldTime()); -+ } - this.profiler.endSection(); - this.sendQueuedBlockEvents(); - } -@@ -232,12 +246,14 @@ - public Biome.SpawnListEntry getSpawnListEntryForTypeAt(EnumCreatureType creatureType, BlockPos pos) - { - List list = this.getChunkProvider().getPossibleCreatures(creatureType, pos); -+ list = net.minecraftforge.event.ForgeEventFactory.getPotentialSpawns(this, creatureType, pos, list); - return list != null && !list.isEmpty() ? WeightedRandom.getRandomItem(this.rand, list) : null; - } - - public boolean canCreatureTypeSpawnHere(EnumCreatureType creatureType, Biome.SpawnListEntry spawnListEntry, BlockPos pos) - { - List list = this.getChunkProvider().getPossibleCreatures(creatureType, pos); -+ list = net.minecraftforge.event.ForgeEventFactory.getPotentialSpawns(this, creatureType, pos, list); - return list != null && !list.isEmpty() ? list.contains(spawnListEntry) : false; - } - -@@ -284,10 +300,7 @@ - - private void resetRainAndThunder() - { -- this.worldInfo.setRainTime(0); -- this.worldInfo.setRaining(false); -- this.worldInfo.setThunderTime(0); -- this.worldInfo.setThundering(false); -+ this.provider.resetRainAndThunder(); - } - - public boolean areAllPlayersAsleep() -@@ -382,7 +395,7 @@ - boolean flag1 = this.isThundering(); - this.profiler.startSection("pollingChunks"); - -- for (Iterator iterator = this.playerChunkMap.getChunkIterator(); iterator.hasNext(); this.profiler.endSection()) -+ for (Iterator iterator = getPersistentChunkIterable(this.playerChunkMap.getChunkIterator()); iterator.hasNext(); this.profiler.endSection()) - { - this.profiler.startSection("getChunk"); - Chunk chunk = iterator.next(); -@@ -394,7 +407,7 @@ - chunk.onTick(false); - this.profiler.endStartSection("thunder"); - -- if (flag && flag1 && this.rand.nextInt(100000) == 0) -+ if (this.provider.canDoLightning(chunk) && flag && flag1 && this.rand.nextInt(100000) == 0) - { - this.updateLCG = this.updateLCG * 3 + 1013904223; - int l = this.updateLCG >> 2; -@@ -422,13 +435,14 @@ - - this.profiler.endStartSection("iceandsnow"); - -- if (this.rand.nextInt(16) == 0) -+ if (this.provider.canDoRainSnowIce(chunk) && this.rand.nextInt(16) == 0) - { - this.updateLCG = this.updateLCG * 3 + 1013904223; - int j2 = this.updateLCG >> 2; - BlockPos blockpos1 = this.getPrecipitationHeight(new BlockPos(j + (j2 & 15), 0, k + (j2 >> 8 & 15))); - BlockPos blockpos2 = blockpos1.down(); - -+ if (this.isAreaLoaded(blockpos2, 1)) // Forge: check area to avoid loading neighbors in unloaded chunks - if (this.canBlockFreezeNoWater(blockpos2)) - { - this.setBlockState(blockpos2, Blocks.ICE.getDefaultState()); -@@ -537,7 +551,10 @@ - { - if (blockIn.requiresUpdates()) - { -- if (this.isAreaLoaded(pos.add(-8, -8, -8), pos.add(8, 8, 8))) -+ //Keeping here as a note for future when it may be restored. -+ boolean isForced = getPersistentChunks().containsKey(new ChunkPos(pos)); -+ int range = isForced ? 0 : 8; -+ if (this.isAreaLoaded(pos.add(-range, -range, -range), pos.add(range, range, range))) - { - IBlockState iblockstate = this.getBlockState(pos); - -@@ -574,6 +591,7 @@ - @Override - public void scheduleBlockUpdate(BlockPos pos, Block blockIn, int delay, int priority) - { -+ if (blockIn == null) return; //Forge: Prevent null blocks from ticking, can happen if blocks are removed in old worlds. TODO: Fix real issue causing block to be null. - NextTickListEntry nextticklistentry = new NextTickListEntry(pos, blockIn); - nextticklistentry.setPriority(priority); - Material material = blockIn.getDefaultState().getMaterial(); -@@ -593,7 +611,7 @@ - @Override - public void updateEntities() - { -- if (this.playerEntities.isEmpty()) -+ if (this.playerEntities.isEmpty() && getPersistentChunks().isEmpty()) - { - if (this.updateEntityTick++ >= 300) - { -@@ -719,6 +737,9 @@ - { - NextTickListEntry nextticklistentry1 = iterator.next(); - iterator.remove(); -+ //Keeping here as a note for future when it may be restored. -+ //boolean isForced = getPersistentChunks().containsKey(new ChunkPos(nextticklistentry.xCoord >> 4, nextticklistentry.zCoord >> 4)); -+ //byte b0 = isForced ? 0 : 8; - int k = 0; - - if (this.isAreaLoaded(nextticklistentry1.position.add(0, 0, 0), nextticklistentry1.position.add(0, 0, 0))) -@@ -854,6 +875,10 @@ - @Override - public boolean isBlockModifiable(EntityPlayer player, BlockPos pos) - { -+ return super.isBlockModifiable(player, pos); -+ } -+ public boolean canMineBlockBody(EntityPlayer player, BlockPos pos) -+ { - return !this.server.isBlockProtected(this, pos, player) && this.getWorldBorder().contains(pos); - } - -@@ -919,6 +944,7 @@ - } - else - { -+ if (net.minecraftforge.event.ForgeEventFactory.onCreateWorldSpawn(this, settings)) return; - this.findingSpawnPoint = true; - BiomeProvider biomeprovider = this.provider.getBiomeProvider(); - List list = biomeprovider.getBiomesToSpawnIn(); -@@ -1003,6 +1029,7 @@ - } - - chunkproviderserver.saveChunks(all); -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.WorldEvent.Save(this)); - - for (Chunk chunk : Lists.newArrayList(chunkproviderserver.getLoadedChunks())) - { -@@ -1047,6 +1074,7 @@ - this.worldInfo.setBorderLerpTime(this.getWorldBorder().getTimeUntilTarget()); - this.saveHandler.saveWorldInfoWithPlayer(this.worldInfo, this.server.getPlayerList().getHostPlayerData()); - this.mapStorage.saveAllData(); -+ this.perWorldStorage.saveAllData(); - } - - @Override -@@ -1060,7 +1088,7 @@ - { - for (Entity entity : Lists.newArrayList(entityCollection)) - { -- if (this.canAddEntity(entity)) -+ if (this.canAddEntity(entity) && !net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.EntityJoinWorldEvent(entity, this))) - { - this.loadedEntityList.add(entity); - this.onEntityAdded(entity); -@@ -1152,7 +1180,7 @@ - entityIn.posY, - entityIn.posZ, - 512.0, -- this.provider.getDimensionType().getId(), -+ this.provider.getDimension(), - new SPacketSpawnGlobalEntity(entityIn) - ); - return true; -@@ -1180,6 +1208,7 @@ - ) - { - Explosion explosion = new Explosion(this, entityIn, x, y, z, strength, causesFire, damagesTerrain); -+ if (net.minecraftforge.event.ForgeEventFactory.onExplosionStart(this, explosion)) return explosion; - explosion.doExplosionA(); - explosion.doExplosionB(false); - -@@ -1238,7 +1267,7 @@ - blockeventdata.getPosition().getY(), - blockeventdata.getPosition().getZ(), - 64.0, -- this.provider.getDimensionType().getId(), -+ this.provider.getDimension(), - new SPacketBlockAction( - blockeventdata.getPosition(), blockeventdata.getBlock(), blockeventdata.getEventID(), blockeventdata.getEventParameter() - ) -@@ -1273,29 +1302,33 @@ - { - this.server - .getPlayerList() -- .sendPacketToAllPlayersInDimension(new SPacketChangeGameState(7, this.rainingStrength), this.provider.getDimensionType().getId()); -+ .sendPacketToAllPlayersInDimension(new SPacketChangeGameState(7, this.rainingStrength), this.provider.getDimension()); - } - - if (this.prevThunderingStrength != this.thunderingStrength) - { - this.server - .getPlayerList() -- .sendPacketToAllPlayersInDimension(new SPacketChangeGameState(8, this.thunderingStrength), this.provider.getDimensionType().getId()); -+ .sendPacketToAllPlayersInDimension(new SPacketChangeGameState(8, this.thunderingStrength), this.provider.getDimension()); - } - -+ /* The function in use here has been replaced in order to only send the weather info to players in the correct dimension, -+ * rather than to all players on the server. This is what causes the client-side rain, as the -+ * client believes that it has started raining locally, rather than in another dimension. -+ */ - if (flag != this.isRaining()) - { - if (flag) - { -- this.server.getPlayerList().sendPacketToAllPlayers(new SPacketChangeGameState(2, 0.0F)); -+ this.server.getPlayerList().sendPacketToAllPlayersInDimension(new SPacketChangeGameState(2, 0.0F), this.provider.getDimension()); - } - else - { -- this.server.getPlayerList().sendPacketToAllPlayers(new SPacketChangeGameState(1, 0.0F)); -+ this.server.getPlayerList().sendPacketToAllPlayersInDimension(new SPacketChangeGameState(1, 0.0F), this.provider.getDimension()); - } - -- this.server.getPlayerList().sendPacketToAllPlayers(new SPacketChangeGameState(7, this.rainingStrength)); -- this.server.getPlayerList().sendPacketToAllPlayers(new SPacketChangeGameState(8, this.thunderingStrength)); -+ this.server.getPlayerList().sendPacketToAllPlayersInDimension(new SPacketChangeGameState(7, this.rainingStrength), this.provider.getDimension()); -+ this.server.getPlayerList().sendPacketToAllPlayersInDimension(new SPacketChangeGameState(8, this.thunderingStrength), this.provider.getDimension()); - } - } - -@@ -1456,6 +1489,11 @@ - public FunctionManager getFunctionManager() - { - return this.functionManager; -+ } -+ -+ public java.io.File getChunkSaveLocation() -+ { -+ return ((net.minecraft.world.chunk.storage.AnvilChunkLoader)getChunkProvider().chunkLoader).chunkSaveLocation; - } - - static class ServerBlockEventList extends ArrayList diff --git a/patches/minecraft/net/minecraft/world/WorldServerMulti.java.patch b/patches/minecraft/net/minecraft/world/WorldServerMulti.java.patch deleted file mode 100644 index b3eafa699..000000000 --- a/patches/minecraft/net/minecraft/world/WorldServerMulti.java.patch +++ /dev/null @@ -1,65 +0,0 @@ ---- before/net/minecraft/world/WorldServerMulti.java -+++ after/net/minecraft/world/WorldServerMulti.java -@@ -11,12 +11,13 @@ - public class WorldServerMulti extends WorldServer - { - private final WorldServer delegate; -+ private IBorderListener borderListener; - - public WorldServerMulti(MinecraftServer server, ISaveHandler saveHandlerIn, int dimensionId, WorldServer delegate, Profiler profilerIn) - { - super(server, saveHandlerIn, new DerivedWorldInfo(delegate.getWorldInfo()), dimensionId, profilerIn); - this.delegate = delegate; -- delegate.getWorldBorder().addListener(new IBorderListener() -+ this.borderListener = new IBorderListener() - { - @Override - public void onSizeChanged(WorldBorder border, double newSize) -@@ -53,12 +54,14 @@ - { - WorldServerMulti.this.getWorldBorder().setDamageBuffer(newSize); - } -- }); -+ }; -+ this.delegate.getWorldBorder().addListener(this.borderListener); - } - - @Override - protected void saveLevel() throws MinecraftException - { -+ this.perWorldStorage.saveAllData(); - } - - @Override -@@ -69,12 +72,12 @@ - this.lootTable = this.delegate.getLootTableManager(); - this.advancementManager = this.delegate.getAdvancementManager(); - String s = VillageCollection.fileNameForProvider(this.provider); -- VillageCollection villagecollection = (VillageCollection)this.mapStorage.getOrLoadData(VillageCollection.class, s); -+ VillageCollection villagecollection = (VillageCollection)this.perWorldStorage.getOrLoadData(VillageCollection.class, s); - - if (villagecollection == null) - { - this.villageCollection = new VillageCollection(this); -- this.mapStorage.setData(s, this.villageCollection); -+ this.perWorldStorage.setData(s, this.villageCollection); - } - else - { -@@ -82,7 +85,16 @@ - this.villageCollection.setWorldsForAll(this); - } - -+ this.initCapabilities(); - return this; -+ } -+ -+ -+ @Override -+ public void flush() -+ { -+ super.flush(); -+ this.delegate.getWorldBorder().removeListener(this.borderListener); // Unlink ourselves, to prevent world leak. - } - - public void saveAdditionalData() diff --git a/patches/minecraft/net/minecraft/world/WorldType.java.patch b/patches/minecraft/net/minecraft/world/WorldType.java.patch deleted file mode 100644 index 084c881b5..000000000 --- a/patches/minecraft/net/minecraft/world/WorldType.java.patch +++ /dev/null @@ -1,157 +0,0 @@ ---- before/net/minecraft/world/WorldType.java -+++ after/net/minecraft/world/WorldType.java -@@ -27,6 +27,7 @@ - - private WorldType(int id, String name, int version) - { -+ if (name.length() > 16 && DEBUG_ALL_BLOCK_STATES != null) throw new IllegalArgumentException("World type names must not be longer then 16: " + name); - this.name = name; - this.version = version; - this.canBeCreated = true; -@@ -112,5 +113,146 @@ - { - this.hasInfoNotice = true; - return this; -+ } -+ -+ public net.minecraft.world.biome.BiomeProvider getBiomeProvider(World world) -+ { -+ if (this == FLAT) -+ { -+ net.minecraft.world.gen.FlatGeneratorInfo flatgeneratorinfo = net.minecraft.world.gen.FlatGeneratorInfo.createFlatGeneratorFromString(world.getWorldInfo().getGeneratorOptions()); -+ return new net.minecraft.world.biome.BiomeProviderSingle(net.minecraft.world.biome.Biome.getBiome(flatgeneratorinfo.getBiome(), net.minecraft.init.Biomes.DEFAULT)); -+ } -+ else if (this == DEBUG_ALL_BLOCK_STATES) -+ { -+ return new net.minecraft.world.biome.BiomeProviderSingle(net.minecraft.init.Biomes.PLAINS); -+ } -+ else -+ { -+ return new net.minecraft.world.biome.BiomeProvider(world.getWorldInfo()); -+ } -+ } -+ -+ public net.minecraft.world.gen.IChunkGenerator getChunkGenerator(World world, String generatorOptions) -+ { -+ if (this == FLAT) return new net.minecraft.world.gen.ChunkGeneratorFlat(world, world.getSeed(), world.getWorldInfo().isMapFeaturesEnabled(), generatorOptions); -+ if (this == DEBUG_ALL_BLOCK_STATES) return new net.minecraft.world.gen.ChunkGeneratorDebug(world); -+ if (this == CUSTOMIZED) return new net.minecraft.world.gen.ChunkGeneratorOverworld(world, world.getSeed(), world.getWorldInfo().isMapFeaturesEnabled(), generatorOptions); -+ return new net.minecraft.world.gen.ChunkGeneratorOverworld(world, world.getSeed(), world.getWorldInfo().isMapFeaturesEnabled(), generatorOptions); -+ } -+ -+ public int getMinimumSpawnHeight(World world) -+ { -+ return this == FLAT ? 4 : world.getSeaLevel() + 1; -+ } -+ -+ public double getHorizon(World world) -+ { -+ return this == FLAT ? 0.0D : 63.0D; -+ } -+ -+ public double voidFadeMagnitude() -+ { -+ return this == FLAT ? 1.0D : 0.03125D; -+ } -+ -+ public boolean handleSlimeSpawnReduction(java.util.Random random, World world) -+ { -+ return this == FLAT ? random.nextInt(4) != 1 : false; -+ } -+ -+ /*=================================================== FORGE START ======================================*/ -+ private static int getNextID() -+ { -+ for (int x = 0; x < WORLD_TYPES.length; x++) -+ { -+ if (WORLD_TYPES[x] == null) -+ { -+ return x; -+ } -+ } -+ -+ int oldLen = WORLD_TYPES.length; -+ WORLD_TYPES = java.util.Arrays.copyOf(WORLD_TYPES, oldLen + 16); -+ return oldLen; -+ } -+ -+ /** -+ * Creates a new world type, the ID is hidden and should not be referenced by modders. -+ * It will automatically expand the underlying workdType array if there are no IDs left. -+ * @param name -+ */ -+ public WorldType(String name) -+ { -+ this(getNextID(), name); -+ } -+ -+ /** -+ * Called when 'Create New World' button is pressed before starting game -+ */ -+ public void onGUICreateWorldPress() { } -+ -+ /** -+ * Gets the spawn fuzz for players who join the world. -+ * Useful for void world types. -+ * @return Fuzz for entity initial spawn in blocks. -+ */ -+ public int getSpawnFuzz(WorldServer world, net.minecraft.server.MinecraftServer server) -+ { -+ return Math.max(0, server.getSpawnRadius(world)); -+ } -+ -+ /** -+ * Called when the 'Customize' button is pressed on world creation GUI -+ * @param mc The Minecraft instance -+ * @param guiCreateWorld the createworld GUI -+ */ -+ @SideOnly(Side.CLIENT) -+ public void onCustomizeButton(net.minecraft.client.Minecraft mc, net.minecraft.client.gui.GuiCreateWorld guiCreateWorld) -+ { -+ if (this == WorldType.FLAT) -+ { -+ mc.displayGuiScreen(new net.minecraft.client.gui.GuiCreateFlatWorld(guiCreateWorld, guiCreateWorld.chunkProviderSettingsJson)); -+ } -+ else if (this == WorldType.CUSTOMIZED) -+ { -+ mc.displayGuiScreen(new net.minecraft.client.gui.GuiCustomizeWorldScreen(guiCreateWorld, guiCreateWorld.chunkProviderSettingsJson)); -+ } -+ } -+ -+ /** -+ * Should world creation GUI show 'Customize' button for this world type? -+ * @return if this world type has customization parameters -+ */ -+ public boolean isCustomizable() -+ { -+ return this == FLAT || this == WorldType.CUSTOMIZED; -+ } -+ -+ -+ /** -+ * Get the height to render the clouds for this world type -+ * @return The height to render clouds at -+ */ -+ public float getCloudHeight() -+ { -+ return 128.0F; -+ } -+ -+ /** -+ * Creates the GenLayerBiome used for generating the world with the specified ChunkProviderSettings JSON String -+ * *IF AND ONLY IF* this WorldType == WorldType.CUSTOMIZED. -+ * -+ * -+ * @param worldSeed The world seed -+ * @param parentLayer The parent layer to feed into any layer you return -+ * @param chunkSettings The ChunkGeneratorSettings constructed from the custom JSON -+ * @return A GenLayer that will return ints representing the Biomes to be generated, see GenLayerBiome -+ */ -+ public net.minecraft.world.gen.layer.GenLayer getBiomeLayer(long worldSeed, net.minecraft.world.gen.layer.GenLayer parentLayer, net.minecraft.world.gen.ChunkGeneratorSettings chunkSettings) -+ { -+ net.minecraft.world.gen.layer.GenLayer ret = new net.minecraft.world.gen.layer.GenLayerBiome(200L, parentLayer, this, chunkSettings); -+ ret = net.minecraft.world.gen.layer.GenLayerZoom.magnify(1000L, ret, 2); -+ ret = new net.minecraft.world.gen.layer.GenLayerBiomeEdge(1000L, ret); -+ return ret; - } - } diff --git a/patches/minecraft/net/minecraft/world/biome/Biome.java.patch b/patches/minecraft/net/minecraft/world/biome/Biome.java.patch deleted file mode 100644 index fe267eca9..000000000 --- a/patches/minecraft/net/minecraft/world/biome/Biome.java.patch +++ /dev/null @@ -1,180 +0,0 @@ ---- before/net/minecraft/world/biome/Biome.java -+++ after/net/minecraft/world/biome/Biome.java -@@ -50,7 +50,7 @@ - import org.apache.logging.log4j.LogManager; - import org.apache.logging.log4j.Logger; - --public abstract class Biome -+public abstract class Biome extends net.minecraftforge.registries.IForgeRegistryEntry.Impl - { - private static final Logger LOGGER = LogManager.getLogger(); - protected static final IBlockState STONE = Blocks.STONE.getDefaultState(); -@@ -68,7 +68,7 @@ - protected static final WorldGenTrees TREE_FEATURE = new WorldGenTrees(false); - protected static final WorldGenBigTree BIG_TREE_FEATURE = new WorldGenBigTree(false); - protected static final WorldGenSwamp SWAMP_FEATURE = new WorldGenSwamp(); -- public static final RegistryNamespaced REGISTRY = new RegistryNamespaced<>(); -+ public static final RegistryNamespaced REGISTRY = net.minecraftforge.registries.GameData.getWrapper(Biome.class); - private final String biomeName; - private final float baseHeight; - private final float heightVariation; -@@ -86,6 +86,8 @@ - protected List spawnableCreatureList = Lists.newArrayList(); - protected List spawnableWaterCreatureList = Lists.newArrayList(); - protected List spawnableCaveCreatureList = Lists.newArrayList(); -+ // Forge: Stores the spawnable lists for non-vanilla EnumCreatureTypes. Can't be an EnumMap as that doesn't handle new enum values being added after it's created. -+ protected java.util.Map> modSpawnableLists = com.google.common.collect.Maps.newHashMap(); - - public static int getIdForBiome(Biome biome) - { -@@ -130,11 +132,12 @@ - this.spawnableMonsterList.add(new Biome.SpawnListEntry(EntityWitch.class, 5, 1, 1)); - this.spawnableWaterCreatureList.add(new Biome.SpawnListEntry(EntitySquid.class, 10, 4, 4)); - this.spawnableCaveCreatureList.add(new Biome.SpawnListEntry(EntityBat.class, 10, 8, 8)); -+ this.addDefaultFlowers(); - } - - public BiomeDecorator createBiomeDecorator() - { -- return new BiomeDecorator(); -+ return getModdedBiomeDecorator(new BiomeDecorator()); - } - - public boolean isMutation() -@@ -178,7 +181,9 @@ - case AMBIENT: - return this.spawnableCaveCreatureList; - default: -- return Collections.emptyList(); -+ // Forge: Return a non-empty list for non-vanilla EnumCreatureTypes -+ if (!this.modSpawnableLists.containsKey(creatureType)) this.modSpawnableLists.put(creatureType, Lists.newArrayList()); -+ return this.modSpawnableLists.get(creatureType); - } - } - -@@ -225,7 +230,7 @@ - { - double d0 = MathHelper.clamp(this.getTemperature(pos), 0.0F, 1.0F); - double d1 = MathHelper.clamp(this.getRainfall(), 0.0F, 1.0F); -- return ColorizerGrass.getGrassColor(d0, d1); -+ return getModdedBiomeGrassColor(ColorizerGrass.getGrassColor(d0, d1)); - } - - @SideOnly(Side.CLIENT) -@@ -233,7 +238,7 @@ - { - double d0 = MathHelper.clamp(this.getTemperature(pos), 0.0F, 1.0F); - double d1 = MathHelper.clamp(this.getRainfall(), 0.0F, 1.0F); -- return ColorizerFoliage.getFoliageColor(d0, d1); -+ return getModdedBiomeFoliageColor(ColorizerFoliage.getFoliageColor(d0, d1)); - } - - public void genTerrainBlocks(World worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) -@@ -389,7 +394,7 @@ - @SideOnly(Side.CLIENT) - public final int getWaterColor() - { -- return this.waterColor; -+ return getWaterColorMultiplier(); - } - - public final boolean isSnowyBiome() -@@ -397,6 +402,84 @@ - return this.enableSnow; - } - -+ /* ========================================= FORGE START ======================================*/ -+ protected List flowers = new java.util.ArrayList(); -+ -+ public BiomeDecorator getModdedBiomeDecorator(BiomeDecorator original) -+ { -+ return new net.minecraftforge.event.terraingen.DeferredBiomeDecorator(original); -+ } -+ -+ public int getWaterColorMultiplier() -+ { -+ net.minecraftforge.event.terraingen.BiomeEvent.GetWaterColor event = new net.minecraftforge.event.terraingen.BiomeEvent.GetWaterColor(this, waterColor); -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event); -+ return event.getNewColor(); -+ } -+ -+ public int getModdedBiomeGrassColor(int original) -+ { -+ net.minecraftforge.event.terraingen.BiomeEvent.GetGrassColor event = new net.minecraftforge.event.terraingen.BiomeEvent.GetGrassColor(this, original); -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event); -+ return event.getNewColor(); -+ } -+ -+ public int getModdedBiomeFoliageColor(int original) -+ { -+ net.minecraftforge.event.terraingen.BiomeEvent.GetFoliageColor event = new net.minecraftforge.event.terraingen.BiomeEvent.GetFoliageColor(this, original); -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event); -+ return event.getNewColor(); -+ } -+ -+ /** -+ * Weighted random holder class used to hold possible flowers -+ * that can spawn in this biome when bonemeal is used on grass. -+ */ -+ public static class FlowerEntry extends WeightedRandom.Item -+ { -+ public final net.minecraft.block.state.IBlockState state; -+ public FlowerEntry(net.minecraft.block.state.IBlockState state, int weight) -+ { -+ super(weight); -+ this.state = state; -+ } -+ } -+ -+ /** -+ * Adds the default flowers, as of 1.7, it is 2 yellow, and 1 red. I chose 10 to allow some wiggle room in the numbers. -+ */ -+ public void addDefaultFlowers() -+ { -+ addFlower(Blocks.YELLOW_FLOWER.getDefaultState().withProperty(Blocks.YELLOW_FLOWER.getTypeProperty(), BlockFlower.EnumFlowerType.DANDELION), 20); -+ addFlower(Blocks.RED_FLOWER.getDefaultState().withProperty(Blocks.RED_FLOWER.getTypeProperty(), BlockFlower.EnumFlowerType.POPPY), 10); -+ } -+ -+ /** Register a new plant to be planted when bonemeal is used on grass. -+ * @param state The block to place. -+ * @param weight The weight of the plant, where red flowers are -+ * 10 and yellow flowers are 20. -+ */ -+ public void addFlower(IBlockState state, int weight) -+ { -+ this.flowers.add(new FlowerEntry(state, weight)); -+ } -+ -+ public void plantFlower(World world, Random rand, BlockPos pos) -+ { -+ if (flowers.isEmpty()) return; -+ FlowerEntry flower = (FlowerEntry)WeightedRandom.getRandomItem(rand, flowers); -+ if (flower == null || flower.state == null || -+ (flower.state.getBlock() instanceof net.minecraft.block.BlockBush && -+ !((net.minecraft.block.BlockBush)flower.state.getBlock()).canBlockStay(world, pos, flower.state))) -+ { -+ return; -+ } -+ -+ world.setBlockState(pos, flower.state, 3); -+ } -+ -+ /* ========================================= FORGE END ======================================*/ -+ - public static void registerBiomes() - { - registerBiome(0, "ocean", new BiomeOcean(new Biome.BiomeProperties("Ocean").setBaseHeight(-1.0F).setHeightVariation(0.1F))); -@@ -972,6 +1055,13 @@ - public String toString() - { - return this.entityClass.getSimpleName() + "*(" + this.minGroupCount + "-" + this.maxGroupCount + "):" + this.itemWeight; -+ } -+ -+ public EntityLiving newInstance(World world) throws Exception -+ { -+ net.minecraftforge.fml.common.registry.EntityEntry entry = net.minecraftforge.fml.common.registry.EntityRegistry.getEntry(this.entityClass); -+ if (entry != null) return (EntityLiving) entry.newInstance(world); -+ return this.entityClass.getConstructor(World.class).newInstance(world); - } - } - diff --git a/patches/minecraft/net/minecraft/world/biome/BiomeDecorator.java.patch b/patches/minecraft/net/minecraft/world/biome/BiomeDecorator.java.patch deleted file mode 100644 index c0013bf79..000000000 --- a/patches/minecraft/net/minecraft/world/biome/BiomeDecorator.java.patch +++ /dev/null @@ -1,224 +0,0 @@ ---- before/net/minecraft/world/biome/BiomeDecorator.java -+++ after/net/minecraft/world/biome/BiomeDecorator.java -@@ -98,8 +98,11 @@ - - protected void genDecorations(Biome biomeIn, World worldIn, Random random) - { -+ net.minecraft.util.math.ChunkPos forgeChunkPos = new net.minecraft.util.math.ChunkPos(chunkPos); // actual ChunkPos instead of BlockPos, used for events -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.terraingen.DecorateBiomeEvent.Pre(worldIn, random, forgeChunkPos)); - this.generateOres(worldIn, random); - -+ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.SAND)) - for (int i = 0; i < this.sandPatchesPerChunk; i++) - { - int j = random.nextInt(16) + 8; -@@ -107,6 +110,7 @@ - this.sandGen.generate(worldIn, random, worldIn.getTopSolidOrLiquidBlock(this.chunkPos.add(j, 0, k))); - } - -+ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.CLAY)) - for (int i1 = 0; i1 < this.clayPerChunk; i1++) - { - int l1 = random.nextInt(16) + 8; -@@ -114,6 +118,7 @@ - this.clayGen.generate(worldIn, random, worldIn.getTopSolidOrLiquidBlock(this.chunkPos.add(l1, 0, i6))); - } - -+ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.SAND_PASS2)) - for (int j1 = 0; j1 < this.gravelPatchesPerChunk; j1++) - { - int i2 = random.nextInt(16) + 8; -@@ -128,6 +133,7 @@ - k1++; - } - -+ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.TREE)) - for (int j2 = 0; j2 < k1; j2++) - { - int k6 = random.nextInt(16) + 8; -@@ -142,6 +148,7 @@ - } - } - -+ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.BIG_SHROOM)) - for (int k2 = 0; k2 < this.bigMushroomsPerChunk; k2++) - { - int l6 = random.nextInt(16) + 8; -@@ -149,6 +156,7 @@ - this.bigMushroomGen.generate(worldIn, random, worldIn.getHeight(this.chunkPos.add(l6, 0, k10))); - } - -+ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.FLOWERS)) - for (int l2 = 0; l2 < this.flowersPerChunk; l2++) - { - int i7 = random.nextInt(16) + 8; -@@ -170,6 +178,7 @@ - } - } - -+ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.GRASS)) - for (int i3 = 0; i3 < this.grassPerChunk; i3++) - { - int j7 = random.nextInt(16) + 8; -@@ -183,6 +192,7 @@ - } - } - -+ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.DEAD_BUSH)) - for (int j3 = 0; j3 < this.deadBushPerChunk; j3++) - { - int k7 = random.nextInt(16) + 8; -@@ -196,6 +206,7 @@ - } - } - -+ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.LILYPAD)) - for (int k3 = 0; k3 < this.waterlilyPerChunk; k3++) - { - int l7 = random.nextInt(16) + 8; -@@ -223,6 +234,8 @@ - } - } - -+ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.SHROOM)) -+ { - for (int l3 = 0; l3 < this.mushroomsPerChunk; l3++) - { - if (random.nextInt(4) == 0) -@@ -274,6 +287,9 @@ - } - } - -+ } // End of Mushroom generation -+ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.REED)) -+ { - for (int k4 = 0; k4 < this.reedsPerChunk; k4++) - { - int i9 = random.nextInt(16) + 8; -@@ -300,6 +316,8 @@ - } - } - -+ } // End of Reed generation -+ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.PUMPKIN)) - if (random.nextInt(32) == 0) - { - int i5 = random.nextInt(16) + 8; -@@ -313,6 +331,7 @@ - } - } - -+ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.CACTUS)) - for (int j5 = 0; j5 < this.cactiPerChunk; j5++) - { - int l9 = random.nextInt(16) + 8; -@@ -328,6 +347,7 @@ - - if (this.generateFalls) - { -+ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.LAKE_WATER)) - for (int k5 = 0; k5 < 50; k5++) - { - int i10 = random.nextInt(16) + 8; -@@ -342,6 +362,7 @@ - } - } - -+ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.LAKE_LAVA)) - for (int l5 = 0; l5 < 20; l5++) - { - int j10 = random.nextInt(16) + 8; -@@ -351,16 +372,21 @@ - new WorldGenLiquids(Blocks.FLOWING_LAVA).generate(worldIn, random, blockpos3); - } - } -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.terraingen.DecorateBiomeEvent.Post(worldIn, random, forgeChunkPos)); - } - - protected void generateOres(World worldIn, Random random) - { -+ net.minecraftforge.common.MinecraftForge.ORE_GEN_BUS.post(new net.minecraftforge.event.terraingen.OreGenEvent.Pre(worldIn, random, chunkPos)); -+ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, dirtGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.DIRT)) - this.genStandardOre1( - worldIn, random, this.chunkProviderSettings.dirtCount, this.dirtGen, this.chunkProviderSettings.dirtMinHeight, this.chunkProviderSettings.dirtMaxHeight - ); -+ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, gravelOreGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.GRAVEL)) - this.genStandardOre1( - worldIn, random, this.chunkProviderSettings.gravelCount, this.gravelOreGen, this.chunkProviderSettings.gravelMinHeight, this.chunkProviderSettings.gravelMaxHeight - ); -+ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, dioriteGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.DIORITE)) - this.genStandardOre1( - worldIn, - random, -@@ -369,6 +395,7 @@ - this.chunkProviderSettings.dioriteMinHeight, - this.chunkProviderSettings.dioriteMaxHeight - ); -+ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, graniteGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.GRANITE)) - this.genStandardOre1( - worldIn, - random, -@@ -377,6 +404,7 @@ - this.chunkProviderSettings.graniteMinHeight, - this.chunkProviderSettings.graniteMaxHeight - ); -+ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, andesiteGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.ANDESITE)) - this.genStandardOre1( - worldIn, - random, -@@ -385,6 +413,7 @@ - this.chunkProviderSettings.andesiteMinHeight, - this.chunkProviderSettings.andesiteMaxHeight - ); -+ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, coalGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.COAL)) - this.genStandardOre1( - worldIn, - random, -@@ -393,6 +422,7 @@ - this.chunkProviderSettings.coalMinHeight, - this.chunkProviderSettings.coalMaxHeight - ); -+ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, ironGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.IRON)) - this.genStandardOre1( - worldIn, - random, -@@ -401,6 +431,7 @@ - this.chunkProviderSettings.ironMinHeight, - this.chunkProviderSettings.ironMaxHeight - ); -+ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, goldGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.GOLD)) - this.genStandardOre1( - worldIn, - random, -@@ -409,6 +440,7 @@ - this.chunkProviderSettings.goldMinHeight, - this.chunkProviderSettings.goldMaxHeight - ); -+ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, redstoneGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.REDSTONE)) - this.genStandardOre1( - worldIn, - random, -@@ -417,6 +449,7 @@ - this.chunkProviderSettings.redstoneMinHeight, - this.chunkProviderSettings.redstoneMaxHeight - ); -+ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, diamondGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.DIAMOND)) - this.genStandardOre1( - worldIn, - random, -@@ -425,6 +458,7 @@ - this.chunkProviderSettings.diamondMinHeight, - this.chunkProviderSettings.diamondMaxHeight - ); -+ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, lapisGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.LAPIS)) - this.genStandardOre2( - worldIn, - random, -@@ -433,6 +467,7 @@ - this.chunkProviderSettings.lapisCenterHeight, - this.chunkProviderSettings.lapisSpread - ); -+ net.minecraftforge.common.MinecraftForge.ORE_GEN_BUS.post(new net.minecraftforge.event.terraingen.OreGenEvent.Post(worldIn, random, chunkPos)); - } - - protected void genStandardOre1(World worldIn, Random random, int blockCount, WorldGenerator generator, int minHeight, int maxHeight) diff --git a/patches/minecraft/net/minecraft/world/biome/BiomeDesert.java.patch b/patches/minecraft/net/minecraft/world/biome/BiomeDesert.java.patch deleted file mode 100644 index c3e948092..000000000 --- a/patches/minecraft/net/minecraft/world/biome/BiomeDesert.java.patch +++ /dev/null @@ -1,18 +0,0 @@ ---- before/net/minecraft/world/biome/BiomeDesert.java -+++ after/net/minecraft/world/biome/BiomeDesert.java -@@ -48,6 +48,7 @@ - { - super.decorate(worldIn, rand, pos); - -+ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.DESERT_WELL)) - if (rand.nextInt(1000) == 0) - { - int i = rand.nextInt(16) + 8; -@@ -56,6 +57,7 @@ - new WorldGenDesertWells().generate(worldIn, rand, blockpos); - } - -+ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.FOSSIL)) - if (rand.nextInt(64) == 0) - { - new WorldGenFossils().generate(worldIn, rand, pos); diff --git a/patches/minecraft/net/minecraft/world/biome/BiomeForest.java.patch b/patches/minecraft/net/minecraft/world/biome/BiomeForest.java.patch deleted file mode 100644 index 783a2904e..000000000 --- a/patches/minecraft/net/minecraft/world/biome/BiomeForest.java.patch +++ /dev/null @@ -1,52 +0,0 @@ ---- before/net/minecraft/world/biome/BiomeForest.java -+++ after/net/minecraft/world/biome/BiomeForest.java -@@ -46,6 +46,17 @@ - { - this.decorator.treesPerChunk = -999; - } -+ -+ if (this.type == BiomeForest.Type.FLOWER) //Needs to be done here so we have access to this.type -+ { -+ this.flowers.clear(); -+ for (BlockFlower.EnumFlowerType type : BlockFlower.EnumFlowerType.values()) -+ { -+ if (type.getBlockType() == BlockFlower.EnumFlowerColor.YELLOW) continue; -+ if (type == BlockFlower.EnumFlowerType.BLUE_ORCHID) type = BlockFlower.EnumFlowerType.POPPY; -+ addFlower(net.minecraft.init.Blocks.RED_FLOWER.getDefaultState().withProperty(net.minecraft.init.Blocks.RED_FLOWER.getTypeProperty(), type), 10); -+ } -+ } - } - - @Override -@@ -90,6 +101,8 @@ - this.addMushrooms(worldIn, rand, pos); - } - -+ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.FLOWERS)) -+ { // no tab for patch - int i = rand.nextInt(5) - 3; - - if (this.type == BiomeForest.Type.FLOWER) -@@ -98,6 +111,7 @@ - } - - this.addDoublePlants(worldIn, rand, pos, i); -+ } - super.decorate(worldIn, rand, pos); - } - -@@ -111,12 +125,12 @@ - int l = j * 4 + 1 + 8 + p_185379_2_.nextInt(3); - BlockPos blockpos = p_185379_1_.getHeight(p_185379_3_.add(k, 0, l)); - -- if (p_185379_2_.nextInt(20) == 0) -+ if (p_185379_2_.nextInt(20) == 0 && net.minecraftforge.event.terraingen.TerrainGen.decorate(p_185379_1_, p_185379_2_, new net.minecraft.util.math.ChunkPos(p_185379_3_), blockpos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.BIG_SHROOM)) - { - WorldGenBigMushroom worldgenbigmushroom = new WorldGenBigMushroom(); - worldgenbigmushroom.generate(p_185379_1_, p_185379_2_, blockpos); - } -- else -+ else if (net.minecraftforge.event.terraingen.TerrainGen.decorate(p_185379_1_, p_185379_2_, new net.minecraft.util.math.ChunkPos(p_185379_3_), blockpos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.TREE)) - { - WorldGenAbstractTree worldgenabstracttree = this.getRandomTreeFeature(p_185379_2_); - worldgenabstracttree.setDecorationDefaults(); diff --git a/patches/minecraft/net/minecraft/world/biome/BiomeHills.java.patch b/patches/minecraft/net/minecraft/world/biome/BiomeHills.java.patch deleted file mode 100644 index 3fe5ad2ec..000000000 --- a/patches/minecraft/net/minecraft/world/biome/BiomeHills.java.patch +++ /dev/null @@ -1,65 +0,0 @@ ---- before/net/minecraft/world/biome/BiomeHills.java -+++ after/net/minecraft/world/biome/BiomeHills.java -@@ -43,28 +43,21 @@ - public void decorate(World worldIn, Random rand, BlockPos pos) - { - super.decorate(worldIn, rand, pos); -- int i = 3 + rand.nextInt(6); -- -- for (int j = 0; j < i; j++) -- { -- int k = rand.nextInt(16); -- int l = rand.nextInt(28) + 4; -- int i1 = rand.nextInt(16); -- BlockPos blockpos = pos.add(k, l, i1); -- -- if (worldIn.getBlockState(blockpos).getBlock() == Blocks.STONE) -- { -- worldIn.setBlockState(blockpos, Blocks.EMERALD_ORE.getDefaultState(), 2); -- } -- } -+ -+ net.minecraftforge.common.MinecraftForge.ORE_GEN_BUS.post(new net.minecraftforge.event.terraingen.OreGenEvent.Pre(worldIn, rand, pos)); -+ WorldGenerator emeralds = new EmeraldGenerator(); -+ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, rand, emeralds, pos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.EMERALD)) -+ emeralds.generate(worldIn, rand, pos); - - for (int j1 = 0; j1 < 7; j1++) - { - int k1 = rand.nextInt(16); - int l1 = rand.nextInt(64); - int i2 = rand.nextInt(16); -+ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, rand, silverfishSpawner, pos.add(j1, k1, l1), net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.SILVERFISH)) - this.silverfishSpawner.generate(worldIn, rand, pos.add(k1, l1, i2)); - } -+ net.minecraftforge.common.MinecraftForge.ORE_GEN_BUS.post(new net.minecraftforge.event.terraingen.OreGenEvent.Post(worldIn, rand, pos)); - } - - @Override -@@ -92,5 +85,26 @@ - NORMAL, - EXTRA_TREES, - MUTATED; -+ } -+ -+ private static class EmeraldGenerator extends WorldGenerator -+ { -+ @Override -+ public boolean generate(World worldIn, Random rand, BlockPos pos) -+ { -+ int count = 3 + rand.nextInt(6); -+ for (int i = 0; i < count; i++) -+ { -+ int offset = net.minecraftforge.common.ForgeModContainer.fixVanillaCascading ? 8 : 0; // MC-114332 -+ BlockPos blockpos = pos.add(rand.nextInt(16) + offset, rand.nextInt(28) + 4, rand.nextInt(16) + offset); -+ -+ net.minecraft.block.state.IBlockState state = worldIn.getBlockState(blockpos); -+ if (state.getBlock().isReplaceableOreGen(state, worldIn, blockpos, net.minecraft.block.state.pattern.BlockMatcher.forBlock(Blocks.STONE))) -+ { -+ worldIn.setBlockState(blockpos, Blocks.EMERALD_ORE.getDefaultState(), 16 | 2); -+ } -+ } -+ return true; -+ } - } - } diff --git a/patches/minecraft/net/minecraft/world/biome/BiomeJungle.java.patch b/patches/minecraft/net/minecraft/world/biome/BiomeJungle.java.patch deleted file mode 100644 index f417e2012..000000000 --- a/patches/minecraft/net/minecraft/world/biome/BiomeJungle.java.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- before/net/minecraft/world/biome/BiomeJungle.java -+++ after/net/minecraft/world/biome/BiomeJungle.java -@@ -94,10 +94,14 @@ - super.decorate(worldIn, rand, pos); - int i = rand.nextInt(16) + 8; - int j = rand.nextInt(16) + 8; -- int k = rand.nextInt(worldIn.getHeight(pos.add(i, 0, j)).getY() * 2); -- new WorldGenMelon().generate(worldIn, rand, pos.add(i, k, j)); -+ int height = worldIn.getHeight(pos.add(i, 0, j)).getY() * 2; // could == 0, which crashes nextInt -+ if (height < 1) height = 1; -+ int k = rand.nextInt(height); -+ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), pos.add(i, k, j), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.PUMPKIN)) -+ (new WorldGenMelon()).generate(worldIn, rand, pos.add(i, k, j)); - WorldGenVines worldgenvines = new WorldGenVines(); - -+ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.GRASS)) - for (int j1 = 0; j1 < 50; j1++) - { - k = rand.nextInt(16) + 8; diff --git a/patches/minecraft/net/minecraft/world/biome/BiomeMesa.java.patch b/patches/minecraft/net/minecraft/world/biome/BiomeMesa.java.patch deleted file mode 100644 index 4ed43a58e..000000000 --- a/patches/minecraft/net/minecraft/world/biome/BiomeMesa.java.patch +++ /dev/null @@ -1,27 +0,0 @@ ---- before/net/minecraft/world/biome/BiomeMesa.java -+++ after/net/minecraft/world/biome/BiomeMesa.java -@@ -74,14 +74,14 @@ - @Override - public int getFoliageColorAtPos(BlockPos pos) - { -- return 10387789; -+ return getModdedBiomeFoliageColor(10387789); - } - - @SideOnly(Side.CLIENT) - @Override - public int getGrassColorAtPos(BlockPos pos) - { -- return 9470285; -+ return getModdedBiomeGrassColor(9470285); - } - - @Override -@@ -340,6 +340,7 @@ - protected void generateOres(World worldIn, Random random) - { - super.generateOres(worldIn, random); -+ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, goldGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.GOLD)) - this.genStandardOre1(worldIn, random, 20, this.goldGen, 32, 80); - } - } diff --git a/patches/minecraft/net/minecraft/world/biome/BiomePlains.java.patch b/patches/minecraft/net/minecraft/world/biome/BiomePlains.java.patch deleted file mode 100644 index 471f9123c..000000000 --- a/patches/minecraft/net/minecraft/world/biome/BiomePlains.java.patch +++ /dev/null @@ -1,40 +0,0 @@ ---- before/net/minecraft/world/biome/BiomePlains.java -+++ after/net/minecraft/world/biome/BiomePlains.java -@@ -82,6 +82,7 @@ - this.decorator.grassPerChunk = 10; - DOUBLE_PLANT_GENERATOR.setPlantType(BlockDoublePlant.EnumPlantType.GRASS); - -+ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.GRASS)) - for (int i = 0; i < 7; i++) - { - int j = rand.nextInt(16) + 8; -@@ -91,7 +92,7 @@ - } - } - -- if (this.sunflowers) -+ if (this.sunflowers && net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.FLOWERS)) - { - DOUBLE_PLANT_GENERATOR.setPlantType(BlockDoublePlant.EnumPlantType.SUNFLOWER); - -@@ -108,6 +109,20 @@ - } - - @Override -+ public void addDefaultFlowers() -+ { -+ BlockFlower red = net.minecraft.init.Blocks.RED_FLOWER; -+ BlockFlower yel = net.minecraft.init.Blocks.YELLOW_FLOWER; -+ addFlower(red.getDefaultState().withProperty(red.getTypeProperty(), BlockFlower.EnumFlowerType.ORANGE_TULIP), 3); -+ addFlower(red.getDefaultState().withProperty(red.getTypeProperty(), BlockFlower.EnumFlowerType.RED_TULIP), 3); -+ addFlower(red.getDefaultState().withProperty(red.getTypeProperty(), BlockFlower.EnumFlowerType.PINK_TULIP), 3); -+ addFlower(red.getDefaultState().withProperty(red.getTypeProperty(), BlockFlower.EnumFlowerType.WHITE_TULIP), 3); -+ addFlower(red.getDefaultState().withProperty(red.getTypeProperty(), BlockFlower.EnumFlowerType.POPPY), 20); -+ addFlower(red.getDefaultState().withProperty(red.getTypeProperty(), BlockFlower.EnumFlowerType.HOUSTONIA), 20); -+ addFlower(red.getDefaultState().withProperty(red.getTypeProperty(), BlockFlower.EnumFlowerType.OXEYE_DAISY), 20); -+ addFlower(yel.getDefaultState().withProperty(yel.getTypeProperty(), BlockFlower.EnumFlowerType.DANDELION), 30); -+ } -+ - public WorldGenAbstractTree getRandomTreeFeature(Random rand) - { - return (WorldGenAbstractTree)(rand.nextInt(3) == 0 ? BIG_TREE_FEATURE : TREE_FEATURE); diff --git a/patches/minecraft/net/minecraft/world/biome/BiomeProvider.java.patch b/patches/minecraft/net/minecraft/world/biome/BiomeProvider.java.patch deleted file mode 100644 index 24da5f091..000000000 --- a/patches/minecraft/net/minecraft/world/biome/BiomeProvider.java.patch +++ /dev/null @@ -1,34 +0,0 @@ ---- before/net/minecraft/world/biome/BiomeProvider.java -+++ after/net/minecraft/world/biome/BiomeProvider.java -@@ -21,7 +21,8 @@ - private GenLayer genBiomes; - private GenLayer biomeIndexLayer; - private final BiomeCache biomeCache = new BiomeCache(this); -- private final List biomesToSpawnIn = Lists.newArrayList( -+ private final List biomesToSpawnIn = Lists.newArrayList(allowedBiomes); -+ public static List allowedBiomes = Lists.newArrayList( - Biomes.FOREST, Biomes.PLAINS, Biomes.TAIGA, Biomes.TAIGA_HILLS, Biomes.FOREST_HILLS, Biomes.JUNGLE, Biomes.JUNGLE_HILLS - ); - -@@ -39,6 +40,7 @@ - } - - GenLayer[] agenlayer = GenLayer.initializeAllBiomeGenerators(seed, worldTypeIn, this.settings); -+ agenlayer = getModdedBiomeGenerators(worldTypeIn, seed, agenlayer); - this.genBiomes = agenlayer[0]; - this.biomeIndexLayer = agenlayer[1]; - } -@@ -205,6 +207,13 @@ - public void cleanupCache() - { - this.biomeCache.cleanupCache(); -+ } -+ -+ public GenLayer[] getModdedBiomeGenerators(WorldType worldType, long seed, GenLayer[] original) -+ { -+ net.minecraftforge.event.terraingen.WorldTypeEvent.InitBiomeGens event = new net.minecraftforge.event.terraingen.WorldTypeEvent.InitBiomeGens(worldType, seed, original); -+ net.minecraftforge.common.MinecraftForge.TERRAIN_GEN_BUS.post(event); -+ return event.getNewBiomeGens(); - } - - public boolean isFixedBiome() diff --git a/patches/minecraft/net/minecraft/world/biome/BiomeSavanna.java.patch b/patches/minecraft/net/minecraft/world/biome/BiomeSavanna.java.patch deleted file mode 100644 index 4a75556ba..000000000 --- a/patches/minecraft/net/minecraft/world/biome/BiomeSavanna.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- before/net/minecraft/world/biome/BiomeSavanna.java -+++ after/net/minecraft/world/biome/BiomeSavanna.java -@@ -41,6 +41,7 @@ - { - DOUBLE_PLANT_GENERATOR.setPlantType(BlockDoublePlant.EnumPlantType.GRASS); - -+ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.GRASS)) - for (int i = 0; i < 7; i++) - { - int j = rand.nextInt(16) + 8; diff --git a/patches/minecraft/net/minecraft/world/biome/BiomeSnow.java.patch b/patches/minecraft/net/minecraft/world/biome/BiomeSnow.java.patch deleted file mode 100644 index bba78bcbc..000000000 --- a/patches/minecraft/net/minecraft/world/biome/BiomeSnow.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/world/biome/BiomeSnow.java -+++ after/net/minecraft/world/biome/BiomeSnow.java -@@ -58,7 +58,7 @@ - @Override - public void decorate(World worldIn, Random rand, BlockPos pos) - { -- if (this.superIcy) -+ if (this.superIcy && net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.ICE)) - { - for (int i = 0; i < 3; i++) - { diff --git a/patches/minecraft/net/minecraft/world/biome/BiomeSwamp.java.patch b/patches/minecraft/net/minecraft/world/biome/BiomeSwamp.java.patch deleted file mode 100644 index 97f7f7a9a..000000000 --- a/patches/minecraft/net/minecraft/world/biome/BiomeSwamp.java.patch +++ /dev/null @@ -1,36 +0,0 @@ ---- before/net/minecraft/world/biome/BiomeSwamp.java -+++ after/net/minecraft/world/biome/BiomeSwamp.java -@@ -45,14 +45,14 @@ - public int getGrassColorAtPos(BlockPos pos) - { - double d0 = GRASS_COLOR_NOISE.getValue(pos.getX() * 0.0225, pos.getZ() * 0.0225); -- return d0 < -0.1 ? 5011004 : 6975545; -+ return getModdedBiomeGrassColor(d0 < -0.1 ? 5011004 : 6975545); - } - - @SideOnly(Side.CLIENT) - @Override - public int getFoliageColorAtPos(BlockPos pos) - { -- return 6975545; -+ return getModdedBiomeFoliageColor(6975545); - } - - @Override -@@ -98,9 +98,16 @@ - { - super.decorate(worldIn, rand, pos); - -+ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.FOSSIL)) - if (rand.nextInt(64) == 0) - { - new WorldGenFossils().generate(worldIn, rand, pos); - } -+ } -+ -+ @Override -+ public void addDefaultFlowers() -+ { -+ addFlower(Blocks.RED_FLOWER.getDefaultState().withProperty(Blocks.RED_FLOWER.getTypeProperty(), BlockFlower.EnumFlowerType.BLUE_ORCHID), 10); - } - } diff --git a/patches/minecraft/net/minecraft/world/biome/BiomeTaiga.java.patch b/patches/minecraft/net/minecraft/world/biome/BiomeTaiga.java.patch deleted file mode 100644 index 88af0770b..000000000 --- a/patches/minecraft/net/minecraft/world/biome/BiomeTaiga.java.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- before/net/minecraft/world/biome/BiomeTaiga.java -+++ after/net/minecraft/world/biome/BiomeTaiga.java -@@ -70,7 +70,7 @@ - @Override - public void decorate(World worldIn, Random rand, BlockPos pos) - { -- if (this.type == BiomeTaiga.Type.MEGA || this.type == BiomeTaiga.Type.MEGA_SPRUCE) -+ if ((this.type == BiomeTaiga.Type.MEGA || this.type == BiomeTaiga.Type.MEGA_SPRUCE) && net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.ROCK)) - { - int i = rand.nextInt(3); - -@@ -85,6 +85,7 @@ - - DOUBLE_PLANT_GENERATOR.setPlantType(BlockDoublePlant.EnumPlantType.FERN); - -+ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.FLOWERS)) - for (int i1 = 0; i1 < 7; i1++) - { - int j1 = rand.nextInt(16) + 8; diff --git a/patches/minecraft/net/minecraft/world/border/WorldBorder.java.patch b/patches/minecraft/net/minecraft/world/border/WorldBorder.java.patch deleted file mode 100644 index c54113846..000000000 --- a/patches/minecraft/net/minecraft/world/border/WorldBorder.java.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- before/net/minecraft/world/border/WorldBorder.java -+++ after/net/minecraft/world/border/WorldBorder.java -@@ -285,4 +285,9 @@ - iborderlistener.onWarningDistanceChanged(this, warningDistance); - } - } -+ -+ public void removeListener(IBorderListener listener) -+ { -+ this.listeners.remove(listener); -+ } - } diff --git a/patches/minecraft/net/minecraft/world/chunk/BlockStateContainer.java.patch b/patches/minecraft/net/minecraft/world/chunk/BlockStateContainer.java.patch deleted file mode 100644 index 666ac5f0d..000000000 --- a/patches/minecraft/net/minecraft/world/chunk/BlockStateContainer.java.patch +++ /dev/null @@ -1,39 +0,0 @@ ---- before/net/minecraft/world/chunk/BlockStateContainer.java -+++ after/net/minecraft/world/chunk/BlockStateContainer.java -@@ -30,6 +30,10 @@ - - private void setBits(int bitsIn) - { -+ setBits(bitsIn, false); -+ } -+ private void setBits(int bitsIn, boolean forceBits) -+ { - if (bitsIn != this.bits) - { - this.bits = bitsIn; -@@ -47,6 +51,8 @@ - { - this.palette = REGISTRY_BASED_PALETTE; - this.bits = MathHelper.log2DeBruijn(Block.BLOCK_STATE_IDS.size()); -+ if (forceBits) -+ this.bits = bitsIn; - } - - this.palette.idFor(AIR_BLOCK_STATE); -@@ -103,11 +109,15 @@ - - if (this.bits != i) - { -- this.setBits(i); -+ this.setBits(i, true); //Forge, Force bit density to fix network issues, resize below if needed. - } - - this.palette.read(buf); - buf.readLongArray(this.storage.getBackingLongArray()); -+ -+ int regSize = MathHelper.log2DeBruijn(Block.BLOCK_STATE_IDS.size()); -+ if (this.palette == REGISTRY_BASED_PALETTE && this.bits != regSize) // Resize bits to fit registry. -+ this.onResize(regSize, AIR_BLOCK_STATE); - } - - public void write(PacketBuffer buf) diff --git a/patches/minecraft/net/minecraft/world/chunk/Chunk.java.patch b/patches/minecraft/net/minecraft/world/chunk/Chunk.java.patch deleted file mode 100644 index 94520b09d..000000000 --- a/patches/minecraft/net/minecraft/world/chunk/Chunk.java.patch +++ /dev/null @@ -1,403 +0,0 @@ ---- before/net/minecraft/world/chunk/Chunk.java -+++ after/net/minecraft/world/chunk/Chunk.java -@@ -41,7 +41,7 @@ - import org.apache.logging.log4j.LogManager; - import org.apache.logging.log4j.Logger; - --public class Chunk -+public class Chunk implements net.minecraftforge.common.capabilities.ICapabilityProvider - { - private static final Logger LOGGER = LogManager.getLogger(); - public static final ExtendedBlockStorage NULL_BLOCK_STORAGE = null; -@@ -84,6 +84,7 @@ - - Arrays.fill(this.precipitationHeightMap, -999); - Arrays.fill(this.blockBiomeArray, (byte) - 1); -+ capabilities = net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(this); - } - - public Chunk(World worldIn, ChunkPrimer primer, int x, int z) -@@ -172,7 +173,7 @@ - { - IBlockState iblockstate = this.getBlockState(j, l - 1, k); - -- if (iblockstate.getLightOpacity() != 0) -+ if (this.getBlockLightOpacity(j, l - 1, k) != 0) - { - this.heightMap[k << 4 | j] = l; - -@@ -442,12 +443,13 @@ - - public int getBlockLightOpacity(BlockPos pos) - { -- return this.getBlockState(pos).getLightOpacity(); -+ return this.getBlockState(pos).getLightOpacity(this.world, pos); - } - - private int getBlockLightOpacity(int x, int y, int z) - { -- return this.getBlockState(x, y, z).getLightOpacity(); -+ IBlockState state = this.getBlockState(x, y, z); //Forge: Can sometimes be called before we are added to the global world list. So use the less accurate one during that. It'll be recalculated later -+ return !loaded ? state.getLightOpacity() : state.getLightOpacity(world, new BlockPos(this.x << 4 | x & 15, y, this.z << 4 | z & 15)); - } - - public IBlockState getBlockState(BlockPos pos) -@@ -529,6 +531,7 @@ - { - Block block = state.getBlock(); - Block block1 = iblockstate.getBlock(); -+ int k1 = iblockstate.getLightOpacity(this.world, pos); // Relocate old light value lookup here, so that it is called before TE is removed. - ExtendedBlockStorage extendedblockstorage = this.storageArrays[j >> 4]; - boolean flag = false; - -@@ -546,14 +549,19 @@ - - extendedblockstorage.set(i, j & 15, k, state); - -- if (block1 != block) -+ //if (block1 != block) - { - if (!this.world.isRemote) - { -+ if (block1 != block) //Only fire block breaks when the block changes. - block1.breakBlock(this.world, pos, iblockstate); -+ TileEntity te = this.getTileEntity(pos, Chunk.EnumCreateEntityType.CHECK); -+ if (te != null && te.shouldRefresh(this.world, pos, iblockstate, state)) this.world.removeTileEntity(pos); - } -- else if (block1 instanceof ITileEntityProvider) -+ else if (block1.hasTileEntity(iblockstate)) - { -+ TileEntity te = this.getTileEntity(pos, Chunk.EnumCreateEntityType.CHECK); -+ if (te != null && te.shouldRefresh(this.world, pos, iblockstate, state)) - this.world.removeTileEntity(pos); - } - } -@@ -570,8 +578,7 @@ - } - else - { -- int j1 = state.getLightOpacity(); -- int k1 = iblockstate.getLightOpacity(); -+ int j1 = state.getLightOpacity(this.world, pos); - - if (j1 > 0) - { -@@ -591,28 +598,19 @@ - } - } - -- if (block1 instanceof ITileEntityProvider) -- { -- TileEntity tileentity = this.getTileEntity(pos, Chunk.EnumCreateEntityType.CHECK); -- -- if (tileentity != null) -- { -- tileentity.updateContainingBlockInfo(); -- } -- } -- -- if (!this.world.isRemote && block1 != block) -+ // If capturing blocks, only run block physics for TE's. Non-TE's are handled in ForgeHooks.onPlaceItemIntoWorld -+ if (!this.world.isRemote && block1 != block && (!this.world.captureBlockSnapshots || block.hasTileEntity(state))) - { - block.onBlockAdded(this.world, pos, state); - } - -- if (block instanceof ITileEntityProvider) -+ if (block.hasTileEntity(state)) - { - TileEntity tileentity1 = this.getTileEntity(pos, Chunk.EnumCreateEntityType.CHECK); - - if (tileentity1 == null) - { -- tileentity1 = ((ITileEntityProvider)block).createNewTileEntity(this.world, block.getMetaFromState(state)); -+ tileentity1 = block.createTileEntity(this.world, state); - this.world.setTileEntity(pos, tileentity1); - } - -@@ -730,11 +728,13 @@ - k = this.entityLists.length - 1; - } - -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.EntityEvent.EnteringChunk(entityIn, this.x, this.z, entityIn.chunkCoordX, entityIn.chunkCoordZ)); - entityIn.addedToChunk = true; - entityIn.chunkCoordX = this.x; - entityIn.chunkCoordY = k; - entityIn.chunkCoordZ = this.z; - this.entityLists[k].add(entityIn); -+ this.markDirty(); // Forge - ensure chunks are marked to save after an entity add - } - - public void removeEntity(Entity entityIn) -@@ -755,6 +755,7 @@ - } - - this.entityLists[index].remove(entityIn); -+ this.markDirty(); // Forge - ensure chunks are marked to save after entity removals - } - - public boolean canSeeSky(BlockPos pos) -@@ -770,9 +771,9 @@ - { - IBlockState iblockstate = this.getBlockState(pos); - Block block = iblockstate.getBlock(); -- return !block.hasTileEntity() -+ return !block.hasTileEntity(iblockstate) - ? null -- : ((ITileEntityProvider)block).createNewTileEntity(this.world, iblockstate.getBlock().getMetaFromState(iblockstate)); -+ : block.createTileEntity(this.world, iblockstate); - } - - @Nullable -@@ -780,6 +781,12 @@ - { - TileEntity tileentity = this.tileEntities.get(pos); - -+ if (tileentity != null && tileentity.isInvalid()) -+ { -+ tileEntities.remove(pos); -+ tileentity = null; -+ } -+ - if (tileentity == null) - { - if (creationMode == Chunk.EnumCreateEntityType.IMMEDIATE) -@@ -789,13 +796,8 @@ - } - else if (creationMode == Chunk.EnumCreateEntityType.QUEUED) - { -- this.tileEntityPosQueue.add(pos); -+ this.tileEntityPosQueue.add(pos.toImmutable()); - } -- } -- else if (tileentity.isInvalid()) -- { -- this.tileEntities.remove(pos); -- return null; - } - - return tileentity; -@@ -813,10 +815,11 @@ - - public void addTileEntity(BlockPos pos, TileEntity tileEntityIn) - { -+ if (tileEntityIn.getWorld() != this.world) //Forge don't call unless it's changed, could screw up bad mods. - tileEntityIn.setWorld(this.world); - tileEntityIn.setPos(pos); - -- if (this.getBlockState(pos).getBlock() instanceof ITileEntityProvider) -+ if (this.getBlockState(pos).getBlock().hasTileEntity(this.getBlockState(pos))) - { - if (this.tileEntities.containsKey(pos)) - { -@@ -848,12 +851,14 @@ - - for (ClassInheritanceMultiMap classinheritancemultimap : this.entityLists) - { -- this.world.loadEntities(classinheritancemultimap); -+ this.world.loadEntities(com.google.common.collect.ImmutableList.copyOf(classinheritancemultimap)); - } -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.ChunkEvent.Load(this)); - } - - public void onUnload() - { -+ java.util.Arrays.stream(entityLists).forEach(multimap -> com.google.common.collect.Lists.newArrayList(multimap.getByClass(net.minecraft.entity.player.EntityPlayer.class)).forEach(player -> world.updateEntityWithOptionalForce(player, false))); // FORGE - Fix for MC-92916 - this.loaded = false; - - for (TileEntity tileentity : this.tileEntities.values()) -@@ -865,6 +870,7 @@ - { - this.world.unloadEntities(classinheritancemultimap); - } -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.ChunkEvent.Unload(this)); - } - - public void markDirty() -@@ -874,8 +880,8 @@ - - public void getEntitiesWithinAABBForEntity(@Nullable Entity entityIn, AxisAlignedBB aabb, List listToFill, Predicate filter) - { -- int i = MathHelper.floor((aabb.minY - 2.0) / 16.0); -- int j = MathHelper.floor((aabb.maxY + 2.0) / 16.0); -+ int i = MathHelper.floor((aabb.minY - World.MAX_ENTITY_RADIUS) / 16.0); -+ int j = MathHelper.floor((aabb.maxY + World.MAX_ENTITY_RADIUS) / 16.0); - i = MathHelper.clamp(i, 0, this.entityLists.length - 1); - j = MathHelper.clamp(j, 0, this.entityLists.length - 1); - -@@ -915,8 +921,8 @@ - Class entityClass, AxisAlignedBB aabb, List listToFill, Predicate filter - ) - { -- int i = MathHelper.floor((aabb.minY - 2.0) / 16.0); -- int j = MathHelper.floor((aabb.maxY + 2.0) / 16.0); -+ int i = MathHelper.floor((aabb.minY - World.MAX_ENTITY_RADIUS) / 16.0); -+ int j = MathHelper.floor((aabb.maxY + World.MAX_ENTITY_RADIUS) / 16.0); - i = MathHelper.clamp(i, 0, this.entityLists.length - 1); - j = MathHelper.clamp(j, 0, this.entityLists.length - 1); - -@@ -1001,6 +1007,9 @@ - - protected void populate(IChunkGenerator generator) - { -+ if (populating != null && net.minecraftforge.common.ForgeModContainer.logCascadingWorldGeneration) logCascadingWorldGeneration(); -+ ChunkPos prev = populating; -+ populating = this.getPos(); - if (this.isTerrainPopulated()) - { - if (generator.generateStructures(this, this.x, this.z)) -@@ -1012,8 +1021,10 @@ - { - this.checkLight(); - generator.populate(this.x, this.z); -+ net.minecraftforge.fml.common.registry.GameRegistry.generateWorld(this.x, this.z, this.world, generator, this.world.getChunkProvider()); - this.markDirty(); - } -+ populating = prev; - } - - public BlockPos getPrecipitationHeight(BlockPos pos) -@@ -1068,7 +1079,7 @@ - { - BlockPos blockpos = this.tileEntityPosQueue.poll(); - -- if (this.getTileEntity(blockpos, Chunk.EnumCreateEntityType.CHECK) == null && this.getBlockState(blockpos).getBlock().hasTileEntity()) -+ if (this.getTileEntity(blockpos, Chunk.EnumCreateEntityType.CHECK) == null && this.getBlockState(blockpos).getBlock().hasTileEntity(this.getBlockState(blockpos))) - { - TileEntity tileentity = this.createNewTileEntity(blockpos); - this.world.setTileEntity(blockpos, tileentity); -@@ -1132,6 +1143,13 @@ - @SideOnly(Side.CLIENT) - public void read(PacketBuffer buf, int availableSections, boolean groundUpContinuous) - { -+ for(TileEntity tileEntity : tileEntities.values()) -+ { -+ tileEntity.updateContainingBlockInfo(); -+ tileEntity.getBlockMetadata(); -+ tileEntity.getBlockType(); -+ } -+ - boolean flag = this.world.provider.hasSkyLight(); - - for (int i = 0; i < this.storageArrays.length; i++) -@@ -1180,10 +1198,16 @@ - this.isTerrainPopulated = true; - this.generateHeightMap(); - -+ List invalidList = new java.util.ArrayList<>(); -+ - for (TileEntity tileentity : this.tileEntities.values()) - { -+ if (tileentity.shouldRefresh(this.world, tileentity.getPos(), tileentity.getBlockType().getStateFromMeta(tileentity.getBlockMetadata()), getBlockState(tileentity.getPos()))) -+ invalidList.add(tileentity); - tileentity.updateContainingBlockInfo(); - } -+ -+ for (TileEntity te : invalidList) te.invalidate(); - } - - public Biome getBiome(BlockPos pos, BiomeProvider provider) -@@ -1194,7 +1218,12 @@ - - if (k == 255) - { -- Biome biome = provider.getBiome(pos, Biomes.PLAINS); -+ // Forge: checking for client ensures that biomes are only generated on integrated server -+ // in singleplayer. Generating biomes on the client may corrupt the biome ID arrays on -+ // the server while they are being generated because IntCache can't be thread safe, -+ // so client and server may end up filling the same array. -+ // This is not necessary in 1.13 and newer versions. -+ Biome biome = world.isRemote ? Biomes.PLAINS : provider.getBiome(pos, Biomes.PLAINS); - k = Biome.getIdForBiome(biome); - this.blockBiomeArray[j << 4 | i] = (byte)(k & 0xFF); - } -@@ -1249,13 +1278,13 @@ - boolean flag = i1 == 0 || i1 == 15 || k == 0 || k == 15 || l == 0 || l == 15; - - if (this.storageArrays[j] == NULL_BLOCK_STORAGE && flag -- || this.storageArrays[j] != NULL_BLOCK_STORAGE && this.storageArrays[j].get(k, i1, l).getMaterial() == Material.AIR) -+ || this.storageArrays[j] != NULL_BLOCK_STORAGE && this.storageArrays[j].get(k, i1, l).getBlock().isAir(this.storageArrays[j].get(k, i1, l), this.world, blockpos1)) - { - for (EnumFacing enumfacing : EnumFacing.values()) - { - BlockPos blockpos2 = blockpos1.offset(enumfacing); - -- if (this.world.getBlockState(blockpos2).getLightValue() > 0) -+ if (this.world.getBlockState(blockpos2).getLightValue(this.world, blockpos2) > 0) - { - this.world.checkLight(blockpos2); - } -@@ -1388,7 +1417,7 @@ - { - blockpos$mutableblockpos.setPos(blockpos$mutableblockpos.getX(), l, blockpos$mutableblockpos.getZ()); - -- if (this.getBlockState(blockpos$mutableblockpos).getLightValue() > 0) -+ if (this.getBlockState(blockpos$mutableblockpos).getLightValue(this.world, blockpos$mutableblockpos) > 0) - { - this.world.checkLight(blockpos$mutableblockpos); - } -@@ -1427,6 +1456,7 @@ - else - { - System.arraycopy(newHeightMap, 0, this.heightMap, 0, this.heightMap.length); -+ this.heightMapMinimum = com.google.common.primitives.Ints.min(this.heightMap); // Forge: fix MC-117412 - } - } - -@@ -1495,5 +1525,56 @@ - IMMEDIATE, - QUEUED, - CHECK; -+ } -+ -+ /* ======================================== FORGE START =====================================*/ -+ /** -+ * Removes the tile entity at the specified position, only if it's -+ * marked as invalid. -+ */ -+ public void removeInvalidTileEntity(BlockPos pos) -+ { -+ if (loaded) -+ { -+ TileEntity entity = (TileEntity)tileEntities.get(pos); -+ if (entity != null && entity.isInvalid()) -+ { -+ tileEntities.remove(pos); -+ } -+ } -+ } -+ -+ private static ChunkPos populating = null; // keep track of cascading chunk generation during chunk population -+ -+ private void logCascadingWorldGeneration() -+ { -+ net.minecraftforge.fml.common.ModContainer activeModContainer = net.minecraftforge.fml.common.Loader.instance().activeModContainer(); -+ String format = "{} loaded a new chunk {} in dimension {} ({}) while populating chunk {}, causing cascading worldgen lag."; -+ -+ if (activeModContainer == null) { // vanilla minecraft has problems too (MC-114332), log it at a quieter level. -+ net.minecraftforge.fml.common.FMLLog.log.debug(format, "Minecraft", this.getPos(), this.world.provider.getDimension(), this.world.provider.getDimensionType().getName(), populating); -+ net.minecraftforge.fml.common.FMLLog.log.debug("Consider setting 'fixVanillaCascading' to 'true' in the Forge config to fix many cases where this occurs in the base game."); -+ } else { -+ net.minecraftforge.fml.common.FMLLog.log.warn(format, activeModContainer.getName(), this.getPos(), this.world.provider.getDimension(), this.world.provider.getDimensionType().getName(), populating); -+ net.minecraftforge.fml.common.FMLLog.log.warn("Please report this to the mod's issue tracker. This log can be disabled in the Forge config."); -+ } -+ } -+ -+ private final net.minecraftforge.common.capabilities.CapabilityDispatcher capabilities; -+ @Nullable -+ public net.minecraftforge.common.capabilities.CapabilityDispatcher getCapabilities() -+ { -+ return capabilities; -+ } -+ @Override -+ public boolean hasCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable EnumFacing facing) -+ { -+ return capabilities == null ? false : capabilities.hasCapability(capability, facing); -+ } -+ @Override -+ @Nullable -+ public T getCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable EnumFacing facing) -+ { -+ return capabilities == null ? null : capabilities.getCapability(capability, facing); - } - } diff --git a/patches/minecraft/net/minecraft/world/chunk/storage/AnvilChunkLoader.java.patch b/patches/minecraft/net/minecraft/world/chunk/storage/AnvilChunkLoader.java.patch deleted file mode 100644 index 76d948fd3..000000000 --- a/patches/minecraft/net/minecraft/world/chunk/storage/AnvilChunkLoader.java.patch +++ /dev/null @@ -1,196 +0,0 @@ ---- before/net/minecraft/world/chunk/storage/AnvilChunkLoader.java -+++ after/net/minecraft/world/chunk/storage/AnvilChunkLoader.java -@@ -49,10 +49,32 @@ - this.fixer = dataFixerIn; - } - -+ @Deprecated // TODO: remove (1.13) -+ public boolean chunkExists(World world, int x, int z) -+ { -+ return isChunkGeneratedAt(x, z); -+ } -+ - @Nullable - @Override - public Chunk loadChunk(World worldIn, int x, int z) throws IOException - { -+ Object[] data = this.loadChunk__Async(worldIn, x, z); -+ -+ if (data != null) -+ { -+ Chunk chunk = (Chunk) data[0]; -+ NBTTagCompound nbttagcompound = (NBTTagCompound) data[1]; -+ this.loadEntities(worldIn, nbttagcompound.getCompoundTag("Level"), chunk); -+ return chunk; -+ } -+ -+ return null; -+ } -+ -+ @Nullable -+ public Object[] loadChunk__Async(World worldIn, int x, int z) throws IOException -+ { - ChunkPos chunkpos = new ChunkPos(x, z); - NBTTagCompound nbttagcompound = this.chunksToSave.get(chunkpos); - -@@ -66,9 +88,10 @@ - } - - nbttagcompound = this.fixer.process(FixTypes.CHUNK, CompressedStreamTools.read(datainputstream)); -+ datainputstream.close(); // Forge: close stream after use - } - -- return this.checkedReadChunkFromNBT(worldIn, x, z, nbttagcompound); -+ return this.checkedReadChunkFromNBT__Async(worldIn, x, z, nbttagcompound); - } - - @Override -@@ -82,6 +105,13 @@ - @Nullable - protected Chunk checkedReadChunkFromNBT(World worldIn, int x, int z, NBTTagCompound compound) - { -+ Object[] data = this.checkedReadChunkFromNBT__Async(worldIn, x, z, compound); -+ return data != null ? (Chunk)data[0] : null; -+ } -+ -+ @Nullable -+ protected Object[] checkedReadChunkFromNBT__Async(World worldIn, int x, int z, NBTTagCompound compound) -+ { - if (!compound.hasKey("Level", 10)) - { - LOGGER.error("Chunk file at {},{} is missing level data, skipping", x, z); -@@ -113,10 +143,29 @@ - ); - nbttagcompound.setInteger("xPos", x); - nbttagcompound.setInteger("zPos", z); -+ -+ // Have to move tile entities since we don't load them at this stage -+ NBTTagList _tileEntities = nbttagcompound.getTagList("TileEntities", 10); -+ -+ if (_tileEntities != null) -+ { -+ for (int te = 0; te < _tileEntities.tagCount(); te++) -+ { -+ NBTTagCompound _nbt = (NBTTagCompound) _tileEntities.getCompoundTagAt(te); -+ _nbt.setInteger("x", x * 16 + (_nbt.getInteger("x") - chunk.x * 16)); -+ _nbt.setInteger("z", z * 16 + (_nbt.getInteger("z") - chunk.z * 16)); -+ } -+ } -+ - chunk = this.readChunkFromNBT(worldIn, nbttagcompound); - } - -- return chunk; -+ Object[] data = new Object[2]; -+ data[0] = chunk; -+ data[1] = compound; -+ // event is fired in ChunkIOProvider.callStage2 since it must be fired after TE's load. -+ // MinecraftForge.EVENT_BUS.post(new ChunkDataEvent.Load(chunk, par4NBTTagCompound)); -+ return data; - } - } - } -@@ -131,7 +180,10 @@ - NBTTagCompound nbttagcompound1 = new NBTTagCompound(); - nbttagcompound.setTag("Level", nbttagcompound1); - nbttagcompound.setInteger("DataVersion", 1343); -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().getDataFixer().writeVersionData(nbttagcompound); - this.writeChunkToNBT(chunkIn, worldIn, nbttagcompound1); -+ net.minecraftforge.common.ForgeChunkManager.storeChunkNBT(chunkIn, nbttagcompound1); -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.ChunkDataEvent.Save(chunkIn, nbttagcompound)); - this.addChunkToPending(chunkIn.getPos(), nbttagcompound); - } - catch (Exception exception) -@@ -322,11 +374,19 @@ - { - NBTTagCompound nbttagcompound2 = new NBTTagCompound(); - -+ try -+ { - if (entity.writeToNBTOptional(nbttagcompound2)) - { - chunkIn.setHasEntities(true); - nbttaglist1.appendTag(nbttagcompound2); - } -+ } -+ catch (Exception e) -+ { -+ net.minecraftforge.fml.common.FMLLog.log.error("An Entity type {} has thrown an exception trying to write state. It will not persist. Report this to the mod author", -+ entity.getClass().getName(), e); -+ } - } - } - -@@ -335,8 +395,16 @@ - - for (TileEntity tileentity : chunkIn.getTileEntityMap().values()) - { -+ try -+ { - NBTTagCompound nbttagcompound3 = tileentity.writeToNBT(new NBTTagCompound()); - nbttaglist2.appendTag(nbttagcompound3); -+ } -+ catch (Exception e) -+ { -+ net.minecraftforge.fml.common.FMLLog.log.error("A TileEntity type {} has throw an exception trying to write state. It will not persist. Report this to the mod author", -+ tileentity.getClass().getName(), e); -+ } - } - - compound.setTag("TileEntities", nbttaglist2); -@@ -362,6 +430,18 @@ - - compound.setTag("TileTicks", nbttaglist3); - } -+ -+ if (chunkIn.getCapabilities() != null) -+ { -+ try -+ { -+ compound.setTag("ForgeCaps", chunkIn.getCapabilities().serializeNBT()); -+ } -+ catch (Exception exception) -+ { -+ net.minecraftforge.fml.common.FMLLog.log.error("A capability provider has thrown an exception trying to write state. It will not persist. Report this to the mod author", exception); -+ } -+ } - } - - private Chunk readChunkFromNBT(World worldIn, NBTTagCompound compound) -@@ -405,6 +485,16 @@ - chunk.setBiomeArray(compound.getByteArray("Biomes")); - } - -+ if (chunk.getCapabilities() != null && compound.hasKey("ForgeCaps")) { -+ chunk.getCapabilities().deserializeNBT(compound.getCompoundTag("ForgeCaps")); -+ } -+ -+ // End this method here and split off entity loading to another method -+ return chunk; -+ } -+ -+ public void loadEntities(World worldIn, NBTTagCompound compound, Chunk chunk) -+ { - NBTTagList nbttaglist1 = compound.getTagList("Entities", 10); - - for (int j1 = 0; j1 < nbttaglist1.tagCount(); j1++) -@@ -453,8 +543,6 @@ - ); - } - } -- -- return chunk; - } - - @Nullable -@@ -586,5 +674,10 @@ - - return entity; - } -+ } -+ -+ public int getPendingSaveCount() -+ { -+ return this.chunksToSave.size(); - } - } diff --git a/patches/minecraft/net/minecraft/world/chunk/storage/AnvilSaveHandler.java.patch b/patches/minecraft/net/minecraft/world/chunk/storage/AnvilSaveHandler.java.patch deleted file mode 100644 index b46f4451e..000000000 --- a/patches/minecraft/net/minecraft/world/chunk/storage/AnvilSaveHandler.java.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- before/net/minecraft/world/chunk/storage/AnvilSaveHandler.java -+++ after/net/minecraft/world/chunk/storage/AnvilSaveHandler.java -@@ -23,17 +23,11 @@ - { - File file1 = this.getWorldDirectory(); - -- if (provider instanceof WorldProviderHell) -+ if (provider.getSaveFolder() != null) - { -- File file3 = new File(file1, "DIM-1"); -+ File file3 = new File(file1, provider.getSaveFolder()); - file3.mkdirs(); - return new AnvilChunkLoader(file3, this.dataFixer); -- } -- else if (provider instanceof WorldProviderEnd) -- { -- File file2 = new File(file1, "DIM1"); -- file2.mkdirs(); -- return new AnvilChunkLoader(file2, this.dataFixer); - } - else - { diff --git a/patches/minecraft/net/minecraft/world/chunk/storage/ExtendedBlockStorage.java.patch b/patches/minecraft/net/minecraft/world/chunk/storage/ExtendedBlockStorage.java.patch deleted file mode 100644 index c4c328697..000000000 --- a/patches/minecraft/net/minecraft/world/chunk/storage/ExtendedBlockStorage.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/world/chunk/storage/ExtendedBlockStorage.java -+++ after/net/minecraft/world/chunk/storage/ExtendedBlockStorage.java -@@ -34,6 +34,8 @@ - - public void set(int x, int y, int z, IBlockState state) - { -+ if (state instanceof net.minecraftforge.common.property.IExtendedBlockState) -+ state = ((net.minecraftforge.common.property.IExtendedBlockState) state).getClean(); - IBlockState iblockstate = this.get(x, y, z); - Block block = iblockstate.getBlock(); - Block block1 = state.getBlock(); diff --git a/patches/minecraft/net/minecraft/world/chunk/storage/RegionFile.java.patch b/patches/minecraft/net/minecraft/world/chunk/storage/RegionFile.java.patch deleted file mode 100644 index 99229b7e3..000000000 --- a/patches/minecraft/net/minecraft/world/chunk/storage/RegionFile.java.patch +++ /dev/null @@ -1,116 +0,0 @@ ---- before/net/minecraft/world/chunk/storage/RegionFile.java -+++ after/net/minecraft/world/chunk/storage/RegionFile.java -@@ -19,6 +19,9 @@ - - public class RegionFile - { -+ // Minecraft is limited to 256 sections per chunk. So 1MB. This can easily be override. -+ // So we extend this to use the REAL size when the count is maxed by seeking to that section and reading the length. -+ private static final boolean FORGE_ENABLE_EXTENDED_SAVE = Boolean.parseBoolean(System.getProperty("forge.enableExtendedSave", "true")); - private static final byte[] EMPTY_SECTOR = new byte[4096]; - private final File fileName; - private RandomAccessFile dataFile; -@@ -74,13 +77,25 @@ - int k = this.dataFile.readInt(); - this.offsets[j1] = k; - -- if (k != 0 && (k >> 8) + (k & 0xFF) <= this.sectorFree.size()) -- { -- for (int l = 0; l < (k & 0xFF); l++) -+ int length = k & 255; -+ if (length == 255) -+ { -+ if ((k >> 8) <= this.sectorFree.size()) -+ { // We're maxed out, so we need to read the proper length from the section -+ this.dataFile.seek((k >> 8) * 4096); -+ length = (this.dataFile.readInt() + 4)/ 4096 + 1; -+ this.dataFile.seek(j1 * 4 + 4); //Go back to where we were -+ } -+ } -+ if (k != 0 && (k >> 8) + length <= this.sectorFree.size()) -+ { -+ for (int l = 0; l < length; l++) - { - this.sectorFree.set((k >> 8) + l, false); - } - } -+ else if (length > 0) -+ net.minecraftforge.fml.common.FMLLog.log.warn("Invalid chunk: ({}, {}) Offset: {} Length: {} runs off end file. {}", j1 % 32, (int)(j1 / 32), k >> 8, length, fileNameIn); - } - - for (int k1 = 0; k1 < 1024; k1++) -@@ -95,6 +110,12 @@ - } - } - -+ @Deprecated // TODO: remove (1.13) -+ public synchronized boolean chunkExists(int x, int z) -+ { -+ return isChunkSaved(x, z); -+ } -+ - @Nullable - - public synchronized DataInputStream getChunkDataInputStream(int x, int z) -@@ -117,6 +138,11 @@ - { - int j = i >> 8; - int k = i & 0xFF; -+ if (k == 255) -+ { -+ this.dataFile.seek(j * 4096); -+ k = (this.dataFile.readInt() + 4) / 4096 + 1; -+ } - - if (j + k > this.sectorFree.size()) - { -@@ -129,10 +155,12 @@ - - if (l > 4096 * k) - { -+ net.minecraftforge.fml.common.FMLLog.log.warn("Invalid chunk: ({}, {}) Offset: {} Invalid Size: {}>{} {}", x, z, j, l, k * 4096, fileName); - return null; - } - else if (l <= 0) - { -+ net.minecraftforge.fml.common.FMLLog.log.warn("Invalid chunk: ({}, {}) Offset: {} Invalid Size: {} {}", x, z, j, l, fileName); - return null; - } - else -@@ -181,11 +209,17 @@ - int i = this.getOffset(x, z); - int j = i >> 8; - int k = i & 0xFF; -+ if (k == 255) -+ { -+ this.dataFile.seek(j * 4096); -+ k = (this.dataFile.readInt() + 4) / 4096 + 1; -+ } - int l = (length + 5) / 4096 + 1; - - if (l >= 256) - { -- return; -+ if (!FORGE_ENABLE_EXTENDED_SAVE) return; -+ net.minecraftforge.fml.common.FMLLog.log.warn("Large Chunk Detected: ({}, {}) Size: {} {}", x, z, l, fileName); - } - - if (j != 0 && k == l) -@@ -233,7 +267,7 @@ - if (j1 >= l) - { - j = l1; -- this.setOffset(x, z, l1 << 8 | l); -+ this.setOffset(x, z, l1 << 8 | (l > 255 ? 255 : l)); - - for (int j2 = 0; j2 < l; j2++) - { -@@ -255,7 +289,7 @@ - - this.sizeDelta += 4096 * l; - this.write(j, data, length); -- this.setOffset(x, z, j << 8 | l); -+ this.setOffset(x, z, j << 8 | (l > 255 ? 255 : l)); - } - } - diff --git a/patches/minecraft/net/minecraft/world/end/DragonFightManager.java.patch b/patches/minecraft/net/minecraft/world/end/DragonFightManager.java.patch deleted file mode 100644 index aaa7df737..000000000 --- a/patches/minecraft/net/minecraft/world/end/DragonFightManager.java.patch +++ /dev/null @@ -1,34 +0,0 @@ ---- before/net/minecraft/world/end/DragonFightManager.java -+++ after/net/minecraft/world/end/DragonFightManager.java -@@ -87,6 +87,7 @@ - - this.dragonKilled = compound.getBoolean("DragonKilled"); - this.previouslyKilled = compound.getBoolean("PreviouslyKilled"); -+ this.scanForLegacyFight = !compound.getBoolean("LegacyScanPerformed"); // Forge: fix MC-105080 - - if (compound.getBoolean("IsRespawning")) - { -@@ -140,6 +141,7 @@ - - nbttagcompound.setBoolean("DragonKilled", this.dragonKilled); - nbttagcompound.setBoolean("PreviouslyKilled", this.previouslyKilled); -+ nbttagcompound.setBoolean("LegacyScanPerformed", !this.scanForLegacyFight); // Forge: fix MC-105080 - - if (this.exitPortalLocation != null) - { -@@ -604,5 +606,15 @@ - entityendercrystal.setBeamTarget(null); - } - } -+ } -+ -+ public void addPlayer(EntityPlayerMP player) -+ { -+ this.bossInfo.addPlayer(player); -+ } -+ -+ public void removePlayer(EntityPlayerMP player) -+ { -+ this.bossInfo.removePlayer(player); - } - } diff --git a/patches/minecraft/net/minecraft/world/gen/ChunkGeneratorEnd.java.patch b/patches/minecraft/net/minecraft/world/gen/ChunkGeneratorEnd.java.patch deleted file mode 100644 index c8aeace69..000000000 --- a/patches/minecraft/net/minecraft/world/gen/ChunkGeneratorEnd.java.patch +++ /dev/null @@ -1,73 +0,0 @@ ---- before/net/minecraft/world/gen/ChunkGeneratorEnd.java -+++ after/net/minecraft/world/gen/ChunkGeneratorEnd.java -@@ -43,6 +43,9 @@ - double[] ar; - double[] br; - private final WorldGenEndIsland endIslands = new WorldGenEndIsland(); -+ // temporary variables used during event handling -+ private int chunkX = 0; -+ private int chunkZ = 0; - - public ChunkGeneratorEnd(World p_i47241_1_, boolean p_i47241_2_, long p_i47241_3_, BlockPos p_i47241_5_) - { -@@ -56,6 +59,17 @@ - this.noiseGen5 = new NoiseGeneratorOctaves(this.rand, 10); - this.noiseGen6 = new NoiseGeneratorOctaves(this.rand, 16); - this.islandNoise = new NoiseGeneratorSimplex(this.rand); -+ -+ net.minecraftforge.event.terraingen.InitNoiseGensEvent.ContextEnd ctx = -+ new net.minecraftforge.event.terraingen.InitNoiseGensEvent.ContextEnd(lperlinNoise1, lperlinNoise2, perlinNoise1, noiseGen5, noiseGen6, islandNoise); -+ ctx = net.minecraftforge.event.terraingen.TerrainGen.getModdedNoiseGenerators(p_i47241_1_, this.rand, ctx); -+ this.lperlinNoise1 = ctx.getLPerlin1(); -+ this.lperlinNoise2 = ctx.getLPerlin2(); -+ this.perlinNoise1 = ctx.getPerlin(); -+ this.noiseGen5 = ctx.getDepth(); -+ this.noiseGen6 = ctx.getScale(); -+ this.islandNoise = ctx.getIsland(); -+ this.endCityGen = (MapGenEndCity) net.minecraftforge.event.terraingen.TerrainGen.getModdedMapGen(this.endCityGen, net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.END_CITY); - } - - public void setBlocksInChunk(int x, int z, ChunkPrimer primer) -@@ -128,6 +142,7 @@ - - public void buildSurfaces(ChunkPrimer primer) - { -+ if (!net.minecraftforge.event.ForgeEventFactory.onReplaceBiomeBlocks(this, this.chunkX, this.chunkZ, primer, this.world)) return; - for (int i = 0; i < 16; i++) - { - for (int j = 0; j < 16; j++) -@@ -174,6 +189,7 @@ - @Override - public Chunk generateChunk(int x, int z) - { -+ this.chunkX = x; this.chunkZ = z; - this.rand.setSeed(x * 341873128712L + z * 132897987541L); - ChunkPrimer chunkprimer = new ChunkPrimer(); - this.biomesForGeneration = this.world.getBiomeProvider().getBiomes(this.biomesForGeneration, x * 16, z * 16, 16, 16); -@@ -255,6 +271,10 @@ - - private double[] getHeights(double[] p_185963_1_, int p_185963_2_, int p_185963_3_, int p_185963_4_, int p_185963_5_, int p_185963_6_, int p_185963_7_) - { -+ net.minecraftforge.event.terraingen.ChunkGeneratorEvent.InitNoiseField event = new net.minecraftforge.event.terraingen.ChunkGeneratorEvent.InitNoiseField(this, p_185963_1_, p_185963_2_, p_185963_3_, p_185963_4_, p_185963_5_, p_185963_6_, p_185963_7_); -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event); -+ if (event.getResult() == net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) return event.getNoisefield(); -+ - if (p_185963_1_ == null) - { - p_185963_1_ = new double[p_185963_5_ * p_185963_6_ * p_185963_7_]; -@@ -333,6 +353,7 @@ - public void populate(int x, int z) - { - BlockFalling.fallInstantly = true; -+ net.minecraftforge.event.ForgeEventFactory.onChunkPopulate(true, this, this.world, this.rand, x, z, false); - BlockPos blockpos = new BlockPos(x * 16, 0, z * 16); - - if (this.mapFeaturesEnabled) -@@ -412,6 +433,7 @@ - } - } - -+ net.minecraftforge.event.ForgeEventFactory.onChunkPopulate(false, this, this.world, this.rand, x, z, false); - BlockFalling.fallInstantly = false; - } - diff --git a/patches/minecraft/net/minecraft/world/gen/ChunkGeneratorFlat.java.patch b/patches/minecraft/net/minecraft/world/gen/ChunkGeneratorFlat.java.patch deleted file mode 100644 index 9690e48b8..000000000 --- a/patches/minecraft/net/minecraft/world/gen/ChunkGeneratorFlat.java.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- before/net/minecraft/world/gen/ChunkGeneratorFlat.java -+++ after/net/minecraft/world/gen/ChunkGeneratorFlat.java -@@ -166,6 +166,7 @@ - @Override - public void populate(int x, int z) - { -+ net.minecraft.block.BlockFalling.fallInstantly = true; - int i = x * 16; - int j = z * 16; - BlockPos blockpos = new BlockPos(i, 0, j); -@@ -177,6 +178,8 @@ - this.random.setSeed(x * k + z * l ^ this.world.getSeed()); - ChunkPos chunkpos = new ChunkPos(x, z); - -+ net.minecraftforge.event.ForgeEventFactory.onChunkPopulate(true, this, this.world, this.random, x, z, flag); -+ - for (MapGenStructure mapgenstructure : this.structureGenerators.values()) - { - boolean flag1 = mapgenstructure.generateStructure(this.world, this.random, chunkpos); -@@ -226,6 +229,9 @@ - { - biome.decorate(this.world, this.random, blockpos); - } -+ -+ net.minecraftforge.event.ForgeEventFactory.onChunkPopulate(false, this, this.world, this.random, x, z, flag); -+ net.minecraft.block.BlockFalling.fallInstantly = false; - } - - @Override diff --git a/patches/minecraft/net/minecraft/world/gen/ChunkGeneratorHell.java.patch b/patches/minecraft/net/minecraft/world/gen/ChunkGeneratorHell.java.patch deleted file mode 100644 index 829ce56ae..000000000 --- a/patches/minecraft/net/minecraft/world/gen/ChunkGeneratorHell.java.patch +++ /dev/null @@ -1,129 +0,0 @@ ---- before/net/minecraft/world/gen/ChunkGeneratorHell.java -+++ after/net/minecraft/world/gen/ChunkGeneratorHell.java -@@ -81,6 +81,19 @@ - this.scaleNoise = new NoiseGeneratorOctaves(this.rand, 10); - this.depthNoise = new NoiseGeneratorOctaves(this.rand, 16); - worldIn.setSeaLevel(63); -+ -+ net.minecraftforge.event.terraingen.InitNoiseGensEvent.ContextHell ctx = -+ new net.minecraftforge.event.terraingen.InitNoiseGensEvent.ContextHell(lperlinNoise1, lperlinNoise2, perlinNoise1, slowsandGravelNoiseGen, netherrackExculsivityNoiseGen, scaleNoise, depthNoise); -+ ctx = net.minecraftforge.event.terraingen.TerrainGen.getModdedNoiseGenerators(worldIn, this.rand, ctx); -+ this.lperlinNoise1 = ctx.getLPerlin1(); -+ this.lperlinNoise2 = ctx.getLPerlin2(); -+ this.perlinNoise1 = ctx.getPerlin(); -+ this.slowsandGravelNoiseGen = ctx.getPerlin2(); -+ this.netherrackExculsivityNoiseGen = ctx.getPerlin3(); -+ this.scaleNoise = ctx.getScale(); -+ this.depthNoise = ctx.getDepth(); -+ this.genNetherBridge = (MapGenNetherBridge)net.minecraftforge.event.terraingen.TerrainGen.getModdedMapGen(genNetherBridge, net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.NETHER_BRIDGE); -+ this.genNetherCaves = net.minecraftforge.event.terraingen.TerrainGen.getModdedMapGen(genNetherCaves, net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.NETHER_CAVE); - } - - public void prepareHeights(int p_185936_1_, int p_185936_2_, ChunkPrimer primer) -@@ -159,6 +172,7 @@ - - public void buildSurfaces(int p_185937_1_, int p_185937_2_, ChunkPrimer primer) - { -+ if (!net.minecraftforge.event.ForgeEventFactory.onReplaceBiomeBlocks(this, p_185937_1_, p_185937_2_, primer, this.world)) return; - int i = this.world.getSeaLevel() + 1; - double d0 = 0.03125; - this.slowsandNoise = this.slowsandGravelNoiseGen.generateNoiseOctaves(this.slowsandNoise, p_185937_1_ * 16, p_185937_2_ * 16, 0, 16, 16, 1, 0.03125, 0.03125, 1.0); -@@ -279,6 +293,10 @@ - p_185938_1_ = new double[p_185938_5_ * p_185938_6_ * p_185938_7_]; - } - -+ net.minecraftforge.event.terraingen.ChunkGeneratorEvent.InitNoiseField event = new net.minecraftforge.event.terraingen.ChunkGeneratorEvent.InitNoiseField(this, p_185938_1_, p_185938_2_, p_185938_3_, p_185938_4_, p_185938_5_, p_185938_6_, p_185938_7_); -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event); -+ if (event.getResult() == net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) return event.getNoisefield(); -+ - double d0 = 684.412; - double d1 = 2053.236; - this.noiseData4 = this.scaleNoise -@@ -368,6 +386,7 @@ - public void populate(int x, int z) - { - BlockFalling.fallInstantly = true; -+ net.minecraftforge.event.ForgeEventFactory.onChunkPopulate(true, this, this.world, this.rand, x, z, false); - int i = x * 16; - int j = z * 16; - BlockPos blockpos = new BlockPos(i, 0, j); -@@ -375,6 +394,7 @@ - ChunkPos chunkpos = new ChunkPos(x, z); - this.genNetherBridge.generateStructure(this.world, this.rand, chunkpos); - -+ if (net.minecraftforge.event.terraingen.TerrainGen.populate(this, this.world, this.rand, x, z, false, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.NETHER_LAVA)) - for (int k = 0; k < 8; k++) - { - this.hellSpringGen -@@ -385,6 +405,7 @@ - ); - } - -+ if (net.minecraftforge.event.terraingen.TerrainGen.populate(this, this.world, this.rand, x, z, false, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.FIRE)) - for (int i1 = 0; i1 < this.rand.nextInt(this.rand.nextInt(10) + 1) + 1; i1++) - { - this.fireFeature -@@ -395,6 +416,8 @@ - ); - } - -+ if (net.minecraftforge.event.terraingen.TerrainGen.populate(this, this.world, this.rand, x, z, false, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.GLOWSTONE)) -+ { - for (int j1 = 0; j1 < this.rand.nextInt(this.rand.nextInt(10) + 1); j1++) - { - this.lightGemGen -@@ -415,6 +438,13 @@ - ); - } - -+ }//Forge: End doGLowstone -+ -+ net.minecraftforge.event.ForgeEventFactory.onChunkPopulate(false, this, this.world, this.rand, x, z, false); -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.terraingen.DecorateBiomeEvent.Pre(this.world, this.rand, chunkpos)); -+ -+ if (net.minecraftforge.event.terraingen.TerrainGen.decorate(this.world, this.rand, chunkpos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.SHROOM)) -+ { - if (this.rand.nextBoolean()) - { - this.brownMushroomFeature -@@ -435,6 +465,8 @@ - ); - } - -+ } -+ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(this.world, this.rand, quartzGen, blockpos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.QUARTZ)) - for (int l1 = 0; l1 < 16; l1++) - { - this.quartzGen -@@ -447,6 +479,7 @@ - - int i2 = this.world.getSeaLevel() / 2 + 1; - -+ if (net.minecraftforge.event.terraingen.TerrainGen.populate(this, this.world, this.rand, x, z, false, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.NETHER_MAGMA)) - for (int l = 0; l < 4; l++) - { - this.magmaGen -@@ -457,17 +490,22 @@ - ); - } - -+ if (net.minecraftforge.event.terraingen.TerrainGen.populate(this, this.world, this.rand, x, z, false, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.NETHER_LAVA2)) - for (int j2 = 0; j2 < 16; j2++) - { -+ int offset = net.minecraftforge.common.ForgeModContainer.fixVanillaCascading ? 8 : 0; // MC-117810 - this.lavaTrapGen - .generate( - this.world, - this.rand, -- blockpos.add(this.rand.nextInt(16), this.rand.nextInt(108) + 10, this.rand.nextInt(16)) -+ blockpos.add(this.rand.nextInt(16) + offset, this.rand.nextInt(108) + 10, this.rand.nextInt(16) + offset) - ); - } - - biome.decorate(this.world, this.rand, new BlockPos(i, 0, j)); -+ -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.terraingen.DecorateBiomeEvent.Post(this.world, this.rand, blockpos)); -+ - BlockFalling.fallInstantly = false; - } - diff --git a/patches/minecraft/net/minecraft/world/gen/ChunkGeneratorOverworld.java.patch b/patches/minecraft/net/minecraft/world/gen/ChunkGeneratorOverworld.java.patch deleted file mode 100644 index a737e6f27..000000000 --- a/patches/minecraft/net/minecraft/world/gen/ChunkGeneratorOverworld.java.patch +++ /dev/null @@ -1,101 +0,0 @@ ---- before/net/minecraft/world/gen/ChunkGeneratorOverworld.java -+++ after/net/minecraft/world/gen/ChunkGeneratorOverworld.java -@@ -61,6 +61,16 @@ - - public ChunkGeneratorOverworld(World worldIn, long seed, boolean mapFeaturesEnabledIn, String generatorOptions) - { -+ { -+ caveGenerator = net.minecraftforge.event.terraingen.TerrainGen.getModdedMapGen(caveGenerator, net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.CAVE); -+ strongholdGenerator = (MapGenStronghold)net.minecraftforge.event.terraingen.TerrainGen.getModdedMapGen(strongholdGenerator, net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.STRONGHOLD); -+ villageGenerator = (MapGenVillage)net.minecraftforge.event.terraingen.TerrainGen.getModdedMapGen(villageGenerator, net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.VILLAGE); -+ mineshaftGenerator = (MapGenMineshaft)net.minecraftforge.event.terraingen.TerrainGen.getModdedMapGen(mineshaftGenerator, net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.MINESHAFT); -+ scatteredFeatureGenerator = (MapGenScatteredFeature)net.minecraftforge.event.terraingen.TerrainGen.getModdedMapGen(scatteredFeatureGenerator, net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.SCATTERED_FEATURE); -+ ravineGenerator = net.minecraftforge.event.terraingen.TerrainGen.getModdedMapGen(ravineGenerator, net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.RAVINE); -+ oceanMonumentGenerator = (StructureOceanMonument)net.minecraftforge.event.terraingen.TerrainGen.getModdedMapGen(oceanMonumentGenerator, net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.OCEAN_MONUMENT); -+ woodlandMansionGenerator = (WoodlandMansion)net.minecraftforge.event.terraingen.TerrainGen.getModdedMapGen(woodlandMansionGenerator, net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.WOODLAND_MANSION); -+ } - this.world = worldIn; - this.mapFeaturesEnabled = mapFeaturesEnabledIn; - this.terrainType = worldIn.getWorldInfo().getTerrainType(); -@@ -90,6 +100,17 @@ - this.oceanBlock = this.settings.useLavaOceans ? Blocks.LAVA.getDefaultState() : Blocks.WATER.getDefaultState(); - worldIn.setSeaLevel(this.settings.seaLevel); - } -+ -+ net.minecraftforge.event.terraingen.InitNoiseGensEvent.ContextOverworld ctx = -+ new net.minecraftforge.event.terraingen.InitNoiseGensEvent.ContextOverworld(minLimitPerlinNoise, maxLimitPerlinNoise, mainPerlinNoise, surfaceNoise, scaleNoise, depthNoise, forestNoise); -+ ctx = net.minecraftforge.event.terraingen.TerrainGen.getModdedNoiseGenerators(worldIn, this.rand, ctx); -+ this.minLimitPerlinNoise = ctx.getLPerlin1(); -+ this.maxLimitPerlinNoise = ctx.getLPerlin2(); -+ this.mainPerlinNoise = ctx.getPerlin(); -+ this.surfaceNoise = ctx.getHeight(); -+ this.scaleNoise = ctx.getScale(); -+ this.depthNoise = ctx.getDepth(); -+ this.forestNoise = ctx.getForest(); - } - - public void setBlocksInChunk(int x, int z, ChunkPrimer primer) -@@ -163,6 +184,7 @@ - - public void replaceBiomeBlocks(int x, int z, ChunkPrimer primer, Biome[] biomesIn) - { -+ if (!net.minecraftforge.event.ForgeEventFactory.onReplaceBiomeBlocks(this, x, z, primer, this.world)) return; - double d0 = 0.03125; - this.depthBuffer = this.surfaceNoise.getRegion(this.depthBuffer, x * 16, z * 16, 16, 16, 0.0625, 0.0625, 1.0); - -@@ -396,6 +418,8 @@ - boolean flag = false; - ChunkPos chunkpos = new ChunkPos(x, z); - -+ net.minecraftforge.event.ForgeEventFactory.onChunkPopulate(true, this, this.world, this.rand, x, z, flag); -+ - if (this.mapFeaturesEnabled) - { - if (this.settings.useMineShafts) -@@ -434,6 +458,7 @@ - && this.settings.useWaterLakes - && !flag - && this.rand.nextInt(this.settings.waterLakeChance) == 0) -+ if (net.minecraftforge.event.terraingen.TerrainGen.populate(this, this.world, this.rand, x, z, flag, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.LAKE)) - { - int i1 = this.rand.nextInt(16) + 8; - int j1 = this.rand.nextInt(256); -@@ -442,6 +467,7 @@ - } - - if (!flag && this.rand.nextInt(this.settings.lavaLakeChance / 10) == 0 && this.settings.useLavaLakes) -+ if (net.minecraftforge.event.terraingen.TerrainGen.populate(this, this.world, this.rand, x, z, flag, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.LAVA)) - { - int i2 = this.rand.nextInt(16) + 8; - int l2 = this.rand.nextInt(this.rand.nextInt(248) + 8); -@@ -454,6 +480,7 @@ - } - - if (this.settings.useDungeons) -+ if (net.minecraftforge.event.terraingen.TerrainGen.populate(this, this.world, this.rand, x, z, flag, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.DUNGEON)) - { - for (int j2 = 0; j2 < this.settings.dungeonChance; j2++) - { -@@ -465,9 +492,12 @@ - } - - biome.decorate(this.world, this.rand, new BlockPos(i, 0, j)); -+ if (net.minecraftforge.event.terraingen.TerrainGen.populate(this, this.world, this.rand, x, z, flag, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.ANIMALS)) - WorldEntitySpawner.performWorldGenSpawning(this.world, biome, i + 8, j + 8, 16, 16, this.rand); - blockpos = blockpos.add(8, 0, 8); - -+ if (net.minecraftforge.event.terraingen.TerrainGen.populate(this, this.world, this.rand, x, z, flag, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.ICE)) -+ { - for (int k2 = 0; k2 < 16; k2++) - { - for (int j3 = 0; j3 < 16; j3++) -@@ -486,6 +516,9 @@ - } - } - } -+ }//Forge: End ICE -+ -+ net.minecraftforge.event.ForgeEventFactory.onChunkPopulate(false, this, this.world, this.rand, x, z, flag); - - BlockFalling.fallInstantly = false; - } diff --git a/patches/minecraft/net/minecraft/world/gen/ChunkProviderServer.java.patch b/patches/minecraft/net/minecraft/world/gen/ChunkProviderServer.java.patch deleted file mode 100644 index 0238ae300..000000000 --- a/patches/minecraft/net/minecraft/world/gen/ChunkProviderServer.java.patch +++ /dev/null @@ -1,91 +0,0 @@ ---- before/net/minecraft/world/gen/ChunkProviderServer.java -+++ after/net/minecraft/world/gen/ChunkProviderServer.java -@@ -34,6 +34,7 @@ - public final IChunkLoader chunkLoader; - public final Long2ObjectMap loadedChunks = new Long2ObjectOpenHashMap<>(8192); - public final WorldServer world; -+ private final Set loadingChunks = com.google.common.collect.Sets.newHashSet(); - - public ChunkProviderServer(WorldServer worldObjIn, IChunkLoader chunkLoaderIn, IChunkGenerator chunkGeneratorIn) - { -@@ -82,20 +83,49 @@ - @Nullable - public Chunk loadChunk(int x, int z) - { -+ return loadChunk(x, z, null); -+ } -+ -+ @Nullable -+ public Chunk loadChunk(int x, int z, @Nullable Runnable runnable) -+ { - Chunk chunk = this.getLoadedChunk(x, z); - - if (chunk == null) - { -- chunk = this.loadChunkFromFile(x, z); -+ long pos = ChunkPos.asLong(x, z); - -- if (chunk != null) -+ chunk = net.minecraftforge.common.ForgeChunkManager.fetchDormantChunk(pos, this.world); -+ if (chunk != null || !(this.chunkLoader instanceof net.minecraft.world.chunk.storage.AnvilChunkLoader)) - { -+ if (!loadingChunks.add(pos)) net.minecraftforge.fml.common.FMLLog.bigWarning("There is an attempt to load a chunk ({},{}) in dimension {} that is already being loaded. This will cause weird chunk breakages.", x, z, this.world.provider.getDimension()); -+ if (chunk == null) chunk = this.loadChunkFromFile(x, z); -+ -+ if (chunk != null) -+ { - this.loadedChunks.put(ChunkPos.asLong(x, z), chunk); - chunk.onLoad(); - chunk.populate(this, this.chunkGenerator); -+ } -+ -+ loadingChunks.remove(pos); -+ } -+ else -+ { -+ net.minecraft.world.chunk.storage.AnvilChunkLoader loader = (net.minecraft.world.chunk.storage.AnvilChunkLoader) this.chunkLoader; -+ if (runnable == null || !net.minecraftforge.common.ForgeChunkManager.asyncChunkLoading) -+ chunk = net.minecraftforge.common.chunkio.ChunkIOExecutor.syncChunkLoad(this.world, loader, this, x, z); -+ else if (loader.isChunkGeneratedAt(x, z)) -+ { -+ // We can only use the async queue for already generated chunks -+ net.minecraftforge.common.chunkio.ChunkIOExecutor.queueChunkLoad(this.world, loader, this, x, z, runnable); -+ return null; -+ } - } - } - -+ // If we didn't load the chunk async and have a callback run it now -+ if (runnable != null) runnable.run(); - return chunk; - } - -@@ -222,6 +252,11 @@ - { - if (!this.droppedChunks.isEmpty()) - { -+ for (ChunkPos forced : this.world.getPersistentChunks().keySet()) -+ { -+ this.droppedChunks.remove(ChunkPos.asLong(forced.x, forced.z)); -+ } -+ - Iterator iterator = this.droppedChunks.iterator(); - - for (int i = 0; i < 100 && iterator.hasNext(); iterator.remove()) -@@ -232,6 +267,7 @@ - if (chunk != null && chunk.unloadQueued) - { - chunk.onUnload(); -+ net.minecraftforge.common.ForgeChunkManager.putDormantChunk(ChunkPos.asLong(chunk.x, chunk.z), chunk); - this.saveChunkData(chunk); - this.saveChunkExtraData(chunk); - this.loadedChunks.remove(olong); -@@ -239,6 +275,8 @@ - } - } - } -+ -+ if (this.loadedChunks.isEmpty()) net.minecraftforge.common.DimensionManager.unloadWorld(this.world.provider.getDimension()); - - this.chunkLoader.chunkTick(); - } diff --git a/patches/minecraft/net/minecraft/world/gen/MapGenCaves.java.patch b/patches/minecraft/net/minecraft/world/gen/MapGenCaves.java.patch deleted file mode 100644 index 0c45c4e5c..000000000 --- a/patches/minecraft/net/minecraft/world/gen/MapGenCaves.java.patch +++ /dev/null @@ -1,118 +0,0 @@ ---- before/net/minecraft/world/gen/MapGenCaves.java -+++ after/net/minecraft/world/gen/MapGenCaves.java -@@ -201,9 +201,7 @@ - { - if (l1 >= 0 && l1 < 256) - { -- IBlockState iblockstate = p_180702_5_.getBlockState(j1, l1, k1); -- -- if (iblockstate.getBlock() == Blocks.FLOWING_WATER || iblockstate.getBlock() == Blocks.WATER) -+ if (isOceanBlock(p_180702_5_, j1, l1, k1, p_180702_3_, p_180702_4_)) - { - flag3 = true; - } -@@ -241,33 +239,12 @@ - IBlockState iblockstate1 = p_180702_5_.getBlockState(j3, j2, i2); - IBlockState iblockstate2 = MoreObjects.firstNonNull(p_180702_5_.getBlockState(j3, j2 + 1, i2), BLK_AIR); - -- if (iblockstate1.getBlock() == Blocks.GRASS || iblockstate1.getBlock() == Blocks.MYCELIUM) -+ if (isTopBlock(p_180702_5_, j3, j2, i2, p_180702_3_, p_180702_4_)) - { - flag1 = true; - } - -- if (this.canReplaceBlock(iblockstate1, iblockstate2)) -- { -- if (j2 - 1 < 10) -- { -- p_180702_5_.setBlockState(j3, j2, i2, BLK_LAVA); -- } -- else -- { -- p_180702_5_.setBlockState(j3, j2, i2, BLK_AIR); -- -- if (flag1 && p_180702_5_.getBlockState(j3, j2 - 1, i2).getBlock() == Blocks.DIRT) -- { -- blockpos$mutableblockpos.setPos(j3 + p_180702_3_ * 16, 0, i2 + p_180702_4_ * 16); -- p_180702_5_.setBlockState( -- j3, -- j2 - 1, -- i2, -- this.world.getBiome(blockpos$mutableblockpos).topBlock.getBlock().getDefaultState() -- ); -- } -- } -- } -+ digBlock(p_180702_5_, j3, j2, i2, p_180702_3_, p_180702_4_, flag1, iblockstate1, iblockstate2); - } - } - } -@@ -362,6 +339,68 @@ - } - - this.addTunnel(this.rand.nextLong(), originalX, originalZ, chunkPrimerIn, d0, d1, d2, f2, f, f1, 0, 0, 1.0); -+ } -+ } -+ } -+ -+ protected boolean isOceanBlock(ChunkPrimer data, int x, int y, int z, int chunkX, int chunkZ) -+ { -+ net.minecraft.block.Block block = data.getBlockState(x, y, z).getBlock(); -+ return block== Blocks.FLOWING_WATER || block == Blocks.WATER; -+ } -+ -+ //Exception biomes to make sure we generate like vanilla -+ private boolean isExceptionBiome(net.minecraft.world.biome.Biome biome) -+ { -+ if (biome == net.minecraft.init.Biomes.BEACH) return true; -+ if (biome == net.minecraft.init.Biomes.DESERT) return true; -+ return false; -+ } -+ -+ //Determine if the block at the specified location is the top block for the biome, we take into account -+ //Vanilla bugs to make sure that we generate the map the same way vanilla does. -+ private boolean isTopBlock(ChunkPrimer data, int x, int y, int z, int chunkX, int chunkZ) -+ { -+ net.minecraft.world.biome.Biome biome = world.getBiome(new BlockPos(x + chunkX * 16, 0, z + chunkZ * 16)); -+ IBlockState state = data.getBlockState(x, y, z); -+ return (isExceptionBiome(biome) ? state.getBlock() == Blocks.GRASS : state.getBlock() == biome.topBlock); -+ } -+ -+ /** -+ * Digs out the current block, default implementation removes stone, filler, and top block -+ * Sets the block to lava if y is less then 10, and air other wise. -+ * If setting to air, it also checks to see if we've broken the surface and if so -+ * tries to make the floor the biome's top block -+ * -+ * @param data Block data array -+ * @param index Pre-calculated index into block data -+ * @param x local X position -+ * @param y local Y position -+ * @param z local Z position -+ * @param chunkX Chunk X position -+ * @param chunkZ Chunk Y position -+ * @param foundTop True if we've encountered the biome's top block. Ideally if we've broken the surface. -+ */ -+ protected void digBlock(ChunkPrimer data, int x, int y, int z, int chunkX, int chunkZ, boolean foundTop, IBlockState state, IBlockState up) -+ { -+ net.minecraft.world.biome.Biome biome = world.getBiome(new BlockPos(x + chunkX * 16, 0, z + chunkZ * 16)); -+ IBlockState top = biome.topBlock; -+ IBlockState filler = biome.fillerBlock; -+ -+ if (this.canReplaceBlock(state, up) || state.getBlock() == top.getBlock() || state.getBlock() == filler.getBlock()) -+ { -+ if (y - 1 < 10) -+ { -+ data.setBlockState(x, y, z, BLK_LAVA); -+ } -+ else -+ { -+ data.setBlockState(x, y, z, BLK_AIR); -+ -+ if (foundTop && data.getBlockState(x, y - 1, z).getBlock() == filler.getBlock()) -+ { -+ data.setBlockState(x, y - 1, z, top.getBlock().getDefaultState()); -+ } - } - } - } diff --git a/patches/minecraft/net/minecraft/world/gen/MapGenRavine.java.patch b/patches/minecraft/net/minecraft/world/gen/MapGenRavine.java.patch deleted file mode 100644 index 8b04e6272..000000000 --- a/patches/minecraft/net/minecraft/world/gen/MapGenRavine.java.patch +++ /dev/null @@ -1,128 +0,0 @@ ---- before/net/minecraft/world/gen/MapGenRavine.java -+++ after/net/minecraft/world/gen/MapGenRavine.java -@@ -145,9 +145,7 @@ - { - if (l1 >= 0 && l1 < 256) - { -- IBlockState iblockstate = p_180707_5_.getBlockState(j1, l1, k1); -- -- if (iblockstate.getBlock() == Blocks.FLOWING_WATER || iblockstate.getBlock() == Blocks.WATER) -+ if (isOceanBlock(p_180707_5_, j1, l1, k1, p_180707_3_, p_180707_4_)) - { - flag2 = true; - } -@@ -163,8 +161,6 @@ - - if (!flag2) - { -- BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos(); -- - for (int j3 = k2; j3 < k; j3++) - { - double d10 = (j3 + p_180707_3_ * 16 + 0.5 - p_180707_6_) / d9; -@@ -182,32 +178,12 @@ - - if ((d10 * d10 + d7 * d7) * this.rs[j2 - 1] + d8 * d8 / 6.0 < 1.0) - { -- IBlockState iblockstate1 = p_180707_5_.getBlockState(j3, j2, i2); -- -- if (iblockstate1.getBlock() == Blocks.GRASS) -+ if (isTopBlock(p_180707_5_, j3, j2, i2, p_180707_3_, p_180707_4_)) - { - flag = true; - } - -- if (iblockstate1.getBlock() == Blocks.STONE -- || iblockstate1.getBlock() == Blocks.DIRT -- || iblockstate1.getBlock() == Blocks.GRASS) -- { -- if (j2 - 1 < 10) -- { -- p_180707_5_.setBlockState(j3, j2, i2, FLOWING_LAVA); -- } -- else -- { -- p_180707_5_.setBlockState(j3, j2, i2, AIR); -- -- if (flag && p_180707_5_.getBlockState(j3, j2 - 1, i2).getBlock() == Blocks.DIRT) -- { -- blockpos$mutableblockpos.setPos(j3 + p_180707_3_ * 16, 0, i2 + p_180707_4_ * 16); -- p_180707_5_.setBlockState(j3, j2 - 1, i2, this.world.getBiome(blockpos$mutableblockpos).topBlock); -- } -- } -- } -+ digBlock(p_180707_5_, j3, j2, i2, p_180707_3_, p_180707_4_, flag); - } - } - } -@@ -240,6 +216,70 @@ - float f1 = (this.rand.nextFloat() - 0.5F) * 2.0F / 8.0F; - float f2 = (this.rand.nextFloat() * 2.0F + this.rand.nextFloat()) * 2.0F; - this.addTunnel(this.rand.nextLong(), originalX, originalZ, chunkPrimerIn, d0, d1, d2, f2, f, f1, 0, 0, 3.0); -+ } -+ } -+ } -+ protected boolean isOceanBlock(ChunkPrimer data, int x, int y, int z, int chunkX, int chunkZ) -+ { -+ net.minecraft.block.Block block = data.getBlockState(x, y, z).getBlock(); -+ return block== Blocks.FLOWING_WATER || block == Blocks.WATER; -+ } -+ -+ //Exception biomes to make sure we generate like vanilla -+ private boolean isExceptionBiome(net.minecraft.world.biome.Biome biome) -+ { -+ if (biome == net.minecraft.init.Biomes.BEACH) return true; -+ if (biome == net.minecraft.init.Biomes.DESERT) return true; -+ if (biome == net.minecraft.init.Biomes.MUSHROOM_ISLAND) return true; -+ if (biome == net.minecraft.init.Biomes.MUSHROOM_ISLAND_SHORE) return true; -+ return false; -+ } -+ -+ //Determine if the block at the specified location is the top block for the biome, we take into account -+ //Vanilla bugs to make sure that we generate the map the same way vanilla does. -+ private boolean isTopBlock(ChunkPrimer data, int x, int y, int z, int chunkX, int chunkZ) -+ { -+ net.minecraft.world.biome.Biome biome = world.getBiome(new BlockPos(x + chunkX * 16, 0, z + chunkZ * 16)); -+ IBlockState state = data.getBlockState(x, y, z); -+ return (isExceptionBiome(biome) ? state.getBlock() == Blocks.GRASS : state.getBlock() == biome.topBlock); -+ } -+ -+ /** -+ * Digs out the current block, default implementation removes stone, filler, and top block -+ * Sets the block to lava if y is less then 10, and air other wise. -+ * If setting to air, it also checks to see if we've broken the surface and if so -+ * tries to make the floor the biome's top block -+ * -+ * @param data Block data array -+ * @param index Pre-calculated index into block data -+ * @param x local X position -+ * @param y local Y position -+ * @param z local Z position -+ * @param chunkX Chunk X position -+ * @param chunkZ Chunk Y position -+ * @param foundTop True if we've encountered the biome's top block. Ideally if we've broken the surface. -+ */ -+ protected void digBlock(ChunkPrimer data, int x, int y, int z, int chunkX, int chunkZ, boolean foundTop) -+ { -+ net.minecraft.world.biome.Biome biome = world.getBiome(new BlockPos(x + chunkX * 16, 0, z + chunkZ * 16)); -+ IBlockState state = data.getBlockState(x, y, z); -+ IBlockState top = isExceptionBiome(biome) ? Blocks.GRASS.getDefaultState() : biome.topBlock; -+ IBlockState filler = isExceptionBiome(biome) ? Blocks.DIRT.getDefaultState() : biome.fillerBlock; -+ -+ if (state.getBlock() == Blocks.STONE || state.getBlock() == top.getBlock() || state.getBlock() == filler.getBlock()) -+ { -+ if (y - 1 < 10) -+ { -+ data.setBlockState(x, y, z, FLOWING_LAVA); -+ } -+ else -+ { -+ data.setBlockState(x, y, z, AIR); -+ -+ if (foundTop && data.getBlockState(x, y - 1, z).getBlock() == filler.getBlock()) -+ { -+ data.setBlockState(x, y - 1, z, top.getBlock().getDefaultState()); -+ } - } - } - } diff --git a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenAbstractTree.java.patch b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenAbstractTree.java.patch deleted file mode 100644 index f18b025a1..000000000 --- a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenAbstractTree.java.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- before/net/minecraft/world/gen/feature/WorldGenAbstractTree.java -+++ after/net/minecraft/world/gen/feature/WorldGenAbstractTree.java -@@ -38,4 +38,10 @@ - this.setBlockAndNotifyAdequately(worldIn, pos, Blocks.DIRT.getDefaultState()); - } - } -+ -+ public boolean isReplaceable(World world, BlockPos pos) -+ { -+ net.minecraft.block.state.IBlockState state = world.getBlockState(pos); -+ return state.getBlock().isAir(state, world, pos) || state.getBlock().isLeaves(state, world, pos) || state.getBlock().isWood(world, pos) || canGrowInto(state.getBlock()); -+ } - } diff --git a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenBigMushroom.java.patch b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenBigMushroom.java.patch deleted file mode 100644 index 4b69b2115..000000000 --- a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenBigMushroom.java.patch +++ /dev/null @@ -1,34 +0,0 @@ ---- before/net/minecraft/world/gen/feature/WorldGenBigMushroom.java -+++ after/net/minecraft/world/gen/feature/WorldGenBigMushroom.java -@@ -63,9 +63,9 @@ - { - if (j >= 0 && j < 256) - { -- Material material = worldIn.getBlockState(blockpos$mutableblockpos.setPos(l, j, i1)).getMaterial(); -+ IBlockState state = worldIn.getBlockState(blockpos$mutableblockpos.setPos(l, j, i1)); - -- if (material != Material.AIR && material != Material.LEAVES) -+ if (!state.getBlock().isAir(state, worldIn, blockpos$mutableblockpos) && !state.getBlock().isLeaves(state, worldIn, blockpos$mutableblockpos)) - { - flag = false; - } -@@ -201,8 +201,9 @@ - || blockhugemushroom$enumtype != BlockHugeMushroom.EnumType.ALL_INSIDE) - { - BlockPos blockpos = new BlockPos(l1, l2, i2); -+ IBlockState state = worldIn.getBlockState(blockpos); - -- if (!worldIn.getBlockState(blockpos).isFullBlock()) -+ if (state.getBlock().canBeReplacedByLeaves(state, worldIn, blockpos)) - { - this.setBlockAndNotifyAdequately( - worldIn, blockpos, block.getDefaultState().withProperty(BlockHugeMushroom.VARIANT, blockhugemushroom$enumtype) -@@ -217,7 +218,7 @@ - { - IBlockState iblockstate = worldIn.getBlockState(position.up(i3)); - -- if (!iblockstate.isFullBlock()) -+ if (iblockstate.getBlock().canBeReplacedByLeaves(iblockstate, worldIn, position.up(i3))) - { - this.setBlockAndNotifyAdequately( - worldIn, diff --git a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenBigTree.java.patch b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenBigTree.java.patch deleted file mode 100644 index 5693fc6b6..000000000 --- a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenBigTree.java.patch +++ /dev/null @@ -1,52 +0,0 @@ ---- before/net/minecraft/world/gen/feature/WorldGenBigTree.java -+++ after/net/minecraft/world/gen/feature/WorldGenBigTree.java -@@ -99,9 +99,9 @@ - if (Math.pow(Math.abs(j) + 0.5, 2.0) + Math.pow(Math.abs(k) + 0.5, 2.0) <= p_181631_2_ * p_181631_2_) - { - BlockPos blockpos = pos.add(j, 0, k); -- Material material = this.world.getBlockState(blockpos).getMaterial(); -+ IBlockState state = this.world.getBlockState(blockpos); - -- if (material == Material.AIR || material == Material.LEAVES) -+ if (state.getBlock().isAir(state, world, blockpos) || state.getBlock().isLeaves(state, world, blockpos)) - { - this.setBlockAndNotifyAdequately(this.world, blockpos, p_181631_3_); - } -@@ -271,7 +271,7 @@ - { - BlockPos blockpos1 = posOne.add(0.5F + j * f, 0.5F + j * f1, 0.5F + j * f2); - -- if (!this.canGrowInto(this.world.getBlockState(blockpos1).getBlock())) -+ if (!this.isReplaceable(world, blockpos1)) - { - return j; - } -@@ -301,6 +301,7 @@ - - if (!this.validTreeLocation()) - { -+ this.world = null; //Fix vanilla Mem leak, holds latest world - return false; - } - else -@@ -309,15 +310,18 @@ - this.generateLeaves(); - this.generateTrunk(); - this.generateLeafNodeBases(); -+ this.world = null; //Fix vanilla Mem leak, holds latest world - return true; - } - } - - private boolean validTreeLocation() - { -- Block block = this.world.getBlockState(this.basePos.down()).getBlock(); -+ BlockPos down = this.basePos.down(); -+ net.minecraft.block.state.IBlockState state = this.world.getBlockState(down); -+ boolean isSoil = state.getBlock().canSustainPlant(state, this.world, down, net.minecraft.util.EnumFacing.UP, ((net.minecraft.block.BlockSapling)Blocks.SAPLING)); - -- if (block != Blocks.DIRT && block != Blocks.GRASS && block != Blocks.FARMLAND) -+ if (!isSoil) - { - return false; - } diff --git a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenBirchTree.java.patch b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenBirchTree.java.patch deleted file mode 100644 index 1fd3dc441..000000000 --- a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenBirchTree.java.patch +++ /dev/null @@ -1,59 +0,0 @@ ---- before/net/minecraft/world/gen/feature/WorldGenBirchTree.java -+++ after/net/minecraft/world/gen/feature/WorldGenBirchTree.java -@@ -62,11 +62,11 @@ - { - for (int i1 = position.getZ() - k; i1 <= position.getZ() + k && flag; i1++) - { -- if (j < 0 || j >= 256) -+ if (j < 0 || j >= worldIn.getHeight()) - { - flag = false; - } -- else if (!this.canGrowInto(worldIn.getBlockState(blockpos$mutableblockpos.setPos(l, j, i1)).getBlock())) -+ else if (!this.isReplaceable(worldIn, blockpos$mutableblockpos.setPos(l, j, i1))) - { - flag = false; - } -@@ -80,12 +80,13 @@ - } - else - { -- Block block = worldIn.getBlockState(position.down()).getBlock(); -+ BlockPos down = position.down(); -+ IBlockState state = worldIn.getBlockState(down); -+ boolean isSoil = state.getBlock().canSustainPlant(state, worldIn, down, net.minecraft.util.EnumFacing.UP, (net.minecraft.block.BlockSapling)Blocks.SAPLING); - -- if ((block == Blocks.GRASS || block == Blocks.DIRT || block == Blocks.FARMLAND) -- && position.getY() < 256 - i - 1) -+ if (isSoil && position.getY() < worldIn.getHeight() - i - 1) - { -- this.setDirtAt(worldIn, position.down()); -+ state.getBlock().onPlantGrow(state, worldIn, down, position); - - for (int i2 = position.getY() - 3 + i; i2 <= position.getY() + i; i2++) - { -@@ -103,9 +104,9 @@ - if (Math.abs(j1) != l2 || Math.abs(l1) != l2 || rand.nextInt(2) != 0 && k2 != 0) - { - BlockPos blockpos = new BlockPos(i3, i2, k1); -- Material material = worldIn.getBlockState(blockpos).getMaterial(); -+ IBlockState state2 = worldIn.getBlockState(blockpos); - -- if (material == Material.AIR || material == Material.LEAVES) -+ if (state2.getBlock().isAir(state2, worldIn, blockpos) || state2.getBlock().isAir(state2, worldIn, blockpos)) - { - this.setBlockAndNotifyAdequately(worldIn, blockpos, LEAF); - } -@@ -116,9 +117,10 @@ - - for (int j2 = 0; j2 < i; j2++) - { -- Material material1 = worldIn.getBlockState(position.up(j2)).getMaterial(); -+ BlockPos upN = position.up(j2); -+ IBlockState state2 = worldIn.getBlockState(upN); - -- if (material1 == Material.AIR || material1 == Material.LEAVES) -+ if (state2.getBlock().isAir(state2, worldIn, upN) || state2.getBlock().isLeaves(state2, worldIn, upN)) - { - this.setBlockAndNotifyAdequately(worldIn, position.up(j2), LOG); - } diff --git a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenBush.java.patch b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenBush.java.patch deleted file mode 100644 index 88a370849..000000000 --- a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenBush.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/world/gen/feature/WorldGenBush.java -+++ after/net/minecraft/world/gen/feature/WorldGenBush.java -@@ -24,7 +24,7 @@ - ); - - if (worldIn.isAirBlock(blockpos) -- && (!worldIn.provider.isNether() || blockpos.getY() < 255) -+ && (!worldIn.provider.isNether() || blockpos.getY() < worldIn.getHeight() - 1) - && this.block.canBlockStay(worldIn, blockpos, this.block.getDefaultState())) - { - worldIn.setBlockState(blockpos, this.block.getDefaultState(), 2); diff --git a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenCanopyTree.java.patch b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenCanopyTree.java.patch deleted file mode 100644 index cdbe7c23e..000000000 --- a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenCanopyTree.java.patch +++ /dev/null @@ -1,72 +0,0 @@ ---- before/net/minecraft/world/gen/feature/WorldGenCanopyTree.java -+++ after/net/minecraft/world/gen/feature/WorldGenCanopyTree.java -@@ -39,9 +39,10 @@ - if (k >= 1 && k + i + 1 < 256) - { - BlockPos blockpos = position.down(); -- Block block = worldIn.getBlockState(blockpos).getBlock(); -+ IBlockState state = worldIn.getBlockState(blockpos); -+ boolean isSoil = state.getBlock().canSustainPlant(state, worldIn, blockpos, net.minecraft.util.EnumFacing.UP, ((net.minecraft.block.BlockSapling)Blocks.SAPLING)); - -- if (block != Blocks.GRASS && block != Blocks.DIRT) -+ if (!(isSoil && position.getY() < worldIn.getHeight() - i - 1)) - { - return false; - } -@@ -51,10 +52,10 @@ - } - else - { -- this.setDirtAt(worldIn, blockpos); -- this.setDirtAt(worldIn, blockpos.east()); -- this.setDirtAt(worldIn, blockpos.south()); -- this.setDirtAt(worldIn, blockpos.south().east()); -+ this.onPlantGrow(worldIn, blockpos, position); -+ this.onPlantGrow(worldIn, blockpos.east(), position); -+ this.onPlantGrow(worldIn, blockpos.south(), position); -+ this.onPlantGrow(worldIn, blockpos.south().east(), position); - EnumFacing enumfacing = EnumFacing.Plane.HORIZONTAL.random(rand); - int i1 = i - rand.nextInt(4); - int j1 = 2 - rand.nextInt(3); -@@ -73,9 +74,9 @@ - - int k2 = k + j2; - BlockPos blockpos1 = new BlockPos(k1, k2, l1); -- Material material = worldIn.getBlockState(blockpos1).getMaterial(); -+ state = worldIn.getBlockState(blockpos1); - -- if (material == Material.AIR || material == Material.LEAVES) -+ if (state.getBlock().isAir(state, worldIn, blockpos1) || state.getBlock().isLeaves(state, worldIn, blockpos1)) - { - this.placeLogAt(worldIn, blockpos1); - this.placeLogAt(worldIn, blockpos1.east()); -@@ -197,7 +198,7 @@ - { - for (int k1 = -i1; k1 <= i1; k1++) - { -- if (!this.canGrowInto(worldIn.getBlockState(blockpos$mutableblockpos.setPos(i + j1, j + l, k + k1)).getBlock())) -+ if (!this.isReplaceable(worldIn, blockpos$mutableblockpos.setPos(i + j1, j + l, k + k1))) - { - return false; - } -@@ -219,11 +220,18 @@ - private void placeLeafAt(World worldIn, int x, int y, int z) - { - BlockPos blockpos = new BlockPos(x, y, z); -- Material material = worldIn.getBlockState(blockpos).getMaterial(); -+ IBlockState state = worldIn.getBlockState(blockpos); - -- if (material == Material.AIR) -+ if (state.getBlock().isAir(state, worldIn, blockpos)) - { - this.setBlockAndNotifyAdequately(worldIn, blockpos, DARK_OAK_LEAVES); - } -+ } -+ -+ //Just a helper macro -+ private void onPlantGrow(World world, BlockPos pos, BlockPos source) -+ { -+ IBlockState state = world.getBlockState(pos); -+ state.getBlock().onPlantGrow(state, world, pos, source); - } - } diff --git a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenDeadBush.java.patch b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenDeadBush.java.patch deleted file mode 100644 index d741b8d76..000000000 --- a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenDeadBush.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/world/gen/feature/WorldGenDeadBush.java -+++ after/net/minecraft/world/gen/feature/WorldGenDeadBush.java -@@ -13,7 +13,7 @@ - public boolean generate(World worldIn, Random rand, BlockPos position) - { - for (IBlockState iblockstate = worldIn.getBlockState(position); -- (iblockstate.getMaterial() == Material.AIR || iblockstate.getMaterial() == Material.LEAVES) && position.getY() > 0; -+ (iblockstate.getBlock().isAir(iblockstate, worldIn, position) || iblockstate.getBlock().isLeaves(iblockstate, worldIn, position)) && position.getY() > 0; - iblockstate = worldIn.getBlockState(position) - ) - { diff --git a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenDungeons.java.patch b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenDungeons.java.patch deleted file mode 100644 index 79eb7c976..000000000 --- a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenDungeons.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- before/net/minecraft/world/gen/feature/WorldGenDungeons.java -+++ after/net/minecraft/world/gen/feature/WorldGenDungeons.java -@@ -174,6 +174,6 @@ - - private ResourceLocation pickMobSpawner(Random rand) - { -- return SPAWNERTYPES[rand.nextInt(SPAWNERTYPES.length)]; -+ return net.minecraftforge.common.DungeonHooks.getRandomDungeonMob(rand); - } - } diff --git a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenGlowStone1.java.patch b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenGlowStone1.java.patch deleted file mode 100644 index 455f9591e..000000000 --- a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenGlowStone1.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/world/gen/feature/WorldGenGlowStone1.java -+++ after/net/minecraft/world/gen/feature/WorldGenGlowStone1.java -@@ -30,7 +30,7 @@ - rand.nextInt(8) - rand.nextInt(8), -rand.nextInt(12), rand.nextInt(8) - rand.nextInt(8) - ); - -- if (worldIn.getBlockState(blockpos).getMaterial() == Material.AIR) -+ if (worldIn.isAirBlock(blockpos)) - { - int j = 0; - diff --git a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenGlowStone2.java.patch b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenGlowStone2.java.patch deleted file mode 100644 index 66c6cdca4..000000000 --- a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenGlowStone2.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/world/gen/feature/WorldGenGlowStone2.java -+++ after/net/minecraft/world/gen/feature/WorldGenGlowStone2.java -@@ -30,7 +30,7 @@ - rand.nextInt(8) - rand.nextInt(8), -rand.nextInt(12), rand.nextInt(8) - rand.nextInt(8) - ); - -- if (worldIn.getBlockState(blockpos).getMaterial() == Material.AIR) -+ if (worldIn.isAirBlock(blockpos)) - { - int j = 0; - diff --git a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenHellLava.java.patch b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenHellLava.java.patch deleted file mode 100644 index 796c08895..000000000 --- a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenHellLava.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/world/gen/feature/WorldGenHellLava.java -+++ after/net/minecraft/world/gen/feature/WorldGenHellLava.java -@@ -26,7 +26,7 @@ - { - return false; - } -- else if (worldIn.getBlockState(position).getMaterial() != Material.AIR -+ else if (!worldIn.isAirBlock(position) - && worldIn.getBlockState(position).getBlock() != Blocks.NETHERRACK) - { - return false; diff --git a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenHugeTrees.java.patch b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenHugeTrees.java.patch deleted file mode 100644 index 9f65dbee8..000000000 --- a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenHugeTrees.java.patch +++ /dev/null @@ -1,69 +0,0 @@ ---- before/net/minecraft/world/gen/feature/WorldGenHugeTrees.java -+++ after/net/minecraft/world/gen/feature/WorldGenHugeTrees.java -@@ -61,7 +61,7 @@ - { - if (leavesPos.getY() + i < 0 - || leavesPos.getY() + i >= 256 -- || !this.canGrowInto(worldIn.getBlockState(leavesPos.add(k, i, l)).getBlock())) -+ || !this.isReplaceable(worldIn,leavesPos.add(k, i, l))) - { - flag = false; - } -@@ -80,14 +80,15 @@ - private boolean ensureDirtsUnderneath(BlockPos pos, World worldIn) - { - BlockPos blockpos = pos.down(); -- Block block = worldIn.getBlockState(blockpos).getBlock(); -+ IBlockState state = worldIn.getBlockState(blockpos); -+ boolean isSoil = state.getBlock().canSustainPlant(state, worldIn, blockpos, net.minecraft.util.EnumFacing.UP, ((net.minecraft.block.BlockSapling)Blocks.SAPLING)); - -- if ((block == Blocks.GRASS || block == Blocks.DIRT) && pos.getY() >= 2) -+ if (isSoil && pos.getY() >= 2) - { -- this.setDirtAt(worldIn, blockpos); -- this.setDirtAt(worldIn, blockpos.east()); -- this.setDirtAt(worldIn, blockpos.south()); -- this.setDirtAt(worldIn, blockpos.south().east()); -+ this.onPlantGrow(worldIn, blockpos, pos); -+ this.onPlantGrow(worldIn, blockpos.east(), pos); -+ this.onPlantGrow(worldIn, blockpos.south(), pos); -+ this.onPlantGrow(worldIn, blockpos.south().east(), pos); - return true; - } - else -@@ -115,9 +116,9 @@ - if (j * j + k * k <= i || l * l + i1 * i1 <= i || j * j + i1 * i1 <= i || l * l + k * k <= i) - { - BlockPos blockpos = layerCenter.add(j, 0, k); -- Material material = worldIn.getBlockState(blockpos).getMaterial(); -+ IBlockState state = worldIn.getBlockState(blockpos); - -- if (material == Material.AIR || material == Material.LEAVES) -+ if (state.getBlock().isAir(state, worldIn, blockpos) || state.getBlock().isLeaves(state, worldIn, blockpos)) - { - this.setBlockAndNotifyAdequately(worldIn, blockpos, this.leavesMetadata); - } -@@ -137,14 +138,21 @@ - if (j * j + k * k <= i) - { - BlockPos blockpos = layerCenter.add(j, 0, k); -- Material material = worldIn.getBlockState(blockpos).getMaterial(); -+ IBlockState state = worldIn.getBlockState(blockpos); - -- if (material == Material.AIR || material == Material.LEAVES) -+ if (state.getBlock().isAir(state, worldIn, blockpos) || state.getBlock().isLeaves(state, worldIn, blockpos)) - { - this.setBlockAndNotifyAdequately(worldIn, blockpos, this.leavesMetadata); - } - } - } - } -+ } -+ -+ //Just a helper macro -+ private void onPlantGrow(World world, BlockPos pos, BlockPos source) -+ { -+ IBlockState state = world.getBlockState(pos); -+ state.getBlock().onPlantGrow(state, world, pos, source); - } - } diff --git a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenIceSpike.java.patch b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenIceSpike.java.patch deleted file mode 100644 index 720f6a5fd..000000000 --- a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenIceSpike.java.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- before/net/minecraft/world/gen/feature/WorldGenIceSpike.java -+++ after/net/minecraft/world/gen/feature/WorldGenIceSpike.java -@@ -53,7 +53,7 @@ - IBlockState iblockstate = worldIn.getBlockState(position.add(i1, k, j1)); - Block block = iblockstate.getBlock(); - -- if (iblockstate.getMaterial() == Material.AIR -+ if (iblockstate.getBlock().isAir(iblockstate, worldIn, position.add(i1, k, j1)) - || block == Blocks.DIRT - || block == Blocks.SNOW - || block == Blocks.ICE) -@@ -66,7 +66,7 @@ - iblockstate = worldIn.getBlockState(position.add(i1, -k, j1)); - block = iblockstate.getBlock(); - -- if (iblockstate.getMaterial() == Material.AIR -+ if (iblockstate.getBlock().isAir(iblockstate, worldIn, position.add(i1, -k, j1)) - || block == Blocks.DIRT - || block == Blocks.SNOW - || block == Blocks.ICE) -@@ -107,7 +107,7 @@ - IBlockState iblockstate1 = worldIn.getBlockState(blockpos); - Block block1 = iblockstate1.getBlock(); - -- if (iblockstate1.getMaterial() != Material.AIR -+ if (!iblockstate1.getBlock().isAir(iblockstate1, worldIn, blockpos) - && block1 != Blocks.DIRT - && block1 != Blocks.SNOW - && block1 != Blocks.ICE diff --git a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenLakes.java.patch b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenLakes.java.patch deleted file mode 100644 index 16655c80e..000000000 --- a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenLakes.java.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- before/net/minecraft/world/gen/feature/WorldGenLakes.java -+++ after/net/minecraft/world/gen/feature/WorldGenLakes.java -@@ -187,7 +187,8 @@ - - if (worldIn.canBlockFreezeWater(position.add(k2, 4, l3))) - { -- worldIn.setBlockState(position.add(k2, 4, l3), Blocks.ICE.getDefaultState(), 2); -+ int flag = net.minecraftforge.common.ForgeModContainer.fixVanillaCascading ? 2| 16 : 2; //Forge: With bit 5 unset, it will notify neighbors and load adjacent chunks. -+ worldIn.setBlockState(position.add(k2, 4, l3), Blocks.ICE.getDefaultState(), flag); //Forge - } - } - } diff --git a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenLiquids.java.patch b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenLiquids.java.patch deleted file mode 100644 index 742813604..000000000 --- a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenLiquids.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/world/gen/feature/WorldGenLiquids.java -+++ after/net/minecraft/world/gen/feature/WorldGenLiquids.java -@@ -32,7 +32,7 @@ - { - IBlockState iblockstate = worldIn.getBlockState(position); - -- if (iblockstate.getMaterial() != Material.AIR && iblockstate.getBlock() != Blocks.STONE) -+ if (!iblockstate.getBlock().isAir(iblockstate, worldIn, position) && iblockstate.getBlock() != Blocks.STONE) - { - return false; - } diff --git a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenMegaJungle.java.patch b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenMegaJungle.java.patch deleted file mode 100644 index fed62e9b0..000000000 --- a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenMegaJungle.java.patch +++ /dev/null @@ -1,51 +0,0 @@ ---- before/net/minecraft/world/gen/feature/WorldGenMegaJungle.java -+++ after/net/minecraft/world/gen/feature/WorldGenMegaJungle.java -@@ -56,7 +56,7 @@ - { - BlockPos blockpos = position.up(i2); - -- if (this.canGrowInto(worldIn.getBlockState(blockpos).getBlock())) -+ if (this.isAirLeaves(worldIn,blockpos)) - { - this.setBlockAndNotifyAdequately(worldIn, blockpos, this.woodMetadata); - -@@ -71,7 +71,7 @@ - { - BlockPos blockpos1 = blockpos.east(); - -- if (this.canGrowInto(worldIn.getBlockState(blockpos1).getBlock())) -+ if (this.isAirLeaves(worldIn,blockpos1)) - { - this.setBlockAndNotifyAdequately(worldIn, blockpos1, this.woodMetadata); - -@@ -84,7 +84,7 @@ - - BlockPos blockpos2 = blockpos.south().east(); - -- if (this.canGrowInto(worldIn.getBlockState(blockpos2).getBlock())) -+ if (this.isAirLeaves(worldIn,blockpos2)) - { - this.setBlockAndNotifyAdequately(worldIn, blockpos2, this.woodMetadata); - -@@ -97,7 +97,7 @@ - - BlockPos blockpos3 = blockpos.south(); - -- if (this.canGrowInto(worldIn.getBlockState(blockpos3).getBlock())) -+ if (this.isAirLeaves(worldIn,blockpos3)) - { - this.setBlockAndNotifyAdequately(worldIn, blockpos3, this.woodMetadata); - -@@ -130,5 +130,12 @@ - { - this.growLeavesLayerStrict(worldIn, p_175930_2_.up(j), p_175930_3_ + 1 - j); - } -+ } -+ -+ //Helper macro -+ private boolean isAirLeaves(World world, BlockPos pos) -+ { -+ IBlockState state = world.getBlockState(pos); -+ return state.getBlock().isAir(state, world, pos) || state.getBlock().isLeaves(state, world, pos); - } - } diff --git a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenMegaPineTree.java.patch b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenMegaPineTree.java.patch deleted file mode 100644 index a7a206d2e..000000000 --- a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenMegaPineTree.java.patch +++ /dev/null @@ -1,61 +0,0 @@ ---- before/net/minecraft/world/gen/feature/WorldGenMegaPineTree.java -+++ after/net/minecraft/world/gen/feature/WorldGenMegaPineTree.java -@@ -47,32 +47,25 @@ - - for (int j = 0; j < i; j++) - { -- IBlockState iblockstate = worldIn.getBlockState(position.up(j)); -- -- if (iblockstate.getMaterial() == Material.AIR || iblockstate.getMaterial() == Material.LEAVES) -+ if (isAirLeaves(worldIn, position.up(j))) - { - this.setBlockAndNotifyAdequately(worldIn, position.up(j), this.woodMetadata); - } - - if (j < i - 1) - { -- iblockstate = worldIn.getBlockState(position.add(1, j, 0)); -- -- if (iblockstate.getMaterial() == Material.AIR || iblockstate.getMaterial() == Material.LEAVES) -+ if (isAirLeaves(worldIn, position.add(1, j, 0))) - { - this.setBlockAndNotifyAdequately(worldIn, position.add(1, j, 0), this.woodMetadata); - } - -- iblockstate = worldIn.getBlockState(position.add(1, j, 1)); -- -- if (iblockstate.getMaterial() == Material.AIR || iblockstate.getMaterial() == Material.LEAVES) -+ if (isAirLeaves(worldIn, position.add(1, j, 1))) - { - this.setBlockAndNotifyAdequately(worldIn, position.add(1, j, 1), this.woodMetadata); - } - -- iblockstate = worldIn.getBlockState(position.add(0, j, 1)); - -- if (iblockstate.getMaterial() == Material.AIR || iblockstate.getMaterial() == Material.LEAVES) -+ if (isAirLeaves(worldIn, position.add(0, j, 1))) - { - this.setBlockAndNotifyAdequately(worldIn, position.add(0, j, 1), this.woodMetadata); - } -@@ -140,7 +133,7 @@ - IBlockState iblockstate = worldIn.getBlockState(blockpos); - Block block = iblockstate.getBlock(); - -- if (block == Blocks.GRASS || block == Blocks.DIRT) -+ if (block.canSustainPlant(iblockstate, worldIn, blockpos, net.minecraft.util.EnumFacing.UP, ((net.minecraft.block.BlockSapling)Blocks.SAPLING))) - { - this.setBlockAndNotifyAdequately(worldIn, blockpos, PODZOL); - break; -@@ -151,5 +144,12 @@ - break; - } - } -+ } -+ -+ //Helper macro -+ private boolean isAirLeaves(World world, BlockPos pos) -+ { -+ IBlockState state = world.getBlockState(pos); -+ return state.getBlock().isAir(state, world, pos) || state.getBlock().isLeaves(state, world, pos); - } - } diff --git a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenMinable.java.patch b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenMinable.java.patch deleted file mode 100644 index edde54343..000000000 --- a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenMinable.java.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- before/net/minecraft/world/gen/feature/WorldGenMinable.java -+++ after/net/minecraft/world/gen/feature/WorldGenMinable.java -@@ -74,7 +74,8 @@ - { - BlockPos blockpos = new BlockPos(l1, i2, j2); - -- if (this.predicate.apply(worldIn.getBlockState(blockpos))) -+ IBlockState state = worldIn.getBlockState(blockpos); -+ if (state.getBlock().isReplaceableOreGen(state, worldIn, blockpos, this.predicate)) - { - worldIn.setBlockState(blockpos, this.oreBlock, 2); - } diff --git a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenSavannaTree.java.patch b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenSavannaTree.java.patch deleted file mode 100644 index 3df4910b0..000000000 --- a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenSavannaTree.java.patch +++ /dev/null @@ -1,64 +0,0 @@ ---- before/net/minecraft/world/gen/feature/WorldGenSavannaTree.java -+++ after/net/minecraft/world/gen/feature/WorldGenSavannaTree.java -@@ -60,7 +60,7 @@ - { - flag = false; - } -- else if (!this.canGrowInto(worldIn.getBlockState(blockpos$mutableblockpos.setPos(l, j, i1)).getBlock())) -+ else if (!this.isReplaceable(worldIn,blockpos$mutableblockpos.setPos(l, j, i1))) - { - flag = false; - } -@@ -74,11 +74,13 @@ - } - else - { -- Block block = worldIn.getBlockState(position.down()).getBlock(); -+ BlockPos down = position.down(); -+ IBlockState state = worldIn.getBlockState(down); -+ boolean isSoil = state.getBlock().canSustainPlant(state, worldIn, down, net.minecraft.util.EnumFacing.UP, ((net.minecraft.block.BlockSapling)Blocks.SAPLING)); - -- if ((block == Blocks.GRASS || block == Blocks.DIRT) && position.getY() < 256 - i - 1) -+ if (isSoil && position.getY() < worldIn.getHeight() - i - 1) - { -- this.setDirtAt(worldIn, position.down()); -+ state.getBlock().onPlantGrow(state, worldIn, down, position); - EnumFacing enumfacing = EnumFacing.Plane.HORIZONTAL.random(rand); - int k2 = i - rand.nextInt(4) - 1; - int l2 = 3 - rand.nextInt(3); -@@ -98,9 +100,9 @@ - } - - BlockPos blockpos = new BlockPos(i3, i2, j1); -- Material material = worldIn.getBlockState(blockpos).getMaterial(); -+ state = worldIn.getBlockState(blockpos); - -- if (material == Material.AIR || material == Material.LEAVES) -+ if (state.getBlock().isAir(state, worldIn, blockpos) || state.getBlock().isLeaves(state, worldIn, blockpos)) - { - this.placeLogAt(worldIn, blockpos); - k1 = i2; -@@ -152,9 +154,9 @@ - i3 += enumfacing1.getXOffset(); - j1 += enumfacing1.getZOffset(); - BlockPos blockpos1 = new BlockPos(i3, j2, j1); -- Material material1 = worldIn.getBlockState(blockpos1).getMaterial(); -+ state = worldIn.getBlockState(blockpos1); - -- if (material1 == Material.AIR || material1 == Material.LEAVES) -+ if (state.getBlock().isAir(state, worldIn, blockpos1) || state.getBlock().isLeaves(state, worldIn, blockpos1)) - { - this.placeLogAt(worldIn, blockpos1); - k1 = j2; -@@ -212,9 +214,9 @@ - - private void placeLeafAt(World worldIn, BlockPos pos) - { -- Material material = worldIn.getBlockState(pos).getMaterial(); -+ IBlockState state = worldIn.getBlockState(pos); - -- if (material == Material.AIR || material == Material.LEAVES) -+ if (state.getBlock().isAir(state, worldIn, pos) || state.getBlock().isLeaves(state, worldIn, pos)) - { - this.setBlockAndNotifyAdequately(worldIn, pos, LEAF); - } diff --git a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenShrub.java.patch b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenShrub.java.patch deleted file mode 100644 index 44edfb788..000000000 --- a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenShrub.java.patch +++ /dev/null @@ -1,34 +0,0 @@ ---- before/net/minecraft/world/gen/feature/WorldGenShrub.java -+++ after/net/minecraft/world/gen/feature/WorldGenShrub.java -@@ -24,16 +24,16 @@ - public boolean generate(World worldIn, Random rand, BlockPos position) - { - for (IBlockState iblockstate = worldIn.getBlockState(position); -- (iblockstate.getMaterial() == Material.AIR || iblockstate.getMaterial() == Material.LEAVES) && position.getY() > 0; -+ (iblockstate.getBlock().isAir(iblockstate, worldIn, position) || iblockstate.getBlock().isLeaves(iblockstate, worldIn, position)) && position.getY() > 0; - iblockstate = worldIn.getBlockState(position) - ) - { - position = position.down(); - } - -- Block block = worldIn.getBlockState(position).getBlock(); -+ IBlockState state = worldIn.getBlockState(position); - -- if (block == Blocks.DIRT || block == Blocks.GRASS) -+ if (state.getBlock().canSustainPlant(state, worldIn, position, net.minecraft.util.EnumFacing.UP, ((net.minecraft.block.BlockSapling)Blocks.SAPLING))) - { - position = position.up(); - this.setBlockAndNotifyAdequately(worldIn, position, this.woodMetadata); -@@ -54,9 +54,9 @@ - if (Math.abs(i1) != k || Math.abs(k1) != k || rand.nextInt(2) != 0) - { - BlockPos blockpos = new BlockPos(l, i, j1); -- Material material = worldIn.getBlockState(blockpos).getMaterial(); -+ state = worldIn.getBlockState(blockpos); - -- if (material == Material.AIR || material == Material.LEAVES) -+ if (state.getBlock().canBeReplacedByLeaves(state, worldIn, blockpos)) - { - this.setBlockAndNotifyAdequately(worldIn, blockpos, this.leavesMetadata); - } diff --git a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenSwamp.java.patch b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenSwamp.java.patch deleted file mode 100644 index 0fedc01ed..000000000 --- a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenSwamp.java.patch +++ /dev/null @@ -1,96 +0,0 @@ ---- before/net/minecraft/world/gen/feature/WorldGenSwamp.java -+++ after/net/minecraft/world/gen/feature/WorldGenSwamp.java -@@ -65,7 +65,7 @@ - IBlockState iblockstate = worldIn.getBlockState(blockpos$mutableblockpos.setPos(l, j, i1)); - Block block = iblockstate.getBlock(); - -- if (iblockstate.getMaterial() != Material.AIR && iblockstate.getMaterial() != Material.LEAVES) -+ if (!iblockstate.getBlock().isAir(iblockstate, worldIn, blockpos$mutableblockpos.setPos(l, j, i1)) && !iblockstate.getBlock().isLeaves(iblockstate, worldIn, blockpos$mutableblockpos.setPos(l, j, i1))) - { - if (block != Blocks.WATER && block != Blocks.FLOWING_WATER) - { -@@ -91,11 +91,13 @@ - } - else - { -- Block block1 = worldIn.getBlockState(position.down()).getBlock(); -+ BlockPos down = position.down(); -+ IBlockState state = worldIn.getBlockState(down); -+ boolean isSoil = state.getBlock().canSustainPlant(state, worldIn, down, net.minecraft.util.EnumFacing.UP, ((net.minecraft.block.BlockSapling)Blocks.SAPLING)); - -- if ((block1 == Blocks.GRASS || block1 == Blocks.DIRT) && position.getY() < 256 - i - 1) -+ if (isSoil && position.getY() < worldIn.getHeight() - i - 1) - { -- this.setDirtAt(worldIn, position.down()); -+ state.getBlock().onPlantGrow(state, worldIn, position.down(),position); - - for (int k1 = position.getY() - 3 + i; k1 <= position.getY() + i; k1++) - { -@@ -113,8 +115,9 @@ - if (Math.abs(k3) != l2 || Math.abs(j1) != l2 || rand.nextInt(2) != 0 && j2 != 0) - { - BlockPos blockpos = new BlockPos(j3, k1, i4); -+ state = worldIn.getBlockState(blockpos); - -- if (!worldIn.getBlockState(blockpos).isFullBlock()) -+ if (state.getBlock().canBeReplacedByLeaves(state, worldIn, blockpos)) - { - this.setBlockAndNotifyAdequately(worldIn, blockpos, LEAF); - } -@@ -125,11 +128,12 @@ - - for (int l1 = 0; l1 < i; l1++) - { -- IBlockState iblockstate1 = worldIn.getBlockState(position.up(l1)); -+ BlockPos upN = position.up(l1); -+ IBlockState iblockstate1 = worldIn.getBlockState(upN); - Block block2 = iblockstate1.getBlock(); - -- if (iblockstate1.getMaterial() == Material.AIR -- || iblockstate1.getMaterial() == Material.LEAVES -+ if (block2.isAir(iblockstate1, worldIn, upN) -+ || block2.isLeaves(iblockstate1, worldIn, upN) - || block2 == Blocks.FLOWING_WATER - || block2 == Blocks.WATER) - { -@@ -156,22 +160,22 @@ - BlockPos blockpos1 = blockpos$mutableblockpos1.north(); - BlockPos blockpos2 = blockpos$mutableblockpos1.south(); - -- if (rand.nextInt(4) == 0 && worldIn.getBlockState(blockpos3).getMaterial() == Material.AIR) -+ if (rand.nextInt(4) == 0 && worldIn.isAirBlock(blockpos3)) - { - this.addVine(worldIn, blockpos3, BlockVine.EAST); - } - -- if (rand.nextInt(4) == 0 && worldIn.getBlockState(blockpos4).getMaterial() == Material.AIR) -+ if (rand.nextInt(4) == 0 && worldIn.isAirBlock(blockpos4)) - { - this.addVine(worldIn, blockpos4, BlockVine.WEST); - } - -- if (rand.nextInt(4) == 0 && worldIn.getBlockState(blockpos1).getMaterial() == Material.AIR) -+ if (rand.nextInt(4) == 0 && worldIn.isAirBlock(blockpos1)) - { - this.addVine(worldIn, blockpos1, BlockVine.SOUTH); - } - -- if (rand.nextInt(4) == 0 && worldIn.getBlockState(blockpos2).getMaterial() == Material.AIR) -+ if (rand.nextInt(4) == 0 && worldIn.isAirBlock(blockpos2)) - { - this.addVine(worldIn, blockpos2, BlockVine.NORTH); - } -@@ -196,11 +200,11 @@ - - private void addVine(World worldIn, BlockPos pos, PropertyBool prop) - { -- IBlockState iblockstate = Blocks.VINE.getDefaultState().withProperty(prop, true); -+ IBlockState iblockstate = Blocks.VINE.getDefaultState().withProperty(prop, Boolean.valueOf(true)); - this.setBlockAndNotifyAdequately(worldIn, pos, iblockstate); - int i = 4; - -- for (BlockPos blockpos = pos.down(); worldIn.getBlockState(blockpos).getMaterial() == Material.AIR && i > 0; i--) -+ for (BlockPos blockpos = pos.down(); worldIn.isAirBlock(blockpos) && i > 0; --i) - { - this.setBlockAndNotifyAdequately(worldIn, blockpos, iblockstate); - blockpos = blockpos.down(); diff --git a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenTaiga1.java.patch b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenTaiga1.java.patch deleted file mode 100644 index 76dd3016a..000000000 --- a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenTaiga1.java.patch +++ /dev/null @@ -1,52 +0,0 @@ ---- before/net/minecraft/world/gen/feature/WorldGenTaiga1.java -+++ after/net/minecraft/world/gen/feature/WorldGenTaiga1.java -@@ -62,7 +62,7 @@ - { - flag = false; - } -- else if (!this.canGrowInto(worldIn.getBlockState(blockpos$mutableblockpos.setPos(k1, i1, l1)).getBlock())) -+ else if (!this.isReplaceable(worldIn,blockpos$mutableblockpos.setPos(k1, i1, l1))) - { - flag = false; - } -@@ -76,11 +76,13 @@ - } - else - { -- Block block = worldIn.getBlockState(position.down()).getBlock(); -+ BlockPos down = position.down(); -+ IBlockState state = worldIn.getBlockState(down); -+ boolean isSoil = state.getBlock().canSustainPlant(state, worldIn, down, net.minecraft.util.EnumFacing.UP, (net.minecraft.block.BlockSapling)Blocks.SAPLING); - -- if ((block == Blocks.GRASS || block == Blocks.DIRT) && position.getY() < 256 - i - 1) -+ if (isSoil && position.getY() < 256 - i - 1) - { -- this.setDirtAt(worldIn, position.down()); -+ state.getBlock().onPlantGrow(state, worldIn, down, position); - int k2 = 0; - - for (int l2 = position.getY() + i; l2 >= position.getY() + j; l2--) -@@ -96,8 +98,9 @@ - if (Math.abs(k3) != k2 || Math.abs(j2) != k2 || k2 <= 0) - { - BlockPos blockpos = new BlockPos(j3, l2, i2); -+ state = worldIn.getBlockState(blockpos); - -- if (!worldIn.getBlockState(blockpos).isFullBlock()) -+ if (state.getBlock().canBeReplacedByLeaves(state, worldIn, blockpos)) - { - this.setBlockAndNotifyAdequately(worldIn, blockpos, LEAF); - } -@@ -117,9 +120,10 @@ - - for (int i3 = 0; i3 < i - 1; i3++) - { -- Material material = worldIn.getBlockState(position.up(i3)).getMaterial(); -+ BlockPos upN = position.up(i3); -+ state = worldIn.getBlockState(upN); - -- if (material == Material.AIR || material == Material.LEAVES) -+ if (state.getBlock().isAir(state, worldIn, upN) || state.getBlock().isLeaves(state, worldIn, upN)) - { - this.setBlockAndNotifyAdequately(worldIn, position.up(i3), TRUNK); - } diff --git a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenTaiga2.java.patch b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenTaiga2.java.patch deleted file mode 100644 index 2a6e4e438..000000000 --- a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenTaiga2.java.patch +++ /dev/null @@ -1,68 +0,0 @@ ---- before/net/minecraft/world/gen/feature/WorldGenTaiga2.java -+++ after/net/minecraft/world/gen/feature/WorldGenTaiga2.java -@@ -36,7 +36,7 @@ - int l = 2 + rand.nextInt(2); - boolean flag = true; - -- if (position.getY() >= 1 && position.getY() + i + 1 <= 256) -+ if (position.getY() >= 1 && position.getY() + i + 1 <= worldIn.getHeight()) - { - for (int i1 = position.getY(); i1 <= position.getY() + 1 + i && flag; i1++) - { -@@ -57,11 +57,11 @@ - { - for (int l1 = position.getZ() - j1; l1 <= position.getZ() + j1 && flag; l1++) - { -- if (i1 >= 0 && i1 < 256) -+ if (i1 >= 0 && i1 < worldIn.getHeight()) - { -- Material material = worldIn.getBlockState(blockpos$mutableblockpos.setPos(k1, i1, l1)).getMaterial(); -+ IBlockState state = worldIn.getBlockState(blockpos$mutableblockpos.setPos(k1, i1, l1)); - -- if (material != Material.AIR && material != Material.LEAVES) -+ if (!state.getBlock().isAir(state, worldIn, blockpos$mutableblockpos.setPos(k1, i1, l1)) && !state.getBlock().isLeaves(state, worldIn, blockpos$mutableblockpos.setPos(k1, i1, l1))) - { - flag = false; - } -@@ -80,12 +80,13 @@ - } - else - { -- Block block = worldIn.getBlockState(position.down()).getBlock(); -+ BlockPos down = position.down(); -+ IBlockState state = worldIn.getBlockState(down); - -- if ((block == Blocks.GRASS || block == Blocks.DIRT || block == Blocks.FARMLAND) -- && position.getY() < 256 - i - 1) -+ if (state.getBlock().canSustainPlant(state, worldIn, down, net.minecraft.util.EnumFacing.UP, (net.minecraft.block.BlockSapling)Blocks.SAPLING) -+ && position.getY() < worldIn.getHeight() - i - 1) - { -- this.setDirtAt(worldIn, position.down()); -+ state.getBlock().onPlantGrow(state, worldIn, down, position); - int i3 = rand.nextInt(2); - int j3 = 1; - int k3 = 0; -@@ -105,8 +106,9 @@ - if (Math.abs(j2) != i3 || Math.abs(l2) != i3 || i3 <= 0) - { - BlockPos blockpos = new BlockPos(i2, j4, k2); -+ state = worldIn.getBlockState(blockpos); - -- if (!worldIn.getBlockState(blockpos).isFullBlock()) -+ if (state.getBlock().canBeReplacedByLeaves(state, worldIn, blockpos)) - { - this.setBlockAndNotifyAdequately(worldIn, blockpos, LEAF); - } -@@ -134,9 +136,10 @@ - - for (int k4 = 0; k4 < i - i4; k4++) - { -- Material material1 = worldIn.getBlockState(position.up(k4)).getMaterial(); -+ BlockPos upN = position.up(k4); -+ state = worldIn.getBlockState(upN); - -- if (material1 == Material.AIR || material1 == Material.LEAVES) -+ if (state.getBlock().isAir(state, worldIn, upN) || state.getBlock().isLeaves(state, worldIn, upN)) - { - this.setBlockAndNotifyAdequately(worldIn, position.up(k4), TRUNK); - } diff --git a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenTallGrass.java.patch b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenTallGrass.java.patch deleted file mode 100644 index 7fd9e8d8d..000000000 --- a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenTallGrass.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/world/gen/feature/WorldGenTallGrass.java -+++ after/net/minecraft/world/gen/feature/WorldGenTallGrass.java -@@ -21,7 +21,7 @@ - public boolean generate(World worldIn, Random rand, BlockPos position) - { - for (IBlockState iblockstate = worldIn.getBlockState(position); -- (iblockstate.getMaterial() == Material.AIR || iblockstate.getMaterial() == Material.LEAVES) && position.getY() > 0; -+ (iblockstate.getBlock().isAir(iblockstate, worldIn, position) || iblockstate.getBlock().isLeaves(iblockstate, worldIn, position)) && position.getY() > 0; - iblockstate = worldIn.getBlockState(position) - ) - { diff --git a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenTrees.java.patch b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenTrees.java.patch deleted file mode 100644 index a43b2cd51..000000000 --- a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenTrees.java.patch +++ /dev/null @@ -1,112 +0,0 @@ ---- before/net/minecraft/world/gen/feature/WorldGenTrees.java -+++ after/net/minecraft/world/gen/feature/WorldGenTrees.java -@@ -48,7 +48,7 @@ - int i = rand.nextInt(3) + this.minTreeHeight; - boolean flag = true; - -- if (position.getY() >= 1 && position.getY() + i + 1 <= 256) -+ if (position.getY() >= 1 && position.getY() + i + 1 <= worldIn.getHeight()) - { - for (int j = position.getY(); j <= position.getY() + 1 + i; j++) - { -@@ -70,11 +70,11 @@ - { - for (int i1 = position.getZ() - k; i1 <= position.getZ() + k && flag; i1++) - { -- if (j < 0 || j >= 256) -+ if (j < 0 || j >= worldIn.getHeight()) - { - flag = false; - } -- else if (!this.canGrowInto(worldIn.getBlockState(blockpos$mutableblockpos.setPos(l, j, i1)).getBlock())) -+ else if (!this.isReplaceable(worldIn,blockpos$mutableblockpos.setPos(l, j, i1))) - { - flag = false; - } -@@ -88,12 +88,12 @@ - } - else - { -- Block block = worldIn.getBlockState(position.down()).getBlock(); -+ IBlockState state = worldIn.getBlockState(position.down()); - -- if ((block == Blocks.GRASS || block == Blocks.DIRT || block == Blocks.FARMLAND) -- && position.getY() < 256 - i - 1) -+ if (state.getBlock().canSustainPlant(state, worldIn, position.down(), net.minecraft.util.EnumFacing.UP, (net.minecraft.block.BlockSapling)Blocks.SAPLING) -+ && position.getY() < worldIn.getHeight() - i - 1) - { -- this.setDirtAt(worldIn, position.down()); -+ state.getBlock().onPlantGrow(state, worldIn, position.down(), position); - int k2 = 3; - int l2 = 0; - -@@ -113,9 +113,9 @@ - if (Math.abs(l1) != j1 || Math.abs(j2) != j1 || rand.nextInt(2) != 0 && i4 != 0) - { - BlockPos blockpos = new BlockPos(k1, i3, i2); -- Material material = worldIn.getBlockState(blockpos).getMaterial(); -+ state = worldIn.getBlockState(blockpos); - -- if (material == Material.AIR || material == Material.LEAVES || material == Material.VINE) -+ if (state.getBlock().isAir(state, worldIn, blockpos) || state.getBlock().isLeaves(state, worldIn, blockpos) || state.getMaterial() == Material.VINE) - { - this.setBlockAndNotifyAdequately(worldIn, blockpos, this.metaLeaves); - } -@@ -126,9 +126,10 @@ - - for (int j3 = 0; j3 < i; j3++) - { -- Material material1 = worldIn.getBlockState(position.up(j3)).getMaterial(); -+ BlockPos upN = position.up(j3); -+ state = worldIn.getBlockState(upN); - -- if (material1 == Material.AIR || material1 == Material.LEAVES || material1 == Material.VINE) -+ if (state.getBlock().isAir(state, worldIn, upN) || state.getBlock().isLeaves(state, worldIn, upN) || state.getMaterial() == Material.VINE) - { - this.setBlockAndNotifyAdequately(worldIn, position.up(j3), this.metaWood); - -@@ -171,29 +172,30 @@ - { - blockpos$mutableblockpos1.setPos(l4, k3, i5); - -- if (worldIn.getBlockState(blockpos$mutableblockpos1).getMaterial() == Material.LEAVES) -+ state = worldIn.getBlockState(blockpos$mutableblockpos1); -+ if (state.getBlock().isLeaves(state, worldIn, blockpos$mutableblockpos1)) - { - BlockPos blockpos2 = blockpos$mutableblockpos1.west(); - BlockPos blockpos3 = blockpos$mutableblockpos1.east(); - BlockPos blockpos4 = blockpos$mutableblockpos1.north(); - BlockPos blockpos1 = blockpos$mutableblockpos1.south(); - -- if (rand.nextInt(4) == 0 && worldIn.getBlockState(blockpos2).getMaterial() == Material.AIR) -+ if (rand.nextInt(4) == 0 && worldIn.isAirBlock(blockpos2)) - { - this.addHangingVine(worldIn, blockpos2, BlockVine.EAST); - } - -- if (rand.nextInt(4) == 0 && worldIn.getBlockState(blockpos3).getMaterial() == Material.AIR) -+ if (rand.nextInt(4) == 0 && worldIn.isAirBlock(blockpos3)) - { - this.addHangingVine(worldIn, blockpos3, BlockVine.WEST); - } - -- if (rand.nextInt(4) == 0 && worldIn.getBlockState(blockpos4).getMaterial() == Material.AIR) -+ if (rand.nextInt(4) == 0 && worldIn.isAirBlock(blockpos4)) - { - this.addHangingVine(worldIn, blockpos4, BlockVine.SOUTH); - } - -- if (rand.nextInt(4) == 0 && worldIn.getBlockState(blockpos1).getMaterial() == Material.AIR) -+ if (rand.nextInt(4) == 0 && worldIn.isAirBlock(blockpos1)) - { - this.addHangingVine(worldIn, blockpos1, BlockVine.NORTH); - } -@@ -256,7 +258,7 @@ - this.addVine(worldIn, pos, prop); - int i = 4; - -- for (BlockPos blockpos = pos.down(); worldIn.getBlockState(blockpos).getMaterial() == Material.AIR && i > 0; i--) -+ for (BlockPos blockpos = pos.down(); worldIn.isAirBlock(blockpos) && i > 0; --i) - { - this.addVine(worldIn, blockpos, prop); - blockpos = blockpos.down(); diff --git a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenerator.java.patch b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenerator.java.patch deleted file mode 100644 index 164f6440c..000000000 --- a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenerator.java.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- before/net/minecraft/world/gen/feature/WorldGenerator.java -+++ after/net/minecraft/world/gen/feature/WorldGenerator.java -@@ -33,7 +33,8 @@ - } - else - { -- worldIn.setBlockState(pos, state, 2); -+ int flag = net.minecraftforge.common.ForgeModContainer.fixVanillaCascading ? 2| 16 : 2; //Forge: With bit 5 unset, it will notify neighbors and load adjacent chunks. -+ worldIn.setBlockState(pos, state, flag); - } - } - } diff --git a/patches/minecraft/net/minecraft/world/gen/feature/WorldGeneratorBonusChest.java.patch b/patches/minecraft/net/minecraft/world/gen/feature/WorldGeneratorBonusChest.java.patch deleted file mode 100644 index c72440607..000000000 --- a/patches/minecraft/net/minecraft/world/gen/feature/WorldGeneratorBonusChest.java.patch +++ /dev/null @@ -1,47 +0,0 @@ ---- before/net/minecraft/world/gen/feature/WorldGeneratorBonusChest.java -+++ after/net/minecraft/world/gen/feature/WorldGeneratorBonusChest.java -@@ -16,7 +16,7 @@ - public boolean generate(World worldIn, Random rand, BlockPos position) - { - for (IBlockState iblockstate = worldIn.getBlockState(position); -- (iblockstate.getMaterial() == Material.AIR || iblockstate.getMaterial() == Material.LEAVES) && position.getY() > 1; -+ (iblockstate.getBlock().isAir(iblockstate, worldIn, position) || iblockstate.getBlock().isLeaves(iblockstate, worldIn, position)) && position.getY() > 1; - iblockstate = worldIn.getBlockState(position) - ) - { -@@ -39,7 +39,7 @@ - rand.nextInt(4) - rand.nextInt(4) - ); - -- if (worldIn.isAirBlock(blockpos) && worldIn.getBlockState(blockpos.down()).isTopSolid()) -+ if (worldIn.isAirBlock(blockpos) && worldIn.getBlockState(blockpos.down()).isSideSolid(worldIn, blockpos.down(), net.minecraft.util.EnumFacing.UP)) - { - worldIn.setBlockState(blockpos, Blocks.CHEST.getDefaultState(), 2); - TileEntity tileentity = worldIn.getTileEntity(blockpos); -@@ -54,22 +54,22 @@ - BlockPos blockpos3 = blockpos.north(); - BlockPos blockpos4 = blockpos.south(); - -- if (worldIn.isAirBlock(blockpos2) && worldIn.getBlockState(blockpos2.down()).isTopSolid()) -+ if (worldIn.isAirBlock(blockpos2) && worldIn.getBlockState(blockpos2.down()).isSideSolid(worldIn, blockpos2.down(), net.minecraft.util.EnumFacing.UP)) - { - worldIn.setBlockState(blockpos2, Blocks.TORCH.getDefaultState(), 2); - } - -- if (worldIn.isAirBlock(blockpos1) && worldIn.getBlockState(blockpos1.down()).isTopSolid()) -+ if (worldIn.isAirBlock(blockpos1) && worldIn.getBlockState(blockpos1.down()).isSideSolid(worldIn, blockpos1.down(), net.minecraft.util.EnumFacing.UP)) - { - worldIn.setBlockState(blockpos1, Blocks.TORCH.getDefaultState(), 2); - } - -- if (worldIn.isAirBlock(blockpos3) && worldIn.getBlockState(blockpos3.down()).isTopSolid()) -+ if (worldIn.isAirBlock(blockpos3) && worldIn.getBlockState(blockpos3.down()).isSideSolid(worldIn, blockpos3.down(), net.minecraft.util.EnumFacing.UP)) - { - worldIn.setBlockState(blockpos3, Blocks.TORCH.getDefaultState(), 2); - } - -- if (worldIn.isAirBlock(blockpos4) && worldIn.getBlockState(blockpos4.down()).isTopSolid()) -+ if (worldIn.isAirBlock(blockpos4) && worldIn.getBlockState(blockpos4.down()).isSideSolid(worldIn, blockpos4.down(), net.minecraft.util.EnumFacing.UP)) - { - worldIn.setBlockState(blockpos4, Blocks.TORCH.getDefaultState(), 2); - } diff --git a/patches/minecraft/net/minecraft/world/gen/layer/GenLayer.java.patch b/patches/minecraft/net/minecraft/world/gen/layer/GenLayer.java.patch deleted file mode 100644 index 495b47b05..000000000 --- a/patches/minecraft/net/minecraft/world/gen/layer/GenLayer.java.patch +++ /dev/null @@ -1,57 +0,0 @@ ---- before/net/minecraft/world/gen/layer/GenLayer.java -+++ after/net/minecraft/world/gen/layer/GenLayer.java -@@ -49,16 +49,14 @@ - - GenLayer lvt_7_1_ = GenLayerZoom.magnify(1000L, genlayer, 0); - GenLayer genlayerriverinit = new GenLayerRiverInit(100L, lvt_7_1_); -- GenLayer lvt_8_1_ = new GenLayerBiome(200L, genlayer, p_180781_2_, p_180781_3_); -- GenLayer genlayer4 = GenLayerZoom.magnify(1000L, lvt_8_1_, 2); -- GenLayer genlayerbiomeedge = new GenLayerBiomeEdge(1000L, genlayer4); -+ GenLayer genlayerbiomeedge = p_180781_2_.getBiomeLayer(seed, genlayer, p_180781_3_); - GenLayer lvt_9_1_ = GenLayerZoom.magnify(1000L, genlayerriverinit, 2); -- GenLayer genlayerhills = new GenLayerHills(1000L, genlayerbiomeedge, lvt_9_1_); -+ GenLayer lvt_8_1_ = new GenLayerHills(1000L, genlayerbiomeedge, lvt_9_1_); - lvt_7_1_ = GenLayerZoom.magnify(1000L, genlayerriverinit, 2); - lvt_7_1_ = GenLayerZoom.magnify(1000L, lvt_7_1_, j); - GenLayer genlayerriver = new GenLayerRiver(1L, lvt_7_1_); - GenLayer genlayersmooth = new GenLayerSmooth(1000L, genlayerriver); -- lvt_8_1_ = new GenLayerRareBiome(1001L, genlayerhills); -+ lvt_8_1_ = new GenLayerRareBiome(1001L, lvt_8_1_); - - for (int k = 0; k < i; k++) - { -@@ -166,9 +164,31 @@ - - protected static boolean isBiomeOceanic(int p_151618_0_) - { -- Biome biome = Biome.getBiome(p_151618_0_); -- return biome == Biomes.OCEAN || biome == Biomes.DEEP_OCEAN || biome == Biomes.FROZEN_OCEAN; -- } -+ return net.minecraftforge.common.BiomeManager.oceanBiomes.contains(Biome.getBiome(p_151618_0_)); -+ } -+ -+ /* ======================================== FORGE START =====================================*/ -+ protected long nextLong(long par1) -+ { -+ long j = (this.chunkSeed >> 24) % par1; -+ -+ if (j < 0) -+ { -+ j += par1; -+ } -+ -+ this.chunkSeed *= this.chunkSeed * 6364136223846793005L + 1442695040888963407L; -+ this.chunkSeed += this.worldGenSeed; -+ return j; -+ } -+ -+ public static int getModdedBiomeSize(WorldType worldType, int original) -+ { -+ net.minecraftforge.event.terraingen.WorldTypeEvent.BiomeSize event = new net.minecraftforge.event.terraingen.WorldTypeEvent.BiomeSize(worldType, original); -+ net.minecraftforge.common.MinecraftForge.TERRAIN_GEN_BUS.post(event); -+ return event.getNewSize(); -+ } -+ /* ========================================= FORGE END ======================================*/ - - protected int selectRandom(int... p_151619_1_) - { diff --git a/patches/minecraft/net/minecraft/world/gen/layer/GenLayerBiome.java.patch b/patches/minecraft/net/minecraft/world/gen/layer/GenLayerBiome.java.patch deleted file mode 100644 index 61cf79b17..000000000 --- a/patches/minecraft/net/minecraft/world/gen/layer/GenLayerBiome.java.patch +++ /dev/null @@ -1,103 +0,0 @@ ---- before/net/minecraft/world/gen/layer/GenLayerBiome.java -+++ after/net/minecraft/world/gen/layer/GenLayerBiome.java -@@ -7,16 +7,8 @@ - - public class GenLayerBiome extends GenLayer - { -- private Biome[] warmBiomes = new Biome[] -- { -- Biomes.DESERT, Biomes.DESERT, Biomes.DESERT, Biomes.SAVANNA, Biomes.SAVANNA, Biomes.PLAINS -- }; -- private final Biome[] mediumBiomes = new Biome[] -- { -- Biomes.FOREST, Biomes.ROOFED_FOREST, Biomes.EXTREME_HILLS, Biomes.PLAINS, Biomes.BIRCH_FOREST, Biomes.SWAMPLAND -- }; -- private final Biome[] coldBiomes = new Biome[] {Biomes.FOREST, Biomes.EXTREME_HILLS, Biomes.TAIGA, Biomes.PLAINS}; -- private final Biome[] iceBiomes = new Biome[] {Biomes.ICE_PLAINS, Biomes.ICE_PLAINS, Biomes.ICE_PLAINS, Biomes.COLD_TAIGA}; -+ @SuppressWarnings("unchecked") -+ private java.util.List[] biomes = new java.util.ArrayList[net.minecraftforge.common.BiomeManager.BiomeType.values().length]; - private final ChunkGeneratorSettings settings; - - public GenLayerBiome(long p_i45560_1_, GenLayer p_i45560_3_, WorldType p_i45560_4_, ChunkGeneratorSettings p_i45560_5_) -@@ -24,12 +16,30 @@ - super(p_i45560_1_); - this.parent = p_i45560_3_; - -+ for (net.minecraftforge.common.BiomeManager.BiomeType type : net.minecraftforge.common.BiomeManager.BiomeType.values()) -+ { -+ com.google.common.collect.ImmutableList biomesToAdd = net.minecraftforge.common.BiomeManager.getBiomes(type); -+ int idx = type.ordinal(); -+ -+ if (biomes[idx] == null) biomes[idx] = new java.util.ArrayList<>(); -+ if (biomesToAdd != null) biomes[idx].addAll(biomesToAdd); -+ } -+ -+ int desertIdx = net.minecraftforge.common.BiomeManager.BiomeType.DESERT.ordinal(); -+ -+ biomes[desertIdx].add(new net.minecraftforge.common.BiomeManager.BiomeEntry(Biomes.DESERT, 30)); -+ biomes[desertIdx].add(new net.minecraftforge.common.BiomeManager.BiomeEntry(Biomes.SAVANNA, 20)); -+ biomes[desertIdx].add(new net.minecraftforge.common.BiomeManager.BiomeEntry(Biomes.PLAINS, 10)); -+ - if (p_i45560_4_ == WorldType.DEFAULT_1_1) - { -- this.warmBiomes = new Biome[] -- { -- Biomes.DESERT, Biomes.FOREST, Biomes.EXTREME_HILLS, Biomes.SWAMPLAND, Biomes.PLAINS, Biomes.TAIGA -- }; -+ biomes[desertIdx].clear(); -+ biomes[desertIdx].add(new net.minecraftforge.common.BiomeManager.BiomeEntry(Biomes.DESERT, 10)); -+ biomes[desertIdx].add(new net.minecraftforge.common.BiomeManager.BiomeEntry(Biomes.FOREST, 10)); -+ biomes[desertIdx].add(new net.minecraftforge.common.BiomeManager.BiomeEntry(Biomes.EXTREME_HILLS, 10)); -+ biomes[desertIdx].add(new net.minecraftforge.common.BiomeManager.BiomeEntry(Biomes.SWAMPLAND, 10)); -+ biomes[desertIdx].add(new net.minecraftforge.common.BiomeManager.BiomeEntry(Biomes.PLAINS, 10)); -+ biomes[desertIdx].add(new net.minecraftforge.common.BiomeManager.BiomeEntry(Biomes.TAIGA, 10)); - this.settings = null; - } - else -@@ -80,7 +90,7 @@ - } - else - { -- aint1[j + i * areaWidth] = Biome.getIdForBiome(this.warmBiomes[this.nextInt(this.warmBiomes.length)]); -+ aint1[j + i * areaWidth] = Biome.getIdForBiome(getWeightedBiomeEntry(net.minecraftforge.common.BiomeManager.BiomeType.DESERT).biome); - } - } - else if (k == 2) -@@ -91,7 +101,7 @@ - } - else - { -- aint1[j + i * areaWidth] = Biome.getIdForBiome(this.mediumBiomes[this.nextInt(this.mediumBiomes.length)]); -+ aint1[j + i * areaWidth] = Biome.getIdForBiome(getWeightedBiomeEntry(net.minecraftforge.common.BiomeManager.BiomeType.WARM).biome); - } - } - else if (k == 3) -@@ -102,12 +112,12 @@ - } - else - { -- aint1[j + i * areaWidth] = Biome.getIdForBiome(this.coldBiomes[this.nextInt(this.coldBiomes.length)]); -+ aint1[j + i * areaWidth] = Biome.getIdForBiome(getWeightedBiomeEntry(net.minecraftforge.common.BiomeManager.BiomeType.COOL).biome); - } - } - else if (k == 4) - { -- aint1[j + i * areaWidth] = Biome.getIdForBiome(this.iceBiomes[this.nextInt(this.iceBiomes.length)]); -+ aint1[j + i * areaWidth] = Biome.getIdForBiome(getWeightedBiomeEntry(net.minecraftforge.common.BiomeManager.BiomeType.ICY).biome); - } - else - { -@@ -117,5 +127,13 @@ - } - - return aint1; -+ } -+ -+ protected net.minecraftforge.common.BiomeManager.BiomeEntry getWeightedBiomeEntry(net.minecraftforge.common.BiomeManager.BiomeType type) -+ { -+ java.util.List biomeList = biomes[type.ordinal()]; -+ int totalWeight = net.minecraft.util.WeightedRandom.getTotalWeight(biomeList); -+ int weight = net.minecraftforge.common.BiomeManager.isTypeListModded(type)?nextInt(totalWeight):nextInt(totalWeight / 10) * 10; -+ return (net.minecraftforge.common.BiomeManager.BiomeEntry)net.minecraft.util.WeightedRandom.getRandomItem(biomeList, weight); - } - } diff --git a/patches/minecraft/net/minecraft/world/gen/structure/MapGenStronghold.java.patch b/patches/minecraft/net/minecraft/world/gen/structure/MapGenStronghold.java.patch deleted file mode 100644 index e8385f852..000000000 --- a/patches/minecraft/net/minecraft/world/gen/structure/MapGenStronghold.java.patch +++ /dev/null @@ -1,30 +0,0 @@ ---- before/net/minecraft/world/gen/structure/MapGenStronghold.java -+++ after/net/minecraft/world/gen/structure/MapGenStronghold.java -@@ -15,8 +15,8 @@ - { - public final List allowedBiomes; - private boolean ranBiomeCheck; -- private ChunkPos[] structureCoords = new ChunkPos[128]; -- private double distance = 32.0; -+ private ChunkPos[] structureCoords= new ChunkPos[128]; -+ private double distance = 32.0D; - private int spread = 3; - - public MapGenStronghold() -@@ -25,7 +25,15 @@ - - for (Biome biome : Biome.REGISTRY) - { -- if (biome != null && biome.getBaseHeight() > 0.0F) -+ if (biome != null && biome.getBaseHeight() > 0.0F && !net.minecraftforge.common.BiomeManager.strongHoldBiomesBlackList.contains(biome)) -+ { -+ this.allowedBiomes.add(biome); -+ } -+ } -+ -+ for (Biome biome : net.minecraftforge.common.BiomeManager.strongHoldBiomes) -+ { -+ if (!this.allowedBiomes.contains(biome)) - { - this.allowedBiomes.add(biome); - } diff --git a/patches/minecraft/net/minecraft/world/gen/structure/MapGenStructure.java.patch b/patches/minecraft/net/minecraft/world/gen/structure/MapGenStructure.java.patch deleted file mode 100644 index 962690808..000000000 --- a/patches/minecraft/net/minecraft/world/gen/structure/MapGenStructure.java.patch +++ /dev/null @@ -1,17 +0,0 @@ ---- before/net/minecraft/world/gen/structure/MapGenStructure.java -+++ after/net/minecraft/world/gen/structure/MapGenStructure.java -@@ -155,12 +155,12 @@ - { - if (this.structureData == null && worldIn != null) - { -- this.structureData = (MapGenStructureData)worldIn.loadData(MapGenStructureData.class, this.getStructureName()); -+ this.structureData = (MapGenStructureData)worldIn.getPerWorldStorage().getOrLoadData(MapGenStructureData.class, this.getStructureName()); - - if (this.structureData == null) - { - this.structureData = new MapGenStructureData(this.getStructureName()); -- worldIn.setData(this.getStructureName(), this.structureData); -+ worldIn.getPerWorldStorage().setData(this.getStructureName(), this.structureData); - } - else - { diff --git a/patches/minecraft/net/minecraft/world/gen/structure/StructureComponent.java.patch b/patches/minecraft/net/minecraft/world/gen/structure/StructureComponent.java.patch deleted file mode 100644 index 033d23a06..000000000 --- a/patches/minecraft/net/minecraft/world/gen/structure/StructureComponent.java.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- before/net/minecraft/world/gen/structure/StructureComponent.java -+++ after/net/minecraft/world/gen/structure/StructureComponent.java -@@ -41,6 +41,10 @@ - - public final NBTTagCompound createStructureBaseNBT() - { -+ if (MapGenStructureIO.getStructureComponentName(this) == null) // Friendlier error then the Null String error below. -+ { -+ throw new RuntimeException("StructureComponent \"" + this.getClass().getName() + "\" missing ID Mapping, Modder see MapGenStructureIO"); -+ } - NBTTagCompound nbttagcompound = new NBTTagCompound(); - nbttagcompound.setString("id", MapGenStructureIO.getStructureComponentName(this)); - nbttagcompound.setTag("BB", this.boundingBox.toNBTTagIntArray()); diff --git a/patches/minecraft/net/minecraft/world/gen/structure/StructureStart.java.patch b/patches/minecraft/net/minecraft/world/gen/structure/StructureStart.java.patch deleted file mode 100644 index 53eba38fc..000000000 --- a/patches/minecraft/net/minecraft/world/gen/structure/StructureStart.java.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- before/net/minecraft/world/gen/structure/StructureStart.java -+++ after/net/minecraft/world/gen/structure/StructureStart.java -@@ -63,6 +63,10 @@ - - public NBTTagCompound writeStructureComponentsToNBT(int chunkX, int chunkZ) - { -+ if (MapGenStructureIO.getStructureStartName(this) == null) // This is just a more friendly error instead of the 'Null String' below -+ { -+ throw new RuntimeException("StructureStart \"" + this.getClass().getName() + "\" missing ID Mapping, Modder see MapGenStructureIO"); -+ } - NBTTagCompound nbttagcompound = new NBTTagCompound(); - nbttagcompound.setString("id", MapGenStructureIO.getStructureStartName(this)); - nbttagcompound.setInteger("ChunkX", chunkX); -@@ -98,7 +102,8 @@ - - for (int i = 0; i < nbttaglist.tagCount(); i++) - { -- this.components.add(MapGenStructureIO.getStructureComponent(nbttaglist.getCompoundTagAt(i), worldIn)); -+ StructureComponent tmp = MapGenStructureIO.getStructureComponent(nbttaglist.getCompoundTagAt(i), worldIn); -+ if (tmp != null) this.components.add(tmp); //Forge: Prevent NPEs further down the line when a componenet can't be loaded. - } - - this.readFromNBT(tagCompound); diff --git a/patches/minecraft/net/minecraft/world/gen/structure/StructureVillagePieces.java.patch b/patches/minecraft/net/minecraft/world/gen/structure/StructureVillagePieces.java.patch deleted file mode 100644 index 7ca513389..000000000 --- a/patches/minecraft/net/minecraft/world/gen/structure/StructureVillagePieces.java.patch +++ /dev/null @@ -1,95 +0,0 @@ ---- before/net/minecraft/world/gen/structure/StructureVillagePieces.java -+++ after/net/minecraft/world/gen/structure/StructureVillagePieces.java -@@ -87,6 +87,7 @@ - list.add( - new StructureVillagePieces.PieceWeight(StructureVillagePieces.House3.class, 8, MathHelper.getInt(random, 0 + size, 3 + size * 2)) - ); -+ net.minecraftforge.fml.common.registry.VillagerRegistry.addExtraVillageComponents(list, random, size); - Iterator iterator = list.iterator(); - - while (iterator.hasNext()) -@@ -188,6 +189,10 @@ - start, structureComponents, rand, structureMinX, structureMinY, structureMinZ, facing, componentType - ); - } -+ else -+ { -+ structurevillagepieces$village = net.minecraftforge.fml.common.registry.VillagerRegistry.getVillageComponent(weight, start , structureComponents, rand, structureMinX, structureMinY, structureMinZ, facing, componentType); -+ } - - return structurevillagepieces$village; - } -@@ -1821,6 +1826,7 @@ - public List structureVillageWeightedPieceList; - public List pendingHouses = Lists.newArrayList(); - public List pendingRoads = Lists.newArrayList(); -+ public Biome biome; - - public Start() - { -@@ -1841,6 +1847,8 @@ - this.structureVillageWeightedPieceList = p_i2104_6_; - this.terrainType = p_i2104_7_; - Biome biome = biomeProviderIn.getBiome(new BlockPos(p_i2104_4_, 0, p_i2104_5_), Biomes.DEFAULT); -+ this.biome = biome; -+ this.startPiece = this; - - if (biome instanceof BiomeDesert) - { -@@ -1922,6 +1930,7 @@ - private int villagersSpawned; - protected int structureType; - protected boolean isZombieInfested; -+ protected StructureVillagePieces.Start startPiece; - - public Village() - { -@@ -1935,6 +1944,7 @@ - { - this.structureType = start.structureType; - this.isZombieInfested = start.isZombieInfested; -+ startPiece = start; - } - } - -@@ -2140,7 +2150,7 @@ - EntityZombieVillager entityzombievillager = new EntityZombieVillager(worldIn); - entityzombievillager.setLocationAndAngles(j + 0.5, k, l + 0.5, 0.0F, 0.0F); - entityzombievillager.onInitialSpawn(worldIn.getDifficultyForLocation(new BlockPos(entityzombievillager)), null); -- entityzombievillager.setProfession(this.chooseProfession(i, 0)); -+ entityzombievillager.setForgeProfession(this.chooseForgeProfession(i, net.minecraftforge.fml.common.registry.VillagerRegistry.FARMER)); - entityzombievillager.enablePersistence(); - worldIn.spawnEntity(entityzombievillager); - } -@@ -2148,7 +2158,8 @@ - { - EntityVillager entityvillager = new EntityVillager(worldIn); - entityvillager.setLocationAndAngles(j + 0.5, k, l + 0.5, 0.0F, 0.0F); -- entityvillager.setProfession(this.chooseProfession(i, worldIn.rand.nextInt(6))); -+ net.minecraftforge.fml.common.registry.VillagerRegistry.setRandomProfession(entityvillager, worldIn.rand); -+ entityvillager.setProfession(this.chooseForgeProfession(i, entityvillager.getProfessionForge())); - entityvillager.finalizeMobSpawn(worldIn.getDifficultyForLocation(new BlockPos(entityvillager)), null, false); - worldIn.spawnEntity(entityvillager); - } -@@ -2156,13 +2167,21 @@ - } - } - -+ @Deprecated // Use Forge version below. - protected int chooseProfession(int villagersSpawnedIn, int currentVillagerProfession) - { - return currentVillagerProfession; - } -+ protected net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession chooseForgeProfession(int count, net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession prof) -+ { -+ return net.minecraftforge.fml.common.registry.VillagerRegistry.getById(chooseProfession(count, net.minecraftforge.fml.common.registry.VillagerRegistry.getId(prof))); -+ } - - protected IBlockState getBiomeSpecificBlockState(IBlockState blockstateIn) - { -+ net.minecraftforge.event.terraingen.BiomeEvent.GetVillageBlockID event = new net.minecraftforge.event.terraingen.BiomeEvent.GetVillageBlockID(startPiece == null ? null : startPiece.biome, blockstateIn); -+ net.minecraftforge.common.MinecraftForge.TERRAIN_GEN_BUS.post(event); -+ if (event.getResult() == net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) return event.getReplacement(); - if (this.structureType == 1) - { - if (blockstateIn.getBlock() == Blocks.LOG || blockstateIn.getBlock() == Blocks.LOG2) diff --git a/patches/minecraft/net/minecraft/world/gen/structure/template/Template.java.patch b/patches/minecraft/net/minecraft/world/gen/structure/template/Template.java.patch deleted file mode 100644 index 469abaeaf..000000000 --- a/patches/minecraft/net/minecraft/world/gen/structure/template/Template.java.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- before/net/minecraft/world/gen/structure/template/Template.java -+++ after/net/minecraft/world/gen/structure/template/Template.java -@@ -226,6 +226,8 @@ - for (Template.BlockInfo template$blockinfo : this.blocks) - { - BlockPos blockpos = transformedBlockPos(placementIn, template$blockinfo.pos).add(pos); -+ // Forge: skip processing blocks outside BB to prevent cascading worldgen issues -+ if (structureboundingbox != null && !structureboundingbox.isVecInside(blockpos)) continue; - Template.BlockInfo template$blockinfo1 = templateProcessor != null - ? templateProcessor.processBlock(worldIn, blockpos, template$blockinfo) - : template$blockinfo; -@@ -555,6 +557,7 @@ - nbttaglist2.appendTag(NBTUtil.writeBlockState(new NBTTagCompound(), iblockstate)); - } - -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().getDataFixer().writeVersionData(nbt); //Moved up for MC updating reasons. - nbt.setTag("palette", nbttaglist2); - nbt.setTag("blocks", nbttaglist); - nbt.setTag("entities", nbttaglist1); diff --git a/patches/minecraft/net/minecraft/world/storage/DerivedWorldInfo.java.patch b/patches/minecraft/net/minecraft/world/storage/DerivedWorldInfo.java.patch deleted file mode 100644 index c1e76c4ca..000000000 --- a/patches/minecraft/net/minecraft/world/storage/DerivedWorldInfo.java.patch +++ /dev/null @@ -1,30 +0,0 @@ ---- before/net/minecraft/world/storage/DerivedWorldInfo.java -+++ after/net/minecraft/world/storage/DerivedWorldInfo.java -@@ -260,15 +260,27 @@ - { - } - -+ @Deprecated - @Override - public void setDimensionData(DimensionType dimensionIn, NBTTagCompound compound) - { - this.delegate.setDimensionData(dimensionIn, compound); - } - -+ @Deprecated - @Override - public NBTTagCompound getDimensionData(DimensionType dimensionIn) - { - return this.delegate.getDimensionData(dimensionIn); -+ } -+ -+ public void setDimensionData(int dimensionID, NBTTagCompound compound) -+ { -+ this.delegate.setDimensionData(dimensionID, compound); -+ } -+ -+ public NBTTagCompound getDimensionData(int dimensionID) -+ { -+ return this.delegate.getDimensionData(dimensionID); - } - } diff --git a/patches/minecraft/net/minecraft/world/storage/MapData.java.patch b/patches/minecraft/net/minecraft/world/storage/MapData.java.patch deleted file mode 100644 index bb0a37fbe..000000000 --- a/patches/minecraft/net/minecraft/world/storage/MapData.java.patch +++ /dev/null @@ -1,41 +0,0 @@ ---- before/net/minecraft/world/storage/MapData.java -+++ after/net/minecraft/world/storage/MapData.java -@@ -20,7 +20,7 @@ - { - public int xCenter; - public int zCenter; -- public byte dimension; -+ public int dimension; //FML byte -> int - public boolean trackingPosition; - public boolean unlimitedTracking; - public byte scale; -@@ -46,7 +46,7 @@ - @Override - public void readFromNBT(NBTTagCompound nbt) - { -- this.dimension = nbt.getByte("dimension"); -+ this.dimension = nbt.getInteger("dimension"); - this.xCenter = nbt.getInteger("xCenter"); - this.zCenter = nbt.getInteger("zCenter"); - this.scale = nbt.getByte("scale"); -@@ -99,7 +99,7 @@ - @Override - public NBTTagCompound writeToNBT(NBTTagCompound compound) - { -- compound.setByte("dimension", this.dimension); -+ compound.setInteger("dimension", this.dimension); - compound.setInteger("xCenter", this.xCenter); - compound.setInteger("zCenter", this.zCenter); - compound.setByte("scale", this.scale); -@@ -232,9 +232,9 @@ - rotationIn += rotationIn < 0.0 ? -8.0 : 8.0; - b2 = (byte)(rotationIn * 16.0 / 360.0); - -- if (this.dimension < 0) -+ if (worldIn.provider.shouldMapSpin(decorationName, worldX, worldZ, rotationIn)) - { -- int l = (int)(worldIn.getWorldInfo().getWorldTime() / 10L); -+ int l = (int)(worldIn.getWorldTime() / 10L); - b2 = (byte)(l * l * 34187121 + l * 121 >> 15 & 15); - } - } diff --git a/patches/minecraft/net/minecraft/world/storage/MapDecoration.java.patch b/patches/minecraft/net/minecraft/world/storage/MapDecoration.java.patch deleted file mode 100644 index 2fc100400..000000000 --- a/patches/minecraft/net/minecraft/world/storage/MapDecoration.java.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- before/net/minecraft/world/storage/MapDecoration.java -+++ after/net/minecraft/world/storage/MapDecoration.java -@@ -89,6 +89,17 @@ - return 31 * i + this.rotation; - } - -+ /** -+ * Renders this decoration, useful for custom sprite sheets. -+ * @param index The index of this icon in the MapData's list. Used by vanilla to offset the Z-coordinate to prevent Z-fighting -+ * @return false to run vanilla logic for this decoration, true to skip it -+ */ -+ @SideOnly(Side.CLIENT) -+ public boolean render(int index) -+ { -+ return false; -+ } -+ - public static enum Type - { - PLAYER(false), diff --git a/patches/minecraft/net/minecraft/world/storage/SaveFormatOld.java.patch b/patches/minecraft/net/minecraft/world/storage/SaveFormatOld.java.patch deleted file mode 100644 index 99dd974c0..000000000 --- a/patches/minecraft/net/minecraft/world/storage/SaveFormatOld.java.patch +++ /dev/null @@ -1,27 +0,0 @@ ---- before/net/minecraft/world/storage/SaveFormatOld.java -+++ after/net/minecraft/world/storage/SaveFormatOld.java -@@ -113,6 +113,24 @@ - } - } - -+ //Forge: Special version of the above that runs during actual world loading and not metadata gathering. -+ public static WorldInfo loadAndFix(File file, DataFixer fixer, SaveHandler save) -+ { -+ try -+ { -+ NBTTagCompound nbt = CompressedStreamTools.readCompressed(new FileInputStream(file)); -+ WorldInfo info = new WorldInfo(fixer.process(FixTypes.LEVEL, nbt.getCompoundTag("Data"))); -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().handleWorldDataLoad(save, info, nbt); -+ return info; -+ } -+ catch (net.minecraftforge.fml.common.StartupQuery.AbortedException e) { throw e; } -+ catch (Exception exception) -+ { -+ LOGGER.error((String)("Exception reading " + file), (Throwable)exception); -+ return null; -+ } -+ } -+ - @SideOnly(Side.CLIENT) - @Override - public void renameWorld(String dirName, String newName) diff --git a/patches/minecraft/net/minecraft/world/storage/SaveHandler.java.patch b/patches/minecraft/net/minecraft/world/storage/SaveHandler.java.patch deleted file mode 100644 index 23c3d5a06..000000000 --- a/patches/minecraft/net/minecraft/world/storage/SaveHandler.java.patch +++ /dev/null @@ -1,71 +0,0 @@ ---- before/net/minecraft/world/storage/SaveHandler.java -+++ after/net/minecraft/world/storage/SaveHandler.java -@@ -123,7 +123,7 @@ - - if (file1.exists()) - { -- WorldInfo worldinfo = SaveFormatOld.getWorldData(file1, this.dataFixer); -+ WorldInfo worldinfo = SaveFormatOld.loadAndFix(file1, this.dataFixer, this); - - if (worldinfo != null) - { -@@ -131,8 +131,9 @@ - } - } - -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().confirmBackupLevelDatUse(this); - file1 = new File(this.worldDirectory, "level.dat_old"); -- return file1.exists() ? SaveFormatOld.getWorldData(file1, this.dataFixer) : null; -+ return file1.exists() ? SaveFormatOld.loadAndFix(file1, this.dataFixer, this) : null; - } - - @Override -@@ -142,6 +143,8 @@ - NBTTagCompound nbttagcompound1 = new NBTTagCompound(); - nbttagcompound1.setTag("Data", nbttagcompound); - -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().handleWorldDataSave(this, worldInformation, nbttagcompound1); -+ - try - { - File file1 = new File(this.worldDirectory, "level.dat_new"); -@@ -196,6 +199,7 @@ - } - - file1.renameTo(file2); -+ net.minecraftforge.event.ForgeEventFactory.firePlayerSavingEvent(player, this.playersDirectory, player.getUniqueID().toString()); - } - catch (Exception exception) - { -@@ -228,6 +232,7 @@ - player.readFromNBT(this.dataFixer.process(FixTypes.PLAYER, nbttagcompound)); - } - -+ net.minecraftforge.event.ForgeEventFactory.firePlayerLoadingEvent(player, playersDirectory, player.getUniqueID().toString()); - return nbttagcompound; - } - -@@ -273,5 +278,23 @@ - public TemplateManager getStructureTemplateManager() - { - return this.structureTemplateManager; -+ } -+ -+ public NBTTagCompound getPlayerNBT(net.minecraft.entity.player.EntityPlayerMP player) -+ { -+ try -+ { -+ File file1 = new File(this.playersDirectory, player.getUniqueID() + ".dat"); -+ -+ if (file1.exists() && file1.isFile()) -+ { -+ return CompressedStreamTools.readCompressed(new FileInputStream(file1)); -+ } -+ } -+ catch (Exception exception) -+ { -+ LOGGER.warn("Failed to load player data for " + player.getName()); -+ } -+ return null; - } - } diff --git a/patches/minecraft/net/minecraft/world/storage/WorldInfo.java.patch b/patches/minecraft/net/minecraft/world/storage/WorldInfo.java.patch deleted file mode 100644 index f47d2ca37..000000000 --- a/patches/minecraft/net/minecraft/world/storage/WorldInfo.java.patch +++ /dev/null @@ -1,101 +0,0 @@ ---- before/net/minecraft/world/storage/WorldInfo.java -+++ after/net/minecraft/world/storage/WorldInfo.java -@@ -63,8 +63,9 @@ - private double borderDamagePerBlock = 0.2; - private int borderWarningDistance = 5; - private int borderWarningTime = 15; -- private final Map dimensionData = Maps.newEnumMap(DimensionType.class); -+ private final Map dimensionData = Maps.newHashMap(); - private GameRules gameRules = new GameRules(); -+ private java.util.Map additionalProperties; - - protected WorldInfo() - { -@@ -252,7 +253,7 @@ - - for (String s : nbttagcompound1.getKeySet()) - { -- this.dimensionData.put(DimensionType.getById(Integer.parseInt(s)), nbttagcompound1.getCompoundTag(s)); -+ this.dimensionData.put(Integer.parseInt(s), nbttagcompound1.getCompoundTag(s)); - } - } - } -@@ -367,6 +368,7 @@ - nbt.setDouble("BorderSizeLerpTarget", this.borderSizeLerpTarget); - nbt.setDouble("BorderWarningBlocks", this.borderWarningDistance); - nbt.setDouble("BorderWarningTime", this.borderWarningTime); -+ net.minecraftforge.fml.common.FMLCommonHandler.instance().getDataFixer().writeVersionData(nbt); - - if (this.difficulty != null) - { -@@ -377,9 +379,10 @@ - nbt.setTag("GameRules", this.gameRules.writeToNBT()); - NBTTagCompound nbttagcompound1 = new NBTTagCompound(); - -- for (Entry entry : this.dimensionData.entrySet()) -+ for (Entry entry : this.dimensionData.entrySet()) - { -- nbttagcompound1.setTag(String.valueOf(entry.getKey().getId()), entry.getValue()); -+ if (entry.getValue() == null || entry.getValue().isEmpty()) continue; -+ nbttagcompound1.setTag(String.valueOf(entry.getKey()), entry.getValue()); - } - - nbt.setTag("DimensionData", nbttagcompound1); -@@ -709,6 +712,7 @@ - - public void setDifficulty(EnumDifficulty newDifficulty) - { -+ net.minecraftforge.common.ForgeHooks.onDifficultyChange(newDifficulty, this.difficulty); - this.difficulty = newDifficulty; - } - -@@ -832,16 +836,47 @@ - } - ); - } -- -+ /** -+ * Allow access to additional mod specific world based properties -+ * Used by FML to store mod list associated with a world, and maybe an id map -+ * Used by Forge to store the dimensions available to a world -+ * @param additionalProperties -+ */ -+ public void setAdditionalProperties(java.util.Map additionalProperties) -+ { -+ // one time set for this -+ if (this.additionalProperties == null) -+ { -+ this.additionalProperties = additionalProperties; -+ } -+ } -+ -+ public net.minecraft.nbt.NBTBase getAdditionalProperty(String additionalProperty) -+ { -+ return this.additionalProperties!=null? this.additionalProperties.get(additionalProperty) : null; -+ } -+ -+ @Deprecated //Use the int version below, and pass in dimension id NOT TYPE id - public NBTTagCompound getDimensionData(DimensionType dimensionIn) - { -+ return getDimensionData(dimensionIn.getId()); -+ } -+ public NBTTagCompound getDimensionData(int dimensionIn) -+ { - NBTTagCompound nbttagcompound = this.dimensionData.get(dimensionIn); - return nbttagcompound == null ? new NBTTagCompound() : nbttagcompound; - } - -+ @Deprecated //Use the int version below, and pass in dimension id NOT TYPE id - public void setDimensionData(DimensionType dimensionIn, NBTTagCompound compound) - { -- this.dimensionData.put(dimensionIn, compound); -+ this.setDimensionData(dimensionIn.getId(), compound); -+ } -+ -+ //Dimension numerical ID version of setter, as two dimensions could in theory have the same DimensionType. ID should be grabbed from the world NOT the Type -+ public void setDimensionData(int dimensionID, NBTTagCompound compound) -+ { -+ this.dimensionData.put(dimensionID, compound); - } - - @SideOnly(Side.CLIENT) diff --git a/patches/minecraft/net/minecraft/world/storage/WorldSavedData.java.patch b/patches/minecraft/net/minecraft/world/storage/WorldSavedData.java.patch deleted file mode 100644 index 51299d867..000000000 --- a/patches/minecraft/net/minecraft/world/storage/WorldSavedData.java.patch +++ /dev/null @@ -1,27 +0,0 @@ ---- before/net/minecraft/world/storage/WorldSavedData.java -+++ after/net/minecraft/world/storage/WorldSavedData.java -@@ -2,7 +2,7 @@ - - import net.minecraft.nbt.NBTTagCompound; - --public abstract class WorldSavedData -+public abstract class WorldSavedData implements net.minecraftforge.common.util.INBTSerializable - { - public final String mapName; - private boolean dirty; -@@ -29,5 +29,15 @@ - public boolean isDirty() - { - return this.dirty; -+ } -+ -+ public void deserializeNBT(NBTTagCompound nbt) -+ { -+ this.readFromNBT(nbt); -+ } -+ -+ public NBTTagCompound serializeNBT() -+ { -+ return this.writeToNBT(new NBTTagCompound()); - } - } diff --git a/patches/minecraft/net/minecraft/world/storage/loot/LootContext.java.patch b/patches/minecraft/net/minecraft/world/storage/loot/LootContext.java.patch deleted file mode 100644 index 306cbeb01..000000000 --- a/patches/minecraft/net/minecraft/world/storage/loot/LootContext.java.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- before/net/minecraft/world/storage/loot/LootContext.java -+++ after/net/minecraft/world/storage/loot/LootContext.java -@@ -96,6 +96,16 @@ - } - } - -+ public WorldServer getWorld() -+ { -+ return world; -+ } -+ -+ public int getLootingModifier() -+ { -+ return net.minecraftforge.common.ForgeHooks.getLootingLevel(getLootedEntity(), getKiller(), damageSource); -+ } -+ - public static class Builder - { - private final WorldServer world; diff --git a/patches/minecraft/net/minecraft/world/storage/loot/LootEntry.java.patch b/patches/minecraft/net/minecraft/world/storage/loot/LootEntry.java.patch deleted file mode 100644 index 8364d293f..000000000 --- a/patches/minecraft/net/minecraft/world/storage/loot/LootEntry.java.patch +++ /dev/null @@ -1,59 +0,0 @@ ---- before/net/minecraft/world/storage/loot/LootEntry.java -+++ after/net/minecraft/world/storage/loot/LootEntry.java -@@ -18,15 +18,17 @@ - - public abstract class LootEntry - { -+ protected final String entryName; - protected final int weight; - protected final int quality; - protected final LootCondition[] conditions; - -- protected LootEntry(int weightIn, int qualityIn, LootCondition[] conditionsIn) -+ protected LootEntry(int weightIn, int qualityIn, LootCondition[] conditionsIn, String entryName) - { - this.weight = weightIn; - this.quality = qualityIn; - this.conditions = conditionsIn; -+ this.entryName = entryName; - } - - public int getEffectiveWeight(float luck) -@@ -34,6 +36,8 @@ - return Math.max(MathHelper.floor(this.weight + this.quality * luck), 0); - } - -+ public String getEntryName(){ return this.entryName; } -+ - public abstract void addLoot(Collection stacks, Random rand, LootContext context); - - protected abstract void serialize(JsonObject json, JsonSerializationContext context); -@@ -57,6 +61,9 @@ - alootcondition = new LootCondition[0]; - } - -+ LootEntry ret = net.minecraftforge.common.ForgeHooks.deserializeJsonLootEntry(s, jsonobject, i, j, alootcondition); -+ if (ret != null) return ret; -+ - if ("item".equals(s)) - { - return LootEntryItem.deserialize(jsonobject, p_deserialize_3_, i, j, alootcondition); -@@ -78,6 +85,8 @@ - public JsonElement serialize(LootEntry p_serialize_1_, Type p_serialize_2_, JsonSerializationContext p_serialize_3_) - { - JsonObject jsonobject = new JsonObject(); -+ if (p_serialize_1_.entryName != null && !p_serialize_1_.entryName.startsWith("custom#")) -+ jsonobject.addProperty("entryName", p_serialize_1_.entryName); - jsonobject.addProperty("weight", p_serialize_1_.weight); - jsonobject.addProperty("quality", p_serialize_1_.quality); - -@@ -86,6 +95,9 @@ - jsonobject.add("conditions", p_serialize_3_.serialize(p_serialize_1_.conditions)); - } - -+ String type = net.minecraftforge.common.ForgeHooks.getLootEntryType(p_serialize_1_); -+ if (type != null) jsonobject.addProperty("type", type); -+ else - if (p_serialize_1_ instanceof LootEntryItem) - { - jsonobject.addProperty("type", "item"); diff --git a/patches/minecraft/net/minecraft/world/storage/loot/LootEntryEmpty.java.patch b/patches/minecraft/net/minecraft/world/storage/loot/LootEntryEmpty.java.patch deleted file mode 100644 index ff0534397..000000000 --- a/patches/minecraft/net/minecraft/world/storage/loot/LootEntryEmpty.java.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- before/net/minecraft/world/storage/loot/LootEntryEmpty.java -+++ after/net/minecraft/world/storage/loot/LootEntryEmpty.java -@@ -10,9 +10,9 @@ - - public class LootEntryEmpty extends LootEntry - { -- public LootEntryEmpty(int weightIn, int qualityIn, LootCondition[] conditionsIn) -+ public LootEntryEmpty(int weightIn, int qualityIn, LootCondition[] conditionsIn, String entryName) - { -- super(weightIn, qualityIn, conditionsIn); -+ super(weightIn, qualityIn, conditionsIn, entryName); - } - - @Override -@@ -29,6 +29,6 @@ - JsonObject object, JsonDeserializationContext deserializationContext, int weightIn, int qualityIn, LootCondition[] conditionsIn - ) - { -- return new LootEntryEmpty(weightIn, qualityIn, conditionsIn); -+ return new LootEntryEmpty(weightIn, qualityIn, conditionsIn, net.minecraftforge.common.ForgeHooks.readLootEntryName(object, "empty")); - } - } diff --git a/patches/minecraft/net/minecraft/world/storage/loot/LootEntryItem.java.patch b/patches/minecraft/net/minecraft/world/storage/loot/LootEntryItem.java.patch deleted file mode 100644 index eee86699f..000000000 --- a/patches/minecraft/net/minecraft/world/storage/loot/LootEntryItem.java.patch +++ /dev/null @@ -1,39 +0,0 @@ ---- before/net/minecraft/world/storage/loot/LootEntryItem.java -+++ after/net/minecraft/world/storage/loot/LootEntryItem.java -@@ -18,9 +18,9 @@ - protected final Item item; - protected final LootFunction[] functions; - -- public LootEntryItem(Item itemIn, int weightIn, int qualityIn, LootFunction[] functionsIn, LootCondition[] conditionsIn) -+ public LootEntryItem(Item itemIn, int weightIn, int qualityIn, LootFunction[] functionsIn, LootCondition[] conditionsIn, String entryName) - { -- super(weightIn, qualityIn, conditionsIn); -+ super(weightIn, qualityIn, conditionsIn, entryName); - this.item = itemIn; - this.functions = functionsIn; - } -@@ -40,7 +40,7 @@ - - if (!itemstack.isEmpty()) - { -- if (itemstack.getCount() < this.item.getItemStackLimit()) -+ if (itemstack.getCount() < this.item.getItemStackLimit(itemstack)) - { - stacks.add(itemstack); - } -@@ -83,6 +83,7 @@ - JsonObject object, JsonDeserializationContext deserializationContext, int weightIn, int qualityIn, LootCondition[] conditionsIn - ) - { -+ String name = net.minecraftforge.common.ForgeHooks.readLootEntryName(object, "item"); - Item item = JsonUtils.getItem(object, "name"); - LootFunction[] alootfunction; - -@@ -95,6 +96,6 @@ - alootfunction = new LootFunction[0]; - } - -- return new LootEntryItem(item, weightIn, qualityIn, alootfunction, conditionsIn); -+ return new LootEntryItem(item, weightIn, qualityIn, alootfunction, conditionsIn, name); - } - } diff --git a/patches/minecraft/net/minecraft/world/storage/loot/LootEntryTable.java.patch b/patches/minecraft/net/minecraft/world/storage/loot/LootEntryTable.java.patch deleted file mode 100644 index 870592195..000000000 --- a/patches/minecraft/net/minecraft/world/storage/loot/LootEntryTable.java.patch +++ /dev/null @@ -1,24 +0,0 @@ ---- before/net/minecraft/world/storage/loot/LootEntryTable.java -+++ after/net/minecraft/world/storage/loot/LootEntryTable.java -@@ -14,9 +14,9 @@ - { - protected final ResourceLocation table; - -- public LootEntryTable(ResourceLocation tableIn, int weightIn, int qualityIn, LootCondition[] conditionsIn) -+ public LootEntryTable(ResourceLocation tableIn, int weightIn, int qualityIn, LootCondition[] conditionsIn, String entryName) - { -- super(weightIn, qualityIn, conditionsIn); -+ super(weightIn, qualityIn, conditionsIn, entryName); - this.table = tableIn; - } - -@@ -38,7 +38,8 @@ - JsonObject object, JsonDeserializationContext deserializationContext, int weightIn, int qualityIn, LootCondition[] conditionsIn - ) - { -+ String name = net.minecraftforge.common.ForgeHooks.readLootEntryName(object, "loot_table"); - ResourceLocation resourcelocation = new ResourceLocation(JsonUtils.getString(object, "name")); -- return new LootEntryTable(resourcelocation, weightIn, qualityIn, conditionsIn); -+ return new LootEntryTable(resourcelocation, weightIn, qualityIn, conditionsIn, name); - } - } diff --git a/patches/minecraft/net/minecraft/world/storage/loot/LootPool.java.patch b/patches/minecraft/net/minecraft/world/storage/loot/LootPool.java.patch deleted file mode 100644 index d9d504643..000000000 --- a/patches/minecraft/net/minecraft/world/storage/loot/LootPool.java.patch +++ /dev/null @@ -1,114 +0,0 @@ ---- before/net/minecraft/world/storage/loot/LootPool.java -+++ after/net/minecraft/world/storage/loot/LootPool.java -@@ -21,17 +21,19 @@ - - public class LootPool - { -- private final LootEntry[] lootEntries; -- private final LootCondition[] poolConditions; -+ private final List lootEntries; -+ private final List poolConditions; - private RandomValueRange rolls; - private RandomValueRange bonusRolls; -+ private final String name; - -- public LootPool(LootEntry[] lootEntriesIn, LootCondition[] poolConditionsIn, RandomValueRange rollsIn, RandomValueRange bonusRollsIn) -+ public LootPool(LootEntry[] lootEntriesIn, LootCondition[] poolConditionsIn, RandomValueRange rollsIn, RandomValueRange bonusRollsIn, String name) - { -- this.lootEntries = lootEntriesIn; -- this.poolConditions = poolConditionsIn; -+ this.lootEntries = Lists.newArrayList(lootEntriesIn); -+ this.poolConditions = Lists.newArrayList(poolConditionsIn); - this.rolls = rollsIn; - this.bonusRolls = bonusRollsIn; -+ this.name = name; - } - - protected void createLootRoll(Collection stacks, Random rand, LootContext context) -@@ -84,23 +86,76 @@ - } - } - -+ //======================== FORGE START ============================================= -+ private boolean isFrozen = false; -+ public void freeze() -+ { -+ this.isFrozen = true; -+ } -+ public boolean isFrozen(){ return this.isFrozen; } -+ private void checkFrozen() -+ { -+ if (this.isFrozen()) -+ throw new RuntimeException("Attempted to modify LootPool after being frozen!"); -+ } -+ -+ public String getName(){ return this.name; } -+ public RandomValueRange getRolls() { return this.rolls; } -+ public RandomValueRange getBonusRolls() { return this.bonusRolls; } -+ public void setRolls (RandomValueRange v){ checkFrozen(); this.rolls = v; } -+ public void setBonusRolls(RandomValueRange v){ checkFrozen(); this.bonusRolls = v; } -+ -+ public LootEntry getEntry(String name) -+ { -+ for (LootEntry entry : this.lootEntries) -+ if (name.equals(entry.getEntryName())) -+ return entry; -+ return null; -+ } -+ public LootEntry removeEntry(String name) -+ { -+ checkFrozen(); -+ for (LootEntry entry : this.lootEntries) -+ { -+ if (name.equals(entry.getEntryName())) -+ { -+ this.lootEntries.remove(entry); -+ return entry; -+ } -+ } -+ return null; -+ } -+ public void addEntry(LootEntry entry) -+ { -+ checkFrozen(); -+ for (LootEntry e : this.lootEntries) -+ if (e == entry || e.getEntryName().equals(entry.getEntryName())) -+ throw new RuntimeException("Attempted to add a duplicate entry to pool: " + e.getEntryName()); -+ this.lootEntries.add(entry); -+ } -+ //TODO: Allow modifications of conditions? If so need a way to uniquely identify them. -+ //======================== FORGE END =============================================== -+ - public static class Serializer implements JsonDeserializer, JsonSerializer - { - public LootPool deserialize(JsonElement p_deserialize_1_, Type p_deserialize_2_, JsonDeserializationContext p_deserialize_3_) throws JsonParseException - { - JsonObject jsonobject = JsonUtils.getJsonObject(p_deserialize_1_, "loot pool"); -+ String name = net.minecraftforge.common.ForgeHooks.readPoolName(jsonobject); - LootEntry[] alootentry = JsonUtils.deserializeClass(jsonobject, "entries", p_deserialize_3_, LootEntry[].class); - LootCondition[] alootcondition = JsonUtils.deserializeClass(jsonobject, "conditions", new LootCondition[0], p_deserialize_3_, LootCondition[].class); - RandomValueRange randomvaluerange = JsonUtils.deserializeClass(jsonobject, "rolls", p_deserialize_3_, RandomValueRange.class); - RandomValueRange randomvaluerange1 = JsonUtils.deserializeClass( - jsonobject, "bonus_rolls", new RandomValueRange(0.0F, 0.0F), p_deserialize_3_, RandomValueRange.class - ); -- return new LootPool(alootentry, alootcondition, randomvaluerange, randomvaluerange1); -+ return new LootPool(alootentry, alootcondition, randomvaluerange, randomvaluerange1, name); - } - - public JsonElement serialize(LootPool p_serialize_1_, Type p_serialize_2_, JsonSerializationContext p_serialize_3_) - { - JsonObject jsonobject = new JsonObject(); -+ if (p_serialize_1_.name != null && !p_serialize_1_.name.startsWith("custom#")) -+ jsonobject.add("name", p_serialize_3_.serialize(p_serialize_1_.name)); - jsonobject.add("entries", p_serialize_3_.serialize(p_serialize_1_.lootEntries)); - jsonobject.add("rolls", p_serialize_3_.serialize(p_serialize_1_.rolls)); - -@@ -109,7 +164,7 @@ - jsonobject.add("bonus_rolls", p_serialize_3_.serialize(p_serialize_1_.bonusRolls)); - } - -- if (!ArrayUtils.isEmpty((Object[])p_serialize_1_.poolConditions)) -+ if (!p_serialize_1_.poolConditions.isEmpty()) - { - jsonobject.add("conditions", p_serialize_3_.serialize(p_serialize_1_.poolConditions)); - } diff --git a/patches/minecraft/net/minecraft/world/storage/loot/LootTable.java.patch b/patches/minecraft/net/minecraft/world/storage/loot/LootTable.java.patch deleted file mode 100644 index fd34c68e8..000000000 --- a/patches/minecraft/net/minecraft/world/storage/loot/LootTable.java.patch +++ /dev/null @@ -1,75 +0,0 @@ ---- before/net/minecraft/world/storage/loot/LootTable.java -+++ after/net/minecraft/world/storage/loot/LootTable.java -@@ -24,11 +24,11 @@ - { - private static final Logger LOGGER = LogManager.getLogger(); - public static final LootTable EMPTY_LOOT_TABLE = new LootTable(new LootPool[0]); -- private final LootPool[] pools; -+ private final List pools; - - public LootTable(LootPool[] poolsIn) - { -- this.pools = poolsIn; -+ this.pools = Lists.newArrayList(poolsIn); - } - - public List generateLootForPools(Random rand, LootContext context) -@@ -143,6 +143,58 @@ - Collections.shuffle(list, rand); - return list; - } -+ -+ //======================== FORGE START ============================================= -+ private boolean isFrozen = false; -+ public void freeze() -+ { -+ this.isFrozen = true; -+ for (LootPool pool : this.pools) -+ pool.freeze(); -+ } -+ public boolean isFrozen(){ return this.isFrozen; } -+ private void checkFrozen() -+ { -+ if (this.isFrozen()) -+ throw new RuntimeException("Attempted to modify LootTable after being finalized!"); -+ } -+ -+ public LootPool getPool(String name) -+ { -+ for (LootPool pool : this.pools) -+ { -+ if (name.equals(pool.getName())) -+ return pool; -+ } -+ return null; -+ } -+ -+ public LootPool removePool(String name) -+ { -+ checkFrozen(); -+ for (LootPool pool : this.pools) -+ { -+ if (name.equals(pool.getName())) -+ { -+ this.pools.remove(pool); -+ return pool; -+ } -+ } -+ -+ return null; -+ } -+ -+ public void addPool(LootPool pool) -+ { -+ checkFrozen(); -+ for (LootPool p : this.pools) -+ { -+ if (p == pool || p.getName().equals(pool.getName())) -+ throw new RuntimeException("Attempted to add a duplicate pool to loot table: " + pool.getName()); -+ } -+ this.pools.add(pool); -+ } -+ //======================== FORGE END =============================================== - - public static class Serializer implements JsonDeserializer, JsonSerializer - { diff --git a/patches/minecraft/net/minecraft/world/storage/loot/LootTableManager.java.patch b/patches/minecraft/net/minecraft/world/storage/loot/LootTableManager.java.patch deleted file mode 100644 index 9bc6ac4df..000000000 --- a/patches/minecraft/net/minecraft/world/storage/loot/LootTableManager.java.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- before/net/minecraft/world/storage/loot/LootTableManager.java -+++ after/net/minecraft/world/storage/loot/LootTableManager.java -@@ -119,7 +119,7 @@ - - try - { -- return JsonUtils.gsonDeserialize(LootTableManager.GSON_INSTANCE, s, LootTable.class); -+ return net.minecraftforge.common.ForgeHooks.loadLootTable(LootTableManager.GSON_INSTANCE, resource, s, true, LootTableManager.this); - } - catch (IllegalArgumentException | JsonParseException jsonparseexception) - { -@@ -161,7 +161,7 @@ - - try - { -- return JsonUtils.gsonDeserialize(LootTableManager.GSON_INSTANCE, s, LootTable.class); -+ return net.minecraftforge.common.ForgeHooks.loadLootTable(LootTableManager.GSON_INSTANCE, resource, s, false, LootTableManager.this); - } - catch (JsonParseException jsonparseexception) - { diff --git a/patches/minecraft/net/minecraft/world/storage/loot/conditions/LootConditionManager.java.patch b/patches/minecraft/net/minecraft/world/storage/loot/conditions/LootConditionManager.java.patch deleted file mode 100644 index db8106b40..000000000 --- a/patches/minecraft/net/minecraft/world/storage/loot/conditions/LootConditionManager.java.patch +++ /dev/null @@ -1,18 +0,0 @@ ---- before/net/minecraft/world/storage/loot/conditions/LootConditionManager.java -+++ after/net/minecraft/world/storage/loot/conditions/LootConditionManager.java -@@ -42,6 +42,15 @@ - } - } - -+ public static boolean testAllConditions(Iterable conditions, Random rand, LootContext context) -+ { -+ if (conditions == null) return true; -+ for (LootCondition cond : conditions) -+ if (!cond.testCondition(rand, context)) -+ return false; -+ return true; -+ } -+ - public static boolean testAllConditions(@Nullable LootCondition[] conditions, Random rand, LootContext context) - { - if (conditions == null) diff --git a/patches/minecraft/net/minecraft/world/storage/loot/conditions/RandomChanceWithLooting.java.patch b/patches/minecraft/net/minecraft/world/storage/loot/conditions/RandomChanceWithLooting.java.patch deleted file mode 100644 index c8dcbc334..000000000 --- a/patches/minecraft/net/minecraft/world/storage/loot/conditions/RandomChanceWithLooting.java.patch +++ /dev/null @@ -1,16 +0,0 @@ ---- before/net/minecraft/world/storage/loot/conditions/RandomChanceWithLooting.java -+++ after/net/minecraft/world/storage/loot/conditions/RandomChanceWithLooting.java -@@ -24,12 +24,7 @@ - @Override - public boolean testCondition(Random rand, LootContext context) - { -- int i = 0; -- -- if (context.getKiller() instanceof EntityLivingBase) -- { -- i = EnchantmentHelper.getLootingModifier((EntityLivingBase)context.getKiller()); -- } -+ int i = context.getLootingModifier(); - - return rand.nextFloat() < this.chance + i * this.lootingMultiplier; - } diff --git a/patches/minecraft/net/minecraft/world/storage/loot/functions/LootingEnchantBonus.java.patch b/patches/minecraft/net/minecraft/world/storage/loot/functions/LootingEnchantBonus.java.patch deleted file mode 100644 index 2a3e992a3..000000000 --- a/patches/minecraft/net/minecraft/world/storage/loot/functions/LootingEnchantBonus.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- before/net/minecraft/world/storage/loot/functions/LootingEnchantBonus.java -+++ after/net/minecraft/world/storage/loot/functions/LootingEnchantBonus.java -@@ -33,7 +33,7 @@ - - if (entity instanceof EntityLivingBase) - { -- int i = EnchantmentHelper.getLootingModifier((EntityLivingBase)entity); -+ int i = context.getLootingModifier(); - - if (i == 0) - { From 3556a66809dc6c43008d55bee8b2766557de492e Mon Sep 17 00:00:00 2001 From: Rongmario Date: Tue, 18 Aug 2026 16:54:28 +0100 Subject: [PATCH 53/99] Fixed mouse deltas not resetting on explicit grab --- .../java/com/cleanroommc/client/input/LegacyInputQueues.java | 5 +++++ .../src/main/java/com/cleanroommc/client/input/Window.java | 2 ++ 2 files changed, 7 insertions(+) diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/input/LegacyInputQueues.java b/module/cleanroom/src/main/java/com/cleanroommc/client/input/LegacyInputQueues.java index cdf3273b0..7c23a9af0 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/input/LegacyInputQueues.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/input/LegacyInputQueues.java @@ -113,6 +113,11 @@ synchronized int queuedMice() { return this.mice.size(); } + synchronized void resetDeltas() { + this.deltaX = 0.0; + this.deltaY = 0.0; + } + synchronized float takeDeltaX() { float value = (float) this.deltaX; this.deltaX = 0.0; diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/input/Window.java b/module/cleanroom/src/main/java/com/cleanroommc/client/input/Window.java index 76d2b5bec..b85bf3c09 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/input/Window.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/input/Window.java @@ -416,6 +416,8 @@ synchronized void grabMouse(boolean grab) { this.ensureOpen(); SDL.check(SDLMouse.SDL_SetWindowRelativeMouseMode(handle, grab), "SDL_SetWindowRelativeMouseMode"); this.mouseGrabbed = grab; + this.legacy.resetDeltas(); + this.mouseWarped = true; } synchronized boolean mouseGrabbed() { From 0dbbef86a12967c824cf51de9fac448fc70013b7 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Wed, 19 Aug 2026 02:18:34 +0100 Subject: [PATCH 54/99] Update CG, start using Versioning + TokenEnvoy --- build.gradle | 34 ++++++------------- gradle.properties | 3 +- .../common/CleanroomContainer.java | 4 +-- .../cleanroommc/common/CleanroomVersion.java | 19 +++++++++++ settings.gradle | 4 +-- 5 files changed, 34 insertions(+), 30 deletions(-) create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/common/CleanroomVersion.java diff --git a/build.gradle b/build.gradle index 01ceb63cd..5cba64748 100644 --- a/build.gradle +++ b/build.gradle @@ -1,12 +1,13 @@ plugins { id 'java-library' id 'com.cleanroommc.cleanroomgradle' + id 'com.cleanroommc.versioning' version '2.0.0' + id 'com.cleanroommc.tokenenvoy' version '1.1.0' id 'idea' id 'maven-publish' } group = 'com.cleanroommc' -com.cleanroommc.gradle.api.Versioning.apply(project) java { toolchain.languageVersion = JavaLanguageVersion.of(providers.gradleProperty('java_major').get()) @@ -21,10 +22,16 @@ idea { } cleanroom { - loaderProject = true + mode = 'loader' accessTransformers.from file('module/forge/src/main/resources/forge_at.cfg') } +tokenEnvoy { + set 'VERSION', project.version + set 'ID', 'cleanroom' + set 'BUILD', versioning.computed +} + def modules = [ 'minecraft', 'forge', @@ -34,22 +41,9 @@ def modules = [ 'builtin/configanytime' ] -def generatedVersionRoot = layout.buildDirectory.dir('generated/sources/version/java') -def generateCleanroomVersion = tasks.register('generateCleanroomVersion', Copy) { - def shortVersion = version.toString().replaceFirst(/\+.*$/, '') - def fullVersion = version.toString() - inputs.property('shortVersion', shortVersion) - inputs.property('fullVersion', fullVersion) - from 'templates/CleanroomVersion.java' - into generatedVersionRoot.map { it.dir('com/cleanroommc/common') } - filter { it.replace('%VERSION%', shortVersion).replace('%BUILD_VERSION%', fullVersion) } - filteringCharset = 'UTF-8' -} - sourceSets { main { java.srcDirs = modules.collect { "module/${it}/src/main/java" } - java.srcDir files(generatedVersionRoot).builtBy(generateCleanroomVersion) // Fixme: Temp java.exclude 'com/cleanroommc/kirino/utils/KsmlcUtils.java' resources.srcDirs = modules.collect { "module/${it}/src/main/resources" } @@ -218,13 +212,6 @@ dependencies { testRuntimeOnly 'org.junit.platform:junit-platform-launcher' } -tasks.register('printVersion') { - group = 'help' - description = 'Prints the computed project version.' - def v = version.toString() - doLast { println v } -} - tasks.named('test', Test) { maxParallelForks = 1 useJUnitPlatform() @@ -233,7 +220,6 @@ tasks.named('test', Test) { } tasks.named('compileJava', JavaCompile).configure { compile -> - dependsOn generateCleanroomVersion def v = version.toString() doFirst { logger.lifecycle("Cleanroom ${v}") @@ -250,7 +236,7 @@ publishing { repositories { maven { name = 'CleanroomMaven' - url = 'https://repo.cleanroommc.com/releases' + url = 'https://maven.cleanroommc.com' credentials(PasswordCredentials) authentication { basic(BasicAuthentication) diff --git a/gradle.properties b/gradle.properties index 02ef029c6..62de2125f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,6 @@ # Project version = 0.6.10 -# Stage only accepts 'alpha', 'beta', 'rc' or 'release' -version_stage = alpha +versioning.stage = alpha java_major = 25 # Libraries diff --git a/module/cleanroom/src/main/java/com/cleanroommc/common/CleanroomContainer.java b/module/cleanroom/src/main/java/com/cleanroommc/common/CleanroomContainer.java index 5d424de1d..322e9096d 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/common/CleanroomContainer.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/common/CleanroomContainer.java @@ -15,13 +15,13 @@ public class CleanroomContainer extends DummyModContainer { public CleanroomContainer() { super(new ModMetadata()); ModMetadata meta = this.getMetadata(); - meta.modId = "cleanroom"; + meta.modId = CleanroomVersion.MOD_ID; meta.name = "Cleanroom"; meta.description = """ Cleanroom is a 1.12.2 Forge fork, providing newer toolchain, new APIs and 99% compatibility. Our plan is to make 1.12.2 up-to-date with latest toolchain while adding more feature to Forge & vanilla, so we don't need to care about higher versions' X point release * Y Mod API headache. """; - meta.version = CleanroomVersion.VERSION; + meta.version = CleanroomVersion.getVersion(); meta.authorList = Arrays.asList("LexManos", "cpw", "fry", "Rongmario", "kappa_maintainer", "Li"); meta.credits = "MrCrayFish for the Catalogue mod as base for the revamped mod list."; meta.url = "https://cleanroommc.com"; diff --git a/module/cleanroom/src/main/java/com/cleanroommc/common/CleanroomVersion.java b/module/cleanroom/src/main/java/com/cleanroommc/common/CleanroomVersion.java new file mode 100644 index 000000000..ca2ed919e --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/common/CleanroomVersion.java @@ -0,0 +1,19 @@ +package com.cleanroommc.common; + +public final class CleanroomVersion { + + public static final String VERSION = "@VERSION"; + public static final String BUILD_VERSION = "@BUILD"; + public static final String MOD_ID = "@ID"; + + public static String getVersion() { + return "@VERSION"; + } + + public static String getBuildVersion() { + return "@BUILD"; + } + + private CleanroomVersion() { } + +} diff --git a/settings.gradle b/settings.gradle index 8f40a0e65..23dd48d59 100644 --- a/settings.gradle +++ b/settings.gradle @@ -2,7 +2,7 @@ pluginManagement { repositories { maven { name = 'CleanroomMC' - url = 'https://repo.cleanroommc.com/releases' + url = 'https://maven.cleanroommc.com' } // MinecraftForge hosts CleanroomGradle's transitive plugin deps (srgutils + renamer-gradle). maven { @@ -14,5 +14,5 @@ pluginManagement { } plugins { - id 'com.cleanroommc.cleanroomgradle.settings' version '0.7.0' + id 'com.cleanroommc.cleanroomgradle.settings' version '0.8.1' } From a1be8a0c5e700c44e3b1daf9f8c7d9df993f3fdc Mon Sep 17 00:00:00 2001 From: Rongmario Date: Wed, 19 Aug 2026 02:26:34 +0100 Subject: [PATCH 55/99] Move `input` => `sdl` --- .../client/{input => sdl}/CleanroomWindowBridge.java | 2 +- .../client/{input => sdl}/LegacyInputQueues.java | 2 +- .../java/com/cleanroommc/client/{input => sdl}/SDL.java | 2 +- .../client/{input => sdl}/SharedGLContext.java | 2 +- .../com/cleanroommc/client/{input => sdl}/Window.java | 2 +- .../net/minecraftforge/client/ForgeClientHandler.java | 2 +- .../java/net/minecraftforge/client/ForgeHooksClient.java | 3 +-- .../net/minecraftforge/fml/client/SplashProgress.java | 4 ++-- .../patches/net/minecraft/client/Minecraft.java.patch | 8 ++++---- .../net/minecraft/client/gui/GuiTextField.java.patch | 2 +- 10 files changed, 14 insertions(+), 15 deletions(-) rename module/cleanroom/src/main/java/com/cleanroommc/client/{input => sdl}/CleanroomWindowBridge.java (99%) rename module/cleanroom/src/main/java/com/cleanroommc/client/{input => sdl}/LegacyInputQueues.java (99%) rename module/cleanroom/src/main/java/com/cleanroommc/client/{input => sdl}/SDL.java (98%) rename module/cleanroom/src/main/java/com/cleanroommc/client/{input => sdl}/SharedGLContext.java (98%) rename module/cleanroom/src/main/java/com/cleanroommc/client/{input => sdl}/Window.java (99%) diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/input/CleanroomWindowBridge.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/CleanroomWindowBridge.java similarity index 99% rename from module/cleanroom/src/main/java/com/cleanroommc/client/input/CleanroomWindowBridge.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/sdl/CleanroomWindowBridge.java index 25ae963d7..da119a31f 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/input/CleanroomWindowBridge.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/CleanroomWindowBridge.java @@ -1,4 +1,4 @@ -package com.cleanroommc.client.input; +package com.cleanroommc.client.sdl; import com.cleanroommc.lwjgly.LWJGLY; import com.cleanroommc.lwjgly.spi.WindowBridge; diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/input/LegacyInputQueues.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/LegacyInputQueues.java similarity index 99% rename from module/cleanroom/src/main/java/com/cleanroommc/client/input/LegacyInputQueues.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/sdl/LegacyInputQueues.java index 7c23a9af0..fee0ad295 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/input/LegacyInputQueues.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/LegacyInputQueues.java @@ -1,4 +1,4 @@ -package com.cleanroommc.client.input; +package com.cleanroommc.client.sdl; import com.cleanroommc.lwjgly.spi.WindowBridge; diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/input/SDL.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SDL.java similarity index 98% rename from module/cleanroom/src/main/java/com/cleanroommc/client/input/SDL.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SDL.java index 4e82a0fb9..098e2c8b5 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/input/SDL.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SDL.java @@ -1,4 +1,4 @@ -package com.cleanroommc.client.input; +package com.cleanroommc.client.sdl; import org.lwjgl.sdl.SDLError; import org.lwjgl.sdl.SDLInit; diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/input/SharedGLContext.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SharedGLContext.java similarity index 98% rename from module/cleanroom/src/main/java/com/cleanroommc/client/input/SharedGLContext.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SharedGLContext.java index 5045410d0..c3ec2244c 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/input/SharedGLContext.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SharedGLContext.java @@ -1,4 +1,4 @@ -package com.cleanroommc.client.input; +package com.cleanroommc.client.sdl; import org.lwjgl.opengl.GL; import org.lwjgl.opengl.GLCapabilities; diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/input/Window.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Window.java similarity index 99% rename from module/cleanroom/src/main/java/com/cleanroommc/client/input/Window.java rename to module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Window.java index b85bf3c09..f07f5c282 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/input/Window.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Window.java @@ -1,4 +1,4 @@ -package com.cleanroommc.client.input; +package com.cleanroommc.client.sdl; import com.cleanroommc.lwjgly.spi.WindowBridge; import org.lwjgl.opengl.GL; diff --git a/module/forge/src/main/java/net/minecraftforge/client/ForgeClientHandler.java b/module/forge/src/main/java/net/minecraftforge/client/ForgeClientHandler.java index 002044b84..acda739a8 100644 --- a/module/forge/src/main/java/net/minecraftforge/client/ForgeClientHandler.java +++ b/module/forge/src/main/java/net/minecraftforge/client/ForgeClientHandler.java @@ -19,7 +19,7 @@ package net.minecraftforge.client; -import com.cleanroommc.client.input.Window; +import com.cleanroommc.client.sdl.Window; import com.cleanroommc.client.modlist.LegacyModListScreen; import com.cleanroommc.client.modlist.ModListConfig; import com.cleanroommc.client.modlist.ModListConstants; diff --git a/module/forge/src/main/java/net/minecraftforge/client/ForgeHooksClient.java b/module/forge/src/main/java/net/minecraftforge/client/ForgeHooksClient.java index 7f985f98c..6329a9cc1 100644 --- a/module/forge/src/main/java/net/minecraftforge/client/ForgeHooksClient.java +++ b/module/forge/src/main/java/net/minecraftforge/client/ForgeHooksClient.java @@ -38,7 +38,7 @@ import javax.vecmath.Vector4f; import com.cleanroommc.client.LoadingTracker; -import com.cleanroommc.client.input.Window; +import com.cleanroommc.client.sdl.Window; import com.cleanroommc.client.windows.DwmApi; import com.cleanroommc.client.windows.NtDll; import com.cleanroommc.client.windows.TaskbarApi; @@ -149,7 +149,6 @@ import org.apache.logging.log4j.core.async.ThreadNameCachingStrategy; import org.apache.logging.log4j.core.impl.ReusableLogEventFactory; import org.lwjgl.BufferUtils; -import org.lwjgl.opengl.Display; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL20; diff --git a/module/forge/src/main/java/net/minecraftforge/fml/client/SplashProgress.java b/module/forge/src/main/java/net/minecraftforge/fml/client/SplashProgress.java index ab0d23cb3..69876b023 100644 --- a/module/forge/src/main/java/net/minecraftforge/fml/client/SplashProgress.java +++ b/module/forge/src/main/java/net/minecraftforge/fml/client/SplashProgress.java @@ -22,8 +22,8 @@ import static org.lwjgl.opengl.GL11.*; import static org.lwjgl.opengl.GL12.*; -import com.cleanroommc.client.input.SharedGLContext; -import com.cleanroommc.client.input.Window; +import com.cleanroommc.client.sdl.SharedGLContext; +import com.cleanroommc.client.sdl.Window; import java.awt.image.BufferedImage; import java.io.File; diff --git a/module/minecraft/patches/net/minecraft/client/Minecraft.java.patch b/module/minecraft/patches/net/minecraft/client/Minecraft.java.patch index 951987850..2f5467ff6 100644 --- a/module/minecraft/patches/net/minecraft/client/Minecraft.java.patch +++ b/module/minecraft/patches/net/minecraft/client/Minecraft.java.patch @@ -21,8 +21,8 @@ this.displayHeight = this.gameSettings.overrideHeight; } - -+ com.cleanroommc.client.input.Window window = com.cleanroommc.client.input.Window.builder().title("Cleanroom").size(this.displayWidth, this.displayHeight).resizable().vsync(this.gameSettings.enableVsync).openGL().build(); -+ com.cleanroommc.client.input.CleanroomWindowBridge.install(window); ++ com.cleanroommc.client.sdl.Window window = com.cleanroommc.client.sdl.Window.builder().title("Cleanroom").size(this.displayWidth, this.displayHeight).resizable().vsync(this.gameSettings.enableVsync).openGL().build(); ++ com.cleanroommc.client.sdl.CleanroomWindowBridge.install(window); LOGGER.info("LWJGL Version: {}", Sys.getVersion()); this.setWindowIcon(); this.setInitialDisplayMode(); @@ -210,7 +210,7 @@ this.soundHandler.unloadSounds(); } finally { + com.cleanroommc.kirino.engine.ShutdownManager.runMainHooks(); -+ com.cleanroommc.client.input.SDL.shutdown(); ++ com.cleanroommc.client.sdl.SDL.shutdown(); Display.destroy(); if (!this.hasCrashed) { System.exit(0); @@ -281,7 +281,7 @@ /** Toggles fullscreen mode. */ public void toggleFullscreen() { + if (net.minecraftforge.common.ForgeEarlyConfig.WINDOW_BORDERLESS_REPLACES_FULLSCREEN) { -+ com.cleanroommc.client.input.Window window = com.cleanroommc.client.input.Window.main(); ++ com.cleanroommc.client.sdl.Window window = com.cleanroommc.client.sdl.Window.main(); + if (window != null) window.borderless(!window.borderless()); + return; + } diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiTextField.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiTextField.java.patch index c51f10a12..5cf52746f 100644 --- a/module/minecraft/patches/net/minecraft/client/gui/GuiTextField.java.patch +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiTextField.java.patch @@ -4,7 +4,7 @@ } this.isFocused = isFocusedIn; -+ com.cleanroommc.client.input.Window window = com.cleanroommc.client.input.Window.main(); ++ com.cleanroommc.client.sdl.Window window = com.cleanroommc.client.sdl.Window.main(); + if (window != null) { + window.textInput(this.isFocused); + } From f33e61af1fb7fb34ed7a99ae434790feef9cbbac Mon Sep 17 00:00:00 2001 From: Rongmario Date: Wed, 19 Aug 2026 02:29:03 +0100 Subject: [PATCH 56/99] Catchup Kirino module --- module/kirino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/kirino b/module/kirino index b629d0ada..9c4fbf931 160000 --- a/module/kirino +++ b/module/kirino @@ -1 +1 @@ -Subproject commit b629d0ada714e41aeafb7d43ccdbb9c85ecb8a58 +Subproject commit 9c4fbf931fb5627b83d3b81daad3d83d052949ec From 11690db0283068693080b85fa888d0a43d85f751 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Wed, 19 Aug 2026 03:53:32 +0100 Subject: [PATCH 57/99] SDL Text API, includes IME func --- .../java/com/cleanroommc/client/sdl/SDL.java | 5 + .../com/cleanroommc/client/sdl/Window.java | 32 +- .../sdl/input/virtual/InputCandidates.java | 20 ++ .../client/sdl/input/virtual/Text.java | 280 ++++++++++++++++++ .../sdl/input/virtual/TextComposition.java | 20 ++ .../sdl/input/virtual/TextInputKind.java | 27 ++ .../client/ForgeClientHandler.java | 3 +- 7 files changed, 378 insertions(+), 9 deletions(-) create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/virtual/InputCandidates.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/virtual/Text.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/virtual/TextComposition.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/virtual/TextInputKind.java diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SDL.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SDL.java index 098e2c8b5..040ab47ac 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SDL.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SDL.java @@ -1,5 +1,6 @@ package com.cleanroommc.client.sdl; +import com.cleanroommc.client.sdl.input.virtual.Text; import org.lwjgl.sdl.SDLError; import org.lwjgl.sdl.SDLInit; @@ -29,6 +30,10 @@ public static synchronized void ensureSubsystem(int flags) { if (missing == 0) { return; } + // TODO: services to load when initializing subsystem? + if ((missing & SDLInit.SDL_INIT_VIDEO) != 0) { + Text.implementIME(true, true); + } initializedBits |= missing; check(SDLInit.SDL_InitSubSystem(missing), "SDL_InitSubSystem"); } diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Window.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Window.java index f07f5c282..781a078ca 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Window.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Window.java @@ -1,8 +1,8 @@ package com.cleanroommc.client.sdl; +import com.cleanroommc.client.sdl.input.virtual.Text; import com.cleanroommc.lwjgly.spi.WindowBridge; import org.lwjgl.opengl.GL; -import org.lwjgl.sdl.SDLKeyboard; import org.lwjgl.sdl.SDLMouse; import org.lwjgl.sdl.SDLProperties; import org.lwjgl.sdl.SDLVideo; @@ -12,6 +12,8 @@ import org.lwjgl.sdl.SDL_MouseButtonEvent; import org.lwjgl.sdl.SDL_MouseMotionEvent; import org.lwjgl.sdl.SDL_MouseWheelEvent; +import org.lwjgl.sdl.SDL_TextEditingCandidatesEvent; +import org.lwjgl.sdl.SDL_TextEditingEvent; import org.lwjgl.sdl.SDL_TextInputEvent; import org.lwjgl.sdl.SDL_WindowEvent; import org.lwjgl.system.MemoryStack; @@ -32,6 +34,7 @@ public final class Window implements AutoCloseable { private final long glContext; private final int id; private final LegacyInputQueues legacy = new LegacyInputQueues(); + private final Text text = new Text(this); private final boolean[] keys = new boolean[MAX_SCANCODES]; private final boolean[] buttons = new boolean[MAX_MOUSE_BUTTONS + 1]; @@ -220,14 +223,12 @@ public Window swapBuffers() { return this; } + public Text text() { + return this.text; + } + public Window textInput(boolean enabled) { - this.ensureOpen(); - boolean active = SDLKeyboard.SDL_TextInputActive(this.handle); - if (enabled && !active) { - SDL.check(SDLKeyboard.SDL_StartTextInput(this.handle), "SDL_StartTextInput"); - } else if (!enabled && active) { - SDL.check(SDLKeyboard.SDL_StopTextInput(this.handle), "SDL_StopTextInput"); - } + this.text.active(enabled); return this; } @@ -250,6 +251,8 @@ private void dispatch(SDL_Event event) { case SDLEvents.SDL_EVENT_QUIT -> closeRequested = true; case SDLEvents.SDL_EVENT_KEY_DOWN, SDLEvents.SDL_EVENT_KEY_UP -> key(event.key()); case SDLEvents.SDL_EVENT_TEXT_INPUT -> text(event.text()); + case SDLEvents.SDL_EVENT_TEXT_EDITING -> editing(event.edit()); + case SDLEvents.SDL_EVENT_TEXT_EDITING_CANDIDATES -> editingCandidates(event.edit_candidates()); case SDLEvents.SDL_EVENT_MOUSE_MOTION -> motion(event.motion()); case SDLEvents.SDL_EVENT_MOUSE_BUTTON_DOWN, SDLEvents.SDL_EVENT_MOUSE_BUTTON_UP -> button(event.button()); case SDLEvents.SDL_EVENT_MOUSE_WHEEL -> wheel(event.wheel()); @@ -280,10 +283,23 @@ private void key(SDL_KeyboardEvent event) { private void text(SDL_TextInputEvent event) { if (event.windowID() == this.id) { + this.text.committed(); this.legacy.text(event.textString(), event.timestamp()); } } + private void editing(SDL_TextEditingEvent event) { + if (event.windowID() == this.id) { + this.text.editing(event); + } + } + + private void editingCandidates(SDL_TextEditingCandidatesEvent event) { + if (event.windowID() == this.id) { + this.text.editingCandidates(event); + } + } + private void motion(SDL_MouseMotionEvent event) { if (event.windowID() != this.id) { return; diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/virtual/InputCandidates.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/virtual/InputCandidates.java new file mode 100644 index 000000000..dcba732e9 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/virtual/InputCandidates.java @@ -0,0 +1,20 @@ +package com.cleanroommc.client.sdl.input.virtual; + +import java.util.List; + +/** + * The candidate list for an input method. + * + * @param entries the candidates, in the input method's order + * @param selected the index into {@code entries} the input method has highlighted, or -1 otherwise + * @param horizontal whether the input method wants a horizontal or vertical list + */ +public record InputCandidates(List entries, int selected, boolean horizontal) { + + public static final InputCandidates NONE = new InputCandidates(List.of(), -1, false); + + public boolean active() { + return !this.entries.isEmpty(); + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/virtual/Text.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/virtual/Text.java new file mode 100644 index 000000000..b04f00c10 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/virtual/Text.java @@ -0,0 +1,280 @@ +package com.cleanroommc.client.sdl.input.virtual; + +import com.cleanroommc.client.sdl.SDL; +import com.cleanroommc.client.sdl.Window; +import org.lwjgl.PointerBuffer; +import org.lwjgl.sdl.SDLHints; +import org.lwjgl.sdl.SDLInit; +import org.lwjgl.sdl.SDLKeyboard; +import org.lwjgl.sdl.SDLProperties; +import org.lwjgl.sdl.SDL_Rect; +import org.lwjgl.sdl.SDL_TextEditingCandidatesEvent; +import org.lwjgl.sdl.SDL_TextEditingEvent; +import org.lwjgl.system.MemoryStack; +import org.lwjgl.system.MemoryUtil; + +import java.nio.IntBuffer; +import java.util.List; + +/** + * A window's text input with input method editor integration. + * Whether a field wants typed text, field type, where the caret sits, and what is being composed can be found here. + * + *

Retrieve the instance from {@link Window#text()}. + * Text input has to be off when text fields aren't in focus. + * Or it will swallow keystrokes meant for movement or other contexts. + */ +public final class Text { + + /** + * The field's rectangle in window coordinates, and the caret's offset from the rectangle's left edge. + * + * @param x left edge + * @param y top edge + * @param width width + * @param height height + * @param cursor caret offset from {@code x}, in window coordinates + */ + public record Area(int x, int y, int width, int height, int cursor) { } + + /** + * Tells SDL which parts of the input method editor's interface the game draws itself. + * + *

This is a hint, so it has to be set before the video subsystem comes up. + * + * @param composition whether the game draws the preedit text at the caret + * @param candidates whether the game draws the candidate list + */ + public static synchronized void implementIME(boolean composition, boolean candidates) { + if (SDL.isInitialized(SDLInit.SDL_INIT_VIDEO)) { + throw new IllegalStateException("SDL's video subsystem had been initialized already. The IME hint would be ignored."); + } + StringBuilder value = new StringBuilder(); + if (composition) { + value.append("composition"); + } + if (candidates) { + if (!value.isEmpty()) { + value.append(','); + } + value.append("candidates"); + } + SDL.check(SDLHints.SDL_SetHint(SDLHints.SDL_HINT_IME_IMPLEMENTED_UI, value.toString()), "SDL_SetHint(SDL_HINT_IME_IMPLEMENTED_UI)"); + } + + /** + * @return whether this platform can show an on-screen keyboard + */ + public static boolean screenKeyboardSupported() { + return SDLKeyboard.SDL_HasScreenKeyboardSupport(); + } + + private final Window window; + + private TextInputKind kind = TextInputKind.TEXT; + private TextComposition composition = TextComposition.NONE; + private InputCandidates candidates = InputCandidates.NONE; + + /** + * Attaches these helpers to {@code window}. Prefer {@link Window#text()}. + */ + public Text(Window window) { + if (window == null) { + throw new IllegalStateException("The SDL window does not exist"); + } + this.window = window; + } + + /** + * @return whether this window is accepting typed text and IME composition + */ + public synchronized boolean active() { + return SDLKeyboard.SDL_TextInputActive(this.handle()); + } + + /** + * Turns text input on or off for this window. + * + *

Leave this off when there are no focused text tields. + * Otherwise, SDL will swallow keys that should move the player or close the screen. + * + * @param enabled {@code true} to start accepting text, {@code false} to stop + */ + public synchronized Text active(boolean enabled) { + boolean active = this.active(); + if (enabled && !active) { + this.start(); + } else if (!enabled && active) { + this.stop(); + } + return this; + } + + /** + * @return the field type last given to {@link #kind(TextInputKind)} + */ + public synchronized TextInputKind kind() { + return this.kind; + } + + /** + * Tells the input method what kind of field is focused. + * + *

If text input is already running, it is restarted so the new type takes effect. + * + * @param kind the field type, such as plain text or a hidden password + */ + public synchronized Text kind(TextInputKind kind) { + if (kind == null) { + throw new IllegalArgumentException("Kind cannot be null"); + } + if (this.kind == kind) { + return this; + } + this.kind = kind; + if (this.active()) { + this.stop(); + this.start(); + } + return this; + } + + /** + * Tells the input method where the field and caret sit, in window coordinates. + * + *

Native candidate lists use this so they do not cover the text being typed. + * + * @param x left edge of the field + * @param y top edge of the field + * @param width field width + * @param height field height + * @param cursor caret offset from {@code x} + */ + public synchronized Text area(int x, int y, int width, int height, int cursor) { + try (MemoryStack stack = MemoryStack.stackPush()) { + SDL_Rect.Buffer rect = SDL_Rect.calloc(1, stack); + rect.x(x).y(y).w(width).h(height); + SDL.check(SDLKeyboard.SDL_SetTextInputArea(this.handle(), rect, cursor), "SDL_SetTextInputArea"); + } + return this; + } + + /** + * @return the field rectangle and caret last given to {@link #area(int, int, int, int, int)} + */ + public synchronized Area area() { + try (MemoryStack stack = MemoryStack.stackPush()) { + SDL_Rect.Buffer rect = SDL_Rect.calloc(1, stack); + IntBuffer cursor = stack.callocInt(1); + SDL.check(SDLKeyboard.SDL_GetTextInputArea(this.handle(), rect, cursor), "SDL_GetTextInputArea"); + return new Area(rect.x(), rect.y(), rect.w(), rect.h(), cursor.get(0)); + } + } + + /** + * Clears the field rectangle so the input method no longer has a caret to sit next to. + */ + public synchronized Text clearArea() { + SDL.check(SDLKeyboard.SDL_SetTextInputArea(this.handle(), null, 0), "SDL_SetTextInputArea"); + return this; + } + + /** + * @return the in-progress preedit, or {@link TextComposition#NONE} when nothing is being composed + */ + public synchronized TextComposition composition() { + return this.composition; + } + + /** + * @return the candidate list, or {@link InputCandidates#NONE} when the input method is not offering any + */ + public synchronized InputCandidates candidates() { + return this.candidates; + } + + /** + * Dismisses the current composition without committing it or turning text input off. + */ + public synchronized Text clearComposition() { + if (this.active()) { + SDL.check(SDLKeyboard.SDL_ClearComposition(this.handle()), "SDL_ClearComposition"); + } + this.reset(); + return this; + } + + /** + * Applies an {@code SDL_EVENT_TEXT_EDITING} event from the window's pump. + */ + public synchronized void editing(SDL_TextEditingEvent event) { + this.composition = composition(event); + if (!this.composition.active()) { + this.candidates = InputCandidates.NONE; + } + } + + /** + * Applies an {@code SDL_EVENT_TEXT_EDITING_CANDIDATES} event from the window's pump. + */ + public synchronized void editingCandidates(SDL_TextEditingCandidatesEvent event) { + this.candidates = candidates(event); + } + + /** + * Drops locally tracked composition after committed text arrives. + */ + public synchronized void committed() { + this.reset(); + } + + private long handle() { + return this.window.handle(); + } + + private void start() { + int props = SDLProperties.SDL_CreateProperties(); + SDL.check(props != 0, "SDL_CreateProperties"); + try { + SDL.check(SDLProperties.SDL_SetNumberProperty(props, SDLKeyboard.SDL_PROP_TEXTINPUT_TYPE_NUMBER, this.kind.value()), + "SDL_SetNumberProperty(" + SDLKeyboard.SDL_PROP_TEXTINPUT_TYPE_NUMBER + ")"); + SDL.check(SDLKeyboard.SDL_StartTextInputWithProperties(this.handle(), props), "SDL_StartTextInputWithProperties"); + } finally { + SDLProperties.SDL_DestroyProperties(props); + } + } + + private void stop() { + SDL.check(SDLKeyboard.SDL_StopTextInput(this.handle()), "SDL_StopTextInput"); + this.reset(); + } + + private void reset() { + this.composition = TextComposition.NONE; + this.candidates = InputCandidates.NONE; + } + + private static TextComposition composition(SDL_TextEditingEvent event) { + String text = event.textString(); + if (text == null || text.isEmpty()) { + return TextComposition.NONE; + } + return new TextComposition(text, event.start(), event.length()); + } + + private static InputCandidates candidates(SDL_TextEditingCandidatesEvent event) { + int count = event.num_candidates(); + PointerBuffer pointers = event.candidates(); + if (count <= 0 || pointers == null || !pointers.hasRemaining()) { + return InputCandidates.NONE; + } + int size = Math.min(count, pointers.remaining()); + String[] entries = new String[size]; + for (int i = 0; i < size; i++) { + String entry = MemoryUtil.memUTF8Safe(pointers.get(i)); + entries[i] = entry == null ? "" : entry; + } + return new InputCandidates(List.of(entries), event.selected_candidate(), event.horizontal()); + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/virtual/TextComposition.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/virtual/TextComposition.java new file mode 100644 index 000000000..327910c2d --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/virtual/TextComposition.java @@ -0,0 +1,20 @@ +package com.cleanroommc.client.sdl.input.virtual; + +/** + * In-progress text, which is not part of the text field's contents until it is committed. + * Renderers draw it at the caret, underlined, with {@code cursor} and {@code selectionLength} + * marking the clause that is being worked on. + * + * @param text the preedit string, empty when no composition is running + * @param cursor the caret's offset into {@code text}, or -1 when there is nothing being composed + * @param selectionLength how many characters after {@code cursor} the has been selected, or -1 otherwise + */ +public record TextComposition(String text, int cursor, int selectionLength) { + + public static final TextComposition NONE = new TextComposition("", -1, -1); + + public boolean active() { + return !this.text.isEmpty(); + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/virtual/TextInputKind.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/virtual/TextInputKind.java new file mode 100644 index 000000000..f45ee9894 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/virtual/TextInputKind.java @@ -0,0 +1,27 @@ +package com.cleanroommc.client.sdl.input.virtual; + +import org.lwjgl.sdl.SDLKeyboard; + +public enum TextInputKind { + + TEXT(SDLKeyboard.SDL_TEXTINPUT_TYPE_TEXT), + NAME(SDLKeyboard.SDL_TEXTINPUT_TYPE_TEXT_NAME), + EMAIL(SDLKeyboard.SDL_TEXTINPUT_TYPE_TEXT_EMAIL), + USERNAME(SDLKeyboard.SDL_TEXTINPUT_TYPE_TEXT_USERNAME), + PASSWORD_HIDDEN(SDLKeyboard.SDL_TEXTINPUT_TYPE_TEXT_PASSWORD_HIDDEN), + PASSWORD_VISIBLE(SDLKeyboard.SDL_TEXTINPUT_TYPE_TEXT_PASSWORD_VISIBLE), + NUMBER(SDLKeyboard.SDL_TEXTINPUT_TYPE_NUMBER), + NUMBER_PASSWORD_HIDDEN(SDLKeyboard.SDL_TEXTINPUT_TYPE_NUMBER_PASSWORD_HIDDEN), + NUMBER_PASSWORD_VISIBLE(SDLKeyboard.SDL_TEXTINPUT_TYPE_NUMBER_PASSWORD_VISIBLE); + + private final int value; + + TextInputKind(int value) { + this.value = value; + } + + int value() { + return this.value; + } + +} diff --git a/module/forge/src/main/java/net/minecraftforge/client/ForgeClientHandler.java b/module/forge/src/main/java/net/minecraftforge/client/ForgeClientHandler.java index acda739a8..0abb9f960 100644 --- a/module/forge/src/main/java/net/minecraftforge/client/ForgeClientHandler.java +++ b/module/forge/src/main/java/net/minecraftforge/client/ForgeClientHandler.java @@ -88,7 +88,8 @@ public static void onGuiOpen(GuiOpenEvent event) Window window = Window.main(); if (window != null) { - window.textInput(gui instanceof GuiScreenBook || gui instanceof GuiEditSign); + GuiScreen opened = event.getGui(); + window.text().active(opened instanceof GuiScreenBook || opened instanceof GuiEditSign); } } From 76dbece07565c971c50bc1a748ad7ca3a495a653 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Wed, 19 Aug 2026 11:16:21 +0100 Subject: [PATCH 58/99] IME support for editing signs, writing books and more --- .../com/cleanroommc/client/sdl/SDLHooks.java | 411 ++++++++++++++++++ .../client/ForgeClientHandler.java | 19 + .../minecraft/client/gui/GuiScreen.java.patch | 14 +- .../client/gui/GuiScreenBook.java.patch | 48 ++ .../client/gui/GuiTextField.java.patch | 23 +- .../gui/inventory/GuiEditSign.java.patch | 20 + .../TileEntitySignRenderer.java.patch | 11 + 7 files changed, 536 insertions(+), 10 deletions(-) create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SDLHooks.java create mode 100644 module/minecraft/patches/net/minecraft/client/gui/inventory/GuiEditSign.java.patch create mode 100644 module/minecraft/patches/net/minecraft/client/renderer/tileentity/TileEntitySignRenderer.java.patch diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SDLHooks.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SDLHooks.java new file mode 100644 index 000000000..a9a6ae73e --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SDLHooks.java @@ -0,0 +1,411 @@ +package com.cleanroommc.client.sdl; + +import com.cleanroommc.client.sdl.input.virtual.InputCandidates; +import com.cleanroommc.client.sdl.input.virtual.Text; +import com.cleanroommc.client.sdl.input.virtual.TextComposition; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.gui.GuiScreenBook; +import net.minecraft.client.gui.GuiTextField; +import net.minecraft.client.gui.inventory.GuiEditSign; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.tileentity.TileEntitySign; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TextComponentString; +import net.minecraft.util.text.TextFormatting; +import org.lwjgl.BufferUtils; +import org.lwjgl.input.Keyboard; +import org.lwjgl.opengl.GL11; +import org.lwjgl.util.glu.GLU; + +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.util.List; + +public final class SDLHooks { + + private static final int COMPOSITION_COLOR = 0xFFE0E0E0; + private static final int COMPOSITION_UNDERLINE = 0xFFE0E0E0; + private static final int COMPOSITION_SELECTION = 0x664080C0; + private static final int CANDIDATE_BACKGROUND = 0xC0101010; + private static final int CANDIDATE_SELECTED = 0xC04060A0; + private static final int CANDIDATE_TEXT = 0xFFE0E0E0; + private static final int CANDIDATE_PADDING = 2; + + private static FloatBuffer modelview; + private static FloatBuffer projection; + private static IntBuffer viewport; + private static FloatBuffer windowCoords; + private static int lastFieldX; + private static int lastFieldY; + private static int lastFieldWidth; + private static int lastFieldHeight; + private static boolean lastFieldSet; + + /** + * Places the native caret and draws composition plus candidates on a focused text field. + */ + public static void textFieldDraw(GuiTextField field) { + if (field == null || !field.getVisible() || !field.isFocused()) { + return; + } + Text text = text(); + if (text == null) { + return; + } + FontRenderer font = font(); + if (font == null) { + return; + } + int caretX = caretX(field, font); + int textY = textY(field); + area(field.x, field.y, field.width, field.height, caretX); + overlay(text, font, caretX, textY, field.getWidth() - (caretX - (field.getEnableBackgroundDrawing() ? field.x + 4 : field.x)), + field.x, field.y, field.width, field.height); + } + + /** + * Swallows keystrokes the input method is already using, and lets committed text through. + * + * @return {@code true} when vanilla should not see this key + */ + public static boolean keyboard(GuiScreen screen) { + if (screen == null) { + return false; + } + Text text = text(); + if (text == null || !busy(text)) { + return false; + } + int key = Keyboard.getEventKey(); + char character = Keyboard.getEventCharacter(); + if (key == 0 && character >= ' ') { + return false; + } + if (key == 1) { + text.clearComposition(); + } + return true; + } + + /** + * @return whether the input method currently has preedit text + */ + public static boolean composing() { + Text text = text(); + return text != null && text.composition().active(); + } + + /** + * @return what is being composed, underlined so it reads as text that is not committed yet, or empty + */ + public static String compositionUnderlined() { + Text text = text(); + String composition = text == null ? "" : text.composition().text(); + return composition.isEmpty() ? "" : TextFormatting.UNDERLINE + composition + TextFormatting.RESET; + } + + /** + * Points the input method at a caret expressed in GUI coordinates. + * + * @param x the field's left edge + * @param y the field's top edge + * @param width the field's width + * @param height the field's height, ideally one line so candidates land beneath the text + * @param cursorOffset the caret's offset from {@code x} + */ + public static void caret(int x, int y, int width, int height, int cursorOffset) { + remember(x, y, width, height); + area(x, y, width, height, x + cursorOffset); + } + + /** + * Lends the sign line being edited what is being composed, for the one frame it takes to draw. + * + * @return what the line held before, which the caller hands to {@link #takeComposition} once the sign is drawn + */ + public static ITextComponent lendComposition(TileEntitySign sign, int line) { + ITextComponent held = sign.signText[line]; + Text text = text(); + String composition = text == null ? "" : text.composition().text(); + if (!composition.isEmpty()) { + sign.signText[line] = new TextComponentString(held.getUnformattedText() + composition); + } + return held; + } + + /** + * Puts back the sign line {@link #lendComposition} took, once the sign has been drawn. + */ + public static void takeComposition(TileEntitySign sign, int line, ITextComponent held) { + sign.signText[line] = held; + } + + /** + * Draws the sign line being edited and projects its caret out of the matrices it was drawn with. + * Allowing the candidate list to follow a line that has no GUI rectangle of its own. + * + * @param text the line's text, without the arrows the edited line is marked with + * @param y the line's top edge, in the text space the sign renders its lines in + */ + public static void drawSignLineBeingEdited(FontRenderer fontRenderer, String text, int y) { + String leading = "> " + text; + String line = leading + " <"; + int width = fontRenderer.getStringWidth(line); + fontRenderer.drawString(line, -width / 2, y, 0); + caretProjected((float) -width / 2, y, width, fontRenderer.FONT_HEIGHT, fontRenderer.getStringWidth(leading)); + } + + /** + * Draws candidates for screens that do not use {@link GuiTextField}. + * Composition for those screens is drawn as part of the screen's own text. + */ + public static void draw(GuiScreen screen) { + if (screen == null || !lastFieldSet) { + return; + } + if (!(screen instanceof GuiScreenBook) && !(screen instanceof GuiEditSign)) { + return; + } + Text text = text(); + if (text == null || !text.active()) { + return; + } + FontRenderer font = font(); + if (font == null) { + return; + } + InputCandidates candidates = text.candidates(); + if (!candidates.active()) { + return; + } + if (screen instanceof GuiEditSign) { + GlStateManager.disableDepth(); + } + candidates(font, candidates, lastFieldX, lastFieldY, lastFieldWidth, lastFieldHeight); + if (screen instanceof GuiEditSign) { + GlStateManager.enableDepth(); + } + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + } + + private static Text text() { + Window window = Window.main(); + return window == null ? null : window.text(); + } + + private static FontRenderer font() { + Minecraft minecraft = Minecraft.getMinecraft(); + return minecraft == null ? null : minecraft.fontRenderer; + } + + private static boolean busy(Text text) { + return text.composition().active() || text.candidates().active(); + } + + private static int caretX(GuiTextField field, FontRenderer font) { + int x = field.getEnableBackgroundDrawing() ? field.x + 4 : field.x; + String contents = field.getText(); + int scroll = field.getLineScrollOffset(); + if (scroll < 0 || scroll > contents.length()) { + return x; + } + String visible = font.trimStringToWidth(contents.substring(scroll), field.getWidth()); + int relative = field.getCursorPosition() - scroll; + if (relative < 0) { + return x; + } + if (relative > visible.length()) { + relative = visible.length(); + } + return x + font.getStringWidth(visible.substring(0, relative)); + } + + private static int textY(GuiTextField field) { + return field.getEnableBackgroundDrawing() ? field.y + (field.height - 8) / 2 : field.y; + } + + private static void remember(int x, int y, int width, int height) { + lastFieldX = x; + lastFieldY = y; + lastFieldWidth = width; + lastFieldHeight = height; + lastFieldSet = true; + } + + private static void caretProjected(float x, float y, float width, float height, float cursorOffset) { + Text text = text(); + Window window = Window.main(); + if (text == null || window == null) { + return; + } + ensureProjectionBuffers(); + modelview.clear(); + projection.clear(); + viewport.clear(); + GL11.glGetFloatv(GL11.GL_MODELVIEW_MATRIX, modelview); + GL11.glGetFloatv(GL11.GL_PROJECTION_MATRIX, projection); + GL11.glGetIntegerv(GL11.GL_VIEWPORT, viewport); + modelview.rewind(); + projection.rewind(); + viewport.rewind(); + float[] origin = project(x, y); + float[] opposite = project(x + width, y + height); + float[] cursor = project(x + cursorOffset, y); + if (origin == null || opposite == null || cursor == null) { + return; + } + double scale = (double) window.width() / Math.max(1, window.pixelWidth()); + int top = viewport.get(3); + int areaX = (int) Math.round(Math.min(origin[0], opposite[0]) * scale); + int areaY = (int) Math.round((top - Math.max(origin[1], opposite[1])) * scale); + int areaWidth = (int) Math.round(Math.abs(opposite[0] - origin[0]) * scale); + int areaHeight = (int) Math.round(Math.abs(opposite[1] - origin[1]) * scale); + int cursorWindow = (int) Math.round(cursor[0] * scale) - areaX; + text.area(areaX, areaY, Math.max(1, areaWidth), Math.max(1, areaHeight), Math.max(0, cursorWindow)); + Minecraft minecraft = Minecraft.getMinecraft(); + int screenWidth = minecraft != null && minecraft.currentScreen != null ? minecraft.currentScreen.width : 0; + int screenHeight = minecraft != null && minecraft.currentScreen != null ? minecraft.currentScreen.height : 0; + if (screenWidth <= 0 || screenHeight <= 0) { + return; + } + int windowWidth = Math.max(1, window.width()); + int windowHeight = Math.max(1, window.height()); + remember(areaX * screenWidth / windowWidth, areaY * screenHeight / windowHeight, + Math.max(1, areaWidth * screenWidth / windowWidth), Math.max(1, areaHeight * screenHeight / windowHeight)); + } + + private static float[] project(float x, float y) { + windowCoords.clear(); + if (!GLU.gluProject(x, y, 0.0F, modelview, projection, viewport, windowCoords)) { + return null; + } + return new float[] { windowCoords.get(0), windowCoords.get(1) } ; + } + + private static void ensureProjectionBuffers() { + if (modelview == null) { + modelview = BufferUtils.createFloatBuffer(16); + projection = BufferUtils.createFloatBuffer(16); + viewport = BufferUtils.createIntBuffer(16); + windowCoords = BufferUtils.createFloatBuffer(3); + } + } + + private static void area(int x, int y, int width, int height, int caretX) { + Text text = text(); + Window window = Window.main(); + Minecraft minecraft = Minecraft.getMinecraft(); + if (text == null || window == null || minecraft == null) { + return; + } + int screenWidth = minecraft.currentScreen != null ? minecraft.currentScreen.width : 0; + int screenHeight = minecraft.currentScreen != null ? minecraft.currentScreen.height : 0; + if (screenWidth <= 0 || screenHeight <= 0) { + return; + } + int windowWidth = Math.max(1, window.width()); + int windowHeight = Math.max(1, window.height()); + text.area(x * windowWidth / screenWidth, y * windowHeight / screenHeight, + Math.max(1, width * windowWidth / screenWidth), Math.max(1, height * windowHeight / screenHeight), + Math.max(0, (caretX - x) * windowWidth / screenWidth)); + } + + private static void overlay(Text text, FontRenderer font, int caretX, int caretY, int remainingWidth, int fieldX, int fieldY, int fieldWidth, int fieldHeight) { + TextComposition composition = text.composition(); + if (composition.active()) { + composition(font, composition, caretX, caretY, Math.max(0, remainingWidth)); + } + InputCandidates candidates = text.candidates(); + if (candidates.active()) { + candidates(font, candidates, fieldX, fieldY, fieldWidth, fieldHeight); + } + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + } + + private static void composition(FontRenderer font, TextComposition composition, int x, int y, int remainingWidth) { + String shown = remainingWidth <= 0 ? composition.text() : font.trimStringToWidth(composition.text(), remainingWidth); + if (shown.isEmpty()) { + return; + } + int width = font.getStringWidth(shown); + int height = font.FONT_HEIGHT; + int cursor = Math.max(0, Math.min(shown.length(), composition.cursor() < 0 ? shown.length() : composition.cursor())); + int selection = composition.selectionLength(); + if (selection > 0) { + int end = Math.min(shown.length(), cursor + selection); + int left = x + font.getStringWidth(shown.substring(0, cursor)); + int right = x + font.getStringWidth(shown.substring(0, end)); + Gui.drawRect(left, y - 1, right, y + height + 1, COMPOSITION_SELECTION); + } + font.drawStringWithShadow(shown, x, y, COMPOSITION_COLOR); + Gui.drawRect(x, y + height, x + width, y + height + 1, COMPOSITION_UNDERLINE); + if (composition.cursor() >= 0) { + int caret = x + font.getStringWidth(shown.substring(0, cursor)); + Gui.drawRect(caret, y - 1, caret + 1, y + height + 1, COMPOSITION_UNDERLINE); + } + } + + private static void candidates(FontRenderer font, InputCandidates candidates, int fieldX, int fieldY, int fieldWidth, int fieldHeight) { + List entries = candidates.entries(); + if (entries.isEmpty()) { + return; + } + Minecraft minecraft = Minecraft.getMinecraft(); + int screenWidth = minecraft != null && minecraft.currentScreen != null ? minecraft.currentScreen.width : fieldX + 256; + int screenHeight = minecraft != null && minecraft.currentScreen != null ? minecraft.currentScreen.height : fieldY + fieldHeight + 64; + int line = font.FONT_HEIGHT + CANDIDATE_PADDING; + boolean horizontal = candidates.horizontal(); + int innerWidth = 0; + if (horizontal) { + for (int i = 0; i < entries.size(); i++) { + if (i > 0) { + innerWidth += CANDIDATE_PADDING; + } + innerWidth += font.getStringWidth(entries.get(i)); + } + } else { + for (String entry : entries) { + innerWidth = Math.max(innerWidth, font.getStringWidth(entry)); + } + } + int boxWidth = innerWidth + CANDIDATE_PADDING * 2; + int boxHeight = horizontal ? line + CANDIDATE_PADDING : entries.size() * line + CANDIDATE_PADDING; + int x = fieldX; + int y = fieldY + fieldHeight + 2; + if (x + boxWidth > screenWidth) { + x = Math.max(0, screenWidth - boxWidth); + } + if (y + boxHeight > screenHeight) { + y = fieldY - 2 - boxHeight; + } + Gui.drawRect(x, y, x + boxWidth, y + boxHeight, CANDIDATE_BACKGROUND); + int selected = candidates.selected(); + if (horizontal) { + int drawX = x + CANDIDATE_PADDING; + int drawY = y + CANDIDATE_PADDING; + for (int i = 0; i < entries.size(); i++) { + String entry = entries.get(i); + int entryWidth = font.getStringWidth(entry); + if (i == selected) { + Gui.drawRect(drawX - 1, drawY - 1, drawX + entryWidth + 1, drawY + font.FONT_HEIGHT + 1, CANDIDATE_SELECTED); + } + font.drawStringWithShadow(entry, drawX, drawY, CANDIDATE_TEXT); + drawX += entryWidth + CANDIDATE_PADDING; + } + return; + } + for (int i = 0; i < entries.size(); i++) { + int drawY = y + CANDIDATE_PADDING + i * line; + if (i == selected) { + Gui.drawRect(x + 1, drawY - 1, x + boxWidth - 1, drawY + font.FONT_HEIGHT + 1, CANDIDATE_SELECTED); + } + font.drawStringWithShadow(entries.get(i), x + CANDIDATE_PADDING, drawY, CANDIDATE_TEXT); + } + } + + private SDLHooks() { } + +} diff --git a/module/forge/src/main/java/net/minecraftforge/client/ForgeClientHandler.java b/module/forge/src/main/java/net/minecraftforge/client/ForgeClientHandler.java index 0abb9f960..d29b0110f 100644 --- a/module/forge/src/main/java/net/minecraftforge/client/ForgeClientHandler.java +++ b/module/forge/src/main/java/net/minecraftforge/client/ForgeClientHandler.java @@ -19,6 +19,7 @@ package net.minecraftforge.client; +import com.cleanroommc.client.sdl.SDLHooks; import com.cleanroommc.client.sdl.Window; import com.cleanroommc.client.modlist.LegacyModListScreen; import com.cleanroommc.client.modlist.ModListConfig; @@ -26,6 +27,7 @@ import com.cleanroommc.client.modlist.screen.ModListScreen; import com.cleanroommc.client.windows.TaskbarApi; import com.cleanroommc.client.windows.WindowsProperties; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiMainMenu; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.GuiScreenBook; @@ -38,6 +40,7 @@ import net.minecraft.util.text.translation.I18n; import net.minecraftforge.client.event.ColorHandlerEvent; import net.minecraftforge.client.event.GuiOpenEvent; +import net.minecraftforge.client.event.GuiScreenEvent; import net.minecraftforge.client.event.ModelRegistryEvent; import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.common.ForgeEarlyConfig; @@ -93,6 +96,22 @@ public static void onGuiOpen(GuiOpenEvent event) } } + @SubscribeEvent(priority = EventPriority.LOWEST) + public static void onGuiDraw(GuiScreenEvent.DrawScreenEvent.Post event) + { + SDLHooks.draw(event.getGui()); + } + + @SubscribeEvent(priority = EventPriority.HIGHEST) + public static void onGuiKeyboard(GuiScreenEvent.KeyboardInputEvent.Pre event) + { + if (SDLHooks.keyboard(event.getGui())) + { + event.setCanceled(true); + Minecraft.getMinecraft().dispatchKeypresses(); + } + } + @SubscribeEvent public static void onConfigChanged(OnConfigChangedEvent event) { diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiScreen.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiScreen.java.patch index e4c7c1757..4d208cc9c 100644 --- a/module/minecraft/patches/net/minecraft/client/gui/GuiScreen.java.patch +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiScreen.java.patch @@ -20,7 +20,7 @@ } public List getItemToolTip(ItemStack p_191927_1_) { -@@ -138,7 +142,7 @@ +@@ -138,7 +143,7 @@ for (int i = 0; i < list.size(); i++) { if (i == 0) { @@ -29,7 +29,7 @@ } else { list.set(i, TextFormatting.GRAY + list.get(i)); } -@@ -162,7 +166,12 @@ +@@ -162,7 +167,12 @@ /** Draws a List of strings as a tooltip. Every entry is drawn on a seperate line. */ public void drawHoveringText(List textLines, int x, int y) { @@ -43,7 +43,7 @@ GlStateManager.disableRescaleNormal(); RenderHelper.disableStandardItemLighting(); GlStateManager.disableLighting(); -@@ -339,9 +348,12 @@ +@@ -339,9 +349,12 @@ } public void sendChatMessage(String msg, boolean addToChat) { @@ -56,7 +56,7 @@ this.mc.player.sendChatMessage(msg); } -@@ -352,9 +364,15 @@ +@@ -352,9 +365,15 @@ for (int i = 0; i < this.buttonList.size(); i++) { GuiButton guibutton = this.buttonList.get(i); if (guibutton.mousePressed(this.mc, mouseX, mouseY)) { @@ -72,7 +72,7 @@ } } } -@@ -383,8 +401,11 @@ +@@ -383,8 +402,11 @@ this.fontRenderer = mc.fontRenderer; this.width = width; this.height = height; @@ -84,7 +84,7 @@ } /** Set the gui to the specified width and height */ -@@ -401,13 +422,19 @@ +@@ -401,13 +423,19 @@ public void handleInput() throws IOException { if (Mouse.isCreated()) { while (Mouse.next()) { @@ -104,7 +104,7 @@ } } } -@@ -465,6 +492,7 @@ +@@ -465,6 +493,7 @@ */ public void drawDefaultBackground() { this.drawWorldBackground(0); diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiScreenBook.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiScreenBook.java.patch index 8ea78235b..fcb5b1568 100644 --- a/module/minecraft/patches/net/minecraft/client/gui/GuiScreenBook.java.patch +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiScreenBook.java.patch @@ -8,3 +8,51 @@ this.bookTotalPages = 1; } } +@@ -300,8 +301,8 @@ + this.drawTexturedModalRect(i, 2, 0, 0, 192, 192); + if (this.bookGettingSigned) { +- String s = this.bookTitle; +- if (this.bookIsUnsigned) { ++ String s = this.bookTitle + com.cleanroommc.client.sdl.SDLHooks.compositionUnderlined(); ++ if (this.bookIsUnsigned && !com.cleanroommc.client.sdl.SDLHooks.composing()) { + if (this.updateCount / 6 % 2 == 0) { + s = s + "" + TextFormatting.BLACK + "_"; + } else { +@@ -313,6 +314,9 @@ + this.fontRenderer.drawString(s1, i + 36 + (116 - k) / 2, 34, 0); + int l = this.fontRenderer.getStringWidth(s); + this.fontRenderer.drawString(s, i + 36 + (116 - l) / 2, 50, 0); ++ if (this.bookIsUnsigned) { ++ com.cleanroommc.client.sdl.SDLHooks.caret(i + 36, 50, 116, this.fontRenderer.FONT_HEIGHT, (116 - l) / 2 + l); ++ } + String s2 = I18n.format("book.byAuthor", this.editingPlayer.getName()); + int i1 = this.fontRenderer.getStringWidth(s2); + this.fontRenderer.drawString(TextFormatting.DARK_GRAY + s2, i + 36 + (116 - i1) / 2, 60, 0); +@@ -326,13 +330,16 @@ + s5 = this.bookPages.getStringTagAt(this.currPage); + } + + if (this.bookIsUnsigned) { ++ s5 = s5 + com.cleanroommc.client.sdl.SDLHooks.compositionUnderlined(); ++ if (!com.cleanroommc.client.sdl.SDLHooks.composing()) { + if (this.fontRenderer.getBidiFlag()) { + s5 = s5 + "_"; + } else if (this.updateCount / 6 % 2 == 0) { + s5 = s5 + "" + TextFormatting.BLACK + "_"; + } else { + s5 = s5 + "" + TextFormatting.GRAY + "_"; + } ++ } + } else if (this.cachedPage != this.currPage) { + if (ItemWrittenBook.validBookTagContents(this.book.getTagCompound())) { + try { +@@ -355,6 +362,10 @@ + this.fontRenderer.drawString(s4, i - j1 + 192 - 44, 18, 0); + if (this.cachedComponents == null) { + this.fontRenderer.drawSplitString(s5, i + 36, 34, 116, 0); ++ if (this.bookIsUnsigned) { ++ int lines = Math.max(1, this.fontRenderer.listFormattedStringToWidth(s5, 116).size()); ++ com.cleanroommc.client.sdl.SDLHooks.caret(i + 36, 34 + (lines - 1) * this.fontRenderer.FONT_HEIGHT, 116, this.fontRenderer.FONT_HEIGHT, 0); ++ } + } else { + int k1 = Math.min(128 / this.fontRenderer.FONT_HEIGHT, this.cachedComponents.size()); diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiTextField.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiTextField.java.patch index 5cf52746f..4c704d943 100644 --- a/module/minecraft/patches/net/minecraft/client/gui/GuiTextField.java.patch +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiTextField.java.patch @@ -1,18 +1,35 @@ --- original/net/minecraft/client/gui/GuiTextField.java +++ modified/net/minecraft/client/gui/GuiTextField.java -@@ -519,6 +519,11 @@ +@@ -395,7 +395,7 @@ + int k = this.selectionEnd - this.lineScrollOffset; + String s = this.fontRenderer.trimStringToWidth(this.text.substring(this.lineScrollOffset), this.getWidth()); + boolean flag = j >= 0 && j <= s.length(); +- boolean flag1 = this.isFocused && this.cursorCounter / 6 % 2 == 0 && flag; ++ boolean flag1 = this.isFocused && this.cursorCounter / 6 % 2 == 0 && flag && !com.cleanroommc.client.sdl.Window.main().text().composition().active(); + int l = this.enableBackgroundDrawing ? this.x + 4 : this.x; + int i1 = this.enableBackgroundDrawing ? this.y + (this.height - 8) / 2 : this.y; + int j1 = l; +@@ -433,6 +433,7 @@ + int l1 = l + this.fontRenderer.getStringWidth(s.substring(0, k)); + this.drawSelectionBox(k1, i1 - 1, l1 - 1, i1 + 1 + this.fontRenderer.FONT_HEIGHT); + } ++ com.cleanroommc.client.sdl.SDLHooks.textFieldDraw(this); + } + } + +@@ -519,6 +520,11 @@ } this.isFocused = isFocusedIn; + com.cleanroommc.client.sdl.Window window = com.cleanroommc.client.sdl.Window.main(); + if (window != null) { -+ window.textInput(this.isFocused); ++ window.text().active(isFocusedIn); + } + if (Minecraft.getMinecraft().currentScreen != null) { Minecraft.getMinecraft().currentScreen.setFocused(isFocusedIn); } -@@ -592,4 +597,8 @@ +@@ -592,4 +598,8 @@ public void setVisible(boolean isVisible) { this.visible = isVisible; } diff --git a/module/minecraft/patches/net/minecraft/client/gui/inventory/GuiEditSign.java.patch b/module/minecraft/patches/net/minecraft/client/gui/inventory/GuiEditSign.java.patch new file mode 100644 index 000000000..421a20bf1 --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/gui/inventory/GuiEditSign.java.patch @@ -0,0 +1,20 @@ +--- original/net/minecraft/client/gui/inventory/GuiEditSign.java ++++ modified/net/minecraft/client/gui/inventory/GuiEditSign.java +@@ -12,6 +12,7 @@ + import net.minecraft.network.play.client.CPacketUpdateSign; + import net.minecraft.tileentity.TileEntitySign; + import net.minecraft.util.ChatAllowedCharacters; ++import net.minecraft.util.text.ITextComponent; + import net.minecraft.util.text.TextComponentString; + import net.minecraftforge.fml.relauncher.Side; + import net.minecraftforge.fml.relauncher.SideOnly; +@@ -135,7 +136,9 @@ + this.tileSign.lineBeingEdited = this.editLine; + } + ++ ITextComponent line = com.cleanroommc.client.sdl.SDLHooks.lendComposition(this.tileSign, this.editLine); + TileEntityRendererDispatcher.instance.render(this.tileSign, -0.5, -0.75, -0.5, 0.0F); ++ com.cleanroommc.client.sdl.SDLHooks.takeComposition(this.tileSign, this.editLine, line); + this.tileSign.lineBeingEdited = -1; + GlStateManager.popMatrix(); + super.drawScreen(mouseX, mouseY, partialTicks); diff --git a/module/minecraft/patches/net/minecraft/client/renderer/tileentity/TileEntitySignRenderer.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/tileentity/TileEntitySignRenderer.java.patch new file mode 100644 index 000000000..4761821ab --- /dev/null +++ b/module/minecraft/patches/net/minecraft/client/renderer/tileentity/TileEntitySignRenderer.java.patch @@ -0,0 +1,11 @@ +--- original/net/minecraft/client/renderer/tileentity/TileEntitySignRenderer.java ++++ modified/net/minecraft/client/renderer/tileentity/TileEntitySignRenderer.java +@@ -81,7 +81,6 @@ + List list = GuiUtilRenderComponents.splitText(itextcomponent, 90, fontrenderer, false, true); + String s = list != null && !list.isEmpty() ? list.get(0).getFormattedText() : ""; + if (j == te.lineBeingEdited) { +- s = "> " + s + " <"; +- fontrenderer.drawString(s, -fontrenderer.getStringWidth(s) / 2, j * 10 - te.signText.length * 5, 0); ++ com.cleanroommc.client.sdl.SDLHooks.drawSignLineBeingEdited(fontrenderer, s, j * 10 - te.signText.length * 5); + } else { + fontrenderer.drawString(s, -fontrenderer.getStringWidth(s) / 2, j * 10 - te.signText.length * 5, 0); From 732527236a01437c6abffb204cf079a89a4b8f6d Mon Sep 17 00:00:00 2001 From: Rongmario Date: Wed, 19 Aug 2026 15:17:46 +0100 Subject: [PATCH 59/99] Update CG to 0.9.0 --- mmcpack-template/patches/net.minecraft.json | 190 -------------------- settings.gradle | 2 +- 2 files changed, 1 insertion(+), 191 deletions(-) delete mode 100644 mmcpack-template/patches/net.minecraft.json diff --git a/mmcpack-template/patches/net.minecraft.json b/mmcpack-template/patches/net.minecraft.json deleted file mode 100644 index 1c461cf8e..000000000 --- a/mmcpack-template/patches/net.minecraft.json +++ /dev/null @@ -1,190 +0,0 @@ -{ - "assetIndex": { - "id": "1.12", - "sha1": "a21e1ded1a24ea1548dd8db0cf30b6acb02655a9", - "size": 143136, - "totalSize": 129843781, - "url": "https://piston-meta.mojang.com/v1/packages/a21e1ded1a24ea1548dd8db0cf30b6acb02655a9/1.12.json" - }, - "compatibleJavaMajors": [ - 25, - 26 - ], - "formatVersion": 1, - "libraries": [ - { - "downloads": { - "artifact": { - "sha1": "c73b5636faf089d9f00e8732a829577de25237ee", - "size": 103871, - "url": "https://libraries.minecraft.net/com/paulscode/codecjorbis/20101023/codecjorbis-20101023.jar" - } - }, - "name": "com.paulscode:codecjorbis:20101023" - }, - { - "downloads": { - "artifact": { - "sha1": "12f031cfe88fef5c1dd36c563c0a3a69bd7261da", - "size": 5618, - "url": "https://libraries.minecraft.net/com/paulscode/codecwav/20101023/codecwav-20101023.jar" - } - }, - "name": "com.paulscode:codecwav:20101023" - }, - { - "downloads": { - "artifact": { - "sha1": "5c5e304366f75f9eaa2e8cca546a1fb6109348b3", - "size": 21679, - "url": "https://libraries.minecraft.net/com/paulscode/libraryjavasound/20101123/libraryjavasound-20101123.jar" - } - }, - "name": "com.paulscode:libraryjavasound:20101123" - }, - { - "downloads": { - "artifact": { - "sha1": "73e80d0794c39665aec3f62eee88ca91676674ef", - "size": 18981, - "url": "https://libraries.minecraft.net/com/paulscode/librarylwjglopenal/20100824/librarylwjglopenal-20100824.jar" - } - }, - "name": "com.paulscode:librarylwjglopenal:20100824" - }, - { - "downloads": { - "artifact": { - "sha1": "419c05fe9be71f792b2d76cfc9b67f1ed0fec7f6", - "size": 65020, - "url": "https://libraries.minecraft.net/com/paulscode/soundsystem/20120107/soundsystem-20120107.jar" - } - }, - "name": "com.paulscode:soundsystem:20120107" - }, - { - "downloads": { - "artifact": { - "sha1": "9834cdf236c22e84b946bba989e2f94ef5897c3c", - "size": 65621, - "url": "https://libraries.minecraft.net/com/mojang/authlib/1.5.25/authlib-1.5.25.jar" - } - }, - "name": "com.mojang:authlib:1.5.25" - }, - { - "downloads": { - "artifact": { - "sha1": "bd0dccebdf3744c75f1ca20063f16e8f7d5e663f", - "size": 7135057, - "url": "https://libraries.minecraft.net/com/mojang/realms/1.10.22/realms-1.10.22.jar" - } - }, - "name": "com.mojang:realms:1.10.22" - }, - { - "downloads": { - "artifact": { - "sha1": "48fd510879dff266c3815947de66e3d4809f8668", - "size": 11055, - "url": "https://libraries.minecraft.net/com/mojang/text2speech/1.10.3/text2speech-1.10.3.jar" - } - }, - "name": "com.mojang:text2speech:1.10.3", - "rules": [ - { - "action": "allow" - }, - { - "action": "disallow", - "os": { - "name": "osx-arm64" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "48fd510879dff266c3815947de66e3d4809f8668", - "size": 11055, - "url": "https://libraries.minecraft.net/com/mojang/text2speech/1.10.3/text2speech-1.10.3.jar" - }, - "classifiers": { - "natives-linux": { - "sha1": "ab7896aec3b3dd272b06194357f2d98f832c0cfc", - "size": 7833, - "url": "https://libraries.minecraft.net/com/mojang/text2speech/1.10.3/text2speech-1.10.3-natives-linux.jar" - }, - "natives-windows": { - "sha1": "84a4b856389cc4f485275b1f63497a95a857a443", - "size": 81217, - "url": "https://libraries.minecraft.net/com/mojang/text2speech/1.10.3/text2speech-1.10.3-natives-windows.jar" - } - } - }, - "extract": { - "exclude": [ - "META-INF/" - ] - }, - "name": "com.mojang:text2speech:1.10.3", - "natives": { - "linux": "natives-linux", - "windows": "natives-windows" - }, - "rules": [ - { - "action": "allow" - }, - { - "action": "disallow", - "os": { - "name": "osx-arm64" - } - } - ] - }, - { - "downloads": { - "artifact": { - "sha1": "f378f889797edd7df8d32272c06ca80a1b6b0f58", - "size": 13164, - "url": "https://libraries.minecraft.net/com/mojang/text2speech/1.11.3/text2speech-1.11.3.jar" - } - }, - "name": "com.mojang:text2speech:1.11.3", - "rules": [ - { - "action": "allow", - "os": { - "name": "osx-arm64" - } - } - ] - } - ], - "mainClass": "net.minecraft.client.main.Main", - "mainJar": { - "downloads": { - "artifact": { - "sha1": "0f275bc1547d01fa5f56ba34bdc87d981ee12daf", - "size": 10180113, - "url": "https://piston-data.mojang.com/v1/objects/0f275bc1547d01fa5f56ba34bdc87d981ee12daf/client.jar" - } - }, - "name": "com.mojang:minecraft:1.12.2:client" - }, - "minecraftArguments": "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} --assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} --accessToken ${auth_access_token} --userType ${user_type} --versionType ${version_type}", - "name": "Minecraft", - "releaseTime": "2017-09-18T08:39:46+00:00", - "requires": [ - { - "suggests": "3.3.1", - "uid": "org.lwjgl3" - } - ], - "type": "release", - "uid": "net.minecraft", - "version": "1.12.2" -} diff --git a/settings.gradle b/settings.gradle index 23dd48d59..7ca492f05 100644 --- a/settings.gradle +++ b/settings.gradle @@ -14,5 +14,5 @@ pluginManagement { } plugins { - id 'com.cleanroommc.cleanroomgradle.settings' version '0.8.1' + id 'com.cleanroommc.cleanroomgradle.settings' version '0.9.0' } From 0d20595003b3d8ffcdc9edbc96481650ca51d80b Mon Sep 17 00:00:00 2001 From: Rongmario Date: Wed, 19 Aug 2026 16:05:50 +0100 Subject: [PATCH 60/99] Update CG to 0.9.1, removed/modified patches accordingly --- .../net/minecraft/block/Block.java.patch | 7 +++-- .../minecraft/client/gui/GuiScreen.java.patch | 14 +++++----- .../client/gui/GuiScreenBook.java.patch | 28 +++++++++++-------- .../client/model/ModelBase.java.patch | 10 ------- .../client/model/ModelBox.java.patch | 10 +------ .../client/model/ModelRenderer.java.patch | 16 +++-------- .../model/PositionTextureVertex.java.patch | 13 --------- .../client/model/TexturedQuad.java.patch | 10 +------ .../TileEntitySignRenderer.java.patch | 3 +- .../net/minecraft/item/Item.java.patch | 11 +++++--- .../net/minecraft/item/ItemSnow.java.patch | 14 ++++++++-- .../handshake/client/C00Handshake.java.patch | 9 ++++-- settings.gradle | 2 +- 13 files changed, 62 insertions(+), 85 deletions(-) delete mode 100644 module/minecraft/patches/net/minecraft/client/model/ModelBase.java.patch delete mode 100644 module/minecraft/patches/net/minecraft/client/model/PositionTextureVertex.java.patch diff --git a/module/minecraft/patches/net/minecraft/block/Block.java.patch b/module/minecraft/patches/net/minecraft/block/Block.java.patch index c2a80e3d8..ed5db8288 100644 --- a/module/minecraft/patches/net/minecraft/block/Block.java.patch +++ b/module/minecraft/patches/net/minecraft/block/Block.java.patch @@ -216,7 +216,7 @@ public SoundType getSoundType() { return this.blockSoundType; } -@@ -969,6 +986,1256 @@ +@@ -969,6 +986,1257 @@ public void addInformation(ItemStack stack, @Nullable World worldIn, List tooltip, ITooltipFlag flagIn) { } @@ -1311,6 +1311,7 @@ + * Queries if this block should render in a given layer. + * ISmartBlockModel can use {@link net.minecraftforge.client.MinecraftForgeClient#getRenderLayer()} to alter their model based on layer. + */ ++ @SideOnly(Side.CLIENT) + public boolean canRenderInLayer(IBlockState state, BlockRenderLayer layer) { + return getRenderLayer() == layer; + } @@ -1473,7 +1474,7 @@ public static void registerBlocks() { registerBlock(0, AIR_ID, new BlockAir().setTranslationKey("air")); registerBlock(1, "stone", new BlockStone().setHardness(1.5F).setResistance(10.0F).setSoundType(SoundType.STONE).setTranslationKey("stone")); -@@ -1520,7 +2787,7 @@ +@@ -1520,7 +2788,7 @@ "quartz_stairs", new BlockStairs(block11.getDefaultState().withProperty(BlockQuartz.VARIANT, BlockQuartz.EnumType.DEFAULT)).setTranslationKey("stairsQuartz") ); @@ -1482,7 +1483,7 @@ registerBlock(158, "dropper", new BlockDropper().setHardness(3.5F).setSoundType(SoundType.STONE).setTranslationKey("dropper")); registerBlock( 159, -@@ -1944,22 +3211,6 @@ +@@ -1944,22 +3212,6 @@ block15.useNeighborBrightness = flag; } } diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiScreen.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiScreen.java.patch index 4d208cc9c..e4c7c1757 100644 --- a/module/minecraft/patches/net/minecraft/client/gui/GuiScreen.java.patch +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiScreen.java.patch @@ -20,7 +20,7 @@ } public List getItemToolTip(ItemStack p_191927_1_) { -@@ -138,7 +143,7 @@ +@@ -138,7 +142,7 @@ for (int i = 0; i < list.size(); i++) { if (i == 0) { @@ -29,7 +29,7 @@ } else { list.set(i, TextFormatting.GRAY + list.get(i)); } -@@ -162,7 +167,12 @@ +@@ -162,7 +166,12 @@ /** Draws a List of strings as a tooltip. Every entry is drawn on a seperate line. */ public void drawHoveringText(List textLines, int x, int y) { @@ -43,7 +43,7 @@ GlStateManager.disableRescaleNormal(); RenderHelper.disableStandardItemLighting(); GlStateManager.disableLighting(); -@@ -339,9 +349,12 @@ +@@ -339,9 +348,12 @@ } public void sendChatMessage(String msg, boolean addToChat) { @@ -56,7 +56,7 @@ this.mc.player.sendChatMessage(msg); } -@@ -352,9 +365,15 @@ +@@ -352,9 +364,15 @@ for (int i = 0; i < this.buttonList.size(); i++) { GuiButton guibutton = this.buttonList.get(i); if (guibutton.mousePressed(this.mc, mouseX, mouseY)) { @@ -72,7 +72,7 @@ } } } -@@ -383,8 +402,11 @@ +@@ -383,8 +401,11 @@ this.fontRenderer = mc.fontRenderer; this.width = width; this.height = height; @@ -84,7 +84,7 @@ } /** Set the gui to the specified width and height */ -@@ -401,13 +423,19 @@ +@@ -401,13 +422,19 @@ public void handleInput() throws IOException { if (Mouse.isCreated()) { while (Mouse.next()) { @@ -104,7 +104,7 @@ } } } -@@ -465,6 +493,7 @@ +@@ -465,6 +492,7 @@ */ public void drawDefaultBackground() { this.drawWorldBackground(0); diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiScreenBook.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiScreenBook.java.patch index fcb5b1568..a3b3729d8 100644 --- a/module/minecraft/patches/net/minecraft/client/gui/GuiScreenBook.java.patch +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiScreenBook.java.patch @@ -8,7 +8,8 @@ this.bookTotalPages = 1; } } -@@ -300,8 +301,8 @@ +@@ -299,8 +300,8 @@ + int j = 2; this.drawTexturedModalRect(i, 2, 0, 0, 192, 192); if (this.bookGettingSigned) { - String s = this.bookTitle; @@ -28,24 +29,28 @@ String s2 = I18n.format("book.byAuthor", this.editingPlayer.getName()); int i1 = this.fontRenderer.getStringWidth(s2); this.fontRenderer.drawString(TextFormatting.DARK_GRAY + s2, i + 36 + (116 - i1) / 2, 60, 0); -@@ -326,13 +330,16 @@ - s5 = this.bookPages.getStringTagAt(this.currPage); +@@ -326,12 +330,15 @@ } if (this.bookIsUnsigned) { +- if (this.fontRenderer.getBidiFlag()) { +- s5 = s5 + "_"; +- } else if (this.updateCount / 6 % 2 == 0) { +- s5 = s5 + "" + TextFormatting.BLACK + "_"; +- } else { +- s5 = s5 + "" + TextFormatting.GRAY + "_"; + s5 = s5 + com.cleanroommc.client.sdl.SDLHooks.compositionUnderlined(); + if (!com.cleanroommc.client.sdl.SDLHooks.composing()) { - if (this.fontRenderer.getBidiFlag()) { - s5 = s5 + "_"; - } else if (this.updateCount / 6 % 2 == 0) { - s5 = s5 + "" + TextFormatting.BLACK + "_"; - } else { - s5 = s5 + "" + TextFormatting.GRAY + "_"; ++ if (this.fontRenderer.getBidiFlag()) { ++ s5 = s5 + "_"; ++ } else if (this.updateCount / 6 % 2 == 0) { ++ s5 = s5 + "" + TextFormatting.BLACK + "_"; ++ } else { ++ s5 = s5 + "" + TextFormatting.GRAY + "_"; ++ } } -+ } } else if (this.cachedPage != this.currPage) { if (ItemWrittenBook.validBookTagContents(this.book.getTagCompound())) { - try { @@ -355,6 +362,10 @@ this.fontRenderer.drawString(s4, i - j1 + 192 - 44, 18, 0); if (this.cachedComponents == null) { @@ -56,3 +61,4 @@ + } } else { int k1 = Math.min(128 / this.fontRenderer.FONT_HEIGHT, this.cachedComponents.size()); + diff --git a/module/minecraft/patches/net/minecraft/client/model/ModelBase.java.patch b/module/minecraft/patches/net/minecraft/client/model/ModelBase.java.patch deleted file mode 100644 index 27bdf435a..000000000 --- a/module/minecraft/patches/net/minecraft/client/model/ModelBase.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- original/net/minecraft/client/model/ModelBase.java -+++ modified/net/minecraft/client/model/ModelBase.java -@@ -10,7 +10,6 @@ - import net.minecraftforge.fml.relauncher.Side; - import net.minecraftforge.fml.relauncher.SideOnly; - --@SideOnly(Side.CLIENT) - public abstract class ModelBase { - public float swingProgress; - public boolean isRiding; diff --git a/module/minecraft/patches/net/minecraft/client/model/ModelBox.java.patch b/module/minecraft/patches/net/minecraft/client/model/ModelBox.java.patch index d907d2c21..4787b1fed 100644 --- a/module/minecraft/patches/net/minecraft/client/model/ModelBox.java.patch +++ b/module/minecraft/patches/net/minecraft/client/model/ModelBox.java.patch @@ -1,14 +1,6 @@ --- original/net/minecraft/client/model/ModelBox.java +++ modified/net/minecraft/client/model/ModelBox.java -@@ -4,7 +4,6 @@ - import net.minecraftforge.fml.relauncher.Side; - import net.minecraftforge.fml.relauncher.SideOnly; - --@SideOnly(Side.CLIENT) - public class ModelBox { - /** The (x,y,z) vertex positions and (u,v) texture coordinates for each of the 8 points on a cube */ - private final PositionTextureVertex[] vertexPositions; -@@ -164,6 +163,7 @@ +@@ -164,6 +164,7 @@ } } diff --git a/module/minecraft/patches/net/minecraft/client/model/ModelRenderer.java.patch b/module/minecraft/patches/net/minecraft/client/model/ModelRenderer.java.patch index 666e7c01e..75cefd133 100644 --- a/module/minecraft/patches/net/minecraft/client/model/ModelRenderer.java.patch +++ b/module/minecraft/patches/net/minecraft/client/model/ModelRenderer.java.patch @@ -1,14 +1,6 @@ --- original/net/minecraft/client/model/ModelRenderer.java +++ modified/net/minecraft/client/model/ModelRenderer.java -@@ -9,7 +9,6 @@ - import net.minecraftforge.fml.relauncher.Side; - import net.minecraftforge.fml.relauncher.SideOnly; - --@SideOnly(Side.CLIENT) - public class ModelRenderer { - /** The size of the texture file's width in pixels. */ - public float textureWidth = 64.0F; -@@ -123,6 +122,7 @@ +@@ -123,6 +123,7 @@ this.rotationPointZ = rotationPointZIn; } @@ -16,7 +8,7 @@ public void render(float scale) { if (!this.isHidden) { if (this.showModel) { -@@ -178,6 +178,7 @@ +@@ -178,6 +179,7 @@ } } @@ -24,7 +16,7 @@ public void renderWithRotation(float scale) { if (!this.isHidden) { if (this.showModel) { -@@ -205,7 +206,7 @@ +@@ -205,7 +207,7 @@ } } @@ -33,7 +25,7 @@ public void postRender(float scale) { if (!this.isHidden) { if (this.showModel) { -@@ -233,7 +234,7 @@ +@@ -233,7 +235,7 @@ } } diff --git a/module/minecraft/patches/net/minecraft/client/model/PositionTextureVertex.java.patch b/module/minecraft/patches/net/minecraft/client/model/PositionTextureVertex.java.patch deleted file mode 100644 index f478b97d0..000000000 --- a/module/minecraft/patches/net/minecraft/client/model/PositionTextureVertex.java.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- original/net/minecraft/client/model/PositionTextureVertex.java -+++ modified/net/minecraft/client/model/PositionTextureVertex.java -@@ -1,10 +1,7 @@ - package net.minecraft.client.model; - - import net.minecraft.util.math.Vec3d; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; - --@SideOnly(Side.CLIENT) - public class PositionTextureVertex { - public Vec3d vector3D; - public float texturePositionX; diff --git a/module/minecraft/patches/net/minecraft/client/model/TexturedQuad.java.patch b/module/minecraft/patches/net/minecraft/client/model/TexturedQuad.java.patch index 52ba370d3..5d432f610 100644 --- a/module/minecraft/patches/net/minecraft/client/model/TexturedQuad.java.patch +++ b/module/minecraft/patches/net/minecraft/client/model/TexturedQuad.java.patch @@ -1,14 +1,6 @@ --- original/net/minecraft/client/model/TexturedQuad.java +++ modified/net/minecraft/client/model/TexturedQuad.java -@@ -7,7 +7,6 @@ - import net.minecraftforge.fml.relauncher.Side; - import net.minecraftforge.fml.relauncher.SideOnly; - --@SideOnly(Side.CLIENT) - public class TexturedQuad { - public PositionTextureVertex[] vertexPositions; - public int nVertices; -@@ -38,7 +37,7 @@ +@@ -38,7 +38,7 @@ this.vertexPositions = apositiontexturevertex; } diff --git a/module/minecraft/patches/net/minecraft/client/renderer/tileentity/TileEntitySignRenderer.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/tileentity/TileEntitySignRenderer.java.patch index 4761821ab..9d6f9fe9a 100644 --- a/module/minecraft/patches/net/minecraft/client/renderer/tileentity/TileEntitySignRenderer.java.patch +++ b/module/minecraft/patches/net/minecraft/client/renderer/tileentity/TileEntitySignRenderer.java.patch @@ -1,6 +1,6 @@ --- original/net/minecraft/client/renderer/tileentity/TileEntitySignRenderer.java +++ modified/net/minecraft/client/renderer/tileentity/TileEntitySignRenderer.java -@@ -81,7 +81,6 @@ +@@ -81,8 +81,7 @@ List list = GuiUtilRenderComponents.splitText(itextcomponent, 90, fontrenderer, false, true); String s = list != null && !list.isEmpty() ? list.get(0).getFormattedText() : ""; if (j == te.lineBeingEdited) { @@ -9,3 +9,4 @@ + com.cleanroommc.client.sdl.SDLHooks.drawSignLineBeingEdited(fontrenderer, s, j * 10 - te.signText.length * 5); } else { fontrenderer.drawString(s, -fontrenderer.getStringWidth(s) / 2, j * 10 - te.signText.length * 5, 0); + } diff --git a/module/minecraft/patches/net/minecraft/item/Item.java.patch b/module/minecraft/patches/net/minecraft/item/Item.java.patch index 350f1685b..2074dcc22 100644 --- a/module/minecraft/patches/net/minecraft/item/Item.java.patch +++ b/module/minecraft/patches/net/minecraft/item/Item.java.patch @@ -78,7 +78,7 @@ CreativeTabs creativetabs = this.getCreativeTab(); return creativetabs != null && (targetTab == CreativeTabs.SEARCH || targetTab == creativetabs); } -@@ -435,11 +438,719 @@ +@@ -435,11 +438,722 @@ return false; } @@ -497,6 +497,7 @@ + * @param stack Stack to get durability from + * @return A packed RGB value for the durability colour (0x00RRGGBB) + */ ++ @SideOnly(Side.CLIENT) + public int getRGBDurabilityForDisplay(ItemStack stack) { + return MathHelper.hsvToRGB(Math.max(0.0F, (float) (1.0F - getDurabilityForDisplay(stack))) / 3.0F, 1.0F, 1.0F); + } @@ -707,6 +708,7 @@ + return null; + } + ++ @SideOnly(Side.CLIENT) + public com.google.common.collect.ImmutableMap getAnimationParameters(final ItemStack stack, final World world, final EntityLivingBase entity) { + com.google.common.collect.ImmutableMap.Builder builder = com.google.common.collect.ImmutableMap.builder(); + for(ResourceLocation location : properties.getKeys()) { @@ -761,6 +763,7 @@ + return net.minecraft.entity.passive.HorseArmorType.getByItem(stack.getItem()); + } + ++ @SideOnly(Side.CLIENT) + public String getHorseArmorTexture(net.minecraft.entity.EntityLiving wearer, ItemStack stack) { + return getHorseArmorType(stack).getTextureName(); + } @@ -799,7 +802,7 @@ public static void registerItems() { registerItemBlock(Blocks.AIR, new ItemAir(Blocks.AIR)); registerItemBlock(Blocks.STONE, new ItemMultiTexture(Blocks.STONE, Blocks.STONE, new ItemMultiTexture.Mapper() { -@@ -999,6 +1710,8 @@ +@@ -999,6 +1713,8 @@ private final float attackDamage; /** Defines the natural enchantability factor of the material. */ private final int enchantability; @@ -808,7 +811,7 @@ ToolMaterial(int harvestLevel, int maxUses, float efficiency, float damageVsEntity, int enchantability) { this.harvestLevel = harvestLevel; -@@ -1033,6 +1746,7 @@ +@@ -1033,6 +1749,7 @@ return this.enchantability; } @@ -816,7 +819,7 @@ public Item getRepairItem() { if (this == WOOD) { return Item.getItemFromBlock(Blocks.PLANKS); -@@ -1046,5 +1760,19 @@ +@@ -1046,5 +1763,19 @@ return this == DIAMOND ? Items.DIAMOND : null; } } diff --git a/module/minecraft/patches/net/minecraft/item/ItemSnow.java.patch b/module/minecraft/patches/net/minecraft/item/ItemSnow.java.patch index 8a13b55f2..560f093fc 100644 --- a/module/minecraft/patches/net/minecraft/item/ItemSnow.java.patch +++ b/module/minecraft/patches/net/minecraft/item/ItemSnow.java.patch @@ -1,6 +1,15 @@ --- original/net/minecraft/item/ItemSnow.java +++ modified/net/minecraft/item/ItemSnow.java -@@ -50,9 +50,9 @@ +@@ -14,6 +14,8 @@ + import net.minecraft.util.math.AxisAlignedBB; + import net.minecraft.util.math.BlockPos; + import net.minecraft.world.World; ++import net.minecraftforge.fml.relauncher.Side; ++import net.minecraftforge.fml.relauncher.SideOnly; + + public class ItemSnow extends ItemBlock { + public ItemSnow(Block block) { +@@ -50,9 +52,9 @@ IBlockState iblockstate1 = iblockstate.withProperty(BlockSnow.LAYERS, i + 1); AxisAlignedBB axisalignedbb = iblockstate1.getCollisionBoundingBox(worldIn, blockpos); if (axisalignedbb != Block.NULL_AABB @@ -13,11 +22,12 @@ worldIn.playSound( player, blockpos, -@@ -82,4 +82,10 @@ +@@ -82,4 +84,11 @@ public int getMetadata(int damage) { return damage; } + ++ @SideOnly(Side.CLIENT) + @Override + public boolean canPlaceBlockOnSide(World world, BlockPos pos, EnumFacing side, EntityPlayer player, ItemStack stack) { + IBlockState state = world.getBlockState(pos); diff --git a/module/minecraft/patches/net/minecraft/network/handshake/client/C00Handshake.java.patch b/module/minecraft/patches/net/minecraft/network/handshake/client/C00Handshake.java.patch index 0e19e8ac5..91c751435 100644 --- a/module/minecraft/patches/net/minecraft/network/handshake/client/C00Handshake.java.patch +++ b/module/minecraft/patches/net/minecraft/network/handshake/client/C00Handshake.java.patch @@ -8,13 +8,16 @@ public C00Handshake() { } -@@ -25,20 +26,26 @@ +@@ -25,20 +26,29 @@ this.requestedState = p_i47613_3_; } - /** Reads the raw packet data from the data stream. */ + public C00Handshake(String address, int port, EnumConnectionState state, boolean addFMLMarker) { -+ this(address, port, state); ++ this.protocolVersion = 340; ++ this.ip = address; ++ this.port = port; ++ this.requestedState = state; + this.hasFMLMarker = addFMLMarker; + } + @@ -37,7 +40,7 @@ buf.writeShort(this.port); buf.writeVarInt(this.requestedState.getId()); } -@@ -55,4 +62,8 @@ +@@ -55,4 +65,8 @@ public int getProtocolVersion() { return this.protocolVersion; } diff --git a/settings.gradle b/settings.gradle index 7ca492f05..a8f6b6b9f 100644 --- a/settings.gradle +++ b/settings.gradle @@ -14,5 +14,5 @@ pluginManagement { } plugins { - id 'com.cleanroommc.cleanroomgradle.settings' version '0.9.0' + id 'com.cleanroommc.cleanroomgradle.settings' version '0.9.1' } From e4e0411ae065dcb4cb88e01f5ef56024cedddcca Mon Sep 17 00:00:00 2001 From: Rongmario Date: Wed, 19 Aug 2026 18:06:22 +0100 Subject: [PATCH 61/99] Capitalization, multiline, autocorrect --- .../sdl/input/virtual/Capitalization.java | 23 ++++++++ .../client/sdl/input/virtual/Text.java | 52 +++++++++++++++++++ .../sdl/input/virtual/TextInputKind.java | 2 +- 3 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/virtual/Capitalization.java diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/virtual/Capitalization.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/virtual/Capitalization.java new file mode 100644 index 000000000..a6fe7366d --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/virtual/Capitalization.java @@ -0,0 +1,23 @@ +package com.cleanroommc.client.sdl.input.virtual; + +import org.lwjgl.sdl.SDLKeyboard; + +/** How the on-screen keyboard capitalizes incoming text. */ +public enum Capitalization { + + NONE(SDLKeyboard.SDL_CAPITALIZE_NONE), + SENTENCES(SDLKeyboard.SDL_CAPITALIZE_SENTENCES), + WORDS(SDLKeyboard.SDL_CAPITALIZE_WORDS), + LETTERS(SDLKeyboard.SDL_CAPITALIZE_LETTERS); + + private final int value; + + Capitalization(int value) { + this.value = value; + } + + public int value() { + return value; + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/virtual/Text.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/virtual/Text.java index b04f00c10..a4a2bc392 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/virtual/Text.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/virtual/Text.java @@ -72,8 +72,11 @@ public static boolean screenKeyboardSupported() { private final Window window; private TextInputKind kind = TextInputKind.TEXT; + private Capitalization capitalization = Capitalization.SENTENCES; private TextComposition composition = TextComposition.NONE; private InputCandidates candidates = InputCandidates.NONE; + private boolean multiline = true; + private boolean autocorrect = true; /** * Attaches these helpers to {@code window}. Prefer {@link Window#text()}. @@ -132,6 +135,49 @@ public synchronized Text kind(TextInputKind kind) { return this; } this.kind = kind; + return restartIfActive(); + } + + public synchronized Capitalization capitalization() { + return this.capitalization; + } + + public synchronized Text capitalization(Capitalization capitalization) { + if (capitalization == null) { + throw new IllegalArgumentException("Capitalization cannot be null"); + } + if (this.capitalization == capitalization) { + return this; + } + this.capitalization = capitalization; + return restartIfActive(); + } + + public synchronized boolean multiline() { + return this.multiline; + } + + public synchronized Text multiline(boolean multiline) { + if (this.multiline == multiline) { + return this; + } + this.multiline = multiline; + return restartIfActive(); + } + + public synchronized boolean autocorrect() { + return this.autocorrect; + } + + public synchronized Text autocorrect(boolean autocorrect) { + if (this.autocorrect == autocorrect) { + return this; + } + this.autocorrect = autocorrect; + return restartIfActive(); + } + + private Text restartIfActive() { if (this.active()) { this.stop(); this.start(); @@ -238,6 +284,12 @@ private void start() { try { SDL.check(SDLProperties.SDL_SetNumberProperty(props, SDLKeyboard.SDL_PROP_TEXTINPUT_TYPE_NUMBER, this.kind.value()), "SDL_SetNumberProperty(" + SDLKeyboard.SDL_PROP_TEXTINPUT_TYPE_NUMBER + ")"); + SDL.check(SDLProperties.SDL_SetNumberProperty(props, SDLKeyboard.SDL_PROP_TEXTINPUT_CAPITALIZATION_NUMBER, this.capitalization.value()), + "SDL_SetNumberProperty(" + SDLKeyboard.SDL_PROP_TEXTINPUT_CAPITALIZATION_NUMBER + ")"); + SDL.check(SDLProperties.SDL_SetBooleanProperty(props, SDLKeyboard.SDL_PROP_TEXTINPUT_MULTILINE_BOOLEAN, this.multiline), + "SDL_SetBooleanProperty(" + SDLKeyboard.SDL_PROP_TEXTINPUT_MULTILINE_BOOLEAN + ")"); + SDL.check(SDLProperties.SDL_SetBooleanProperty(props, SDLKeyboard.SDL_PROP_TEXTINPUT_AUTOCORRECT_BOOLEAN, this.autocorrect), + "SDL_SetBooleanProperty(" + SDLKeyboard.SDL_PROP_TEXTINPUT_AUTOCORRECT_BOOLEAN + ")"); SDL.check(SDLKeyboard.SDL_StartTextInputWithProperties(this.handle(), props), "SDL_StartTextInputWithProperties"); } finally { SDLProperties.SDL_DestroyProperties(props); diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/virtual/TextInputKind.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/virtual/TextInputKind.java index f45ee9894..894c7e179 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/virtual/TextInputKind.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/virtual/TextInputKind.java @@ -20,7 +20,7 @@ public enum TextInputKind { this.value = value; } - int value() { + public int value() { return this.value; } From b1cc9bf845ffcd3a87b24afb075f39eb6d26c40b Mon Sep 17 00:00:00 2001 From: Rongmario Date: Wed, 19 Aug 2026 18:51:54 +0100 Subject: [PATCH 62/99] Drops --- .../client/sdl/drop/DropListener.java | 18 ++++ .../cleanroommc/client/sdl/drop/Drops.java | 96 +++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/drop/DropListener.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/drop/Drops.java diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/drop/DropListener.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/drop/DropListener.java new file mode 100644 index 000000000..86b561be4 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/drop/DropListener.java @@ -0,0 +1,18 @@ +package com.cleanroommc.client.sdl.drop; + +import java.nio.file.Path; + +/** File and text drops onto the host window. Called from {@link com.cleanroommc.client.sdl.Window#pump()}. */ +public interface DropListener { + + default void begin() { } + + default void file(Path path) { } + + default void text(String text) { } + + default void position(float x, float y) { } + + default void complete() { } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/drop/Drops.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/drop/Drops.java new file mode 100644 index 000000000..4f34ff318 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/drop/Drops.java @@ -0,0 +1,96 @@ +package com.cleanroommc.client.sdl.drop; + +import org.lwjgl.sdl.SDLEvents; +import org.lwjgl.sdl.SDL_DropEvent; +import org.lwjgl.sdl.SDL_Event; + +import java.nio.file.Path; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * Process-wide drop target. {@link com.cleanroommc.client.sdl.Window} forwards the SDL drop events here. + */ +public final class Drops { + + private static final List LISTENERS = new CopyOnWriteArrayList<>(); + + private Drops() { } + + public static void listen(DropListener listener) { + if (listener == null) { + throw new IllegalArgumentException("Listener cannot be null"); + } + LISTENERS.add(listener); + } + + public static void mute(DropListener listener) { + LISTENERS.remove(listener); + } + + public static void dispatchFile(Path path) { + if (path != null) { + file(path.toString()); + } + } + + public static void dispatchText(String text) { + text(text); + } + + public static void handle(SDL_Event event) { + SDL_DropEvent drop = event.drop(); + switch (event.type()) { + case SDLEvents.SDL_EVENT_DROP_BEGIN -> begin(); + case SDLEvents.SDL_EVENT_DROP_FILE -> file(drop.dataString()); + case SDLEvents.SDL_EVENT_DROP_TEXT -> text(drop.dataString()); + case SDLEvents.SDL_EVENT_DROP_POSITION -> position(drop.x(), drop.y()); + case SDLEvents.SDL_EVENT_DROP_COMPLETE -> complete(); + default -> { } + } + } + + static void begin() { + for (DropListener listener : LISTENERS) { + listener.begin(); + } + } + + static void file(String data) { + if (data == null || data.isEmpty()) { + return; + } + Path path = Path.of(data); + for (DropListener listener : LISTENERS) { + listener.file(path); + } + } + + static void text(String data) { + String value = data == null ? "" : data; + for (DropListener listener : LISTENERS) { + listener.text(value); + } + } + + static void position(float x, float y) { + for (DropListener listener : LISTENERS) { + listener.position(x, y); + } + } + + static void complete() { + for (DropListener listener : LISTENERS) { + listener.complete(); + } + } + + public static void reset() { + LISTENERS.clear(); + } + + public static int listenerCount() { + return LISTENERS.size(); + } + +} From a6f7c8249e1a44cc37ee86c396312465be7ab495 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Wed, 19 Aug 2026 21:51:36 +0100 Subject: [PATCH 63/99] Snap --- .../cleanroommc/client/sdl/camera/Camera.java | 156 ++++++++++++++++ .../client/sdl/camera/CameraListener.java | 14 ++ .../client/sdl/camera/CameraPermission.java | 33 ++++ .../client/sdl/camera/CameraPosition.java | 33 ++++ .../client/sdl/camera/CameraSpec.java | 29 +++ .../client/sdl/camera/Cameras.java | 171 ++++++++++++++++++ 6 files changed, 436 insertions(+) create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/camera/Camera.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/camera/CameraListener.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/camera/CameraPermission.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/camera/CameraPosition.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/camera/CameraSpec.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/camera/Cameras.java diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/camera/Camera.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/camera/Camera.java new file mode 100644 index 000000000..574d4c4fa --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/camera/Camera.java @@ -0,0 +1,156 @@ +package com.cleanroommc.client.sdl.camera; + +import com.cleanroommc.client.sdl.SDLException; +import com.cleanroommc.client.sdl.Surfaces; +import org.lwjgl.PointerBuffer; +import org.lwjgl.sdl.SDLCamera; +import org.lwjgl.sdl.SDLStdinc; +import org.lwjgl.sdl.SDL_CameraSpec; +import org.lwjgl.sdl.SDL_Surface; +import org.lwjgl.system.MemoryStack; + +import java.awt.image.BufferedImage; +import java.nio.LongBuffer; +import java.util.ArrayList; +import java.util.List; + +/** + * One camera. {@link #open} acquires the device, {@link #acquire} copies the latest frame into a Java image. + */ +public final class Camera implements AutoCloseable { + + private static CameraSpec fromNative(SDL_CameraSpec spec) { + return new CameraSpec(spec.width(), spec.height(), spec.format(), spec.framerate_numerator(), spec.framerate_denominator()); + } + + /** + * @param timestampNs SDL's timestamp, or {@code 0} if unknown + */ + public record Frame(int width, int height, int format, long timestampNs, BufferedImage image) { } + + private final int id; + + private long handle; + + Camera(int id) { + this.id = id; + } + + public int id() { + return id; + } + + public long handle() { + return handle; + } + + public String name() { + String name = SDLCamera.SDL_GetCameraName(id); + return name == null ? "" : name; + } + + public CameraPosition position() { + return CameraPosition.of(SDLCamera.SDL_GetCameraPosition(id)); + } + + public List formats() { + PointerBuffer pointers = SDLCamera.SDL_GetCameraSupportedFormats(id); + if (pointers == null) { + return List.of(); + } + try { + List specs = new ArrayList<>(pointers.remaining()); + while (pointers.hasRemaining()) { + SDL_CameraSpec spec = SDL_CameraSpec.createSafe(pointers.get()); + if (spec != null) { + specs.add(fromNative(spec)); + } + } + return List.copyOf(specs); + } finally { + SDLStdinc.SDL_free(pointers); + } + } + + public boolean opened() { + return handle != 0L; + } + + public Camera open() { + return open(null); + } + + public Camera open(CameraSpec spec) { + if (handle != 0L) { + return this; + } + if (spec == null) { + handle = SDLCamera.SDL_OpenCamera(id, null); + } else { + try (MemoryStack stack = MemoryStack.stackPush()) { + SDL_CameraSpec nativeSpec = SDL_CameraSpec.calloc(stack) + .format(spec.format()) + .width(spec.width()) + .height(spec.height()) + .framerate_numerator(spec.fpsNumerator()) + .framerate_denominator(spec.fpsDenominator()); + handle = SDLCamera.SDL_OpenCamera(id, nativeSpec); + } + } + if (handle == 0L) { + throw new SDLException("SDL_OpenCamera failed: " + org.lwjgl.sdl.SDLError.SDL_GetError()); + } + return this; + } + + public CameraPermission permission() { + if (handle == 0L) { + return CameraPermission.PENDING; + } + return CameraPermission.of(SDLCamera.SDL_GetCameraPermissionState(handle)); + } + + public CameraSpec spec() { + if (handle == 0L) { + return null; + } + try (MemoryStack stack = MemoryStack.stackPush()) { + SDL_CameraSpec nativeSpec = SDL_CameraSpec.calloc(stack); + if (!SDLCamera.SDL_GetCameraFormat(handle, nativeSpec)) { + return null; + } + return fromNative(nativeSpec); + } + } + + /** + * @return the latest frame, or {@code null} if none is ready + */ + public Frame acquire() { + if (handle == 0L) { + throw new IllegalStateException("The camera is not open"); + } + try (MemoryStack stack = MemoryStack.stackPush()) { + LongBuffer timestamp = stack.mallocLong(1); + SDL_Surface surface = SDLCamera.SDL_AcquireCameraFrame(handle, timestamp); + if (surface == null) { + return null; + } + try { + return new Frame(surface.w(), surface.h(), surface.format(), timestamp.get(0), Surfaces.toImage(surface)); + } finally { + SDLCamera.SDL_ReleaseCameraFrame(handle, surface); + } + } + } + + @Override + public void close() { + if (handle == 0L) { + return; + } + SDLCamera.SDL_CloseCamera(handle); + handle = 0L; + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/camera/CameraListener.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/camera/CameraListener.java new file mode 100644 index 000000000..cb38d7f26 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/camera/CameraListener.java @@ -0,0 +1,14 @@ +package com.cleanroommc.client.sdl.camera; + +/** Camera hotplug and permission. Called from {@link com.cleanroommc.client.sdl.Window#pump()}. */ +public interface CameraListener { + + default void added(Camera camera) { } + + default void removed(int id) { } + + default void approved(Camera camera) { } + + default void denied(int id) { } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/camera/CameraPermission.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/camera/CameraPermission.java new file mode 100644 index 000000000..15c216a0c --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/camera/CameraPermission.java @@ -0,0 +1,33 @@ +package com.cleanroommc.client.sdl.camera; + +import org.lwjgl.sdl.SDLCamera; + +import java.util.HashMap; +import java.util.Map; + +/** OS permission for an opened camera. */ +public enum CameraPermission { + + DENIED(SDLCamera.SDL_CAMERA_PERMISSION_STATE_DENIED), + PENDING(SDLCamera.SDL_CAMERA_PERMISSION_STATE_PENDING), + APPROVED(SDLCamera.SDL_CAMERA_PERMISSION_STATE_APPROVED); + + public static CameraPermission of(int value) { + return switch (value) { + case SDLCamera.SDL_CAMERA_PERMISSION_STATE_DENIED -> DENIED; + case SDLCamera.SDL_CAMERA_PERMISSION_STATE_APPROVED -> APPROVED; + default -> PENDING; + }; + } + + private final int value; + + CameraPermission(int value) { + this.value = value; + } + + public int value() { + return value; + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/camera/CameraPosition.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/camera/CameraPosition.java new file mode 100644 index 000000000..8d716e325 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/camera/CameraPosition.java @@ -0,0 +1,33 @@ +package com.cleanroommc.client.sdl.camera; + +import org.lwjgl.sdl.SDLCamera; + +import java.util.HashMap; +import java.util.Map; + +/** Front/back/unknown, as the OS reports it. */ +public enum CameraPosition { + + UNKNOWN(SDLCamera.SDL_CAMERA_POSITION_UNKNOWN), + FRONT(SDLCamera.SDL_CAMERA_POSITION_FRONT_FACING), + BACK(SDLCamera.SDL_CAMERA_POSITION_BACK_FACING); + + public static CameraPosition of(int value) { + return switch (value) { + case SDLCamera.SDL_CAMERA_POSITION_FRONT_FACING -> FRONT; + case SDLCamera.SDL_CAMERA_POSITION_BACK_FACING -> BACK; + default -> UNKNOWN; + }; + } + + private final int value; + + CameraPosition(int value) { + this.value = value; + } + + public int value() { + return value; + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/camera/CameraSpec.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/camera/CameraSpec.java new file mode 100644 index 000000000..516f6279d --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/camera/CameraSpec.java @@ -0,0 +1,29 @@ +package com.cleanroommc.client.sdl.camera; + +/** + * Requested or negotiated camera format. + * + * @param width pixels + * @param height pixels + * @param format SDL pixel format, or {@code 0} to let SDL pick + * @param fpsNumerator frames + * @param fpsDenominator per this many seconds + */ +public record CameraSpec(int width, int height, int format, int fpsNumerator, int fpsDenominator) { + + public static CameraSpec of(int width, int height) { + return new CameraSpec(width, height, 0, 0, 0); + } + + public static CameraSpec of(int width, int height, float fps) { + if (fps <= 0.0F) { + return of(width, height); + } + return new CameraSpec(width, height, 0, Math.round(fps * 1000.0F), 1000); + } + + public float fps() { + return fpsDenominator == 0 ? 0.0F : fpsNumerator / (float) fpsDenominator; + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/camera/Cameras.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/camera/Cameras.java new file mode 100644 index 000000000..230add662 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/camera/Cameras.java @@ -0,0 +1,171 @@ +package com.cleanroommc.client.sdl.camera; + +import com.cleanroommc.client.sdl.SDL; +import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import org.lwjgl.sdl.SDLCamera; +import org.lwjgl.sdl.SDLEvents; +import org.lwjgl.sdl.SDLInit; +import org.lwjgl.sdl.SDLStdinc; +import org.lwjgl.sdl.SDL_CameraDeviceEvent; +import org.lwjgl.sdl.SDL_Event; + +import java.nio.IntBuffer; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * Connected cameras. First use initializes {@code SDL_INIT_CAMERA}. + */ +public final class Cameras { + + private static final Cameras INSTANCE = new Cameras(); + + public static Cameras instance() { + return INSTANCE; + } + + public static List list() { + return INSTANCE.devices(); + } + + public static Camera first() { + List cameras = list(); + return cameras.isEmpty() ? null : cameras.getFirst(); + } + + public static Camera byId(int id) { + INSTANCE.ensure(); + return INSTANCE.cameras.get(id); + } + + public static void listen(CameraListener listener) { + if (listener == null) { + throw new IllegalArgumentException("Listener cannot be null"); + } + INSTANCE.listeners.add(listener); + } + + public static void mute(CameraListener listener) { + INSTANCE.listeners.remove(listener); + } + + public static void handle(SDL_Event event) { + INSTANCE.dispatch(event); + } + + public static void reset() { + INSTANCE.clear(); + } + + private final Int2ObjectMap cameras = new Int2ObjectArrayMap<>(); + private final List listeners = new CopyOnWriteArrayList<>(); + + private boolean started; + + private Cameras() { } + + synchronized List devices() { + ensure(); + return List.copyOf(cameras.values()); + } + + synchronized void ensure() { + if (started) { + return; + } + SDL.ensureSubsystem(SDLInit.SDL_INIT_CAMERA); + started = true; + openConnected(); + } + + synchronized void dispatch(SDL_Event event) { + if (!started) { + return; + } + int type = event.type(); + SDL_CameraDeviceEvent device = event.cdevice(); + int id = device.which(); + switch (type) { + case SDLEvents.SDL_EVENT_CAMERA_DEVICE_ADDED -> { + Camera camera = remember(id); + for (CameraListener listener : listeners) { + listener.added(camera); + } + } + case SDLEvents.SDL_EVENT_CAMERA_DEVICE_REMOVED -> { + Camera camera = cameras.remove(id); + if (camera != null) { + camera.close(); + } + for (CameraListener listener : listeners) { + listener.removed(id); + } + } + case SDLEvents.SDL_EVENT_CAMERA_DEVICE_APPROVED -> { + Camera camera = cameras.get(id); + if (camera != null) { + for (CameraListener listener : listeners) { + listener.approved(camera); + } + } + } + case SDLEvents.SDL_EVENT_CAMERA_DEVICE_DENIED -> { + for (CameraListener listener : listeners) { + listener.denied(id); + } + } + } + } + + synchronized void clear() { + for (Camera camera : cameras.values()) { + camera.close(); + } + cameras.clear(); + listeners.clear(); + started = false; + } + + synchronized Camera injectAdded(int id) { + started = true; + Camera camera = remember(id); + List snapshot = new ArrayList<>(listeners); + for (CameraListener listener : snapshot) { + listener.added(camera); + } + return camera; + } + + synchronized void injectRemoved(int id) { + Camera camera = cameras.remove(id); + if (camera != null) { + camera.close(); + } + for (CameraListener listener : listeners) { + listener.removed(id); + } + } + + private void openConnected() { + IntBuffer ids = SDLCamera.SDL_GetCameras(); + if (ids == null) { + return; + } + try { + while (ids.hasRemaining()) { + remember(ids.get()); + } + } finally { + SDLStdinc.SDL_free(ids); + } + } + + private Camera remember(int id) { + return cameras.computeIfAbsent(id, Camera::new); + } + +} From 994269966fcc323f7bf928e60f3a7e9f19cddf6d Mon Sep 17 00:00:00 2001 From: Rongmario Date: Wed, 19 Aug 2026 21:58:29 +0100 Subject: [PATCH 64/99] SDLException, oops --- .../java/com/cleanroommc/client/sdl/SDLException.java | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SDLException.java diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SDLException.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SDLException.java new file mode 100644 index 000000000..49e5edd33 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SDLException.java @@ -0,0 +1,9 @@ +package com.cleanroommc.client.sdl; + +public class SDLException extends RuntimeException { + + public SDLException(String message) { + super(message); + } + +} From dae5fb891918f55111c408d4e8e05447418b12d3 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Wed, 19 Aug 2026 22:01:56 +0100 Subject: [PATCH 65/99] HID Devices --- .../com/cleanroommc/client/sdl/hid/Hid.java | 118 ++++++++++++++++++ .../cleanroommc/client/sdl/hid/HidBus.java | 34 +++++ .../cleanroommc/client/sdl/hid/HidDevice.java | 98 +++++++++++++++ .../cleanroommc/client/sdl/hid/HidInfo.java | 7 ++ 4 files changed, 257 insertions(+) create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/hid/Hid.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/hid/HidBus.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/hid/HidDevice.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/hid/HidInfo.java diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/hid/Hid.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/hid/Hid.java new file mode 100644 index 000000000..d45331bad --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/hid/Hid.java @@ -0,0 +1,118 @@ +package com.cleanroommc.client.sdl.hid; + +import com.cleanroommc.client.sdl.SDL; +import com.cleanroommc.client.sdl.SDLException; +import org.lwjgl.sdl.SDLHIDAPI; +import org.lwjgl.sdl.SDL_hid_device_info; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Raw HID enumeration. First use calls {@code SDL_hid_init}. + */ +public final class Hid { + + private static final Set OPEN = new HashSet<>(); + private static boolean started; + + private Hid() { } + + public static List enumerate() { + return enumerate(0, 0); + } + + public static List enumerate(int vendor, int product) { + ensure(); + SDL_hid_device_info head = SDLHIDAPI.SDL_hid_enumerate((short) vendor, (short) product); + if (head == null) { + return List.of(); + } + try { + List devices = new ArrayList<>(); + for (SDL_hid_device_info info = head; info != null; info = info.next()) { + devices.add(fromNative(info)); + } + return List.copyOf(devices); + } finally { + SDLHIDAPI.SDL_hid_free_enumeration(head); + } + } + + public static HidDevice open(int vendor, int product) { + return open(vendor, product, null); + } + + public static HidDevice open(int vendor, int product, String serial) { + ensure(); + long handle = SDLHIDAPI.SDL_hid_open((short) vendor, (short) product, serial); + return track(handle, "SDL_hid_open"); + } + + public static HidDevice openPath(String path) { + if (path == null || path.isEmpty()) { + throw new IllegalArgumentException("Path cannot be empty"); + } + ensure(); + long handle = SDLHIDAPI.SDL_hid_open_path(path); + return track(handle, "SDL_hid_open_path"); + } + + public static int changeCount() { + ensure(); + return SDLHIDAPI.SDL_hid_device_change_count(); + } + + public static synchronized void reset() { + for (HidDevice device : Set.copyOf(OPEN)) { + device.close(); + } + OPEN.clear(); + if (started) { + SDLHIDAPI.SDL_hid_exit(); + started = false; + } + } + + static synchronized void forget(HidDevice device) { + OPEN.remove(device); + } + + static HidInfo fromNative(SDL_hid_device_info info) { + return new HidInfo( + empty(info.pathString()), + Short.toUnsignedInt(info.vendor_id()), + Short.toUnsignedInt(info.product_id()), + empty(info.serial_numberString()), + empty(info.manufacturer_stringString()), + empty(info.product_stringString()), + Short.toUnsignedInt(info.usage_page()), + Short.toUnsignedInt(info.usage()), + HidBus.of(info.bus_type()) + ); + } + + private static synchronized void ensure() { + if (started) { + return; + } + if (SDLHIDAPI.SDL_hid_init() < 0) { + throw new SDLException("SDL_hid_init failed"); + } + started = true; + } + + private static synchronized HidDevice track(long handle, String call) { + SDL.checkHandle(handle, call); + HidDevice device = new HidDevice(handle); + OPEN.add(device); + return device; + } + + private static String empty(String value) { + return value == null ? "" : value; + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/hid/HidBus.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/hid/HidBus.java new file mode 100644 index 000000000..8504863d8 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/hid/HidBus.java @@ -0,0 +1,34 @@ +package com.cleanroommc.client.sdl.hid; + +import org.lwjgl.sdl.SDLHIDAPI; + +/** Bus a HID device is attached to. */ +public enum HidBus { + + UNKNOWN(SDLHIDAPI.SDL_HID_API_BUS_UNKNOWN), + USB(SDLHIDAPI.SDL_HID_API_BUS_USB), + BLUETOOTH(SDLHIDAPI.SDL_HID_API_BUS_BLUETOOTH), + I2C(SDLHIDAPI.SDL_HID_API_BUS_I2C), + SPI(SDLHIDAPI.SDL_HID_API_BUS_SPI); + + public static HidBus of(int value) { + return switch (value) { + case SDLHIDAPI.SDL_HID_API_BUS_USB -> USB; + case SDLHIDAPI.SDL_HID_API_BUS_BLUETOOTH -> BLUETOOTH; + case SDLHIDAPI.SDL_HID_API_BUS_I2C -> I2C; + case SDLHIDAPI.SDL_HID_API_BUS_SPI -> SPI; + default -> UNKNOWN; + }; + } + + private final int value; + + HidBus(int value) { + this.value = value; + } + + public int value() { + return value; + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/hid/HidDevice.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/hid/HidDevice.java new file mode 100644 index 000000000..c9d1c45d1 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/hid/HidDevice.java @@ -0,0 +1,98 @@ +package com.cleanroommc.client.sdl.hid; + +import com.cleanroommc.client.sdl.SDL; +import com.cleanroommc.client.sdl.SDLException; +import org.lwjgl.sdl.SDLHIDAPI; +import org.lwjgl.sdl.SDL_hid_device_info; + +import java.nio.ByteBuffer; + +/** An open HID handle. */ +public final class HidDevice implements AutoCloseable { + + private final long handle; + + private boolean closed; + + HidDevice(long handle) { + this.handle = handle; + } + + public HidInfo info() { + SDL_hid_device_info info = SDLHIDAPI.SDL_hid_get_device_info(handle); + if (info == null) { + return null; + } + return Hid.fromNative(info); + } + + public int write(ByteBuffer data) { + ensureOpen(); + int written = SDLHIDAPI.SDL_hid_write(handle, data); + if (written < 0) { + throw new SDLException("SDL_hid_write failed"); + } + return written; + } + + public int read(ByteBuffer dest) { + ensureOpen(); + int read = SDLHIDAPI.SDL_hid_read(handle, dest); + if (read < 0) { + throw new SDLException("SDL_hid_read failed"); + } + return read; + } + + public int read(ByteBuffer dest, int timeoutMs) { + ensureOpen(); + int read = SDLHIDAPI.SDL_hid_read_timeout(handle, dest, timeoutMs); + if (read < 0) { + throw new SDLException("SDL_hid_read_timeout failed"); + } + return read; + } + + public int feature(ByteBuffer dest) { + ensureOpen(); + int read = SDLHIDAPI.SDL_hid_get_feature_report(handle, dest); + if (read < 0) { + throw new SDLException("SDL_hid_get_feature_report failed"); + } + return read; + } + + public int sendFeature(ByteBuffer data) { + ensureOpen(); + int written = SDLHIDAPI.SDL_hid_send_feature_report(handle, data); + if (written < 0) { + throw new SDLException("SDL_hid_send_feature_report failed"); + } + return written; + } + + public HidDevice nonblocking(boolean enabled) { + ensureOpen(); + if (SDLHIDAPI.SDL_hid_set_nonblocking(handle, enabled) < 0) { + throw new SDLException("SDL_hid_set_nonblocking failed"); + } + return this; + } + + private void ensureOpen() { + if (closed) { + throw new IllegalStateException("The HID device is closed"); + } + } + + @Override + public void close() { + if (closed) { + return; + } + closed = true; + Hid.forget(this); + SDLHIDAPI.SDL_hid_close(handle); + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/hid/HidInfo.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/hid/HidInfo.java new file mode 100644 index 000000000..56f61d84e --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/hid/HidInfo.java @@ -0,0 +1,7 @@ +package com.cleanroommc.client.sdl.hid; + +/** + * One enumerated HID device. Vendor/product are unsigned 16-bits. + */ +public record HidInfo(String path, int vendor, int product, String serial, String manufacturer, String productName, + int usagePage, int usage, HidBus bus) { } From b60211cf1cd51e469010bbfb7409c6aac47efddd Mon Sep 17 00:00:00 2001 From: Rongmario Date: Wed, 19 Aug 2026 22:05:32 +0100 Subject: [PATCH 66/99] Displays --- .../cleanroommc/client/sdl/video/Display.java | 117 ++++++++++++++++++ .../client/sdl/video/DisplayMode.java | 19 +++ .../client/sdl/video/Displays.java | 54 ++++++++ 3 files changed, 190 insertions(+) create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/video/Display.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/video/DisplayMode.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/video/Displays.java diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/video/Display.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/video/Display.java new file mode 100644 index 000000000..be883f49e --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/video/Display.java @@ -0,0 +1,117 @@ +package com.cleanroommc.client.sdl.video; + +import com.cleanroommc.client.sdl.SDL; +import org.lwjgl.PointerBuffer; +import org.lwjgl.sdl.SDLStdinc; +import org.lwjgl.sdl.SDLVideo; +import org.lwjgl.sdl.SDL_DisplayMode; +import org.lwjgl.sdl.SDL_Rect; +import org.lwjgl.system.MemoryStack; + +import java.util.ArrayList; +import java.util.List; + +/** One connected display. */ +public final class Display { + + public record Bounds(int x, int y, int width, int height) { } + + static DisplayMode snapshot(SDL_DisplayMode mode) { + return new DisplayMode(mode.displayID(), mode.format(), mode.w(), mode.h(), mode.pixel_density(), mode.refresh_rate()); + } + + private final int id; + + Display(int id) { + this.id = id; + } + + public int id() { + return id; + } + + public String name() { + String name = SDLVideo.SDL_GetDisplayName(id); + return name == null ? "" : name; + } + + public Bounds bounds() { + return bounds(false); + } + + public Bounds usableBounds() { + return bounds(true); + } + + public float contentScale() { + return SDLVideo.SDL_GetDisplayContentScale(id); + } + + public DisplayMode desktopMode() { + SDL_DisplayMode mode = SDLVideo.SDL_GetDesktopDisplayMode(id); + return mode == null ? null : snapshot(mode); + } + + public DisplayMode currentMode() { + SDL_DisplayMode mode = SDLVideo.SDL_GetCurrentDisplayMode(id); + return mode == null ? null : snapshot(mode); + } + + public List modes() { + PointerBuffer pointers = SDLVideo.SDL_GetFullscreenDisplayModes(id); + if (pointers == null) { + return List.of(); + } + try { + List modes = new ArrayList<>(pointers.remaining()); + while (pointers.hasRemaining()) { + SDL_DisplayMode mode = SDL_DisplayMode.createSafe(pointers.get()); + if (mode != null) { + modes.add(snapshot(mode)); + } + } + return List.copyOf(modes); + } finally { + SDLStdinc.SDL_free(pointers); + } + } + + DisplayMode match(int width, int height, float refreshRate) { + DisplayMode best = null; + for (DisplayMode mode : modes()) { + if (!mode.matches(width, height, 0)) { + continue; + } + if (refreshRate <= 0 || mode.matches(width, height, refreshRate)) { + return mode; + } + if (best == null) { + best = mode; + } + } + return best; + } + + private Bounds bounds(boolean usable) { + try (MemoryStack stack = MemoryStack.stackPush()) { + SDL_Rect rect = SDL_Rect.calloc(stack); + if (usable) { + SDL.check(SDLVideo.SDL_GetDisplayUsableBounds(id, rect), "SDL_GetDisplayUsableBounds"); + } else { + SDL.check(SDLVideo.SDL_GetDisplayBounds(id, rect), "SDL_GetDisplayBounds"); + } + return new Bounds(rect.x(), rect.y(), rect.w(), rect.h()); + } + } + + @Override + public boolean equals(Object other) { + return other instanceof Display display && display.id == id; + } + + @Override + public int hashCode() { + return id; + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/video/DisplayMode.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/video/DisplayMode.java new file mode 100644 index 000000000..a19575881 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/video/DisplayMode.java @@ -0,0 +1,19 @@ +package com.cleanroommc.client.sdl.video; + +/** + * A fullscreen mode on a display. + * + * @param displayId SDL display id + * @param format SDL pixel format + * @param width width in screen coordinates + * @param height height in screen coordinates + * @param pixelDensity pixel density + * @param refreshRate refresh rate in Hz, or {@code 0} when unknown + */ +public record DisplayMode(int displayId, int format, int width, int height, float pixelDensity, float refreshRate) { + + public boolean matches(int width, int height, float refreshRate) { + return this.width == width && this.height == height && (refreshRate <= 0 || Math.abs(this.refreshRate - refreshRate) < 0.5F); + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/video/Displays.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/video/Displays.java new file mode 100644 index 000000000..db2ef4195 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/video/Displays.java @@ -0,0 +1,54 @@ +package com.cleanroommc.client.sdl.video; + +import com.cleanroommc.client.sdl.SDL; +import org.lwjgl.sdl.SDLStdinc; +import org.lwjgl.sdl.SDLVideo; + +import java.nio.IntBuffer; +import java.util.ArrayList; +import java.util.List; + +/** Connected displays. Requires the video subsystem. */ +public final class Displays { + + public static List all() { + SDL.ensureVideo(); + IntBuffer ids = SDLVideo.SDL_GetDisplays(); + if (ids == null) { + return List.of(); + } + try { + List displays = new ArrayList<>(ids.remaining()); + while (ids.hasRemaining()) { + displays.add(new Display(ids.get())); + } + return List.copyOf(displays); + } finally { + SDLStdinc.SDL_free(ids); + } + } + + public static Display primary() { + SDL.ensureVideo(); + int id = SDLVideo.SDL_GetPrimaryDisplay(); + return id == 0 ? null : new Display(id); + } + + public static Display of(int id) { + return id == 0 ? null : new Display(id); + } + + public static String driver() { + SDL.ensureVideo(); + String name = SDLVideo.SDL_GetCurrentVideoDriver(); + return name == null ? "" : name; + } + + /** Called from the window pump when a display comes or goes. */ + public static void handle(int eventType, int displayId) { + // Display lists are queried live + } + + private Displays() { } + +} From 45de5a0d6afd256556a35476d747455a78f39be2 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Wed, 19 Aug 2026 22:16:31 +0100 Subject: [PATCH 67/99] Clipboard --- .../com/cleanroommc/client/sdl/Clipboard.java | 221 ++++++++++++++++++ 1 file changed, 221 insertions(+) create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Clipboard.java diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Clipboard.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Clipboard.java new file mode 100644 index 000000000..c823cf561 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Clipboard.java @@ -0,0 +1,221 @@ +package com.cleanroommc.client.sdl; + +import org.lwjgl.PointerBuffer; +import org.lwjgl.sdl.SDLClipboard; +import org.lwjgl.sdl.SDLIOStream; +import org.lwjgl.sdl.SDLStdinc; +import org.lwjgl.sdl.SDLSurface; +import org.lwjgl.sdl.SDL_ClipboardCleanupCallback; +import org.lwjgl.sdl.SDL_ClipboardDataCallback; +import org.lwjgl.sdl.SDL_Surface; +import org.lwjgl.system.MemoryStack; +import org.lwjgl.system.MemoryUtil; +import org.lwjgl.system.Pointer; + +import java.awt.image.BufferedImage; +import java.nio.ByteBuffer; +import java.util.Optional; + +/** + * System clipboard and X11 primary selection. + */ +public final class Clipboard { + + private static final String IMAGE_PNG = "image/png"; + private static final String IMAGE_BMP = "image/bmp"; + + private static volatile boolean textKnown; + private static volatile boolean hasText; + + private static ByteBuffer offeredImage; + private static SDL_ClipboardDataCallback imageData; + private static SDL_ClipboardCleanupCallback imageCleanup; + + public static boolean hasText() { + if (textKnown) { + return hasText; + } + return SDLClipboard.SDL_HasClipboardText(); + } + + public static String text() { + String value = SDLClipboard.SDL_GetClipboardText(); + String text = value == null ? "" : value; + cache(!text.isEmpty()); + return text; + } + + public static void text(String value) { + if (value == null) { + value = ""; + } + SDL.check(SDLClipboard.SDL_SetClipboardText(value), "SDL_SetClipboardText"); + cache(!value.isEmpty()); + } + + public static boolean hasPrimary() { + return SDLClipboard.SDL_HasPrimarySelectionText(); + } + + public static String primary() { + String value = SDLClipboard.SDL_GetPrimarySelectionText(); + return value == null ? "" : value; + } + + public static void primary(String value) { + if (value == null) { + value = ""; + } + SDL.check(SDLClipboard.SDL_SetPrimarySelectionText(value), "SDL_SetPrimarySelectionText"); + } + + public static boolean has(String mime) { + return mime != null && SDLClipboard.SDL_HasClipboardData(mime); + } + + public static Optional data(String mime) { + if (mime == null) { + return Optional.empty(); + } + ByteBuffer buffer = SDLClipboard.SDL_GetClipboardData(mime); + return Optional.ofNullable(buffer); + } + + public static void free(ByteBuffer data) { + if (data != null) { + SDLStdinc.SDL_free(data); + } + } + + public static boolean hasImage() { + return has(IMAGE_PNG) || has(IMAGE_BMP); + } + + public static Optional image() { + Optional png = data(IMAGE_PNG); + if (png.isPresent()) { + return Optional.ofNullable(decode(png.get(), true)); + } + Optional bmp = data(IMAGE_BMP); + if (bmp.isPresent()) { + return Optional.ofNullable(decode(bmp.get(), false)); + } + return Optional.empty(); + } + + public static void image(BufferedImage image) { + if (image == null) { + throw new IllegalArgumentException("Image cannot be null"); + } + SDL_Surface surface = Surfaces.from(image); + ByteBuffer png; + try { + png = encodePng(surface); + } finally { + SDLSurface.SDL_DestroySurface(surface); + } + offer(png); + } + + /** Called from the window pump when {@code SDL_EVENT_CLIPBOARD_UPDATE} arrives. */ + public static void updated() { + textKnown = false; + } + + static void cache(boolean present) { + hasText = present; + textKnown = true; + } + + static boolean cachedPresent() { + return textKnown && hasText; + } + + static boolean cacheValid() { + return textKnown; + } + + public static void reset() { + textKnown = false; + hasText = false; + clearOffer(); + } + + private static BufferedImage decode(ByteBuffer bytes, boolean png) { + try { + long io = SDLIOStream.SDL_IOFromConstMem(bytes); + if (io == 0L) { + return null; + } + SDL_Surface surface = png ? SDLSurface.SDL_LoadPNG_IO(io, true) : SDLSurface.SDL_LoadBMP_IO(io, true); + if (surface == null) { + return null; + } + try { + return Surfaces.toImage(surface); + } finally { + SDLSurface.SDL_DestroySurface(surface); + } + } finally { + free(bytes); + } + } + + private static ByteBuffer encodePng(SDL_Surface surface) { + long io = SDL.checkHandle(SDLIOStream.SDL_IOFromDynamicMem(), "SDL_IOFromDynamicMem"); + boolean closed = false; + try { + SDL.check(SDLSurface.SDL_SavePNG_IO(surface, io, false), "SDL_SavePNG_IO"); + long size = SDLIOStream.SDL_GetIOSize(io); + if (size < 0L || SDLIOStream.SDL_SeekIO(io, 0L, SDLIOStream.SDL_IO_SEEK_SET) < 0L) { + throw new SDLException("SDL_GetIOSize/SeekIO failed"); + } + ByteBuffer dest = MemoryUtil.memAlloc((int) size); + long read = SDLIOStream.SDL_ReadIO(io, dest); + dest.limit((int) Math.max(0L, read)).position(0); + return dest; + } catch (RuntimeException failure) { + SDLIOStream.SDL_CloseIO(io); + closed = true; + throw failure; + } finally { + if (!closed) { + SDLIOStream.SDL_CloseIO(io); + } + } + } + + private static synchronized void offer(ByteBuffer png) { + clearOffer(); + offeredImage = png; + if (imageData == null) { + imageData = SDL_ClipboardDataCallback.create((_, mime, size) -> { + ByteBuffer offered = offeredImage; + if (offered == null || !IMAGE_PNG.equals(MemoryUtil.memUTF8(mime))) { + return 0L; + } + if (Pointer.BITS64) { + MemoryUtil.memPutLong(size, offered.remaining()); + } else { + MemoryUtil.memPutInt(size, offered.remaining()); + } + return MemoryUtil.memAddress(offered); + }); + imageCleanup = SDL_ClipboardCleanupCallback.create(_ -> clearOffer()); + } + try (MemoryStack stack = MemoryStack.stackPush()) { + PointerBuffer mimes = stack.pointers(stack.UTF8(IMAGE_PNG)); + SDL.check(SDLClipboard.SDL_SetClipboardData(imageData, imageCleanup, 0L, mimes), "SDL_SetClipboardData"); + } + } + + private static synchronized void clearOffer() { + if (offeredImage != null) { + MemoryUtil.memFree(offeredImage); + offeredImage = null; + } + } + + private Clipboard() { } + +} From da32c6ad9ccbecea8dc5f94664d82d01860d7821 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Wed, 19 Aug 2026 22:24:10 +0100 Subject: [PATCH 68/99] Some more SDL funny moments --- .../cleanroommc/client/sdl/Compositor.java | 35 ++++ .../com/cleanroommc/client/sdl/Desktop.java | 44 +++++ .../com/cleanroommc/client/sdl/Devices.java | 32 ++++ .../cleanroommc/client/sdl/FileDialogs.java | 166 ++++++++++++++++++ .../cleanroommc/client/sdl/FileSystem.java | 103 +++++++++++ .../com/cleanroommc/client/sdl/Folder.java | 47 +++++ .../cleanroommc/client/sdl/input/Cursor.java | 70 ++++++++ .../cleanroommc/client/sdl/input/Finger.java | 4 + 8 files changed, 501 insertions(+) create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Compositor.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Desktop.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Devices.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/FileDialogs.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/FileSystem.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Folder.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Cursor.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Finger.java diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Compositor.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Compositor.java new file mode 100644 index 000000000..f05a8b0d4 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Compositor.java @@ -0,0 +1,35 @@ +package com.cleanroommc.client.sdl; + +import org.lwjgl.sdl.SDLVideo; + +/** + * The platform window system that owns {@link NativeWindow#handle()}. + */ +public enum Compositor { + + WIN32(SDLVideo.SDL_PROP_WINDOW_WIN32_HWND_POINTER, true), + WAYLAND(SDLVideo.SDL_PROP_WINDOW_WAYLAND_SURFACE_POINTER, true), + X11(SDLVideo.SDL_PROP_WINDOW_X11_WINDOW_NUMBER, false), + COCOA(SDLVideo.SDL_PROP_WINDOW_COCOA_WINDOW_POINTER, true), + ANDROID(SDLVideo.SDL_PROP_WINDOW_ANDROID_WINDOW_POINTER, true), + UIKIT(SDLVideo.SDL_PROP_WINDOW_UIKIT_WINDOW_POINTER, true), + VIVANTE(SDLVideo.SDL_PROP_WINDOW_VIVANTE_WINDOW_POINTER, true), + UNKNOWN("", false); + + private final String property; + private final boolean pointer; + + Compositor(String property, boolean pointer) { + this.property = property; + this.pointer = pointer; + } + + public String property() { + return property; + } + + public boolean pointer() { + return pointer; + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Desktop.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Desktop.java new file mode 100644 index 000000000..f2cc242df --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Desktop.java @@ -0,0 +1,44 @@ +package com.cleanroommc.client.sdl; + +import org.lwjgl.sdl.SDLMisc; + +import java.io.File; +import java.net.URI; +import java.nio.file.Path; + +/** + * Opens URLs and files with the platform handler ({@code SDL_OpenURL}). + */ +public final class Desktop { + + public static void open(URI uri) { + if (uri == null) { + throw new IllegalArgumentException("URI cannot be null"); + } + open(uri.toString()); + } + + public static void open(Path path) { + if (path == null) { + throw new IllegalArgumentException("Path cannot be null"); + } + open(path.toAbsolutePath().toUri()); + } + + public static void open(File file) { + if (file == null) { + throw new IllegalArgumentException("File cannot be null"); + } + open(file.toPath()); + } + + public static void open(String url) { + if (url == null || url.isEmpty()) { + throw new IllegalArgumentException("URL cannot be empty"); + } + SDL.check(SDLMisc.SDL_OpenURL(url), "SDL_OpenURL"); + } + + private Desktop() { } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Devices.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Devices.java new file mode 100644 index 000000000..471d65788 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Devices.java @@ -0,0 +1,32 @@ +package com.cleanroommc.client.sdl; + +import com.cleanroommc.client.sdl.camera.Cameras; +import com.cleanroommc.client.sdl.drop.Drops; +import com.cleanroommc.client.sdl.hid.Hid; +import com.cleanroommc.client.sdl.input.Inputs; +import org.lwjgl.sdl.SDL_Event; + +/** {@link Window#pump()} delegates to optional device registries. */ +final class Devices { + + static void dispatch(SDL_Event event) { + Inputs.dispatch(event); + Cameras.handle(event); + } + + static void afterPump() { + Tray.pump(); + } + + static void reset() { + Inputs.reset(); + Cameras.reset(); + Hid.reset(); + Tray.reset(); + Clipboard.reset(); + Drops.reset(); + } + + private Devices() { } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/FileDialogs.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/FileDialogs.java new file mode 100644 index 000000000..dacf44b65 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/FileDialogs.java @@ -0,0 +1,166 @@ +package com.cleanroommc.client.sdl; + +import org.lwjgl.sdl.SDLDialog; +import org.lwjgl.sdl.SDLMessageBox; +import org.lwjgl.sdl.SDL_DialogFileCallback; +import org.lwjgl.sdl.SDL_DialogFileFilter; +import org.lwjgl.sdl.SDL_MessageBoxButtonData; +import org.lwjgl.sdl.SDL_MessageBoxData; +import org.lwjgl.system.MemoryStack; +import org.lwjgl.system.MemoryUtil; + +import java.nio.IntBuffer; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + +/** + * Native message boxes and file dialogs. + * + *

File dialogs complete on a later {@link Window#pump()} and invoke {@code onResult} on that thread. + */ +public final class FileDialogs { + + public record Filter(String name, String pattern) { } + + public record Button(int id, String text, boolean isDefault, boolean isEscape) { + + public Button(int id, String text) { + this(id, text, false, false); + } + + } + + public static void error(Window window, String title, String message) { + box(SDLMessageBox.SDL_MESSAGEBOX_ERROR, window, title, message); + } + + public static void warn(Window window, String title, String message) { + box(SDLMessageBox.SDL_MESSAGEBOX_WARNING, window, title, message); + } + + public static void info(Window window, String title, String message) { + box(SDLMessageBox.SDL_MESSAGEBOX_INFORMATION, window, title, message); + } + + /** + * Blocking custom button box. + * + * @return the id of the button that was pressed, or {@code -1} if the box was dismissed + */ + public static int ask(Window window, String title, String message, Button... buttons) { + if (buttons == null || buttons.length == 0) { + throw new IllegalArgumentException("At least one button is required"); + } + try (MemoryStack stack = MemoryStack.stackPush()) { + SDL_MessageBoxButtonData.Buffer nativeButtons = SDL_MessageBoxButtonData.calloc(buttons.length, stack); + for (int i = 0; i < buttons.length; i++) { + Button button = buttons[i]; + int flags = 0; + if (button.isDefault()) { + flags |= SDLMessageBox.SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT; + } + if (button.isEscape()) { + flags |= SDLMessageBox.SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT; + } + nativeButtons.get(i) + .flags(flags) + .buttonID(button.id()) + .text(stack.UTF8(button.text())); + } + SDL_MessageBoxData data = SDL_MessageBoxData.calloc(stack); + data.flags(0) + .window(handle(window)) + .title(stack.UTF8(title == null ? "" : title)) + .message(stack.UTF8(message == null ? "" : message)) + .buttons(nativeButtons); + IntBuffer pressed = stack.mallocInt(1); + SDL.check(SDLMessageBox.SDL_ShowMessageBox(data, pressed), "SDL_ShowMessageBox"); + return pressed.get(0); + } + } + + public static void openFile(Window window, List filters, boolean many, Consumer> onResult) { + fileDialog(window, filters, many, null, true, false, onResult); + } + + public static void saveFile(Window window, List filters, String defaultLocation, Consumer> onResult) { + fileDialog(window, filters, false, defaultLocation, false, false, onResult); + } + + public static void openFolder(Window window, boolean many, Consumer> onResult) { + fileDialog(window, List.of(), many, null, false, true, onResult); + } + + private static void fileDialog(Window window, List filters, boolean many, String location, + boolean openFile, boolean folder, Consumer> onResult) { + if (onResult == null) { + throw new IllegalArgumentException("onResult cannot be null"); + } + SDL_DialogFileCallback[] holder = new SDL_DialogFileCallback[1]; + holder[0] = SDL_DialogFileCallback.create((userdata, filelist, filter) -> { + try { + onResult.accept(readPaths(filelist)); + } finally { + if (holder[0] != null) { + holder[0].free(); + } + } + }); + try (MemoryStack stack = MemoryStack.stackPush()) { + SDL_DialogFileFilter.Buffer nativeFilters = filters == null || filters.isEmpty() + ? null : SDL_DialogFileFilter.calloc(filters.size(), stack); + if (nativeFilters != null) { + for (int i = 0; i < filters.size(); i++) { + Filter filter = filters.get(i); + nativeFilters.get(i) + .name(stack.UTF8(filter.name())) + .pattern(stack.UTF8(filter.pattern())); + } + } + long parent = handle(window); + java.nio.ByteBuffer where = (location == null || location.isEmpty()) ? null : stack.UTF8(location); + if (folder) { + SDLDialog.SDL_ShowOpenFolderDialog(holder[0], 0L, parent, where, many); + } else if (openFile) { + SDLDialog.SDL_ShowOpenFileDialog(holder[0], 0L, parent, nativeFilters, where, many); + } else { + SDLDialog.SDL_ShowSaveFileDialog(holder[0], 0L, parent, nativeFilters, where); + } + } + } + + private static List readPaths(long filelist) { + List paths = new ArrayList<>(); + if (filelist == 0L) { + return paths; + } + int pointerSize = org.lwjgl.system.Pointer.POINTER_SIZE; + for (int i = 0; ; i++) { + long address = MemoryUtil.memGetAddress(filelist + (long) i * pointerSize); + if (address == 0L) { + break; + } + String value = MemoryUtil.memUTF8Safe(address); + if (value != null && !value.isEmpty()) { + paths.add(Path.of(value)); + } + } + return paths; + } + + private static void box(int flags, Window window, String title, String message) { + SDL.check(SDLMessageBox.SDL_ShowSimpleMessageBox(flags, + title == null ? "" : title, + message == null ? "" : message, + handle(window)), "SDL_ShowSimpleMessageBox"); + } + + private static long handle(Window window) { + return window == null ? 0L : window.handle(); + } + + private FileDialogs() { } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/FileSystem.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/FileSystem.java new file mode 100644 index 000000000..ff02bef52 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/FileSystem.java @@ -0,0 +1,103 @@ +package com.cleanroommc.client.sdl; + +import org.lwjgl.PointerBuffer; +import org.lwjgl.sdl.SDLFileSystem; +import org.lwjgl.sdl.SDLStdinc; +import org.lwjgl.sdl.SDL_PathInfo; +import org.lwjgl.system.MemoryStack; +import org.lwjgl.system.MemoryUtil; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +/** + * OS well-known folders and path queries. Not a replacement for {@code java.nio.file}. + */ +public final class FileSystem { + + public static Path base() { + return pathOrNull(SDLFileSystem.SDL_GetBasePath()); + } + + public static Path pref(String org, String app) { + if (org == null || app == null) { + throw new IllegalArgumentException("org and app cannot be null"); + } + return pathOrNull(SDLFileSystem.SDL_GetPrefPath(org, app)); + } + + public static Path current() { + return pathOrNull(SDLFileSystem.SDL_GetCurrentDirectory()); + } + + public static Path folder(Folder folder) { + if (folder == null) { + throw new IllegalArgumentException("Folder cannot be null"); + } + return pathOrNull(SDLFileSystem.SDL_GetUserFolder(folder.value())); + } + + public static Optional info(Path path) { + if (path == null) { + return Optional.empty(); + } + return info(path.toAbsolutePath().toString()); + } + + public static Optional info(String path) { + if (path == null || path.isEmpty()) { + return Optional.empty(); + } + try (MemoryStack stack = MemoryStack.stackPush()) { + SDL_PathInfo nativeInfo = SDL_PathInfo.calloc(stack); + if (!SDLFileSystem.SDL_GetPathInfo(path, nativeInfo)) { + return Optional.empty(); + } + return Optional.of(new PathInfo( + PathKind.of(nativeInfo.type()), + nativeInfo.size(), + nativeInfo.create_time(), + nativeInfo.modify_time(), + nativeInfo.access_time() + )); + } + } + + public static List glob(Path directory, String pattern) { + if (directory == null) { + throw new IllegalArgumentException("Directory cannot be null"); + } + return glob(directory.toAbsolutePath().toString(), pattern); + } + + public static List glob(String directory, String pattern) { + if (directory == null) { + throw new IllegalArgumentException("Directory cannot be null"); + } + PointerBuffer matches = SDLFileSystem.SDL_GlobDirectory(directory, pattern, 0); + if (matches == null) { + return List.of(); + } + try { + List paths = new ArrayList<>(matches.remaining()); + while (matches.hasRemaining()) { + String value = MemoryUtil.memUTF8(matches.get()); + if (value != null && !value.isEmpty()) { + paths.add(Path.of(value)); + } + } + return List.copyOf(paths); + } finally { + SDLStdinc.SDL_free(matches); + } + } + + private static Path pathOrNull(String value) { + return value == null || value.isEmpty() ? null : Path.of(value); + } + + private FileSystem() { } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Folder.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Folder.java new file mode 100644 index 000000000..21867ca4e --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Folder.java @@ -0,0 +1,47 @@ +package com.cleanroommc.client.sdl; + +import org.lwjgl.sdl.SDLFileSystem; + +/** OS well-known folders from {@code SDL_GetUserFolder}. */ +public enum Folder { + + HOME(SDLFileSystem.SDL_FOLDER_HOME), + DESKTOP(SDLFileSystem.SDL_FOLDER_DESKTOP), + DOCUMENTS(SDLFileSystem.SDL_FOLDER_DOCUMENTS), + DOWNLOADS(SDLFileSystem.SDL_FOLDER_DOWNLOADS), + MUSIC(SDLFileSystem.SDL_FOLDER_MUSIC), + PICTURES(SDLFileSystem.SDL_FOLDER_PICTURES), + PUBLIC_SHARE(SDLFileSystem.SDL_FOLDER_PUBLICSHARE), + SAVED_GAMES(SDLFileSystem.SDL_FOLDER_SAVEDGAMES), + SCREENSHOTS(SDLFileSystem.SDL_FOLDER_SCREENSHOTS), + TEMPLATES(SDLFileSystem.SDL_FOLDER_TEMPLATES), + VIDEOS(SDLFileSystem.SDL_FOLDER_VIDEOS); + + public static Folder of(int value) { + return switch (value) { + case SDLFileSystem.SDL_FOLDER_HOME -> HOME; + case SDLFileSystem.SDL_FOLDER_DESKTOP -> DESKTOP; + case SDLFileSystem.SDL_FOLDER_DOCUMENTS -> DOCUMENTS; + case SDLFileSystem.SDL_FOLDER_DOWNLOADS -> DOWNLOADS; + case SDLFileSystem.SDL_FOLDER_MUSIC -> MUSIC; + case SDLFileSystem.SDL_FOLDER_PICTURES -> PICTURES; + case SDLFileSystem.SDL_FOLDER_PUBLICSHARE -> PUBLIC_SHARE; + case SDLFileSystem.SDL_FOLDER_SAVEDGAMES -> SAVED_GAMES; + case SDLFileSystem.SDL_FOLDER_SCREENSHOTS -> SCREENSHOTS; + case SDLFileSystem.SDL_FOLDER_TEMPLATES -> TEMPLATES; + case SDLFileSystem.SDL_FOLDER_VIDEOS -> VIDEOS; + default -> null; + }; + } + + private final int value; + + Folder(int value) { + this.value = value; + } + + public int value() { + return value; + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Cursor.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Cursor.java new file mode 100644 index 000000000..3664c06f8 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Cursor.java @@ -0,0 +1,70 @@ +package com.cleanroommc.client.sdl.input; + +import com.cleanroommc.client.sdl.SDL; +import com.cleanroommc.client.sdl.Surfaces; +import org.lwjgl.sdl.SDLMouse; +import org.lwjgl.sdl.SDLSurface; +import org.lwjgl.sdl.SDL_Surface; + +import java.awt.image.BufferedImage; + +/** A color cursor owned by the caller. Destroy it, or let {@link Inputs#reset()} do so. */ +public final class Cursor implements AutoCloseable { + + public static Cursor of(BufferedImage image) { + return of(image, 0, 0); + } + + public static Cursor of(BufferedImage image, int hotX, int hotY) { + SDL_Surface surface = Surfaces.from(image); + try { + long handle = SDL.checkHandle(SDLMouse.SDL_CreateColorCursor(surface, hotX, hotY), "SDL_CreateColorCursor"); + Cursor cursor = new Cursor(handle, false); + Inputs.track(cursor); + return cursor; + } finally { + SDLSurface.SDL_DestroySurface(surface); + } + } + + static Cursor system(SystemCursor kind) { + long handle = SDL.checkHandle(SDLMouse.SDL_CreateSystemCursor(kind.value()), "SDL_CreateSystemCursor"); + return new Cursor(handle, true); + } + + private final long handle; + private final boolean system; + + private boolean closed; + + private Cursor(long handle, boolean system) { + this.handle = handle; + this.system = system; + } + + void apply() { + ensureOpen(); + SDL.check(SDLMouse.SDL_SetCursor(handle), "SDL_SetCursor"); + } + + boolean system() { + return system; + } + + private void ensureOpen() { + if (closed) { + throw new IllegalStateException("The cursor is closed"); + } + } + + @Override + public void close() { + if (closed) { + return; + } + closed = true; + SDLMouse.SDL_DestroyCursor(handle); + Inputs.forget(this); + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Finger.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Finger.java new file mode 100644 index 000000000..d66213bd8 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Finger.java @@ -0,0 +1,4 @@ +package com.cleanroommc.client.sdl.input; + +/** One touch finger. Coordinates are normalized {@code 0..1}. */ +public record Finger(long id, float x, float y, float pressure) { } From 2a7df65758841fcb41fd8aec87b07f2aed4b6297 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Wed, 19 Aug 2026 22:24:50 +0100 Subject: [PATCH 69/99] Gamepads --- .../cleanroommc/client/sdl/input/Gamepad.java | 197 ++++++++++++++++++ .../client/sdl/input/GamepadAxis.java | 41 ++++ .../client/sdl/input/GamepadButton.java | 77 +++++++ .../client/sdl/input/GamepadLabel.java | 42 ++++ .../client/sdl/input/GamepadListener.java | 16 ++ .../client/sdl/input/GamepadType.java | 48 +++++ .../client/sdl/input/Gamepads.java | 189 +++++++++++++++++ .../client/sdl/input/GamepadsTest.java | 22 ++ 8 files changed, 632 insertions(+) create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Gamepad.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/GamepadAxis.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/GamepadButton.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/GamepadLabel.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/GamepadListener.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/GamepadType.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Gamepads.java create mode 100644 module/cleanroom/src/test/java/com/cleanroommc/client/sdl/input/GamepadsTest.java diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Gamepad.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Gamepad.java new file mode 100644 index 000000000..d5f0c6a56 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Gamepad.java @@ -0,0 +1,197 @@ +package com.cleanroommc.client.sdl.input; + +import com.cleanroommc.client.sdl.SDL; +import org.lwjgl.sdl.SDLGamepad; +import org.lwjgl.system.MemoryStack; + +import java.nio.ByteBuffer; +import java.nio.FloatBuffer; + +/** + * One mapped gamepad. Query buttons, axes and rumble if the pad supports it. + */ +public final class Gamepad { + + static final float DEFAULT_DEADZONE = 0.2F; + static final float AXIS_SCALE = 32767.0F; + + private final int instanceId; + private final long handle; + + Gamepad(int instanceId, long handle) { + this.instanceId = instanceId; + this.handle = handle; + } + + public int id() { + return instanceId; + } + + public String name() { + String name = SDLGamepad.SDL_GetGamepadName(handle); + return name == null ? "" : name; + } + + public GamepadType type() { + return GamepadType.of(SDLGamepad.SDL_GetGamepadType(handle)); + } + + public boolean connected() { + return SDLGamepad.SDL_GamepadConnected(handle); + } + + public boolean button(GamepadButton button) { + return button != null && SDLGamepad.SDL_GetGamepadButton(handle, button.value()); + } + + /** + * @return {@code [-1, 1]} for sticks, {@code [0, 1]} for triggers, after the default deadzone + */ + public float axis(GamepadAxis axis) { + return axis(axis, DEFAULT_DEADZONE); + } + + public float axis(GamepadAxis axis, float deadzone) { + if (axis == null) { + return 0.0F; + } + float raw = SDLGamepad.SDL_GetGamepadAxis(handle, axis.value()) / AXIS_SCALE; + if (axis.trigger()) { + return raw < deadzone ? 0.0F : Math.min(1.0F, raw); + } + float magnitude = Math.abs(raw); + if (magnitude < deadzone) { + return 0.0F; + } + float scaled = (magnitude - deadzone) / (1.0F - deadzone); + return Math.copySign(Math.min(1.0F, scaled), raw); + } + + public GamepadLabel label(GamepadButton button) { + if (button == null) { + return GamepadLabel.UNKNOWN; + } + return GamepadLabel.of(SDLGamepad.SDL_GetGamepadButtonLabel(handle, button.value())); + } + + public int playerIndex() { + return SDLGamepad.SDL_GetGamepadPlayerIndex(handle); + } + + public Gamepad playerIndex(int index) { + SDL.check(SDLGamepad.SDL_SetGamepadPlayerIndex(handle, index), "SDL_SetGamepadPlayerIndex"); + return this; + } + + /** + * @param low low-frequency rumble, {@code 0..1} + * @param high high-frequency rumble, {@code 0..1} + * @param durationMs how long to rumble + */ + public Gamepad rumble(float low, float high, int durationMs) { + SDL.check(SDLGamepad.SDL_RumbleGamepad(handle, toStrength(low), toStrength(high), durationMs), "SDL_RumbleGamepad"); + return this; + } + + public Gamepad rumbleTriggers(float left, float right, int durationMs) { + SDL.check(SDLGamepad.SDL_RumbleGamepadTriggers(handle, toStrength(left), toStrength(right), durationMs), + "SDL_RumbleGamepadTriggers"); + return this; + } + + public Gamepad led(int red, int green, int blue) { + SDL.check(SDLGamepad.SDL_SetGamepadLED(handle, (byte) red, (byte) green, (byte) blue), "SDL_SetGamepadLED"); + return this; + } + + public boolean has(GamepadButton button) { + return button != null && SDLGamepad.SDL_GamepadHasButton(handle, button.value()); + } + + public boolean has(GamepadAxis axis) { + return axis != null && SDLGamepad.SDL_GamepadHasAxis(handle, axis.value()); + } + + public boolean has(SensorType sensor) { + return sensor != null && SDLGamepad.SDL_GamepadHasSensor(handle, sensor.value()); + } + + public Gamepad sensor(SensorType sensor, boolean enabled) { + if (sensor == null) { + throw new IllegalArgumentException("Sensor cannot be null"); + } + SDL.check(SDLGamepad.SDL_SetGamepadSensorEnabled(handle, sensor.value(), enabled), "SDL_SetGamepadSensorEnabled"); + return this; + } + + public boolean sensorEnabled(SensorType sensor) { + return sensor != null && SDLGamepad.SDL_GamepadSensorEnabled(handle, sensor.value()); + } + + /** + * @return three floats, or an empty array if this pad has no such sensor + */ + public float[] sensor(SensorType sensor) { + if (sensor == null || !has(sensor)) { + return new float[0]; + } + try (MemoryStack stack = MemoryStack.stackPush()) { + FloatBuffer buffer = stack.mallocFloat(3); + if (!SDLGamepad.SDL_GetGamepadSensorData(handle, sensor.value(), buffer)) { + return new float[0]; + } + return new float[] {buffer.get(0), buffer.get(1), buffer.get(2)}; + } + } + + public int touchpads() { + return Math.max(0, SDLGamepad.SDL_GetNumGamepadTouchpads(handle)); + } + + public int fingers(int touchpad) { + return Math.max(0, SDLGamepad.SDL_GetNumGamepadTouchpadFingers(handle, touchpad)); + } + + /** + * @return {@code null} if the finger is not down or the pad has no such touchpad + */ + public Finger finger(int touchpad, int finger) { + try (MemoryStack stack = MemoryStack.stackPush()) { + ByteBuffer down = stack.malloc(1); + FloatBuffer x = stack.mallocFloat(1); + FloatBuffer y = stack.mallocFloat(1); + FloatBuffer pressure = stack.mallocFloat(1); + if (!SDLGamepad.SDL_GetGamepadTouchpadFinger(handle, touchpad, finger, down, x, y, pressure)) { + return null; + } + if (down.get(0) == 0) { + return null; + } + return new Finger(finger, x.get(0), y.get(0), pressure.get(0)); + } + } + + public String serial() { + String serial = SDLGamepad.SDL_GetGamepadSerial(handle); + return serial == null ? "" : serial; + } + + public int firmwareVersion() { + return Short.toUnsignedInt(SDLGamepad.SDL_GetGamepadFirmwareVersion(handle)); + } + + public String mapping() { + String mapping = SDLGamepad.SDL_GetGamepadMapping(handle); + return mapping == null ? "" : mapping; + } + + long handle() { + return handle; + } + + static short toStrength(float value) { + float clamped = Math.max(0.0F, Math.min(1.0F, value)); + return (short) Math.round(clamped * 65535.0F); + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/GamepadAxis.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/GamepadAxis.java new file mode 100644 index 000000000..ab354de81 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/GamepadAxis.java @@ -0,0 +1,41 @@ +package com.cleanroommc.client.sdl.input; + +import org.lwjgl.sdl.SDLGamepad; + +/** SDL gamepad axes. */ +public enum GamepadAxis { + + LEFT_X(SDLGamepad.SDL_GAMEPAD_AXIS_LEFTX), + LEFT_Y(SDLGamepad.SDL_GAMEPAD_AXIS_LEFTY), + RIGHT_X(SDLGamepad.SDL_GAMEPAD_AXIS_RIGHTX), + RIGHT_Y(SDLGamepad.SDL_GAMEPAD_AXIS_RIGHTY), + LEFT_TRIGGER(SDLGamepad.SDL_GAMEPAD_AXIS_LEFT_TRIGGER), + RIGHT_TRIGGER(SDLGamepad.SDL_GAMEPAD_AXIS_RIGHT_TRIGGER); + + public static GamepadAxis of(int value) { + return switch (value) { + case SDLGamepad.SDL_GAMEPAD_AXIS_LEFTX -> LEFT_X; + case SDLGamepad.SDL_GAMEPAD_AXIS_LEFTY -> LEFT_Y; + case SDLGamepad.SDL_GAMEPAD_AXIS_RIGHTX -> RIGHT_X; + case SDLGamepad.SDL_GAMEPAD_AXIS_RIGHTY -> RIGHT_Y; + case SDLGamepad.SDL_GAMEPAD_AXIS_LEFT_TRIGGER -> LEFT_TRIGGER; + case SDLGamepad.SDL_GAMEPAD_AXIS_RIGHT_TRIGGER -> RIGHT_TRIGGER; + default -> null; + }; + } + + private final int value; + + GamepadAxis(int value) { + this.value = value; + } + + public int value() { + return value; + } + + public boolean trigger() { + return this == LEFT_TRIGGER || this == RIGHT_TRIGGER; + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/GamepadButton.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/GamepadButton.java new file mode 100644 index 000000000..84c4bcac4 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/GamepadButton.java @@ -0,0 +1,77 @@ +package com.cleanroommc.client.sdl.input; + +import org.lwjgl.sdl.SDLGamepad; + +/** SDL gamepad buttons, face-neutral ({@code SOUTH} is A on Xbox and Cross on PlayStation). */ +public enum GamepadButton { + + SOUTH(SDLGamepad.SDL_GAMEPAD_BUTTON_SOUTH), + EAST(SDLGamepad.SDL_GAMEPAD_BUTTON_EAST), + WEST(SDLGamepad.SDL_GAMEPAD_BUTTON_WEST), + NORTH(SDLGamepad.SDL_GAMEPAD_BUTTON_NORTH), + BACK(SDLGamepad.SDL_GAMEPAD_BUTTON_BACK), + GUIDE(SDLGamepad.SDL_GAMEPAD_BUTTON_GUIDE), + START(SDLGamepad.SDL_GAMEPAD_BUTTON_START), + LEFT_STICK(SDLGamepad.SDL_GAMEPAD_BUTTON_LEFT_STICK), + RIGHT_STICK(SDLGamepad.SDL_GAMEPAD_BUTTON_RIGHT_STICK), + LEFT_SHOULDER(SDLGamepad.SDL_GAMEPAD_BUTTON_LEFT_SHOULDER), + RIGHT_SHOULDER(SDLGamepad.SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER), + DPAD_UP(SDLGamepad.SDL_GAMEPAD_BUTTON_DPAD_UP), + DPAD_DOWN(SDLGamepad.SDL_GAMEPAD_BUTTON_DPAD_DOWN), + DPAD_LEFT(SDLGamepad.SDL_GAMEPAD_BUTTON_DPAD_LEFT), + DPAD_RIGHT(SDLGamepad.SDL_GAMEPAD_BUTTON_DPAD_RIGHT), + MISC1(SDLGamepad.SDL_GAMEPAD_BUTTON_MISC1), + RIGHT_PADDLE1(SDLGamepad.SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1), + LEFT_PADDLE1(SDLGamepad.SDL_GAMEPAD_BUTTON_LEFT_PADDLE1), + RIGHT_PADDLE2(SDLGamepad.SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2), + LEFT_PADDLE2(SDLGamepad.SDL_GAMEPAD_BUTTON_LEFT_PADDLE2), + TOUCHPAD(SDLGamepad.SDL_GAMEPAD_BUTTON_TOUCHPAD), + MISC2(SDLGamepad.SDL_GAMEPAD_BUTTON_MISC2), + MISC3(SDLGamepad.SDL_GAMEPAD_BUTTON_MISC3), + MISC4(SDLGamepad.SDL_GAMEPAD_BUTTON_MISC4), + MISC5(SDLGamepad.SDL_GAMEPAD_BUTTON_MISC5), + MISC6(SDLGamepad.SDL_GAMEPAD_BUTTON_MISC6); + + public static GamepadButton of(int value) { + return switch (value) { + case SDLGamepad.SDL_GAMEPAD_BUTTON_SOUTH -> SOUTH; + case SDLGamepad.SDL_GAMEPAD_BUTTON_EAST -> EAST; + case SDLGamepad.SDL_GAMEPAD_BUTTON_WEST -> WEST; + case SDLGamepad.SDL_GAMEPAD_BUTTON_NORTH -> NORTH; + case SDLGamepad.SDL_GAMEPAD_BUTTON_BACK -> BACK; + case SDLGamepad.SDL_GAMEPAD_BUTTON_GUIDE -> GUIDE; + case SDLGamepad.SDL_GAMEPAD_BUTTON_START -> START; + case SDLGamepad.SDL_GAMEPAD_BUTTON_LEFT_STICK -> LEFT_STICK; + case SDLGamepad.SDL_GAMEPAD_BUTTON_RIGHT_STICK -> RIGHT_STICK; + case SDLGamepad.SDL_GAMEPAD_BUTTON_LEFT_SHOULDER -> LEFT_SHOULDER; + case SDLGamepad.SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER -> RIGHT_SHOULDER; + case SDLGamepad.SDL_GAMEPAD_BUTTON_DPAD_UP -> DPAD_UP; + case SDLGamepad.SDL_GAMEPAD_BUTTON_DPAD_DOWN -> DPAD_DOWN; + case SDLGamepad.SDL_GAMEPAD_BUTTON_DPAD_LEFT -> DPAD_LEFT; + case SDLGamepad.SDL_GAMEPAD_BUTTON_DPAD_RIGHT -> DPAD_RIGHT; + case SDLGamepad.SDL_GAMEPAD_BUTTON_MISC1 -> MISC1; + case SDLGamepad.SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1 -> RIGHT_PADDLE1; + case SDLGamepad.SDL_GAMEPAD_BUTTON_LEFT_PADDLE1 -> LEFT_PADDLE1; + case SDLGamepad.SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2 -> RIGHT_PADDLE2; + case SDLGamepad.SDL_GAMEPAD_BUTTON_LEFT_PADDLE2 -> LEFT_PADDLE2; + case SDLGamepad.SDL_GAMEPAD_BUTTON_TOUCHPAD -> TOUCHPAD; + case SDLGamepad.SDL_GAMEPAD_BUTTON_MISC2 -> MISC2; + case SDLGamepad.SDL_GAMEPAD_BUTTON_MISC3 -> MISC3; + case SDLGamepad.SDL_GAMEPAD_BUTTON_MISC4 -> MISC4; + case SDLGamepad.SDL_GAMEPAD_BUTTON_MISC5 -> MISC5; + case SDLGamepad.SDL_GAMEPAD_BUTTON_MISC6 -> MISC6; + default -> null; + }; + } + + private final int value; + + GamepadButton(int value) { + this.value = value; + } + + public int value() { + return value; + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/GamepadLabel.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/GamepadLabel.java new file mode 100644 index 000000000..367769597 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/GamepadLabel.java @@ -0,0 +1,42 @@ +package com.cleanroommc.client.sdl.input; + +import org.lwjgl.sdl.SDLGamepad; + +/** Face-button glyph for the pad's own layout (A vs Cross, etc.). */ +public enum GamepadLabel { + + UNKNOWN(SDLGamepad.SDL_GAMEPAD_BUTTON_LABEL_UNKNOWN), + A(SDLGamepad.SDL_GAMEPAD_BUTTON_LABEL_A), + B(SDLGamepad.SDL_GAMEPAD_BUTTON_LABEL_B), + X(SDLGamepad.SDL_GAMEPAD_BUTTON_LABEL_X), + Y(SDLGamepad.SDL_GAMEPAD_BUTTON_LABEL_Y), + CROSS(SDLGamepad.SDL_GAMEPAD_BUTTON_LABEL_CROSS), + CIRCLE(SDLGamepad.SDL_GAMEPAD_BUTTON_LABEL_CIRCLE), + SQUARE(SDLGamepad.SDL_GAMEPAD_BUTTON_LABEL_SQUARE), + TRIANGLE(SDLGamepad.SDL_GAMEPAD_BUTTON_LABEL_TRIANGLE); + + public static GamepadLabel of(int value) { + return switch (value) { + case SDLGamepad.SDL_GAMEPAD_BUTTON_LABEL_A -> A; + case SDLGamepad.SDL_GAMEPAD_BUTTON_LABEL_B -> B; + case SDLGamepad.SDL_GAMEPAD_BUTTON_LABEL_X -> X; + case SDLGamepad.SDL_GAMEPAD_BUTTON_LABEL_Y -> Y; + case SDLGamepad.SDL_GAMEPAD_BUTTON_LABEL_CROSS -> CROSS; + case SDLGamepad.SDL_GAMEPAD_BUTTON_LABEL_CIRCLE -> CIRCLE; + case SDLGamepad.SDL_GAMEPAD_BUTTON_LABEL_SQUARE -> SQUARE; + case SDLGamepad.SDL_GAMEPAD_BUTTON_LABEL_TRIANGLE -> TRIANGLE; + default -> UNKNOWN; + }; + } + + private final int value; + + GamepadLabel(int value) { + this.value = value; + } + + public int value() { + return value; + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/GamepadListener.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/GamepadListener.java new file mode 100644 index 000000000..b1c306cbc --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/GamepadListener.java @@ -0,0 +1,16 @@ +package com.cleanroommc.client.sdl.input; + +/** Hotplug for mapped gamepads. Called from {@link com.cleanroommc.client.sdl.Window#pump()}. */ +public interface GamepadListener { + + default void added(Gamepad gamepad) { } + + default void removed(int instanceId) { } + + default void remapped(Gamepad gamepad) { } + + default void touchpad(Gamepad gamepad, int touchpad, int finger, float x, float y, float pressure, boolean down) { } + + default void sensor(Gamepad gamepad, SensorType type, float[] data) { } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/GamepadType.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/GamepadType.java new file mode 100644 index 000000000..4a6f94080 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/GamepadType.java @@ -0,0 +1,48 @@ +package com.cleanroommc.client.sdl.input; + +import org.lwjgl.sdl.SDLGamepad; + +/** SDL's idea of which family a pad belongs to. */ +public enum GamepadType { + + UNKNOWN(SDLGamepad.SDL_GAMEPAD_TYPE_UNKNOWN), + STANDARD(SDLGamepad.SDL_GAMEPAD_TYPE_STANDARD), + XBOX360(SDLGamepad.SDL_GAMEPAD_TYPE_XBOX360), + XBOXONE(SDLGamepad.SDL_GAMEPAD_TYPE_XBOXONE), + PS3(SDLGamepad.SDL_GAMEPAD_TYPE_PS3), + PS4(SDLGamepad.SDL_GAMEPAD_TYPE_PS4), + PS5(SDLGamepad.SDL_GAMEPAD_TYPE_PS5), + NINTENDO_SWITCH_PRO(SDLGamepad.SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO), + NINTENDO_SWITCH_JOYCON_LEFT(SDLGamepad.SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_LEFT), + NINTENDO_SWITCH_JOYCON_RIGHT(SDLGamepad.SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT), + NINTENDO_SWITCH_JOYCON_PAIR(SDLGamepad.SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_PAIR), + GAMECUBE(SDLGamepad.SDL_GAMEPAD_TYPE_GAMECUBE); + + public static GamepadType of(int value) { + return switch (value) { + case SDLGamepad.SDL_GAMEPAD_TYPE_STANDARD -> STANDARD; + case SDLGamepad.SDL_GAMEPAD_TYPE_XBOX360 -> XBOX360; + case SDLGamepad.SDL_GAMEPAD_TYPE_XBOXONE -> XBOXONE; + case SDLGamepad.SDL_GAMEPAD_TYPE_PS3 -> PS3; + case SDLGamepad.SDL_GAMEPAD_TYPE_PS4 -> PS4; + case SDLGamepad.SDL_GAMEPAD_TYPE_PS5 -> PS5; + case SDLGamepad.SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO -> NINTENDO_SWITCH_PRO; + case SDLGamepad.SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_LEFT -> NINTENDO_SWITCH_JOYCON_LEFT; + case SDLGamepad.SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT -> NINTENDO_SWITCH_JOYCON_RIGHT; + case SDLGamepad.SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_PAIR -> NINTENDO_SWITCH_JOYCON_PAIR; + case SDLGamepad.SDL_GAMEPAD_TYPE_GAMECUBE -> GAMECUBE; + default -> UNKNOWN; + }; + } + + private final int value; + + GamepadType(int value) { + this.value = value; + } + + public int value() { + return value; + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Gamepads.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Gamepads.java new file mode 100644 index 000000000..e28a5c863 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Gamepads.java @@ -0,0 +1,189 @@ +package com.cleanroommc.client.sdl.input; + +import com.cleanroommc.client.sdl.SDL; +import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import org.lwjgl.sdl.SDLEvents; +import org.lwjgl.sdl.SDLGamepad; +import org.lwjgl.sdl.SDLInit; +import org.lwjgl.sdl.SDLStdinc; +import org.lwjgl.sdl.SDL_Event; +import org.lwjgl.sdl.SDL_GamepadDeviceEvent; + +import java.nio.IntBuffer; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * Connected, mapped gamepads. First use initializes {@code SDL_INIT_GAMEPAD}. + */ +public final class Gamepads { + + private final Int2ObjectMap pads = new Int2ObjectArrayMap<>(); + private final List listeners = new CopyOnWriteArrayList<>(); + + private boolean started; + + Gamepads() { } + + synchronized void ensure() { + if (started) { + return; + } + SDL.ensureSubsystem(SDLInit.SDL_INIT_GAMEPAD); + started = true; + openConnected(); + } + + public synchronized List list() { + ensure(); + return List.copyOf(pads.values()); + } + + public Gamepad first() { + List list = list(); + return list.isEmpty() ? null : list.get(0); + } + + public synchronized Gamepad byId(int instanceId) { + ensure(); + return pads.get(instanceId); + } + + public Gamepads listen(GamepadListener listener) { + if (listener == null) { + throw new IllegalArgumentException("Listener cannot be null"); + } + listeners.add(listener); + return this; + } + + public Gamepads mute(GamepadListener listener) { + listeners.remove(listener); + return this; + } + + /** + * Applies a gamepad device event from the window's pump. + */ + public synchronized void handle(SDL_Event event) { + if (!started) { + return; + } + int type = event.type(); + SDL_GamepadDeviceEvent device = event.gdevice(); + int id = device.which(); + switch (type) { + case SDLEvents.SDL_EVENT_GAMEPAD_ADDED -> { + Gamepad pad = open(id); + if (pad != null) { + for (GamepadListener listener : listeners) { + listener.added(pad); + } + } + } + case SDLEvents.SDL_EVENT_GAMEPAD_REMOVED -> { + Gamepad pad = pads.remove(id); + if (pad != null) { + SDLGamepad.SDL_CloseGamepad(pad.handle()); + } + for (GamepadListener listener : listeners) { + listener.removed(id); + } + } + case SDLEvents.SDL_EVENT_GAMEPAD_REMAPPED -> { + Gamepad pad = pads.get(id); + if (pad != null) { + for (GamepadListener listener : listeners) { + listener.remapped(pad); + } + } + } + case SDLEvents.SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN, + SDLEvents.SDL_EVENT_GAMEPAD_TOUCHPAD_UP, + SDLEvents.SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION -> { + org.lwjgl.sdl.SDL_GamepadTouchpadEvent touch = event.gtouchpad(); + Gamepad pad = pads.get(touch.which()); + if (pad == null) { + return; + } + boolean down = type != SDLEvents.SDL_EVENT_GAMEPAD_TOUCHPAD_UP; + for (GamepadListener listener : listeners) { + listener.touchpad(pad, touch.touchpad(), touch.finger(), touch.x(), touch.y(), touch.pressure(), down); + } + } + case SDLEvents.SDL_EVENT_GAMEPAD_SENSOR_UPDATE -> { + org.lwjgl.sdl.SDL_GamepadSensorEvent update = event.gsensor(); + Gamepad pad = pads.get(update.which()); + if (pad == null) { + return; + } + SensorType sensor = SensorType.of(update.sensor()); + float[] data = {update.data(0), update.data(1), update.data(2)}; + for (GamepadListener listener : listeners) { + listener.sensor(pad, sensor, data); + } + } + default -> { } + } + } + + synchronized void reset() { + for (Gamepad pad : pads.values()) { + SDLGamepad.SDL_CloseGamepad(pad.handle()); + } + pads.clear(); + listeners.clear(); + started = false; + } + + private void openConnected() { + IntBuffer ids = SDLGamepad.SDL_GetGamepads(); + if (ids == null) { + return; + } + try { + while (ids.hasRemaining()) { + open(ids.get()); + } + } finally { + SDLStdinc.SDL_free(ids); + } + } + + private Gamepad open(int instanceId) { + Gamepad existing = pads.get(instanceId); + if (existing != null) { + return existing; + } + long already = SDLGamepad.SDL_GetGamepadFromID(instanceId); + long handle = already != 0L ? already : SDLGamepad.SDL_OpenGamepad(instanceId); + if (handle == 0L) { + return null; + } + Gamepad pad = new Gamepad(instanceId, handle); + pads.put(instanceId, pad); + return pad; + } + + /** Package-visible for tests that inject add/remove without SDL events. */ + synchronized Gamepad injectAdded(int instanceId, long handle) { + started = true; + Gamepad pad = new Gamepad(instanceId, handle); + pads.put(instanceId, pad); + List snapshot = new ArrayList<>(listeners); + for (GamepadListener listener : snapshot) { + listener.added(pad); + } + return pad; + } + + synchronized void injectRemoved(int instanceId) { + pads.remove(instanceId); + for (GamepadListener listener : listeners) { + listener.removed(instanceId); + } + } + +} diff --git a/module/cleanroom/src/test/java/com/cleanroommc/client/sdl/input/GamepadsTest.java b/module/cleanroom/src/test/java/com/cleanroommc/client/sdl/input/GamepadsTest.java new file mode 100644 index 000000000..a06d81c99 --- /dev/null +++ b/module/cleanroom/src/test/java/com/cleanroommc/client/sdl/input/GamepadsTest.java @@ -0,0 +1,22 @@ +package com.cleanroommc.client.sdl.input; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class GamepadsTest { + + private static int unsigned(short value) { + return value & 0xFFFF; + } + + @Test + void rumbleStrengthClampsToUnsignedShortRange() { + assertEquals(0, unsigned(Gamepad.toStrength(0.0F))); + assertEquals(65535, unsigned(Gamepad.toStrength(1.0F))); + assertEquals(65535, unsigned(Gamepad.toStrength(2.0F))); + assertEquals(0, unsigned(Gamepad.toStrength(-1.0F))); + assertEquals(32768, unsigned(Gamepad.toStrength(0.5F))); + } + +} From 7c358cb81be78c795ac9119cd2d046acf2499bd7 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Wed, 19 Aug 2026 22:27:27 +0100 Subject: [PATCH 70/99] Haptic Feedback --- .../cleanroommc/client/sdl/input/Haptic.java | 164 ++++++++++++++++++ .../client/sdl/input/HapticFeature.java | 59 +++++++ .../cleanroommc/client/sdl/input/Haptics.java | 126 ++++++++++++++ 3 files changed, 349 insertions(+) create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Haptic.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/HapticFeature.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Haptics.java diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Haptic.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Haptic.java new file mode 100644 index 000000000..303f8be9c --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Haptic.java @@ -0,0 +1,164 @@ +package com.cleanroommc.client.sdl.input; + +import com.cleanroommc.client.sdl.SDL; +import com.cleanroommc.client.sdl.SDLException; +import org.lwjgl.sdl.SDLHaptic; +import org.lwjgl.sdl.SDL_HapticEffect; +import org.lwjgl.system.MemoryStack; + +/** + * One force-feedback device. {@link Gamepad#rumble} is the easy path. + * This is the rest of the effect set. + */ +public final class Haptic implements AutoCloseable { + + static float clamp01(float value) { + return Math.max(0.0F, Math.min(1.0F, value)); + } + + private static int clampPercent(int value) { + return Math.max(0, Math.min(100, value)); + } + + private final int id; + private final long handle; + + private boolean rumbleReady; + private boolean closed; + + Haptic(int id, long handle) { + this.id = id; + this.handle = handle; + } + + public int id() { + return id; + } + + public String name() { + String name = SDLHaptic.SDL_GetHapticName(handle); + return name == null ? "" : name; + } + + public int axes() { + return Math.max(0, SDLHaptic.SDL_GetNumHapticAxes(handle)); + } + + public int maxEffects() { + return Math.max(0, SDLHaptic.SDL_GetMaxHapticEffects(handle)); + } + + public boolean has(HapticFeature feature) { + return feature != null && (SDLHaptic.SDL_GetHapticFeatures(handle) & feature.value()) != 0; + } + + public boolean rumbleSupported() { + return SDLHaptic.SDL_HapticRumbleSupported(handle); + } + + /** + * Simple rumble. Strength is {@code 0..1}. + */ + public Haptic rumble(float strength, int durationMs) { + ensureOpen(); + if (!rumbleReady) { + SDL.check(SDLHaptic.SDL_InitHapticRumble(handle), "SDL_InitHapticRumble"); + rumbleReady = true; + } + SDL.check(SDLHaptic.SDL_PlayHapticRumble(handle, clamp01(strength), durationMs), "SDL_PlayHapticRumble"); + return this; + } + + public Haptic stopRumble() { + ensureOpen(); + SDL.check(SDLHaptic.SDL_StopHapticRumble(handle), "SDL_StopHapticRumble"); + return this; + } + + /** + * Dual-motor left/right effect. Strengths are {@code 0..1}. + * + * @return the SDL effect id + */ + public int leftRight(float large, float small, int durationMs) { + ensureOpen(); + try (MemoryStack stack = MemoryStack.stackPush()) { + SDL_HapticEffect effect = SDL_HapticEffect.calloc(stack); + effect.type((short) SDLHaptic.SDL_HAPTIC_LEFTRIGHT); + effect.leftright() + .type((short) SDLHaptic.SDL_HAPTIC_LEFTRIGHT) + .length(durationMs) + .large_magnitude(Gamepad.toStrength(large)) + .small_magnitude(Gamepad.toStrength(small)); + int id = SDLHaptic.SDL_CreateHapticEffect(handle, effect); + if (id < 0) { + throw new SDLException("SDL_CreateHapticEffect failed: " + org.lwjgl.sdl.SDLError.SDL_GetError()); + } + SDL.check(SDLHaptic.SDL_RunHapticEffect(handle, id, 1), "SDL_RunHapticEffect"); + return id; + } + } + + public Haptic stop(int effectId) { + ensureOpen(); + SDL.check(SDLHaptic.SDL_StopHapticEffect(handle, effectId), "SDL_StopHapticEffect"); + return this; + } + + public Haptic destroy(int effectId) { + ensureOpen(); + SDLHaptic.SDL_DestroyHapticEffect(handle, effectId); + return this; + } + + public Haptic gain(int percent) { + ensureOpen(); + SDL.check(SDLHaptic.SDL_SetHapticGain(handle, clampPercent(percent)), "SDL_SetHapticGain"); + return this; + } + + public Haptic autocenter(int percent) { + ensureOpen(); + SDL.check(SDLHaptic.SDL_SetHapticAutocenter(handle, clampPercent(percent)), "SDL_SetHapticAutocenter"); + return this; + } + + public Haptic pause() { + ensureOpen(); + SDL.check(SDLHaptic.SDL_PauseHaptic(handle), "SDL_PauseHaptic"); + return this; + } + + public Haptic resume() { + ensureOpen(); + SDL.check(SDLHaptic.SDL_ResumeHaptic(handle), "SDL_ResumeHaptic"); + return this; + } + + public Haptic stop() { + ensureOpen(); + SDL.check(SDLHaptic.SDL_StopHapticEffects(handle), "SDL_StopHapticEffects"); + return this; + } + + long handle() { + return handle; + } + + private void ensureOpen() { + if (closed) { + throw new IllegalStateException("The haptic device is closed"); + } + } + + @Override + public void close() { + if (closed) { + return; + } + closed = true; + Inputs.haptics().forget(this); + SDLHaptic.SDL_CloseHaptic(handle); + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/HapticFeature.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/HapticFeature.java new file mode 100644 index 000000000..285f4e4d5 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/HapticFeature.java @@ -0,0 +1,59 @@ +package com.cleanroommc.client.sdl.input; + +import org.lwjgl.sdl.SDLHaptic; + +/** Bits from {@code SDL_GetHapticFeatures}. */ +public enum HapticFeature { + + CONSTANT(SDLHaptic.SDL_HAPTIC_CONSTANT), + SINE(SDLHaptic.SDL_HAPTIC_SINE), + SQUARE(SDLHaptic.SDL_HAPTIC_SQUARE), + TRIANGLE(SDLHaptic.SDL_HAPTIC_TRIANGLE), + SAWTOOTH_UP(SDLHaptic.SDL_HAPTIC_SAWTOOTHUP), + SAWTOOTH_DOWN(SDLHaptic.SDL_HAPTIC_SAWTOOTHDOWN), + RAMP(SDLHaptic.SDL_HAPTIC_RAMP), + SPRING(SDLHaptic.SDL_HAPTIC_SPRING), + DAMPER(SDLHaptic.SDL_HAPTIC_DAMPER), + INERTIA(SDLHaptic.SDL_HAPTIC_INERTIA), + FRICTION(SDLHaptic.SDL_HAPTIC_FRICTION), + LEFTRIGHT(SDLHaptic.SDL_HAPTIC_LEFTRIGHT), + CUSTOM(SDLHaptic.SDL_HAPTIC_CUSTOM), + GAIN(SDLHaptic.SDL_HAPTIC_GAIN), + AUTOCENTER(SDLHaptic.SDL_HAPTIC_AUTOCENTER), + STATUS(SDLHaptic.SDL_HAPTIC_STATUS), + PAUSE(SDLHaptic.SDL_HAPTIC_PAUSE); + + public static HapticFeature of(int value) { + return switch (value) { + case SDLHaptic.SDL_HAPTIC_CONSTANT -> CONSTANT; + case SDLHaptic.SDL_HAPTIC_SINE -> SINE; + case SDLHaptic.SDL_HAPTIC_SQUARE -> SQUARE; + case SDLHaptic.SDL_HAPTIC_TRIANGLE -> TRIANGLE; + case SDLHaptic.SDL_HAPTIC_SAWTOOTHUP -> SAWTOOTH_UP; + case SDLHaptic.SDL_HAPTIC_SAWTOOTHDOWN -> SAWTOOTH_DOWN; + case SDLHaptic.SDL_HAPTIC_RAMP -> RAMP; + case SDLHaptic.SDL_HAPTIC_SPRING -> SPRING; + case SDLHaptic.SDL_HAPTIC_DAMPER -> DAMPER; + case SDLHaptic.SDL_HAPTIC_INERTIA -> INERTIA; + case SDLHaptic.SDL_HAPTIC_FRICTION -> FRICTION; + case SDLHaptic.SDL_HAPTIC_LEFTRIGHT -> LEFTRIGHT; + case SDLHaptic.SDL_HAPTIC_CUSTOM -> CUSTOM; + case SDLHaptic.SDL_HAPTIC_GAIN -> GAIN; + case SDLHaptic.SDL_HAPTIC_AUTOCENTER -> AUTOCENTER; + case SDLHaptic.SDL_HAPTIC_STATUS -> STATUS; + case SDLHaptic.SDL_HAPTIC_PAUSE -> PAUSE; + default -> null; + }; + } + + private final int value; + + HapticFeature(int value) { + this.value = value; + } + + public int value() { + return value; + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Haptics.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Haptics.java new file mode 100644 index 000000000..d9a625f6a --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Haptics.java @@ -0,0 +1,126 @@ +package com.cleanroommc.client.sdl.input; + +import com.cleanroommc.client.sdl.SDL; +import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import org.lwjgl.sdl.SDLHaptic; +import org.lwjgl.sdl.SDLInit; +import org.lwjgl.sdl.SDLStdinc; + +import java.nio.IntBuffer; +import java.util.ArrayList; +import java.util.List; + +/** + * Force-feedback devices. First use initializes {@code SDL_INIT_HAPTIC}. + */ +public final class Haptics { + + private final Int2ObjectMap devices = new Int2ObjectArrayMap<>(); + + private boolean started; + + Haptics() { } + + synchronized void ensure() { + if (started) { + return; + } + SDL.ensureSubsystem(SDLInit.SDL_INIT_HAPTIC); + started = true; + } + + public synchronized List list() { + ensure(); + IntBuffer ids = SDLHaptic.SDL_GetHaptics(); + if (ids == null) { + return List.copyOf(devices.values()); + } + try { + while (ids.hasRemaining()) { + open(ids.get()); + } + } finally { + SDLStdinc.SDL_free(ids); + } + return List.copyOf(devices.values()); + } + + public Haptic first() { + List list = list(); + return list.isEmpty() ? null : list.get(0); + } + + public synchronized Haptic byId(int id) { + ensure(); + Haptic existing = devices.get(id); + return existing != null ? existing : open(id); + } + + /** + * Opens the haptic side of a joystick, if it has one. + */ + public synchronized Haptic open(Joystick joystick) { + if (joystick == null) { + throw new IllegalArgumentException("Joystick cannot be null"); + } + ensure(); + if (!SDLHaptic.SDL_IsJoystickHaptic(joystick.handle())) { + return null; + } + long handle = SDLHaptic.SDL_OpenHapticFromJoystick(joystick.handle()); + if (handle == 0L) { + return null; + } + return track(handle); + } + + public Haptic mouse() { + ensure(); + if (!SDLHaptic.SDL_IsMouseHaptic()) { + return null; + } + long handle = SDLHaptic.SDL_OpenHapticFromMouse(); + if (handle == 0L) { + return null; + } + return track(handle); + } + + synchronized void forget(Haptic haptic) { + devices.values().removeIf(owned -> owned == haptic); + } + + synchronized void reset() { + for (Haptic haptic : new ArrayList<>(devices.values())) { + haptic.close(); + } + devices.clear(); + started = false; + } + + private Haptic open(int id) { + Haptic existing = devices.get(id); + if (existing != null) { + return existing; + } + long already = SDLHaptic.SDL_GetHapticFromID(id); + long handle = already != 0L ? already : SDLHaptic.SDL_OpenHaptic(id); + if (handle == 0L) { + return null; + } + return track(handle); + } + + private Haptic track(long handle) { + int id = SDLHaptic.SDL_GetHapticID(handle); + Haptic existing = devices.get(id); + if (existing != null) { + return existing; + } + Haptic haptic = new Haptic(id, handle); + devices.put(id, haptic); + return haptic; + } + +} From d38d7ef4fdf158719f5c6909c0a344c0e7907032 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Wed, 19 Aug 2026 22:31:51 +0100 Subject: [PATCH 71/99] Joysticks --- .../client/sdl/input/Joystick.java | 194 ++++++++++++++++++ .../client/sdl/input/JoystickConnection.java | 32 +++ .../client/sdl/input/JoystickHat.java | 58 ++++++ .../client/sdl/input/JoystickListener.java | 14 ++ .../client/sdl/input/JoystickType.java | 44 ++++ .../client/sdl/input/Joysticks.java | 166 +++++++++++++++ 6 files changed, 508 insertions(+) create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Joystick.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/JoystickConnection.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/JoystickHat.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/JoystickListener.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/JoystickType.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Joysticks.java diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Joystick.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Joystick.java new file mode 100644 index 000000000..6c4b41644 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Joystick.java @@ -0,0 +1,194 @@ +package com.cleanroommc.client.sdl.input; + +import com.cleanroommc.client.sdl.Power; +import com.cleanroommc.client.sdl.SDL; +import org.lwjgl.sdl.SDLGUID; +import org.lwjgl.sdl.SDLJoystick; +import org.lwjgl.sdl.SDL_GUID; +import org.lwjgl.system.MemoryStack; +import org.lwjgl.system.MemoryUtil; + +import java.nio.ByteBuffer; +import java.nio.IntBuffer; + +/** + * One unmapped joystick. Hats, axes, buttons and trackballs are numbered from zero. + */ +public final class Joystick { + + private final int instanceId; + private final long handle; + + Joystick(int instanceId, long handle) { + this.instanceId = instanceId; + this.handle = handle; + } + + public int id() { + return instanceId; + } + + public String name() { + String name = SDLJoystick.SDL_GetJoystickName(handle); + return name == null ? "" : name; + } + + public String path() { + String path = SDLJoystick.SDL_GetJoystickPath(handle); + return path == null ? "" : path; + } + + public String guid() { + try (MemoryStack stack = MemoryStack.stackPush()) { + SDL_GUID guid = SDL_GUID.malloc(stack); + SDLJoystick.SDL_GetJoystickGUID(handle, guid); + ByteBuffer text = stack.malloc(33); + SDLGUID.SDL_GUIDToString(guid, text); + return MemoryUtil.memUTF8(text); + } + } + + public String serial() { + String serial = SDLJoystick.SDL_GetJoystickSerial(handle); + return serial == null ? "" : serial; + } + + public JoystickType type() { + return JoystickType.of(SDLJoystick.SDL_GetJoystickType(handle)); + } + + public boolean connected() { + return SDLJoystick.SDL_JoystickConnected(handle); + } + + public boolean virtual() { + return SDLJoystick.SDL_IsJoystickVirtual(instanceId); + } + + public int vendor() { + return Short.toUnsignedInt(SDLJoystick.SDL_GetJoystickVendor(handle)); + } + + public int product() { + return Short.toUnsignedInt(SDLJoystick.SDL_GetJoystickProduct(handle)); + } + + public int productVersion() { + return Short.toUnsignedInt(SDLJoystick.SDL_GetJoystickProductVersion(handle)); + } + + public int firmwareVersion() { + return Short.toUnsignedInt(SDLJoystick.SDL_GetJoystickFirmwareVersion(handle)); + } + + public int player() { + return SDLJoystick.SDL_GetJoystickPlayerIndex(handle); + } + + public Joystick player(int index) { + SDL.check(SDLJoystick.SDL_SetJoystickPlayerIndex(handle, index), "SDL_SetJoystickPlayerIndex"); + return this; + } + + public int axes() { + return Math.max(0, SDLJoystick.SDL_GetNumJoystickAxes(handle)); + } + + public int buttons() { + return Math.max(0, SDLJoystick.SDL_GetNumJoystickButtons(handle)); + } + + public int hats() { + return Math.max(0, SDLJoystick.SDL_GetNumJoystickHats(handle)); + } + + public int balls() { + return Math.max(0, SDLJoystick.SDL_GetNumJoystickBalls(handle)); + } + + /** + * @return {@code [-1, 1]} after the default deadzone + */ + public float axis(int index) { + return axis(index, Gamepad.DEFAULT_DEADZONE); + } + + public float axis(int index, float deadzone) { + if (index < 0 || index >= axes()) { + return 0.0F; + } + float raw = SDLJoystick.SDL_GetJoystickAxis(handle, index) / Gamepad.AXIS_SCALE; + float magnitude = Math.abs(raw); + if (magnitude < deadzone) { + return 0.0F; + } + float scaled = (magnitude - deadzone) / (1.0F - deadzone); + return Math.copySign(Math.min(1.0F, scaled), raw); + } + + public boolean button(int index) { + return index >= 0 && SDLJoystick.SDL_GetJoystickButton(handle, index); + } + + public JoystickHat hat(int index) { + if (index < 0 || index >= hats()) { + return JoystickHat.CENTERED; + } + return JoystickHat.of(SDLJoystick.SDL_GetJoystickHat(handle, index) & 0xFF); + } + + public int[] ball(int index) { + if (index < 0 || index >= balls()) { + return new int[] {0, 0}; + } + try (MemoryStack stack = MemoryStack.stackPush()) { + IntBuffer dx = stack.mallocInt(1); + IntBuffer dy = stack.mallocInt(1); + if (!SDLJoystick.SDL_GetJoystickBall(handle, index, dx, dy)) { + return new int[] {0, 0}; + } + return new int[] {dx.get(0), dy.get(0)}; + } + } + + public JoystickConnection connection() { + return JoystickConnection.of(SDLJoystick.SDL_GetJoystickConnectionState(handle)); + } + + public Power power() { + try (MemoryStack stack = MemoryStack.stackPush()) { + IntBuffer percent = stack.mallocInt(1); + int state = SDLJoystick.SDL_GetJoystickPowerInfo(handle, percent); + return new Power(Power.State.of(state), -1, percent.get(0)); + } + } + + public Joystick rumble(float low, float high, int durationMs) { + SDL.check(SDLJoystick.SDL_RumbleJoystick(handle, Gamepad.toStrength(low), Gamepad.toStrength(high), durationMs), + "SDL_RumbleJoystick"); + return this; + } + + public Joystick rumbleTriggers(float left, float right, int durationMs) { + SDL.check(SDLJoystick.SDL_RumbleJoystickTriggers(handle, Gamepad.toStrength(left), Gamepad.toStrength(right), durationMs), + "SDL_RumbleJoystickTriggers"); + return this; + } + + public Joystick led(int red, int green, int blue) { + SDL.check(SDLJoystick.SDL_SetJoystickLED(handle, (byte) red, (byte) green, (byte) blue), "SDL_SetJoystickLED"); + return this; + } + + /** + * Opens this stick's haptic device, if it has one. + */ + public Haptic haptic() { + return Inputs.haptics().open(this); + } + + long handle() { + return handle; + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/JoystickConnection.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/JoystickConnection.java new file mode 100644 index 000000000..0fd7310f2 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/JoystickConnection.java @@ -0,0 +1,32 @@ +package com.cleanroommc.client.sdl.input; + +import org.lwjgl.sdl.SDLJoystick; + +/** How a joystick is attached. */ +public enum JoystickConnection { + + INVALID(SDLJoystick.SDL_JOYSTICK_CONNECTION_INVALID), + UNKNOWN(SDLJoystick.SDL_JOYSTICK_CONNECTION_UNKNOWN), + WIRED(SDLJoystick.SDL_JOYSTICK_CONNECTION_WIRED), + WIRELESS(SDLJoystick.SDL_JOYSTICK_CONNECTION_WIRELESS); + + public static JoystickConnection of(int value) { + return switch (value) { + case SDLJoystick.SDL_JOYSTICK_CONNECTION_INVALID -> INVALID; + case SDLJoystick.SDL_JOYSTICK_CONNECTION_WIRED -> WIRED; + case SDLJoystick.SDL_JOYSTICK_CONNECTION_WIRELESS -> WIRELESS; + default -> UNKNOWN; + }; + } + + private final int value; + + JoystickConnection(int value) { + this.value = value; + } + + public int value() { + return value; + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/JoystickHat.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/JoystickHat.java new file mode 100644 index 000000000..c496b32b3 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/JoystickHat.java @@ -0,0 +1,58 @@ +package com.cleanroommc.client.sdl.input; + +import org.lwjgl.sdl.SDLJoystick; + +/** One hat position. Diagonals are their own values, not a combination of the four-way names. */ +public enum JoystickHat { + + CENTERED(SDLJoystick.SDL_HAT_CENTERED), + UP(SDLJoystick.SDL_HAT_UP), + RIGHT(SDLJoystick.SDL_HAT_RIGHT), + DOWN(SDLJoystick.SDL_HAT_DOWN), + LEFT(SDLJoystick.SDL_HAT_LEFT), + RIGHT_UP(SDLJoystick.SDL_HAT_RIGHTUP), + RIGHT_DOWN(SDLJoystick.SDL_HAT_RIGHTDOWN), + LEFT_UP(SDLJoystick.SDL_HAT_LEFTUP), + LEFT_DOWN(SDLJoystick.SDL_HAT_LEFTDOWN); + + public static JoystickHat of(int value) { + return switch (value) { + case SDLJoystick.SDL_HAT_UP -> UP; + case SDLJoystick.SDL_HAT_RIGHT -> RIGHT; + case SDLJoystick.SDL_HAT_DOWN -> DOWN; + case SDLJoystick.SDL_HAT_LEFT -> LEFT; + case SDLJoystick.SDL_HAT_RIGHTUP -> RIGHT_UP; + case SDLJoystick.SDL_HAT_RIGHTDOWN -> RIGHT_DOWN; + case SDLJoystick.SDL_HAT_LEFTUP -> LEFT_UP; + case SDLJoystick.SDL_HAT_LEFTDOWN -> LEFT_DOWN; + default -> CENTERED; + }; + } + + private final int value; + + JoystickHat(int value) { + this.value = value; + } + + public int value() { + return value; + } + + public boolean up() { + return (value & SDLJoystick.SDL_HAT_UP) != 0; + } + + public boolean down() { + return (value & SDLJoystick.SDL_HAT_DOWN) != 0; + } + + public boolean left() { + return (value & SDLJoystick.SDL_HAT_LEFT) != 0; + } + + public boolean right() { + return (value & SDLJoystick.SDL_HAT_RIGHT) != 0; + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/JoystickListener.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/JoystickListener.java new file mode 100644 index 000000000..f913a61a8 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/JoystickListener.java @@ -0,0 +1,14 @@ +package com.cleanroommc.client.sdl.input; + +import com.cleanroommc.client.sdl.Power; + +/** Hotplug and battery for raw joysticks. Called from {@link com.cleanroommc.client.sdl.Window#pump()}. */ +public interface JoystickListener { + + default void added(Joystick joystick) { } + + default void removed(int instanceId) { } + + default void battery(Joystick joystick, Power.State state, int percent) { } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/JoystickType.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/JoystickType.java new file mode 100644 index 000000000..7756cd9e7 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/JoystickType.java @@ -0,0 +1,44 @@ +package com.cleanroommc.client.sdl.input; + +import org.lwjgl.sdl.SDLJoystick; + +/** SDL's idea of what a raw joystick is. */ +public enum JoystickType { + + UNKNOWN(SDLJoystick.SDL_JOYSTICK_TYPE_UNKNOWN), + GAMEPAD(SDLJoystick.SDL_JOYSTICK_TYPE_GAMEPAD), + WHEEL(SDLJoystick.SDL_JOYSTICK_TYPE_WHEEL), + ARCADE_STICK(SDLJoystick.SDL_JOYSTICK_TYPE_ARCADE_STICK), + FLIGHT_STICK(SDLJoystick.SDL_JOYSTICK_TYPE_FLIGHT_STICK), + DANCE_PAD(SDLJoystick.SDL_JOYSTICK_TYPE_DANCE_PAD), + GUITAR(SDLJoystick.SDL_JOYSTICK_TYPE_GUITAR), + DRUM_KIT(SDLJoystick.SDL_JOYSTICK_TYPE_DRUM_KIT), + ARCADE_PAD(SDLJoystick.SDL_JOYSTICK_TYPE_ARCADE_PAD), + THROTTLE(SDLJoystick.SDL_JOYSTICK_TYPE_THROTTLE); + + public static JoystickType of(int value) { + return switch (value) { + case SDLJoystick.SDL_JOYSTICK_TYPE_GAMEPAD -> GAMEPAD; + case SDLJoystick.SDL_JOYSTICK_TYPE_WHEEL -> WHEEL; + case SDLJoystick.SDL_JOYSTICK_TYPE_ARCADE_STICK -> ARCADE_STICK; + case SDLJoystick.SDL_JOYSTICK_TYPE_FLIGHT_STICK -> FLIGHT_STICK; + case SDLJoystick.SDL_JOYSTICK_TYPE_DANCE_PAD -> DANCE_PAD; + case SDLJoystick.SDL_JOYSTICK_TYPE_GUITAR -> GUITAR; + case SDLJoystick.SDL_JOYSTICK_TYPE_DRUM_KIT -> DRUM_KIT; + case SDLJoystick.SDL_JOYSTICK_TYPE_ARCADE_PAD -> ARCADE_PAD; + case SDLJoystick.SDL_JOYSTICK_TYPE_THROTTLE -> THROTTLE; + default -> UNKNOWN; + }; + } + + private final int value; + + JoystickType(int value) { + this.value = value; + } + + public int value() { + return value; + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Joysticks.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Joysticks.java new file mode 100644 index 000000000..07ac04fa0 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Joysticks.java @@ -0,0 +1,166 @@ +package com.cleanroommc.client.sdl.input; + +import com.cleanroommc.client.sdl.Power; +import com.cleanroommc.client.sdl.SDL; +import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import org.lwjgl.sdl.SDLEvents; +import org.lwjgl.sdl.SDLInit; +import org.lwjgl.sdl.SDLJoystick; +import org.lwjgl.sdl.SDLStdinc; +import org.lwjgl.sdl.SDL_Event; +import org.lwjgl.sdl.SDL_JoyBatteryEvent; +import org.lwjgl.sdl.SDL_JoyDeviceEvent; + +import java.nio.IntBuffer; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * Connected raw joysticks. First use initializes {@code SDL_INIT_JOYSTICK}. + */ +public final class Joysticks { + + private final Int2ObjectMap sticks = new Int2ObjectArrayMap<>(); + private final List listeners = new CopyOnWriteArrayList<>(); + + private boolean started; + + Joysticks() { } + + synchronized void ensure() { + if (started) { + return; + } + SDL.ensureSubsystem(SDLInit.SDL_INIT_JOYSTICK); + started = true; + openConnected(); + } + + public synchronized List list() { + ensure(); + return List.copyOf(sticks.values()); + } + + public Joystick first() { + List list = list(); + return list.isEmpty() ? null : list.get(0); + } + + public synchronized Joystick byId(int instanceId) { + ensure(); + return sticks.get(instanceId); + } + + public Joysticks listen(JoystickListener listener) { + if (listener == null) { + throw new IllegalArgumentException("Listener cannot be null"); + } + listeners.add(listener); + return this; + } + + public Joysticks mute(JoystickListener listener) { + listeners.remove(listener); + return this; + } + + public synchronized void handle(SDL_Event event) { + if (!started) { + return; + } + int type = event.type(); + switch (type) { + case SDLEvents.SDL_EVENT_JOYSTICK_ADDED -> { + int id = event.jdevice().which(); + Joystick stick = open(id); + if (stick != null) { + for (JoystickListener listener : listeners) { + listener.added(stick); + } + } + } + case SDLEvents.SDL_EVENT_JOYSTICK_REMOVED -> { + SDL_JoyDeviceEvent device = event.jdevice(); + int id = device.which(); + Joystick stick = sticks.remove(id); + if (stick != null) { + SDLJoystick.SDL_CloseJoystick(stick.handle()); + } + for (JoystickListener listener : listeners) { + listener.removed(id); + } + } + case SDLEvents.SDL_EVENT_JOYSTICK_BATTERY_UPDATED -> { + SDL_JoyBatteryEvent battery = event.jbattery(); + Joystick stick = sticks.get(battery.which()); + if (stick != null) { + Power.State state = Power.State.of(battery.state()); + int percent = battery.percent(); + for (JoystickListener listener : listeners) { + listener.battery(stick, state, percent); + } + } + } + default -> { } + } + } + + synchronized void reset() { + for (Joystick stick : sticks.values()) { + SDLJoystick.SDL_CloseJoystick(stick.handle()); + } + sticks.clear(); + listeners.clear(); + started = false; + } + + private void openConnected() { + IntBuffer ids = SDLJoystick.SDL_GetJoysticks(); + if (ids == null) { + return; + } + try { + while (ids.hasRemaining()) { + open(ids.get()); + } + } finally { + SDLStdinc.SDL_free(ids); + } + } + + private Joystick open(int instanceId) { + Joystick existing = sticks.get(instanceId); + if (existing != null) { + return existing; + } + long already = SDLJoystick.SDL_GetJoystickFromID(instanceId); + long handle = already != 0L ? already : SDLJoystick.SDL_OpenJoystick(instanceId); + if (handle == 0L) { + return null; + } + Joystick stick = new Joystick(instanceId, handle); + sticks.put(instanceId, stick); + return stick; + } + + synchronized Joystick injectAdded(int instanceId, long handle) { + started = true; + Joystick stick = new Joystick(instanceId, handle); + sticks.put(instanceId, stick); + List snapshot = new ArrayList<>(listeners); + for (JoystickListener listener : snapshot) { + listener.added(stick); + } + return stick; + } + + synchronized void injectRemoved(int instanceId) { + sticks.remove(instanceId); + for (JoystickListener listener : listeners) { + listener.removed(instanceId); + } + } + +} From 2d8d5b23152687394125905256333303d9672087 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Wed, 19 Aug 2026 22:36:17 +0100 Subject: [PATCH 72/99] Some more SDL stuff --- .../com/cleanroommc/client/sdl/Locales.java | 40 ++++ .../cleanroommc/client/sdl/NativeWindow.java | 17 ++ .../com/cleanroommc/client/sdl/PathInfo.java | 12 ++ .../com/cleanroommc/client/sdl/PathKind.java | 32 ++++ .../com/cleanroommc/client/sdl/Power.java | 58 ++++++ .../cleanroommc/client/sdl/RuntimeInfo.java | 51 +++++ .../java/com/cleanroommc/client/sdl/Tray.java | 181 ++++++++++++++++++ .../client/sdl/WindowListener.java | 18 ++ .../cleanroommc/client/sdl/camera/Camera.java | 8 +- .../cleanroommc/client/sdl/input/Gamepad.java | 4 +- 10 files changed, 415 insertions(+), 6 deletions(-) create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Locales.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/NativeWindow.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/PathInfo.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/PathKind.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Power.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/RuntimeInfo.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Tray.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/WindowListener.java diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Locales.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Locales.java new file mode 100644 index 000000000..447729a5e --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Locales.java @@ -0,0 +1,40 @@ +package com.cleanroommc.client.sdl; + +import org.lwjgl.PointerBuffer; +import org.lwjgl.sdl.SDLLocale; +import org.lwjgl.sdl.SDLStdinc; +import org.lwjgl.sdl.SDL_Locale; + +import java.util.ArrayList; +import java.util.List; + +/** Preferred locales from SDL. */ +public final class Locales { + + public record Preferred(String language, String country) { } + + public static List preferred() { + PointerBuffer pointers = SDLLocale.SDL_GetPreferredLocales(); + if (pointers == null) { + return List.of(); + } + try { + List locales = new ArrayList<>(pointers.remaining()); + while (pointers.hasRemaining()) { + SDL_Locale locale = SDL_Locale.createSafe(pointers.get()); + if (locale == null) { + continue; + } + String language = locale.languageString(); + String country = locale.countryString(); + locales.add(new Preferred(language == null ? "" : language, country == null ? "" : country)); + } + return List.copyOf(locales); + } finally { + SDLStdinc.SDL_free(pointers); + } + } + + private Locales() { } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/NativeWindow.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/NativeWindow.java new file mode 100644 index 000000000..c780a806a --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/NativeWindow.java @@ -0,0 +1,17 @@ +package com.cleanroommc.client.sdl; + +/** + * The platform window behind Cleanroom's SDL window. + * + * @param compositor which window system {@code handle} belongs to + * @param handle HWND, wl_surface, X11 Window, NSWindow, and so on; {@code 0} when unknown + */ +public record NativeWindow(Compositor compositor, long handle) { + + public static final NativeWindow UNKNOWN = new NativeWindow(Compositor.UNKNOWN, 0L); + + public boolean known() { + return compositor != Compositor.UNKNOWN && handle != 0L; + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/PathInfo.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/PathInfo.java new file mode 100644 index 000000000..97f2448a2 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/PathInfo.java @@ -0,0 +1,12 @@ +package com.cleanroommc.client.sdl; + +/** + * Snapshot from {@code SDL_GetPathInfo}. + * + * @param kind file, directory, or other + * @param size bytes, for files + * @param createdNs SDL time, or {@code 0} + * @param modifiedNs SDL time, or {@code 0} + * @param accessedNs SDL time, or {@code 0} + */ +public record PathInfo(PathKind kind, long size, long createdNs, long modifiedNs, long accessedNs) { } diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/PathKind.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/PathKind.java new file mode 100644 index 000000000..714a00a76 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/PathKind.java @@ -0,0 +1,32 @@ +package com.cleanroommc.client.sdl; + +import org.lwjgl.sdl.SDLFileSystem; + +/** What {@link FileSystem#info} found at a path. */ +public enum PathKind { + + NONE(SDLFileSystem.SDL_PATHTYPE_NONE), + FILE(SDLFileSystem.SDL_PATHTYPE_FILE), + DIRECTORY(SDLFileSystem.SDL_PATHTYPE_DIRECTORY), + OTHER(SDLFileSystem.SDL_PATHTYPE_OTHER); + + public static PathKind of(int value) { + return switch (value) { + case SDLFileSystem.SDL_PATHTYPE_FILE -> FILE; + case SDLFileSystem.SDL_PATHTYPE_DIRECTORY -> DIRECTORY; + case SDLFileSystem.SDL_PATHTYPE_OTHER -> OTHER; + default -> NONE; + }; + } + + private final int value; + + PathKind(int value) { + this.value = value; + } + + public int value() { + return value; + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Power.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Power.java new file mode 100644 index 000000000..d17147fbd --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Power.java @@ -0,0 +1,58 @@ +package com.cleanroommc.client.sdl; + +import org.lwjgl.sdl.SDLPower; +import org.lwjgl.system.MemoryStack; + +import java.nio.IntBuffer; + +/** + * Battery/power snapshot from {@code SDL_GetPowerInfo}. + * + * @param state how the machine is powered + * @param seconds estimated seconds remaining, or {@code -1} + * @param percent estimated charge, {@code 0..100}, or {@code -1} + */ +public record Power(State state, int seconds, int percent) { + + public enum State { + + ERROR(SDLPower.SDL_POWERSTATE_ERROR), + UNKNOWN(SDLPower.SDL_POWERSTATE_UNKNOWN), + ON_BATTERY(SDLPower.SDL_POWERSTATE_ON_BATTERY), + NO_BATTERY(SDLPower.SDL_POWERSTATE_NO_BATTERY), + CHARGING(SDLPower.SDL_POWERSTATE_CHARGING), + CHARGED(SDLPower.SDL_POWERSTATE_CHARGED); + + public static State of(int value) { + return switch (value) { + case SDLPower.SDL_POWERSTATE_ERROR -> ERROR; + case SDLPower.SDL_POWERSTATE_ON_BATTERY -> ON_BATTERY; + case SDLPower.SDL_POWERSTATE_NO_BATTERY -> NO_BATTERY; + case SDLPower.SDL_POWERSTATE_CHARGING -> CHARGING; + case SDLPower.SDL_POWERSTATE_CHARGED -> CHARGED; + default -> UNKNOWN; + }; + } + + private final int value; + + State(int value) { + this.value = value; + } + + public int value() { + return value; + } + + } + + public static Power query() { + try (MemoryStack stack = MemoryStack.stackPush()) { + IntBuffer seconds = stack.mallocInt(1); + IntBuffer percent = stack.mallocInt(1); + int state = SDLPower.SDL_GetPowerInfo(seconds, percent); + return new Power(State.of(state), seconds.get(0), percent.get(0)); + } + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/RuntimeInfo.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/RuntimeInfo.java new file mode 100644 index 000000000..dfc4f1059 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/RuntimeInfo.java @@ -0,0 +1,51 @@ +package com.cleanroommc.client.sdl; + +import org.lwjgl.sdl.SDLPlatform; +import org.lwjgl.sdl.SDLVersion; + +/** SDL version and host facts. Header values do not load natives. */ +public final class RuntimeInfo { + + public record Version(int major, int minor, int micro) { + + public static Version ofPacked(int packed) { + return new Version( + SDLVersion.SDL_VERSIONNUM_MAJOR(packed), + SDLVersion.SDL_VERSIONNUM_MINOR(packed), + SDLVersion.SDL_VERSIONNUM_MICRO(packed) + ); + } + + @Override + public String toString() { + return major + "." + minor + "." + micro; + } + } + + /** + * Version the bindings were compiled against. Safe without {@code SDL_Init}. + */ + public static Version header() { + return new Version(SDLVersion.SDL_MAJOR_VERSION, SDLVersion.SDL_MINOR_VERSION, SDLVersion.SDL_MICRO_VERSION); + } + + /** + * Version of the loaded SDL library. + */ + public static Version version() { + return Version.ofPacked(SDLVersion.SDL_GetVersion()); + } + + public static String revision() { + String revision = SDLVersion.SDL_GetRevision(); + return revision == null ? "" : revision; + } + + public static String platform() { + String platform = SDLPlatform.SDL_GetPlatform(); + return platform == null ? "" : platform; + } + + private RuntimeInfo() { } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Tray.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Tray.java new file mode 100644 index 000000000..d81128bee --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Tray.java @@ -0,0 +1,181 @@ +package com.cleanroommc.client.sdl; + +import org.lwjgl.sdl.SDLSurface; +import org.lwjgl.sdl.SDLTray; +import org.lwjgl.sdl.SDL_Surface; +import org.lwjgl.sdl.SDL_TrayCallback; +import org.lwjgl.system.MemoryStack; +import org.lwjgl.system.MemoryUtil; + +import java.awt.image.BufferedImage; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + +/** + * One system-tray icon. Clicks arrive on the thread that {@link Window#pump() pumps}. + */ +public final class Tray implements AutoCloseable { + + private static final List OPEN = new ArrayList<>(); + + private final long handle; + private final List callbacks = new ArrayList<>(); + + private boolean closed; + + private Tray(long handle) { + this.handle = handle; + } + + public static Tray create(BufferedImage icon, String tooltip) { + SDL.ensureVideo(); + if (icon == null) { + throw new IllegalArgumentException("Icon cannot be null"); + } + SDL_Surface surface = Surfaces.from(icon); + try (MemoryStack stack = MemoryStack.stackPush()) { + long tooltipAddress = MemoryUtil.memAddress(stack.UTF8(tooltip == null ? "" : tooltip)); + long handle = SDL.checkHandle(SDLTray.nSDL_CreateTray(surface.address(), tooltipAddress), "SDL_CreateTray"); + Tray tray = new Tray(handle); + synchronized (OPEN) { + OPEN.add(tray); + } + return tray; + } finally { + SDLSurface.SDL_DestroySurface(surface); + } + } + + public Tray tooltip(String tooltip) { + ensureOpen(); + SDLTray.SDL_SetTrayTooltip(handle, tooltip == null ? "" : tooltip); + return this; + } + + public Tray icon(BufferedImage image) { + ensureOpen(); + if (image == null) { + throw new IllegalArgumentException("Image cannot be null"); + } + SDL_Surface surface = Surfaces.from(image); + try { + SDLTray.SDL_SetTrayIcon(handle, surface); + } finally { + SDLSurface.SDL_DestroySurface(surface); + } + return this; + } + + public Menu menu() { + ensureOpen(); + long existing = SDLTray.SDL_GetTrayMenu(handle); + long menu = existing != 0L ? existing : SDLTray.SDL_CreateTrayMenu(handle); + SDL.checkHandle(menu, "SDL_CreateTrayMenu"); + return new Menu(menu); + } + + static void pump() { + synchronized (OPEN) { + if (!OPEN.isEmpty()) { + SDLTray.SDL_UpdateTrays(); + } + } + } + + public static void reset() { + synchronized (OPEN) { + for (Tray tray : List.copyOf(OPEN)) { + tray.close(); + } + OPEN.clear(); + } + } + + private void ensureOpen() { + if (closed) { + throw new IllegalStateException("The tray is closed"); + } + } + + @Override + public void close() { + if (closed) { + return; + } + closed = true; + synchronized (OPEN) { + OPEN.remove(this); + } + SDLTray.SDL_DestroyTray(handle); + callbacks.clear(); + } + + public final class Menu { + + private final long handle; + + Menu(long handle) { + this.handle = handle; + } + + public Menu button(String label, Runnable action) { + long entry = insert(label, SDLTray.SDL_TRAYENTRY_BUTTON); + bind(entry, ignored -> { + if (action != null) { + action.run(); + } + }); + return this; + } + + public Menu checkbox(String label, boolean checked, Consumer action) { + int flags = SDLTray.SDL_TRAYENTRY_CHECKBOX; + if (checked) { + flags |= SDLTray.SDL_TRAYENTRY_CHECKED; + } + long entry = insert(label, flags); + bind(entry, clicked -> { + boolean now = SDLTray.SDL_GetTrayEntryChecked(clicked); + if (action != null) { + action.accept(now); + } + }); + return this; + } + + public Menu separator() { + insert(null, 0); + return this; + } + + public Menu submenu(String label, Consumer

build) { + long entry = insert(label, SDLTray.SDL_TRAYENTRY_SUBMENU); + long submenu = SDLTray.SDL_CreateTraySubmenu(entry); + SDL.checkHandle(submenu, "SDL_CreateTraySubmenu"); + if (build != null) { + build.accept(new Menu(submenu)); + } + return this; + } + + private long insert(String label, int flags) { + ensureOpen(); + long entry = label == null + ? SDLTray.nSDL_InsertTrayEntryAt(handle, -1, 0L, flags) + : SDLTray.SDL_InsertTrayEntryAt(handle, -1, label, flags); + if (label != null) { + SDL.checkHandle(entry, "SDL_InsertTrayEntryAt"); + } + return entry; + } + + private void bind(long entry, Consumer action) { + SDL_TrayCallback callback = SDL_TrayCallback.create((userdata, clicked) -> action.accept(clicked)); + callbacks.add(callback); + SDLTray.SDL_SetTrayEntryCallback(entry, callback, 0L); + } + + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/WindowListener.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/WindowListener.java new file mode 100644 index 000000000..b7df25c98 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/WindowListener.java @@ -0,0 +1,18 @@ +package com.cleanroommc.client.sdl; + +/** + * Host-window notifications. Called from {@link Window#pump()} on the thread that pumps. + */ +public interface WindowListener { + + default void resized(int width, int height) { } + + default void focus(boolean focused) { } + + default void closeRequested() { } + + default void displayChanged() { } + + default void scaleChanged(float scale) { } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/camera/Camera.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/camera/Camera.java index 574d4c4fa..142c6831b 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/camera/Camera.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/camera/Camera.java @@ -40,10 +40,6 @@ public int id() { return id; } - public long handle() { - return handle; - } - public String name() { String name = SDLCamera.SDL_GetCameraName(id); return name == null ? "" : name; @@ -153,4 +149,8 @@ public void close() { handle = 0L; } + long handle() { + return handle; + } + } diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Gamepad.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Gamepad.java index d5f0c6a56..4273e4a8e 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Gamepad.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Gamepad.java @@ -74,11 +74,11 @@ public GamepadLabel label(GamepadButton button) { return GamepadLabel.of(SDLGamepad.SDL_GetGamepadButtonLabel(handle, button.value())); } - public int playerIndex() { + public int player() { return SDLGamepad.SDL_GetGamepadPlayerIndex(handle); } - public Gamepad playerIndex(int index) { + public Gamepad player(int index) { SDL.check(SDLGamepad.SDL_SetGamepadPlayerIndex(handle, index), "SDL_SetGamepadPlayerIndex"); return this; } From 8139211715057a0daf5e193539dcfc36802495a0 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Wed, 19 Aug 2026 22:47:00 +0100 Subject: [PATCH 73/99] Keyboard, keys, mouse, pens --- .../client/sdl/input/KeyModifier.java | 85 +++ .../client/sdl/input/Keyboard.java | 80 +++ .../cleanroommc/client/sdl/input/Keycode.java | 540 ++++++++++++++++++ .../cleanroommc/client/sdl/input/Mouse.java | 85 +++ .../client/sdl/input/MouseButton.java | 35 ++ .../cleanroommc/client/sdl/input/PenAxis.java | 39 ++ .../client/sdl/input/PenListener.java | 18 + .../cleanroommc/client/sdl/input/PenType.java | 32 ++ .../cleanroommc/client/sdl/input/Pens.java | 95 +++ .../client/sdl/input/Scancode.java | 525 +++++++++++++++++ .../client/sdl/input/SystemCursor.java | 39 ++ 11 files changed, 1573 insertions(+) create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/KeyModifier.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Keyboard.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Keycode.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Mouse.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/MouseButton.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/PenAxis.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/PenListener.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/PenType.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Pens.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Scancode.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/SystemCursor.java diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/KeyModifier.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/KeyModifier.java new file mode 100644 index 000000000..46f12739d --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/KeyModifier.java @@ -0,0 +1,85 @@ +package com.cleanroommc.client.sdl.input; + +import org.lwjgl.sdl.SDLKeycode; + +/** + * Modifier bits from {@code SDL_GetModState}. Combine with {@link #has(int)}. + */ +public final class KeyModifier { + + public static final int NONE = SDLKeycode.SDL_KMOD_NONE; + public static final int LSHIFT = SDLKeycode.SDL_KMOD_LSHIFT; + public static final int RSHIFT = SDLKeycode.SDL_KMOD_RSHIFT; + public static final int SHIFT = SDLKeycode.SDL_KMOD_SHIFT; + public static final int LCTRL = SDLKeycode.SDL_KMOD_LCTRL; + public static final int RCTRL = SDLKeycode.SDL_KMOD_RCTRL; + public static final int CTRL = SDLKeycode.SDL_KMOD_CTRL; + public static final int LALT = SDLKeycode.SDL_KMOD_LALT; + public static final int RALT = SDLKeycode.SDL_KMOD_RALT; + public static final int ALT = SDLKeycode.SDL_KMOD_ALT; + public static final int LGUI = SDLKeycode.SDL_KMOD_LGUI; + public static final int RGUI = SDLKeycode.SDL_KMOD_RGUI; + public static final int GUI = SDLKeycode.SDL_KMOD_GUI; + public static final int NUM = SDLKeycode.SDL_KMOD_NUM; + public static final int CAPS = SDLKeycode.SDL_KMOD_CAPS; + public static final int MODE = SDLKeycode.SDL_KMOD_MODE; + public static final int SCROLL = SDLKeycode.SDL_KMOD_SCROLL; + + public static KeyModifier none() { + return new KeyModifier(NONE); + } + + public static KeyModifier of(int bits) { + return new KeyModifier(bits); + } + + private final int bits; + + private KeyModifier(int bits) { + this.bits = bits; + } + + public int value() { + return bits; + } + + public boolean has(int mask) { + return (bits & mask) != 0; + } + + public boolean shift() { + return has(SHIFT); + } + + public boolean ctrl() { + return has(CTRL); + } + + public boolean alt() { + return has(ALT); + } + + public boolean gui() { + return has(GUI); + } + + public boolean capsLock() { + return has(CAPS); + } + + @Override + public boolean equals(Object other) { + return other instanceof KeyModifier mod && mod.bits == bits; + } + + @Override + public int hashCode() { + return bits; + } + + @Override + public String toString() { + return "KeyMod{0x" + Integer.toHexString(bits) + "}"; + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Keyboard.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Keyboard.java new file mode 100644 index 000000000..d5ffce9c3 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Keyboard.java @@ -0,0 +1,80 @@ +package com.cleanroommc.client.sdl.input; + +import com.cleanroommc.client.sdl.Window; +import org.lwjgl.sdl.SDLKeyboard; +import org.lwjgl.system.MemoryStack; + +import java.nio.ShortBuffer; + +/** + * Physical and layout-aware key state for the host window. + */ +public final class Keyboard { + + Keyboard() { } + + /** + * @return whether {@code scancode} is held on the host window + */ + public boolean down(Scancode scancode) { + if (scancode == null) { + return false; + } + Window window = Window.main(); + return window != null && window.keyDown(scancode.value()); + } + + /** + * @return whether the key that currently produces {@code keycode} is held + */ + public boolean down(Keycode keycode) { + if (keycode == null) { + return false; + } + try (MemoryStack stack = MemoryStack.stackPush()) { + ShortBuffer unused = stack.mallocShort(1); + int scancode = SDLKeyboard.SDL_GetScancodeFromKey(keycode.value(), unused); + return Window.main() != null && Window.main().keyDown(scancode); + } + } + + /** + * @return the current modifier bits + */ + public KeyModifier mods() { + if (Window.main() == null) { + return KeyModifier.none(); + } + return KeyModifier.of(SDLKeyboard.SDL_GetModState() & 0xFFFF); + } + + /** + * @return SDL's name for {@code scancode}, such as {@code "W"} + */ + public String name(Scancode scancode) { + if (scancode == null) { + return ""; + } + String name = SDLKeyboard.SDL_GetScancodeName(scancode.value()); + return name == null ? "" : name; + } + + /** + * @return SDL's name for {@code keycode} + */ + public String name(Keycode keycode) { + if (keycode == null) { + return ""; + } + String name = SDLKeyboard.SDL_GetKeyName(keycode.value()); + return name == null ? "" : name; + } + + /** + * Asks SDL to release every key. The host window also synthesizes key-ups on focus loss. + */ + public void reset() { + SDLKeyboard.SDL_ResetKeyboard(); + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Keycode.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Keycode.java new file mode 100644 index 000000000..7d593b45f --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Keycode.java @@ -0,0 +1,540 @@ +package com.cleanroommc.client.sdl.input; + +import org.lwjgl.sdl.SDLKeycode; + +/** + * SDL keycodes. + */ +public enum Keycode { + + UNKNOWN(SDLKeycode.SDLK_UNKNOWN), + RETURN(SDLKeycode.SDLK_RETURN), + ESCAPE(SDLKeycode.SDLK_ESCAPE), + BACKSPACE(SDLKeycode.SDLK_BACKSPACE), + TAB(SDLKeycode.SDLK_TAB), + SPACE(SDLKeycode.SDLK_SPACE), + EXCLAIM(SDLKeycode.SDLK_EXCLAIM), + DBLAPOSTROPHE(SDLKeycode.SDLK_DBLAPOSTROPHE), + HASH(SDLKeycode.SDLK_HASH), + DOLLAR(SDLKeycode.SDLK_DOLLAR), + PERCENT(SDLKeycode.SDLK_PERCENT), + AMPERSAND(SDLKeycode.SDLK_AMPERSAND), + APOSTROPHE(SDLKeycode.SDLK_APOSTROPHE), + LEFTPAREN(SDLKeycode.SDLK_LEFTPAREN), + RIGHTPAREN(SDLKeycode.SDLK_RIGHTPAREN), + ASTERISK(SDLKeycode.SDLK_ASTERISK), + PLUS(SDLKeycode.SDLK_PLUS), + COMMA(SDLKeycode.SDLK_COMMA), + MINUS(SDLKeycode.SDLK_MINUS), + PERIOD(SDLKeycode.SDLK_PERIOD), + SLASH(SDLKeycode.SDLK_SLASH), + DIGIT_0(SDLKeycode.SDLK_0), + DIGIT_1(SDLKeycode.SDLK_1), + DIGIT_2(SDLKeycode.SDLK_2), + DIGIT_3(SDLKeycode.SDLK_3), + DIGIT_4(SDLKeycode.SDLK_4), + DIGIT_5(SDLKeycode.SDLK_5), + DIGIT_6(SDLKeycode.SDLK_6), + DIGIT_7(SDLKeycode.SDLK_7), + DIGIT_8(SDLKeycode.SDLK_8), + DIGIT_9(SDLKeycode.SDLK_9), + COLON(SDLKeycode.SDLK_COLON), + SEMICOLON(SDLKeycode.SDLK_SEMICOLON), + LESS(SDLKeycode.SDLK_LESS), + EQUALS(SDLKeycode.SDLK_EQUALS), + GREATER(SDLKeycode.SDLK_GREATER), + QUESTION(SDLKeycode.SDLK_QUESTION), + AT(SDLKeycode.SDLK_AT), + LEFTBRACKET(SDLKeycode.SDLK_LEFTBRACKET), + BACKSLASH(SDLKeycode.SDLK_BACKSLASH), + RIGHTBRACKET(SDLKeycode.SDLK_RIGHTBRACKET), + CARET(SDLKeycode.SDLK_CARET), + UNDERSCORE(SDLKeycode.SDLK_UNDERSCORE), + GRAVE(SDLKeycode.SDLK_GRAVE), + A(SDLKeycode.SDLK_A), + B(SDLKeycode.SDLK_B), + C(SDLKeycode.SDLK_C), + D(SDLKeycode.SDLK_D), + E(SDLKeycode.SDLK_E), + F(SDLKeycode.SDLK_F), + G(SDLKeycode.SDLK_G), + H(SDLKeycode.SDLK_H), + I(SDLKeycode.SDLK_I), + J(SDLKeycode.SDLK_J), + K(SDLKeycode.SDLK_K), + L(SDLKeycode.SDLK_L), + M(SDLKeycode.SDLK_M), + N(SDLKeycode.SDLK_N), + O(SDLKeycode.SDLK_O), + P(SDLKeycode.SDLK_P), + Q(SDLKeycode.SDLK_Q), + R(SDLKeycode.SDLK_R), + S(SDLKeycode.SDLK_S), + T(SDLKeycode.SDLK_T), + U(SDLKeycode.SDLK_U), + V(SDLKeycode.SDLK_V), + W(SDLKeycode.SDLK_W), + X(SDLKeycode.SDLK_X), + Y(SDLKeycode.SDLK_Y), + Z(SDLKeycode.SDLK_Z), + LEFTBRACE(SDLKeycode.SDLK_LEFTBRACE), + PIPE(SDLKeycode.SDLK_PIPE), + RIGHTBRACE(SDLKeycode.SDLK_RIGHTBRACE), + TILDE(SDLKeycode.SDLK_TILDE), + DELETE(SDLKeycode.SDLK_DELETE), + PLUSMINUS(SDLKeycode.SDLK_PLUSMINUS), + CAPSLOCK(SDLKeycode.SDLK_CAPSLOCK), + F1(SDLKeycode.SDLK_F1), + F2(SDLKeycode.SDLK_F2), + F3(SDLKeycode.SDLK_F3), + F4(SDLKeycode.SDLK_F4), + F5(SDLKeycode.SDLK_F5), + F6(SDLKeycode.SDLK_F6), + F7(SDLKeycode.SDLK_F7), + F8(SDLKeycode.SDLK_F8), + F9(SDLKeycode.SDLK_F9), + F10(SDLKeycode.SDLK_F10), + F11(SDLKeycode.SDLK_F11), + F12(SDLKeycode.SDLK_F12), + PRINTSCREEN(SDLKeycode.SDLK_PRINTSCREEN), + SCROLLLOCK(SDLKeycode.SDLK_SCROLLLOCK), + PAUSE(SDLKeycode.SDLK_PAUSE), + INSERT(SDLKeycode.SDLK_INSERT), + HOME(SDLKeycode.SDLK_HOME), + PAGEUP(SDLKeycode.SDLK_PAGEUP), + END(SDLKeycode.SDLK_END), + PAGEDOWN(SDLKeycode.SDLK_PAGEDOWN), + RIGHT(SDLKeycode.SDLK_RIGHT), + LEFT(SDLKeycode.SDLK_LEFT), + DOWN(SDLKeycode.SDLK_DOWN), + UP(SDLKeycode.SDLK_UP), + NUMLOCKCLEAR(SDLKeycode.SDLK_NUMLOCKCLEAR), + KP_DIVIDE(SDLKeycode.SDLK_KP_DIVIDE), + KP_MULTIPLY(SDLKeycode.SDLK_KP_MULTIPLY), + KP_MINUS(SDLKeycode.SDLK_KP_MINUS), + KP_PLUS(SDLKeycode.SDLK_KP_PLUS), + KP_ENTER(SDLKeycode.SDLK_KP_ENTER), + KP_1(SDLKeycode.SDLK_KP_1), + KP_2(SDLKeycode.SDLK_KP_2), + KP_3(SDLKeycode.SDLK_KP_3), + KP_4(SDLKeycode.SDLK_KP_4), + KP_5(SDLKeycode.SDLK_KP_5), + KP_6(SDLKeycode.SDLK_KP_6), + KP_7(SDLKeycode.SDLK_KP_7), + KP_8(SDLKeycode.SDLK_KP_8), + KP_9(SDLKeycode.SDLK_KP_9), + KP_0(SDLKeycode.SDLK_KP_0), + KP_PERIOD(SDLKeycode.SDLK_KP_PERIOD), + APPLICATION(SDLKeycode.SDLK_APPLICATION), + POWER(SDLKeycode.SDLK_POWER), + KP_EQUALS(SDLKeycode.SDLK_KP_EQUALS), + F13(SDLKeycode.SDLK_F13), + F14(SDLKeycode.SDLK_F14), + F15(SDLKeycode.SDLK_F15), + F16(SDLKeycode.SDLK_F16), + F17(SDLKeycode.SDLK_F17), + F18(SDLKeycode.SDLK_F18), + F19(SDLKeycode.SDLK_F19), + F20(SDLKeycode.SDLK_F20), + F21(SDLKeycode.SDLK_F21), + F22(SDLKeycode.SDLK_F22), + F23(SDLKeycode.SDLK_F23), + F24(SDLKeycode.SDLK_F24), + EXECUTE(SDLKeycode.SDLK_EXECUTE), + HELP(SDLKeycode.SDLK_HELP), + MENU(SDLKeycode.SDLK_MENU), + SELECT(SDLKeycode.SDLK_SELECT), + STOP(SDLKeycode.SDLK_STOP), + AGAIN(SDLKeycode.SDLK_AGAIN), + UNDO(SDLKeycode.SDLK_UNDO), + CUT(SDLKeycode.SDLK_CUT), + COPY(SDLKeycode.SDLK_COPY), + PASTE(SDLKeycode.SDLK_PASTE), + FIND(SDLKeycode.SDLK_FIND), + MUTE(SDLKeycode.SDLK_MUTE), + VOLUMEUP(SDLKeycode.SDLK_VOLUMEUP), + VOLUMEDOWN(SDLKeycode.SDLK_VOLUMEDOWN), + KP_COMMA(SDLKeycode.SDLK_KP_COMMA), + KP_EQUALSAS400(SDLKeycode.SDLK_KP_EQUALSAS400), + ALTERASE(SDLKeycode.SDLK_ALTERASE), + SYSREQ(SDLKeycode.SDLK_SYSREQ), + CANCEL(SDLKeycode.SDLK_CANCEL), + CLEAR(SDLKeycode.SDLK_CLEAR), + PRIOR(SDLKeycode.SDLK_PRIOR), + RETURN2(SDLKeycode.SDLK_RETURN2), + SEPARATOR(SDLKeycode.SDLK_SEPARATOR), + OUT(SDLKeycode.SDLK_OUT), + OPER(SDLKeycode.SDLK_OPER), + CLEARAGAIN(SDLKeycode.SDLK_CLEARAGAIN), + CRSEL(SDLKeycode.SDLK_CRSEL), + EXSEL(SDLKeycode.SDLK_EXSEL), + KP_00(SDLKeycode.SDLK_KP_00), + KP_000(SDLKeycode.SDLK_KP_000), + THOUSANDSSEPARATOR(SDLKeycode.SDLK_THOUSANDSSEPARATOR), + DECIMALSEPARATOR(SDLKeycode.SDLK_DECIMALSEPARATOR), + CURRENCYUNIT(SDLKeycode.SDLK_CURRENCYUNIT), + CURRENCYSUBUNIT(SDLKeycode.SDLK_CURRENCYSUBUNIT), + KP_LEFTPAREN(SDLKeycode.SDLK_KP_LEFTPAREN), + KP_RIGHTPAREN(SDLKeycode.SDLK_KP_RIGHTPAREN), + KP_LEFTBRACE(SDLKeycode.SDLK_KP_LEFTBRACE), + KP_RIGHTBRACE(SDLKeycode.SDLK_KP_RIGHTBRACE), + KP_TAB(SDLKeycode.SDLK_KP_TAB), + KP_BACKSPACE(SDLKeycode.SDLK_KP_BACKSPACE), + KP_A(SDLKeycode.SDLK_KP_A), + KP_B(SDLKeycode.SDLK_KP_B), + KP_C(SDLKeycode.SDLK_KP_C), + KP_D(SDLKeycode.SDLK_KP_D), + KP_E(SDLKeycode.SDLK_KP_E), + KP_F(SDLKeycode.SDLK_KP_F), + KP_XOR(SDLKeycode.SDLK_KP_XOR), + KP_POWER(SDLKeycode.SDLK_KP_POWER), + KP_PERCENT(SDLKeycode.SDLK_KP_PERCENT), + KP_LESS(SDLKeycode.SDLK_KP_LESS), + KP_GREATER(SDLKeycode.SDLK_KP_GREATER), + KP_AMPERSAND(SDLKeycode.SDLK_KP_AMPERSAND), + KP_DBLAMPERSAND(SDLKeycode.SDLK_KP_DBLAMPERSAND), + KP_VERTICALBAR(SDLKeycode.SDLK_KP_VERTICALBAR), + KP_DBLVERTICALBAR(SDLKeycode.SDLK_KP_DBLVERTICALBAR), + KP_COLON(SDLKeycode.SDLK_KP_COLON), + KP_HASH(SDLKeycode.SDLK_KP_HASH), + KP_SPACE(SDLKeycode.SDLK_KP_SPACE), + KP_AT(SDLKeycode.SDLK_KP_AT), + KP_EXCLAM(SDLKeycode.SDLK_KP_EXCLAM), + KP_MEMSTORE(SDLKeycode.SDLK_KP_MEMSTORE), + KP_MEMRECALL(SDLKeycode.SDLK_KP_MEMRECALL), + KP_MEMCLEAR(SDLKeycode.SDLK_KP_MEMCLEAR), + KP_MEMADD(SDLKeycode.SDLK_KP_MEMADD), + KP_MEMSUBTRACT(SDLKeycode.SDLK_KP_MEMSUBTRACT), + KP_MEMMULTIPLY(SDLKeycode.SDLK_KP_MEMMULTIPLY), + KP_MEMDIVIDE(SDLKeycode.SDLK_KP_MEMDIVIDE), + KP_PLUSMINUS(SDLKeycode.SDLK_KP_PLUSMINUS), + KP_CLEAR(SDLKeycode.SDLK_KP_CLEAR), + KP_CLEARENTRY(SDLKeycode.SDLK_KP_CLEARENTRY), + KP_BINARY(SDLKeycode.SDLK_KP_BINARY), + KP_OCTAL(SDLKeycode.SDLK_KP_OCTAL), + KP_DECIMAL(SDLKeycode.SDLK_KP_DECIMAL), + KP_HEXADECIMAL(SDLKeycode.SDLK_KP_HEXADECIMAL), + LCTRL(SDLKeycode.SDLK_LCTRL), + LSHIFT(SDLKeycode.SDLK_LSHIFT), + LALT(SDLKeycode.SDLK_LALT), + LGUI(SDLKeycode.SDLK_LGUI), + RCTRL(SDLKeycode.SDLK_RCTRL), + RSHIFT(SDLKeycode.SDLK_RSHIFT), + RALT(SDLKeycode.SDLK_RALT), + RGUI(SDLKeycode.SDLK_RGUI), + MODE(SDLKeycode.SDLK_MODE), + SLEEP(SDLKeycode.SDLK_SLEEP), + WAKE(SDLKeycode.SDLK_WAKE), + CHANNEL_INCREMENT(SDLKeycode.SDLK_CHANNEL_INCREMENT), + CHANNEL_DECREMENT(SDLKeycode.SDLK_CHANNEL_DECREMENT), + MEDIA_PLAY(SDLKeycode.SDLK_MEDIA_PLAY), + MEDIA_PAUSE(SDLKeycode.SDLK_MEDIA_PAUSE), + MEDIA_RECORD(SDLKeycode.SDLK_MEDIA_RECORD), + MEDIA_FAST_FORWARD(SDLKeycode.SDLK_MEDIA_FAST_FORWARD), + MEDIA_REWIND(SDLKeycode.SDLK_MEDIA_REWIND), + MEDIA_NEXT_TRACK(SDLKeycode.SDLK_MEDIA_NEXT_TRACK), + MEDIA_PREVIOUS_TRACK(SDLKeycode.SDLK_MEDIA_PREVIOUS_TRACK), + MEDIA_STOP(SDLKeycode.SDLK_MEDIA_STOP), + MEDIA_EJECT(SDLKeycode.SDLK_MEDIA_EJECT), + MEDIA_PLAY_PAUSE(SDLKeycode.SDLK_MEDIA_PLAY_PAUSE), + MEDIA_SELECT(SDLKeycode.SDLK_MEDIA_SELECT), + AC_NEW(SDLKeycode.SDLK_AC_NEW), + AC_OPEN(SDLKeycode.SDLK_AC_OPEN), + AC_CLOSE(SDLKeycode.SDLK_AC_CLOSE), + AC_EXIT(SDLKeycode.SDLK_AC_EXIT), + AC_SAVE(SDLKeycode.SDLK_AC_SAVE), + AC_PRINT(SDLKeycode.SDLK_AC_PRINT), + AC_PROPERTIES(SDLKeycode.SDLK_AC_PROPERTIES), + AC_SEARCH(SDLKeycode.SDLK_AC_SEARCH), + AC_HOME(SDLKeycode.SDLK_AC_HOME), + AC_BACK(SDLKeycode.SDLK_AC_BACK), + AC_FORWARD(SDLKeycode.SDLK_AC_FORWARD), + AC_STOP(SDLKeycode.SDLK_AC_STOP), + AC_REFRESH(SDLKeycode.SDLK_AC_REFRESH), + AC_BOOKMARKS(SDLKeycode.SDLK_AC_BOOKMARKS), + SOFTLEFT(SDLKeycode.SDLK_SOFTLEFT), + SOFTRIGHT(SDLKeycode.SDLK_SOFTRIGHT), + CALL(SDLKeycode.SDLK_CALL), + ENDCALL(SDLKeycode.SDLK_ENDCALL), + LEFT_TAB(SDLKeycode.SDLK_LEFT_TAB), + LEVEL5_SHIFT(SDLKeycode.SDLK_LEVEL5_SHIFT), + MULTI_KEY_COMPOSE(SDLKeycode.SDLK_MULTI_KEY_COMPOSE), + LMETA(SDLKeycode.SDLK_LMETA), + RMETA(SDLKeycode.SDLK_RMETA), + LHYPER(SDLKeycode.SDLK_LHYPER), + RHYPER(SDLKeycode.SDLK_RHYPER); + + private final int value; + + Keycode(int value) { + this.value = value; + } + + /** @return the SDLK_* value */ + public int value() { + return this.value; + } + + /** @return the named keycode, or null when SDL has no name for value */ + public static Keycode of(int value) { + return switch (value) { + case SDLKeycode.SDLK_UNKNOWN -> UNKNOWN; + case SDLKeycode.SDLK_RETURN -> RETURN; + case SDLKeycode.SDLK_ESCAPE -> ESCAPE; + case SDLKeycode.SDLK_BACKSPACE -> BACKSPACE; + case SDLKeycode.SDLK_TAB -> TAB; + case SDLKeycode.SDLK_SPACE -> SPACE; + case SDLKeycode.SDLK_EXCLAIM -> EXCLAIM; + case SDLKeycode.SDLK_DBLAPOSTROPHE -> DBLAPOSTROPHE; + case SDLKeycode.SDLK_HASH -> HASH; + case SDLKeycode.SDLK_DOLLAR -> DOLLAR; + case SDLKeycode.SDLK_PERCENT -> PERCENT; + case SDLKeycode.SDLK_AMPERSAND -> AMPERSAND; + case SDLKeycode.SDLK_APOSTROPHE -> APOSTROPHE; + case SDLKeycode.SDLK_LEFTPAREN -> LEFTPAREN; + case SDLKeycode.SDLK_RIGHTPAREN -> RIGHTPAREN; + case SDLKeycode.SDLK_ASTERISK -> ASTERISK; + case SDLKeycode.SDLK_PLUS -> PLUS; + case SDLKeycode.SDLK_COMMA -> COMMA; + case SDLKeycode.SDLK_MINUS -> MINUS; + case SDLKeycode.SDLK_PERIOD -> PERIOD; + case SDLKeycode.SDLK_SLASH -> SLASH; + case SDLKeycode.SDLK_0 -> DIGIT_0; + case SDLKeycode.SDLK_1 -> DIGIT_1; + case SDLKeycode.SDLK_2 -> DIGIT_2; + case SDLKeycode.SDLK_3 -> DIGIT_3; + case SDLKeycode.SDLK_4 -> DIGIT_4; + case SDLKeycode.SDLK_5 -> DIGIT_5; + case SDLKeycode.SDLK_6 -> DIGIT_6; + case SDLKeycode.SDLK_7 -> DIGIT_7; + case SDLKeycode.SDLK_8 -> DIGIT_8; + case SDLKeycode.SDLK_9 -> DIGIT_9; + case SDLKeycode.SDLK_COLON -> COLON; + case SDLKeycode.SDLK_SEMICOLON -> SEMICOLON; + case SDLKeycode.SDLK_LESS -> LESS; + case SDLKeycode.SDLK_EQUALS -> EQUALS; + case SDLKeycode.SDLK_GREATER -> GREATER; + case SDLKeycode.SDLK_QUESTION -> QUESTION; + case SDLKeycode.SDLK_AT -> AT; + case SDLKeycode.SDLK_LEFTBRACKET -> LEFTBRACKET; + case SDLKeycode.SDLK_BACKSLASH -> BACKSLASH; + case SDLKeycode.SDLK_RIGHTBRACKET -> RIGHTBRACKET; + case SDLKeycode.SDLK_CARET -> CARET; + case SDLKeycode.SDLK_UNDERSCORE -> UNDERSCORE; + case SDLKeycode.SDLK_GRAVE -> GRAVE; + case SDLKeycode.SDLK_A -> A; + case SDLKeycode.SDLK_B -> B; + case SDLKeycode.SDLK_C -> C; + case SDLKeycode.SDLK_D -> D; + case SDLKeycode.SDLK_E -> E; + case SDLKeycode.SDLK_F -> F; + case SDLKeycode.SDLK_G -> G; + case SDLKeycode.SDLK_H -> H; + case SDLKeycode.SDLK_I -> I; + case SDLKeycode.SDLK_J -> J; + case SDLKeycode.SDLK_K -> K; + case SDLKeycode.SDLK_L -> L; + case SDLKeycode.SDLK_M -> M; + case SDLKeycode.SDLK_N -> N; + case SDLKeycode.SDLK_O -> O; + case SDLKeycode.SDLK_P -> P; + case SDLKeycode.SDLK_Q -> Q; + case SDLKeycode.SDLK_R -> R; + case SDLKeycode.SDLK_S -> S; + case SDLKeycode.SDLK_T -> T; + case SDLKeycode.SDLK_U -> U; + case SDLKeycode.SDLK_V -> V; + case SDLKeycode.SDLK_W -> W; + case SDLKeycode.SDLK_X -> X; + case SDLKeycode.SDLK_Y -> Y; + case SDLKeycode.SDLK_Z -> Z; + case SDLKeycode.SDLK_LEFTBRACE -> LEFTBRACE; + case SDLKeycode.SDLK_PIPE -> PIPE; + case SDLKeycode.SDLK_RIGHTBRACE -> RIGHTBRACE; + case SDLKeycode.SDLK_TILDE -> TILDE; + case SDLKeycode.SDLK_DELETE -> DELETE; + case SDLKeycode.SDLK_PLUSMINUS -> PLUSMINUS; + case SDLKeycode.SDLK_CAPSLOCK -> CAPSLOCK; + case SDLKeycode.SDLK_F1 -> F1; + case SDLKeycode.SDLK_F2 -> F2; + case SDLKeycode.SDLK_F3 -> F3; + case SDLKeycode.SDLK_F4 -> F4; + case SDLKeycode.SDLK_F5 -> F5; + case SDLKeycode.SDLK_F6 -> F6; + case SDLKeycode.SDLK_F7 -> F7; + case SDLKeycode.SDLK_F8 -> F8; + case SDLKeycode.SDLK_F9 -> F9; + case SDLKeycode.SDLK_F10 -> F10; + case SDLKeycode.SDLK_F11 -> F11; + case SDLKeycode.SDLK_F12 -> F12; + case SDLKeycode.SDLK_PRINTSCREEN -> PRINTSCREEN; + case SDLKeycode.SDLK_SCROLLLOCK -> SCROLLLOCK; + case SDLKeycode.SDLK_PAUSE -> PAUSE; + case SDLKeycode.SDLK_INSERT -> INSERT; + case SDLKeycode.SDLK_HOME -> HOME; + case SDLKeycode.SDLK_PAGEUP -> PAGEUP; + case SDLKeycode.SDLK_END -> END; + case SDLKeycode.SDLK_PAGEDOWN -> PAGEDOWN; + case SDLKeycode.SDLK_RIGHT -> RIGHT; + case SDLKeycode.SDLK_LEFT -> LEFT; + case SDLKeycode.SDLK_DOWN -> DOWN; + case SDLKeycode.SDLK_UP -> UP; + case SDLKeycode.SDLK_NUMLOCKCLEAR -> NUMLOCKCLEAR; + case SDLKeycode.SDLK_KP_DIVIDE -> KP_DIVIDE; + case SDLKeycode.SDLK_KP_MULTIPLY -> KP_MULTIPLY; + case SDLKeycode.SDLK_KP_MINUS -> KP_MINUS; + case SDLKeycode.SDLK_KP_PLUS -> KP_PLUS; + case SDLKeycode.SDLK_KP_ENTER -> KP_ENTER; + case SDLKeycode.SDLK_KP_1 -> KP_1; + case SDLKeycode.SDLK_KP_2 -> KP_2; + case SDLKeycode.SDLK_KP_3 -> KP_3; + case SDLKeycode.SDLK_KP_4 -> KP_4; + case SDLKeycode.SDLK_KP_5 -> KP_5; + case SDLKeycode.SDLK_KP_6 -> KP_6; + case SDLKeycode.SDLK_KP_7 -> KP_7; + case SDLKeycode.SDLK_KP_8 -> KP_8; + case SDLKeycode.SDLK_KP_9 -> KP_9; + case SDLKeycode.SDLK_KP_0 -> KP_0; + case SDLKeycode.SDLK_KP_PERIOD -> KP_PERIOD; + case SDLKeycode.SDLK_APPLICATION -> APPLICATION; + case SDLKeycode.SDLK_POWER -> POWER; + case SDLKeycode.SDLK_KP_EQUALS -> KP_EQUALS; + case SDLKeycode.SDLK_F13 -> F13; + case SDLKeycode.SDLK_F14 -> F14; + case SDLKeycode.SDLK_F15 -> F15; + case SDLKeycode.SDLK_F16 -> F16; + case SDLKeycode.SDLK_F17 -> F17; + case SDLKeycode.SDLK_F18 -> F18; + case SDLKeycode.SDLK_F19 -> F19; + case SDLKeycode.SDLK_F20 -> F20; + case SDLKeycode.SDLK_F21 -> F21; + case SDLKeycode.SDLK_F22 -> F22; + case SDLKeycode.SDLK_F23 -> F23; + case SDLKeycode.SDLK_F24 -> F24; + case SDLKeycode.SDLK_EXECUTE -> EXECUTE; + case SDLKeycode.SDLK_HELP -> HELP; + case SDLKeycode.SDLK_MENU -> MENU; + case SDLKeycode.SDLK_SELECT -> SELECT; + case SDLKeycode.SDLK_STOP -> STOP; + case SDLKeycode.SDLK_AGAIN -> AGAIN; + case SDLKeycode.SDLK_UNDO -> UNDO; + case SDLKeycode.SDLK_CUT -> CUT; + case SDLKeycode.SDLK_COPY -> COPY; + case SDLKeycode.SDLK_PASTE -> PASTE; + case SDLKeycode.SDLK_FIND -> FIND; + case SDLKeycode.SDLK_MUTE -> MUTE; + case SDLKeycode.SDLK_VOLUMEUP -> VOLUMEUP; + case SDLKeycode.SDLK_VOLUMEDOWN -> VOLUMEDOWN; + case SDLKeycode.SDLK_KP_COMMA -> KP_COMMA; + case SDLKeycode.SDLK_KP_EQUALSAS400 -> KP_EQUALSAS400; + case SDLKeycode.SDLK_ALTERASE -> ALTERASE; + case SDLKeycode.SDLK_SYSREQ -> SYSREQ; + case SDLKeycode.SDLK_CANCEL -> CANCEL; + case SDLKeycode.SDLK_CLEAR -> CLEAR; + case SDLKeycode.SDLK_PRIOR -> PRIOR; + case SDLKeycode.SDLK_RETURN2 -> RETURN2; + case SDLKeycode.SDLK_SEPARATOR -> SEPARATOR; + case SDLKeycode.SDLK_OUT -> OUT; + case SDLKeycode.SDLK_OPER -> OPER; + case SDLKeycode.SDLK_CLEARAGAIN -> CLEARAGAIN; + case SDLKeycode.SDLK_CRSEL -> CRSEL; + case SDLKeycode.SDLK_EXSEL -> EXSEL; + case SDLKeycode.SDLK_KP_00 -> KP_00; + case SDLKeycode.SDLK_KP_000 -> KP_000; + case SDLKeycode.SDLK_THOUSANDSSEPARATOR -> THOUSANDSSEPARATOR; + case SDLKeycode.SDLK_DECIMALSEPARATOR -> DECIMALSEPARATOR; + case SDLKeycode.SDLK_CURRENCYUNIT -> CURRENCYUNIT; + case SDLKeycode.SDLK_CURRENCYSUBUNIT -> CURRENCYSUBUNIT; + case SDLKeycode.SDLK_KP_LEFTPAREN -> KP_LEFTPAREN; + case SDLKeycode.SDLK_KP_RIGHTPAREN -> KP_RIGHTPAREN; + case SDLKeycode.SDLK_KP_LEFTBRACE -> KP_LEFTBRACE; + case SDLKeycode.SDLK_KP_RIGHTBRACE -> KP_RIGHTBRACE; + case SDLKeycode.SDLK_KP_TAB -> KP_TAB; + case SDLKeycode.SDLK_KP_BACKSPACE -> KP_BACKSPACE; + case SDLKeycode.SDLK_KP_A -> KP_A; + case SDLKeycode.SDLK_KP_B -> KP_B; + case SDLKeycode.SDLK_KP_C -> KP_C; + case SDLKeycode.SDLK_KP_D -> KP_D; + case SDLKeycode.SDLK_KP_E -> KP_E; + case SDLKeycode.SDLK_KP_F -> KP_F; + case SDLKeycode.SDLK_KP_XOR -> KP_XOR; + case SDLKeycode.SDLK_KP_POWER -> KP_POWER; + case SDLKeycode.SDLK_KP_PERCENT -> KP_PERCENT; + case SDLKeycode.SDLK_KP_LESS -> KP_LESS; + case SDLKeycode.SDLK_KP_GREATER -> KP_GREATER; + case SDLKeycode.SDLK_KP_AMPERSAND -> KP_AMPERSAND; + case SDLKeycode.SDLK_KP_DBLAMPERSAND -> KP_DBLAMPERSAND; + case SDLKeycode.SDLK_KP_VERTICALBAR -> KP_VERTICALBAR; + case SDLKeycode.SDLK_KP_DBLVERTICALBAR -> KP_DBLVERTICALBAR; + case SDLKeycode.SDLK_KP_COLON -> KP_COLON; + case SDLKeycode.SDLK_KP_HASH -> KP_HASH; + case SDLKeycode.SDLK_KP_SPACE -> KP_SPACE; + case SDLKeycode.SDLK_KP_AT -> KP_AT; + case SDLKeycode.SDLK_KP_EXCLAM -> KP_EXCLAM; + case SDLKeycode.SDLK_KP_MEMSTORE -> KP_MEMSTORE; + case SDLKeycode.SDLK_KP_MEMRECALL -> KP_MEMRECALL; + case SDLKeycode.SDLK_KP_MEMCLEAR -> KP_MEMCLEAR; + case SDLKeycode.SDLK_KP_MEMADD -> KP_MEMADD; + case SDLKeycode.SDLK_KP_MEMSUBTRACT -> KP_MEMSUBTRACT; + case SDLKeycode.SDLK_KP_MEMMULTIPLY -> KP_MEMMULTIPLY; + case SDLKeycode.SDLK_KP_MEMDIVIDE -> KP_MEMDIVIDE; + case SDLKeycode.SDLK_KP_PLUSMINUS -> KP_PLUSMINUS; + case SDLKeycode.SDLK_KP_CLEAR -> KP_CLEAR; + case SDLKeycode.SDLK_KP_CLEARENTRY -> KP_CLEARENTRY; + case SDLKeycode.SDLK_KP_BINARY -> KP_BINARY; + case SDLKeycode.SDLK_KP_OCTAL -> KP_OCTAL; + case SDLKeycode.SDLK_KP_DECIMAL -> KP_DECIMAL; + case SDLKeycode.SDLK_KP_HEXADECIMAL -> KP_HEXADECIMAL; + case SDLKeycode.SDLK_LCTRL -> LCTRL; + case SDLKeycode.SDLK_LSHIFT -> LSHIFT; + case SDLKeycode.SDLK_LALT -> LALT; + case SDLKeycode.SDLK_LGUI -> LGUI; + case SDLKeycode.SDLK_RCTRL -> RCTRL; + case SDLKeycode.SDLK_RSHIFT -> RSHIFT; + case SDLKeycode.SDLK_RALT -> RALT; + case SDLKeycode.SDLK_RGUI -> RGUI; + case SDLKeycode.SDLK_MODE -> MODE; + case SDLKeycode.SDLK_SLEEP -> SLEEP; + case SDLKeycode.SDLK_WAKE -> WAKE; + case SDLKeycode.SDLK_CHANNEL_INCREMENT -> CHANNEL_INCREMENT; + case SDLKeycode.SDLK_CHANNEL_DECREMENT -> CHANNEL_DECREMENT; + case SDLKeycode.SDLK_MEDIA_PLAY -> MEDIA_PLAY; + case SDLKeycode.SDLK_MEDIA_PAUSE -> MEDIA_PAUSE; + case SDLKeycode.SDLK_MEDIA_RECORD -> MEDIA_RECORD; + case SDLKeycode.SDLK_MEDIA_FAST_FORWARD -> MEDIA_FAST_FORWARD; + case SDLKeycode.SDLK_MEDIA_REWIND -> MEDIA_REWIND; + case SDLKeycode.SDLK_MEDIA_NEXT_TRACK -> MEDIA_NEXT_TRACK; + case SDLKeycode.SDLK_MEDIA_PREVIOUS_TRACK -> MEDIA_PREVIOUS_TRACK; + case SDLKeycode.SDLK_MEDIA_STOP -> MEDIA_STOP; + case SDLKeycode.SDLK_MEDIA_EJECT -> MEDIA_EJECT; + case SDLKeycode.SDLK_MEDIA_PLAY_PAUSE -> MEDIA_PLAY_PAUSE; + case SDLKeycode.SDLK_MEDIA_SELECT -> MEDIA_SELECT; + case SDLKeycode.SDLK_AC_NEW -> AC_NEW; + case SDLKeycode.SDLK_AC_OPEN -> AC_OPEN; + case SDLKeycode.SDLK_AC_CLOSE -> AC_CLOSE; + case SDLKeycode.SDLK_AC_EXIT -> AC_EXIT; + case SDLKeycode.SDLK_AC_SAVE -> AC_SAVE; + case SDLKeycode.SDLK_AC_PRINT -> AC_PRINT; + case SDLKeycode.SDLK_AC_PROPERTIES -> AC_PROPERTIES; + case SDLKeycode.SDLK_AC_SEARCH -> AC_SEARCH; + case SDLKeycode.SDLK_AC_HOME -> AC_HOME; + case SDLKeycode.SDLK_AC_BACK -> AC_BACK; + case SDLKeycode.SDLK_AC_FORWARD -> AC_FORWARD; + case SDLKeycode.SDLK_AC_STOP -> AC_STOP; + case SDLKeycode.SDLK_AC_REFRESH -> AC_REFRESH; + case SDLKeycode.SDLK_AC_BOOKMARKS -> AC_BOOKMARKS; + case SDLKeycode.SDLK_SOFTLEFT -> SOFTLEFT; + case SDLKeycode.SDLK_SOFTRIGHT -> SOFTRIGHT; + case SDLKeycode.SDLK_CALL -> CALL; + case SDLKeycode.SDLK_ENDCALL -> ENDCALL; + case SDLKeycode.SDLK_LEFT_TAB -> LEFT_TAB; + case SDLKeycode.SDLK_LEVEL5_SHIFT -> LEVEL5_SHIFT; + case SDLKeycode.SDLK_MULTI_KEY_COMPOSE -> MULTI_KEY_COMPOSE; + case SDLKeycode.SDLK_LMETA -> LMETA; + case SDLKeycode.SDLK_RMETA -> RMETA; + case SDLKeycode.SDLK_LHYPER -> LHYPER; + case SDLKeycode.SDLK_RHYPER -> RHYPER; + default -> null; + }; + } +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Mouse.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Mouse.java new file mode 100644 index 000000000..262686f9f --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Mouse.java @@ -0,0 +1,85 @@ +package com.cleanroommc.client.sdl.input; + +import com.cleanroommc.client.sdl.SDL; +import com.cleanroommc.client.sdl.Window; +import org.lwjgl.sdl.SDLMouse; + +/** + * Pointer position, buttons, grab and cursor for the host window. + * + *

Coordinates are SDL's, origin at the top-left. LWJGLY still flips Y for {@code org.lwjgl.input.Mouse}. + */ +public final class Mouse { + + Mouse() { } + + public float x() { + Window window = Window.main(); + return window == null ? 0.0F : window.mouseX(); + } + + public float y() { + Window window = Window.main(); + return window == null ? 0.0F : window.mouseY(); + } + + public boolean button(MouseButton button) { + if (button == null) { + return false; + } + Window window = Window.main(); + return window != null && window.mouseButtonDown(button.value()); + } + + public boolean grabbed() { + Window window = Window.main(); + return window != null && window.mouseGrabbed(); + } + + public Mouse grabbed(boolean grab) { + Window window = Window.main(); + if (window != null) { + window.grabMouse(grab); + } + return this; + } + + public Mouse position(float x, float y) { + Window window = Window.main(); + if (window != null) { + window.mousePosition(x, y); + } + return this; + } + + public boolean visible() { + return SDLMouse.SDL_CursorVisible(); + } + + public Mouse visible(boolean visible) { + if (visible) { + SDL.check(SDLMouse.SDL_ShowCursor(), "SDL_ShowCursor"); + } else { + SDL.check(SDLMouse.SDL_HideCursor(), "SDL_HideCursor"); + } + return this; + } + + public Mouse cursor(SystemCursor cursor) { + if (cursor == null) { + throw new IllegalArgumentException("Cursor cannot be null"); + } + Inputs.systemCursor(cursor).apply(); + return this; + } + + public Mouse cursor(Cursor cursor) { + if (cursor == null) { + SDL.check(SDLMouse.SDL_SetCursor(SDLMouse.SDL_GetDefaultCursor()), "SDL_SetCursor"); + return this; + } + cursor.apply(); + return this; + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/MouseButton.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/MouseButton.java new file mode 100644 index 000000000..5ce1b427e --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/MouseButton.java @@ -0,0 +1,35 @@ +package com.cleanroommc.client.sdl.input; + +import org.lwjgl.sdl.SDLMouse; + +/** SDL mouse buttons. */ +public enum MouseButton { + + LEFT(SDLMouse.SDL_BUTTON_LEFT), + MIDDLE(SDLMouse.SDL_BUTTON_MIDDLE), + RIGHT(SDLMouse.SDL_BUTTON_RIGHT), + X1(SDLMouse.SDL_BUTTON_X1), + X2(SDLMouse.SDL_BUTTON_X2); + + public static MouseButton of(int value) { + return switch (value) { + case SDLMouse.SDL_BUTTON_LEFT -> LEFT; + case SDLMouse.SDL_BUTTON_MIDDLE -> MIDDLE; + case SDLMouse.SDL_BUTTON_RIGHT -> RIGHT; + case SDLMouse.SDL_BUTTON_X1 -> X1; + case SDLMouse.SDL_BUTTON_X2 -> X2; + default -> null; + }; + } + + private final int value; + + MouseButton(int value) { + this.value = value; + } + + public int value() { + return value; + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/PenAxis.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/PenAxis.java new file mode 100644 index 000000000..6c59f63da --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/PenAxis.java @@ -0,0 +1,39 @@ +package com.cleanroommc.client.sdl.input; + +import org.lwjgl.sdl.SDLPen; + +/** Axes a drawing tablet reports. */ +public enum PenAxis { + + PRESSURE(SDLPen.SDL_PEN_AXIS_PRESSURE), + X_TILT(SDLPen.SDL_PEN_AXIS_XTILT), + Y_TILT(SDLPen.SDL_PEN_AXIS_YTILT), + DISTANCE(SDLPen.SDL_PEN_AXIS_DISTANCE), + ROTATION(SDLPen.SDL_PEN_AXIS_ROTATION), + SLIDER(SDLPen.SDL_PEN_AXIS_SLIDER), + TANGENTIAL_PRESSURE(SDLPen.SDL_PEN_AXIS_TANGENTIAL_PRESSURE); + + public static PenAxis of(int value) { + return switch (value) { + case SDLPen.SDL_PEN_AXIS_PRESSURE -> PRESSURE; + case SDLPen.SDL_PEN_AXIS_XTILT -> X_TILT; + case SDLPen.SDL_PEN_AXIS_YTILT -> Y_TILT; + case SDLPen.SDL_PEN_AXIS_DISTANCE -> DISTANCE; + case SDLPen.SDL_PEN_AXIS_ROTATION -> ROTATION; + case SDLPen.SDL_PEN_AXIS_SLIDER -> SLIDER; + case SDLPen.SDL_PEN_AXIS_TANGENTIAL_PRESSURE -> TANGENTIAL_PRESSURE; + default -> null; + }; + } + + private final int value; + + PenAxis(int value) { + this.value = value; + } + + public int value() { + return value; + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/PenListener.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/PenListener.java new file mode 100644 index 000000000..44226c1e9 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/PenListener.java @@ -0,0 +1,18 @@ +package com.cleanroommc.client.sdl.input; + +/** Drawing-tablet events. Called from {@link com.cleanroommc.client.sdl.Window#pump()}. */ +public interface PenListener { + + default void proximity(int pen, boolean in) { } + + default void down(int pen, float x, float y, boolean eraser) { } + + default void up(int pen, float x, float y, boolean eraser) { } + + default void motion(int pen, float x, float y) { } + + default void button(int pen, float x, float y, int button, boolean down) { } + + default void axis(int pen, float x, float y, PenAxis axis, float value) { } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/PenType.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/PenType.java new file mode 100644 index 000000000..d5d890e66 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/PenType.java @@ -0,0 +1,32 @@ +package com.cleanroommc.client.sdl.input; + +import org.lwjgl.sdl.SDLPen; + +/** Direct (display) vs indirect (tablet) pens. */ +public enum PenType { + + INVALID(SDLPen.SDL_PEN_DEVICE_TYPE_INVALID), + UNKNOWN(SDLPen.SDL_PEN_DEVICE_TYPE_UNKNOWN), + DIRECT(SDLPen.SDL_PEN_DEVICE_TYPE_DIRECT), + INDIRECT(SDLPen.SDL_PEN_DEVICE_TYPE_INDIRECT); + + public static PenType of(int value) { + return switch (value) { + case SDLPen.SDL_PEN_DEVICE_TYPE_INVALID -> INVALID; + case SDLPen.SDL_PEN_DEVICE_TYPE_DIRECT -> DIRECT; + case SDLPen.SDL_PEN_DEVICE_TYPE_INDIRECT -> INDIRECT; + default -> UNKNOWN; + }; + } + + private final int value; + + PenType(int value) { + this.value = value; + } + + public int value() { + return value; + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Pens.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Pens.java new file mode 100644 index 000000000..4bd393983 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Pens.java @@ -0,0 +1,95 @@ +package com.cleanroommc.client.sdl.input; + +import org.lwjgl.sdl.SDLEvents; +import org.lwjgl.sdl.SDLPen; +import org.lwjgl.sdl.SDL_Event; +import org.lwjgl.sdl.SDL_PenAxisEvent; +import org.lwjgl.sdl.SDL_PenButtonEvent; +import org.lwjgl.sdl.SDL_PenMotionEvent; +import org.lwjgl.sdl.SDL_PenProximityEvent; +import org.lwjgl.sdl.SDL_PenTouchEvent; + +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * Drawing tablets. No extra SDL subsystem as video already delivers the events. + */ +public final class Pens { + + private final List listeners = new CopyOnWriteArrayList<>(); + + Pens() { } + + public PenType type(int pen) { + return PenType.of(SDLPen.SDL_GetPenDeviceType(pen)); + } + + public Pens listen(PenListener listener) { + if (listener == null) { + throw new IllegalArgumentException("Listener cannot be null"); + } + listeners.add(listener); + return this; + } + + public Pens mute(PenListener listener) { + listeners.remove(listener); + return this; + } + + public void handle(SDL_Event event) { + if (listeners.isEmpty()) { + return; + } + int type = event.type(); + switch (type) { + case SDLEvents.SDL_EVENT_PEN_PROXIMITY_IN, SDLEvents.SDL_EVENT_PEN_PROXIMITY_OUT -> { + SDL_PenProximityEvent proximity = event.pproximity(); + boolean in = type == SDLEvents.SDL_EVENT_PEN_PROXIMITY_IN; + for (PenListener listener : listeners) { + listener.proximity(proximity.which(), in); + } + } + case SDLEvents.SDL_EVENT_PEN_DOWN, SDLEvents.SDL_EVENT_PEN_UP -> { + SDL_PenTouchEvent touch = event.ptouch(); + boolean down = type == SDLEvents.SDL_EVENT_PEN_DOWN; + for (PenListener listener : listeners) { + if (down) { + listener.down(touch.which(), touch.x(), touch.y(), touch.eraser()); + } else { + listener.up(touch.which(), touch.x(), touch.y(), touch.eraser()); + } + } + } + case SDLEvents.SDL_EVENT_PEN_MOTION -> { + SDL_PenMotionEvent motion = event.pmotion(); + for (PenListener listener : listeners) { + listener.motion(motion.which(), motion.x(), motion.y()); + } + } + case SDLEvents.SDL_EVENT_PEN_BUTTON_DOWN, SDLEvents.SDL_EVENT_PEN_BUTTON_UP -> { + SDL_PenButtonEvent button = event.pbutton(); + for (PenListener listener : listeners) { + listener.button(button.which(), button.x(), button.y(), button.button() & 0xFF, button.down()); + } + } + case SDLEvents.SDL_EVENT_PEN_AXIS -> { + SDL_PenAxisEvent axis = event.paxis(); + PenAxis kind = PenAxis.of(axis.axis()); + if (kind == null) { + return; + } + for (PenListener listener : listeners) { + listener.axis(axis.which(), axis.x(), axis.y(), kind, axis.value()); + } + } + default -> { } + } + } + + void reset() { + listeners.clear(); + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Scancode.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Scancode.java new file mode 100644 index 000000000..942ef08d1 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Scancode.java @@ -0,0 +1,525 @@ +package com.cleanroommc.client.sdl.input; + +import org.lwjgl.sdl.SDLScancode; + +/** + * SDL scancodes, so callers do not import org.lwjgl.sdl. + */ +public enum Scancode { + + UNKNOWN(SDLScancode.SDL_SCANCODE_UNKNOWN), + A(SDLScancode.SDL_SCANCODE_A), + B(SDLScancode.SDL_SCANCODE_B), + C(SDLScancode.SDL_SCANCODE_C), + D(SDLScancode.SDL_SCANCODE_D), + E(SDLScancode.SDL_SCANCODE_E), + F(SDLScancode.SDL_SCANCODE_F), + G(SDLScancode.SDL_SCANCODE_G), + H(SDLScancode.SDL_SCANCODE_H), + I(SDLScancode.SDL_SCANCODE_I), + J(SDLScancode.SDL_SCANCODE_J), + K(SDLScancode.SDL_SCANCODE_K), + L(SDLScancode.SDL_SCANCODE_L), + M(SDLScancode.SDL_SCANCODE_M), + N(SDLScancode.SDL_SCANCODE_N), + O(SDLScancode.SDL_SCANCODE_O), + P(SDLScancode.SDL_SCANCODE_P), + Q(SDLScancode.SDL_SCANCODE_Q), + R(SDLScancode.SDL_SCANCODE_R), + S(SDLScancode.SDL_SCANCODE_S), + T(SDLScancode.SDL_SCANCODE_T), + U(SDLScancode.SDL_SCANCODE_U), + V(SDLScancode.SDL_SCANCODE_V), + W(SDLScancode.SDL_SCANCODE_W), + X(SDLScancode.SDL_SCANCODE_X), + Y(SDLScancode.SDL_SCANCODE_Y), + Z(SDLScancode.SDL_SCANCODE_Z), + DIGIT_1(SDLScancode.SDL_SCANCODE_1), + DIGIT_2(SDLScancode.SDL_SCANCODE_2), + DIGIT_3(SDLScancode.SDL_SCANCODE_3), + DIGIT_4(SDLScancode.SDL_SCANCODE_4), + DIGIT_5(SDLScancode.SDL_SCANCODE_5), + DIGIT_6(SDLScancode.SDL_SCANCODE_6), + DIGIT_7(SDLScancode.SDL_SCANCODE_7), + DIGIT_8(SDLScancode.SDL_SCANCODE_8), + DIGIT_9(SDLScancode.SDL_SCANCODE_9), + DIGIT_0(SDLScancode.SDL_SCANCODE_0), + RETURN(SDLScancode.SDL_SCANCODE_RETURN), + ESCAPE(SDLScancode.SDL_SCANCODE_ESCAPE), + BACKSPACE(SDLScancode.SDL_SCANCODE_BACKSPACE), + TAB(SDLScancode.SDL_SCANCODE_TAB), + SPACE(SDLScancode.SDL_SCANCODE_SPACE), + MINUS(SDLScancode.SDL_SCANCODE_MINUS), + EQUALS(SDLScancode.SDL_SCANCODE_EQUALS), + LEFTBRACKET(SDLScancode.SDL_SCANCODE_LEFTBRACKET), + RIGHTBRACKET(SDLScancode.SDL_SCANCODE_RIGHTBRACKET), + BACKSLASH(SDLScancode.SDL_SCANCODE_BACKSLASH), + NONUSHASH(SDLScancode.SDL_SCANCODE_NONUSHASH), + SEMICOLON(SDLScancode.SDL_SCANCODE_SEMICOLON), + APOSTROPHE(SDLScancode.SDL_SCANCODE_APOSTROPHE), + GRAVE(SDLScancode.SDL_SCANCODE_GRAVE), + COMMA(SDLScancode.SDL_SCANCODE_COMMA), + PERIOD(SDLScancode.SDL_SCANCODE_PERIOD), + SLASH(SDLScancode.SDL_SCANCODE_SLASH), + CAPSLOCK(SDLScancode.SDL_SCANCODE_CAPSLOCK), + F1(SDLScancode.SDL_SCANCODE_F1), + F2(SDLScancode.SDL_SCANCODE_F2), + F3(SDLScancode.SDL_SCANCODE_F3), + F4(SDLScancode.SDL_SCANCODE_F4), + F5(SDLScancode.SDL_SCANCODE_F5), + F6(SDLScancode.SDL_SCANCODE_F6), + F7(SDLScancode.SDL_SCANCODE_F7), + F8(SDLScancode.SDL_SCANCODE_F8), + F9(SDLScancode.SDL_SCANCODE_F9), + F10(SDLScancode.SDL_SCANCODE_F10), + F11(SDLScancode.SDL_SCANCODE_F11), + F12(SDLScancode.SDL_SCANCODE_F12), + PRINTSCREEN(SDLScancode.SDL_SCANCODE_PRINTSCREEN), + SCROLLLOCK(SDLScancode.SDL_SCANCODE_SCROLLLOCK), + PAUSE(SDLScancode.SDL_SCANCODE_PAUSE), + INSERT(SDLScancode.SDL_SCANCODE_INSERT), + HOME(SDLScancode.SDL_SCANCODE_HOME), + PAGEUP(SDLScancode.SDL_SCANCODE_PAGEUP), + DELETE(SDLScancode.SDL_SCANCODE_DELETE), + END(SDLScancode.SDL_SCANCODE_END), + PAGEDOWN(SDLScancode.SDL_SCANCODE_PAGEDOWN), + RIGHT(SDLScancode.SDL_SCANCODE_RIGHT), + LEFT(SDLScancode.SDL_SCANCODE_LEFT), + DOWN(SDLScancode.SDL_SCANCODE_DOWN), + UP(SDLScancode.SDL_SCANCODE_UP), + NUMLOCKCLEAR(SDLScancode.SDL_SCANCODE_NUMLOCKCLEAR), + KP_DIVIDE(SDLScancode.SDL_SCANCODE_KP_DIVIDE), + KP_MULTIPLY(SDLScancode.SDL_SCANCODE_KP_MULTIPLY), + KP_MINUS(SDLScancode.SDL_SCANCODE_KP_MINUS), + KP_PLUS(SDLScancode.SDL_SCANCODE_KP_PLUS), + KP_ENTER(SDLScancode.SDL_SCANCODE_KP_ENTER), + KP_1(SDLScancode.SDL_SCANCODE_KP_1), + KP_2(SDLScancode.SDL_SCANCODE_KP_2), + KP_3(SDLScancode.SDL_SCANCODE_KP_3), + KP_4(SDLScancode.SDL_SCANCODE_KP_4), + KP_5(SDLScancode.SDL_SCANCODE_KP_5), + KP_6(SDLScancode.SDL_SCANCODE_KP_6), + KP_7(SDLScancode.SDL_SCANCODE_KP_7), + KP_8(SDLScancode.SDL_SCANCODE_KP_8), + KP_9(SDLScancode.SDL_SCANCODE_KP_9), + KP_0(SDLScancode.SDL_SCANCODE_KP_0), + KP_PERIOD(SDLScancode.SDL_SCANCODE_KP_PERIOD), + NONUSBACKSLASH(SDLScancode.SDL_SCANCODE_NONUSBACKSLASH), + APPLICATION(SDLScancode.SDL_SCANCODE_APPLICATION), + POWER(SDLScancode.SDL_SCANCODE_POWER), + KP_EQUALS(SDLScancode.SDL_SCANCODE_KP_EQUALS), + F13(SDLScancode.SDL_SCANCODE_F13), + F14(SDLScancode.SDL_SCANCODE_F14), + F15(SDLScancode.SDL_SCANCODE_F15), + F16(SDLScancode.SDL_SCANCODE_F16), + F17(SDLScancode.SDL_SCANCODE_F17), + F18(SDLScancode.SDL_SCANCODE_F18), + F19(SDLScancode.SDL_SCANCODE_F19), + F20(SDLScancode.SDL_SCANCODE_F20), + F21(SDLScancode.SDL_SCANCODE_F21), + F22(SDLScancode.SDL_SCANCODE_F22), + F23(SDLScancode.SDL_SCANCODE_F23), + F24(SDLScancode.SDL_SCANCODE_F24), + EXECUTE(SDLScancode.SDL_SCANCODE_EXECUTE), + HELP(SDLScancode.SDL_SCANCODE_HELP), + MENU(SDLScancode.SDL_SCANCODE_MENU), + SELECT(SDLScancode.SDL_SCANCODE_SELECT), + STOP(SDLScancode.SDL_SCANCODE_STOP), + AGAIN(SDLScancode.SDL_SCANCODE_AGAIN), + UNDO(SDLScancode.SDL_SCANCODE_UNDO), + CUT(SDLScancode.SDL_SCANCODE_CUT), + COPY(SDLScancode.SDL_SCANCODE_COPY), + PASTE(SDLScancode.SDL_SCANCODE_PASTE), + FIND(SDLScancode.SDL_SCANCODE_FIND), + MUTE(SDLScancode.SDL_SCANCODE_MUTE), + VOLUMEUP(SDLScancode.SDL_SCANCODE_VOLUMEUP), + VOLUMEDOWN(SDLScancode.SDL_SCANCODE_VOLUMEDOWN), + KP_COMMA(SDLScancode.SDL_SCANCODE_KP_COMMA), + KP_EQUALSAS400(SDLScancode.SDL_SCANCODE_KP_EQUALSAS400), + INTERNATIONAL1(SDLScancode.SDL_SCANCODE_INTERNATIONAL1), + INTERNATIONAL2(SDLScancode.SDL_SCANCODE_INTERNATIONAL2), + INTERNATIONAL3(SDLScancode.SDL_SCANCODE_INTERNATIONAL3), + INTERNATIONAL4(SDLScancode.SDL_SCANCODE_INTERNATIONAL4), + INTERNATIONAL5(SDLScancode.SDL_SCANCODE_INTERNATIONAL5), + INTERNATIONAL6(SDLScancode.SDL_SCANCODE_INTERNATIONAL6), + INTERNATIONAL7(SDLScancode.SDL_SCANCODE_INTERNATIONAL7), + INTERNATIONAL8(SDLScancode.SDL_SCANCODE_INTERNATIONAL8), + INTERNATIONAL9(SDLScancode.SDL_SCANCODE_INTERNATIONAL9), + LANG1(SDLScancode.SDL_SCANCODE_LANG1), + LANG2(SDLScancode.SDL_SCANCODE_LANG2), + LANG3(SDLScancode.SDL_SCANCODE_LANG3), + LANG4(SDLScancode.SDL_SCANCODE_LANG4), + LANG5(SDLScancode.SDL_SCANCODE_LANG5), + LANG6(SDLScancode.SDL_SCANCODE_LANG6), + LANG7(SDLScancode.SDL_SCANCODE_LANG7), + LANG8(SDLScancode.SDL_SCANCODE_LANG8), + LANG9(SDLScancode.SDL_SCANCODE_LANG9), + ALTERASE(SDLScancode.SDL_SCANCODE_ALTERASE), + SYSREQ(SDLScancode.SDL_SCANCODE_SYSREQ), + CANCEL(SDLScancode.SDL_SCANCODE_CANCEL), + CLEAR(SDLScancode.SDL_SCANCODE_CLEAR), + PRIOR(SDLScancode.SDL_SCANCODE_PRIOR), + RETURN2(SDLScancode.SDL_SCANCODE_RETURN2), + SEPARATOR(SDLScancode.SDL_SCANCODE_SEPARATOR), + OUT(SDLScancode.SDL_SCANCODE_OUT), + OPER(SDLScancode.SDL_SCANCODE_OPER), + CLEARAGAIN(SDLScancode.SDL_SCANCODE_CLEARAGAIN), + CRSEL(SDLScancode.SDL_SCANCODE_CRSEL), + EXSEL(SDLScancode.SDL_SCANCODE_EXSEL), + KP_00(SDLScancode.SDL_SCANCODE_KP_00), + KP_000(SDLScancode.SDL_SCANCODE_KP_000), + THOUSANDSSEPARATOR(SDLScancode.SDL_SCANCODE_THOUSANDSSEPARATOR), + DECIMALSEPARATOR(SDLScancode.SDL_SCANCODE_DECIMALSEPARATOR), + CURRENCYUNIT(SDLScancode.SDL_SCANCODE_CURRENCYUNIT), + CURRENCYSUBUNIT(SDLScancode.SDL_SCANCODE_CURRENCYSUBUNIT), + KP_LEFTPAREN(SDLScancode.SDL_SCANCODE_KP_LEFTPAREN), + KP_RIGHTPAREN(SDLScancode.SDL_SCANCODE_KP_RIGHTPAREN), + KP_LEFTBRACE(SDLScancode.SDL_SCANCODE_KP_LEFTBRACE), + KP_RIGHTBRACE(SDLScancode.SDL_SCANCODE_KP_RIGHTBRACE), + KP_TAB(SDLScancode.SDL_SCANCODE_KP_TAB), + KP_BACKSPACE(SDLScancode.SDL_SCANCODE_KP_BACKSPACE), + KP_A(SDLScancode.SDL_SCANCODE_KP_A), + KP_B(SDLScancode.SDL_SCANCODE_KP_B), + KP_C(SDLScancode.SDL_SCANCODE_KP_C), + KP_D(SDLScancode.SDL_SCANCODE_KP_D), + KP_E(SDLScancode.SDL_SCANCODE_KP_E), + KP_F(SDLScancode.SDL_SCANCODE_KP_F), + KP_XOR(SDLScancode.SDL_SCANCODE_KP_XOR), + KP_POWER(SDLScancode.SDL_SCANCODE_KP_POWER), + KP_PERCENT(SDLScancode.SDL_SCANCODE_KP_PERCENT), + KP_LESS(SDLScancode.SDL_SCANCODE_KP_LESS), + KP_GREATER(SDLScancode.SDL_SCANCODE_KP_GREATER), + KP_AMPERSAND(SDLScancode.SDL_SCANCODE_KP_AMPERSAND), + KP_DBLAMPERSAND(SDLScancode.SDL_SCANCODE_KP_DBLAMPERSAND), + KP_VERTICALBAR(SDLScancode.SDL_SCANCODE_KP_VERTICALBAR), + KP_DBLVERTICALBAR(SDLScancode.SDL_SCANCODE_KP_DBLVERTICALBAR), + KP_COLON(SDLScancode.SDL_SCANCODE_KP_COLON), + KP_HASH(SDLScancode.SDL_SCANCODE_KP_HASH), + KP_SPACE(SDLScancode.SDL_SCANCODE_KP_SPACE), + KP_AT(SDLScancode.SDL_SCANCODE_KP_AT), + KP_EXCLAM(SDLScancode.SDL_SCANCODE_KP_EXCLAM), + KP_MEMSTORE(SDLScancode.SDL_SCANCODE_KP_MEMSTORE), + KP_MEMRECALL(SDLScancode.SDL_SCANCODE_KP_MEMRECALL), + KP_MEMCLEAR(SDLScancode.SDL_SCANCODE_KP_MEMCLEAR), + KP_MEMADD(SDLScancode.SDL_SCANCODE_KP_MEMADD), + KP_MEMSUBTRACT(SDLScancode.SDL_SCANCODE_KP_MEMSUBTRACT), + KP_MEMMULTIPLY(SDLScancode.SDL_SCANCODE_KP_MEMMULTIPLY), + KP_MEMDIVIDE(SDLScancode.SDL_SCANCODE_KP_MEMDIVIDE), + KP_PLUSMINUS(SDLScancode.SDL_SCANCODE_KP_PLUSMINUS), + KP_CLEAR(SDLScancode.SDL_SCANCODE_KP_CLEAR), + KP_CLEARENTRY(SDLScancode.SDL_SCANCODE_KP_CLEARENTRY), + KP_BINARY(SDLScancode.SDL_SCANCODE_KP_BINARY), + KP_OCTAL(SDLScancode.SDL_SCANCODE_KP_OCTAL), + KP_DECIMAL(SDLScancode.SDL_SCANCODE_KP_DECIMAL), + KP_HEXADECIMAL(SDLScancode.SDL_SCANCODE_KP_HEXADECIMAL), + LCTRL(SDLScancode.SDL_SCANCODE_LCTRL), + LSHIFT(SDLScancode.SDL_SCANCODE_LSHIFT), + LALT(SDLScancode.SDL_SCANCODE_LALT), + LGUI(SDLScancode.SDL_SCANCODE_LGUI), + RCTRL(SDLScancode.SDL_SCANCODE_RCTRL), + RSHIFT(SDLScancode.SDL_SCANCODE_RSHIFT), + RALT(SDLScancode.SDL_SCANCODE_RALT), + RGUI(SDLScancode.SDL_SCANCODE_RGUI), + MODE(SDLScancode.SDL_SCANCODE_MODE), + SLEEP(SDLScancode.SDL_SCANCODE_SLEEP), + WAKE(SDLScancode.SDL_SCANCODE_WAKE), + CHANNEL_INCREMENT(SDLScancode.SDL_SCANCODE_CHANNEL_INCREMENT), + CHANNEL_DECREMENT(SDLScancode.SDL_SCANCODE_CHANNEL_DECREMENT), + MEDIA_PLAY(SDLScancode.SDL_SCANCODE_MEDIA_PLAY), + MEDIA_PAUSE(SDLScancode.SDL_SCANCODE_MEDIA_PAUSE), + MEDIA_RECORD(SDLScancode.SDL_SCANCODE_MEDIA_RECORD), + MEDIA_FAST_FORWARD(SDLScancode.SDL_SCANCODE_MEDIA_FAST_FORWARD), + MEDIA_REWIND(SDLScancode.SDL_SCANCODE_MEDIA_REWIND), + MEDIA_NEXT_TRACK(SDLScancode.SDL_SCANCODE_MEDIA_NEXT_TRACK), + MEDIA_PREVIOUS_TRACK(SDLScancode.SDL_SCANCODE_MEDIA_PREVIOUS_TRACK), + MEDIA_STOP(SDLScancode.SDL_SCANCODE_MEDIA_STOP), + MEDIA_EJECT(SDLScancode.SDL_SCANCODE_MEDIA_EJECT), + MEDIA_PLAY_PAUSE(SDLScancode.SDL_SCANCODE_MEDIA_PLAY_PAUSE), + MEDIA_SELECT(SDLScancode.SDL_SCANCODE_MEDIA_SELECT), + AC_NEW(SDLScancode.SDL_SCANCODE_AC_NEW), + AC_OPEN(SDLScancode.SDL_SCANCODE_AC_OPEN), + AC_CLOSE(SDLScancode.SDL_SCANCODE_AC_CLOSE), + AC_EXIT(SDLScancode.SDL_SCANCODE_AC_EXIT), + AC_SAVE(SDLScancode.SDL_SCANCODE_AC_SAVE), + AC_PRINT(SDLScancode.SDL_SCANCODE_AC_PRINT), + AC_PROPERTIES(SDLScancode.SDL_SCANCODE_AC_PROPERTIES), + AC_SEARCH(SDLScancode.SDL_SCANCODE_AC_SEARCH), + AC_HOME(SDLScancode.SDL_SCANCODE_AC_HOME), + AC_BACK(SDLScancode.SDL_SCANCODE_AC_BACK), + AC_FORWARD(SDLScancode.SDL_SCANCODE_AC_FORWARD), + AC_STOP(SDLScancode.SDL_SCANCODE_AC_STOP), + AC_REFRESH(SDLScancode.SDL_SCANCODE_AC_REFRESH), + AC_BOOKMARKS(SDLScancode.SDL_SCANCODE_AC_BOOKMARKS), + SOFTLEFT(SDLScancode.SDL_SCANCODE_SOFTLEFT), + SOFTRIGHT(SDLScancode.SDL_SCANCODE_SOFTRIGHT), + CALL(SDLScancode.SDL_SCANCODE_CALL), + ENDCALL(SDLScancode.SDL_SCANCODE_ENDCALL), + RESERVED(SDLScancode.SDL_SCANCODE_RESERVED); + + /** @return the named scancode, or null when SDL has no name for value */ + public static Scancode of(int value) { + return switch (value) { + case SDLScancode.SDL_SCANCODE_UNKNOWN -> UNKNOWN; + case SDLScancode.SDL_SCANCODE_A -> A; + case SDLScancode.SDL_SCANCODE_B -> B; + case SDLScancode.SDL_SCANCODE_C -> C; + case SDLScancode.SDL_SCANCODE_D -> D; + case SDLScancode.SDL_SCANCODE_E -> E; + case SDLScancode.SDL_SCANCODE_F -> F; + case SDLScancode.SDL_SCANCODE_G -> G; + case SDLScancode.SDL_SCANCODE_H -> H; + case SDLScancode.SDL_SCANCODE_I -> I; + case SDLScancode.SDL_SCANCODE_J -> J; + case SDLScancode.SDL_SCANCODE_K -> K; + case SDLScancode.SDL_SCANCODE_L -> L; + case SDLScancode.SDL_SCANCODE_M -> M; + case SDLScancode.SDL_SCANCODE_N -> N; + case SDLScancode.SDL_SCANCODE_O -> O; + case SDLScancode.SDL_SCANCODE_P -> P; + case SDLScancode.SDL_SCANCODE_Q -> Q; + case SDLScancode.SDL_SCANCODE_R -> R; + case SDLScancode.SDL_SCANCODE_S -> S; + case SDLScancode.SDL_SCANCODE_T -> T; + case SDLScancode.SDL_SCANCODE_U -> U; + case SDLScancode.SDL_SCANCODE_V -> V; + case SDLScancode.SDL_SCANCODE_W -> W; + case SDLScancode.SDL_SCANCODE_X -> X; + case SDLScancode.SDL_SCANCODE_Y -> Y; + case SDLScancode.SDL_SCANCODE_Z -> Z; + case SDLScancode.SDL_SCANCODE_1 -> DIGIT_1; + case SDLScancode.SDL_SCANCODE_2 -> DIGIT_2; + case SDLScancode.SDL_SCANCODE_3 -> DIGIT_3; + case SDLScancode.SDL_SCANCODE_4 -> DIGIT_4; + case SDLScancode.SDL_SCANCODE_5 -> DIGIT_5; + case SDLScancode.SDL_SCANCODE_6 -> DIGIT_6; + case SDLScancode.SDL_SCANCODE_7 -> DIGIT_7; + case SDLScancode.SDL_SCANCODE_8 -> DIGIT_8; + case SDLScancode.SDL_SCANCODE_9 -> DIGIT_9; + case SDLScancode.SDL_SCANCODE_0 -> DIGIT_0; + case SDLScancode.SDL_SCANCODE_RETURN -> RETURN; + case SDLScancode.SDL_SCANCODE_ESCAPE -> ESCAPE; + case SDLScancode.SDL_SCANCODE_BACKSPACE -> BACKSPACE; + case SDLScancode.SDL_SCANCODE_TAB -> TAB; + case SDLScancode.SDL_SCANCODE_SPACE -> SPACE; + case SDLScancode.SDL_SCANCODE_MINUS -> MINUS; + case SDLScancode.SDL_SCANCODE_EQUALS -> EQUALS; + case SDLScancode.SDL_SCANCODE_LEFTBRACKET -> LEFTBRACKET; + case SDLScancode.SDL_SCANCODE_RIGHTBRACKET -> RIGHTBRACKET; + case SDLScancode.SDL_SCANCODE_BACKSLASH -> BACKSLASH; + case SDLScancode.SDL_SCANCODE_NONUSHASH -> NONUSHASH; + case SDLScancode.SDL_SCANCODE_SEMICOLON -> SEMICOLON; + case SDLScancode.SDL_SCANCODE_APOSTROPHE -> APOSTROPHE; + case SDLScancode.SDL_SCANCODE_GRAVE -> GRAVE; + case SDLScancode.SDL_SCANCODE_COMMA -> COMMA; + case SDLScancode.SDL_SCANCODE_PERIOD -> PERIOD; + case SDLScancode.SDL_SCANCODE_SLASH -> SLASH; + case SDLScancode.SDL_SCANCODE_CAPSLOCK -> CAPSLOCK; + case SDLScancode.SDL_SCANCODE_F1 -> F1; + case SDLScancode.SDL_SCANCODE_F2 -> F2; + case SDLScancode.SDL_SCANCODE_F3 -> F3; + case SDLScancode.SDL_SCANCODE_F4 -> F4; + case SDLScancode.SDL_SCANCODE_F5 -> F5; + case SDLScancode.SDL_SCANCODE_F6 -> F6; + case SDLScancode.SDL_SCANCODE_F7 -> F7; + case SDLScancode.SDL_SCANCODE_F8 -> F8; + case SDLScancode.SDL_SCANCODE_F9 -> F9; + case SDLScancode.SDL_SCANCODE_F10 -> F10; + case SDLScancode.SDL_SCANCODE_F11 -> F11; + case SDLScancode.SDL_SCANCODE_F12 -> F12; + case SDLScancode.SDL_SCANCODE_PRINTSCREEN -> PRINTSCREEN; + case SDLScancode.SDL_SCANCODE_SCROLLLOCK -> SCROLLLOCK; + case SDLScancode.SDL_SCANCODE_PAUSE -> PAUSE; + case SDLScancode.SDL_SCANCODE_INSERT -> INSERT; + case SDLScancode.SDL_SCANCODE_HOME -> HOME; + case SDLScancode.SDL_SCANCODE_PAGEUP -> PAGEUP; + case SDLScancode.SDL_SCANCODE_DELETE -> DELETE; + case SDLScancode.SDL_SCANCODE_END -> END; + case SDLScancode.SDL_SCANCODE_PAGEDOWN -> PAGEDOWN; + case SDLScancode.SDL_SCANCODE_RIGHT -> RIGHT; + case SDLScancode.SDL_SCANCODE_LEFT -> LEFT; + case SDLScancode.SDL_SCANCODE_DOWN -> DOWN; + case SDLScancode.SDL_SCANCODE_UP -> UP; + case SDLScancode.SDL_SCANCODE_NUMLOCKCLEAR -> NUMLOCKCLEAR; + case SDLScancode.SDL_SCANCODE_KP_DIVIDE -> KP_DIVIDE; + case SDLScancode.SDL_SCANCODE_KP_MULTIPLY -> KP_MULTIPLY; + case SDLScancode.SDL_SCANCODE_KP_MINUS -> KP_MINUS; + case SDLScancode.SDL_SCANCODE_KP_PLUS -> KP_PLUS; + case SDLScancode.SDL_SCANCODE_KP_ENTER -> KP_ENTER; + case SDLScancode.SDL_SCANCODE_KP_1 -> KP_1; + case SDLScancode.SDL_SCANCODE_KP_2 -> KP_2; + case SDLScancode.SDL_SCANCODE_KP_3 -> KP_3; + case SDLScancode.SDL_SCANCODE_KP_4 -> KP_4; + case SDLScancode.SDL_SCANCODE_KP_5 -> KP_5; + case SDLScancode.SDL_SCANCODE_KP_6 -> KP_6; + case SDLScancode.SDL_SCANCODE_KP_7 -> KP_7; + case SDLScancode.SDL_SCANCODE_KP_8 -> KP_8; + case SDLScancode.SDL_SCANCODE_KP_9 -> KP_9; + case SDLScancode.SDL_SCANCODE_KP_0 -> KP_0; + case SDLScancode.SDL_SCANCODE_KP_PERIOD -> KP_PERIOD; + case SDLScancode.SDL_SCANCODE_NONUSBACKSLASH -> NONUSBACKSLASH; + case SDLScancode.SDL_SCANCODE_APPLICATION -> APPLICATION; + case SDLScancode.SDL_SCANCODE_POWER -> POWER; + case SDLScancode.SDL_SCANCODE_KP_EQUALS -> KP_EQUALS; + case SDLScancode.SDL_SCANCODE_F13 -> F13; + case SDLScancode.SDL_SCANCODE_F14 -> F14; + case SDLScancode.SDL_SCANCODE_F15 -> F15; + case SDLScancode.SDL_SCANCODE_F16 -> F16; + case SDLScancode.SDL_SCANCODE_F17 -> F17; + case SDLScancode.SDL_SCANCODE_F18 -> F18; + case SDLScancode.SDL_SCANCODE_F19 -> F19; + case SDLScancode.SDL_SCANCODE_F20 -> F20; + case SDLScancode.SDL_SCANCODE_F21 -> F21; + case SDLScancode.SDL_SCANCODE_F22 -> F22; + case SDLScancode.SDL_SCANCODE_F23 -> F23; + case SDLScancode.SDL_SCANCODE_F24 -> F24; + case SDLScancode.SDL_SCANCODE_EXECUTE -> EXECUTE; + case SDLScancode.SDL_SCANCODE_HELP -> HELP; + case SDLScancode.SDL_SCANCODE_MENU -> MENU; + case SDLScancode.SDL_SCANCODE_SELECT -> SELECT; + case SDLScancode.SDL_SCANCODE_STOP -> STOP; + case SDLScancode.SDL_SCANCODE_AGAIN -> AGAIN; + case SDLScancode.SDL_SCANCODE_UNDO -> UNDO; + case SDLScancode.SDL_SCANCODE_CUT -> CUT; + case SDLScancode.SDL_SCANCODE_COPY -> COPY; + case SDLScancode.SDL_SCANCODE_PASTE -> PASTE; + case SDLScancode.SDL_SCANCODE_FIND -> FIND; + case SDLScancode.SDL_SCANCODE_MUTE -> MUTE; + case SDLScancode.SDL_SCANCODE_VOLUMEUP -> VOLUMEUP; + case SDLScancode.SDL_SCANCODE_VOLUMEDOWN -> VOLUMEDOWN; + case SDLScancode.SDL_SCANCODE_KP_COMMA -> KP_COMMA; + case SDLScancode.SDL_SCANCODE_KP_EQUALSAS400 -> KP_EQUALSAS400; + case SDLScancode.SDL_SCANCODE_INTERNATIONAL1 -> INTERNATIONAL1; + case SDLScancode.SDL_SCANCODE_INTERNATIONAL2 -> INTERNATIONAL2; + case SDLScancode.SDL_SCANCODE_INTERNATIONAL3 -> INTERNATIONAL3; + case SDLScancode.SDL_SCANCODE_INTERNATIONAL4 -> INTERNATIONAL4; + case SDLScancode.SDL_SCANCODE_INTERNATIONAL5 -> INTERNATIONAL5; + case SDLScancode.SDL_SCANCODE_INTERNATIONAL6 -> INTERNATIONAL6; + case SDLScancode.SDL_SCANCODE_INTERNATIONAL7 -> INTERNATIONAL7; + case SDLScancode.SDL_SCANCODE_INTERNATIONAL8 -> INTERNATIONAL8; + case SDLScancode.SDL_SCANCODE_INTERNATIONAL9 -> INTERNATIONAL9; + case SDLScancode.SDL_SCANCODE_LANG1 -> LANG1; + case SDLScancode.SDL_SCANCODE_LANG2 -> LANG2; + case SDLScancode.SDL_SCANCODE_LANG3 -> LANG3; + case SDLScancode.SDL_SCANCODE_LANG4 -> LANG4; + case SDLScancode.SDL_SCANCODE_LANG5 -> LANG5; + case SDLScancode.SDL_SCANCODE_LANG6 -> LANG6; + case SDLScancode.SDL_SCANCODE_LANG7 -> LANG7; + case SDLScancode.SDL_SCANCODE_LANG8 -> LANG8; + case SDLScancode.SDL_SCANCODE_LANG9 -> LANG9; + case SDLScancode.SDL_SCANCODE_ALTERASE -> ALTERASE; + case SDLScancode.SDL_SCANCODE_SYSREQ -> SYSREQ; + case SDLScancode.SDL_SCANCODE_CANCEL -> CANCEL; + case SDLScancode.SDL_SCANCODE_CLEAR -> CLEAR; + case SDLScancode.SDL_SCANCODE_PRIOR -> PRIOR; + case SDLScancode.SDL_SCANCODE_RETURN2 -> RETURN2; + case SDLScancode.SDL_SCANCODE_SEPARATOR -> SEPARATOR; + case SDLScancode.SDL_SCANCODE_OUT -> OUT; + case SDLScancode.SDL_SCANCODE_OPER -> OPER; + case SDLScancode.SDL_SCANCODE_CLEARAGAIN -> CLEARAGAIN; + case SDLScancode.SDL_SCANCODE_CRSEL -> CRSEL; + case SDLScancode.SDL_SCANCODE_EXSEL -> EXSEL; + case SDLScancode.SDL_SCANCODE_KP_00 -> KP_00; + case SDLScancode.SDL_SCANCODE_KP_000 -> KP_000; + case SDLScancode.SDL_SCANCODE_THOUSANDSSEPARATOR -> THOUSANDSSEPARATOR; + case SDLScancode.SDL_SCANCODE_DECIMALSEPARATOR -> DECIMALSEPARATOR; + case SDLScancode.SDL_SCANCODE_CURRENCYUNIT -> CURRENCYUNIT; + case SDLScancode.SDL_SCANCODE_CURRENCYSUBUNIT -> CURRENCYSUBUNIT; + case SDLScancode.SDL_SCANCODE_KP_LEFTPAREN -> KP_LEFTPAREN; + case SDLScancode.SDL_SCANCODE_KP_RIGHTPAREN -> KP_RIGHTPAREN; + case SDLScancode.SDL_SCANCODE_KP_LEFTBRACE -> KP_LEFTBRACE; + case SDLScancode.SDL_SCANCODE_KP_RIGHTBRACE -> KP_RIGHTBRACE; + case SDLScancode.SDL_SCANCODE_KP_TAB -> KP_TAB; + case SDLScancode.SDL_SCANCODE_KP_BACKSPACE -> KP_BACKSPACE; + case SDLScancode.SDL_SCANCODE_KP_A -> KP_A; + case SDLScancode.SDL_SCANCODE_KP_B -> KP_B; + case SDLScancode.SDL_SCANCODE_KP_C -> KP_C; + case SDLScancode.SDL_SCANCODE_KP_D -> KP_D; + case SDLScancode.SDL_SCANCODE_KP_E -> KP_E; + case SDLScancode.SDL_SCANCODE_KP_F -> KP_F; + case SDLScancode.SDL_SCANCODE_KP_XOR -> KP_XOR; + case SDLScancode.SDL_SCANCODE_KP_POWER -> KP_POWER; + case SDLScancode.SDL_SCANCODE_KP_PERCENT -> KP_PERCENT; + case SDLScancode.SDL_SCANCODE_KP_LESS -> KP_LESS; + case SDLScancode.SDL_SCANCODE_KP_GREATER -> KP_GREATER; + case SDLScancode.SDL_SCANCODE_KP_AMPERSAND -> KP_AMPERSAND; + case SDLScancode.SDL_SCANCODE_KP_DBLAMPERSAND -> KP_DBLAMPERSAND; + case SDLScancode.SDL_SCANCODE_KP_VERTICALBAR -> KP_VERTICALBAR; + case SDLScancode.SDL_SCANCODE_KP_DBLVERTICALBAR -> KP_DBLVERTICALBAR; + case SDLScancode.SDL_SCANCODE_KP_COLON -> KP_COLON; + case SDLScancode.SDL_SCANCODE_KP_HASH -> KP_HASH; + case SDLScancode.SDL_SCANCODE_KP_SPACE -> KP_SPACE; + case SDLScancode.SDL_SCANCODE_KP_AT -> KP_AT; + case SDLScancode.SDL_SCANCODE_KP_EXCLAM -> KP_EXCLAM; + case SDLScancode.SDL_SCANCODE_KP_MEMSTORE -> KP_MEMSTORE; + case SDLScancode.SDL_SCANCODE_KP_MEMRECALL -> KP_MEMRECALL; + case SDLScancode.SDL_SCANCODE_KP_MEMCLEAR -> KP_MEMCLEAR; + case SDLScancode.SDL_SCANCODE_KP_MEMADD -> KP_MEMADD; + case SDLScancode.SDL_SCANCODE_KP_MEMSUBTRACT -> KP_MEMSUBTRACT; + case SDLScancode.SDL_SCANCODE_KP_MEMMULTIPLY -> KP_MEMMULTIPLY; + case SDLScancode.SDL_SCANCODE_KP_MEMDIVIDE -> KP_MEMDIVIDE; + case SDLScancode.SDL_SCANCODE_KP_PLUSMINUS -> KP_PLUSMINUS; + case SDLScancode.SDL_SCANCODE_KP_CLEAR -> KP_CLEAR; + case SDLScancode.SDL_SCANCODE_KP_CLEARENTRY -> KP_CLEARENTRY; + case SDLScancode.SDL_SCANCODE_KP_BINARY -> KP_BINARY; + case SDLScancode.SDL_SCANCODE_KP_OCTAL -> KP_OCTAL; + case SDLScancode.SDL_SCANCODE_KP_DECIMAL -> KP_DECIMAL; + case SDLScancode.SDL_SCANCODE_KP_HEXADECIMAL -> KP_HEXADECIMAL; + case SDLScancode.SDL_SCANCODE_LCTRL -> LCTRL; + case SDLScancode.SDL_SCANCODE_LSHIFT -> LSHIFT; + case SDLScancode.SDL_SCANCODE_LALT -> LALT; + case SDLScancode.SDL_SCANCODE_LGUI -> LGUI; + case SDLScancode.SDL_SCANCODE_RCTRL -> RCTRL; + case SDLScancode.SDL_SCANCODE_RSHIFT -> RSHIFT; + case SDLScancode.SDL_SCANCODE_RALT -> RALT; + case SDLScancode.SDL_SCANCODE_RGUI -> RGUI; + case SDLScancode.SDL_SCANCODE_MODE -> MODE; + case SDLScancode.SDL_SCANCODE_SLEEP -> SLEEP; + case SDLScancode.SDL_SCANCODE_WAKE -> WAKE; + case SDLScancode.SDL_SCANCODE_CHANNEL_INCREMENT -> CHANNEL_INCREMENT; + case SDLScancode.SDL_SCANCODE_CHANNEL_DECREMENT -> CHANNEL_DECREMENT; + case SDLScancode.SDL_SCANCODE_MEDIA_PLAY -> MEDIA_PLAY; + case SDLScancode.SDL_SCANCODE_MEDIA_PAUSE -> MEDIA_PAUSE; + case SDLScancode.SDL_SCANCODE_MEDIA_RECORD -> MEDIA_RECORD; + case SDLScancode.SDL_SCANCODE_MEDIA_FAST_FORWARD -> MEDIA_FAST_FORWARD; + case SDLScancode.SDL_SCANCODE_MEDIA_REWIND -> MEDIA_REWIND; + case SDLScancode.SDL_SCANCODE_MEDIA_NEXT_TRACK -> MEDIA_NEXT_TRACK; + case SDLScancode.SDL_SCANCODE_MEDIA_PREVIOUS_TRACK -> MEDIA_PREVIOUS_TRACK; + case SDLScancode.SDL_SCANCODE_MEDIA_STOP -> MEDIA_STOP; + case SDLScancode.SDL_SCANCODE_MEDIA_EJECT -> MEDIA_EJECT; + case SDLScancode.SDL_SCANCODE_MEDIA_PLAY_PAUSE -> MEDIA_PLAY_PAUSE; + case SDLScancode.SDL_SCANCODE_MEDIA_SELECT -> MEDIA_SELECT; + case SDLScancode.SDL_SCANCODE_AC_NEW -> AC_NEW; + case SDLScancode.SDL_SCANCODE_AC_OPEN -> AC_OPEN; + case SDLScancode.SDL_SCANCODE_AC_CLOSE -> AC_CLOSE; + case SDLScancode.SDL_SCANCODE_AC_EXIT -> AC_EXIT; + case SDLScancode.SDL_SCANCODE_AC_SAVE -> AC_SAVE; + case SDLScancode.SDL_SCANCODE_AC_PRINT -> AC_PRINT; + case SDLScancode.SDL_SCANCODE_AC_PROPERTIES -> AC_PROPERTIES; + case SDLScancode.SDL_SCANCODE_AC_SEARCH -> AC_SEARCH; + case SDLScancode.SDL_SCANCODE_AC_HOME -> AC_HOME; + case SDLScancode.SDL_SCANCODE_AC_BACK -> AC_BACK; + case SDLScancode.SDL_SCANCODE_AC_FORWARD -> AC_FORWARD; + case SDLScancode.SDL_SCANCODE_AC_STOP -> AC_STOP; + case SDLScancode.SDL_SCANCODE_AC_REFRESH -> AC_REFRESH; + case SDLScancode.SDL_SCANCODE_AC_BOOKMARKS -> AC_BOOKMARKS; + case SDLScancode.SDL_SCANCODE_SOFTLEFT -> SOFTLEFT; + case SDLScancode.SDL_SCANCODE_SOFTRIGHT -> SOFTRIGHT; + case SDLScancode.SDL_SCANCODE_CALL -> CALL; + case SDLScancode.SDL_SCANCODE_ENDCALL -> ENDCALL; + case SDLScancode.SDL_SCANCODE_RESERVED -> RESERVED; + default -> null; + }; + } + + private final int value; + + Scancode(int value) { + this.value = value; + } + + /** @return the SDL_SCANCODE_* value */ + public int value() { + return this.value; + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/SystemCursor.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/SystemCursor.java new file mode 100644 index 000000000..8dff4eccc --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/SystemCursor.java @@ -0,0 +1,39 @@ +package com.cleanroommc.client.sdl.input; + +import org.lwjgl.sdl.SDLMouse; + +/** SDL's stock cursors. */ +public enum SystemCursor { + + DEFAULT(SDLMouse.SDL_SYSTEM_CURSOR_DEFAULT), + TEXT(SDLMouse.SDL_SYSTEM_CURSOR_TEXT), + WAIT(SDLMouse.SDL_SYSTEM_CURSOR_WAIT), + CROSSHAIR(SDLMouse.SDL_SYSTEM_CURSOR_CROSSHAIR), + PROGRESS(SDLMouse.SDL_SYSTEM_CURSOR_PROGRESS), + POINTER(SDLMouse.SDL_SYSTEM_CURSOR_POINTER), + NOT_ALLOWED(SDLMouse.SDL_SYSTEM_CURSOR_NOT_ALLOWED), + MOVE(SDLMouse.SDL_SYSTEM_CURSOR_MOVE), + NWSE_RESIZE(SDLMouse.SDL_SYSTEM_CURSOR_NWSE_RESIZE), + NESW_RESIZE(SDLMouse.SDL_SYSTEM_CURSOR_NESW_RESIZE), + EW_RESIZE(SDLMouse.SDL_SYSTEM_CURSOR_EW_RESIZE), + NS_RESIZE(SDLMouse.SDL_SYSTEM_CURSOR_NS_RESIZE), + NW_RESIZE(SDLMouse.SDL_SYSTEM_CURSOR_NW_RESIZE), + N_RESIZE(SDLMouse.SDL_SYSTEM_CURSOR_N_RESIZE), + NE_RESIZE(SDLMouse.SDL_SYSTEM_CURSOR_NE_RESIZE), + E_RESIZE(SDLMouse.SDL_SYSTEM_CURSOR_E_RESIZE), + SE_RESIZE(SDLMouse.SDL_SYSTEM_CURSOR_SE_RESIZE), + S_RESIZE(SDLMouse.SDL_SYSTEM_CURSOR_S_RESIZE), + SW_RESIZE(SDLMouse.SDL_SYSTEM_CURSOR_SW_RESIZE), + W_RESIZE(SDLMouse.SDL_SYSTEM_CURSOR_W_RESIZE); + + private final int value; + + SystemCursor(int value) { + this.value = value; + } + + int value() { + return value; + } + +} From 1a08f96f0f7c80a4b4acbbac232dca7c455a8a0b Mon Sep 17 00:00:00 2001 From: Rongmario Date: Wed, 19 Aug 2026 22:49:36 +0100 Subject: [PATCH 74/99] Sensors and surfaces --- .../java/com/cleanroommc/client/sdl/SDL.java | 70 +++++++-- .../com/cleanroommc/client/sdl/Surfaces.java | 100 +++++++++++++ .../cleanroommc/client/sdl/drop/Drops.java | 1 - .../client/sdl/input/Gamepads.java | 1 - .../cleanroommc/client/sdl/input/Inputs.java | 134 +++++++++++++++++ .../client/sdl/input/Joysticks.java | 1 - .../cleanroommc/client/sdl/input/Pens.java | 1 - .../cleanroommc/client/sdl/input/Sensor.java | 53 +++++++ .../client/sdl/input/SensorListener.java | 12 ++ .../client/sdl/input/SensorType.java | 40 +++++ .../cleanroommc/client/sdl/input/Sensors.java | 137 ++++++++++++++++++ .../cleanroommc/client/sdl/input/Touch.java | 52 +++++++ .../client/sdl/input/TouchKind.java | 32 ++++ .../client/sdl/input/TouchListener.java | 20 +++ .../cleanroommc/client/sdl/input/Touches.java | 109 ++++++++++++++ 15 files changed, 744 insertions(+), 19 deletions(-) create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Surfaces.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Inputs.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Sensor.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/SensorListener.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/SensorType.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Sensors.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Touch.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/TouchKind.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/TouchListener.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Touches.java diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SDL.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SDL.java index 040ab47ac..baa5c99d5 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SDL.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SDL.java @@ -1,8 +1,15 @@ package com.cleanroommc.client.sdl; import com.cleanroommc.client.sdl.input.virtual.Text; +import com.cleanroommc.common.CleanroomVersion; import org.lwjgl.sdl.SDLError; +import org.lwjgl.sdl.SDLHints; import org.lwjgl.sdl.SDLInit; +import org.lwjgl.sdl.SDLLog; +import org.lwjgl.sdl.SDL_LogOutputFunction; +import org.lwjgl.system.MemoryUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * SDL's lifecycle helpers. @@ -10,6 +17,7 @@ public final class SDL { private static int initializedBits; + private static SDL_LogOutputFunction logOutput; /** * Brings up the video and event subsystems, if they are not already up. @@ -30,12 +38,33 @@ public static synchronized void ensureSubsystem(int flags) { if (missing == 0) { return; } - // TODO: services to load when initializing subsystem? + installLog(); + prepare(missing); + check(SDLInit.SDL_InitSubSystem(missing), "SDL_InitSubSystem"); + initializedBits |= missing; + } + + /** + * Hints that must be set before a subsystem comes up, plus app metadata for the video path. + */ + private static void prepare(int missing) { if ((missing & SDLInit.SDL_INIT_VIDEO) != 0) { Text.implementIME(true, true); + check(SDLInit.SDL_SetAppMetadata("Cleanroom", CleanroomVersion.VERSION, "com.cleanroommc.cleanroom"), + "SDL_SetAppMetadata"); + check(SDLInit.SDL_SetAppMetadataProperty(SDLInit.SDL_PROP_APP_METADATA_TYPE_STRING, "game"), + "SDL_SetAppMetadataProperty"); } - initializedBits |= missing; - check(SDLInit.SDL_InitSubSystem(missing), "SDL_InitSubSystem"); + } + + /** + * Sets an SDL hint. Some hints are ignored once the matching subsystem is up. + */ + public static void hint(String name, String value) { + if (name == null || value == null) { + throw new IllegalArgumentException("Hint name and value cannot be null"); + } + check(SDLHints.SDL_SetHint(name, value), "SDL_SetHint(" + name + ")"); } /** @@ -48,17 +77,36 @@ public static synchronized boolean isInitialized(int flags) { /** Closes the host window and tears down every subsystem this class brought up. */ public static synchronized void shutdown() { + Devices.reset(); + CleanroomWindowBridge.uninstall(); + Window.closeMain(); if (initializedBits == 0) { return; } - // TODO: new SDL input stack - // Inputs.reset(); - CleanroomWindowBridge.uninstall(); - Window.closeMain(); SDLInit.SDL_Quit(); initializedBits = 0; } + private static void installLog() { + if (logOutput != null) { + return; + } + Logger logger = LoggerFactory.getLogger("com.cleanroommc.client.sdl"); + logOutput = SDL_LogOutputFunction.create((userdata, category, priority, message) -> { + String text = MemoryUtil.memUTF8(message); + if (priority >= SDLLog.SDL_LOG_PRIORITY_ERROR) { + logger.error("{}", text); + } else if (priority == SDLLog.SDL_LOG_PRIORITY_WARN) { + logger.warn("{}", text); + } else if (priority == SDLLog.SDL_LOG_PRIORITY_INFO) { + logger.info("{}", text); + } else { + logger.debug("{}", text); + } + }); + SDLLog.SDL_SetLogOutputFunction(logOutput, 0L); + } + /** * @param result the {@code boolean} an SDL call returned * @param call the call's name, for the message @@ -85,12 +133,4 @@ public static long checkHandle(long handle, String call) { private SDL() { } - public static final class SDLException extends RuntimeException { - - SDLException(String message) { - super(message); - } - - } - } diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Surfaces.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Surfaces.java new file mode 100644 index 000000000..15b9d2775 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Surfaces.java @@ -0,0 +1,100 @@ +package com.cleanroommc.client.sdl; + +import org.lwjgl.sdl.SDLPixels; +import org.lwjgl.sdl.SDLSurface; +import org.lwjgl.sdl.SDL_Surface; + +import java.awt.image.BufferedImage; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +/** Shared ARGB {@code SDL_Surface} helpers for icons and cursors. */ +public final class Surfaces { + + public static SDL_Surface from(BufferedImage image) { + if (image == null) { + throw new IllegalArgumentException("Image cannot be null"); + } + int width = image.getWidth(); + int height = image.getHeight(); + SDL_Surface surface = SDLSurface.SDL_CreateSurface(width, height, SDLPixels.SDL_PIXELFORMAT_ARGB8888); + if (surface == null) { + throw new SDLException("SDL_CreateSurface failed"); + } + boolean locked = false; + try { + if (SDLSurface.SDL_MUSTLOCK(surface)) { + SDL.check(SDLSurface.SDL_LockSurface(surface), "SDL_LockSurface"); + locked = true; + } + ByteBuffer pixels = surface.pixels(); + if (pixels == null) { + throw new SDLException("SDL_CreateSurface returned no pixels"); + } + pixels = pixels.duplicate().order(ByteOrder.nativeOrder()); + int[] argb = image.getRGB(0, 0, width, height, null, 0, width); + for (int pixel : argb) { + pixels.putInt(pixel); + } + pixels.flip(); + return surface; + } catch (RuntimeException failure) { + SDLSurface.SDL_DestroySurface(surface); + throw failure; + } finally { + if (locked) { + SDLSurface.SDL_UnlockSurface(surface); + } + } + } + + public static BufferedImage toImage(SDL_Surface surface) { + if (surface == null) { + throw new IllegalArgumentException("Surface cannot be null"); + } + SDL_Surface readable = surface; + SDL_Surface converted = null; + boolean locked = false; + try { + if (surface.format() != SDLPixels.SDL_PIXELFORMAT_ARGB8888) { + converted = SDLSurface.SDL_ConvertSurface(surface, SDLPixels.SDL_PIXELFORMAT_ARGB8888); + if (converted == null) { + throw new SDLException("SDL_ConvertSurface failed"); + } + readable = converted; + } + if (SDLSurface.SDL_MUSTLOCK(readable)) { + SDL.check(SDLSurface.SDL_LockSurface(readable), "SDL_LockSurface"); + locked = true; + } + ByteBuffer pixels = readable.pixels(); + if (pixels == null) { + throw new SDLException("Surface has no pixels"); + } + int width = readable.w(); + int height = readable.h(); + int pitch = readable.pitch(); + pixels = pixels.duplicate().order(ByteOrder.nativeOrder()); + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + int[] argb = new int[width]; + for (int y = 0; y < height; y++) { + pixels.position(y * pitch); + for (int x = 0; x < width; x++) { + argb[x] = pixels.getInt(); + } + image.setRGB(0, y, width, 1, argb, 0, width); + } + return image; + } finally { + if (locked) { + SDLSurface.SDL_UnlockSurface(readable); + } + if (converted != null) { + SDLSurface.SDL_DestroySurface(converted); + } + } + } + + private Surfaces() { } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/drop/Drops.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/drop/Drops.java index 4f34ff318..3d466ae80 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/drop/Drops.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/drop/Drops.java @@ -46,7 +46,6 @@ public static void handle(SDL_Event event) { case SDLEvents.SDL_EVENT_DROP_TEXT -> text(drop.dataString()); case SDLEvents.SDL_EVENT_DROP_POSITION -> position(drop.x(), drop.y()); case SDLEvents.SDL_EVENT_DROP_COMPLETE -> complete(); - default -> { } } } diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Gamepads.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Gamepads.java index e28a5c863..74566b162 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Gamepads.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Gamepads.java @@ -125,7 +125,6 @@ public synchronized void handle(SDL_Event event) { listener.sensor(pad, sensor, data); } } - default -> { } } } diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Inputs.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Inputs.java new file mode 100644 index 000000000..d07951060 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Inputs.java @@ -0,0 +1,134 @@ +package com.cleanroommc.client.sdl.input; + +import org.lwjgl.sdl.SDL_Event; + +import java.util.EnumMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Process-wide input facade. Keyboard and mouse read the host {@link com.cleanroommc.client.sdl.Window}; + * gamepads, joysticks, haptics and sensors come up on first use. + */ +public final class Inputs { + + private static final Keyboard KEYBOARD = new Keyboard(); + private static final Mouse MOUSE = new Mouse(); + private static final Gamepads GAMEPADS = new Gamepads(); + private static final Joysticks JOYSTICKS = new Joysticks(); + private static final Haptics HAPTICS = new Haptics(); + private static final Sensors SENSORS = new Sensors(); + private static final Touches TOUCHES = new Touches(); + private static final Pens PENS = new Pens(); + private static final Map SYSTEM_CURSORS = new EnumMap<>(SystemCursor.class); + private static final Set CUSTOM_CURSORS = new HashSet<>(); + + public static Keyboard keyboard() { + return KEYBOARD; + } + + public static Mouse mouse() { + return MOUSE; + } + + /** + * Brings up SDL's gamepad subsystem the first time it is called. + */ + public static Gamepads gamepads() { + GAMEPADS.ensure(); + return GAMEPADS; + } + + /** + * Brings up SDL's joystick subsystem the first time it is called. + */ + public static Joysticks joysticks() { + JOYSTICKS.ensure(); + return JOYSTICKS; + } + + /** + * Brings up SDL's haptic subsystem the first time it is called. + */ + public static Haptics haptics() { + HAPTICS.ensure(); + return HAPTICS; + } + + /** + * Brings up SDL's sensor subsystem the first time it is called. + */ + public static Sensors sensors() { + SENSORS.ensure(); + return SENSORS; + } + + /** + * Touch devices. No extra subsystem; events flow once video is up. + */ + public static Touches touches() { + return TOUCHES; + } + + /** + * Drawing tablets. No extra subsystem; events flow once video is up. + */ + public static Pens pens() { + return PENS; + } + + /** + * Forwards device events if the matching subsystem was started (or if touch/pen listeners exist). + */ + public static void dispatch(SDL_Event event) { + GAMEPADS.handle(event); + JOYSTICKS.handle(event); + SENSORS.handle(event); + TOUCHES.handle(event); + PENS.handle(event); + } + + /** + * Forwards a gamepad device event if the gamepad subsystem was started. + */ + public static void dispatchGamepad(SDL_Event event) { + GAMEPADS.handle(event); + } + + public static synchronized void reset() { + GAMEPADS.reset(); + JOYSTICKS.reset(); + HAPTICS.reset(); + SENSORS.reset(); + TOUCHES.reset(); + PENS.reset(); + for (Cursor cursor : List.copyOf(SYSTEM_CURSORS.values())) { + cursor.close(); + } + SYSTEM_CURSORS.clear(); + for (Cursor cursor : Set.copyOf(CUSTOM_CURSORS)) { + cursor.close(); + } + CUSTOM_CURSORS.clear(); + } + + static synchronized Cursor systemCursor(SystemCursor kind) { + return SYSTEM_CURSORS.computeIfAbsent(kind, Cursor::system); + } + + static synchronized void track(Cursor cursor) { + CUSTOM_CURSORS.add(cursor); + } + + static synchronized void forget(Cursor cursor) { + CUSTOM_CURSORS.remove(cursor); + if (cursor.system()) { + SYSTEM_CURSORS.values().removeIf(owned -> owned == cursor); + } + } + + private Inputs() { } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Joysticks.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Joysticks.java index 07ac04fa0..56886e832 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Joysticks.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Joysticks.java @@ -103,7 +103,6 @@ public synchronized void handle(SDL_Event event) { } } } - default -> { } } } diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Pens.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Pens.java index 4bd393983..a9b382023 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Pens.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Pens.java @@ -84,7 +84,6 @@ public void handle(SDL_Event event) { listener.axis(axis.which(), axis.x(), axis.y(), kind, axis.value()); } } - default -> { } } } diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Sensor.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Sensor.java new file mode 100644 index 000000000..48aad8606 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Sensor.java @@ -0,0 +1,53 @@ +package com.cleanroommc.client.sdl.input; + +import org.lwjgl.sdl.SDLSensor; +import org.lwjgl.system.MemoryStack; + +import java.nio.FloatBuffer; + +/** One standalone sensor (accel/gyro that is not hanging off a {@link Gamepad}). */ +public final class Sensor { + + private static final int DATA_COUNT = 3; + + private final int id; + private final long handle; + + Sensor(int id, long handle) { + this.id = id; + this.handle = handle; + } + + public int id() { + return id; + } + + public String name() { + String name = SDLSensor.SDL_GetSensorName(handle); + return name == null ? "" : name; + } + + public SensorType type() { + return SensorType.of(SDLSensor.SDL_GetSensorType(handle)); + } + + /** + * @return three floats: accel is in m/s², gyro is in rad/s + */ + public float[] data() { + try (MemoryStack stack = MemoryStack.stackPush()) { + FloatBuffer buffer = stack.mallocFloat(DATA_COUNT); + if (!SDLSensor.SDL_GetSensorData(handle, buffer)) { + return new float[DATA_COUNT]; + } + float[] values = new float[DATA_COUNT]; + buffer.get(values); + return values; + } + } + + long handle() { + return handle; + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/SensorListener.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/SensorListener.java new file mode 100644 index 000000000..0ab0ff56d --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/SensorListener.java @@ -0,0 +1,12 @@ +package com.cleanroommc.client.sdl.input; + +/** Hotplug for standalone sensors. Called from {@link com.cleanroommc.client.sdl.Window#pump()}. */ +public interface SensorListener { + + default void added(Sensor sensor) { } + + default void removed(int id) { } + + default void updated(Sensor sensor, float[] data) { } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/SensorType.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/SensorType.java new file mode 100644 index 000000000..5af71073f --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/SensorType.java @@ -0,0 +1,40 @@ +package com.cleanroommc.client.sdl.input; + +import org.lwjgl.sdl.SDLSensor; + +/** SDL sensor kinds, including left/right Joy-Con variants. */ +public enum SensorType { + + INVALID(SDLSensor.SDL_SENSOR_INVALID), + UNKNOWN(SDLSensor.SDL_SENSOR_UNKNOWN), + ACCEL(SDLSensor.SDL_SENSOR_ACCEL), + GYRO(SDLSensor.SDL_SENSOR_GYRO), + ACCEL_L(SDLSensor.SDL_SENSOR_ACCEL_L), + GYRO_L(SDLSensor.SDL_SENSOR_GYRO_L), + ACCEL_R(SDLSensor.SDL_SENSOR_ACCEL_R), + GYRO_R(SDLSensor.SDL_SENSOR_GYRO_R); + + public static SensorType of(int value) { + return switch (value) { + case SDLSensor.SDL_SENSOR_INVALID -> INVALID; + case SDLSensor.SDL_SENSOR_ACCEL -> ACCEL; + case SDLSensor.SDL_SENSOR_GYRO -> GYRO; + case SDLSensor.SDL_SENSOR_ACCEL_L -> ACCEL_L; + case SDLSensor.SDL_SENSOR_GYRO_L -> GYRO_L; + case SDLSensor.SDL_SENSOR_ACCEL_R -> ACCEL_R; + case SDLSensor.SDL_SENSOR_GYRO_R -> GYRO_R; + default -> UNKNOWN; + }; + } + + private final int value; + + SensorType(int value) { + this.value = value; + } + + public int value() { + return value; + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Sensors.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Sensors.java new file mode 100644 index 000000000..9e78070fc --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Sensors.java @@ -0,0 +1,137 @@ +package com.cleanroommc.client.sdl.input; + +import com.cleanroommc.client.sdl.SDL; +import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import org.lwjgl.sdl.SDLEvents; +import org.lwjgl.sdl.SDLInit; +import org.lwjgl.sdl.SDLSensor; +import org.lwjgl.sdl.SDLStdinc; +import org.lwjgl.sdl.SDL_Event; +import org.lwjgl.sdl.SDL_SensorEvent; + +import java.nio.IntBuffer; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * Standalone sensors. First use initializes {@code SDL_INIT_SENSOR}. + */ +public final class Sensors { + + private final Int2ObjectMap sensors = new Int2ObjectArrayMap<>(); + private final List listeners = new CopyOnWriteArrayList<>(); + + private boolean started; + + Sensors() { } + + synchronized void ensure() { + if (started) { + return; + } + SDL.ensureSubsystem(SDLInit.SDL_INIT_SENSOR); + started = true; + openConnected(); + } + + public synchronized List list() { + ensure(); + return List.copyOf(sensors.values()); + } + + public synchronized Sensor byId(int id) { + ensure(); + return sensors.get(id); + } + + public Sensors listen(SensorListener listener) { + if (listener == null) { + throw new IllegalArgumentException("Listener cannot be null"); + } + listeners.add(listener); + return this; + } + + public Sensors mute(SensorListener listener) { + listeners.remove(listener); + return this; + } + + public synchronized void handle(SDL_Event event) { + if (!started) { + return; + } + int type = event.type(); + if (type == SDLEvents.SDL_EVENT_SENSOR_UPDATE) { + SDL_SensorEvent update = event.sensor(); + Sensor sensor = sensors.get(update.which()); + if (sensor == null) { + return; + } + float[] data = {update.data(0), update.data(1), update.data(2)}; + for (SensorListener listener : listeners) { + listener.updated(sensor, data); + } + } + // Standalone sensors have no add/remove event + } + + synchronized void reset() { + for (Sensor sensor : sensors.values()) { + SDLSensor.SDL_CloseSensor(sensor.handle()); + } + sensors.clear(); + listeners.clear(); + started = false; + } + + private void openConnected() { + IntBuffer ids = SDLSensor.SDL_GetSensors(); + if (ids == null) { + return; + } + try { + while (ids.hasRemaining()) { + open(ids.get()); + } + } finally { + SDLStdinc.SDL_free(ids); + } + } + + private Sensor open(int id) { + Sensor existing = sensors.get(id); + if (existing != null) { + return existing; + } + long already = SDLSensor.SDL_GetSensorFromID(id); + long handle = already != 0L ? already : SDLSensor.SDL_OpenSensor(id); + if (handle == 0L) { + return null; + } + Sensor sensor = new Sensor(id, handle); + sensors.put(id, sensor); + return sensor; + } + + synchronized Sensor injectAdded(int id, long handle) { + started = true; + Sensor sensor = new Sensor(id, handle); + sensors.put(id, sensor); + List snapshot = new ArrayList<>(listeners); + for (SensorListener listener : snapshot) { + listener.added(sensor); + } + return sensor; + } + + synchronized void injectRemoved(int id) { + sensors.remove(id); + for (SensorListener listener : listeners) { + listener.removed(id); + } + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Touch.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Touch.java new file mode 100644 index 000000000..e5b10840d --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Touch.java @@ -0,0 +1,52 @@ +package com.cleanroommc.client.sdl.input; + +import org.lwjgl.PointerBuffer; +import org.lwjgl.sdl.SDLStdinc; +import org.lwjgl.sdl.SDLTouch; +import org.lwjgl.sdl.SDL_Finger; + +import java.util.ArrayList; +import java.util.List; + +/** One touch device. */ +public final class Touch { + + private final long id; + + Touch(long id) { + this.id = id; + } + + public long id() { + return id; + } + + public String name() { + String name = SDLTouch.SDL_GetTouchDeviceName(id); + return name == null ? "" : name; + } + + public TouchKind kind() { + return TouchKind.of(SDLTouch.SDL_GetTouchDeviceType(id)); + } + + public List fingers() { + PointerBuffer pointers = SDLTouch.SDL_GetTouchFingers(id); + if (pointers == null) { + return List.of(); + } + try { + List fingers = new ArrayList<>(pointers.remaining()); + while (pointers.hasRemaining()) { + SDL_Finger finger = SDL_Finger.createSafe(pointers.get()); + if (finger != null) { + fingers.add(new Finger(finger.id(), finger.x(), finger.y(), finger.pressure())); + } + } + return List.copyOf(fingers); + } finally { + SDLStdinc.SDL_free(pointers); + } + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/TouchKind.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/TouchKind.java new file mode 100644 index 000000000..0839a9972 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/TouchKind.java @@ -0,0 +1,32 @@ +package com.cleanroommc.client.sdl.input; + +import org.lwjgl.sdl.SDLTouch; + +/** How a touch device reports coordinates. */ +public enum TouchKind { + + INVALID(SDLTouch.SDL_TOUCH_DEVICE_INVALID), + DIRECT(SDLTouch.SDL_TOUCH_DEVICE_DIRECT), + INDIRECT_ABSOLUTE(SDLTouch.SDL_TOUCH_DEVICE_INDIRECT_ABSOLUTE), + INDIRECT_RELATIVE(SDLTouch.SDL_TOUCH_DEVICE_INDIRECT_RELATIVE); + + private final int value; + + TouchKind(int value) { + this.value = value; + } + + public int value() { + return value; + } + + public static TouchKind of(int value) { + return switch (value) { + case SDLTouch.SDL_TOUCH_DEVICE_DIRECT -> DIRECT; + case SDLTouch.SDL_TOUCH_DEVICE_INDIRECT_ABSOLUTE -> INDIRECT_ABSOLUTE; + case SDLTouch.SDL_TOUCH_DEVICE_INDIRECT_RELATIVE -> INDIRECT_RELATIVE; + default -> INVALID; + }; + } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/TouchListener.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/TouchListener.java new file mode 100644 index 000000000..e04e7f40b --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/TouchListener.java @@ -0,0 +1,20 @@ +package com.cleanroommc.client.sdl.input; + +/** Multi-touch and pinch. Called from {@link com.cleanroommc.client.sdl.Window#pump()}. */ +public interface TouchListener { + + default void down(long device, long finger, float x, float y, float pressure) { } + + default void up(long device, long finger, float x, float y, float pressure) { } + + default void motion(long device, long finger, float x, float y, float dx, float dy, float pressure) { } + + default void canceled(long device, long finger, float x, float y, float pressure) { } + + default void pinchBegin(float scale) { } + + default void pinch(float scale) { } + + default void pinchEnd(float scale) { } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Touches.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Touches.java new file mode 100644 index 000000000..37ab61523 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Touches.java @@ -0,0 +1,109 @@ +package com.cleanroommc.client.sdl.input; + +import org.lwjgl.sdl.SDLEvents; +import org.lwjgl.sdl.SDLStdinc; +import org.lwjgl.sdl.SDLTouch; +import org.lwjgl.sdl.SDL_Event; +import org.lwjgl.sdl.SDL_PinchFingerEvent; +import org.lwjgl.sdl.SDL_TouchFingerEvent; + +import java.nio.LongBuffer; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * Touchscreens and trackpads. No extra SDL subsystem as video already delivers the events. + */ +public final class Touches { + + private final List listeners = new CopyOnWriteArrayList<>(); + + Touches() { } + + public List list() { + LongBuffer ids = SDLTouch.SDL_GetTouchDevices(); + if (ids == null) { + return List.of(); + } + try { + List devices = new ArrayList<>(ids.remaining()); + while (ids.hasRemaining()) { + devices.add(new Touch(ids.get())); + } + return List.copyOf(devices); + } finally { + SDLStdinc.SDL_free(ids); + } + } + + public Touches listen(TouchListener listener) { + if (listener == null) { + throw new IllegalArgumentException("Listener cannot be null"); + } + listeners.add(listener); + return this; + } + + public Touches mute(TouchListener listener) { + listeners.remove(listener); + return this; + } + + public void handle(SDL_Event event) { + if (listeners.isEmpty()) { + return; + } + int type = event.type(); + switch (type) { + case SDLEvents.SDL_EVENT_FINGER_DOWN -> { + SDL_TouchFingerEvent finger = event.tfinger(); + for (TouchListener listener : listeners) { + listener.down(finger.touchID(), finger.fingerID(), finger.x(), finger.y(), finger.pressure()); + } + } + case SDLEvents.SDL_EVENT_FINGER_UP -> { + SDL_TouchFingerEvent finger = event.tfinger(); + for (TouchListener listener : listeners) { + listener.up(finger.touchID(), finger.fingerID(), finger.x(), finger.y(), finger.pressure()); + } + } + case SDLEvents.SDL_EVENT_FINGER_MOTION -> { + SDL_TouchFingerEvent finger = event.tfinger(); + for (TouchListener listener : listeners) { + listener.motion(finger.touchID(), finger.fingerID(), finger.x(), finger.y(), finger.dx(), finger.dy(), + finger.pressure()); + } + } + case SDLEvents.SDL_EVENT_FINGER_CANCELED -> { + SDL_TouchFingerEvent finger = event.tfinger(); + for (TouchListener listener : listeners) { + listener.canceled(finger.touchID(), finger.fingerID(), finger.x(), finger.y(), finger.pressure()); + } + } + case SDLEvents.SDL_EVENT_PINCH_BEGIN -> { + SDL_PinchFingerEvent pinch = event.pinch(); + for (TouchListener listener : listeners) { + listener.pinchBegin(pinch.scale()); + } + } + case SDLEvents.SDL_EVENT_PINCH_UPDATE -> { + SDL_PinchFingerEvent pinch = event.pinch(); + for (TouchListener listener : listeners) { + listener.pinch(pinch.scale()); + } + } + case SDLEvents.SDL_EVENT_PINCH_END -> { + SDL_PinchFingerEvent pinch = event.pinch(); + for (TouchListener listener : listeners) { + listener.pinchEnd(pinch.scale()); + } + } + } + } + + void reset() { + listeners.clear(); + } + +} From 4aa03cb1d61d2c3096364e6bb4d924fed60c7333 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Wed, 19 Aug 2026 22:55:08 +0100 Subject: [PATCH 75/99] Remove `lwjgl-tinyfd` --- build.gradle | 2 -- 1 file changed, 2 deletions(-) diff --git a/build.gradle b/build.gradle index 5cba64748..791f30ec8 100644 --- a/build.gradle +++ b/build.gradle @@ -185,7 +185,6 @@ dependencies { api 'org.lwjgl:lwjgl-opengl' api 'org.lwjgl:lwjgl-openal' api 'org.lwjgl:lwjgl-stb' - api 'org.lwjgl:lwjgl-tinyfd' api 'org.lwjgl:lwjgl-sdl' // TODO @@ -196,7 +195,6 @@ dependencies { lwjglNative 'org.lwjgl:lwjgl-opengl' lwjglNative 'org.lwjgl:lwjgl-openal' lwjglNative 'org.lwjgl:lwjgl-stb' - lwjglNative 'org.lwjgl:lwjgl-tinyfd' lwjglNative 'org.lwjgl:lwjgl-sdl' // Kirino From 16341ef6af7223865c6e4b8abb16eafa811eb0b4 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Wed, 19 Aug 2026 22:57:42 +0100 Subject: [PATCH 76/99] Window with many more events to be dispatched and properties to be had --- .../com/cleanroommc/client/sdl/Window.java | 432 ++++++++++++++++-- 1 file changed, 393 insertions(+), 39 deletions(-) diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Window.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Window.java index 781a078ca..516f775b2 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Window.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Window.java @@ -1,25 +1,38 @@ package com.cleanroommc.client.sdl; +import com.cleanroommc.client.sdl.drop.Drops; import com.cleanroommc.client.sdl.input.virtual.Text; +import com.cleanroommc.client.sdl.video.Display; +import com.cleanroommc.client.sdl.video.DisplayMode; +import com.cleanroommc.client.sdl.video.Displays; import com.cleanroommc.lwjgly.spi.WindowBridge; +import org.lwjgl.PointerBuffer; import org.lwjgl.opengl.GL; import org.lwjgl.sdl.SDLMouse; import org.lwjgl.sdl.SDLProperties; +import org.lwjgl.sdl.SDLStdinc; +import org.lwjgl.sdl.SDLSurface; import org.lwjgl.sdl.SDLVideo; import org.lwjgl.sdl.SDLEvents; +import org.lwjgl.sdl.SDL_DisplayMode; import org.lwjgl.sdl.SDL_Event; import org.lwjgl.sdl.SDL_KeyboardEvent; import org.lwjgl.sdl.SDL_MouseButtonEvent; import org.lwjgl.sdl.SDL_MouseMotionEvent; import org.lwjgl.sdl.SDL_MouseWheelEvent; +import org.lwjgl.sdl.SDL_Surface; import org.lwjgl.sdl.SDL_TextEditingCandidatesEvent; import org.lwjgl.sdl.SDL_TextEditingEvent; import org.lwjgl.sdl.SDL_TextInputEvent; import org.lwjgl.sdl.SDL_WindowEvent; import org.lwjgl.system.MemoryStack; +import java.awt.image.BufferedImage; import java.nio.IntBuffer; +import java.nio.file.Path; import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.function.Consumer; /** The single SDL window, OpenGL context and event pump owned by Cleanroom. */ @@ -37,6 +50,7 @@ public final class Window implements AutoCloseable { private final Text text = new Text(this); private final boolean[] keys = new boolean[MAX_SCANCODES]; private final boolean[] buttons = new boolean[MAX_MOUSE_BUTTONS + 1]; + private final List listeners = new CopyOnWriteArrayList<>(); private String title; private int width; @@ -45,17 +59,63 @@ public final class Window implements AutoCloseable { private int pixelHeight; private float mouseX; private float mouseY; + private float opacity = 1.0F; private boolean focused = true; private boolean closeRequested; private boolean resized; private boolean fullscreen; private boolean borderless; private boolean minimized; + private boolean maximized; + private boolean hidden; + private boolean resizable; + private boolean alwaysOnTop; private boolean mouseGrabbed; private boolean mouseWarped; + private boolean mouseInside = true; private volatile boolean closed; + /** Attention request passed to {@link #flash(Flash)}. */ + public enum Flash { + + CANCEL(SDLVideo.SDL_FLASH_CANCEL), + BRIEFLY(SDLVideo.SDL_FLASH_BRIEFLY), + UNTIL_FOCUSED(SDLVideo.SDL_FLASH_UNTIL_FOCUSED); + + private final int value; + + Flash(int value) { + this.value = value; + } + + public int value() { + return value; + } + + } + + /** Taskbar/dock progress passed to {@link #progress(Progress, float)}. */ + public enum Progress { + + NONE(SDLVideo.SDL_PROGRESS_STATE_NONE), + INDETERMINATE(SDLVideo.SDL_PROGRESS_STATE_INDETERMINATE), + NORMAL(SDLVideo.SDL_PROGRESS_STATE_NORMAL), + PAUSED(SDLVideo.SDL_PROGRESS_STATE_PAUSED), + ERROR(SDLVideo.SDL_PROGRESS_STATE_ERROR); + + private final int value; + + Progress(int value) { + this.value = value; + } + + public int value() { + return value; + } + + } + private Window(long handle, long glContext, String title, int width, int height) { this.handle = handle; this.glContext = glContext; @@ -90,39 +150,32 @@ public long handle() { /** * Returns the platform window handle rather than SDL's opaque window pointer. - * TODO: Make compositors into an enum */ public long nativeHandle() { + return nativeWindow().handle(); + } + + /** + * @return which compositor owns the native handle, and the handle itself + */ + public NativeWindow nativeWindow() { this.ensureOpen(); int properties = SDLVideo.SDL_GetWindowProperties(handle); if (properties == 0) { - return 0L; - } - long hwnd = SDLProperties.SDL_GetPointerProperty(properties, SDLVideo.SDL_PROP_WINDOW_WIN32_HWND_POINTER, 0L); - if (hwnd != 0L) { - return hwnd; - } - long wayland = SDLProperties.SDL_GetPointerProperty(properties, SDLVideo.SDL_PROP_WINDOW_WAYLAND_SURFACE_POINTER, 0L); - if (wayland != 0L) { - return wayland; - } - long x11 = SDLProperties.SDL_GetNumberProperty(properties, SDLVideo.SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0L); - if (x11 != 0L) { - return x11; + return NativeWindow.UNKNOWN; } - long macOS = SDLProperties.SDL_GetNumberProperty(properties, SDLVideo.SDL_PROP_WINDOW_COCOA_WINDOW_POINTER, 0L); - if (macOS != 0L) { - return macOS; - } - long android = SDLProperties.SDL_GetNumberProperty(properties, SDLVideo.SDL_PROP_WINDOW_ANDROID_WINDOW_POINTER, 0L); - if (android != 0L) { - return android; - } - long ios = SDLProperties.SDL_GetNumberProperty(properties, SDLVideo.SDL_PROP_WINDOW_UIKIT_WINDOW_POINTER, 0L); - if (ios != 0L) { - return ios; + for (Compositor compositor : Compositor.values()) { + if (compositor == Compositor.UNKNOWN) { + continue; + } + long value = compositor.pointer() + ? SDLProperties.SDL_GetPointerProperty(properties, compositor.property(), 0L) + : SDLProperties.SDL_GetNumberProperty(properties, compositor.property(), 0L); + if (value != 0L) { + return new NativeWindow(compositor, value); + } } - return SDLProperties.SDL_GetNumberProperty(properties, SDLVideo.SDL_PROP_WINDOW_VIVANTE_WINDOW_POINTER, 0L); + return NativeWindow.UNKNOWN; } public synchronized int width() { @@ -165,6 +218,26 @@ public synchronized boolean borderless() { return borderless; } + public synchronized boolean maximized() { + return maximized; + } + + public synchronized boolean hidden() { + return hidden; + } + + public synchronized boolean resizable() { + return resizable; + } + + public synchronized boolean alwaysOnTop() { + return alwaysOnTop; + } + + public synchronized boolean mouseInside() { + return mouseInside; + } + public synchronized boolean consumeResized() { boolean value = this.resized; this.resized = false; @@ -193,6 +266,236 @@ public synchronized Window borderless(boolean borderless) { return this; } + public synchronized Window size(int width, int height) { + this.ensureOpen(); + SDL.check(SDLVideo.SDL_SetWindowSize(this.handle, width, height), "SDL_SetWindowSize"); + this.refreshSize(); + return this; + } + + public synchronized int[] position() { + this.ensureOpen(); + try (MemoryStack stack = MemoryStack.stackPush()) { + IntBuffer x = stack.mallocInt(1); + IntBuffer y = stack.mallocInt(1); + SDL.check(SDLVideo.SDL_GetWindowPosition(this.handle, x, y), "SDL_GetWindowPosition"); + return new int[] { x.get(0), y.get(0) }; + } + } + + public synchronized Window position(int x, int y) { + this.ensureOpen(); + SDL.check(SDLVideo.SDL_SetWindowPosition(this.handle, x, y), "SDL_SetWindowPosition"); + return this; + } + + public synchronized Window minimumSize(int width, int height) { + this.ensureOpen(); + SDL.check(SDLVideo.SDL_SetWindowMinimumSize(this.handle, width, height), "SDL_SetWindowMinimumSize"); + return this; + } + + public synchronized Window maximumSize(int width, int height) { + this.ensureOpen(); + SDL.check(SDLVideo.SDL_SetWindowMaximumSize(this.handle, width, height), "SDL_SetWindowMaximumSize"); + return this; + } + + public synchronized Window resizable(boolean resizable) { + this.ensureOpen(); + SDL.check(SDLVideo.SDL_SetWindowResizable(this.handle, resizable), "SDL_SetWindowResizable"); + this.resizable = resizable; + return this; + } + + public synchronized Window alwaysOnTop(boolean alwaysOnTop) { + this.ensureOpen(); + SDL.check(SDLVideo.SDL_SetWindowAlwaysOnTop(this.handle, alwaysOnTop), "SDL_SetWindowAlwaysOnTop"); + this.alwaysOnTop = alwaysOnTop; + return this; + } + + public synchronized Window opacity(float opacity) { + this.ensureOpen(); + SDL.check(SDLVideo.SDL_SetWindowOpacity(this.handle, opacity), "SDL_SetWindowOpacity"); + this.opacity = opacity; + return this; + } + + public synchronized float opacity() { + return opacity; + } + + public synchronized Window show() { + this.ensureOpen(); + SDL.check(SDLVideo.SDL_ShowWindow(this.handle), "SDL_ShowWindow"); + this.hidden = false; + return this; + } + + public synchronized Window hide() { + this.ensureOpen(); + SDL.check(SDLVideo.SDL_HideWindow(this.handle), "SDL_HideWindow"); + this.hidden = true; + return this; + } + + public synchronized Window raise() { + this.ensureOpen(); + SDL.check(SDLVideo.SDL_RaiseWindow(this.handle), "SDL_RaiseWindow"); + return this; + } + + public synchronized Window minimize() { + this.ensureOpen(); + SDL.check(SDLVideo.SDL_MinimizeWindow(this.handle), "SDL_MinimizeWindow"); + this.minimized = true; + this.maximized = false; + return this; + } + + public synchronized Window maximize() { + this.ensureOpen(); + SDL.check(SDLVideo.SDL_MaximizeWindow(this.handle), "SDL_MaximizeWindow"); + this.maximized = true; + this.minimized = false; + return this; + } + + public synchronized Window flash(Flash flash) { + this.ensureOpen(); + if (flash == null) { + throw new IllegalArgumentException("Flash cannot be null"); + } + SDL.check(SDLVideo.SDL_FlashWindow(this.handle, flash.value), "SDL_FlashWindow"); + return this; + } + + public synchronized Window progress(Progress state) { + return progress(state, 0.0F); + } + + /** + * @param state taskbar progress kind + * @param value {@code 0..1} when {@code state} is {@link Progress#NORMAL}, {@link Progress#PAUSED} or {@link Progress#ERROR} + */ + public synchronized Window progress(Progress state, float value) { + this.ensureOpen(); + if (state == null) { + throw new IllegalArgumentException("Progress cannot be null"); + } + SDL.check(SDLVideo.SDL_SetWindowProgressState(this.handle, state.value), "SDL_SetWindowProgressState"); + if (state != Progress.NONE && state != Progress.INDETERMINATE) { + SDL.check(SDLVideo.SDL_SetWindowProgressValue(this.handle, Math.max(0.0F, Math.min(1.0F, value))), + "SDL_SetWindowProgressValue"); + } + return this; + } + + public Window icon(BufferedImage... images) { + this.ensureOpen(); + if (images == null || images.length == 0 || images[0] == null) { + throw new IllegalArgumentException("At least one icon image is required"); + } + SDL_Surface primary = Surfaces.from(images[0]); + try { + for (int i = 1; i < images.length; i++) { + if (images[i] == null) { + continue; + } + SDL_Surface extra = Surfaces.from(images[i]); + try { + SDL.check(SDLSurface.SDL_AddSurfaceAlternateImage(primary, extra), "SDL_AddSurfaceAlternateImage"); + } finally { + SDLSurface.SDL_DestroySurface(extra); + } + } + SDL.check(SDLVideo.SDL_SetWindowIcon(this.handle, primary), "SDL_SetWindowIcon"); + } finally { + SDLSurface.SDL_DestroySurface(primary); + } + return this; + } + + public Window icon(Path path) { + this.ensureOpen(); + if (path == null) { + throw new IllegalArgumentException("Path cannot be null"); + } + SDL_Surface surface = SDLSurface.SDL_LoadSurface(path.toAbsolutePath().toString()); + if (surface == null) { + throw new SDLException("SDL_LoadSurface failed"); + } + try { + SDL.check(SDLVideo.SDL_SetWindowIcon(this.handle, surface), "SDL_SetWindowIcon"); + } finally { + SDLSurface.SDL_DestroySurface(surface); + } + return this; + } + + public Display display() { + this.ensureOpen(); + return Displays.of(SDLVideo.SDL_GetDisplayForWindow(this.handle)); + } + + public float pixelDensity() { + this.ensureOpen(); + return SDLVideo.SDL_GetWindowPixelDensity(this.handle); + } + + public float displayScale() { + this.ensureOpen(); + return SDLVideo.SDL_GetWindowDisplayScale(this.handle); + } + + /** + * Exclusive fullscreen using {@code mode}, or borderless desktop fullscreen when {@code mode} is {@code null}. + */ + public synchronized Window fullscreenMode(DisplayMode mode) { + this.ensureOpen(); + if (mode == null) { + SDL.check(SDLVideo.SDL_SetWindowFullscreenMode(this.handle, null), "SDL_SetWindowFullscreenMode"); + return fullscreen(true); + } + PointerBuffer modes = SDLVideo.SDL_GetFullscreenDisplayModes(mode.displayId()); + if (modes == null) { + return fullscreen(true); + } + try { + SDL_DisplayMode found = null; + while (modes.hasRemaining()) { + SDL_DisplayMode candidate = SDL_DisplayMode.createSafe(modes.get()); + if (candidate != null + && candidate.w() == mode.width() + && candidate.h() == mode.height() + && (mode.refreshRate() <= 0 || Math.abs(candidate.refresh_rate() - mode.refreshRate()) < 0.5F)) { + found = candidate; + break; + } + } + if (found != null) { + SDL.check(SDLVideo.SDL_SetWindowFullscreenMode(this.handle, found), "SDL_SetWindowFullscreenMode"); + } + } finally { + SDLStdinc.SDL_free(modes); + } + return fullscreen(true); + } + + public Window listen(WindowListener listener) { + if (listener == null) { + throw new IllegalArgumentException("Listener cannot be null"); + } + listeners.add(listener); + return this; + } + + public Window mute(WindowListener listener) { + listeners.remove(listener); + return this; + } + /** * Sets the swap interval of whichever context is current on this thread, which SDL keys to the context rather than * to the window. Make this window current first if another context may have taken over the thread. @@ -241,6 +544,7 @@ public synchronized Window pump() { dispatch(event); } } + Devices.afterPump(); this.mouseWarped = false; return this; } @@ -264,9 +568,27 @@ private void dispatch(SDL_Event event) { SDLEvents.SDL_EVENT_WINDOW_MINIMIZED, SDLEvents.SDL_EVENT_WINDOW_MAXIMIZED, SDLEvents.SDL_EVENT_WINDOW_RESTORED, + SDLEvents.SDL_EVENT_WINDOW_SHOWN, + SDLEvents.SDL_EVENT_WINDOW_HIDDEN, + SDLEvents.SDL_EVENT_WINDOW_MOUSE_ENTER, + SDLEvents.SDL_EVENT_WINDOW_MOUSE_LEAVE, + SDLEvents.SDL_EVENT_WINDOW_DISPLAY_CHANGED, + SDLEvents.SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED, SDLEvents.SDL_EVENT_WINDOW_ENTER_FULLSCREEN, SDLEvents.SDL_EVENT_WINDOW_LEAVE_FULLSCREEN -> window(type, event.window()); - default -> { } + case SDLEvents.SDL_EVENT_CLIPBOARD_UPDATE -> Clipboard.updated(); + case SDLEvents.SDL_EVENT_DROP_FILE, + SDLEvents.SDL_EVENT_DROP_TEXT, + SDLEvents.SDL_EVENT_DROP_BEGIN, + SDLEvents.SDL_EVENT_DROP_COMPLETE, + SDLEvents.SDL_EVENT_DROP_POSITION -> Drops.handle(event); + case SDLEvents.SDL_EVENT_DISPLAY_ADDED, + SDLEvents.SDL_EVENT_DISPLAY_REMOVED, + SDLEvents.SDL_EVENT_DISPLAY_MOVED, + SDLEvents.SDL_EVENT_DISPLAY_DESKTOP_MODE_CHANGED, + SDLEvents.SDL_EVENT_DISPLAY_CURRENT_MODE_CHANGED, + SDLEvents.SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED -> Displays.handle(type, event.display().displayID()); + default -> Devices.dispatch(event); } } @@ -341,27 +663,57 @@ private void window(int type, SDL_WindowEvent event) { return; } switch (type) { - case SDLEvents.SDL_EVENT_WINDOW_CLOSE_REQUESTED -> this.closeRequested = true; + case SDLEvents.SDL_EVENT_WINDOW_CLOSE_REQUESTED -> { + this.closeRequested = true; + notifyListeners(listener -> listener.closeRequested()); + } case SDLEvents.SDL_EVENT_WINDOW_RESIZED -> { this.width = event.data1(); this.height = event.data2(); this.resized = true; + notifyListeners(listener -> listener.resized(this.width, this.height)); } case SDLEvents.SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED -> { this.pixelWidth = event.data1(); this.pixelHeight = event.data2(); this.resized = true; } - case SDLEvents.SDL_EVENT_WINDOW_FOCUS_GAINED -> this.focused = true; + case SDLEvents.SDL_EVENT_WINDOW_FOCUS_GAINED -> { + this.focused = true; + notifyListeners(listener -> listener.focus(true)); + } case SDLEvents.SDL_EVENT_WINDOW_FOCUS_LOST -> { this.focused = false; this.releaseHeldInput(event.timestamp()); + notifyListeners(listener -> listener.focus(false)); + } + case SDLEvents.SDL_EVENT_WINDOW_MINIMIZED -> { + this.minimized = true; + this.maximized = false; + } + case SDLEvents.SDL_EVENT_WINDOW_MAXIMIZED -> { + this.maximized = true; + this.minimized = false; } - case SDLEvents.SDL_EVENT_WINDOW_MINIMIZED -> this.minimized = true; - case SDLEvents.SDL_EVENT_WINDOW_MAXIMIZED, SDLEvents.SDL_EVENT_WINDOW_RESTORED -> this.minimized = false; + case SDLEvents.SDL_EVENT_WINDOW_RESTORED -> { + this.minimized = false; + this.maximized = false; + } + case SDLEvents.SDL_EVENT_WINDOW_SHOWN -> this.hidden = false; + case SDLEvents.SDL_EVENT_WINDOW_HIDDEN -> this.hidden = true; + case SDLEvents.SDL_EVENT_WINDOW_MOUSE_ENTER -> this.mouseInside = true; + case SDLEvents.SDL_EVENT_WINDOW_MOUSE_LEAVE -> this.mouseInside = false; + case SDLEvents.SDL_EVENT_WINDOW_DISPLAY_CHANGED -> notifyListeners(WindowListener::displayChanged); + case SDLEvents.SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED -> + notifyListeners(listener -> listener.scaleChanged(SDLVideo.SDL_GetWindowDisplayScale(this.handle))); case SDLEvents.SDL_EVENT_WINDOW_ENTER_FULLSCREEN -> this.fullscreen = true; case SDLEvents.SDL_EVENT_WINDOW_LEAVE_FULLSCREEN -> this.fullscreen = false; - default -> { } + } + } + + private void notifyListeners(Consumer action) { + for (WindowListener listener : listeners) { + action.accept(listener); } } @@ -404,23 +756,23 @@ private void refreshSize() { } } - synchronized boolean keyDown(int scancode) { + public synchronized boolean keyDown(int scancode) { return scancode >= 0 && scancode < this.keys.length && this.keys[scancode]; } - synchronized boolean mouseButtonDown(int button) { + public synchronized boolean mouseButtonDown(int button) { return button > 0 && button < this.buttons.length && this.buttons[button]; } - synchronized float mouseX() { + public synchronized float mouseX() { return mouseX; } - synchronized float mouseY() { + public synchronized float mouseY() { return mouseY; } - synchronized void mousePosition(float x, float y) { + public synchronized void mousePosition(float x, float y) { this.ensureOpen(); SDLMouse.SDL_WarpMouseInWindow(this.handle, x, y); this.mouseX = x; @@ -428,7 +780,7 @@ synchronized void mousePosition(float x, float y) { this.mouseWarped = !this.mouseGrabbed; } - synchronized void grabMouse(boolean grab) { + public synchronized void grabMouse(boolean grab) { this.ensureOpen(); SDL.check(SDLMouse.SDL_SetWindowRelativeMouseMode(handle, grab), "SDL_SetWindowRelativeMouseMode"); this.mouseGrabbed = grab; @@ -436,7 +788,7 @@ synchronized void grabMouse(boolean grab) { this.mouseWarped = true; } - synchronized boolean mouseGrabbed() { + public synchronized boolean mouseGrabbed() { return mouseGrabbed; } @@ -582,6 +934,8 @@ private Window create() { } Window window = new Window(handle, context, this.title, this.width, this.height); window.fullscreen = this.fullscreen; + window.hidden = this.hidden; + window.resizable = this.resizable; window.refreshSize(); main = window; created = true; From e23debd80af03ccdbdf637e74b3035d07195c759 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Wed, 19 Aug 2026 23:03:11 +0100 Subject: [PATCH 77/99] Add category into SDL3 logging --- .../main/java/com/cleanroommc/client/sdl/SDL.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SDL.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SDL.java index baa5c99d5..702ded121 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SDL.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SDL.java @@ -91,17 +91,17 @@ private static void installLog() { if (logOutput != null) { return; } - Logger logger = LoggerFactory.getLogger("com.cleanroommc.client.sdl"); - logOutput = SDL_LogOutputFunction.create((userdata, category, priority, message) -> { + Logger logger = LoggerFactory.getLogger("SDL3"); + logOutput = SDL_LogOutputFunction.create((_, category, priority, message) -> { String text = MemoryUtil.memUTF8(message); if (priority >= SDLLog.SDL_LOG_PRIORITY_ERROR) { - logger.error("{}", text); + logger.error("[{}] {}", category, text); } else if (priority == SDLLog.SDL_LOG_PRIORITY_WARN) { - logger.warn("{}", text); + logger.warn("[{}] {}", category, text); } else if (priority == SDLLog.SDL_LOG_PRIORITY_INFO) { - logger.info("{}", text); + logger.info("[{}] {}", category, text); } else { - logger.debug("{}", text); + logger.debug("[{}] {}", category, text); } }); SDLLog.SDL_SetLogOutputFunction(logOutput, 0L); From 86e0ee8376028e8d671bd5b67f44c3542c5f046c Mon Sep 17 00:00:00 2001 From: Rongmario Date: Wed, 19 Aug 2026 23:24:38 +0100 Subject: [PATCH 78/99] Would you look at that, SDL3 also reports system themes --- .../cleanroommc/client/sdl/SystemTheme.java | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SystemTheme.java diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SystemTheme.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SystemTheme.java new file mode 100644 index 000000000..440d61e7e --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SystemTheme.java @@ -0,0 +1,68 @@ +package com.cleanroommc.client.sdl; + +import org.lwjgl.sdl.SDLVideo; + +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +/** Light/dark preference reported by the desktop environment. Requires the video subsystem. */ +public enum SystemTheme { + + UNKNOWN(SDLVideo.SDL_SYSTEM_THEME_UNKNOWN), + LIGHT(SDLVideo.SDL_SYSTEM_THEME_LIGHT), + DARK(SDLVideo.SDL_SYSTEM_THEME_DARK); + + /** Notified from the window pump when the desktop theme changes. */ + public interface Listener { + + void themeChanged(SystemTheme theme); + + } + + private static final List LISTENERS = new CopyOnWriteArrayList<>(); + + public static void listen(Listener listener) { + if (listener != null && !LISTENERS.contains(listener)) { + LISTENERS.add(listener); + } + } + + public static void mute(Listener listener) { + LISTENERS.remove(listener); + } + + /** Called from the window pump when {@code SDL_EVENT_SYSTEM_THEME_CHANGED} arrives. */ + public static void changed() { + SystemTheme theme = current(); + for (Listener listener : LISTENERS) { + listener.themeChanged(theme); + } + } + + /** @return the current desktop theme, or {@link #UNKNOWN} when the platform does not report one */ + public static SystemTheme current() { + SDL.ensureVideo(); + int theme = SDLVideo.SDL_GetSystemTheme(); + for (SystemTheme candidate : values()) { + if (candidate.value == theme) { + return candidate; + } + } + return UNKNOWN; + } + + private final int value; + + SystemTheme(int value) { + this.value = value; + } + + public int value() { + return value; + } + + public boolean dark() { + return this == DARK; + } + +} From 944d84b4bd783169ab3de87e76792995e5539455 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Wed, 19 Aug 2026 23:36:13 +0100 Subject: [PATCH 79/99] Flashing, progress bar, theme changes - through SDL3 --- .../cleanroommc/client/LoadingTracker.java | 42 +-- .../cleanroommc/client/sdl/SystemTheme.java | 22 +- .../com/cleanroommc/client/sdl/Window.java | 15 +- .../client/sdl/WindowListener.java | 8 +- .../cleanroommc/client/windows/DwmApi.java | 6 +- .../client/windows/TaskbarApi.java | 270 ------------------ .../client/windows/WindowsProperties.java | 8 + .../client/windows/WindowsTheme.java | 38 --- .../client/ForgeClientHandler.java | 23 +- .../client/ForgeHooksClient.java | 79 +++-- 10 files changed, 122 insertions(+), 389 deletions(-) delete mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/windows/TaskbarApi.java delete mode 100644 module/cleanroom/src/main/java/com/cleanroommc/client/windows/WindowsTheme.java diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/LoadingTracker.java b/module/cleanroom/src/main/java/com/cleanroommc/client/LoadingTracker.java index 05eb3bca6..185b592ae 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/LoadingTracker.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/LoadingTracker.java @@ -3,10 +3,7 @@ import java.io.*; import java.util.*; -import com.cleanroommc.client.windows.TaskbarApi; -import com.cleanroommc.client.windows.WindowsProperties; -import com.sun.jna.platform.win32.WinDef.HWND; - +import com.cleanroommc.client.sdl.Window; import net.minecraft.launchwrapper.Launch; import net.minecraftforge.common.ForgeEarlyConfig; import net.minecraftforge.fml.common.FMLLog; @@ -14,8 +11,6 @@ import net.minecraftforge.fml.common.ProgressManager; import net.minecraftforge.fml.common.ProgressManager.ProgressBar; -import org.apache.commons.lang3.SystemUtils; - public class LoadingTracker { private static final int MAX_PROGRESS = 10000; @@ -162,10 +157,9 @@ public static void init() { }); if (ForgeEarlyConfig.MODERN_WINDOWS_STYLES.UPDATE_WINDOWS_TASKBAR_PROGRESS) { - setTaskbarState(TaskbarApi.TBPFLAG.TBPF_NORMAL); - updateTaskbar(0); + setWindowProgress(Window.Progress.NORMAL, 0.0F); } else { - setTaskbarState(TaskbarApi.TBPFLAG.TBPF_INDETERMINATE); + setWindowProgress(Window.Progress.INDETERMINATE, 0.0F); } } @@ -176,7 +170,7 @@ public static void finish() { endPhaseTimer(currentPhase); } - updateTaskbar(MAX_PROGRESS); + setWindowProgress(Window.Progress.NORMAL, 1.0F); saveHistory(); initialized = false; @@ -265,7 +259,9 @@ private static void updateProgress(Phase phase, double subProgress) { if (progress > lastProgress) { lastProgress = progress; - updateTaskbar(progress); + if (ForgeEarlyConfig.MODERN_WINDOWS_STYLES.UPDATE_WINDOWS_TASKBAR_PROGRESS) { + setWindowProgress(Window.Progress.NORMAL, progress / (float) MAX_PROGRESS); + } } } @@ -276,27 +272,15 @@ private static void endPhaseTimer(Phase phase) { } } - private static void setTaskbarState(TaskbarApi.TBPFLAG flag) { - if (!SystemUtils.IS_OS_WINDOWS) return; - TaskbarApi api = TaskbarApi.getInstance(); - if (api == null || WindowsProperties.handle == Long.MIN_VALUE) return; - try { - HWND hwnd = TaskbarApi.hwnd(WindowsProperties.handle); - api.setProgressState(hwnd, flag); - } catch (Throwable t) { - FMLLog.log.debug("LoadingTracker: Failed to set taskbar state", t); + private static void setWindowProgress(Window.Progress state, float value) { + Window window = Window.main(); + if (window == null) { + return; } - } - - private static void updateTaskbar(int progress) { - if (!SystemUtils.IS_OS_WINDOWS || !ForgeEarlyConfig.MODERN_WINDOWS_STYLES.UPDATE_WINDOWS_TASKBAR_PROGRESS) return; - TaskbarApi api = TaskbarApi.getInstance(); - if (api == null || WindowsProperties.handle == Long.MIN_VALUE) return; try { - HWND hwnd = TaskbarApi.hwnd(WindowsProperties.handle); - api.setProgressValue(hwnd, progress, MAX_PROGRESS); + window.progress(state, value); } catch (Throwable t) { - FMLLog.log.debug("LoadingTracker: Failed to update taskbar progress", t); + FMLLog.log.debug("LoadingTracker: Failed to set window progress", t); } } diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SystemTheme.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SystemTheme.java index 440d61e7e..7e0599703 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SystemTheme.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SystemTheme.java @@ -12,7 +12,17 @@ public enum SystemTheme { LIGHT(SDLVideo.SDL_SYSTEM_THEME_LIGHT), DARK(SDLVideo.SDL_SYSTEM_THEME_DARK); - /** Notified from the window pump when the desktop theme changes. */ + private final int value; + + SystemTheme(int value) { + this.value = value; + } + + public int value() { + return value; + } + + @FunctionalInterface public interface Listener { void themeChanged(SystemTheme theme); @@ -51,16 +61,6 @@ public static SystemTheme current() { return UNKNOWN; } - private final int value; - - SystemTheme(int value) { - this.value = value; - } - - public int value() { - return value; - } - public boolean dark() { return this == DARK; } diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Window.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Window.java index 516f775b2..d55943a05 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Window.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Window.java @@ -263,6 +263,7 @@ public synchronized Window borderless(boolean borderless) { this.ensureOpen(); SDL.check(SDLVideo.SDL_SetWindowBordered(this.handle, !borderless), "SDL_SetWindowBordered"); this.borderless = borderless; + notifyListeners(listener -> listener.borderlessChanged(borderless)); return this; } @@ -386,8 +387,7 @@ public synchronized Window progress(Progress state, float value) { } SDL.check(SDLVideo.SDL_SetWindowProgressState(this.handle, state.value), "SDL_SetWindowProgressState"); if (state != Progress.NONE && state != Progress.INDETERMINATE) { - SDL.check(SDLVideo.SDL_SetWindowProgressValue(this.handle, Math.max(0.0F, Math.min(1.0F, value))), - "SDL_SetWindowProgressValue"); + SDL.check(SDLVideo.SDL_SetWindowProgressValue(this.handle, Math.clamp(value, 0.0F, 1.0F)), "SDL_SetWindowProgressValue"); } return this; } @@ -577,6 +577,7 @@ private void dispatch(SDL_Event event) { SDLEvents.SDL_EVENT_WINDOW_ENTER_FULLSCREEN, SDLEvents.SDL_EVENT_WINDOW_LEAVE_FULLSCREEN -> window(type, event.window()); case SDLEvents.SDL_EVENT_CLIPBOARD_UPDATE -> Clipboard.updated(); + case SDLEvents.SDL_EVENT_SYSTEM_THEME_CHANGED -> SystemTheme.changed(); case SDLEvents.SDL_EVENT_DROP_FILE, SDLEvents.SDL_EVENT_DROP_TEXT, SDLEvents.SDL_EVENT_DROP_BEGIN, @@ -706,8 +707,14 @@ private void window(int type, SDL_WindowEvent event) { case SDLEvents.SDL_EVENT_WINDOW_DISPLAY_CHANGED -> notifyListeners(WindowListener::displayChanged); case SDLEvents.SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED -> notifyListeners(listener -> listener.scaleChanged(SDLVideo.SDL_GetWindowDisplayScale(this.handle))); - case SDLEvents.SDL_EVENT_WINDOW_ENTER_FULLSCREEN -> this.fullscreen = true; - case SDLEvents.SDL_EVENT_WINDOW_LEAVE_FULLSCREEN -> this.fullscreen = false; + case SDLEvents.SDL_EVENT_WINDOW_ENTER_FULLSCREEN -> { + this.fullscreen = true; + notifyListeners(listener -> listener.fullscreenChanged(true)); + } + case SDLEvents.SDL_EVENT_WINDOW_LEAVE_FULLSCREEN -> { + this.fullscreen = false; + notifyListeners(listener -> listener.fullscreenChanged(false)); + } } } diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/WindowListener.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/WindowListener.java index b7df25c98..fafa33aa2 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/WindowListener.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/WindowListener.java @@ -1,7 +1,9 @@ package com.cleanroommc.client.sdl; /** - * Host-window notifications. Called from {@link Window#pump()} on the thread that pumps. + * Host-window notifications. Called from {@link Window#pump()} on the thread that pumps, except + * {@link #borderlessChanged(boolean)}, which fires from {@link Window#borderless(boolean)} because SDL + * reports no event for it. */ public interface WindowListener { @@ -15,4 +17,8 @@ default void displayChanged() { } default void scaleChanged(float scale) { } + default void fullscreenChanged(boolean fullscreen) { } + + default void borderlessChanged(boolean borderless) { } + } diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/windows/DwmApi.java b/module/cleanroom/src/main/java/com/cleanroommc/client/windows/DwmApi.java index 4d3d2e4fc..6ecfd62c9 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/windows/DwmApi.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/windows/DwmApi.java @@ -1,7 +1,7 @@ /// Copyright under MIT https://github.com/LemonCaramel/Mica package com.cleanroommc.client.windows; -import com.cleanroommc.client.windows.WindowsProperties; +import com.cleanroommc.client.sdl.SystemTheme; import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.Pointer; @@ -96,14 +96,14 @@ static void updateDwm(final boolean fullscreen, final long window) { return; } - final HWND hwnd = TaskbarApi.hwnd(window); + final HWND hwnd = WindowsProperties.hwnd(window); if (fullscreen) { DwmApi.disableWindowEffect(hwnd); return; } // DWMWA_USE_IMMERSIVE_DARK_MODE - final boolean useImmersiveDarkMode = ForgeEarlyConfig.MODERN_WINDOWS_STYLES.USE_IMMERSIVE_DARK_MODE && WindowsTheme.isAppsDarkTheme(); + final boolean useImmersiveDarkMode = ForgeEarlyConfig.MODERN_WINDOWS_STYLES.USE_IMMERSIVE_DARK_MODE && SystemTheme.current().dark(); INSTANCE.DwmSetWindowAttribute(hwnd, DWMWA_USE_IMMERSIVE_DARK_MODE, new IntByReference(useImmersiveDarkMode ? BOOL_TRUE : BOOL_FALSE), INT_SIZE); // DWMWA_SYSTEMBACKDROP_TYPE diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/windows/TaskbarApi.java b/module/cleanroom/src/main/java/com/cleanroommc/client/windows/TaskbarApi.java deleted file mode 100644 index 56cbcfaac..000000000 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/windows/TaskbarApi.java +++ /dev/null @@ -1,270 +0,0 @@ -package com.cleanroommc.client.windows; - -import com.sun.jna.Function; -import com.sun.jna.Native; -import com.sun.jna.Pointer; -import com.sun.jna.Structure; -import com.sun.jna.WString; -import com.sun.jna.platform.win32.WinDef; -import com.sun.jna.ptr.PointerByReference; -import com.sun.jna.platform.win32.Guid.GUID; -import com.sun.jna.platform.win32.WinDef.HICON; -import com.sun.jna.platform.win32.WinDef.HWND; -import com.sun.jna.platform.win32.WinNT.HRESULT; -import com.sun.jna.win32.StdCallLibrary; -import com.sun.jna.win32.W32APIOptions; -import java.util.List; - -public final class TaskbarApi implements AutoCloseable { - private TaskbarApi(Pointer raw, boolean needCoUninitialize) { - this.raw = raw; - this.needCoUninitialize = needCoUninitialize; - } - - private final Pointer raw; - private final boolean needCoUninitialize; - private boolean closed; - - private static final GUID CLSID_TASKBAR_LIST = - new GUID("{56FDF344-FD6D-11d0-958A-006097C9A090}"); - private static final GUID IID_ITASKBAR_LIST3 = - new GUID("{EA1AFB91-9E28-4B86-90E9-9E9F8A5EEFAF}"); - - private static final int CLSCTX_INPROC_SERVER = 0x1; - private static final int COINIT_APARTMENTTHREADED = 0x2; - private static final int RPC_E_CHANGED_MODE = 0x80010106; - - // IUnknown - private static final int VTBL_QUERY_INTERFACE = 0; - private static final int VTBL_ADD_REF = 1; - private static final int VTBL_RELEASE = 2; - - // ITaskbarList - private static final int VTBL_HR_INIT = 3; - - // ITaskbarList3 - private static final int VTBL_SET_PROGRESS_VALUE = 9; - private static final int VTBL_SET_PROGRESS_STATE = 10; - private static final int VTBL_SET_OVERLAY_ICON = 18; - - private static TaskbarApi INSTANCE; - - public static TaskbarApi getInstance() { - return INSTANCE; - } - - public enum TBPFLAG { - TBPF_NOPROGRESS(0x00000000), - TBPF_INDETERMINATE(0x00000001), - TBPF_NORMAL(0x00000002), - TBPF_ERROR(0x00000004), - TBPF_PAUSED(0x00000008); - - public final int value; - - TBPFLAG(int value) { - this.value = value; - } - } - - public static TaskbarApi create() { - HRESULT hrInit = Ole32Ex.INSTANCE.CoInitializeEx(Pointer.NULL, COINIT_APARTMENTTHREADED); - int initCode = hrInit.intValue(); - - // S_OK = 0, S_FALSE = 1, RPC_E_CHANGED_MODE = 0x80010106 - if (initCode != 0 && initCode != 1 && initCode != RPC_E_CHANGED_MODE) { - throw new IllegalStateException("CoInitializeEx failed: 0x" + hex(initCode)); - } - - boolean needCoUninitialize = (initCode == 0 || initCode == 1); - - PointerByReference ppv = new PointerByReference(); - HRESULT hr = Ole32Ex.INSTANCE.CoCreateInstance( - CLSID_TASKBAR_LIST, - Pointer.NULL, - CLSCTX_INPROC_SERVER, - IID_ITASKBAR_LIST3, - ppv - ); - checkHR(hr, "CoCreateInstance(CLSID_TaskbarList, IID_ITaskbarList3)"); - - TaskbarApi api = new TaskbarApi(ppv.getValue(), needCoUninitialize); - api.hrInit(); - INSTANCE = api; - return api; - } - - /** Converts an operating-system window handle to JNA's HWND wrapper. */ - public static HWND hwnd(long nativeWindow) { - return new HWND(Pointer.createConstant(nativeWindow)); - } - - public void hrInit() { - checkHR(invokeHRESULT(VTBL_HR_INIT), "ITaskbarList::HrInit"); - } - - public void setProgressState(HWND hwnd, TBPFLAG state) { - checkHR(invokeHRESULT(VTBL_SET_PROGRESS_STATE, hwnd, state.value), - "ITaskbarList3::SetProgressState"); - } - - public void setProgressValue(HWND hwnd, long completed, long total) { - checkHR(invokeHRESULT(VTBL_SET_PROGRESS_VALUE, hwnd, completed, total), - "ITaskbarList3::SetProgressValue"); - } - - public void clearProgress(HWND hwnd) { - setProgressState(hwnd, TBPFLAG.TBPF_NOPROGRESS); - } - - public void setOverlayIcon(HWND hwnd, HICON hIcon, String description) { - checkHR(invokeHRESULT( - VTBL_SET_OVERLAY_ICON, - hwnd, - hIcon, - description == null ? null : new WString(description) - ), - "ITaskbarList3::SetOverlayIcon"); - } - - public void clearOverlayIcon(HWND hwnd) { - setOverlayIcon(hwnd, null, null); - } - - public int addRef() { - return invokeInt(VTBL_ADD_REF); - } - - public int release() { - return invokeInt(VTBL_RELEASE); - } - - @Override - public void close() { - if (closed) { - return; - } - closed = true; - - try { - release(); - } finally { - if (needCoUninitialize) { - Ole32Ex.INSTANCE.CoUninitialize(); - } - } - } - - public static boolean flashTaskbar(HWND hwnd, int count) { - User32Ex.FLASHWINFO info = new User32Ex.FLASHWINFO(); - info.hwnd = hwnd; - info.dwFlags = User32Ex.FLASHW_TRAY; - info.uCount = count; - info.dwTimeout = 0; - return User32Ex.INSTANCE.FlashWindowEx(info); - } - - public static boolean flashTaskbarUntilForeground(long window) { - final WinDef.HWND hwnd = hwnd(window); - User32Ex.FLASHWINFO info = new User32Ex.FLASHWINFO(); - info.hwnd = hwnd; - info.dwFlags = User32Ex.FLASHW_TRAY | User32Ex.FLASHW_TIMERNOFG; - info.uCount = 0; - info.dwTimeout = 0; - return User32Ex.INSTANCE.FlashWindowEx(info); - } - - public static boolean stopFlash(HWND hwnd) { - User32Ex.FLASHWINFO info = new User32Ex.FLASHWINFO(); - info.hwnd = hwnd; - info.dwFlags = User32Ex.FLASHW_STOP; - info.uCount = 0; - info.dwTimeout = 0; - return User32Ex.INSTANCE.FlashWindowEx(info); - } - - public static void clearInstance() { - TaskbarApi old = INSTANCE; - INSTANCE = null; - if (old != null) { - old.close(); - } - } - - private HRESULT invokeHRESULT(int vtblIndex, Object... args) { - Pointer vtbl = raw.getPointer(0); - Pointer fnPtr = vtbl.getPointer((long) vtblIndex * Native.POINTER_SIZE); - Function fn = Function.getFunction(fnPtr, Function.ALT_CONVENTION); - - Object[] fullArgs = new Object[args.length + 1]; - fullArgs[0] = raw; - System.arraycopy(args, 0, fullArgs, 1, args.length); - - return (HRESULT) fn.invoke(HRESULT.class, fullArgs); - } - - private int invokeInt(int vtblIndex, Object... args) { - Pointer vtbl = raw.getPointer(0); - Pointer fnPtr = vtbl.getPointer((long) vtblIndex * Native.POINTER_SIZE); - Function fn = Function.getFunction(fnPtr, Function.ALT_CONVENTION); - - Object[] fullArgs = new Object[args.length + 1]; - fullArgs[0] = raw; - System.arraycopy(args, 0, fullArgs, 1, args.length); - - return fn.invokeInt(fullArgs); - } - - private static void checkHR(HRESULT hr, String action) { - int code = hr.intValue(); - if (code < 0) { - throw new IllegalStateException(action + " failed: 0x" + hex(code)); - } - } - - private static String hex(int value) { - return String.format("%08X", value); - } - - public interface Ole32Ex extends StdCallLibrary { - Ole32Ex INSTANCE = Native.load("ole32", Ole32Ex.class, W32APIOptions.DEFAULT_OPTIONS); - - HRESULT CoInitializeEx(Pointer pvReserved, int dwCoInit); - - void CoUninitialize(); - - HRESULT CoCreateInstance( - GUID rclsid, - Pointer pUnkOuter, - int dwClsContext, - GUID riid, - PointerByReference ppv - ); - } - - public interface User32Ex extends StdCallLibrary { - User32Ex INSTANCE = Native.load("user32", User32Ex.class, W32APIOptions.DEFAULT_OPTIONS); - - int FLASHW_STOP = 0x00000000; - int FLASHW_CAPTION = 0x00000001; - int FLASHW_TRAY = 0x00000002; - int FLASHW_ALL = FLASHW_CAPTION | FLASHW_TRAY; - int FLASHW_TIMER = 0x00000004; - int FLASHW_TIMERNOFG = 0x0000000C; - - boolean FlashWindowEx(FLASHWINFO info); - - class FLASHWINFO extends Structure { - public int cbSize = size(); - public HWND hwnd; - public int dwFlags; - public int uCount; - public int dwTimeout; - - @Override - protected List getFieldOrder() { - return List.of("cbSize", "hwnd", "dwFlags", "uCount", "dwTimeout"); - } - } - } -} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/windows/WindowsProperties.java b/module/cleanroom/src/main/java/com/cleanroommc/client/windows/WindowsProperties.java index ef03781ce..c396a8bde 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/windows/WindowsProperties.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/windows/WindowsProperties.java @@ -1,6 +1,9 @@ /// Copyright under MIT https://github.com/LemonCaramel/Mica package com.cleanroommc.client.windows; +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.WinDef.HWND; + public class WindowsProperties { public static final int MINIMUM_BUILD_NUM = 22000; public static final int BACKDROP_BUILD_NUM = 22621; @@ -18,4 +21,9 @@ public class WindowsProperties { public static boolean checkCompatibility() { return (WindowsProperties.majorVersion >= 10 && WindowsProperties.buildNumber >= WindowsProperties.MINIMUM_BUILD_NUM); } + + /** Converts an operating-system window handle to JNA's HWND wrapper. */ + public static HWND hwnd(long nativeWindow) { + return new HWND(Pointer.createConstant(nativeWindow)); + } } diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/windows/WindowsTheme.java b/module/cleanroom/src/main/java/com/cleanroommc/client/windows/WindowsTheme.java deleted file mode 100644 index bf3ffd62e..000000000 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/windows/WindowsTheme.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.cleanroommc.client.windows; - -import com.sun.jna.platform.win32.Advapi32Util; -import com.sun.jna.platform.win32.WinReg; - -public class WindowsTheme { - private static final String PERSONALIZE_KEY = - "Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"; - - private static final String APPS_USE_LIGHT_THEME = "AppsUseLightTheme"; - - private WindowsTheme() { - } - - private static boolean isAppsUseLightTheme() { - try { - if (!Advapi32Util.registryValueExists( - WinReg.HKEY_CURRENT_USER, - PERSONALIZE_KEY, - APPS_USE_LIGHT_THEME)) { - return true; - } - - int value = Advapi32Util.registryGetIntValue( - WinReg.HKEY_CURRENT_USER, - PERSONALIZE_KEY, - APPS_USE_LIGHT_THEME); - - return value != 0; - } catch (Throwable t) { - return true; - } - } - - public static boolean isAppsDarkTheme() { - return !isAppsUseLightTheme(); - } -} diff --git a/module/forge/src/main/java/net/minecraftforge/client/ForgeClientHandler.java b/module/forge/src/main/java/net/minecraftforge/client/ForgeClientHandler.java index d29b0110f..f6f14454f 100644 --- a/module/forge/src/main/java/net/minecraftforge/client/ForgeClientHandler.java +++ b/module/forge/src/main/java/net/minecraftforge/client/ForgeClientHandler.java @@ -25,8 +25,6 @@ import com.cleanroommc.client.modlist.ModListConfig; import com.cleanroommc.client.modlist.ModListConstants; import com.cleanroommc.client.modlist.screen.ModListScreen; -import com.cleanroommc.client.windows.TaskbarApi; -import com.cleanroommc.client.windows.WindowsProperties; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiMainMenu; import net.minecraft.client.gui.GuiScreen; @@ -35,7 +33,6 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntityFurnace; -import net.minecraft.util.Util; import net.minecraft.util.text.TextFormatting; import net.minecraft.util.text.translation.I18n; import net.minecraftforge.client.event.ColorHandlerEvent; @@ -58,6 +55,7 @@ public class ForgeClientHandler { private static boolean played = false; + @SubscribeEvent public static void registerModels(ModelRegistryEvent event) { @@ -124,16 +122,23 @@ public static void onConfigChanged(OnConfigChangedEvent event) @SubscribeEvent(priority = EventPriority.LOWEST) public static void onGuiOpenLast(GuiOpenEvent event) { - if (Util.getOSType().equals(Util.EnumOS.WINDOWS)) + if (event.getGui() instanceof GuiMainMenu && !played) { - if (event.getGui() instanceof GuiMainMenu && !played) + played = true; + if (ForgeEarlyConfig.MODERN_WINDOWS_STYLES.DISABLE_FLASH_AFTER_LOADED) + { + return; + } + Window window = Window.main(); + if (window != null) { - if (WindowsProperties.handle == Long.MIN_VALUE) return; - if (!ForgeEarlyConfig.MODERN_WINDOWS_STYLES.DISABLE_FLASH_AFTER_LOADED) + try + { + window.flash(Window.Flash.UNTIL_FOCUSED); + } + catch (RuntimeException ignored) { - TaskbarApi.flashTaskbarUntilForeground(WindowsProperties.handle); } - played = true; } } } diff --git a/module/forge/src/main/java/net/minecraftforge/client/ForgeHooksClient.java b/module/forge/src/main/java/net/minecraftforge/client/ForgeHooksClient.java index 6329a9cc1..121e5bf33 100644 --- a/module/forge/src/main/java/net/minecraftforge/client/ForgeHooksClient.java +++ b/module/forge/src/main/java/net/minecraftforge/client/ForgeHooksClient.java @@ -38,10 +38,11 @@ import javax.vecmath.Vector4f; import com.cleanroommc.client.LoadingTracker; +import com.cleanroommc.client.sdl.SystemTheme; import com.cleanroommc.client.sdl.Window; +import com.cleanroommc.client.sdl.WindowListener; import com.cleanroommc.client.windows.DwmApi; import com.cleanroommc.client.windows.NtDll; -import com.cleanroommc.client.windows.TaskbarApi; import com.cleanroommc.client.windows.WindowsProperties; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; @@ -986,49 +987,79 @@ public static void invalidateLog4jThreadCache() } } + private static boolean styleListenersRegistered = false; + public static void setWindowStyle(boolean isFullScreen) { if (SystemUtils.IS_OS_WINDOWS) { + listenForStyleChanges(); DwmApi.updateDwm(isFullScreen, WindowsProperties.handle); } } + /** Re-applies the window style from the window's own state. */ + private static void updateWindowStyle() { + Window window = Window.main(); + setWindowStyle(window != null && window.fullscreen()); + } + + /** + * Re-applies the window style whenever the desktop switches between light and dark, or the window enters + * or leaves fullscreen, so the title bar keeps following the system theme without a restart. + */ + private static void listenForStyleChanges() { + if (styleListenersRegistered) { + return; + } + styleListenersRegistered = true; + SystemTheme.listen(_ -> updateWindowStyle()); + Window window = Window.main(); + if (window != null) { + window.listen(new WindowListener() { + + @Override + public void fullscreenChanged(boolean fullscreen) { + setWindowStyle(fullscreen); + } + + @Override + public void borderlessChanged(boolean borderless) { + updateWindowStyle(); + } + + }); + } + } + public static void initializeWindowsInformation() { if (SystemUtils.IS_OS_WINDOWS) { Window window = Window.main(); if (window != null) { - NtDll.initializeWindowsInformation(window.nativeHandle()); + com.cleanroommc.client.sdl.NativeWindow nativeWindow = window.nativeWindow(); + if (nativeWindow.compositor() == com.cleanroommc.client.sdl.Compositor.WIN32) { + NtDll.initializeWindowsInformation(nativeWindow.handle()); + } else { + NtDll.initializeWindowsInformation(window.nativeHandle()); + } } } } public static void initializeTaskbarAPI() { - if (SystemUtils.IS_OS_WINDOWS) { - try { - TaskbarApi.create(); - } catch (Throwable t) { - FMLLog.log.error("Unable to initialize Taskbar API", t); - TaskbarApi.clearInstance(); - } - } LoadingTracker.init(); } - public static void shutdownTaskbarAPI() { - TaskbarApi api = TaskbarApi.getInstance(); - if (api != null) { - api.close(); - TaskbarApi.clearInstance(); - } - } - public static void clearTaskbarProgress() { LoadingTracker.finish(); - if (SystemUtils.IS_OS_WINDOWS) { - var taskbar = TaskbarApi.getInstance(); - if (taskbar != null) { - taskbar.clearProgress(TaskbarApi.hwnd(WindowsProperties.handle)); - } else { - FMLLog.log.error("Unable to clear taskbar progress, cannot invoke a null object."); + Window window = Window.main(); + if (window != null) + { + try + { + window.progress(Window.Progress.NONE); + } + catch (RuntimeException e) + { + FMLLog.log.debug("Unable to clear taskbar progress", e); } } } From a9e071a6eb6f4192d3779e38559ad0f7e83f0d5a Mon Sep 17 00:00:00 2001 From: Rongmario Date: Wed, 19 Aug 2026 23:48:30 +0100 Subject: [PATCH 80/99] Clipboard + open link replacement in GuiScreen --- .../minecraft/client/gui/GuiScreen.java.patch | 70 ++++++++++++++++--- 1 file changed, 61 insertions(+), 9 deletions(-) diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiScreen.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiScreen.java.patch index e4c7c1757..79bad91ab 100644 --- a/module/minecraft/patches/net/minecraft/client/gui/GuiScreen.java.patch +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiScreen.java.patch @@ -1,6 +1,17 @@ --- original/net/minecraft/client/gui/GuiScreen.java +++ modified/net/minecraft/client/gui/GuiScreen.java -@@ -68,6 +68,7 @@ +@@ -3,10 +3,6 @@ + import com.google.common.base.Splitter; + import com.google.common.collect.Lists; + import com.google.common.collect.Sets; +-import java.awt.Toolkit; +-import java.awt.datatransfer.DataFlavor; +-import java.awt.datatransfer.StringSelection; +-import java.awt.datatransfer.Transferable; + import java.io.File; + import java.io.IOException; + import java.net.URI; +@@ -68,6 +64,7 @@ private int touchValue; private URI clickedLinkURI; private boolean focused; @@ -8,7 +19,32 @@ /** Draws the screen and all the components in it. */ public void drawScreen(int mouseX, int mouseY, float partialTicks) { -@@ -127,7 +128,10 @@ +@@ -104,30 +101,21 @@ + + /** Returns a string stored in the system clipboard. */ + public static String getClipboardString() { +- try { +- Transferable transferable = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null); +- if (transferable != null && transferable.isDataFlavorSupported(DataFlavor.stringFlavor)) { +- return (String)transferable.getTransferData(DataFlavor.stringFlavor); +- } +- } catch (Exception exception) { +- } +- +- return ""; ++ return com.cleanroommc.client.sdl.Clipboard.text(); + } + + /** Stores the given string in the system clipboard */ + public static void setClipboardString(String copyText) { + if (!StringUtils.isEmpty(copyText)) { +- try { +- StringSelection stringselection = new StringSelection(copyText); +- Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringselection, null); +- } catch (Exception exception) { +- } ++ com.cleanroommc.client.sdl.Clipboard.text(copyText); + } } protected void renderToolTip(ItemStack stack, int x, int y) { @@ -20,7 +56,7 @@ } public List getItemToolTip(ItemStack p_191927_1_) { -@@ -138,7 +142,7 @@ +@@ -138,7 +126,7 @@ for (int i = 0; i < list.size(); i++) { if (i == 0) { @@ -29,7 +65,7 @@ } else { list.set(i, TextFormatting.GRAY + list.get(i)); } -@@ -162,7 +166,12 @@ +@@ -162,7 +150,12 @@ /** Draws a List of strings as a tooltip. Every entry is drawn on a seperate line. */ public void drawHoveringText(List textLines, int x, int y) { @@ -43,7 +79,7 @@ GlStateManager.disableRescaleNormal(); RenderHelper.disableStandardItemLighting(); GlStateManager.disableLighting(); -@@ -339,9 +348,12 @@ +@@ -339,9 +332,12 @@ } public void sendChatMessage(String msg, boolean addToChat) { @@ -56,7 +92,7 @@ this.mc.player.sendChatMessage(msg); } -@@ -352,9 +364,15 @@ +@@ -352,9 +348,15 @@ for (int i = 0; i < this.buttonList.size(); i++) { GuiButton guibutton = this.buttonList.get(i); if (guibutton.mousePressed(this.mc, mouseX, mouseY)) { @@ -72,7 +108,7 @@ } } } -@@ -383,8 +401,11 @@ +@@ -383,8 +385,11 @@ this.fontRenderer = mc.fontRenderer; this.width = width; this.height = height; @@ -84,7 +120,7 @@ } /** Set the gui to the specified width and height */ -@@ -401,13 +422,19 @@ +@@ -401,13 +406,19 @@ public void handleInput() throws IOException { if (Mouse.isCreated()) { while (Mouse.next()) { @@ -104,7 +140,7 @@ } } } -@@ -465,6 +492,7 @@ +@@ -465,6 +476,7 @@ */ public void drawDefaultBackground() { this.drawWorldBackground(0); @@ -112,3 +148,19 @@ } /** +@@ -532,14 +544,7 @@ + } + + private void openWebLink(URI url) { +- try { +- Class oclass = Class.forName("java.awt.Desktop"); +- Object object = oclass.getMethod("getDesktop").invoke(null); +- oclass.getMethod("browse", URI.class).invoke(object, url); +- } catch (Throwable throwable1) { +- Throwable throwable = throwable1.getCause(); +- LOGGER.error("Couldn't open link: {}", throwable == null ? "" : throwable.getMessage()); +- } ++ com.cleanroommc.client.sdl.Desktop.open(url); + } + + /** Returns true if either windows ctrl key is down or if either mac meta key is down */ From 2407bf4973b4c82108a4b32e8aa09b1c123c69a4 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Wed, 19 Aug 2026 23:50:53 +0100 Subject: [PATCH 81/99] setIcon + error dialog on crash + fullscreen + borderless --- .../net/minecraft/client/Minecraft.java.patch | 134 ++++++++++++++---- 1 file changed, 108 insertions(+), 26 deletions(-) diff --git a/module/minecraft/patches/net/minecraft/client/Minecraft.java.patch b/module/minecraft/patches/net/minecraft/client/Minecraft.java.patch index 2f5467ff6..5ed5b0d2b 100644 --- a/module/minecraft/patches/net/minecraft/client/Minecraft.java.patch +++ b/module/minecraft/patches/net/minecraft/client/Minecraft.java.patch @@ -1,6 +1,48 @@ --- original/net/minecraft/client/Minecraft.java +++ modified/net/minecraft/client/Minecraft.java -@@ -363,6 +363,7 @@ +@@ -37,9 +37,8 @@ + import java.util.stream.Collectors; + import javax.annotation.Nullable; + import javax.imageio.ImageIO; +-import net.minecraft.block.Block; ++ + import net.minecraft.block.material.Material; +-import net.minecraft.block.state.IBlockState; + import net.minecraft.client.audio.MusicTicker; + import net.minecraft.client.audio.SoundHandler; + import net.minecraft.client.entity.EntityPlayerSP; +@@ -66,7 +65,6 @@ + import net.minecraft.client.gui.recipebook.RecipeList; + import net.minecraft.client.gui.toasts.GuiToast; + import net.minecraft.client.main.GameConfiguration; +-import net.minecraft.client.multiplayer.GuiConnecting; + import net.minecraft.client.multiplayer.PlayerControllerMP; + import net.minecraft.client.multiplayer.ServerData; + import net.minecraft.client.multiplayer.WorldClient; +@@ -130,22 +128,11 @@ + import net.minecraft.crash.ICrashReportDetail; + import net.minecraft.creativetab.CreativeTabs; + import net.minecraft.entity.Entity; +-import net.minecraft.entity.EntityLeashKnot; +-import net.minecraft.entity.EntityList; +-import net.minecraft.entity.item.EntityArmorStand; +-import net.minecraft.entity.item.EntityBoat; +-import net.minecraft.entity.item.EntityEnderCrystal; +-import net.minecraft.entity.item.EntityItemFrame; +-import net.minecraft.entity.item.EntityMinecart; +-import net.minecraft.entity.item.EntityPainting; + import net.minecraft.entity.player.EntityPlayer; +-import net.minecraft.entity.player.InventoryPlayer; + import net.minecraft.init.Bootstrap; + import net.minecraft.init.Items; + import net.minecraft.item.Item; +-import net.minecraft.item.ItemMonsterPlacer; + import net.minecraft.item.ItemStack; +-import net.minecraft.item.crafting.IRecipe; + import net.minecraft.nbt.NBTTagCompound; + import net.minecraft.nbt.NBTTagList; + import net.minecraft.nbt.NBTTagString; +@@ -363,6 +350,7 @@ public Minecraft(GameConfiguration gameConfig) { instance = this; @@ -8,7 +50,7 @@ this.gameDir = gameConfig.folderInfo.gameDir; this.fileAssets = gameConfig.folderInfo.assetsDir; this.fileResourcepacks = gameConfig.folderInfo.resourcePacksDir; -@@ -375,7 +376,6 @@ +@@ -375,7 +363,6 @@ this.sessionService = new YggdrasilAuthenticationService(this.proxy, UUID.randomUUID().toString()).createMinecraftSessionService(); this.session = gameConfig.userInfo.session; LOGGER.info("Setting user: {}", this.session.getUsername()); @@ -16,7 +58,7 @@ this.isDemo = gameConfig.gameInfo.isDemo; this.displayWidth = gameConfig.displayInfo.width > 0 ? gameConfig.displayInfo.width : 1; this.displayHeight = gameConfig.displayInfo.height > 0 ? gameConfig.displayInfo.height : 1; -@@ -455,7 +455,8 @@ +@@ -455,7 +442,8 @@ this.displayWidth = this.gameSettings.overrideWidth; this.displayHeight = this.gameSettings.overrideHeight; } @@ -26,7 +68,7 @@ LOGGER.info("LWJGL Version: {}", Sys.getVersion()); this.setWindowIcon(); this.setInitialDisplayMode(); -@@ -470,10 +471,10 @@ +@@ -470,10 +458,10 @@ this.resourceManager = new SimpleReloadableResourceManager(this.metadataSerializer); this.languageManager = new LanguageManager(this.metadataSerializer, this.gameSettings.language); this.resourceManager.registerReloadListener(this.languageManager); @@ -39,7 +81,7 @@ this.skinManager = new SkinManager(this.renderEngine, new File(this.fileAssets, "skins"), this.sessionService); this.saveLoader = new AnvilSaveConverter(new File(this.gameDir, "saves"), this.dataFixer); this.soundHandler = new SoundHandler(this.resourceManager, this.gameSettings); -@@ -491,6 +492,8 @@ +@@ -491,6 +479,8 @@ this.resourceManager.registerReloadListener(new GrassColorReloadListener()); this.resourceManager.registerReloadListener(new FoliageColorReloadListener()); this.mouseHelper = new MouseHelper(); @@ -48,7 +90,7 @@ this.checkGLError("Pre startup"); GlStateManager.enableTexture2D(); GlStateManager.shadeModel(7425); -@@ -504,19 +507,24 @@ +@@ -504,19 +494,24 @@ GlStateManager.loadIdentity(); GlStateManager.matrixMode(5888); this.checkGLError("Startup"); @@ -73,7 +115,7 @@ this.entityRenderer = new EntityRenderer(this, this.resourceManager); this.resourceManager.registerReloadListener(this.entityRenderer); this.blockRenderDispatcher = new BlockRendererDispatcher(this.modelManager.getBlockModelShapes(), this.blockColors); -@@ -527,18 +535,25 @@ +@@ -527,18 +522,25 @@ this.resourceManager.registerReloadListener(this.searchTreeManager); GlStateManager.viewport(0, 0, this.displayWidth, this.displayHeight); this.effectRenderer = new ParticleManager(this.world, this.renderEngine); @@ -102,7 +144,7 @@ if (this.gameSettings.fullScreen && !this.fullscreen) { this.toggleFullscreen(); } -@@ -599,24 +614,12 @@ +@@ -599,34 +601,22 @@ private void createDisplay() throws LWJGLException { Display.setResizable(true); @@ -131,8 +173,33 @@ + net.minecraftforge.client.ForgeHooksClient.initializeTaskbarAPI(); } - private void setInitialDisplayMode() throws LWJGLException { -@@ -679,6 +682,7 @@ +- private void setInitialDisplayMode() throws LWJGLException { ++ private void setInitialDisplayMode() { ++ com.cleanroommc.client.sdl.Window window = com.cleanroommc.client.sdl.Window.main(); + if (this.fullscreen) { +- Display.setFullscreen(true); +- DisplayMode displaymode = Display.getDisplayMode(); +- this.displayWidth = Math.max(1, displaymode.getWidth()); +- this.displayHeight = Math.max(1, displaymode.getHeight()); ++ window.fullscreen(true); ++ this.displayWidth = window.width(); ++ this.displayHeight = window.height(); + } else { +- Display.setDisplayMode(new DisplayMode(this.displayWidth, this.displayHeight)); ++ window.size(this.displayWidth, this.displayHeight); + } + } + +@@ -640,7 +630,7 @@ + inputstream = this.defaultResourcePack.getInputStreamAssets(new ResourceLocation("icons/icon_16x16.png")); + inputstream1 = this.defaultResourcePack.getInputStreamAssets(new ResourceLocation("icons/icon_32x32.png")); + if (inputstream != null && inputstream1 != null) { +- Display.setIcon(new ByteBuffer[]{this.readImageToBuffer(inputstream), this.readImageToBuffer(inputstream1)}); ++ com.cleanroommc.client.sdl.Window window = com.cleanroommc.client.sdl.Window.main().icon(ImageIO.read(inputstream), ImageIO.read(inputstream1)); + } + } catch (IOException ioexception) { + LOGGER.error("Couldn't set icon", ioexception); +@@ -679,6 +669,7 @@ } private void startTimerHackThread() { @@ -140,7 +207,7 @@ Thread thread = new Thread("Timer hack thread") { @Override public void run() { -@@ -691,6 +695,7 @@ +@@ -691,6 +682,7 @@ } }; thread.setDaemon(true); @@ -148,7 +215,7 @@ thread.start(); } -@@ -704,22 +709,26 @@ +@@ -704,22 +696,31 @@ File file1 = new File(getMinecraft().gameDir, "crash-reports"); File file2 = new File(file1, "crash-" + new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss").format(new Date()) + "-client.txt"); Bootstrap.printToSYSOUT(crashReportIn.getCompleteReport()); @@ -167,6 +234,11 @@ - System.exit(-2); + retVal = -2; } ++ try { ++ String where = crashReportIn.getFile() != null ? crashReportIn.getFile().getAbsolutePath() : (file2.isFile() ? file2.getAbsolutePath() : "the console"); ++ com.cleanroommc.client.sdl.FileDialogs.error(com.cleanroommc.client.sdl.Window.main(), "Cleanroom", "The game crashed. A report was saved to:\n" + where); ++ } catch (Throwable ignored) { ++ } + net.minecraftforge.fml.common.FMLCommonHandler.instance().handleExit(retVal); } @@ -178,7 +250,7 @@ public void refreshResources() { List list = Lists.newArrayList(this.defaultResourcePacks); if (this.integratedServer != null) { -@@ -902,16 +911,22 @@ +@@ -902,16 +903,22 @@ * @param guiScreenIn The {@link GuiScreen} to display. If it is {@code null}, any open GUI will be closed. */ public void displayGuiScreen(@Nullable GuiScreen guiScreenIn) { @@ -205,7 +277,7 @@ if (guiScreenIn instanceof GuiMainMenu || guiScreenIn instanceof GuiMultiplayer) { this.gameSettings.showDebugInfo = false; this.ingameGUI.getChatGUI().clearChatMessages(true); -@@ -962,6 +977,8 @@ +@@ -962,6 +969,8 @@ this.soundHandler.unloadSounds(); } finally { @@ -214,7 +286,7 @@ Display.destroy(); if (!this.hasCrashed) { System.exit(0); -@@ -999,7 +1016,7 @@ +@@ -999,7 +1008,7 @@ long i1 = System.nanoTime() - l; this.checkGLError("Pre render"); this.profiler.endStartSection("sound"); @@ -223,7 +295,7 @@ this.profiler.endSection(); this.profiler.startSection("render"); GlStateManager.pushMatrix(); -@@ -1009,11 +1026,13 @@ +@@ -1009,11 +1018,13 @@ GlStateManager.enableTexture2D(); this.profiler.endSection(); if (!this.skipRenderWorld) { @@ -237,7 +309,7 @@ } this.profiler.endSection(); -@@ -1308,9 +1327,9 @@ +@@ -1308,9 +1319,9 @@ if (this.leftClickCounter <= 0 && !this.player.isHandActive()) { if (leftClick && this.objectMouseOver != null && this.objectMouseOver.typeOfHit == RayTraceResult.Type.BLOCK) { BlockPos blockpos = this.objectMouseOver.getBlockPos(); @@ -250,7 +322,7 @@ this.player.swingArm(EnumHand.MAIN_HAND); } } else { -@@ -1333,7 +1352,8 @@ +@@ -1333,7 +1344,8 @@ break; case BLOCK: BlockPos blockpos = this.objectMouseOver.getBlockPos(); @@ -260,7 +332,7 @@ this.playerController.clickBlock(blockpos, this.objectMouseOver.sideHit); break; } -@@ -1343,6 +1363,7 @@ +@@ -1343,6 +1355,7 @@ } this.player.resetCooldown(); @@ -268,7 +340,7 @@ } this.player.swingArm(EnumHand.MAIN_HAND); -@@ -1399,6 +1420,7 @@ +@@ -1399,6 +1412,7 @@ } } @@ -276,7 +348,7 @@ if (!itemstack.isEmpty() && this.playerController.processRightClick(this.player, this.world, enumhand) == EnumActionResult.SUCCESS) { this.entityRenderer.itemRenderer.resetEquippedProgress(enumhand); -@@ -1411,6 +1433,11 @@ +@@ -1411,6 +1425,11 @@ /** Toggles fullscreen mode. */ public void toggleFullscreen() { @@ -288,13 +360,23 @@ try { this.fullscreen = !this.fullscreen; this.gameSettings.fullScreen = this.fullscreen; -@@ -1445,6 +1472,10 @@ +@@ -1444,7 +1463,19 @@ + this.updateFramebufferSize(); } - Display.setFullscreen(this.fullscreen); -+ if (!this.fullscreen && (Util.getOSType() == Util.EnumOS.WINDOWS)) { //Forge: Fix MC-68754, Screen is not resizeable after exiting fullscreen due to LWJGL bug https://github.com/LWJGL/lwjgl/issues/142 which is fixed, but not in the version MC ships -+ Display.setResizable(false); -+ Display.setResizable(true); +- Display.setFullscreen(this.fullscreen); ++ com.cleanroommc.client.sdl.Window host = com.cleanroommc.client.sdl.Window.main(); ++ if (host != null) { ++ host.fullscreen(this.fullscreen); ++ if (!this.fullscreen) { ++ host.resizable(false).resizable(true); ++ } ++ } else { ++ Display.setFullscreen(this.fullscreen); ++ if (!this.fullscreen && (Util.getOSType() == Util.EnumOS.WINDOWS)) { //Forge: Fix MC-68754, Screen is not resizeable after exiting fullscreen due to LWJGL bug https://github.com/LWJGL/lwjgl/issues/142 which is fixed, but not in the version MC ships ++ Display.setResizable(false); ++ Display.setResizable(true); ++ } + } Display.setVSyncEnabled(this.gameSettings.enableVsync); this.updateDisplay(); From de8e8640648a69d987bae5d5d932527103153f90 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Wed, 19 Aug 2026 23:53:09 +0100 Subject: [PATCH 82/99] Remove redundant SideOnly patches with the help of a SAS file - Fuck SRG names... --- build.gradle | 1 + module/cleanroom/minecraft.sas | 60 ++++++++++ .../net/minecraft/block/SoundType.java.patch | 21 ++-- .../client/gui/GuiOverlayDebug.java.patch | 15 ++- .../client/renderer/OpenGlHelper.java.patch | 76 +++++++++++-- .../model/ModelResourceLocation.java.patch | 14 --- .../minecraft/entity/EntityLiving.java.patch | 9 +- .../item/crafting/IRecipe.java.patch | 16 +-- .../item/crafting/Ingredient.java.patch | 15 +-- .../crafting/RecipeBookCloning.java.patch | 8 +- .../item/crafting/RecipeFireworks.java.patch | 16 +-- .../item/crafting/RecipeRepairItem.java.patch | 16 +-- .../crafting/RecipeTippedArrow.java.patch | 8 +- .../item/crafting/RecipesArmorDyes.java.patch | 14 +-- .../item/crafting/RecipesBanners.java.patch | 33 ++---- .../crafting/RecipesMapCloning.java.patch | 10 +- .../item/crafting/ShapedRecipes.java.patch | 19 ++-- .../item/crafting/ShapelessRecipes.java.patch | 13 +-- .../item/crafting/ShieldRecipes.java.patch | 14 +-- .../crafting/ShulkerBoxRecipes.java.patch | 18 +-- .../nbt/CompressedStreamTools.java.patch | 35 +----- .../net/minecraft/potion/Potion.java.patch | 5 +- .../tileentity/TileEntity.java.patch | 7 +- .../util/BlockRenderLayer.java.patch | 12 -- .../net/minecraft/util/EnumFacing.java.patch | 45 +------- .../util/IntIdentityHashBiMap.java.patch | 15 +-- .../net/minecraft/util/math/Vec2f.java.patch | 12 -- .../net/minecraft/util/math/Vec3d.java.patch | 19 +--- .../util/text/ITextComponent.java.patch | 12 +- .../net/minecraft/util/text/Style.java.patch | 15 ++- .../util/text/TextComponentBase.java.patch | 12 +- .../net/minecraft/world/BossInfo.java.patch | 27 ----- .../minecraft/world/BossInfoServer.java.patch | 27 ----- .../net/minecraft/world/World.java.patch | 107 +++++++++--------- 34 files changed, 314 insertions(+), 432 deletions(-) create mode 100644 module/cleanroom/minecraft.sas delete mode 100644 module/minecraft/patches/net/minecraft/client/renderer/block/model/ModelResourceLocation.java.patch delete mode 100644 module/minecraft/patches/net/minecraft/util/BlockRenderLayer.java.patch delete mode 100644 module/minecraft/patches/net/minecraft/util/math/Vec2f.java.patch delete mode 100644 module/minecraft/patches/net/minecraft/world/BossInfo.java.patch delete mode 100644 module/minecraft/patches/net/minecraft/world/BossInfoServer.java.patch diff --git a/build.gradle b/build.gradle index 791f30ec8..2bd657928 100644 --- a/build.gradle +++ b/build.gradle @@ -24,6 +24,7 @@ idea { cleanroom { mode = 'loader' accessTransformers.from file('module/forge/src/main/resources/forge_at.cfg') + sideAnnotationStrippers.from file('module/cleanroom/minecraft.sas') } tokenEnvoy { diff --git a/module/cleanroom/minecraft.sas b/module/cleanroom/minecraft.sas new file mode 100644 index 000000000..f65a4ffcc --- /dev/null +++ b/module/cleanroom/minecraft.sas @@ -0,0 +1,60 @@ +# Side annotation strippers for the vanilla Minecraft jar +# +# Format: [ []] (SRG names, '.' or '/' separated) + +# Whole Classes +net/minecraft/client/renderer/block/model/ModelResourceLocation +net/minecraft/util/BlockRenderLayer +net/minecraft/util/math/Vec2f + +# net.minecraft.block.SoundType +net/minecraft/block/SoundType func_185845_c()Lnet/minecraft/util/SoundEvent; # getBreakSound +net/minecraft/block/SoundType func_185846_f()Lnet/minecraft/util/SoundEvent; # getHitSound + +# net.minecraft.entity.EntityLiving +net/minecraft/entity/EntityLiving func_70603_bj()F # getRenderSizeModifier + +# net.minecraft.item.crafting +net/minecraft/item/crafting/IRecipe func_194133_a(II)Z # canFit +net/minecraft/item/crafting/IRecipe func_193358_e()Ljava/lang/String; # getGroup +net/minecraft/item/crafting/Ingredient func_193365_a()[Lnet/minecraft/item/ItemStack; # getMatchingStacks + +# net.minecraft.nbt.CompressedStreamTools +net/minecraft/nbt/CompressedStreamTools func_74797_a(Ljava/io/File;)Lnet/minecraft/nbt/NBTTagCompound; # read +net/minecraft/nbt/CompressedStreamTools func_74793_a(Lnet/minecraft/nbt/NBTTagCompound;Ljava/io/File;)V # safeWrite +net/minecraft/nbt/CompressedStreamTools func_74795_b(Lnet/minecraft/nbt/NBTTagCompound;Ljava/io/File;)V # write + +# net.minecraft.potion.Potion +net/minecraft/potion/Potion func_76398_f()Z # isBadEffect + +# net.minecraft.tileentity.TileEntity +net/minecraft/tileentity/TileEntity func_145835_a(DDD)D # getDistanceSq + +# net.minecraft.util.EnumFacing +net/minecraft/util/EnumFacing func_176739_a(Ljava/lang/String;)Lnet/minecraft/util/EnumFacing; # byName +net/minecraft/util/EnumFacing func_176730_m()Lnet/minecraft/util/math/Vec3i; # getDirectionVec +net/minecraft/util/EnumFacing func_176737_a(FFF)Lnet/minecraft/util/EnumFacing; # getFacingFromVector +net/minecraft/util/EnumFacing func_176732_a(Lnet/minecraft/util/EnumFacing$Axis;)Lnet/minecraft/util/EnumFacing; # rotateAround +net/minecraft/util/EnumFacing func_176744_n()Lnet/minecraft/util/EnumFacing; # rotateX +net/minecraft/util/EnumFacing func_176738_p()Lnet/minecraft/util/EnumFacing; # rotateZ +net/minecraft/util/EnumFacing$Axis func_176717_a(Ljava/lang/String;)Lnet/minecraft/util/EnumFacing$Axis; # byName + +# net.minecraft.util.IntIdentityHashBiMap +net/minecraft/util/IntIdentityHashBiMap func_186812_a()V # clear + +# net.minecraft.util.math.Vec3d +net/minecraft/util/math/Vec3d func_72431_c(Lnet/minecraft/util/math/Vec3d;)Lnet/minecraft/util/math/Vec3d; # crossProduct +net/minecraft/util/math/Vec3d func_189986_a(FF)Lnet/minecraft/util/math/Vec3d; # fromPitchYaw +net/minecraft/util/math/Vec3d func_189984_a(Lnet/minecraft/util/math/Vec2f;)Lnet/minecraft/util/math/Vec3d; # fromPitchYaw +net/minecraft/util/math/Vec3d func_189985_c()D # lengthSquared + +# net.minecraft.util.text +net/minecraft/util/text/ITextComponent func_150254_d()Ljava/lang/String; # getFormattedText +net/minecraft/util/text/Style func_150218_j()Ljava/lang/String; # getFormattingCode + +# net.minecraft.world.BossInfo +net/minecraft/world/BossInfo func_186745_a(Lnet/minecraft/world/BossInfo$Color;)V # setColor +net/minecraft/world/BossInfo func_186746_a(Lnet/minecraft/world/BossInfo$Overlay;)V # setOverlay + +# net.minecraft.world.World +net/minecraft/world/World func_72848_b(Lnet/minecraft/world/IWorldEventListener;)V # removeEventListener diff --git a/module/minecraft/patches/net/minecraft/block/SoundType.java.patch b/module/minecraft/patches/net/minecraft/block/SoundType.java.patch index f7df3d459..77c487e24 100644 --- a/module/minecraft/patches/net/minecraft/block/SoundType.java.patch +++ b/module/minecraft/patches/net/minecraft/block/SoundType.java.patch @@ -1,18 +1,11 @@ --- original/net/minecraft/block/SoundType.java +++ modified/net/minecraft/block/SoundType.java -@@ -147,7 +147,6 @@ - return this.pitch; - } +@@ -2,6 +2,8 @@ -- @SideOnly(Side.CLIENT) - public SoundEvent getBreakSound() { - return this.breakSound; - } -@@ -160,7 +159,6 @@ - return this.placeSound; - } + import net.minecraft.init.SoundEvents; + import net.minecraft.util.SoundEvent; ++import net.minecraftforge.fml.relauncher.Side; ++import net.minecraftforge.fml.relauncher.SideOnly; -- @SideOnly(Side.CLIENT) - public SoundEvent getHitSound() { - return this.hitSound; - } + public class SoundType { + public static final SoundType WOOD = new SoundType( diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiOverlayDebug.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiOverlayDebug.java.patch index a335f5858..de4b5a18e 100644 --- a/module/minecraft/patches/net/minecraft/client/gui/GuiOverlayDebug.java.patch +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiOverlayDebug.java.patch @@ -16,7 +16,7 @@ import org.lwjgl.opengl.Display; @SideOnly(Side.CLIENT) -@@ -218,16 +220,21 @@ +@@ -218,16 +220,34 @@ long k = Runtime.getRuntime().freeMemory(); long l = j - k; List list = Lists.newArrayList( @@ -41,6 +41,19 @@ + GlStateManager.glGetString(7937), + GlStateManager.glGetString(7938) + ); ++ com.cleanroommc.client.sdl.Window window = com.cleanroommc.client.sdl.Window.main(); ++ if (window != null) { ++ com.cleanroommc.client.sdl.video.Display display = window.display(); ++ if (display != null) { ++ list.add(String.format("Monitor: %s scale: %.2f", display.name(), window.displayScale())); ++ } ++ com.cleanroommc.client.sdl.Power power = com.cleanroommc.client.sdl.Power.query(); ++ if (power.state() == com.cleanroommc.client.sdl.Power.State.ON_BATTERY ++ || power.state() == com.cleanroommc.client.sdl.Power.State.CHARGING ++ || power.state() == com.cleanroommc.client.sdl.Power.State.CHARGED) { ++ list.add(String.format("Power: %s %d%%", power.state(), power.percent())); ++ } ++ } + + list.add(""); + list.addAll(net.minecraftforge.fml.common.FMLCommonHandler.instance().getBrandings(false)); diff --git a/module/minecraft/patches/net/minecraft/client/renderer/OpenGlHelper.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/OpenGlHelper.java.patch index 1c7d2c0b0..49ad4fcb5 100644 --- a/module/minecraft/patches/net/minecraft/client/renderer/OpenGlHelper.java.patch +++ b/module/minecraft/patches/net/minecraft/client/renderer/OpenGlHelper.java.patch @@ -1,6 +1,23 @@ --- original/net/minecraft/client/renderer/OpenGlHelper.java +++ modified/net/minecraft/client/renderer/OpenGlHelper.java -@@ -31,8 +31,8 @@ +@@ -1,8 +1,6 @@ + package net.minecraft.client.renderer; + + import java.io.File; +-import java.io.IOException; +-import java.net.URI; + import java.nio.ByteBuffer; + import java.nio.FloatBuffer; + import java.nio.IntBuffer; +@@ -10,7 +8,6 @@ + import net.minecraft.client.Minecraft; + import net.minecraft.client.renderer.vertex.DefaultVertexFormats; + import net.minecraft.client.settings.GameSettings; +-import net.minecraft.util.Util; + import net.minecraftforge.fml.relauncher.Side; + import net.minecraftforge.fml.relauncher.SideOnly; + import org.apache.logging.log4j.LogManager; +@@ -31,8 +28,8 @@ import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL30; import org.lwjgl.opengl.GLContext; @@ -11,7 +28,7 @@ @SideOnly(Side.CLIENT) public class OpenGlHelper { -@@ -95,7 +95,10 @@ +@@ -95,7 +92,10 @@ public static int GL_ARRAY_BUFFER; public static int GL_STATIC_DRAW; @@ -23,7 +40,7 @@ public static void initializeTextures() { ContextCapabilities contextcapabilities = GLContext.getCapabilities(); arbMultitexture = contextcapabilities.GL_ARB_multitexture && !contextcapabilities.OpenGL13; -@@ -263,8 +266,8 @@ +@@ -263,8 +263,8 @@ } try { @@ -34,7 +51,7 @@ } catch (Throwable throwable) { } } -@@ -303,10 +306,11 @@ +@@ -303,10 +303,11 @@ } public static void glShaderSource(int shaderIn, ByteBuffer string) { @@ -48,7 +65,7 @@ } } -@@ -364,9 +368,9 @@ +@@ -364,9 +365,9 @@ public static void glUniform1(int location, IntBuffer values) { if (arbShaders) { @@ -60,7 +77,7 @@ } } -@@ -380,81 +384,81 @@ +@@ -380,81 +381,81 @@ public static void glUniform1(int location, FloatBuffer values) { if (arbShaders) { @@ -162,7 +179,7 @@ } } -@@ -676,6 +680,11 @@ +@@ -676,6 +677,11 @@ } else { GL13.glMultiTexCoord2f(target, x, y); } @@ -174,3 +191,48 @@ } public static void glBlendFunc(int sFactorRGB, int dFactorRGB, int sfactorAlpha, int dfactorAlpha) { +@@ -727,41 +733,12 @@ + } + + public static void openFile(File fileIn) { +- String s = fileIn.getAbsolutePath(); +- if (Util.getOSType() == Util.EnumOS.OSX) { +- try { +- LOGGER.info(s); +- Runtime.getRuntime().exec(new String[]{"/usr/bin/open", s}); +- return; +- } catch (IOException ioexception1) { +- LOGGER.error("Couldn't open file", ioexception1); +- } +- } else if (Util.getOSType() == Util.EnumOS.WINDOWS) { +- String s1 = String.format("cmd.exe /C start \"Open file\" \"%s\"", s); +- +- try { +- Runtime.getRuntime().exec(s1); +- return; +- } catch (IOException ioexception) { +- LOGGER.error("Couldn't open file", ioexception); +- } +- } +- +- boolean flag = false; +- + try { +- Class oclass = Class.forName("java.awt.Desktop"); +- Object object = oclass.getMethod("getDesktop").invoke(null); +- oclass.getMethod("browse", URI.class).invoke(object, fileIn.toURI()); ++ com.cleanroommc.client.sdl.Desktop.open(fileIn); + } catch (Throwable throwable) { +- LOGGER.error("Couldn't open link", throwable); +- flag = true; ++ LOGGER.error("Couldn't open file", throwable); ++ Sys.openURL("file://" + fileIn.getAbsolutePath()); + } +- +- if (flag) { +- LOGGER.info("Opening via system class!"); +- Sys.openURL("file://" + s); +- } + } + + @SideOnly(Side.CLIENT) diff --git a/module/minecraft/patches/net/minecraft/client/renderer/block/model/ModelResourceLocation.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/block/model/ModelResourceLocation.java.patch deleted file mode 100644 index 85b738e85..000000000 --- a/module/minecraft/patches/net/minecraft/client/renderer/block/model/ModelResourceLocation.java.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- original/net/minecraft/client/renderer/block/model/ModelResourceLocation.java -+++ modified/net/minecraft/client/renderer/block/model/ModelResourceLocation.java -@@ -2,11 +2,8 @@ - - import java.util.Locale; - import net.minecraft.util.ResourceLocation; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; - import org.apache.commons.lang3.StringUtils; - --@SideOnly(Side.CLIENT) - public class ModelResourceLocation extends ResourceLocation { - private final String variant; - diff --git a/module/minecraft/patches/net/minecraft/entity/EntityLiving.java.patch b/module/minecraft/patches/net/minecraft/entity/EntityLiving.java.patch index a2e8abdb5..eb20f496f 100644 --- a/module/minecraft/patches/net/minecraft/entity/EntityLiving.java.patch +++ b/module/minecraft/patches/net/minecraft/entity/EntityLiving.java.patch @@ -34,16 +34,15 @@ } else { Entity entity = this.world.getClosestPlayerToEntity(this, -1.0); if (entity != null) { -@@ -730,8 +739,6 @@ +@@ -730,7 +739,6 @@ && this.world.checkNoEntityCollision(this.getEntityBoundingBox(), this); } - /** Returns render size modifier */ -- @SideOnly(Side.CLIENT) public float getRenderSizeModifier() { return 1.0F; } -@@ -862,6 +869,8 @@ +@@ -861,6 +869,8 @@ } public static EntityEquipmentSlot getSlotForItemStack(ItemStack stack) { @@ -52,7 +51,7 @@ if (stack.getItem() == Item.getItemFromBlock(Blocks.PUMPKIN) || stack.getItem() == Items.SKULL) { return EntityEquipmentSlot.HEAD; } else if (stack.getItem() instanceof ItemArmor) { -@@ -869,7 +878,7 @@ +@@ -868,7 +878,7 @@ } else if (stack.getItem() == Items.ELYTRA) { return EntityEquipmentSlot.CHEST; } else { @@ -61,7 +60,7 @@ } } -@@ -1203,5 +1212,17 @@ +@@ -1202,5 +1212,17 @@ ON_GROUND, IN_AIR, IN_WATER; diff --git a/module/minecraft/patches/net/minecraft/item/crafting/IRecipe.java.patch b/module/minecraft/patches/net/minecraft/item/crafting/IRecipe.java.patch index b7d2a63ca..d14739b8c 100644 --- a/module/minecraft/patches/net/minecraft/item/crafting/IRecipe.java.patch +++ b/module/minecraft/patches/net/minecraft/item/crafting/IRecipe.java.patch @@ -1,24 +1,15 @@ --- original/net/minecraft/item/crafting/IRecipe.java +++ modified/net/minecraft/item/crafting/IRecipe.java -@@ -4,10 +4,8 @@ - import net.minecraft.item.ItemStack; +@@ -5,7 +5,7 @@ import net.minecraft.util.NonNullList; import net.minecraft.world.World; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; -public interface IRecipe { +public interface IRecipe extends net.minecraftforge.registries.IForgeRegistryEntry { /** Used to check if a recipe matches current crafting inventory */ boolean matches(InventoryCrafting var1, World var2); -@@ -15,13 +13,14 @@ - ItemStack getCraftingResult(InventoryCrafting var1); - - /** Used to determine if this recipe can fit in a grid of the given width/height */ -- @SideOnly(Side.CLIENT) - boolean canFit(int var1, int var2); - +@@ -18,7 +18,9 @@ /** Get the result of this recipe, usually for display purposes (e.g. recipe book). If your recipe has more than one possible result (e.g. it's dynamic and depends on its inputs), then return an empty stack. */ ItemStack getRecipeOutput(); @@ -29,12 +20,11 @@ default NonNullList getIngredients() { return NonNullList.create(); -@@ -32,9 +31,7 @@ +@@ -29,8 +31,7 @@ return false; } - /** Recipes with equal group are combined into one button in the recipe book */ -- @SideOnly(Side.CLIENT) - default String getGroup() { +default String getGroup() { return ""; diff --git a/module/minecraft/patches/net/minecraft/item/crafting/Ingredient.java.patch b/module/minecraft/patches/net/minecraft/item/crafting/Ingredient.java.patch index 0fe213e9c..a9a03b18e 100644 --- a/module/minecraft/patches/net/minecraft/item/crafting/Ingredient.java.patch +++ b/module/minecraft/patches/net/minecraft/item/crafting/Ingredient.java.patch @@ -1,11 +1,7 @@ --- original/net/minecraft/item/crafting/Ingredient.java +++ modified/net/minecraft/item/crafting/Ingredient.java -@@ -9,10 +9,10 @@ - import net.minecraft.client.util.RecipeItemHelper; - import net.minecraft.item.Item; +@@ -11,6 +11,8 @@ import net.minecraft.item.ItemStack; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; public class Ingredient implements Predicate { + // Invalidate Mojang's caches @@ -13,7 +9,7 @@ public static final Ingredient EMPTY = new Ingredient() { @Override public boolean apply(@Nullable ItemStack p_apply_1_) { -@@ -20,15 +20,35 @@ +@@ -18,14 +20,35 @@ } }; private final ItemStack[] matchingStacks; @@ -44,14 +40,13 @@ + Ingredient.INSTANCES.add(this); } -- @SideOnly(Side.CLIENT) public ItemStack[] getMatchingStacks() { - return this.matchingStacks; + return this.matchingStacksExploded; } public boolean apply(@Nullable ItemStack p_apply_1_) { -@@ -50,9 +70,9 @@ +@@ -47,9 +70,9 @@ public IntList getValidItemStacksPacked() { if (this.matchingStacksPacked == null) { @@ -63,7 +58,7 @@ this.matchingStacksPacked.add(RecipeItemHelper.pack(itemstack)); } -@@ -62,6 +82,16 @@ +@@ -59,6 +82,16 @@ return this.matchingStacksPacked; } @@ -80,7 +75,7 @@ public static Ingredient fromItem(Item p_193367_0_) { return fromStacks(new ItemStack(p_193367_0_, 1, 32767)); } -@@ -87,4 +117,19 @@ +@@ -84,4 +117,19 @@ return EMPTY; } diff --git a/module/minecraft/patches/net/minecraft/item/crafting/RecipeBookCloning.java.patch b/module/minecraft/patches/net/minecraft/item/crafting/RecipeBookCloning.java.patch index 3a32a56ed..a1e11fcb4 100644 --- a/module/minecraft/patches/net/minecraft/item/crafting/RecipeBookCloning.java.patch +++ b/module/minecraft/patches/net/minecraft/item/crafting/RecipeBookCloning.java.patch @@ -1,11 +1,8 @@ --- original/net/minecraft/item/crafting/RecipeBookCloning.java +++ modified/net/minecraft/item/crafting/RecipeBookCloning.java -@@ -6,11 +6,8 @@ - import net.minecraft.item.ItemWrittenBook; +@@ -7,8 +7,7 @@ import net.minecraft.util.NonNullList; import net.minecraft.world.World; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; -public class RecipeBookCloning implements IRecipe { - /** Used to check if a recipe matches current crafting inventory */ @@ -13,12 +10,11 @@ @Override public boolean matches(InventoryCrafting inv, World worldIn) { int i = 0; -@@ -106,8 +103,6 @@ +@@ -104,7 +103,6 @@ return true; } - /** Used to determine if this recipe can fit in a grid of the given width/height */ -- @SideOnly(Side.CLIENT) @Override public boolean canFit(int width, int height) { return width >= 3 && height >= 3; diff --git a/module/minecraft/patches/net/minecraft/item/crafting/RecipeFireworks.java.patch b/module/minecraft/patches/net/minecraft/item/crafting/RecipeFireworks.java.patch index c3fbf9982..47d3395fe 100644 --- a/module/minecraft/patches/net/minecraft/item/crafting/RecipeFireworks.java.patch +++ b/module/minecraft/patches/net/minecraft/item/crafting/RecipeFireworks.java.patch @@ -1,18 +1,15 @@ --- original/net/minecraft/item/crafting/RecipeFireworks.java +++ modified/net/minecraft/item/crafting/RecipeFireworks.java -@@ -10,10 +10,8 @@ - import net.minecraft.nbt.NBTTagList; +@@ -11,7 +11,7 @@ import net.minecraft.util.NonNullList; import net.minecraft.world.World; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; -public class RecipeFireworks implements IRecipe { +public class RecipeFireworks extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe { private ItemStack resultItem = ItemStack.EMPTY; /** Used to check if a recipe matches current crafting inventory */ -@@ -34,7 +32,7 @@ +@@ -32,7 +32,7 @@ j++; } else if (itemstack.getItem() == Items.FIREWORK_CHARGE) { l++; @@ -21,7 +18,7 @@ k++; } else if (itemstack.getItem() == Items.PAPER) { i++; -@@ -96,8 +94,8 @@ +@@ -94,8 +94,8 @@ for (int l1 = 0; l1 < inv.getSizeInventory(); l1++) { ItemStack itemstack2 = inv.getStackInSlot(l1); if (!itemstack2.isEmpty()) { @@ -32,7 +29,7 @@ } else if (itemstack2.getItem() == Items.GLOWSTONE_DUST) { nbttagcompound2.setBoolean("Flicker", true); } else if (itemstack2.getItem() == Items.DIAMOND) { -@@ -131,8 +129,8 @@ +@@ -129,8 +129,8 @@ for (int i2 = 0; i2 < inv.getSizeInventory(); i2++) { ItemStack itemstack1 = inv.getStackInSlot(i2); if (!itemstack1.isEmpty()) { @@ -43,7 +40,7 @@ } else if (itemstack1.getItem() == Items.FIREWORK_CHARGE) { this.resultItem = itemstack1.copy(); this.resultItem.setCount(1); -@@ -180,9 +178,8 @@ +@@ -178,9 +178,8 @@ for (int i = 0; i < nonnulllist.size(); i++) { ItemStack itemstack = inv.getStackInSlot(i); @@ -55,12 +52,11 @@ } return nonnulllist; -@@ -194,8 +191,6 @@ +@@ -192,7 +191,6 @@ return true; } - /** Used to determine if this recipe can fit in a grid of the given width/height */ -- @SideOnly(Side.CLIENT) @Override public boolean canFit(int width, int height) { return width * height >= 1; diff --git a/module/minecraft/patches/net/minecraft/item/crafting/RecipeRepairItem.java.patch b/module/minecraft/patches/net/minecraft/item/crafting/RecipeRepairItem.java.patch index 8a1391fe2..131b1e6e2 100644 --- a/module/minecraft/patches/net/minecraft/item/crafting/RecipeRepairItem.java.patch +++ b/module/minecraft/patches/net/minecraft/item/crafting/RecipeRepairItem.java.patch @@ -1,11 +1,8 @@ --- original/net/minecraft/item/crafting/RecipeRepairItem.java +++ modified/net/minecraft/item/crafting/RecipeRepairItem.java -@@ -7,11 +7,8 @@ - import net.minecraft.item.ItemStack; +@@ -8,8 +8,7 @@ import net.minecraft.util.NonNullList; import net.minecraft.world.World; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; -public class RecipeRepairItem implements IRecipe { - /** Used to check if a recipe matches current crafting inventory */ @@ -13,7 +10,7 @@ @Override public boolean matches(InventoryCrafting inv, World worldIn) { List list = Lists.newArrayList(); -@@ -23,9 +20,9 @@ +@@ -21,9 +20,9 @@ if (list.size() > 1) { ItemStack itemstack1 = list.get(0); if (itemstack.getItem() != itemstack1.getItem() @@ -26,7 +23,7 @@ return false; } } -@@ -47,9 +44,9 @@ +@@ -45,9 +44,9 @@ if (list.size() > 1) { ItemStack itemstack1 = list.get(0); if (itemstack.getItem() != itemstack1.getItem() @@ -39,7 +36,7 @@ return ItemStack.EMPTY; } } -@@ -60,14 +57,15 @@ +@@ -58,14 +57,15 @@ ItemStack itemstack2 = list.get(0); ItemStack itemstack3 = list.get(1); if (itemstack2.getItem() == itemstack3.getItem() @@ -63,7 +60,7 @@ if (i1 < 0) { i1 = 0; } -@@ -91,9 +89,7 @@ +@@ -89,9 +89,7 @@ for (int i = 0; i < nonnulllist.size(); i++) { ItemStack itemstack = inv.getStackInSlot(i); @@ -74,12 +71,11 @@ } return nonnulllist; -@@ -105,8 +101,6 @@ +@@ -103,7 +101,6 @@ return true; } - /** Used to determine if this recipe can fit in a grid of the given width/height */ -- @SideOnly(Side.CLIENT) @Override public boolean canFit(int width, int height) { return width * height >= 2; diff --git a/module/minecraft/patches/net/minecraft/item/crafting/RecipeTippedArrow.java.patch b/module/minecraft/patches/net/minecraft/item/crafting/RecipeTippedArrow.java.patch index 4d5d51acb..b7d7d414a 100644 --- a/module/minecraft/patches/net/minecraft/item/crafting/RecipeTippedArrow.java.patch +++ b/module/minecraft/patches/net/minecraft/item/crafting/RecipeTippedArrow.java.patch @@ -1,11 +1,8 @@ --- original/net/minecraft/item/crafting/RecipeTippedArrow.java +++ modified/net/minecraft/item/crafting/RecipeTippedArrow.java -@@ -7,11 +7,8 @@ - import net.minecraft.potion.PotionUtils; +@@ -8,8 +8,7 @@ import net.minecraft.util.NonNullList; import net.minecraft.world.World; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; -public class RecipeTippedArrow implements IRecipe { - /** Used to check if a recipe matches current crafting inventory */ @@ -13,12 +10,11 @@ @Override public boolean matches(InventoryCrafting inv, World worldIn) { if (inv.getWidth() == 3 && inv.getHeight() == 3) { -@@ -70,8 +67,6 @@ +@@ -68,7 +67,6 @@ return true; } - /** Used to determine if this recipe can fit in a grid of the given width/height */ -- @SideOnly(Side.CLIENT) @Override public boolean canFit(int width, int height) { return width >= 2 && height >= 2; diff --git a/module/minecraft/patches/net/minecraft/item/crafting/RecipesArmorDyes.java.patch b/module/minecraft/patches/net/minecraft/item/crafting/RecipesArmorDyes.java.patch index 06709ff5f..8563385dd 100644 --- a/module/minecraft/patches/net/minecraft/item/crafting/RecipesArmorDyes.java.patch +++ b/module/minecraft/patches/net/minecraft/item/crafting/RecipesArmorDyes.java.patch @@ -1,11 +1,8 @@ --- original/net/minecraft/item/crafting/RecipesArmorDyes.java +++ modified/net/minecraft/item/crafting/RecipesArmorDyes.java -@@ -9,11 +9,8 @@ - import net.minecraft.item.ItemStack; +@@ -10,8 +10,7 @@ import net.minecraft.util.NonNullList; import net.minecraft.world.World; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; -public class RecipesArmorDyes implements IRecipe { - /** Used to check if a recipe matches current crafting inventory */ @@ -13,7 +10,7 @@ @Override public boolean matches(InventoryCrafting inv, World worldIn) { ItemStack itemstack = ItemStack.EMPTY; -@@ -30,7 +27,7 @@ +@@ -28,7 +27,7 @@ itemstack = itemstack1; } else { @@ -22,7 +19,7 @@ return false; } -@@ -74,11 +71,11 @@ +@@ -72,11 +71,11 @@ j++; } } else { @@ -36,7 +33,7 @@ int l1 = (int)(afloat[0] * 255.0F); int i2 = (int)(afloat[1] * 255.0F); int j2 = (int)(afloat[2] * 255.0F); -@@ -122,9 +119,7 @@ +@@ -120,9 +119,7 @@ for (int i = 0; i < nonnulllist.size(); i++) { ItemStack itemstack = inv.getStackInSlot(i); @@ -47,12 +44,11 @@ } return nonnulllist; -@@ -136,8 +131,6 @@ +@@ -134,7 +131,6 @@ return true; } - /** Used to determine if this recipe can fit in a grid of the given width/height */ -- @SideOnly(Side.CLIENT) @Override public boolean canFit(int width, int height) { return width * height >= 2; diff --git a/module/minecraft/patches/net/minecraft/item/crafting/RecipesBanners.java.patch b/module/minecraft/patches/net/minecraft/item/crafting/RecipesBanners.java.patch index 4a689ec3d..5c8d0e3f0 100644 --- a/module/minecraft/patches/net/minecraft/item/crafting/RecipesBanners.java.patch +++ b/module/minecraft/patches/net/minecraft/item/crafting/RecipesBanners.java.patch @@ -1,11 +1,7 @@ --- original/net/minecraft/item/crafting/RecipesBanners.java +++ modified/net/minecraft/item/crafting/RecipesBanners.java -@@ -12,11 +12,9 @@ - import net.minecraft.tileentity.TileEntityBanner; - import net.minecraft.util.NonNullList; +@@ -14,7 +14,7 @@ import net.minecraft.world.World; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; public class RecipesBanners { - public static class RecipeAddPattern implements IRecipe { @@ -13,7 +9,7 @@ /** Used to check if a recipe matches current crafting inventory */ @Override public boolean matches(InventoryCrafting inv, World worldIn) { -@@ -60,8 +58,9 @@ +@@ -58,8 +58,9 @@ for (int j = 0; j < inv.getSizeInventory(); j++) { ItemStack itemstack2 = inv.getStackInSlot(j); @@ -25,7 +21,7 @@ break; } } -@@ -96,9 +95,7 @@ +@@ -94,9 +95,7 @@ for (int i = 0; i < nonnulllist.size(); i++) { ItemStack itemstack = inv.getStackInSlot(i); @@ -36,7 +32,7 @@ } return nonnulllist; -@@ -116,7 +113,7 @@ +@@ -114,7 +113,7 @@ for (int i = 0; i < p_190933_1_.getSizeInventory() && flag; i++) { ItemStack itemstack = p_190933_1_.getStackInSlot(i); if (!itemstack.isEmpty() && itemstack.getItem() != Items.BANNER) { @@ -45,7 +41,7 @@ if (flag2) { flag = false; break; -@@ -145,7 +142,7 @@ +@@ -143,7 +142,7 @@ int i1 = k % 3; ItemStack itemstack1 = p_190933_1_.getStackInSlot(k); if (!itemstack1.isEmpty() && itemstack1.getItem() != Items.BANNER) { @@ -54,14 +50,7 @@ flag = false; break; } -@@ -186,14 +183,13 @@ - } - - /** Used to determine if this recipe can fit in a grid of the given width/height */ -- @SideOnly(Side.CLIENT) - @Override - public boolean canFit(int width, int height) { - return width >= 3 && height >= 3; +@@ -190,7 +189,7 @@ } } @@ -70,7 +59,7 @@ /** Used to check if a recipe matches current crafting inventory */ @Override public boolean matches(InventoryCrafting inv, World worldIn) { -@@ -272,8 +268,8 @@ +@@ -269,8 +268,8 @@ for (int i = 0; i < nonnulllist.size(); i++) { ItemStack itemstack = inv.getStackInSlot(i); if (!itemstack.isEmpty()) { @@ -81,11 +70,3 @@ } else if (itemstack.hasTagCompound() && TileEntityBanner.getPatterns(itemstack) > 0) { ItemStack itemstack1 = itemstack.copy(); itemstack1.setCount(1); -@@ -292,7 +288,6 @@ - } - - /** Used to determine if this recipe can fit in a grid of the given width/height */ -- @SideOnly(Side.CLIENT) - @Override - public boolean canFit(int width, int height) { - return width * height >= 2; diff --git a/module/minecraft/patches/net/minecraft/item/crafting/RecipesMapCloning.java.patch b/module/minecraft/patches/net/minecraft/item/crafting/RecipesMapCloning.java.patch index 8d96eb919..41867bd59 100644 --- a/module/minecraft/patches/net/minecraft/item/crafting/RecipesMapCloning.java.patch +++ b/module/minecraft/patches/net/minecraft/item/crafting/RecipesMapCloning.java.patch @@ -1,11 +1,8 @@ --- original/net/minecraft/item/crafting/RecipesMapCloning.java +++ modified/net/minecraft/item/crafting/RecipesMapCloning.java -@@ -5,11 +5,8 @@ - import net.minecraft.item.ItemStack; +@@ -6,8 +6,7 @@ import net.minecraft.util.NonNullList; import net.minecraft.world.World; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; -public class RecipesMapCloning implements IRecipe { - /** Used to check if a recipe matches current crafting inventory */ @@ -13,7 +10,7 @@ @Override public boolean matches(InventoryCrafting inv, World worldIn) { int i = 0; -@@ -90,9 +87,7 @@ +@@ -88,9 +87,7 @@ for (int i = 0; i < nonnulllist.size(); i++) { ItemStack itemstack = inv.getStackInSlot(i); @@ -24,12 +21,11 @@ } return nonnulllist; -@@ -104,8 +99,6 @@ +@@ -102,7 +99,6 @@ return true; } - /** Used to determine if this recipe can fit in a grid of the given width/height */ -- @SideOnly(Side.CLIENT) @Override public boolean canFit(int width, int height) { return width >= 3 && height >= 3; diff --git a/module/minecraft/patches/net/minecraft/item/crafting/ShapedRecipes.java.patch b/module/minecraft/patches/net/minecraft/item/crafting/ShapedRecipes.java.patch index 125ce46cf..1ed0f704f 100644 --- a/module/minecraft/patches/net/minecraft/item/crafting/ShapedRecipes.java.patch +++ b/module/minecraft/patches/net/minecraft/item/crafting/ShapedRecipes.java.patch @@ -1,27 +1,23 @@ --- original/net/minecraft/item/crafting/ShapedRecipes.java +++ modified/net/minecraft/item/crafting/ShapedRecipes.java -@@ -19,10 +19,8 @@ - import net.minecraft.util.NonNullList; +@@ -20,7 +20,7 @@ import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; -public class ShapedRecipes implements IRecipe { +public class ShapedRecipes extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements net.minecraftforge.common.crafting.IShapedRecipe { /** How many horizontal slots this recipe is wide. */ public final int recipeWidth; /** How many vertical slots this recipe uses. */ -@@ -41,8 +39,6 @@ +@@ -39,7 +39,6 @@ this.recipeOutput = result; } - /** Recipes with equal group are combined into one button in the recipe book */ -- @SideOnly(Side.CLIENT) @Override public String getGroup() { return this.group; -@@ -60,9 +56,8 @@ +@@ -57,9 +56,8 @@ for (int i = 0; i < nonnulllist.size(); i++) { ItemStack itemstack = inv.getStackInSlot(i); @@ -33,16 +29,15 @@ } return nonnulllist; -@@ -73,8 +68,6 @@ +@@ -70,7 +68,6 @@ return this.recipeItems; } - /** Used to determine if this recipe can fit in a grid of the given width/height */ -- @SideOnly(Side.CLIENT) @Override public boolean canFit(int width, int height) { return width >= this.recipeWidth && height >= this.recipeHeight; -@@ -83,8 +76,8 @@ +@@ -79,8 +76,8 @@ /** Used to check if a recipe matches current crafting inventory */ @Override public boolean matches(InventoryCrafting inv, World worldIn) { @@ -53,7 +48,7 @@ if (this.checkMatch(inv, i, j, true)) { return true; } -@@ -100,8 +93,8 @@ +@@ -96,8 +93,8 @@ /** Checks if the region of a crafting inventory is match for the recipe. */ private boolean checkMatch(InventoryCrafting craftingInventory, int p_77573_2_, int p_77573_3_, boolean p_77573_4_) { @@ -64,7 +59,7 @@ int k = i - p_77573_2_; int l = j - p_77573_3_; Ingredient ingredient = Ingredient.EMPTY; -@@ -319,4 +312,14 @@ +@@ -315,4 +312,14 @@ int j = useCount ? JsonUtils.getInt(json, "count", 1) : 1; return new ItemStack(item, j, i); } diff --git a/module/minecraft/patches/net/minecraft/item/crafting/ShapelessRecipes.java.patch b/module/minecraft/patches/net/minecraft/item/crafting/ShapelessRecipes.java.patch index f41512cb6..f2e3c87ba 100644 --- a/module/minecraft/patches/net/minecraft/item/crafting/ShapelessRecipes.java.patch +++ b/module/minecraft/patches/net/minecraft/item/crafting/ShapelessRecipes.java.patch @@ -1,11 +1,8 @@ --- original/net/minecraft/item/crafting/ShapelessRecipes.java +++ modified/net/minecraft/item/crafting/ShapelessRecipes.java -@@ -10,24 +10,24 @@ - import net.minecraft.util.JsonUtils; +@@ -11,20 +11,23 @@ import net.minecraft.util.NonNullList; import net.minecraft.world.World; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; -public class ShapelessRecipes implements IRecipe { - /** Is the ItemStack that you get when craft the recipe. */ @@ -27,11 +24,10 @@ } - /** Recipes with equal group are combined into one button in the recipe book */ -- @SideOnly(Side.CLIENT) @Override public String getGroup() { return this.group; -@@ -50,9 +50,8 @@ +@@ -47,9 +50,8 @@ for (int i = 0; i < nonnulllist.size(); i++) { ItemStack itemstack = inv.getStackInSlot(i); @@ -43,7 +39,7 @@ } return nonnulllist; -@@ -61,30 +60,30 @@ +@@ -58,30 +60,30 @@ /** Used to check if a recipe matches current crafting inventory */ @Override public boolean matches(InventoryCrafting inv, World worldIn) { @@ -89,12 +85,11 @@ } /** Returns an Item that is the result of this recipe */ -@@ -121,8 +120,6 @@ +@@ -118,7 +120,6 @@ return nonnulllist; } - /** Used to determine if this recipe can fit in a grid of the given width/height */ -- @SideOnly(Side.CLIENT) @Override public boolean canFit(int width, int height) { return width * height >= this.recipeItems.size(); diff --git a/module/minecraft/patches/net/minecraft/item/crafting/ShieldRecipes.java.patch b/module/minecraft/patches/net/minecraft/item/crafting/ShieldRecipes.java.patch index b5c4d0685..2d1f7ff3e 100644 --- a/module/minecraft/patches/net/minecraft/item/crafting/ShieldRecipes.java.patch +++ b/module/minecraft/patches/net/minecraft/item/crafting/ShieldRecipes.java.patch @@ -1,11 +1,7 @@ --- original/net/minecraft/item/crafting/ShieldRecipes.java +++ modified/net/minecraft/item/crafting/ShieldRecipes.java -@@ -6,11 +6,9 @@ - import net.minecraft.nbt.NBTTagCompound; - import net.minecraft.util.NonNullList; +@@ -8,7 +8,7 @@ import net.minecraft.world.World; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; public class ShieldRecipes { - public static class Decoration implements IRecipe { @@ -13,11 +9,3 @@ /** Used to check if a recipe matches current crafting inventory */ @Override public boolean matches(InventoryCrafting inv, World worldIn) { -@@ -102,7 +100,6 @@ - } - - /** Used to determine if this recipe can fit in a grid of the given width/height */ -- @SideOnly(Side.CLIENT) - @Override - public boolean canFit(int width, int height) { - return width * height >= 2; diff --git a/module/minecraft/patches/net/minecraft/item/crafting/ShulkerBoxRecipes.java.patch b/module/minecraft/patches/net/minecraft/item/crafting/ShulkerBoxRecipes.java.patch index 2e62cca88..f7a6356eb 100644 --- a/module/minecraft/patches/net/minecraft/item/crafting/ShulkerBoxRecipes.java.patch +++ b/module/minecraft/patches/net/minecraft/item/crafting/ShulkerBoxRecipes.java.patch @@ -1,11 +1,7 @@ --- original/net/minecraft/item/crafting/ShulkerBoxRecipes.java +++ modified/net/minecraft/item/crafting/ShulkerBoxRecipes.java -@@ -8,11 +8,9 @@ - import net.minecraft.item.ItemStack; - import net.minecraft.util.NonNullList; +@@ -10,7 +10,7 @@ import net.minecraft.world.World; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; public class ShulkerBoxRecipes { - public static class ShulkerBoxColoring implements IRecipe { @@ -13,7 +9,7 @@ /** Used to check if a recipe matches current crafting inventory */ @Override public boolean matches(InventoryCrafting inv, World worldIn) { -@@ -25,7 +23,7 @@ +@@ -23,7 +23,7 @@ if (Block.getBlockFromItem(itemstack.getItem()) instanceof BlockShulkerBox) { i++; } else { @@ -22,7 +18,7 @@ return false; } -@@ -52,13 +50,13 @@ +@@ -50,13 +50,13 @@ if (!itemstack2.isEmpty()) { if (Block.getBlockFromItem(itemstack2.getItem()) instanceof BlockShulkerBox) { itemstack = itemstack2; @@ -38,11 +34,3 @@ if (itemstack.hasTagCompound()) { itemstack3.setTagCompound(itemstack.getTagCompound().copy()); } -@@ -93,7 +91,6 @@ - } - - /** Used to determine if this recipe can fit in a grid of the given width/height */ -- @SideOnly(Side.CLIENT) - @Override - public boolean canFit(int width, int height) { - return width * height >= 2; diff --git a/module/minecraft/patches/net/minecraft/nbt/CompressedStreamTools.java.patch b/module/minecraft/patches/net/minecraft/nbt/CompressedStreamTools.java.patch index b10ff256b..671fc66b7 100644 --- a/module/minecraft/patches/net/minecraft/nbt/CompressedStreamTools.java.patch +++ b/module/minecraft/patches/net/minecraft/nbt/CompressedStreamTools.java.patch @@ -1,39 +1,6 @@ --- original/net/minecraft/nbt/CompressedStreamTools.java +++ modified/net/minecraft/nbt/CompressedStreamTools.java -@@ -18,8 +18,6 @@ - import net.minecraft.crash.CrashReport; - import net.minecraft.crash.CrashReportCategory; - import net.minecraft.util.ReportedException; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; - - public class CompressedStreamTools { - /** Load the gzipped compound from the inputstream. */ -@@ -44,7 +42,6 @@ - } - } - -- @SideOnly(Side.CLIENT) - public static void safeWrite(NBTTagCompound compound, File fileIn) throws IOException { - File file1 = new File(fileIn.getAbsolutePath() + "_tmp"); - if (file1.exists()) { -@@ -63,7 +60,6 @@ - file1.renameTo(fileIn); - } - -- @SideOnly(Side.CLIENT) - public static void write(NBTTagCompound compound, File fileIn) throws IOException { - DataOutputStream dataoutputstream = new DataOutputStream(new FileOutputStream(fileIn)); - -@@ -75,7 +71,6 @@ - } - - @Nullable -- @SideOnly(Side.CLIENT) - public static NBTTagCompound read(File fileIn) throws IOException { - if (!fileIn.exists()) { - return null; -@@ -119,11 +114,13 @@ +@@ -114,11 +114,13 @@ private static NBTBase read(DataInput input, int depth, NBTSizeTracker accounter) throws IOException { byte b0 = input.readByte(); diff --git a/module/minecraft/patches/net/minecraft/potion/Potion.java.patch b/module/minecraft/patches/net/minecraft/potion/Potion.java.patch index a3ba6f3cc..5ccf6a59f 100644 --- a/module/minecraft/patches/net/minecraft/potion/Potion.java.patch +++ b/module/minecraft/patches/net/minecraft/potion/Potion.java.patch @@ -12,16 +12,15 @@ private final Map attributeModifierMap = Maps.newHashMap(); /** This field indicated if the effect is 'bad' - negative - for the entity. */ private final boolean isBadEffect; -@@ -156,8 +155,6 @@ +@@ -156,7 +155,6 @@ return this.statusIconIndex; } - /** This method returns true if the potion effect is bad - negative - for the entity. */ -- @SideOnly(Side.CLIENT) public boolean isBadEffect() { return this.isBadEffect; } -@@ -225,8 +222,116 @@ +@@ -224,8 +222,116 @@ return modifier.getAmount() * (amplifier + 1); } diff --git a/module/minecraft/patches/net/minecraft/tileentity/TileEntity.java.patch b/module/minecraft/patches/net/minecraft/tileentity/TileEntity.java.patch index ce7678d3c..d4d6a6c37 100644 --- a/module/minecraft/patches/net/minecraft/tileentity/TileEntity.java.patch +++ b/module/minecraft/patches/net/minecraft/tileentity/TileEntity.java.patch @@ -56,16 +56,15 @@ tileentity = null; } } else { -@@ -130,8 +139,6 @@ +@@ -130,7 +139,6 @@ } } - /** Returns the square of the distance between this entity and the passed in coordinates. */ -- @SideOnly(Side.CLIENT) public double getDistanceSq(double x, double y, double z) { double d0 = this.pos.getX() + 0.5 - x; double d1 = this.pos.getY() + 0.5 - y; -@@ -213,7 +220,7 @@ +@@ -212,7 +220,7 @@ try { return String.format( @@ -74,7 +73,7 @@ ); } catch (Throwable throwable) { return "ID #" + i; -@@ -267,6 +274,177 @@ +@@ -266,6 +274,177 @@ public void mirror(Mirror mirrorIn) { } diff --git a/module/minecraft/patches/net/minecraft/util/BlockRenderLayer.java.patch b/module/minecraft/patches/net/minecraft/util/BlockRenderLayer.java.patch deleted file mode 100644 index 4a82974e8..000000000 --- a/module/minecraft/patches/net/minecraft/util/BlockRenderLayer.java.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- original/net/minecraft/util/BlockRenderLayer.java -+++ modified/net/minecraft/util/BlockRenderLayer.java -@@ -1,9 +1,5 @@ - package net.minecraft.util; - --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; -- --@SideOnly(Side.CLIENT) - public enum BlockRenderLayer { - SOLID("Solid"), - CUTOUT_MIPPED("Mipped Cutout"), diff --git a/module/minecraft/patches/net/minecraft/util/EnumFacing.java.patch b/module/minecraft/patches/net/minecraft/util/EnumFacing.java.patch index 0165be7c1..74546cb42 100644 --- a/module/minecraft/patches/net/minecraft/util/EnumFacing.java.patch +++ b/module/minecraft/patches/net/minecraft/util/EnumFacing.java.patch @@ -1,71 +1,34 @@ --- original/net/minecraft/util/EnumFacing.java +++ modified/net/minecraft/util/EnumFacing.java -@@ -12,8 +12,6 @@ - import net.minecraft.util.math.BlockPos; - import net.minecraft.util.math.MathHelper; - import net.minecraft.util.math.Vec3i; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; - - public enum EnumFacing implements IStringSerializable { - DOWN(0, 1, -1, "down", EnumFacing.AxisDirection.NEGATIVE, EnumFacing.Axis.Y, new Vec3i(0, -1, 0)), -@@ -78,8 +76,6 @@ +@@ -76,7 +76,6 @@ return byIndex(this.opposite); } - /** Rotate this Facing around the given axis clockwise. If this facing cannot be rotated around the given axis, returns this facing without rotating. */ -- @SideOnly(Side.CLIENT) public EnumFacing rotateAround(EnumFacing.Axis axis) { switch (axis) { case X: -@@ -121,8 +117,6 @@ +@@ -118,7 +117,6 @@ } } - /** Rotate this Facing around the X axis (NORTH => DOWN => SOUTH => UP => NORTH) */ -- @SideOnly(Side.CLIENT) private EnumFacing rotateX() { switch (this) { case NORTH: -@@ -140,8 +134,6 @@ +@@ -136,7 +134,6 @@ } } - /** Rotate this Facing around the Z axis (EAST => DOWN => WEST => UP => EAST) */ -- @SideOnly(Side.CLIENT) private EnumFacing rotateZ() { switch (this) { case EAST: -@@ -200,7 +192,6 @@ - - /** Get the facing specified by the given name */ - @Nullable -- @SideOnly(Side.CLIENT) - public static EnumFacing byName(String name) { - return name == null ? null : NAME_LOOKUP.get(name.toLowerCase(Locale.ROOT)); - } -@@ -230,7 +221,6 @@ - return values()[rand.nextInt(values().length)]; - } - -- @SideOnly(Side.CLIENT) - public static EnumFacing getFacingFromVector(float x, float y, float z) { - EnumFacing enumfacing = NORTH; - float f = Float.MIN_VALUE; -@@ -284,8 +274,6 @@ +@@ -277,7 +274,6 @@ return placer.getHorizontalFacing().getOpposite(); } - /** Get a normalized Vector that points in the direction of this Facing. */ -- @SideOnly(Side.CLIENT) public Vec3i getDirectionVec() { return this.directionVec; } -@@ -317,7 +305,6 @@ - - /** Get the axis specified by the given name */ - @Nullable -- @SideOnly(Side.CLIENT) - public static EnumFacing.Axis byName(String name) { - return name == null ? null : NAME_LOOKUP.get(name.toLowerCase(Locale.ROOT)); - } diff --git a/module/minecraft/patches/net/minecraft/util/IntIdentityHashBiMap.java.patch b/module/minecraft/patches/net/minecraft/util/IntIdentityHashBiMap.java.patch index 93345fe4c..0ed736cd4 100644 --- a/module/minecraft/patches/net/minecraft/util/IntIdentityHashBiMap.java.patch +++ b/module/minecraft/patches/net/minecraft/util/IntIdentityHashBiMap.java.patch @@ -1,10 +1,11 @@ --- original/net/minecraft/util/IntIdentityHashBiMap.java +++ modified/net/minecraft/util/IntIdentityHashBiMap.java -@@ -141,7 +141,6 @@ - return Iterators.filter(Iterators.forArray(this.byId), Predicates.notNull()); - } +@@ -6,6 +6,8 @@ + import java.util.Iterator; + import javax.annotation.Nullable; + import net.minecraft.util.math.MathHelper; ++import net.minecraftforge.fml.relauncher.Side; ++import net.minecraftforge.fml.relauncher.SideOnly; -- @SideOnly(Side.CLIENT) - public void clear() { - Arrays.fill(this.values, null); - Arrays.fill(this.byId, null); + public class IntIdentityHashBiMap implements IObjectIntIterable { + private static final Object EMPTY = null; diff --git a/module/minecraft/patches/net/minecraft/util/math/Vec2f.java.patch b/module/minecraft/patches/net/minecraft/util/math/Vec2f.java.patch deleted file mode 100644 index 805dd8d97..000000000 --- a/module/minecraft/patches/net/minecraft/util/math/Vec2f.java.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- original/net/minecraft/util/math/Vec2f.java -+++ modified/net/minecraft/util/math/Vec2f.java -@@ -1,9 +1,5 @@ - package net.minecraft.util.math; - --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; -- --@SideOnly(Side.CLIENT) - public class Vec2f { - /** An immutable vector with {@code 0.0F} as the x and y components. */ - public static final Vec2f ZERO = new Vec2f(0.0F, 0.0F); diff --git a/module/minecraft/patches/net/minecraft/util/math/Vec3d.java.patch b/module/minecraft/patches/net/minecraft/util/math/Vec3d.java.patch index 2288ffa1c..4481c464a 100644 --- a/module/minecraft/patches/net/minecraft/util/math/Vec3d.java.patch +++ b/module/minecraft/patches/net/minecraft/util/math/Vec3d.java.patch @@ -1,44 +1,31 @@ --- original/net/minecraft/util/math/Vec3d.java +++ modified/net/minecraft/util/math/Vec3d.java -@@ -1,9 +1,6 @@ +@@ -1,7 +1,6 @@ package net.minecraft.util.math; import javax.annotation.Nullable; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; - public class Vec3d { public static final Vec3d ZERO = new Vec3d(0.0, 0.0, 0.0); /** X coordinate of Vec3D */ -@@ -54,8 +51,6 @@ +@@ -52,7 +51,6 @@ return this.x * vec.x + this.y * vec.y + this.z * vec.z; } - /** Returns a new vector with the result of this vector x the specified vector. */ -- @SideOnly(Side.CLIENT) public Vec3d crossProduct(Vec3d vec) { return new Vec3d( this.y * vec.z - this.z * vec.y, -@@ -115,7 +110,6 @@ - ); - } - -- @SideOnly(Side.CLIENT) - public double lengthSquared() { - return this.x * this.x + this.y * this.y + this.z * this.z; - } -@@ -211,14 +205,10 @@ +@@ -207,12 +205,10 @@ return new Vec3d(d0, d1, d2); } - /** returns a Vec3d from given pitch and yaw degrees as Vec2f */ -- @SideOnly(Side.CLIENT) public static Vec3d fromPitchYaw(Vec2f p_189984_0_) { return fromPitchYaw(p_189984_0_.x, p_189984_0_.y); } - /** returns a Vec3d from given pitch and yaw degrees */ -- @SideOnly(Side.CLIENT) public static Vec3d fromPitchYaw(float p_189986_0_, float p_189986_1_) { float f = MathHelper.cos(-p_189986_1_ * (float) (Math.PI / 180.0) - (float) Math.PI); float f1 = MathHelper.sin(-p_189986_1_ * (float) (Math.PI / 180.0) - (float) Math.PI); diff --git a/module/minecraft/patches/net/minecraft/util/text/ITextComponent.java.patch b/module/minecraft/patches/net/minecraft/util/text/ITextComponent.java.patch index 126ccf39e..26709e281 100644 --- a/module/minecraft/patches/net/minecraft/util/text/ITextComponent.java.patch +++ b/module/minecraft/patches/net/minecraft/util/text/ITextComponent.java.patch @@ -1,11 +1,19 @@ --- original/net/minecraft/util/text/ITextComponent.java +++ modified/net/minecraft/util/text/ITextComponent.java -@@ -53,8 +53,6 @@ +@@ -17,6 +17,8 @@ + import javax.annotation.Nullable; + import net.minecraft.util.EnumTypeAdapterFactory; + import net.minecraft.util.JsonUtils; ++import net.minecraftforge.fml.relauncher.Side; ++import net.minecraftforge.fml.relauncher.SideOnly; + + public interface ITextComponent extends Iterable { + /** Sets the style of this component and updates the parent style of all of the sibling components. */ +@@ -51,7 +53,6 @@ /** Gets the text of this component and all sibling components, without any formatting codes. */ String getUnformattedText(); - /** Gets the text of this component and all sibling components, with formatting codes added for rendering. */ -- @SideOnly(Side.CLIENT) String getFormattedText(); /** Gets the sibling components of this one. */ diff --git a/module/minecraft/patches/net/minecraft/util/text/Style.java.patch b/module/minecraft/patches/net/minecraft/util/text/Style.java.patch index ebf969de5..73da1009c 100644 --- a/module/minecraft/patches/net/minecraft/util/text/Style.java.patch +++ b/module/minecraft/patches/net/minecraft/util/text/Style.java.patch @@ -1,6 +1,15 @@ --- original/net/minecraft/util/text/Style.java +++ modified/net/minecraft/util/text/Style.java -@@ -157,13 +157,6 @@ +@@ -12,6 +12,8 @@ + import javax.annotation.Nullable; + import net.minecraft.util.text.event.ClickEvent; + import net.minecraft.util.text.event.HoverEvent; ++import net.minecraftforge.fml.relauncher.Side; ++import net.minecraftforge.fml.relauncher.SideOnly; + + public class Style { + /** The parent of this ChatStyle. Used for looking up values that this instance does not override. */ +@@ -155,12 +157,6 @@ public Style createDeepCopy() { return this; } @@ -10,11 +19,10 @@ - * - * @return A formatted string that can be combined with text to produce this style. - */ -- @SideOnly(Side.CLIENT) @Override public String getFormattingCode() { return ""; -@@ -292,12 +285,6 @@ +@@ -289,11 +285,6 @@ return this; } @@ -23,7 +31,6 @@ - * - * @return A formatted string that can be combined with text to produce this style. - */ -- @SideOnly(Side.CLIENT) public String getFormattingCode() { if (this.isEmpty()) { return this.parentStyle != null ? this.parentStyle.getFormattingCode() : ""; diff --git a/module/minecraft/patches/net/minecraft/util/text/TextComponentBase.java.patch b/module/minecraft/patches/net/minecraft/util/text/TextComponentBase.java.patch index f05069a32..3bb6fded4 100644 --- a/module/minecraft/patches/net/minecraft/util/text/TextComponentBase.java.patch +++ b/module/minecraft/patches/net/minecraft/util/text/TextComponentBase.java.patch @@ -1,11 +1,19 @@ --- original/net/minecraft/util/text/TextComponentBase.java +++ modified/net/minecraft/util/text/TextComponentBase.java -@@ -91,8 +91,6 @@ +@@ -6,6 +6,8 @@ + import java.util.Iterator; + import java.util.List; + import javax.annotation.Nullable; ++import net.minecraftforge.fml.relauncher.Side; ++import net.minecraftforge.fml.relauncher.SideOnly; + + public abstract class TextComponentBase implements ITextComponent { + /** The later siblings of this component. If this component turns the text bold, that will apply to all the siblings until a later sibling turns the text something else. */ +@@ -89,7 +91,6 @@ return stringbuilder.toString(); } - /** Gets the text of this component and all sibling components, with formatting codes added for rendering. */ -- @SideOnly(Side.CLIENT) @Override public final String getFormattedText() { StringBuilder stringbuilder = new StringBuilder(); diff --git a/module/minecraft/patches/net/minecraft/world/BossInfo.java.patch b/module/minecraft/patches/net/minecraft/world/BossInfo.java.patch deleted file mode 100644 index 9dd9f52f6..000000000 --- a/module/minecraft/patches/net/minecraft/world/BossInfo.java.patch +++ /dev/null @@ -1,27 +0,0 @@ ---- original/net/minecraft/world/BossInfo.java -+++ modified/net/minecraft/world/BossInfo.java -@@ -2,8 +2,6 @@ - - import java.util.UUID; - import net.minecraft.util.text.ITextComponent; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; - - public abstract class BossInfo { - private final UUID uniqueId; -@@ -47,7 +45,6 @@ - return this.color; - } - -- @SideOnly(Side.CLIENT) - public void setColor(BossInfo.Color colorIn) { - this.color = colorIn; - } -@@ -56,7 +53,6 @@ - return this.overlay; - } - -- @SideOnly(Side.CLIENT) - public void setOverlay(BossInfo.Overlay overlayIn) { - this.overlay = overlayIn; - } diff --git a/module/minecraft/patches/net/minecraft/world/BossInfoServer.java.patch b/module/minecraft/patches/net/minecraft/world/BossInfoServer.java.patch deleted file mode 100644 index af5ac3bfc..000000000 --- a/module/minecraft/patches/net/minecraft/world/BossInfoServer.java.patch +++ /dev/null @@ -1,27 +0,0 @@ ---- original/net/minecraft/world/BossInfoServer.java -+++ modified/net/minecraft/world/BossInfoServer.java -@@ -9,8 +9,6 @@ - import net.minecraft.network.play.server.SPacketUpdateBossInfo; - import net.minecraft.util.math.MathHelper; - import net.minecraft.util.text.ITextComponent; --import net.minecraftforge.fml.relauncher.Side; --import net.minecraftforge.fml.relauncher.SideOnly; - - public class BossInfoServer extends BossInfo { - private final Set players = Sets.newHashSet(); -@@ -29,7 +27,6 @@ - } - } - -- @SideOnly(Side.CLIENT) - @Override - public void setColor(BossInfo.Color colorIn) { - if (colorIn != this.color) { -@@ -38,7 +35,6 @@ - } - } - -- @SideOnly(Side.CLIENT) - @Override - public void setOverlay(BossInfo.Overlay overlayIn) { - if (overlayIn != this.overlay) { diff --git a/module/minecraft/patches/net/minecraft/world/World.java.patch b/module/minecraft/patches/net/minecraft/world/World.java.patch index 4240d8cd4..eff370517 100644 --- a/module/minecraft/patches/net/minecraft/world/World.java.patch +++ b/module/minecraft/patches/net/minecraft/world/World.java.patch @@ -310,16 +310,15 @@ } /** Schedule the entity for removal during the next tick. Marks the entity dead in anticipation. */ -@@ -1134,8 +1188,6 @@ +@@ -1134,7 +1188,6 @@ this.eventListeners.add(listener); } - /** Remove a world event listener */ -- @SideOnly(Side.CLIENT) public void removeEventListener(IWorldEventListener listener) { this.eventListeners.remove(listener); } -@@ -1162,6 +1214,7 @@ +@@ -1161,6 +1214,7 @@ IBlockState iblockstate = Blocks.STONE.getDefaultState(); BlockPos.PooledMutableBlockPos blockpos$pooledmutableblockpos = BlockPos.PooledMutableBlockPos.retain(); @@ -327,7 +326,7 @@ try { for (int k1 = i; k1 < j; k1++) { for (int l1 = i1; l1 < j1; l1++) { -@@ -1187,7 +1240,8 @@ +@@ -1186,7 +1240,8 @@ } iblockstate1.addCollisionBoxToList(this, blockpos$pooledmutableblockpos, aabb, outList, entityIn, false); @@ -337,7 +336,7 @@ return true; } } -@@ -1224,7 +1278,7 @@ +@@ -1223,7 +1278,7 @@ } } } @@ -346,7 +345,7 @@ return list; } -@@ -1255,19 +1309,36 @@ +@@ -1254,19 +1309,36 @@ /** Returns the amount of skylight subtracted for the current time */ public int calculateSkylightSubtracted(float partialTicks) { @@ -385,7 +384,7 @@ float f = this.getCelestialAngle(partialTicks); float f1 = 1.0F - (MathHelper.cos(f * (float) (Math.PI * 2)) * 2.0F + 0.2F); f1 = MathHelper.clamp(f1, 0.0F, 1.0F); -@@ -1280,6 +1351,11 @@ +@@ -1279,6 +1351,11 @@ /** Calculates the color for the skybox */ @SideOnly(Side.CLIENT) public Vec3d getSkyColor(Entity entityIn, float partialTicks) { @@ -397,7 +396,7 @@ float f = this.getCelestialAngle(partialTicks); float f1 = MathHelper.cos(f * (float) (Math.PI * 2)) * 2.0F + 0.5F; f1 = MathHelper.clamp(f1, 0.0F, 1.0F); -@@ -1287,9 +1363,7 @@ +@@ -1286,9 +1363,7 @@ int j = MathHelper.floor(entityIn.posY); int k = MathHelper.floor(entityIn.posZ); BlockPos blockpos = new BlockPos(i, j, k); @@ -408,7 +407,7 @@ float f3 = (l >> 16 & 0xFF) / 255.0F; float f4 = (l >> 8 & 0xFF) / 255.0F; float f5 = (l & 0xFF) / 255.0F; -@@ -1331,19 +1405,23 @@ +@@ -1330,19 +1405,23 @@ /** calls calculateCelestialAngle */ public float getCelestialAngle(float partialTicks) { @@ -435,7 +434,7 @@ /** Return getCelestialAngle()*2*PI */ public float getCelestialAngleRadians(float partialTicks) { float f = this.getCelestialAngle(partialTicks); -@@ -1352,6 +1430,11 @@ +@@ -1351,6 +1430,11 @@ @SideOnly(Side.CLIENT) public Vec3d getCloudColour(float partialTicks) { @@ -447,7 +446,7 @@ float f = this.getCelestialAngle(partialTicks); float f1 = MathHelper.cos(f * (float) (Math.PI * 2)) * 2.0F + 0.5F; f1 = MathHelper.clamp(f1, 0.0F, 1.0F); -@@ -1400,8 +1483,9 @@ +@@ -1399,8 +1483,9 @@ while (blockpos.getY() >= 0) { BlockPos blockpos1 = blockpos.down(); @@ -459,7 +458,7 @@ break; } -@@ -1414,6 +1498,11 @@ +@@ -1413,6 +1498,11 @@ /** How bright are stars in the sky */ @SideOnly(Side.CLIENT) public float getStarBrightness(float partialTicks) { @@ -471,7 +470,7 @@ float f = this.getCelestialAngle(partialTicks); float f1 = 1.0F - (MathHelper.cos(f * (float) (Math.PI * 2)) * 2.0F + 0.25F); f1 = MathHelper.clamp(f1, 0.0F, 1.0F); -@@ -1444,17 +1533,23 @@ +@@ -1443,17 +1533,23 @@ Entity entity = this.weatherEffects.get(i); try { @@ -495,7 +494,7 @@ throw new ReportedException(crashreport); } -@@ -1470,6 +1565,7 @@ +@@ -1469,6 +1565,7 @@ Entity entity1 = this.unloadedEntityList.get(k); int j = entity1.chunkCoordX; int k1 = entity1.chunkCoordZ; @@ -503,7 +502,7 @@ if (entity1.addedToChunk && this.isChunkLoaded(j, k1, true)) { this.getChunk(j, k1).removeEntity(entity1); } -@@ -1486,6 +1582,7 @@ +@@ -1485,6 +1582,7 @@ for (int i1 = 0; i1 < this.loadedEntityList.size(); i1++) { Entity entity2 = this.loadedEntityList.get(i1); Entity entity3 = entity2.getRidingEntity(); @@ -511,7 +510,7 @@ if (entity3 != null) { if (!entity3.isDead && entity3.isPassenger(entity2)) { continue; -@@ -1495,22 +1592,31 @@ +@@ -1494,22 +1592,31 @@ } this.profiler.startSection("tick"); @@ -543,7 +542,7 @@ if (entity2.addedToChunk && this.isChunkLoaded(l1, i2, true)) { this.getChunk(l1, i2).removeEntity(entity2); } -@@ -1523,28 +1629,46 @@ +@@ -1522,28 +1629,46 @@ } this.profiler.endStartSection("blockEntities"); @@ -595,7 +594,7 @@ throw new ReportedException(crashreport2); } } -@@ -1553,17 +1677,23 @@ +@@ -1552,17 +1677,23 @@ if (tileentity.isInvalid()) { iterator.remove(); this.loadedTileEntityList.remove(tileentity); @@ -620,7 +619,7 @@ if (!tileentity1.isInvalid()) { if (!this.loadedTileEntityList.contains(tileentity1)) { this.addTileEntity(tileentity1); -@@ -1589,10 +1719,16 @@ +@@ -1588,10 +1719,16 @@ } public boolean addTileEntity(TileEntity tile) { @@ -637,7 +636,7 @@ if (this.isRemote) { BlockPos blockpos = tile.getPos(); -@@ -1605,6 +1741,10 @@ +@@ -1604,6 +1741,10 @@ public void addTileEntities(Collection tileEntityCollection) { if (this.processingLoadedTiles) { @@ -648,7 +647,7 @@ this.addedTileEntityList.addAll(tileEntityCollection); } else { for (TileEntity tileentity : tileEntityCollection) { -@@ -1623,8 +1763,13 @@ +@@ -1622,8 +1763,13 @@ if (!(entityIn instanceof EntityPlayer)) { int i = MathHelper.floor(entityIn.posX); int j = MathHelper.floor(entityIn.posZ); @@ -664,7 +663,7 @@ return; } } -@@ -1639,6 +1784,7 @@ +@@ -1638,6 +1784,7 @@ if (entityIn.isRiding()) { entityIn.updateRidden(); } else { @@ -672,7 +671,7 @@ entityIn.onUpdate(); } } -@@ -1702,7 +1848,8 @@ +@@ -1701,7 +1848,8 @@ for (int i = 0; i < list.size(); i++) { Entity entity = list.get(i); @@ -682,7 +681,7 @@ return false; } } -@@ -1750,6 +1897,13 @@ +@@ -1749,6 +1897,13 @@ for (int l1 = k; l1 < l; l1++) { for (int i2 = i1; i2 < j1; i2++) { IBlockState iblockstate = this.getBlockState(blockpos$pooledmutableblockpos.setPos(k1, l1, i2)); @@ -696,7 +695,7 @@ if (iblockstate.getMaterial().isLiquid()) { blockpos$pooledmutableblockpos.release(); return true; -@@ -1779,6 +1933,9 @@ +@@ -1778,6 +1933,9 @@ if (block == Blocks.FIRE || block == Blocks.FLOWING_LAVA || block == Blocks.LAVA) { blockpos$pooledmutableblockpos.release(); return true; @@ -706,7 +705,7 @@ } } } -@@ -1798,41 +1955,53 @@ +@@ -1797,41 +1955,53 @@ int l = MathHelper.ceil(bb.maxY); int i1 = MathHelper.floor(bb.minZ); int j1 = MathHelper.ceil(bb.maxZ); @@ -783,7 +782,7 @@ } /** Returns true if the given bounding box contains the given material */ -@@ -1848,10 +2017,17 @@ +@@ -1847,10 +2017,17 @@ for (int k1 = i; k1 < j; k1++) { for (int l1 = k; l1 < l; l1++) { for (int i2 = i1; i2 < j1; i2++) { @@ -802,7 +801,7 @@ } } } -@@ -1870,6 +2046,7 @@ +@@ -1869,6 +2046,7 @@ @Nullable Entity entityIn, double x, double y, double z, float strength, boolean causesFire, boolean damagesTerrain ) { Explosion explosion = new Explosion(this, entityIn, x, y, z, strength, causesFire, damagesTerrain); @@ -810,7 +809,7 @@ explosion.doExplosionA(); explosion.doExplosionB(true); return explosion; -@@ -1967,23 +2144,29 @@ +@@ -1966,23 +2144,29 @@ } public void setTileEntity(BlockPos pos, @Nullable TileEntity tileEntityIn) { @@ -842,7 +841,7 @@ this.addTileEntity(tileEntityIn); } } -@@ -1995,6 +2178,8 @@ +@@ -1994,6 +2178,8 @@ if (tileentity != null && this.processingLoadedTiles) { tileentity.invalidate(); this.addedTileEntityList.remove(tileentity); @@ -851,7 +850,7 @@ } else { if (tileentity != null) { this.addedTileEntityList.remove(tileentity); -@@ -2004,6 +2189,7 @@ +@@ -2003,6 +2189,7 @@ this.getChunk(pos).removeTileEntity(pos); } @@ -859,7 +858,7 @@ } /** Adds the specified TileEntity to the pending removal list. */ -@@ -2024,7 +2210,7 @@ +@@ -2023,7 +2210,7 @@ Chunk chunk = this.chunkProvider.getLoadedChunk(pos.getX() >> 4, pos.getZ() >> 4); if (chunk != null && !chunk.isEmpty()) { IBlockState iblockstate = this.getBlockState(pos); @@ -868,7 +867,7 @@ } else { return _default; } -@@ -2043,6 +2229,7 @@ +@@ -2042,6 +2229,7 @@ public void setAllowedSpawnTypes(boolean hostile, boolean peaceful) { this.spawnHostileMobs = hostile; this.spawnPeacefulMobs = peaceful; @@ -876,7 +875,7 @@ } /** Runs a single tick for the world */ -@@ -2052,6 +2239,10 @@ +@@ -2051,6 +2239,10 @@ /** Called from World constructor to set rainingStrength and thunderingStrength */ protected void calculateInitialWeather() { @@ -887,7 +886,7 @@ if (this.worldInfo.isRaining()) { this.rainingStrength = 1.0F; if (this.worldInfo.isThundering()) { -@@ -2062,6 +2253,10 @@ +@@ -2061,6 +2253,10 @@ /** Updates all weather states. */ protected void updateWeather() { @@ -898,7 +897,7 @@ if (this.provider.hasSkyLight()) { if (!this.isRemote) { boolean flag = this.getGameRules().getBoolean("doWeatherCycle"); -@@ -2146,6 +2341,10 @@ +@@ -2145,6 +2341,10 @@ /** Checks to see if a given block is both water and cold enough to freeze. */ public boolean canBlockFreeze(BlockPos pos, boolean noWaterAdj) { @@ -909,7 +908,7 @@ Biome biome = this.getBiome(pos); float f = biome.getTemperature(pos); if (f >= 0.15F) { -@@ -2179,6 +2378,10 @@ +@@ -2178,6 +2378,10 @@ /** Checks to see if a given block can accumulate snow from it snowing */ public boolean canSnowAt(BlockPos pos, boolean checkLight) { @@ -920,7 +919,7 @@ Biome biome = this.getBiome(pos); float f = biome.getTemperature(pos); if (f >= 0.15F) { -@@ -2191,7 +2394,7 @@ +@@ -2190,7 +2394,7 @@ if (pos.getY() >= 0 && pos.getY() < 256 && this.getLightFor(EnumSkyBlock.BLOCK, pos) < 10) { IBlockState iblockstate = this.getBlockState(pos); @@ -929,7 +928,7 @@ return true; } } -@@ -2212,153 +2415,163 @@ +@@ -2211,153 +2415,163 @@ private int getRawLight(BlockPos pos, EnumSkyBlock lightType) { if (lightType == EnumSkyBlock.SKY && this.canSeeSky(pos)) { return 15; @@ -1203,7 +1202,7 @@ } /** Runs through the list of updates to run and ticks them */ -@@ -2384,10 +2597,10 @@ +@@ -2383,10 +2597,10 @@ /** Gets all entities within the specified AABB excluding the one passed into it. */ public List getEntitiesInAABBexcluding(@Nullable Entity entityIn, AxisAlignedBB boundingBox, @Nullable Predicate predicate) { List list = Lists.newArrayList(); @@ -1218,7 +1217,7 @@ for (int i1 = i; i1 <= j; i1++) { for (int j1 = k; j1 <= l; j1++) { -@@ -2430,10 +2643,10 @@ +@@ -2429,10 +2643,10 @@ } public List getEntitiesWithinAABB(Class clazz, AxisAlignedBB aabb, @Nullable Predicate filter) { @@ -1233,7 +1232,7 @@ List list = Lists.newArrayList(); for (int i1 = i; i1 < j; i1++) { -@@ -2499,10 +2712,11 @@ +@@ -2498,10 +2712,11 @@ } public void loadEntities(Collection entityCollection) { @@ -1248,7 +1247,7 @@ } } -@@ -2514,7 +2728,9 @@ +@@ -2513,7 +2728,9 @@ public boolean mayPlace(Block blockIn, BlockPos pos, boolean skipCollisionCheck, EnumFacing sidePlacedOn, @Nullable Entity placer) { IBlockState iblockstate = this.getBlockState(pos); AxisAlignedBB axisalignedbb = skipCollisionCheck ? null : blockIn.getDefaultState().getCollisionBoundingBox(this, pos); @@ -1259,7 +1258,7 @@ return false; } else { return iblockstate.getMaterial() == Material.CIRCUITS && blockIn == Blocks.ANVIL -@@ -2580,7 +2796,7 @@ +@@ -2579,7 +2796,7 @@ public int getRedstonePower(BlockPos pos, EnumFacing facing) { IBlockState iblockstate = this.getBlockState(pos); @@ -1268,7 +1267,7 @@ } public boolean isBlockPowered(BlockPos pos) { -@@ -2717,6 +2933,8 @@ +@@ -2716,6 +2933,8 @@ d2 *= MoreObjects.firstNonNull(playerToDouble.apply(entityplayer1), 1.0); } @@ -1277,7 +1276,7 @@ if ((maxYDistance < 0.0 || Math.abs(entityplayer1.posY - posY) < maxYDistance * maxYDistance) && (maxXZDistance < 0.0 || d1 < d2 * d2) && (d0 == -1.0 || d1 < d0)) { -@@ -2771,7 +2989,7 @@ +@@ -2770,7 +2989,7 @@ /** gets the random world seed */ public long getSeed() { @@ -1286,7 +1285,7 @@ } public long getTotalWorldTime() { -@@ -2779,17 +2997,18 @@ +@@ -2778,17 +2997,18 @@ } public long getWorldTime() { @@ -1308,7 +1307,7 @@ if (!this.getWorldBorder().contains(blockpos)) { blockpos = this.getHeight(new BlockPos(this.getWorldBorder().getCenterX(), 0.0, this.getWorldBorder().getCenterZ())); } -@@ -2798,7 +3017,7 @@ +@@ -2797,7 +3017,7 @@ } public void setSpawnPoint(BlockPos pos) { @@ -1317,7 +1316,7 @@ } /** spwans an entity and loads surrounding chunks */ -@@ -2815,11 +3034,16 @@ +@@ -2814,11 +3034,16 @@ } if (!this.loadedEntityList.contains(entityIn)) { @@ -1334,7 +1333,7 @@ return true; } -@@ -2907,8 +3131,7 @@ +@@ -2906,8 +3131,7 @@ } public boolean isBlockinHighHumidity(BlockPos pos) { @@ -1344,7 +1343,7 @@ } @Nullable -@@ -2960,12 +3183,12 @@ +@@ -2959,12 +3183,12 @@ /** Returns maximum world height. */ public int getHeight() { @@ -1359,7 +1358,7 @@ } /** puts the World Random seed to a specific state dependant on the inputs */ -@@ -2978,7 +3201,7 @@ +@@ -2977,7 +3201,7 @@ /** Returns horizon height for use in rendering the sky. */ @SideOnly(Side.CLIENT) public double getHorizon() { @@ -1368,7 +1367,7 @@ } /** Adds some basic stats of the world to the given crash report. */ -@@ -3032,17 +3255,18 @@ +@@ -3031,17 +3255,18 @@ } public void updateComparatorOutputLevel(BlockPos pos, Block blockIn) { @@ -1393,7 +1392,7 @@ } } } -@@ -3098,6 +3322,107 @@ +@@ -3097,6 +3322,107 @@ return i >= -128 && i <= 128 && j >= -128 && j <= 128; } From f4744c246148a48f1d779f753923d41448272697 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Thu, 20 Aug 2026 01:03:43 +0100 Subject: [PATCH 83/99] Better memory management in Clipboard --- .../com/cleanroommc/client/sdl/Clipboard.java | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Clipboard.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Clipboard.java index c823cf561..940bec7d3 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Clipboard.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Clipboard.java @@ -39,8 +39,7 @@ public static boolean hasText() { } public static String text() { - String value = SDLClipboard.SDL_GetClipboardText(); - String text = value == null ? "" : value; + String text = hasText() ? SDLClipboard.SDL_GetClipboardText() : ""; cache(!text.isEmpty()); return text; } @@ -58,8 +57,10 @@ public static boolean hasPrimary() { } public static String primary() { - String value = SDLClipboard.SDL_GetPrimarySelectionText(); - return value == null ? "" : value; + if (hasPrimary()) { + return SDLClipboard.SDL_GetPrimarySelectionText(); + } + return ""; } public static void primary(String value) { @@ -135,10 +136,21 @@ static boolean cacheValid() { return textKnown; } - public static void reset() { + public static synchronized void reset() { textKnown = false; hasText = false; + if (imageData != null) { + SDLClipboard.SDL_ClearClipboardData(); + } clearOffer(); + if (imageData != null) { + imageData.free(); + imageData = null; + } + if (imageCleanup != null) { + imageCleanup.free(); + imageCleanup = null; + } } private static BufferedImage decode(ByteBuffer bytes, boolean png) { @@ -186,6 +198,9 @@ private static ByteBuffer encodePng(SDL_Surface surface) { } private static synchronized void offer(ByteBuffer png) { + if (imageData != null) { + SDLClipboard.SDL_ClearClipboardData(); + } clearOffer(); offeredImage = png; if (imageData == null) { From 6fcab5b754da40b4f7a55545d7a7e83e0e56f901 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Thu, 20 Aug 2026 01:15:37 +0100 Subject: [PATCH 84/99] More cleanups --- .../com/cleanroommc/client/sdl/Devices.java | 1 + .../cleanroommc/client/sdl/FileDialogs.java | 72 ++++++++++++++----- .../java/com/cleanroommc/client/sdl/Tray.java | 3 + .../cleanroommc/client/sdl/input/Haptic.java | 25 +++++-- .../client/sdl/input/Joystick.java | 5 +- 5 files changed, 81 insertions(+), 25 deletions(-) diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Devices.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Devices.java index 471d65788..0518beaa1 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Devices.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Devices.java @@ -16,6 +16,7 @@ static void dispatch(SDL_Event event) { static void afterPump() { Tray.pump(); + FileDialogs.pump(); } static void reset() { diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/FileDialogs.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/FileDialogs.java index dacf44b65..0609cbe0c 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/FileDialogs.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/FileDialogs.java @@ -8,11 +8,15 @@ import org.lwjgl.sdl.SDL_MessageBoxData; import org.lwjgl.system.MemoryStack; import org.lwjgl.system.MemoryUtil; +import org.lwjgl.system.Pointer; +import java.nio.ByteBuffer; import java.nio.IntBuffer; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; import java.util.function.Consumer; /** @@ -32,6 +36,8 @@ public Button(int id, String text) { } + private static final Queue PENDING_RELEASE = new ConcurrentLinkedQueue<>(); + public static void error(Window window, String title, String message) { box(SDLMessageBox.SDL_MESSAGEBOX_ERROR, window, title, message); } @@ -93,34 +99,49 @@ public static void openFolder(Window window, boolean many, Consumer> fileDialog(window, List.of(), many, null, false, true, onResult); } + /** Releases the native memory of dialogs that completed during the last {@link Window#pump()}. */ + static void pump() { + Runnable release; + while ((release = PENDING_RELEASE.poll()) != null) { + release.run(); + } + } + private static void fileDialog(Window window, List filters, boolean many, String location, boolean openFile, boolean folder, Consumer> onResult) { if (onResult == null) { throw new IllegalArgumentException("onResult cannot be null"); } + List strings = new ArrayList<>(); + SDL_DialogFileFilter.Buffer nativeFilters = null; + if (filters != null && !filters.isEmpty()) { + nativeFilters = SDL_DialogFileFilter.calloc(filters.size()); + for (int i = 0; i < filters.size(); i++) { + Filter filter = filters.get(i); + ByteBuffer name = MemoryUtil.memUTF8(filter.name()); + ByteBuffer pattern = MemoryUtil.memUTF8(filter.pattern()); + strings.add(name); + strings.add(pattern); + nativeFilters.get(i).name(name).pattern(pattern); + } + } + ByteBuffer where = location == null || location.isEmpty() ? null : MemoryUtil.memUTF8(location); + if (where != null) { + strings.add(where); + } + + SDL_DialogFileFilter.Buffer ownedFilters = nativeFilters; SDL_DialogFileCallback[] holder = new SDL_DialogFileCallback[1]; holder[0] = SDL_DialogFileCallback.create((userdata, filelist, filter) -> { + SDL_DialogFileCallback callback = holder[0]; try { onResult.accept(readPaths(filelist)); } finally { - if (holder[0] != null) { - holder[0].free(); - } + PENDING_RELEASE.add(() -> release(callback, ownedFilters, strings)); } }); - try (MemoryStack stack = MemoryStack.stackPush()) { - SDL_DialogFileFilter.Buffer nativeFilters = filters == null || filters.isEmpty() - ? null : SDL_DialogFileFilter.calloc(filters.size(), stack); - if (nativeFilters != null) { - for (int i = 0; i < filters.size(); i++) { - Filter filter = filters.get(i); - nativeFilters.get(i) - .name(stack.UTF8(filter.name())) - .pattern(stack.UTF8(filter.pattern())); - } - } + try { long parent = handle(window); - java.nio.ByteBuffer where = (location == null || location.isEmpty()) ? null : stack.UTF8(location); if (folder) { SDLDialog.SDL_ShowOpenFolderDialog(holder[0], 0L, parent, where, many); } else if (openFile) { @@ -128,7 +149,23 @@ private static void fileDialog(Window window, List filters, boolean many } else { SDLDialog.SDL_ShowSaveFileDialog(holder[0], 0L, parent, nativeFilters, where); } + } catch (RuntimeException e) { + release(holder[0], nativeFilters, strings); + throw e; + } + } + + private static void release(SDL_DialogFileCallback callback, SDL_DialogFileFilter.Buffer filters, List strings) { + if (callback != null) { + callback.free(); + } + if (filters != null) { + filters.free(); + } + for (ByteBuffer string : strings) { + MemoryUtil.memFree(string); } + strings.clear(); } private static List readPaths(long filelist) { @@ -136,7 +173,7 @@ private static List readPaths(long filelist) { if (filelist == 0L) { return paths; } - int pointerSize = org.lwjgl.system.Pointer.POINTER_SIZE; + int pointerSize = Pointer.POINTER_SIZE; for (int i = 0; ; i++) { long address = MemoryUtil.memGetAddress(filelist + (long) i * pointerSize); if (address == 0L) { @@ -154,7 +191,8 @@ private static void box(int flags, Window window, String title, String message) SDL.check(SDLMessageBox.SDL_ShowSimpleMessageBox(flags, title == null ? "" : title, message == null ? "" : message, - handle(window)), "SDL_ShowSimpleMessageBox"); + handle(window)), "SDL_ShowSimpleMessageBox" + ); } private static long handle(Window window) { diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Tray.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Tray.java index d81128bee..e70df7db9 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Tray.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Tray.java @@ -108,6 +108,9 @@ public void close() { OPEN.remove(this); } SDLTray.SDL_DestroyTray(handle); + for (SDL_TrayCallback callback : callbacks) { + callback.free(); + } callbacks.clear(); } diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Haptic.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Haptic.java index 303f8be9c..9cd242483 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Haptic.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Haptic.java @@ -23,6 +23,7 @@ private static int clampPercent(int value) { private final int id; private final long handle; + private int leftRightEffect = -1; private boolean rumbleReady; private boolean closed; @@ -78,7 +79,10 @@ public Haptic stopRumble() { /** * Dual-motor left/right effect. Strengths are {@code 0..1}. * - * @return the SDL effect id + *

The effect is uploaded once and updated in place afterwards. + * since a device holds only {@link #maxEffects()} of them at a time. + * + * @return the SDL effect id, which stays the same across calls until {@link #destroy(int)} */ public int leftRight(float large, float small, int durationMs) { ensureOpen(); @@ -90,12 +94,17 @@ public int leftRight(float large, float small, int durationMs) { .length(durationMs) .large_magnitude(Gamepad.toStrength(large)) .small_magnitude(Gamepad.toStrength(small)); - int id = SDLHaptic.SDL_CreateHapticEffect(handle, effect); - if (id < 0) { - throw new SDLException("SDL_CreateHapticEffect failed: " + org.lwjgl.sdl.SDLError.SDL_GetError()); + if (this.leftRightEffect < 0) { + int id = SDLHaptic.SDL_CreateHapticEffect(handle, effect); + if (id < 0) { + throw new SDLException("SDL_CreateHapticEffect failed: " + org.lwjgl.sdl.SDLError.SDL_GetError()); + } + this.leftRightEffect = id; + } else { + SDL.check(SDLHaptic.SDL_UpdateHapticEffect(handle, this.leftRightEffect, effect), "SDL_UpdateHapticEffect"); } - SDL.check(SDLHaptic.SDL_RunHapticEffect(handle, id, 1), "SDL_RunHapticEffect"); - return id; + SDL.check(SDLHaptic.SDL_RunHapticEffect(handle, this.leftRightEffect, 1), "SDL_RunHapticEffect"); + return this.leftRightEffect; } } @@ -108,6 +117,9 @@ public Haptic stop(int effectId) { public Haptic destroy(int effectId) { ensureOpen(); SDLHaptic.SDL_DestroyHapticEffect(handle, effectId); + if (this.leftRightEffect == effectId) { + this.leftRightEffect = -1; + } return this; } @@ -157,6 +169,7 @@ public void close() { return; } closed = true; + this.leftRightEffect = -1; Inputs.haptics().forget(this); SDLHaptic.SDL_CloseHaptic(handle); } diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Joystick.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Joystick.java index 6c4b41644..cf716cab8 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Joystick.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/input/Joystick.java @@ -42,9 +42,10 @@ public String guid() { try (MemoryStack stack = MemoryStack.stackPush()) { SDL_GUID guid = SDL_GUID.malloc(stack); SDLJoystick.SDL_GetJoystickGUID(handle, guid); - ByteBuffer text = stack.malloc(33); + ByteBuffer text = stack.calloc(33); SDLGUID.SDL_GUIDToString(guid, text); - return MemoryUtil.memUTF8(text); + String value = MemoryUtil.memUTF8Safe(MemoryUtil.memAddress(text)); + return value == null ? "" : value; } } From 258fae0a64725704b703108b359aad8de9527cd2 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Thu, 20 Aug 2026 02:26:12 +0100 Subject: [PATCH 85/99] Update kirino submodule --- module/kirino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/kirino b/module/kirino index 9c4fbf931..35fed740b 160000 --- a/module/kirino +++ b/module/kirino @@ -1 +1 @@ -Subproject commit 9c4fbf931fb5627b83d3b81daad3d83d052949ec +Subproject commit 35fed740b5a210c9ed873736cc3a336fc561cead From 054ff51b4d46c79a4234c92c39cb033466b06c7a Mon Sep 17 00:00:00 2001 From: Rongmario Date: Thu, 20 Aug 2026 02:34:45 +0100 Subject: [PATCH 86/99] Proper fullscreen + borderless support --- .../com/cleanroommc/client/sdl/SDLHooks.java | 22 ++++ .../com/cleanroommc/client/sdl/Window.java | 95 +++++++++++++++- .../client/sdl/video/Displays.java | 5 - .../net/minecraft/client/Minecraft.java.patch | 102 ++++++++++-------- 4 files changed, 168 insertions(+), 56 deletions(-) diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SDLHooks.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SDLHooks.java index a9a6ae73e..ea00a3228 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SDLHooks.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/SDLHooks.java @@ -12,9 +12,11 @@ import net.minecraft.client.gui.inventory.GuiEditSign; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.tileentity.TileEntitySign; +import net.minecraft.util.Util; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TextComponentString; import net.minecraft.util.text.TextFormatting; +import net.minecraftforge.common.ForgeEarlyConfig; import org.lwjgl.BufferUtils; import org.lwjgl.input.Keyboard; import org.lwjgl.opengl.GL11; @@ -90,6 +92,26 @@ public static boolean keyboard(GuiScreen screen) { return true; } + public static void applyDisplayMode(boolean fullscreen) { + Window window = Window.main(); + if (window == null) { + return; + } + if (!fullscreen) { + window.fullscreen(false); + return; + } + if (ForgeEarlyConfig.WINDOW_BORDERLESS_REPLACES_FULLSCREEN) { + if (ForgeEarlyConfig.WINDOW_BORDERLESS_WINDOWS_COMPATIBILITY && Util.getOSType() == Util.EnumOS.WINDOWS) { + window.coverDisplay(true, 1); + } else { + window.fullscreenMode(null); + } + return; + } + window.exclusiveFullscreen(); + } + /** * @return whether the input method currently has preedit text */ diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Window.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Window.java index d55943a05..b042dc29b 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Window.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/Window.java @@ -64,9 +64,14 @@ public final class Window implements AutoCloseable { private boolean closeRequested; private boolean resized; private boolean fullscreen; + private boolean covering; private boolean borderless; private boolean minimized; private boolean maximized; + private int restoreX; + private int restoreY; + private int restoreWidth; + private int restoreHeight; private boolean hidden; private boolean resizable; private boolean alwaysOnTop; @@ -211,7 +216,7 @@ public synchronized boolean closeRequested() { } public synchronized boolean fullscreen() { - return fullscreen; + return fullscreen || covering; } public synchronized boolean borderless() { @@ -253,9 +258,15 @@ public synchronized Window title(String title) { public synchronized Window fullscreen(boolean fullscreen) { this.ensureOpen(); - SDL.check(SDLVideo.SDL_SetWindowFullscreen(handle, fullscreen), "SDL_SetWindowFullscreen"); + if (!fullscreen && this.covering) { + return coverDisplay(false, 0); + } + if (fullscreen && this.covering) { + this.coverDisplay(false, 0); + } + SDL.check(SDLVideo.SDL_SetWindowFullscreen(this.handle, fullscreen), "SDL_SetWindowFullscreen"); this.fullscreen = fullscreen; - this.refreshSize(); + this.syncState(); return this; } @@ -449,6 +460,65 @@ public float displayScale() { return SDLVideo.SDL_GetWindowDisplayScale(this.handle); } + public synchronized Window exclusiveFullscreen() { + this.ensureOpen(); + Display display = this.display(); + if (display != null) { + SDL_DisplayMode desktop = SDLVideo.SDL_GetDesktopDisplayMode(display.id()); + if (desktop == null || !SDLVideo.SDL_SetWindowFullscreenMode(this.handle, desktop)) { + SDLVideo.SDL_SetWindowFullscreenMode(this.handle, null); + } + } + return fullscreen(true); + } + + /** + * Covers the current display with a borderless window, or restores the previous windowed geometry. + * {@code heightAdjust} is added to the display height (the Windows DWM 1-pixel workaround). + */ + public synchronized Window coverDisplay(boolean cover, int heightAdjust) { + this.ensureOpen(); + if (cover) { + if (this.fullscreen) { + SDL.check(SDLVideo.SDL_SetWindowFullscreen(this.handle, false), "SDL_SetWindowFullscreen"); + this.fullscreen = false; + this.syncState(); + } + if (this.maximized) { + SDL.check(SDLVideo.SDL_RestoreWindow(this.handle), "SDL_RestoreWindow"); + this.maximized = false; + this.syncState(); + } + if (!this.covering) { + int[] pos = this.position(); + this.restoreX = pos[0]; + this.restoreY = pos[1]; + this.restoreWidth = this.width; + this.restoreHeight = this.height; + this.covering = true; + } + Display display = this.display(); + Display.Bounds bounds = display != null + ? display.bounds() + : new Display.Bounds(this.restoreX, this.restoreY, this.restoreWidth, this.restoreHeight); + this.borderless(true); + this.position(bounds.x(), bounds.y()); + this.size(Math.max(1, bounds.width()), Math.max(1, bounds.height() + heightAdjust)); + this.syncState(); + notifyListeners(listener -> listener.fullscreenChanged(true)); + return this; + } + if (this.covering) { + this.covering = false; + this.borderless(false); + this.position(this.restoreX, this.restoreY); + this.size(Math.max(1, this.restoreWidth), Math.max(1, this.restoreHeight)); + this.syncState(); + notifyListeners(listener -> listener.fullscreenChanged(false)); + } + return this; + } + /** * Exclusive fullscreen using {@code mode}, or borderless desktop fullscreen when {@code mode} is {@code null}. */ @@ -588,7 +658,7 @@ private void dispatch(SDL_Event event) { SDLEvents.SDL_EVENT_DISPLAY_MOVED, SDLEvents.SDL_EVENT_DISPLAY_DESKTOP_MODE_CHANGED, SDLEvents.SDL_EVENT_DISPLAY_CURRENT_MODE_CHANGED, - SDLEvents.SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED -> Displays.handle(type, event.display().displayID()); + SDLEvents.SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED -> { } default -> Devices.dispatch(event); } } @@ -713,7 +783,9 @@ private void window(int type, SDL_WindowEvent event) { } case SDLEvents.SDL_EVENT_WINDOW_LEAVE_FULLSCREEN -> { this.fullscreen = false; - notifyListeners(listener -> listener.fullscreenChanged(false)); + if (!this.covering) { + notifyListeners(listener -> listener.fullscreenChanged(false)); + } } } } @@ -748,7 +820,16 @@ private void ensureOpen() { } } + private void syncState() { + SDLVideo.SDL_SyncWindow(this.handle); + this.refreshSize(); + } + private void refreshSize() { + int previousWidth = this.width; + int previousHeight = this.height; + int previousPixelWidth = this.pixelWidth; + int previousPixelHeight = this.pixelHeight; try (MemoryStack stack = MemoryStack.stackPush()) { IntBuffer w = stack.mallocInt(1); IntBuffer h = stack.mallocInt(1); @@ -761,6 +842,10 @@ private void refreshSize() { this.pixelHeight = h.get(0); } } + if (this.width != previousWidth || this.height != previousHeight + || this.pixelWidth != previousPixelWidth || this.pixelHeight != previousPixelHeight) { + this.resized = true; + } } public synchronized boolean keyDown(int scancode) { diff --git a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/video/Displays.java b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/video/Displays.java index db2ef4195..696d84d88 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/video/Displays.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/client/sdl/video/Displays.java @@ -44,11 +44,6 @@ public static String driver() { return name == null ? "" : name; } - /** Called from the window pump when a display comes or goes. */ - public static void handle(int eventType, int displayId) { - // Display lists are queried live - } - private Displays() { } } diff --git a/module/minecraft/patches/net/minecraft/client/Minecraft.java.patch b/module/minecraft/patches/net/minecraft/client/Minecraft.java.patch index 5ed5b0d2b..64fcc428f 100644 --- a/module/minecraft/patches/net/minecraft/client/Minecraft.java.patch +++ b/module/minecraft/patches/net/minecraft/client/Minecraft.java.patch @@ -181,9 +181,9 @@ - DisplayMode displaymode = Display.getDisplayMode(); - this.displayWidth = Math.max(1, displaymode.getWidth()); - this.displayHeight = Math.max(1, displaymode.getHeight()); -+ window.fullscreen(true); -+ this.displayWidth = window.width(); -+ this.displayHeight = window.height(); ++ com.cleanroommc.client.sdl.SDLHooks.applyDisplayMode(true); ++ this.displayWidth = Math.max(1, window.width()); ++ this.displayHeight = Math.max(1, window.height()); } else { - Display.setDisplayMode(new DisplayMode(this.displayWidth, this.displayHeight)); + window.size(this.displayWidth, this.displayHeight); @@ -277,16 +277,17 @@ if (guiScreenIn instanceof GuiMainMenu || guiScreenIn instanceof GuiMultiplayer) { this.gameSettings.showDebugInfo = false; this.ingameGUI.getChatGUI().clearChatMessages(true); -@@ -962,6 +969,8 @@ +@@ -962,7 +969,8 @@ this.soundHandler.unloadSounds(); } finally { +- Display.destroy(); + com.cleanroommc.kirino.engine.ShutdownManager.runMainHooks(); + com.cleanroommc.client.sdl.SDL.shutdown(); - Display.destroy(); if (!this.hasCrashed) { System.exit(0); -@@ -999,7 +1008,7 @@ + } +@@ -999,7 +1007,7 @@ long i1 = System.nanoTime() - l; this.checkGLError("Pre render"); this.profiler.endStartSection("sound"); @@ -295,7 +296,7 @@ this.profiler.endSection(); this.profiler.startSection("render"); GlStateManager.pushMatrix(); -@@ -1009,11 +1018,13 @@ +@@ -1009,11 +1017,13 @@ GlStateManager.enableTexture2D(); this.profiler.endSection(); if (!this.skipRenderWorld) { @@ -309,7 +310,16 @@ } this.profiler.endSection(); -@@ -1308,9 +1319,9 @@ +@@ -1096,7 +1106,7 @@ + } + + protected void checkWindowResize() { +- if (!this.fullscreen && Display.wasResized()) { ++ if (Display.wasResized()) { + int i = this.displayWidth; + int j = this.displayHeight; + this.displayWidth = Display.getWidth(); +@@ -1308,9 +1318,9 @@ if (this.leftClickCounter <= 0 && !this.player.isHandActive()) { if (leftClick && this.objectMouseOver != null && this.objectMouseOver.typeOfHit == RayTraceResult.Type.BLOCK) { BlockPos blockpos = this.objectMouseOver.getBlockPos(); @@ -322,7 +332,7 @@ this.player.swingArm(EnumHand.MAIN_HAND); } } else { -@@ -1333,7 +1344,8 @@ +@@ -1333,7 +1343,8 @@ break; case BLOCK: BlockPos blockpos = this.objectMouseOver.getBlockPos(); @@ -332,7 +342,7 @@ this.playerController.clickBlock(blockpos, this.objectMouseOver.sideHit); break; } -@@ -1343,6 +1355,7 @@ +@@ -1343,6 +1354,7 @@ } this.player.resetCooldown(); @@ -340,7 +350,7 @@ } this.player.swingArm(EnumHand.MAIN_HAND); -@@ -1399,6 +1412,7 @@ +@@ -1399,6 +1411,7 @@ } } @@ -348,26 +358,26 @@ if (!itemstack.isEmpty() && this.playerController.processRightClick(this.player, this.world, enumhand) == EnumActionResult.SUCCESS) { this.entityRenderer.itemRenderer.resetEquippedProgress(enumhand); -@@ -1411,6 +1425,11 @@ - - /** Toggles fullscreen mode. */ - public void toggleFullscreen() { -+ if (net.minecraftforge.common.ForgeEarlyConfig.WINDOW_BORDERLESS_REPLACES_FULLSCREEN) { -+ com.cleanroommc.client.sdl.Window window = com.cleanroommc.client.sdl.Window.main(); -+ if (window != null) window.borderless(!window.borderless()); -+ return; -+ } +@@ -1414,7 +1427,12 @@ try { this.fullscreen = !this.fullscreen; this.gameSettings.fullScreen = this.fullscreen; -@@ -1444,7 +1463,19 @@ +- if (this.fullscreen) { ++ com.cleanroommc.client.sdl.Window host = com.cleanroommc.client.sdl.Window.main(); ++ if (host != null) { ++ com.cleanroommc.client.sdl.SDLHooks.applyDisplayMode(this.fullscreen); ++ this.displayWidth = Math.max(1, host.width()); ++ this.displayHeight = Math.max(1, host.height()); ++ } else if (this.fullscreen) { + this.updateDisplayMode(); + this.displayWidth = Display.getDisplayMode().getWidth(); + this.displayHeight = Display.getDisplayMode().getHeight(); +@@ -1444,7 +1462,17 @@ this.updateFramebufferSize(); } - Display.setFullscreen(this.fullscreen); -+ com.cleanroommc.client.sdl.Window host = com.cleanroommc.client.sdl.Window.main(); + if (host != null) { -+ host.fullscreen(this.fullscreen); + if (!this.fullscreen) { + host.resizable(false).resizable(true); + } @@ -381,7 +391,7 @@ Display.setVSyncEnabled(this.gameSettings.enableVsync); this.updateDisplay(); } catch (Exception exception) { -@@ -1483,6 +1514,8 @@ +@@ -1483,6 +1511,8 @@ this.rightClickDelayTimer--; } @@ -390,7 +400,7 @@ this.profiler.startSection("gui"); if (!this.isGamePaused) { this.ingameGUI.updateTick(); -@@ -1632,6 +1665,7 @@ +@@ -1632,6 +1662,7 @@ } this.profiler.endSection(); @@ -398,7 +408,7 @@ this.systemTime = getSystemTime(); } -@@ -1705,6 +1739,7 @@ +@@ -1705,6 +1736,7 @@ } } } @@ -406,7 +416,7 @@ } this.processKeyBinds(); -@@ -1896,6 +1931,8 @@ +@@ -1896,6 +1928,8 @@ private void runTickMouse() throws IOException { while (Mouse.next()) { @@ -415,7 +425,7 @@ int i = Mouse.getEventButton(); KeyBinding.setKeyBindState(i - 100, Mouse.getEventButtonState()); if (Mouse.getEventButtonState()) { -@@ -1931,6 +1968,7 @@ +@@ -1931,6 +1965,7 @@ this.currentScreen.handleMouseInput(); } } @@ -423,7 +433,7 @@ } } -@@ -1949,6 +1987,7 @@ +@@ -1949,6 +1984,7 @@ /** Arguments: World foldername, World ingame name, WorldSettings */ public void launchIntegratedServer(String folderName, String worldName, @Nullable WorldSettings worldSettingsIn) { @@ -431,7 +441,7 @@ this.loadWorld(null); System.gc(); ISaveHandler isavehandler = this.saveLoader.getSaveLoader(folderName, false); -@@ -1990,6 +2029,11 @@ +@@ -1990,6 +2026,11 @@ this.loadingScreen.displaySavingString(I18n.format("menu.loadingLevel")); while (!this.integratedServer.serverIsInRunLoop()) { @@ -443,7 +453,7 @@ String s = this.integratedServer.getUserMessage(); if (s != null) { this.loadingScreen.displayLoadingString(I18n.format(s)); -@@ -2007,8 +2051,13 @@ +@@ -2007,8 +2048,13 @@ SocketAddress socketaddress = this.integratedServer.getNetworkSystem().addLocalEndpoint(); NetworkManager networkmanager = NetworkManager.provideLocalClient(socketaddress); networkmanager.setNetHandler(new NetHandlerLoginClient(networkmanager, this, null)); @@ -459,7 +469,7 @@ this.networkManager = networkmanager; } -@@ -2019,6 +2068,8 @@ +@@ -2019,6 +2065,8 @@ /** par2Str is displayed on the loading screen to the user unloads the current world first */ public void loadWorld(@Nullable WorldClient worldClientIn, String loadingMessage) { @@ -468,7 +478,7 @@ if (worldClientIn == null) { NetHandlerPlayClient nethandlerplayclient = this.getConnection(); if (nethandlerplayclient != null) { -@@ -2027,6 +2078,14 @@ +@@ -2027,6 +2075,14 @@ if (this.integratedServer != null && this.integratedServer.isAnvilFileSet()) { this.integratedServer.initiateShutdown(); @@ -483,7 +493,7 @@ } this.integratedServer = null; -@@ -2047,6 +2106,7 @@ +@@ -2047,6 +2103,7 @@ this.ingameGUI.resetPlayersOverlayFooterHeader(); this.setServerData(null); this.integratedServerIsRunning = false; @@ -491,7 +501,7 @@ } this.soundHandler.stopSounds(); -@@ -2060,6 +2120,8 @@ +@@ -2060,6 +2117,8 @@ } TileEntityRendererDispatcher.instance.setWorld(worldClientIn); @@ -500,7 +510,7 @@ if (worldClientIn != null) { if (!this.integratedServerIsRunning) { AuthenticationService authenticationservice = new YggdrasilAuthenticationService(this.proxy, UUID.randomUUID().toString()); -@@ -2112,6 +2174,7 @@ +@@ -2112,6 +2171,7 @@ this.player == null ? new RecipeBook() : this.player.getRecipeBook() ); this.player.getDataManager().setEntryValues(entityplayersp.getDataManager().getAll()); @@ -508,7 +518,7 @@ this.player.dimension = dimension; this.renderViewEntity = this.player; this.player.preparePlayerToSpawn(); -@@ -2153,110 +2216,8 @@ +@@ -2153,110 +2213,8 @@ /** Called when user clicked he's mouse middle button (pick block) */ private void middleClickMouse() { if (this.objectMouseOver != null && this.objectMouseOver.typeOfHit != RayTraceResult.Type.MISS) { @@ -621,7 +631,7 @@ } } -@@ -2293,7 +2254,11 @@ +@@ -2293,7 +2251,11 @@ }); theCrash.getCategory().addDetail("OpenGL", new ICrashReportDetail() { public String call() { @@ -634,7 +644,7 @@ } }); theCrash.getCategory().addDetail("GL Caps", new ICrashReportDetail() { -@@ -2372,6 +2337,7 @@ +@@ -2372,6 +2334,7 @@ return instance; } @@ -642,7 +652,7 @@ public ListenableFuture scheduleResourcesRefresh() { return this.addScheduledTask(new Runnable() { @Override -@@ -2536,15 +2502,8 @@ +@@ -2536,15 +2499,8 @@ /** Used in the usage snooper. */ public static int getGLMaximumTextureSize() { @@ -660,7 +670,7 @@ } /** Returns whether snooping is enabled or not. */ -@@ -2658,6 +2617,9 @@ +@@ -2658,6 +2614,9 @@ } if (this.player != null) { @@ -670,7 +680,7 @@ if (this.player.world.provider instanceof WorldProviderHell) { return MusicTicker.MusicType.NETHER; } else if (this.player.world.provider instanceof WorldProviderEnd) { -@@ -2677,9 +2639,9 @@ +@@ -2677,9 +2636,9 @@ if (i != 0 && !Keyboard.isRepeatEvent()) { if (!(this.currentScreen instanceof GuiControls) || ((GuiControls)this.currentScreen).time <= getSystemTime() - 20L) { if (Keyboard.getEventKeyState()) { @@ -682,7 +692,7 @@ this.ingameGUI .getChatGUI() .printChatMessage(ScreenShotHelper.saveScreenshot(this.gameDir, this.displayWidth, this.displayHeight, this.framebuffer)); -@@ -2691,7 +2653,7 @@ +@@ -2691,7 +2650,7 @@ ((ScreenChatOptions)this.currentScreen).updateNarratorButton(); } } @@ -691,7 +701,7 @@ } } } -@@ -2720,7 +2682,7 @@ +@@ -2720,7 +2679,7 @@ try { return Futures.immediateFuture(callableToSchedule.call()); } catch (Exception exception) { @@ -700,7 +710,7 @@ } } else { ListenableFutureTask listenablefuturetask = ListenableFutureTask.create(callableToSchedule); -@@ -2802,7 +2764,11 @@ +@@ -2802,7 +2761,11 @@ return this.blockColors; } @@ -713,7 +723,7 @@ public boolean isReducedDebug() { return this.player != null && this.player.hasReducedDebug() || this.gameSettings.reducedDebugInfo; } -@@ -2814,4 +2780,8 @@ +@@ -2814,4 +2777,8 @@ public Tutorial getTutorial() { return this.tutorial; } From 21d7420938cdd995c23214d11869476723c792c4 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Thu, 20 Aug 2026 11:21:44 +0100 Subject: [PATCH 87/99] Fixed token placeholders --- .../java/com/cleanroommc/common/CleanroomVersion.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/module/cleanroom/src/main/java/com/cleanroommc/common/CleanroomVersion.java b/module/cleanroom/src/main/java/com/cleanroommc/common/CleanroomVersion.java index ca2ed919e..3d6c9639d 100644 --- a/module/cleanroom/src/main/java/com/cleanroommc/common/CleanroomVersion.java +++ b/module/cleanroom/src/main/java/com/cleanroommc/common/CleanroomVersion.java @@ -2,16 +2,16 @@ public final class CleanroomVersion { - public static final String VERSION = "@VERSION"; - public static final String BUILD_VERSION = "@BUILD"; - public static final String MOD_ID = "@ID"; + public static final String VERSION = getVersion(); + public static final String BUILD_VERSION = getBuildVersion(); + public static final String MOD_ID = "@{ID}"; public static String getVersion() { - return "@VERSION"; + return "@{VERSION}"; } public static String getBuildVersion() { - return "@BUILD"; + return "@{BUILD}"; } private CleanroomVersion() { } From fa551ce739080076b1cbc497ee3dc3df53637632 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Fri, 21 Aug 2026 23:13:35 +0100 Subject: [PATCH 88/99] Use new non-LZMA ClassPatchManager --- .../com/cleanroommc/util/patch/BinDelta.java | 66 ++++++ .../util/patch/ClassPatchManager.java | 205 ++++++++++++++++++ .../fml/common/asm/FMLSanityChecker.java | 7 +- .../asm/transformers/PatchingTransformer.java | 2 +- .../deobf/FMLDeobfuscatingRemapper.java | 2 +- 5 files changed, 275 insertions(+), 7 deletions(-) create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/util/patch/BinDelta.java create mode 100644 module/cleanroom/src/main/java/com/cleanroommc/util/patch/ClassPatchManager.java diff --git a/module/cleanroom/src/main/java/com/cleanroommc/util/patch/BinDelta.java b/module/cleanroom/src/main/java/com/cleanroommc/util/patch/BinDelta.java new file mode 100644 index 000000000..c9f1a489a --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/util/patch/BinDelta.java @@ -0,0 +1,66 @@ +package com.cleanroommc.util.patch; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; + +/** + * Decodes COPY/INSERT binary deltas produced by CleanroomGradle's {@code GenerateBinPatches} task. + */ +final class BinDelta { + + private static final int COPY = 0; + private static final int INSERT = 1; + + static byte[] decode(byte[] original, byte[] delta) { + ByteArrayInputStream input = new ByteArrayInputStream(delta); + ByteArrayOutputStream output = new ByteArrayOutputStream(original.length + 64); + int tag; + while ((tag = input.read()) != -1) { + switch (tag) { + case COPY -> { + int offset = readVarInt(input); + int length = readVarInt(input); + if (offset > original.length || length > original.length - offset) { + throw corrupt("COPY range is outside the original buffer"); + } + output.write(original, offset, length); + } + case INSERT -> { + int length = readVarInt(input); + if (length > input.available()) { + throw corrupt("INSERT length exceeds the remaining delta"); + } + output.write(delta, delta.length - input.available(), length); + input.skip(length); + } + default -> throw corrupt("Unknown operation tag " + tag); + } + } + return output.toByteArray(); + } + + private static int readVarInt(ByteArrayInputStream input) { + int value = 0; + for (int byteIndex = 0; byteIndex < 5; byteIndex++) { + int next = input.read(); + if (next == -1) { + throw corrupt("Truncated VarInt"); + } + if (byteIndex == 4 && (next & 0xF8) != 0) { + throw corrupt("VarInt exceeds signed int range"); + } + value |= (next & 0x7F) << (byteIndex * 7); + if ((next & 0x80) == 0) { + return value; + } + } + throw corrupt("VarInt is too long"); + } + + private static IllegalArgumentException corrupt(String detail) { + return new IllegalArgumentException("Corrupt delta: " + detail); + } + + private BinDelta() { } + +} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/util/patch/ClassPatchManager.java b/module/cleanroom/src/main/java/com/cleanroommc/util/patch/ClassPatchManager.java new file mode 100644 index 000000000..933094246 --- /dev/null +++ b/module/cleanroom/src/main/java/com/cleanroommc/util/patch/ClassPatchManager.java @@ -0,0 +1,205 @@ +package com.cleanroommc.util.patch; + +import com.cleanroommc.common.CleanroomEnvironment; +import com.cleanroommc.util.CleanroomLog; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.ListMultimap; +import com.google.common.collect.Maps; +import com.google.common.io.ByteStreams; +import com.google.common.io.Files; +import net.minecraft.launchwrapper.LaunchClassLoader; +import net.minecraftforge.fml.relauncher.FMLLaunchHandler; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.*; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +/** + * Non-LZMA version. + */ +public final class ClassPatchManager { + + private record ClassPatch(String sourceClassName, boolean existsAtTarget, byte[] expectedHash, byte[] patch) { + + @Override + public String toString() { + return "%s (%s) size %d".formatted(sourceClassName, existsAtTarget ? "modify" : "add", patch.length); + } + + } + + public static final boolean dumpPatched = Boolean.parseBoolean(System.getProperty("fml.dumpPatchedClasses", "false")); + public static final boolean DEBUG = Boolean.parseBoolean(System.getProperty("fml.debugClassPatchManager", "false")); + public static final ClassPatchManager INSTANCE = new ClassPatchManager(); + + private static final int SHA256_LENGTH = 32; + private static final String RESOURCE_NAME = "/binpatches.zip"; + private static final String REMOVED_ENTRY = "META-INF/binpatch-removed.txt"; + + private final Map patchedClasses = Maps.newHashMap(); + + private ListMultimap patches; + private Set removedClasses = Set.of(); + private File tempDir; + + private ClassPatchManager() { + if (dumpPatched) { + tempDir = Files.createTempDir(); + CleanroomLog.get().info("Dumping patched classes to {}", tempDir.getAbsolutePath()); + } + } + + public byte[] getPatchedResource(String name, String mappedName, LaunchClassLoader loader) throws IOException { + byte[] rawClassBytes = loader.getClassBytes(name); + return applyPatch(name, mappedName, rawClassBytes); + } + + public byte[] applyPatch(String name, String mappedName, byte[] inputData) { + if (patches == null) { + return inputData; + } + if (patchedClasses.containsKey(name)) { + return patchedClasses.get(name); + } + if (removedClasses.contains(name)) { + if (DEBUG) + CleanroomLog.get().debug("Refusing to load {} ({}), the binary patch set removes it", mappedName, name); + patchedClasses.put(name, null); + return null; + } + List list = patches.get(name); + if (list.isEmpty()) { + return inputData; + } + boolean ignoredError = false; + if (DEBUG) + CleanroomLog.get().debug("Runtime patching class {} (input size {}), found {} patch{}", mappedName, (inputData == null ? 0 : inputData.length), list.size(), list.size() != 1 ? "es" : ""); + for (ClassPatch patch : list) { + if (!patch.existsAtTarget() && (inputData == null || inputData.length == 0)) { + inputData = patch.patch(); + } else if (!patch.existsAtTarget()) { + CleanroomLog.get().warn("Patcher expecting empty class data file for {}, but received non-empty", name); + inputData = patch.patch(); + } else if (inputData == null || inputData.length == 0) { + CleanroomLog.get().error("Patcher expecting non-empty class data file for {}, but received empty.", name); + throw new RuntimeException("Patcher expecting non-empty class data file for %s, but received empty, your vanilla jar may be corrupt.".formatted(name)); + } else { + byte[] actualHash = sha256(inputData); + if (!Arrays.equals(actualHash, patch.expectedHash())) { + CleanroomLog.get().error("There is a binary discrepancy between the expected input class {} ({}) and the actual class. Hash on disk is {}, in patch {}. Things are probably about to go very wrong. Did you put something into the jar file?", + mappedName, name, HexFormat.of().formatHex(actualHash), HexFormat.of().formatHex(patch.expectedHash())); + if (!Boolean.parseBoolean(System.getProperty("fml.ignorePatchDiscrepancies", "false"))) { + CleanroomLog.get().error("The game is going to exit, because this is a critical error, and it is very improbable that the modded game will work, please obtain clean jar files."); + System.exit(1); + } else { + CleanroomLog.get().error("FML is going to ignore this error, note that the patch will not be applied, and there is likely to be a malfunctioning behaviour, including not running at all"); + ignoredError = true; + continue; + } + } + try { + inputData = BinDelta.decode(inputData, patch.patch()); + } catch (Exception e) { + CleanroomLog.get().error("Encountered problem runtime patching class {}", name, e); + continue; + } + } + } + if (!ignoredError && DEBUG) { + CleanroomLog.get().debug("Successfully applied runtime patches for {} (new size {})", mappedName, inputData.length); + } + if (dumpPatched) { + try { + Files.write(inputData, new File(tempDir, mappedName)); + } catch (IOException e) { + CleanroomLog.get().error("Failed to write {} to {}", mappedName, tempDir.getAbsolutePath(), e); + } + } + patchedClasses.put(name, inputData); + return inputData; + } + + public void setup() { + var sidePrefix = "binpatch/%s/".formatted(CleanroomEnvironment.side().toString().toLowerCase(Locale.ENGLISH)); + + try (InputStream resource = getClass().getResourceAsStream(RESOURCE_NAME)) { + if (resource == null) { + if (!FMLLaunchHandler.isDeobfuscatedEnvironment()) { + CleanroomLog.get().error("The binary patch set is missing, things are not going to work!"); + } else { + CleanroomLog.get().error("The binary patch set is missing, because you are in a development environment!"); + } + return; + } + + patches = ArrayListMultimap.create(); + var removed = new HashSet(); + + try (var zip = new ZipInputStream(resource)) { + ZipEntry entry; + while ((entry = zip.getNextEntry()) != null) { + var entryName = entry.getName(); + if (entry.isDirectory() || !entryName.startsWith(sidePrefix)) { + continue; + } + var relative = entryName.substring(sidePrefix.length()); + if (relative.equals(REMOVED_ENTRY)) { + for (var line : new String(ByteStreams.toByteArray(zip), StandardCharsets.UTF_8).split("\n")) { + var removedClass = line.trim(); + if (!removedClass.isEmpty()) { + removed.add(stripClassExtension(removedClass).replace('/', '.')); + } + } + } else if (relative.endsWith(".binpatch")) { + var className = relative.substring(0, relative.length() - ".binpatch".length()); + className = stripClassExtension(className); + var data = ByteStreams.toByteArray(zip); + if (data.length < SHA256_LENGTH) { + CleanroomLog.get().warn("Binpatch entry {} is too short, skipping", entryName); + continue; + } + var expectedHash = Arrays.copyOfRange(data, 0, SHA256_LENGTH); + var delta = Arrays.copyOfRange(data, SHA256_LENGTH, data.length); + var cp = new ClassPatch(className.replace('/', '.'), true, expectedHash, delta); + patches.put(cp.sourceClassName(), cp); + } else if (relative.endsWith(".add")) { + var className = relative.substring(0, relative.length() - ".add".length()); + className = stripClassExtension(className); + var data = ByteStreams.toByteArray(zip); + var cp = new ClassPatch(className.replace('/', '.'), false, null, data); + patches.put(cp.sourceClassName(), cp); + } + } + } + + removedClasses = Set.copyOf(removed); + } catch (Exception e) { + throw new RuntimeException("Error occurred reading binary patches. Expect severe problems!", e); + } + + CleanroomLog.get().debug("Read {} binary patches, {} removed classes", patches.size(), removedClasses.size()); + if (DEBUG) + CleanroomLog.get().debug("Patch list :\n\t{}", com.google.common.base.Joiner.on("\t\n").join(patches.asMap().entrySet())); + patchedClasses.clear(); + } + + private static String stripClassExtension(String name) { + return name.endsWith(".class") ? name.substring(0, name.length() - ".class".length()) : name; + } + + private static byte[] sha256(byte[] data) { + try { + return MessageDigest.getInstance("SHA-256").digest(data); + } catch (NoSuchAlgorithmException e) { + throw new IllegalStateException("SHA-256 is unavailable", e); + } + } + + +} diff --git a/module/forge/src/main/java/net/minecraftforge/fml/common/asm/FMLSanityChecker.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/FMLSanityChecker.java index 2424a9717..e14b7f629 100644 --- a/module/forge/src/main/java/net/minecraftforge/fml/common/asm/FMLSanityChecker.java +++ b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/FMLSanityChecker.java @@ -21,9 +21,6 @@ import java.io.File; import java.io.InputStream; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; import java.security.CodeSource; @@ -32,6 +29,7 @@ import java.util.jar.JarEntry; import java.util.jar.JarFile; +import com.cleanroommc.util.patch.ClassPatchManager; import net.minecraftforge.fml.common.FMLLog; import org.apache.commons.io.IOUtils; @@ -39,7 +37,6 @@ import net.minecraftforge.fml.common.CertificateHelper; import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper; -import net.minecraftforge.fml.common.patcher.ClassPatchManager; import net.minecraftforge.fml.relauncher.FMLLaunchHandler; import net.minecraftforge.fml.relauncher.IFMLCallHook; import net.minecraftforge.fml.relauncher.Side; @@ -187,7 +184,7 @@ public void injectData(Map data) cl = (LaunchClassLoader) data.get("classLoader"); File mcDir = (File)data.get("mcLocation"); fmlLocation = (File)data.get("coremodLocation"); - ClassPatchManager.INSTANCE.setup(FMLLaunchHandler.side()); + ClassPatchManager.INSTANCE.setup(); FMLDeobfuscatingRemapper.INSTANCE.setup(mcDir, cl, (String) data.get("deobfuscationFileName"), liveEnv); } diff --git a/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/PatchingTransformer.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/PatchingTransformer.java index 7dc573d92..699147467 100644 --- a/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/PatchingTransformer.java +++ b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/PatchingTransformer.java @@ -19,8 +19,8 @@ package net.minecraftforge.fml.common.asm.transformers; +import com.cleanroommc.util.patch.ClassPatchManager; import net.minecraft.launchwrapper.IClassTransformer; -import net.minecraftforge.fml.common.patcher.ClassPatchManager; public class PatchingTransformer implements IClassTransformer { @Override diff --git a/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java index 7a5661c6c..8934a987b 100644 --- a/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java +++ b/module/forge/src/main/java/net/minecraftforge/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java @@ -26,9 +26,9 @@ import java.util.Map; import java.util.Set; +import com.cleanroommc.util.patch.ClassPatchManager; import net.minecraft.launchwrapper.LaunchClassLoader; import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.common.patcher.ClassPatchManager; import org.apache.commons.io.IOUtils; import org.objectweb.asm.ClassReader; From 10f18d494d1fd10b9915a09c578c94bf324abf30 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Sat, 22 Aug 2026 01:12:26 +0100 Subject: [PATCH 89/99] Add exclusion for cleanroom class patcher --- .../java/net/minecraftforge/fml/relauncher/FMLLaunchHandler.java | 1 + 1 file changed, 1 insertion(+) diff --git a/module/forge/src/main/java/net/minecraftforge/fml/relauncher/FMLLaunchHandler.java b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/FMLLaunchHandler.java index 5eccf7530..ef408301e 100644 --- a/module/forge/src/main/java/net/minecraftforge/fml/relauncher/FMLLaunchHandler.java +++ b/module/forge/src/main/java/net/minecraftforge/fml/relauncher/FMLLaunchHandler.java @@ -81,6 +81,7 @@ private FMLLaunchHandler(LaunchClassLoader launchLoader, FMLTweaker tweaker) this.classLoader.addTransformerExclusion("net.minecraftforge.classloading."); this.classLoader.addTransformerExclusion("net.minecraftforge.fml.common.asm.transformers."); this.classLoader.addTransformerExclusion("net.minecraftforge.fml.common.patcher."); + this.classLoader.addTransformerExclusion("com.cleanroommc.util.patch."); this.classLoader.addTransformerExclusion("net.minecraftforge.fml.repackage."); this.classLoader.addTransformerExclusion("LZMA."); this.classLoader.addTransformerExclusion("scala."); From 8f45d0745a93cba723dca2e1824b3bac4011fb5b Mon Sep 17 00:00:00 2001 From: Rongmario Date: Sat, 22 Aug 2026 01:13:02 +0100 Subject: [PATCH 90/99] Update CG to 0.10.3 --- build.gradle | 7 ++++--- settings.gradle | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 2bd657928..d775ff775 100644 --- a/build.gradle +++ b/build.gradle @@ -23,8 +23,10 @@ idea { cleanroom { mode = 'loader' - accessTransformers.from file('module/forge/src/main/resources/forge_at.cfg') - sideAnnotationStrippers.from file('module/cleanroom/minecraft.sas') + loader { + accessTransformers.from file('module/forge/src/main/resources/forge_at.cfg') + sideAnnotationStrippers.from file('module/cleanroom/minecraft.sas') + } } tokenEnvoy { @@ -110,7 +112,6 @@ configurations.configureEach { configuration -> } configurations.named('vanillaNatives') { - exclude group: 'ca.weblite', module: 'java-objc-bridge' // LWJGL 2's natives are never loaded: LWJGLY reaches LWJGL 3's instead. exclude group: 'org.lwjgl.lwjgl' } diff --git a/settings.gradle b/settings.gradle index a8f6b6b9f..93b4472a6 100644 --- a/settings.gradle +++ b/settings.gradle @@ -14,5 +14,5 @@ pluginManagement { } plugins { - id 'com.cleanroommc.cleanroomgradle.settings' version '0.9.1' + id 'com.cleanroommc.cleanroomgradle.settings' version '0.10.3' } From 8da100b4ea375ccad993fd84a7b8964faa26c341 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Sat, 22 Aug 2026 01:33:34 +0100 Subject: [PATCH 91/99] More patches fixed --- .../server/dedicated/DedicatedServer.java.patch | 14 +++++++++++--- .../patches/net/minecraft/world/World.java.patch | 2 +- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/module/minecraft/patches/net/minecraft/server/dedicated/DedicatedServer.java.patch b/module/minecraft/patches/net/minecraft/server/dedicated/DedicatedServer.java.patch index fc494a321..3bc68af99 100644 --- a/module/minecraft/patches/net/minecraft/server/dedicated/DedicatedServer.java.patch +++ b/module/minecraft/patches/net/minecraft/server/dedicated/DedicatedServer.java.patch @@ -46,7 +46,15 @@ this.setPlayerList(new DedicatedPlayerList(this)); long j = System.nanoTime(); if (this.getFolderName() == null) { -@@ -258,7 +265,8 @@ +@@ -225,6 +232,7 @@ + TileEntitySkull.setProfileCache(this.getPlayerProfileCache()); + TileEntitySkull.setSessionService(this.getMinecraftSessionService()); + PlayerProfileCache.setOnlineMode(this.isServerInOnlineMode()); ++ if (!net.minecraftforge.fml.common.FMLCommonHandler.instance().handleServerAboutToStart(this)) return false; + LOGGER.info("Preparing level \"{}\"", this.getFolderName()); + this.loadAllWorlds(this.getFolderName(), this.getFolderName(), k, worldtype, s2); + long i1 = System.nanoTime() - j; +@@ -258,7 +266,8 @@ } Items.AIR.getSubItems(CreativeTabs.SEARCH, NonNullList.create()); @@ -56,7 +64,7 @@ } public String loadResourcePackSHA() { -@@ -478,7 +486,7 @@ +@@ -478,7 +487,7 @@ @Override public boolean isBlockProtected(World worldIn, BlockPos pos, EntityPlayer playerIn) { @@ -65,7 +73,7 @@ return false; } -@@ -543,6 +551,9 @@ +@@ -543,6 +552,9 @@ return this.settings.getIntProperty("network-compression-threshold", super.getNetworkCompressionThreshold()); } diff --git a/module/minecraft/patches/net/minecraft/world/World.java.patch b/module/minecraft/patches/net/minecraft/world/World.java.patch index eff370517..8c6fc42f9 100644 --- a/module/minecraft/patches/net/minecraft/world/World.java.patch +++ b/module/minecraft/patches/net/minecraft/world/World.java.patch @@ -1476,7 +1476,7 @@ + net.minecraftforge.common.util.WorldCapabilityData data = (net.minecraftforge.common.util.WorldCapabilityData)perWorldStorage.getOrLoadData(net.minecraftforge.common.util.WorldCapabilityData.class, net.minecraftforge.common.util.WorldCapabilityData.ID); + if (data == null) { + capabilityData = new net.minecraftforge.common.util.WorldCapabilityData(capabilities); -+ perWorldStorage.setData(capabilityData.mapName, capabilityData); ++ perWorldStorage.setData(net.minecraftforge.common.util.WorldCapabilityData.ID, capabilityData); + } else { + capabilityData = data; + capabilityData.setCapabilities(provider, capabilities); From 09dbd5a2364504c54833f88df1fbe821fabfdc62 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Sat, 22 Aug 2026 01:54:52 +0100 Subject: [PATCH 92/99] Update CG to 0.10.4 --- settings.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle b/settings.gradle index 93b4472a6..3fbfc77a4 100644 --- a/settings.gradle +++ b/settings.gradle @@ -14,5 +14,5 @@ pluginManagement { } plugins { - id 'com.cleanroommc.cleanroomgradle.settings' version '0.10.3' + id 'com.cleanroommc.cleanroomgradle.settings' version '0.10.4' } From ddf125cd3ab5589bff875103259b64d5b41c65d4 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Sun, 23 Aug 2026 21:29:27 +0100 Subject: [PATCH 93/99] Bump Kirino --- module/kirino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/kirino b/module/kirino index 35fed740b..1e43363f5 160000 --- a/module/kirino +++ b/module/kirino @@ -1 +1 @@ -Subproject commit 35fed740b5a210c9ed873736cc3a336fc561cead +Subproject commit 1e43363f522532c8489d3280e380025e898ae003 From aa0551fc0726f0a5e1277b1f042a5c33bfbd42c8 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Sun, 23 Aug 2026 21:43:34 +0100 Subject: [PATCH 94/99] Effort to reduce AWT initializations --- .../client/model/ModelLoader.java | 12 ++--- .../client/gui/GuiMainMenu.java.patch | 21 ++++++-- .../client/gui/GuiScreenDemo.java.patch | 13 ++++- .../client/renderer/EntityRenderer.java.patch | 51 +++++++++++++------ 4 files changed, 67 insertions(+), 30 deletions(-) diff --git a/module/forge/src/main/java/net/minecraftforge/client/model/ModelLoader.java b/module/forge/src/main/java/net/minecraftforge/client/model/ModelLoader.java index 605ea4146..778164f7e 100644 --- a/module/forge/src/main/java/net/minecraftforge/client/model/ModelLoader.java +++ b/module/forge/src/main/java/net/minecraftforge/client/model/ModelLoader.java @@ -19,10 +19,8 @@ package net.minecraftforge.client.model; -import java.awt.Color; -import java.awt.Graphics2D; -import java.awt.image.BufferedImage; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Comparator; import java.util.List; @@ -898,13 +896,9 @@ public boolean hasCustomLoader(IResourceManager manager, ResourceLocation locati @Override public boolean load(IResourceManager manager, ResourceLocation location, Function textureGetter) { - BufferedImage image = new BufferedImage(this.getIconWidth(), this.getIconHeight(), BufferedImage.TYPE_INT_ARGB); - Graphics2D graphics = image.createGraphics(); - graphics.setBackground(Color.WHITE); - graphics.clearRect(0, 0, this.getIconWidth(), this.getIconHeight()); int[][] pixels = new int[Minecraft.getMinecraft().gameSettings.mipmapLevels + 1][]; - pixels[0] = new int[image.getWidth() * image.getHeight()]; - image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels[0], 0, image.getWidth()); + pixels[0] = new int[this.getIconWidth() * this.getIconHeight()]; + Arrays.fill(pixels[0], 0xFFFFFFFF); this.clearFramesTextureData(); this.framesTextureData.add(pixels); return false; diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiMainMenu.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiMainMenu.java.patch index 49318db89..77e8f53e7 100644 --- a/module/minecraft/patches/net/minecraft/client/gui/GuiMainMenu.java.patch +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiMainMenu.java.patch @@ -86,7 +86,18 @@ } @Override -@@ -482,6 +462,9 @@ +@@ -294,9 +274,7 @@ + } else if (id == 13) { + if (result) { + try { +- Class oclass = Class.forName("java.awt.Desktop"); +- Object object = oclass.getMethod("getDesktop").invoke(null); +- oclass.getMethod("browse", URI.class).invoke(object, new URI(this.openGLWarningLink)); ++ com.cleanroommc.client.sdl.Desktop.open(new URI(this.openGLWarningLink)); + } catch (Throwable throwable) { + LOGGER.error("Couldn't open link", throwable); + } +@@ -482,6 +460,9 @@ this.mc.getTextureManager().bindTexture(field_194400_H); drawModalRectWithCustomSizedTexture(j + 88, 67, 0.0F, 0.0F, 98, 14, 128.0F, 16.0F); @@ -96,7 +107,7 @@ GlStateManager.pushMatrix(); GlStateManager.translate(this.width / 2 + 90, 70.0F, 0.0F); GlStateManager.rotate(-20.0F, 0.0F, 0.0F, 1.0F); -@@ -497,7 +480,14 @@ +@@ -497,7 +478,14 @@ s = s + ("release".equalsIgnoreCase(this.mc.getVersionType()) ? "" : "/" + this.mc.getVersionType()); } @@ -112,7 +123,7 @@ this.drawString(this.fontRenderer, "Copyright Mojang AB. Do not distribute!", this.widthCopyrightRest, this.height - 10, -1); if (mouseX > this.widthCopyrightRest && mouseX < this.widthCopyrightRest + this.widthCopyright -@@ -516,9 +506,8 @@ +@@ -516,9 +504,8 @@ } super.drawScreen(mouseX, mouseY, partialTicks); @@ -124,7 +135,7 @@ } /** Called when the mouse is clicked. Args : mouseX, mouseY, clickedButton */ -@@ -538,10 +527,6 @@ +@@ -538,10 +525,6 @@ } } @@ -135,7 +146,7 @@ if (mouseX > this.widthCopyrightRest && mouseX < this.widthCopyrightRest + this.widthCopyright && mouseY > this.height - 10 -@@ -550,11 +535,4 @@ +@@ -550,11 +533,4 @@ } } diff --git a/module/minecraft/patches/net/minecraft/client/gui/GuiScreenDemo.java.patch b/module/minecraft/patches/net/minecraft/client/gui/GuiScreenDemo.java.patch index f67cb531b..b5cf8eac2 100644 --- a/module/minecraft/patches/net/minecraft/client/gui/GuiScreenDemo.java.patch +++ b/module/minecraft/patches/net/minecraft/client/gui/GuiScreenDemo.java.patch @@ -1,6 +1,17 @@ --- original/net/minecraft/client/gui/GuiScreenDemo.java +++ modified/net/minecraft/client/gui/GuiScreenDemo.java -@@ -75,23 +75,23 @@ +@@ -35,9 +35,7 @@ + button.enabled = false; + + try { +- Class oclass = Class.forName("java.awt.Desktop"); +- Object object = oclass.getMethod("getDesktop").invoke(null); +- oclass.getMethod("browse", URI.class).invoke(object, new URI("http://www.minecraft.net/store?source=demo")); ++ com.cleanroommc.client.sdl.Desktop.open(new URI("http://www.minecraft.net/store?source=demo")); + } catch (Throwable throwable) { + LOGGER.error("Couldn't open link", throwable); + } +@@ -75,23 +73,23 @@ j += 12; GameSettings gamesettings = this.mc.gameSettings; this.fontRenderer diff --git a/module/minecraft/patches/net/minecraft/client/renderer/EntityRenderer.java.patch b/module/minecraft/patches/net/minecraft/client/renderer/EntityRenderer.java.patch index 0ad3220d9..f1a87f340 100644 --- a/module/minecraft/patches/net/minecraft/client/renderer/EntityRenderer.java.patch +++ b/module/minecraft/patches/net/minecraft/client/renderer/EntityRenderer.java.patch @@ -138,7 +138,28 @@ } catch (Throwable throwable) { CrashReport crashreport = CrashReport.makeCrashReport(throwable, "Rendering screen"); CrashReportCategory crashreportcategory = crashreport.makeCategory("Screen render details"); -@@ -1067,7 +1090,7 @@ +@@ -1039,10 +1062,16 @@ + } + + try { +- BufferedImage bufferedimage1 = new BufferedImage(64, 64, 1); +- Graphics graphics = bufferedimage1.createGraphics(); +- graphics.drawImage(bufferedimage, 0, 0, 64, 64, k, l, k + i, l + i, null); +- graphics.dispose(); ++ BufferedImage bufferedimage1 = new BufferedImage(64, 64, BufferedImage.TYPE_INT_RGB); ++ int[] source = bufferedimage.getRGB(k, l, i, i, null, 0, i); ++ int[] scaled = new int[64 * 64]; ++ for (int y = 0; y < 64; ++y) { ++ int sourceRow = y * i / 64 * i; ++ for (int x = 0; x < 64; ++x) { ++ scaled[y * 64 + x] = source[sourceRow + x * i / 64]; ++ } ++ } ++ bufferedimage1.setRGB(0, 0, 64, 64, scaled, 0, 64); + ImageIO.write(bufferedimage1, "png", this.mc.getIntegratedServer().getWorldIconFile()); + } catch (IOException ioexception) { + LOGGER.warn("Couldn't save auto screenshot", ioexception); +@@ -1067,7 +1096,7 @@ BlockPos blockpos = this.mc.objectMouseOver.getBlockPos(); Block block = this.mc.world.getBlockState(blockpos).getBlock(); if (this.mc.playerController.getCurrentGameType() == GameType.SPECTATOR) { @@ -147,7 +168,7 @@ } else { flag = !itemstack.isEmpty() && (itemstack.canDestroy(block) || itemstack.canPlaceOn(block)); } -@@ -1104,6 +1127,15 @@ +@@ -1104,6 +1133,15 @@ } private void renderWorldPass(int pass, float partialTicks, long finishTimeNano) { @@ -163,7 +184,7 @@ RenderGlobal renderglobal = this.mc.renderGlobal; ParticleManager particlemanager = this.mc.effectRenderer; boolean flag = this.isDrawBlockOutline(); -@@ -1114,7 +1146,7 @@ +@@ -1114,7 +1152,7 @@ GlStateManager.clear(16640); this.mc.profiler.endStartSection("camera"); this.setupCameraTransform(partialTicks, pass); @@ -172,7 +193,7 @@ this.mc.profiler.endStartSection("frustum"); ClippingHelperImpl.getInstance(); this.mc.profiler.endStartSection("culling"); -@@ -1154,6 +1186,13 @@ +@@ -1154,6 +1192,13 @@ this.renderCloudsCheck(renderglobal, partialTicks, pass, d0, d1, d2); } @@ -186,7 +207,7 @@ this.mc.profiler.endStartSection("prepareterrain"); this.setupFog(0, partialTicks); this.mc.getTextureManager().bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); -@@ -1171,7 +1210,9 @@ +@@ -1171,7 +1216,9 @@ GlStateManager.disableAlpha(); renderglobal.renderBlockLayer(BlockRenderLayer.SOLID, partialTicks, pass, entity); GlStateManager.enableAlpha(); @@ -196,7 +217,7 @@ this.mc.getTextureManager().getTexture(TextureMap.LOCATION_BLOCKS_TEXTURE).setBlurMipmap(false, false); renderglobal.renderBlockLayer(BlockRenderLayer.CUTOUT, partialTicks, pass, entity); this.mc.getTextureManager().getTexture(TextureMap.LOCATION_BLOCKS_TEXTURE).restoreLastBlurMipmap(); -@@ -1183,7 +1224,9 @@ +@@ -1183,7 +1230,9 @@ GlStateManager.pushMatrix(); RenderHelper.enableStandardItemLighting(); this.mc.profiler.endStartSection("entities"); @@ -206,7 +227,7 @@ RenderHelper.disableStandardItemLighting(); this.disableLightmap(); } -@@ -1194,6 +1237,7 @@ +@@ -1194,6 +1243,7 @@ EntityPlayer entityplayer = (EntityPlayer)entity; GlStateManager.disableAlpha(); this.mc.profiler.endStartSection("outline"); @@ -214,7 +235,7 @@ renderglobal.drawSelectionBox(entityplayer, this.mc.objectMouseOver, 0, partialTicks); GlStateManager.enableAlpha(); } -@@ -1242,8 +1286,25 @@ +@@ -1242,8 +1292,25 @@ GlStateManager.depthMask(false); this.mc.getTextureManager().bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); GlStateManager.shadeModel(7425); @@ -240,7 +261,7 @@ GlStateManager.shadeModel(7424); GlStateManager.depthMask(true); GlStateManager.enableCull(); -@@ -1254,11 +1315,21 @@ +@@ -1254,11 +1321,21 @@ this.renderCloudsCheck(renderglobal, partialTicks, pass, d0, d1, d2); } @@ -262,7 +283,7 @@ } private void renderCloudsCheck(RenderGlobal renderGlobalIn, float partialTicks, int pass, double x, double y, double z) { -@@ -1376,6 +1447,12 @@ +@@ -1376,6 +1453,12 @@ /** Render rain and snow */ protected void renderRainSnow(float partialTicks) { @@ -275,7 +296,7 @@ float f = this.mc.world.getRainStrength(partialTicks); if (!(f <= 0.0F)) { this.enableLightmap(); -@@ -1612,22 +1689,15 @@ +@@ -1612,22 +1695,15 @@ this.fogColorRed = (float)vec3d3.x; this.fogColorGreen = (float)vec3d3.y; this.fogColorBlue = (float)vec3d3.z; @@ -307,7 +328,7 @@ } float f13 = this.fogColor2 + (this.fogColor1 - this.fogColor2) * partialTicks; -@@ -1673,6 +1743,9 @@ +@@ -1673,6 +1749,9 @@ f6 = 1.0F / this.fogColorBlue; } @@ -317,7 +338,7 @@ this.fogColorRed = this.fogColorRed * (1.0F - f15) + this.fogColorRed * f6 * f15; this.fogColorGreen = this.fogColorGreen * (1.0F - f15) + this.fogColorGreen * f6 * f15; this.fogColorBlue = this.fogColorBlue * (1.0F - f15) + this.fogColorBlue * f6 * f15; -@@ -1687,6 +1760,13 @@ +@@ -1687,6 +1766,13 @@ this.fogColorBlue = f7; } @@ -331,7 +352,7 @@ GlStateManager.clearColor(this.fogColorRed, this.fogColorGreen, this.fogColorBlue, 0.0F); } -@@ -1697,6 +1777,9 @@ +@@ -1697,6 +1783,9 @@ GlStateManager.glNormal3f(0.0F, -1.0F, 0.0F); GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); IBlockState iblockstate = ActiveRenderInfo.getBlockStateAtEntityViewpoint(this.mc.world, entity, partialTicks); @@ -341,7 +362,7 @@ if (entity instanceof EntityLivingBase && ((EntityLivingBase)entity).isPotionActive(MobEffects.BLINDNESS)) { float f1 = 5.0F; int i = ((EntityLivingBase)entity).getActivePotionEffect(MobEffects.BLINDNESS).getDuration(); -@@ -1753,6 +1836,7 @@ +@@ -1753,6 +1842,7 @@ GlStateManager.setFogStart(f * 0.05F); GlStateManager.setFogEnd(Math.min(f, 192.0F) * 0.5F); } From ff2cdfdebe34d3810f562cc2cc082e71f3e17148 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Mon, 24 Aug 2026 13:40:39 +0100 Subject: [PATCH 95/99] Update CleanroomGradle and LWJGL 3 --- build.gradle | 10 +--------- settings.gradle | 2 +- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/build.gradle b/build.gradle index d775ff775..0c90e9853 100644 --- a/build.gradle +++ b/build.gradle @@ -71,20 +71,12 @@ var export_arguments = [ '--add-exports=java.base/jdk.internal.reflect=ALL-UNNAMED' ] -def toolConfigurations = [ - 'decompiler', 'mergetool', 'mcinjector', 'installertools', 'accesstransformer' -] as Set - configurations.configureEach { configuration -> exclude group: 'com.ibm.icu', module: 'icu4j-core-mojang' // patchy ships its own copy of io.netty.bootstrap.Bootstrap // Against 4.2 netty it shadows the real class and dies on a superclass method that no longer exists exclude group: 'com.mojang', module: 'patchy' - if (configuration.name in toolConfigurations) { - return - } - resolutionStrategy.eachDependency { details -> switch ("${details.requested.group}:${details.requested.name}") { case 'com.google.guava:guava': details.useVersion '33.6.0-jre'; break @@ -181,7 +173,7 @@ dependencies { // java-objc-bridge bumped here for updated OSX arm64 natives api 'ca.weblite:java-objc-bridge:1.2' - api platform('org.lwjgl:lwjgl-bom:3.4.2') + api platform('org.lwjgl:lwjgl-bom:3.4.3') api 'org.lwjgl:lwjgl' api 'org.lwjgl:lwjgl-jemalloc' api 'org.lwjgl:lwjgl-opengl' diff --git a/settings.gradle b/settings.gradle index 3fbfc77a4..71a63f349 100644 --- a/settings.gradle +++ b/settings.gradle @@ -14,5 +14,5 @@ pluginManagement { } plugins { - id 'com.cleanroommc.cleanroomgradle.settings' version '0.10.4' + id 'com.cleanroommc.cleanroomgradle.settings' version '0.13.0' } From 8f2d7070b203b1ebb8500b89d0df47131bb0e017 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Wed, 26 Aug 2026 00:34:18 +0100 Subject: [PATCH 96/99] Update CG + ImagineBreaker --- build.gradle | 3 +- .../com/cleanroommc/hackery/Reflection.java | 57 ------- .../hackery/ReflectionHackery.java | 161 ------------------ .../hackery/enums/EnumHackery.java | 19 --- .../cleanroommc/hackery/EnumHackeryTest.java | 130 -------------- .../client/EnumHelperClient.java | 11 +- .../common/util/EnumHelper.java | 44 ++--- .../common/registry/ItemStackHolderRef.java | 25 +-- .../registries/ObjectHolderRef.java | 13 +- settings.gradle | 2 +- 10 files changed, 37 insertions(+), 428 deletions(-) delete mode 100644 module/cleanroom/src/main/java/com/cleanroommc/hackery/Reflection.java delete mode 100644 module/cleanroom/src/main/java/com/cleanroommc/hackery/ReflectionHackery.java delete mode 100644 module/cleanroom/src/main/java/com/cleanroommc/hackery/enums/EnumHackery.java delete mode 100644 module/cleanroom/src/test/java/com/cleanroommc/hackery/EnumHackeryTest.java diff --git a/build.gradle b/build.gradle index 0c90e9853..838bd9b58 100644 --- a/build.gradle +++ b/build.gradle @@ -124,8 +124,7 @@ dependencies { api 'org.jspecify:jspecify:1.0.0' api 'top.outlands:foundation:0.19.11' - api 'net.lenni0451:Reflect:1.6.4' // FIXME - api 'net.lenni0451.commons:unchecked:1.9.2' // FIXME + api 'zone.rong:imaginebreaker:3.2' api 'org.javassist:javassist:3.30.2-GA' // FIXME api 'lzma:lzma:0.0.1' api 'java3d:vecmath:1.5.2' // TODO: joml diff --git a/module/cleanroom/src/main/java/com/cleanroommc/hackery/Reflection.java b/module/cleanroom/src/main/java/com/cleanroommc/hackery/Reflection.java deleted file mode 100644 index 3d0e5633c..000000000 --- a/module/cleanroom/src/main/java/com/cleanroommc/hackery/Reflection.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.cleanroommc.hackery; - - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.Set; - -public class Reflection { - - public Reflection() { - } - - - public static Class getCallerClass(){ - return StackWalker.getInstance(Set.of(StackWalker.Option.RETAIN_CLASS_REFERENCE), 1).walk(s -> s.map(StackWalker.StackFrame::getDeclaringClass).skip(1).findFirst()).get(); - } - - - public static Class getCallerClass(int var0){ - return StackWalker.getInstance(Set.of(StackWalker.Option.RETAIN_CLASS_REFERENCE), var0 + 1).walk(s -> s.map(StackWalker.StackFrame::getDeclaringClass).skip(var0 + 1).findFirst()).get(); - } - - public static int getClassAccessFlags(Class var0){return var0.getModifiers();} - - public static boolean quickCheckMemberAccess(Class var0, int var1) { - return false; - } - - public static void ensureMemberAccess(Class var0, Class var1, Object var2, int var3) throws IllegalAccessException {} - - public static boolean verifyMemberAccess(Class var0, Class var1, Object var2, int var3) { - return false; - } - - - static boolean isSubclassOf(Class var0, Class var1) { - return false; - } - - public static synchronized void registerFieldsToFilter(Class var0, String... var1) {} - - public static synchronized void registerMethodsToFilter(Class var0, String... var1) {} - - public static Field[] filterFields(Class var0, Field[] var1) { - return null; - } - - public static Method[] filterMethods(Class var0, Method[] var1) { - return null; - } - - - public static boolean isCallerSensitive(Method var0) { - return false; - } - -} \ No newline at end of file diff --git a/module/cleanroom/src/main/java/com/cleanroommc/hackery/ReflectionHackery.java b/module/cleanroom/src/main/java/com/cleanroommc/hackery/ReflectionHackery.java deleted file mode 100644 index 3f3f55557..000000000 --- a/module/cleanroom/src/main/java/com/cleanroommc/hackery/ReflectionHackery.java +++ /dev/null @@ -1,161 +0,0 @@ -package com.cleanroommc.hackery; - -import net.lenni0451.reflect.Classes; -import net.lenni0451.reflect.Fields; - -import javax.annotation.Nullable; -import java.lang.reflect.*; -import java.util.function.Predicate; - -public final class ReflectionHackery { - - private static final Field field$modifiers; - - static { - Field modifiers; - modifiers = Fields.getDeclaredField(Field.class, "modifiers"); - if (modifiers == null) { - try { - modifiers = Field.class.getDeclaredField( - "modifiers"); // Try the standard way, this should always work with ImagineBreaker - } catch (ReflectiveOperationException ex) { - try { - modifiers = deepSearchForField( - Field.class, field -> "modifiers".equals(field.getName()), false); // Reliable Fallback - } catch (Exception exception) { - throw new RuntimeException(ex); - } - } - } - field$modifiers = modifiers; - field$modifiers.setAccessible(true); - } - - // Sensitive fields such as "modifiers" are only query-able via the native getDeclaredFields0 call - public static @Nullable Field deepSearchForField(Class clazz, Predicate search, boolean setAccessible) - throws ReflectiveOperationException { - Method getDeclaredFields0; - if (System.getProperty("java.vendor").contains("IBM")) { - getDeclaredFields0 = Class.class.getDeclaredMethod("getDeclaredFieldsImpl"); - getDeclaredFields0.setAccessible(true); - for (Field declaredField : (Field[]) getDeclaredFields0.invoke(clazz)) { - if (search.test(declaredField)) { - if (setAccessible) { - declaredField.setAccessible(true); - } - return declaredField; - } - } - } else { - getDeclaredFields0 = Class.class.getDeclaredMethod("getDeclaredFields0", boolean.class); // TODO: cache? - getDeclaredFields0.setAccessible(true); - for (Field declaredField : (Field[]) getDeclaredFields0.invoke(clazz, false)) { - if (search.test(declaredField)) { - if (setAccessible) { - declaredField.setAccessible(true); - } - return declaredField; - } - } - } - return null; - } - - public static void stripFieldOfFinalModifier(Field field) throws IllegalAccessException { - stripFieldOfModifier(field, Modifier.FINAL); - } - - public static void stripFieldOfModifier(Field field, int modifierFlag) throws IllegalAccessException { - Fields.setInt(field, field$modifiers, field.getModifiers() & ~modifierFlag); - } - - public static void setField(Field field, Object owner, Object value) { - Classes.ensureInitialized(field.getDeclaringClass()); - Fields.set(owner, field, value); - } - - public static void setBooleanField(Field field, Object owner, boolean value) { - Classes.ensureInitialized(field.getDeclaringClass()); - Fields.setBoolean(owner, field, value); - } - - public static void setByteField(Field field, Object owner, byte value) { - Classes.ensureInitialized(field.getDeclaringClass()); - Fields.setByte(owner, field, value); - } - - public static void setCharField(Field field, Object owner, char value) { - Classes.ensureInitialized(field.getDeclaringClass()); - Fields.setChar(owner, field, value); - } - - public static void setShortField(Field field, Object owner, short value) { - Classes.ensureInitialized(field.getDeclaringClass()); - Fields.setShort(owner, field, value); - } - - public static void setIntField(Field field, Object owner, int value) { - Classes.ensureInitialized(field.getDeclaringClass()); - Fields.setInt(owner, field, value); - } - - public static void setLongField(Field field, Object owner, long value) { - Classes.ensureInitialized(field.getDeclaringClass()); - Fields.setLong(owner, field, value); - } - - public static void setFloatField(Field field, Object owner, float value) { - Classes.ensureInitialized(field.getDeclaringClass()); - Fields.setFloat(owner, field, value); - } - - public static void setDoubleField(Field field, Object owner, double value) { - Classes.ensureInitialized(field.getDeclaringClass()); - Fields.setDouble(owner, field, value); - } - - public static Object getField(Field field, Object owner) { - Classes.ensureInitialized(field.getDeclaringClass()); - return Fields.get(owner, field); - } - - public static boolean getBooleanField(Field field, Object owner) { - Classes.ensureInitialized(field.getDeclaringClass()); - return Fields.getBoolean(owner, field); - } - - public static byte getByteField(Field field, Object owner) { - Classes.ensureInitialized(field.getDeclaringClass()); - return Fields.getByte(owner, field); - } - - public static char getCharField(Field field, Object owner) { - Classes.ensureInitialized(field.getDeclaringClass()); - return Fields.getChar(owner, field); - } - - public static short getShortField(Field field, Object owner) { - Classes.ensureInitialized(field.getDeclaringClass()); - return Fields.getShort(owner, field); - } - - public static int getIntField(Field field, Object owner) { - Classes.ensureInitialized(field.getDeclaringClass()); - return Fields.getInt(owner, field); - } - - public static long getLongField(Field field, Object owner) { - Classes.ensureInitialized(field.getDeclaringClass()); - return Fields.getLong(owner, field); - } - - public static float getFloatField(Field field, Object owner) { - Classes.ensureInitialized(field.getDeclaringClass()); - return Fields.getFloat(owner, field); - } - - public static double getDoubleField(Field field, Object owner) { - Classes.ensureInitialized(field.getDeclaringClass()); - return Fields.getDouble(owner, field); - } -} diff --git a/module/cleanroom/src/main/java/com/cleanroommc/hackery/enums/EnumHackery.java b/module/cleanroom/src/main/java/com/cleanroommc/hackery/enums/EnumHackery.java deleted file mode 100644 index 2ed244ff3..000000000 --- a/module/cleanroom/src/main/java/com/cleanroommc/hackery/enums/EnumHackery.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.cleanroommc.hackery.enums; - -import net.lenni0451.reflect.Enums; - -public final class EnumHackery { - - public static > T addEnumEntry(Class enumClass, String enumName) { - return addEnumEntry(enumClass, enumName, new Class[0], new Object[0]); - } - - public static > T addEnumEntry(Class enumClass, String enumName, Class[] parameterTypes, Object[] parameterValues) { - T o = Enums.newInstance(enumClass, enumName, enumClass.getEnumConstants().length, parameterTypes, parameterValues); - Enums.addEnumInstance(enumClass, o); - return o; - } - - private EnumHackery() { } - -} diff --git a/module/cleanroom/src/test/java/com/cleanroommc/hackery/EnumHackeryTest.java b/module/cleanroom/src/test/java/com/cleanroommc/hackery/EnumHackeryTest.java deleted file mode 100644 index 6f7239172..000000000 --- a/module/cleanroom/src/test/java/com/cleanroommc/hackery/EnumHackeryTest.java +++ /dev/null @@ -1,130 +0,0 @@ -package com.cleanroommc.hackery; - -import com.cleanroommc.hackery.enums.EnumHackery; -import net.lenni0451.reflect.Constructors; -import net.minecraft.item.ItemStack; -import org.junit.jupiter.api.Test; - -import java.util.Arrays; - -import static org.junit.jupiter.api.Assertions.*; - -public class EnumHackeryTest { - - public enum TestEnum { - - ONE, - TWO; - - } - - public enum CtorTestEnum { - - ONE("one"), - TWO("two"); - - CtorTestEnum(String string) { } - - } - - public enum VarargTestEnum { - ONE("one", "test1", "test2"), - TWO("two", "test3", "test4"); - - VarargTestEnum(String one, String... varargs) {} - } - - public enum MassiveTestEnum { - LEATHER("leather", 5, new int[]{1, 2, 3, 1}), - CHAIN("chainmail", 15, new int[]{1, 4, 5, 2}), - IRON("iron", 15, new int[]{2, 5, 6, 2}), - GOLD("gold", 7, new int[]{1, 3, 5, 2}), - DIAMOND("diamond", 33, new int[]{3, 6, 8, 3}); - - - public final String name; - public final int maxDamageFactor; - public final int[] damageReductionAmountArray; - //Added by forge for custom Armor materials. - public ItemStack repairMaterial = ItemStack.EMPTY; - - MassiveTestEnum(String nameIn, int maxDamageFactorIn, int[] damageReductionAmountArrayIn) - { - this.name = nameIn; - this.maxDamageFactor = maxDamageFactorIn; - this.damageReductionAmountArray = damageReductionAmountArrayIn; - } - - } - - @Test - public void testAddEnumEntryWithoutParameters() { - TestEnum[] oldValues = TestEnum.values(); - TestEnum three = EnumHackery.addEnumEntry(TestEnum.class, "THREE"); - TestEnum[] newValues = TestEnum.values(); - assertNotNull(Enum.valueOf(TestEnum.class, "THREE")); - assertEquals(Enum.valueOf(TestEnum.class, "THREE"), three); - assertNotNull(TestEnum.valueOf("THREE")); - assertEquals(TestEnum.valueOf("THREE"), three); - assertNotEquals(oldValues, newValues); - } - - @Test - public void testAddEnumEntryWithParameters() { - CtorTestEnum[] oldValues = CtorTestEnum.values(); - CtorTestEnum three = EnumHackery.addEnumEntry(CtorTestEnum.class, "THREE", new Class[] { String.class }, new Object[] { "three" }); - CtorTestEnum four = EnumHackery.addEnumEntry(CtorTestEnum.class, "FOUR", new Class[] { String.class }, new Object[] { "four" }); - CtorTestEnum[] newValues = CtorTestEnum.values(); - assertNotNull(Enum.valueOf(CtorTestEnum.class, "THREE")); - assertEquals(Enum.valueOf(CtorTestEnum.class, "THREE"), three); - assertNotNull(Enum.valueOf(CtorTestEnum.class, "FOUR")); - assertEquals(Enum.valueOf(CtorTestEnum.class, "FOUR"), four); - assertNotNull(CtorTestEnum.valueOf("THREE")); - assertEquals(CtorTestEnum.valueOf("THREE"), three); - assertNotNull(CtorTestEnum.valueOf("FOUR")); - assertEquals(CtorTestEnum.valueOf("FOUR"), four); - assertNotEquals(oldValues, newValues); - assertEquals(2, newValues.length - oldValues.length); - } - - @Test - public void testAddEnumEntryWithMassiveParameters() { - MassiveTestEnum[] oldValues = MassiveTestEnum.values(); - MassiveTestEnum obsidian = EnumHackery.addEnumEntry(MassiveTestEnum.class, "OBSIDIAN", new Class[] { String.class, int.class, int[].class }, new Object[] {"obsidian", 40, new int[]{1, 1, 1, 1}}); - MassiveTestEnum[] newValues = MassiveTestEnum.values(); - assertNotNull(Enum.valueOf(MassiveTestEnum.class, "OBSIDIAN")); - assertEquals(Enum.valueOf(MassiveTestEnum.class, "OBSIDIAN"), obsidian); - assertNotNull(MassiveTestEnum.valueOf("OBSIDIAN")); - assertEquals(MassiveTestEnum.valueOf("OBSIDIAN"), obsidian); - assertEquals("obsidian", obsidian.name); - assertEquals(40, obsidian.maxDamageFactor); - assertTrue(Arrays.stream(obsidian.damageReductionAmountArray).allMatch((a) -> a == 1)); - assertNotEquals(oldValues, newValues); - assertNotNull(MassiveTestEnum.CHAIN.repairMaterial); - assertNotNull(obsidian.repairMaterial); - assertEquals(obsidian.repairMaterial, MassiveTestEnum.valueOf("OBSIDIAN").repairMaterial); - } - - @Test - public void testAddEnumEntryWithVarargParameters() { - System.out.println("=============================="); - Arrays.stream(Constructors.getDeclaredConstructors(VarargTestEnum.class)).forEach(System.out::println); - System.out.println("=============================="); - VarargTestEnum[] oldValues = VarargTestEnum.values(); - VarargTestEnum three = EnumHackery.addEnumEntry(VarargTestEnum.class, "THREE", new Class[] { String.class, String[].class }, new Object[] { "three", new String[] { "test5", "test6" } }); - VarargTestEnum four = EnumHackery.addEnumEntry(VarargTestEnum.class, "FOUR", new Class[] { String.class, String[].class }, new Object[] { "four", new String[] { "test7", "test8", "test9" } }); - VarargTestEnum[] newValues = VarargTestEnum.values(); - assertNotNull(Enum.valueOf(VarargTestEnum.class, "THREE")); - assertEquals(Enum.valueOf(VarargTestEnum.class, "THREE"), three); - assertNotNull(Enum.valueOf(VarargTestEnum.class, "FOUR")); - assertEquals(Enum.valueOf(VarargTestEnum.class, "FOUR"), four); - assertNotNull(VarargTestEnum.valueOf("THREE")); - assertEquals(VarargTestEnum.valueOf("THREE"), three); - assertNotNull(VarargTestEnum.valueOf("FOUR")); - assertEquals(VarargTestEnum.valueOf("FOUR"), four); - assertNotEquals(oldValues, newValues); - assertEquals(2, newValues.length - oldValues.length); - } - - -} diff --git a/module/forge/src/main/java/net/minecraftforge/client/EnumHelperClient.java b/module/forge/src/main/java/net/minecraftforge/client/EnumHelperClient.java index 4117cc0d7..f83b55f49 100644 --- a/module/forge/src/main/java/net/minecraftforge/client/EnumHelperClient.java +++ b/module/forge/src/main/java/net/minecraftforge/client/EnumHelperClient.java @@ -19,7 +19,6 @@ package net.minecraftforge.client; -import com.cleanroommc.hackery.enums.EnumHackery; import net.minecraft.client.audio.MusicTicker; import net.minecraft.util.SoundEvent; import net.minecraft.util.Util.EnumOS; @@ -42,7 +41,7 @@ public class EnumHelperClient extends EnumHelper @Nullable public static GameType addGameType(String name, int id, String displayName, String shortName) { - return EnumHackery.addEnumEntry(GameType.class, name, + return addEnum(GameType.class, name, new Class[] { int.class, String.class, String.class }, new Object[] { id, displayName, shortName }); } @@ -50,7 +49,7 @@ public static GameType addGameType(String name, int id, String displayName, Stri @Nullable public static Options addOptions(String name, String langName, boolean isSlider, boolean isToggle) { - return EnumHackery.addEnumEntry(Options.class, name, + return addEnum(Options.class, name, new Class[] { String.class, boolean.class, boolean.class }, new Object[] { langName, isSlider, isToggle }); } @@ -58,7 +57,7 @@ public static Options addOptions(String name, String langName, boolean isSlider, @Nullable public static Options addOptions(String name, String langName, boolean isSlider, boolean isToggle, float valMin, float valMax, float valStep) { - return EnumHackery.addEnumEntry(Options.class, name, + return addEnum(Options.class, name, new Class[] { String.class, boolean.class, boolean.class, float.class, float.class, float.class }, new Object[] { langName, isSlider, isToggle, valMin, valMax, valStep }); } @@ -66,13 +65,13 @@ public static Options addOptions(String name, String langName, boolean isSlider, @Nullable public static EnumOS addOS2(String name) { - return EnumHackery.addEnumEntry(EnumOS.class, name); + return addEnum(EnumOS.class, name, new Class[0]); } @Nullable public static MusicTicker.MusicType addMusicType(String name, SoundEvent sound, int minDelay, int maxDelay) { - return EnumHackery.addEnumEntry(MusicTicker.MusicType.class, name, + return addEnum(MusicTicker.MusicType.class, name, new Class[] { SoundEvent.class, int.class, int.class }, new Object[] { sound, minDelay, maxDelay }); } diff --git a/module/forge/src/main/java/net/minecraftforge/common/util/EnumHelper.java b/module/forge/src/main/java/net/minecraftforge/common/util/EnumHelper.java index 8e4231bcc..88f21cd85 100644 --- a/module/forge/src/main/java/net/minecraftforge/common/util/EnumHelper.java +++ b/module/forge/src/main/java/net/minecraftforge/common/util/EnumHelper.java @@ -23,11 +23,9 @@ import java.util.*; import java.util.function.BiPredicate; -import com.cleanroommc.hackery.enums.EnumHackery; import com.google.common.base.Predicate; import com.google.common.collect.Lists; -import net.lenni0451.reflect.Fields; import net.minecraftforge.fml.common.EnhancedRuntimeException; import net.minecraftforge.fml.common.FMLLog; import net.minecraft.block.BlockPressurePlate.Sensitivity; @@ -53,6 +51,8 @@ import net.minecraft.world.IBlockAccess; import net.minecraft.world.gen.structure.StructureStrongholdPieces.Stronghold.Door; import net.minecraftforge.classloading.FMLForgePlugin; +import zone.rong.imaginebreaker.Index; +import zone.rong.imaginebreaker.api.ImagineBreaker; import org.apache.commons.lang3.ArrayUtils; import javax.annotation.Nullable; @@ -83,68 +83,68 @@ public class EnumHelper @Nullable public static EnumAction addAction(String name) { - return EnumHackery.addEnumEntry(EnumAction.class, name); + return addEnum(EnumAction.class, name, new Class[0]); } @Nullable public static ArmorMaterial addArmorMaterial(String name, String textureName, int durability, int[] reductionAmounts, int enchantability, SoundEvent soundOnEquip, float toughness) { - return EnumHackery.addEnumEntry(ArmorMaterial.class, name, + return addEnum(ArmorMaterial.class, name, new Class[] { String.class, int.class, int[].class, int.class, SoundEvent.class, float.class }, new Object[] { textureName, durability, reductionAmounts, enchantability, soundOnEquip, toughness }); } @Nullable public static EnumArt addArt(String name, String tile, int sizeX, int sizeY, int offsetX, int offsetY) { - return EnumHackery.addEnumEntry(EnumArt.class, name, + return addEnum(EnumArt.class, name, new Class[] { String.class, int.class, int.class, int.class, int.class }, new Object[] { tile, sizeX, sizeY, offsetX, offsetY }); } @Nullable public static EnumCreatureAttribute addCreatureAttribute(String name) { - return EnumHackery.addEnumEntry(EnumCreatureAttribute.class, name); + return addEnum(EnumCreatureAttribute.class, name, new Class[0]); } @Nullable public static EnumCreatureType addCreatureType(String name, Class typeClass, int maxNumber, Material material, boolean peaceful, boolean animal) { - return EnumHackery.addEnumEntry(EnumCreatureType.class, name, + return addEnum(EnumCreatureType.class, name, new Class[] { Class.class, int.class, Material.class, boolean.class, boolean.class }, new Object[] { typeClass, maxNumber, material, peaceful, animal }); } @Nullable public static Door addDoor(String name) { - return EnumHackery.addEnumEntry(Door.class, name); + return addEnum(Door.class, name, new Class[0]); } @Nullable public static EnumEnchantmentType addEnchantmentType(String name, Predicate delegate) { - return EnumHackery.addEnumEntry(EnumEnchantmentType.class, name, new Class[] { Predicate.class }, new Object[] { delegate }); + return addEnum(EnumEnchantmentType.class, name, new Class[] { Predicate.class }, new Object[] { delegate }); } @Nullable public static Sensitivity addSensitivity(String name) { - return EnumHackery.addEnumEntry(Sensitivity.class, name); + return addEnum(Sensitivity.class, name, new Class[0]); } @Nullable public static RayTraceResult.Type addMovingObjectType(String name) { - return EnumHackery.addEnumEntry(RayTraceResult.Type.class, name); + return addEnum(RayTraceResult.Type.class, name, new Class[0]); } @Nullable public static EnumSkyBlock addSkyBlock(String name, int lightValue) { - return EnumHackery.addEnumEntry(EnumSkyBlock.class, name, new Class[] { int.class }, new Object[] { lightValue }); + return addEnum(EnumSkyBlock.class, name, new Class[] { int.class }, new Object[] { lightValue }); } @Nullable public static SleepResult addStatus(String name) { - return EnumHackery.addEnumEntry(SleepResult.class, name); + return addEnum(SleepResult.class, name, new Class[0]); } @Nullable public static ToolMaterial addToolMaterial(String name, int harvestLevel, int maxUses, float efficiency, float damage, int enchantability) { - return EnumHackery.addEnumEntry(ToolMaterial.class, name, + return addEnum(ToolMaterial.class, name, new Class[] { int.class, int.class, float.class, float.class, int.class }, new Object[] { harvestLevel, maxUses, efficiency, damage, enchantability }); } @@ -154,13 +154,13 @@ public static ToolMaterial addToolMaterial(String name, int harvestLevel, int ma @Deprecated public static EnumRarity addRarity(String name, TextFormatting color, String displayName) { - return EnumHackery.addEnumEntry(EnumRarity.class, name, new Class[] { TextFormatting.class, String.class }, new Object[] { color, displayName }); + return addEnum(EnumRarity.class, name, new Class[] { TextFormatting.class, String.class }, new Object[] { color, displayName }); } @Nullable public static EntityLiving.SpawnPlacementType addSpawnPlacementType(String name, BiPredicate predicate) { - return EnumHackery.addEnumEntry(EntityLiving.SpawnPlacementType.class, name, new Class[] { BiPredicate.class }, new Object[] { predicate }); + return addEnum(EntityLiving.SpawnPlacementType.class, name, new Class[] { BiPredicate.class }, new Object[] { predicate }); } /** @@ -173,12 +173,12 @@ public static EntityLiving.SpawnPlacementType addSpawnPlacementType(String name, @Nullable public static HorseArmorType addHorseArmor(String name, String textureLocation, int armorStrength) { - return EnumHackery.addEnumEntry(HorseArmorType.class, name, new Class[] { String.class, int.class }, new Object[] { textureLocation, armorStrength }); + return addEnum(HorseArmorType.class, name, new Class[] { String.class, int.class }, new Object[] { textureLocation, armorStrength }); } public static void setFailsafeFieldValue(Field field, @Nullable Object target, @Nullable Object value) throws Exception { - Fields.setObject(target, field, value); + Index.get().set(target, field, value); } //Tests an enum is compatible with these args, throws an error if not. @@ -282,10 +282,12 @@ protected void printStackTrace(WrappedPrintStream stream) } @Nullable - @SuppressWarnings({"unchecked", "rawtypes"}) - public static > T addEnum(Class enumType, String enumName, Class[] paramTypes, Object... paramValues) + public static > T addEnum(Class enumType, String enumName, Class[] paramTypes, Object... paramValues) { - return (T) EnumHackery.addEnumEntry((Class) enumType, enumName, paramTypes, paramValues); + ImagineBreaker imagineBreaker = Index.get(); + T value = imagineBreaker.newEnum(enumType, enumName, enumType.getEnumConstants().length, paramTypes, paramValues); + imagineBreaker.addEnum(enumType, value); + return value; } diff --git a/module/forge/src/main/java/net/minecraftforge/fml/common/registry/ItemStackHolderRef.java b/module/forge/src/main/java/net/minecraftforge/fml/common/registry/ItemStackHolderRef.java index 568a0f2af..49a16e067 100644 --- a/module/forge/src/main/java/net/minecraftforge/fml/common/registry/ItemStackHolderRef.java +++ b/module/forge/src/main/java/net/minecraftforge/fml/common/registry/ItemStackHolderRef.java @@ -21,11 +21,10 @@ import java.lang.reflect.Field; -import com.cleanroommc.hackery.ReflectionHackery; -import net.lenni0451.reflect.Classes; -import net.lenni0451.reflect.Fields; import net.minecraft.item.ItemStack; import net.minecraftforge.fml.common.FMLLog; +import zone.rong.imaginebreaker.Index; +import zone.rong.imaginebreaker.api.ImagineBreaker; /** * Internal class used in tracking {@link GameRegistry.ItemStackHolder} references @@ -46,20 +45,6 @@ class ItemStackHolderRef { this.itemName = itemName; this.meta = meta; this.serializednbt = serializednbt; - makeWritable(field); - } - - private static void makeWritable(Field f) - { - try - { - f.setAccessible(true); - ReflectionHackery.stripFieldOfFinalModifier(f); - } - catch (ReflectiveOperationException e) - { - throw new RuntimeException(e); - } } public void apply() @@ -75,9 +60,9 @@ public void apply() } try { - Classes.ensureInitialized(field.getDeclaringClass()); - Fields.setObject(null, field, is); - //field.set(null, is); + ImagineBreaker touma = Index.get(); + touma.ensureInitialized(field.getDeclaringClass()); + touma.set(null, field, is); } catch (Exception e) { diff --git a/module/forge/src/main/java/net/minecraftforge/registries/ObjectHolderRef.java b/module/forge/src/main/java/net/minecraftforge/registries/ObjectHolderRef.java index 194c71b61..7bf4a884e 100644 --- a/module/forge/src/main/java/net/minecraftforge/registries/ObjectHolderRef.java +++ b/module/forge/src/main/java/net/minecraftforge/registries/ObjectHolderRef.java @@ -24,12 +24,12 @@ import java.util.LinkedList; import java.util.Queue; -import com.cleanroommc.hackery.ReflectionHackery; import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.common.FMLLog; import net.minecraftforge.fml.common.registry.GameRegistry; import net.minecraftforge.fml.common.registry.GameRegistry.ObjectHolder; +import zone.rong.imaginebreaker.Index; import javax.annotation.Nullable; @@ -82,15 +82,6 @@ class ObjectHolderRef { throw new IllegalStateException(String.format("The ObjectHolder annotation cannot apply to a field that does not map to a registry. Ensure the registry was created during the RegistryEvent.NewRegistry event. (found : %s at %s.%s)", field.getType().getName(), field.getDeclaringClass().getName(), field.getName())); } - try - { - field.setAccessible(true); - ReflectionHackery.stripFieldOfFinalModifier(field); - } - catch (ReflectiveOperationException e) - { - throw new RuntimeException(e); - } } @SuppressWarnings("unchecked") @@ -142,7 +133,7 @@ public void apply() } try { - ReflectionHackery.setField(field, null, thing); + Index.get().set(null, field, thing); } catch (IllegalArgumentException e) { diff --git a/settings.gradle b/settings.gradle index 71a63f349..b5c4c33ef 100644 --- a/settings.gradle +++ b/settings.gradle @@ -14,5 +14,5 @@ pluginManagement { } plugins { - id 'com.cleanroommc.cleanroomgradle.settings' version '0.13.0' + id 'com.cleanroommc.cleanroomgradle.settings' version '0.13.2' } From 66595fbbd13d01e200393399319eab0cae2fffa0 Mon Sep 17 00:00:00 2001 From: Rongmario Date: Wed, 26 Aug 2026 15:33:16 +0100 Subject: [PATCH 97/99] Catchup kirino --- module/kirino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/kirino b/module/kirino index 1e43363f5..3c03b9fa9 160000 --- a/module/kirino +++ b/module/kirino @@ -1 +1 @@ -Subproject commit 1e43363f522532c8489d3280e380025e898ae003 +Subproject commit 3c03b9fa95e2b6a886845642481bf5ec1a7c4882 From eb61c35cf2b8a803041ea846f3bbbbaf41450b2c Mon Sep 17 00:00:00 2001 From: Rongmario Date: Wed, 26 Aug 2026 17:11:52 +0100 Subject: [PATCH 98/99] Catchup Kirino again --- module/kirino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/kirino b/module/kirino index 3c03b9fa9..55257fc26 160000 --- a/module/kirino +++ b/module/kirino @@ -1 +1 @@ -Subproject commit 3c03b9fa95e2b6a886845642481bf5ec1a7c4882 +Subproject commit 55257fc26e8a9c491d7a60afde9ec3e8b2168f96 From 1881956afbcb36bd09eb090262d8c900eac2a21a Mon Sep 17 00:00:00 2001 From: Rongmario Date: Thu, 27 Aug 2026 11:31:21 +0100 Subject: [PATCH 99/99] Update Foundation --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 838bd9b58..db16eefbc 100644 --- a/build.gradle +++ b/build.gradle @@ -123,7 +123,7 @@ dependencies { implementation "com.cleanroommc:mixinextras-common:${providers.gradleProperty('mixinextras_version').get()}" api 'org.jspecify:jspecify:1.0.0' - api 'top.outlands:foundation:0.19.11' + api 'top.outlands:foundation:0.21.0' api 'zone.rong:imaginebreaker:3.2' api 'org.javassist:javassist:3.30.2-GA' // FIXME api 'lzma:lzma:0.0.1'