diff --git a/patches/net/minecraft/client/color/item/ItemColors.java.patch b/patches/net/minecraft/client/color/item/ItemColors.java.patch index afe4aac398..e98475f291 100644 --- a/patches/net/minecraft/client/color/item/ItemColors.java.patch +++ b/patches/net/minecraft/client/color/item/ItemColors.java.patch @@ -10,7 +10,7 @@ public static ItemColors createDefault(BlockColors p_92684_) { ItemColors itemcolors = new ItemColors(); -@@ -101,17 +_,20 @@ +@@ -101,17 +_,28 @@ (p_359075_, p_359076_) -> p_359076_ == 0 ? -1 : ARGB.opaque(p_359075_.getOrDefault(DataComponents.MAP_COLOR, MapItemColor.DEFAULT).rgb()), Items.FILLED_MAP ); @@ -24,6 +24,14 @@ return itemcolor == null ? -1 : itemcolor.getColor(p_92677_, p_92678_); } ++ /** ++ * Neo: returns the color handler for the given {@code item}, or {@code null} if one isn't registered. ++ */ ++ @org.jetbrains.annotations.Nullable ++ public ItemColor get(Item item) { ++ return itemColors.get(item); ++ } ++ + /** @deprecated Register via {@link net.neoforged.neoforge.client.event.RegisterColorHandlersEvent.Item} */ + @Deprecated public void register(ItemColor p_92690_, ItemLike... p_92691_) { diff --git a/patches/net/minecraft/client/gui/Font.java.patch b/patches/net/minecraft/client/gui/Font.java.patch index 92bc34f85a..a45603a940 100644 --- a/patches/net/minecraft/client/gui/Font.java.patch +++ b/patches/net/minecraft/client/gui/Font.java.patch @@ -9,12 +9,48 @@ private static final float EFFECT_DEPTH = 0.01F; private static final Vector3f SHADOW_OFFSET = new Vector3f(0.0F, 0.0F, 0.03F); public static final int ALPHA_CUTOFF = 8; -@@ -309,6 +_,8 @@ - public StringSplitter getSplitter() { +@@ -42,6 +_,8 @@ + private final Function fonts; + final boolean filterFishyGlyphs; + private final StringSplitter splitter; ++ /** Neo: enables linear filtering on text */ ++ public boolean enableTextTextureLinearFiltering = false; + + public Font(Function p_243253_, boolean p_243245_) { + this.fonts = p_243253_; +@@ -310,6 +_,8 @@ return this.splitter; } -+ -+ @Override public Font self() { return this; } ++ @Override public Font self() { return this; } ++ @OnlyIn(Dist.CLIENT) public static enum DisplayMode { + NORMAL, +@@ -417,7 +_,7 @@ + p_381032_ - 1.0F, this.y + 9.0F, this.x, this.y - 1.0F, this.getUnderTextEffectDepth(), this.backgroundColor + ); + bakedglyph = Font.this.getFontSet(Style.DEFAULT_FONT).whiteGlyph(); +- VertexConsumer vertexconsumer = this.bufferSource.getBuffer(bakedglyph.renderType(this.mode)); ++ VertexConsumer vertexconsumer = this.bufferSource.getBuffer(bakedglyph.renderType(this.mode, Font.this.enableTextTextureLinearFiltering)); + bakedglyph.renderEffect(bakedglyph$effect, this.pose, vertexconsumer, this.packedLightCoords); + } + +@@ -427,7 +_,7 @@ + bakedglyph = Font.this.getFontSet(Style.DEFAULT_FONT).whiteGlyph(); + } + +- VertexConsumer vertexconsumer1 = this.bufferSource.getBuffer(bakedglyph.renderType(this.mode)); ++ VertexConsumer vertexconsumer1 = this.bufferSource.getBuffer(bakedglyph.renderType(this.mode, Font.this.enableTextTextureLinearFiltering)); + + for (BakedGlyph.Effect bakedglyph$effect1 : this.effects) { + bakedglyph.renderEffect(bakedglyph$effect1, this.pose, vertexconsumer1, this.packedLightCoords); +@@ -440,7 +_,7 @@ + void renderCharacters() { + for (BakedGlyph.GlyphInstance bakedglyph$glyphinstance : this.glyphInstances) { + BakedGlyph bakedglyph = bakedglyph$glyphinstance.glyph(); +- VertexConsumer vertexconsumer = this.bufferSource.getBuffer(bakedglyph.renderType(this.mode)); ++ VertexConsumer vertexconsumer = this.bufferSource.getBuffer(bakedglyph.renderType(this.mode, Font.this.enableTextTextureLinearFiltering)); + bakedglyph.renderChar(bakedglyph$glyphinstance, this.pose, vertexconsumer, this.packedLightCoords); + } + } diff --git a/patches/net/minecraft/client/gui/font/GlyphRenderTypes.java.patch b/patches/net/minecraft/client/gui/font/GlyphRenderTypes.java.patch new file mode 100644 index 0000000000..41aedd3241 --- /dev/null +++ b/patches/net/minecraft/client/gui/font/GlyphRenderTypes.java.patch @@ -0,0 +1,50 @@ +--- a/net/minecraft/client/gui/font/GlyphRenderTypes.java ++++ b/net/minecraft/client/gui/font/GlyphRenderTypes.java +@@ -7,22 +_,42 @@ + import net.neoforged.api.distmarker.OnlyIn; + + @OnlyIn(Dist.CLIENT) +-public record GlyphRenderTypes(RenderType normal, RenderType seeThrough, RenderType polygonOffset) { ++public record GlyphRenderTypes(RenderType normal, RenderType seeThrough, RenderType polygonOffset, RenderType normalBlur, RenderType seeThroughBlur, RenderType polygonOffsetBlur) { ++ /** @deprecated Neo: Use {@link GlyphRenderTypes(RenderType,RenderType,RenderType,RenderType,RenderType,RenderType)} instead */ ++ @Deprecated ++ public GlyphRenderTypes(RenderType normal, RenderType seeThrough, RenderType polygonOffset) { ++ this(normal, seeThrough, polygonOffset, normal, seeThrough, polygonOffset); ++ } ++ + public static GlyphRenderTypes createForIntensityTexture(ResourceLocation p_285411_) { + return new GlyphRenderTypes( + RenderType.textIntensity(p_285411_), RenderType.textIntensitySeeThrough(p_285411_), RenderType.textIntensityPolygonOffset(p_285411_) ++ , net.neoforged.neoforge.client.NeoForgeRenderTypes.getTextIntensityFiltered(p_285411_), ++ net.neoforged.neoforge.client.NeoForgeRenderTypes.getTextIntensitySeeThroughFiltered(p_285411_), ++ net.neoforged.neoforge.client.NeoForgeRenderTypes.getTextIntensityPolygonOffsetFiltered(p_285411_) + ); + } + + public static GlyphRenderTypes createForColorTexture(ResourceLocation p_285486_) { +- return new GlyphRenderTypes(RenderType.text(p_285486_), RenderType.textSeeThrough(p_285486_), RenderType.textPolygonOffset(p_285486_)); ++ return new GlyphRenderTypes(RenderType.text(p_285486_), RenderType.textSeeThrough(p_285486_), RenderType.textPolygonOffset(p_285486_), ++ net.neoforged.neoforge.client.NeoForgeRenderTypes.getTextFiltered(p_285486_), ++ net.neoforged.neoforge.client.NeoForgeRenderTypes.getTextSeeThroughFiltered(p_285486_), ++ net.neoforged.neoforge.client.NeoForgeRenderTypes.getTextPolygonOffsetFiltered(p_285486_) ++ ); + } + + public RenderType select(Font.DisplayMode p_285259_) { ++ return this.select(p_285259_, false); ++ } ++ ++ /** ++ * Neo: returns the {@link RenderType} to use for the given {@link Font.DisplayMode} and blur setting ++ */ ++ public RenderType select(Font.DisplayMode p_285259_, boolean blur) { + return switch (p_285259_) { +- case NORMAL -> this.normal; +- case SEE_THROUGH -> this.seeThrough; +- case POLYGON_OFFSET -> this.polygonOffset; ++ case NORMAL -> blur ? this.normalBlur : this.normal; ++ case SEE_THROUGH -> blur ? this.seeThroughBlur : this.seeThrough; ++ case POLYGON_OFFSET -> blur ? this.polygonOffsetBlur : this.polygonOffset; + }; + } + } diff --git a/patches/net/minecraft/client/gui/font/glyphs/BakedGlyph.java.patch b/patches/net/minecraft/client/gui/font/glyphs/BakedGlyph.java.patch new file mode 100644 index 0000000000..44c6510a6f --- /dev/null +++ b/patches/net/minecraft/client/gui/font/glyphs/BakedGlyph.java.patch @@ -0,0 +1,18 @@ +--- a/net/minecraft/client/gui/font/glyphs/BakedGlyph.java ++++ b/net/minecraft/client/gui/font/glyphs/BakedGlyph.java +@@ -75,6 +_,15 @@ + p_95223_.addVertex(p_254370_, p_95221_.x0, p_95221_.y1, p_95221_.depth).setColor(p_95221_.color).setUv(this.u1, this.v0).setLight(p_95224_); + } + ++ /** ++ * Neo: returns the {@link RenderType} to use for the given {@link Font.DisplayMode} and blur setting ++ */ ++ public RenderType renderType(Font.DisplayMode p_181388_, boolean blur) { ++ return this.renderTypes.select(p_181388_, blur); ++ } ++ ++ /** @deprecated Neo: Use {@link #renderType(Font.DisplayMode, boolean)} instead */ ++ @Deprecated + public RenderType renderType(Font.DisplayMode p_181388_) { + return this.renderTypes.select(p_181388_); + } diff --git a/patches/net/minecraft/client/renderer/RenderType.java.patch b/patches/net/minecraft/client/renderer/RenderType.java.patch index 3186edd211..9f4bd0f613 100644 --- a/patches/net/minecraft/client/renderer/RenderType.java.patch +++ b/patches/net/minecraft/client/renderer/RenderType.java.patch @@ -1,52 +1,9 @@ --- a/net/minecraft/client/renderer/RenderType.java +++ b/net/minecraft/client/renderer/RenderType.java -@@ -1098,7 +_,7 @@ - } - - public static RenderType text(ResourceLocation p_110498_) { -- return TEXT.apply(p_110498_); -+ return net.neoforged.neoforge.client.NeoForgeRenderTypes.getText(p_110498_); - } - - public static RenderType textBackground() { -@@ -1106,19 +_,19 @@ - } - - public static RenderType textIntensity(ResourceLocation p_173238_) { -- return TEXT_INTENSITY.apply(p_173238_); -+ return net.neoforged.neoforge.client.NeoForgeRenderTypes.getTextIntensity(p_173238_); - } - - public static RenderType textPolygonOffset(ResourceLocation p_181445_) { -- return TEXT_POLYGON_OFFSET.apply(p_181445_); -+ return net.neoforged.neoforge.client.NeoForgeRenderTypes.getTextPolygonOffset(p_181445_); - } - - public static RenderType textIntensityPolygonOffset(ResourceLocation p_181447_) { -- return TEXT_INTENSITY_POLYGON_OFFSET.apply(p_181447_); -+ return net.neoforged.neoforge.client.NeoForgeRenderTypes.getTextIntensityPolygonOffset(p_181447_); - } - - public static RenderType textSeeThrough(ResourceLocation p_110501_) { -- return TEXT_SEE_THROUGH.apply(p_110501_); -+ return net.neoforged.neoforge.client.NeoForgeRenderTypes.getTextSeeThrough(p_110501_); - } - - public static RenderType textBackgroundSeeThrough() { -@@ -1126,7 +_,7 @@ - } - - public static RenderType textIntensitySeeThrough(ResourceLocation p_173241_) { -- return TEXT_INTENSITY_SEE_THROUGH.apply(p_173241_); -+ return net.neoforged.neoforge.client.NeoForgeRenderTypes.getTextIntensitySeeThrough(p_173241_); - } - - public static RenderType lightning() { -@@ -1622,5 +_,17 @@ - public String toString() { +@@ -1623,4 +_,16 @@ return this.name; } -+ } + } + + // Neo: Assign internal IDs for RenderType to be used in rendering + private int chunkLayerId = -1; @@ -58,5 +15,5 @@ + int i = 0; + for (var layer : chunkBufferLayers()) + layer.chunkLayerId = i++; - } ++ } } diff --git a/patches/net/minecraft/server/Main.java.patch b/patches/net/minecraft/server/Main.java.patch index e32cfe17d8..08f6bb71e1 100644 --- a/patches/net/minecraft/server/Main.java.patch +++ b/patches/net/minecraft/server/Main.java.patch @@ -85,6 +85,22 @@ } catch (NbtException | ReportedNbtException | IOException ioexception) { LOGGER.error("Failed to load world data from {}", levelstoragesource$leveldirectory.oldDataFile(), ioexception); LOGGER.error( +@@ -173,6 +_,15 @@ + + PackRepository packrepository = ServerPacksSource.createPackRepository(levelstoragesource$levelstorageaccess); + ++ if (gametestEnabled) { ++ net.neoforged.neoforge.gametest.GameTestHooks.registerGametests(); ++ net.minecraft.core.BlockPos spawnPos = optionset.valueOf(spawnPosOpt); ++ MinecraftServer.spin(thread -> net.minecraft.gametest.framework.GameTestServer.create(thread, levelstoragesource$levelstorageaccess, packrepository, net.minecraft.gametest.framework.GameTestRegistry.getAllTestFunctions(), spawnPos)); ++ // If we're running a gametest server we don't need to load the resources normally (GameTestServer#create does it using a flat world) ++ // or create a shutdown thread as the gametest server will always exit itself ++ return; ++ } ++ + WorldStem worldstem; + try { + WorldLoader.InitConfig worldloader$initconfig = loadOrCreateConfig(dedicatedserversettings.getProperties(), dynamic1, flag, packrepository); @@ -214,6 +_,9 @@ worlddimensions = dedicatedserverproperties.createDimensions(p_359487_.datapackWorldgen()); } @@ -95,48 +111,9 @@ WorldDimensions.Complete worlddimensions$complete = worlddimensions.bake(registry); Lifecycle lifecycle = worlddimensions$complete.lifecycle().add(p_359487_.datapackWorldgen().allRegistriesLifecycle()); return new WorldLoader.DataLoadOutput<>( -@@ -246,24 +_,22 @@ - - WorldData worlddata = worldstem.worldData(); - levelstoragesource$levelstorageaccess.saveDataTag(registryaccess$frozen, worlddata); -- final DedicatedServer dedicatedserver = MinecraftServer.spin( -+ final MinecraftServer dedicatedserver = MinecraftServer.spin( - p_293760_ -> { -- DedicatedServer dedicatedserver1 = new DedicatedServer( -- p_293760_, -- levelstoragesource$levelstorageaccess, -- packrepository, -- worldstem, -- dedicatedserversettings, -- DataFixers.getDataFixer(), -- services, -- LoggerChunkProgressListener::createFromGameruleRadius -- ); -+ MinecraftServer dedicatedserver1; -+ if (gametestEnabled) { -+ net.neoforged.neoforge.gametest.GameTestHooks.registerGametests(); -+ net.minecraft.core.BlockPos spawnPos = optionset.valueOf(spawnPosOpt); -+ dedicatedserver1 = net.minecraft.gametest.framework.GameTestServer.create(p_293760_, levelstoragesource$levelstorageaccess, packrepository, net.minecraft.gametest.framework.GameTestRegistry.getAllTestFunctions(), spawnPos); -+ } else { -+ dedicatedserver1 = new DedicatedServer(p_293760_, levelstoragesource$levelstorageaccess, packrepository, worldstem, dedicatedserversettings, DataFixers.getDataFixer(), services, LoggerChunkProgressListener::createFromGameruleRadius); -+ } - dedicatedserver1.setPort(optionset.valueOf(optionspec11)); - dedicatedserver1.setDemo(optionset.has(optionspec2)); - dedicatedserver1.setId(optionset.valueOf(optionspec12)); - boolean flag2 = !optionset.has(optionspec) && !optionset.valuesOf(optionspec15).contains("nogui"); -- if (flag2 && !GraphicsEnvironment.isHeadless()) { -- dedicatedserver1.showGui(); -+ if (dedicatedserver1 instanceof DedicatedServer dedicatedServer && flag2 && !GraphicsEnvironment.isHeadless()) { -+ dedicatedServer.showGui(); - } - - return dedicatedserver1; -@@ -272,7 +_,10 @@ - Thread thread = new Thread("Server Shutdown Thread") { +@@ -273,6 +_,7 @@ @Override public void run() { -+ // FORGE: Halting as GameTestServer will cause issues as it always calls System#exit on both crash and normal exit, so skip it -+ if (!(dedicatedserver instanceof net.minecraft.gametest.framework.GameTestServer)) dedicatedserver.halt(true); + org.apache.logging.log4j.LogManager.shutdown(); // we're manually managing the logging shutdown on the server. Make sure we do it here at the end. } diff --git a/patches/net/minecraft/world/entity/LivingEntity.java.patch b/patches/net/minecraft/world/entity/LivingEntity.java.patch index e219806900..7e9bf2eaed 100644 --- a/patches/net/minecraft/world/entity/LivingEntity.java.patch +++ b/patches/net/minecraft/world/entity/LivingEntity.java.patch @@ -290,6 +290,15 @@ itemstack = itemstack1.copy(); itemstack1.shrink(1); break; +@@ -1309,7 +_,7 @@ + } + + ItemStack itemstack = this.getItemBlockingWith(); +- if (!p_21276_.is(DamageTypeTags.BYPASSES_SHIELD) && itemstack != null && itemstack.getItem() instanceof ShieldItem && !flag) { ++ if (!p_21276_.is(DamageTypeTags.BYPASSES_SHIELD) && itemstack != null && !flag) { + Vec3 vec3 = p_21276_.getSourcePosition(); + if (vec3 != null) { + Vec3 vec31 = this.calculateViewVector(0.0F, this.getYHeadRot()); @@ -1343,6 +_,7 @@ } diff --git a/patches/net/minecraft/world/entity/item/FallingBlockEntity.java.patch b/patches/net/minecraft/world/entity/item/FallingBlockEntity.java.patch index a8174886eb..9c04db9fba 100644 --- a/patches/net/minecraft/world/entity/item/FallingBlockEntity.java.patch +++ b/patches/net/minecraft/world/entity/item/FallingBlockEntity.java.patch @@ -18,3 +18,13 @@ blockpos = blockhitresult.getBlockPos(); flag1 = true; } +@@ -236,6 +_,9 @@ + } + + this.setDeltaMovement(this.getDeltaMovement().scale(0.98)); ++ if (isAlive() && block instanceof net.neoforged.neoforge.common.extensions.IFallableExtension feblock) { ++ feblock.fallingTick(level(), blockPosition(), this); ++ } + } + } + diff --git a/patches/net/minecraft/world/inventory/FurnaceResultSlot.java.patch b/patches/net/minecraft/world/inventory/FurnaceResultSlot.java.patch index b437d67b28..e7e60046f5 100644 --- a/patches/net/minecraft/world/inventory/FurnaceResultSlot.java.patch +++ b/patches/net/minecraft/world/inventory/FurnaceResultSlot.java.patch @@ -1,9 +1,12 @@ --- a/net/minecraft/world/inventory/FurnaceResultSlot.java +++ b/net/minecraft/world/inventory/FurnaceResultSlot.java -@@ -49,5 +_,6 @@ +@@ -48,6 +_,9 @@ + abstractfurnaceblockentity.awardUsedRecipesAndPopExperience(serverplayer); } ++ if (this.removeCount != 0) { ++ net.neoforged.neoforge.event.EventHooks.firePlayerSmeltedEvent(this.player, p_39558_, this.removeCount); ++ } this.removeCount = 0; -+ net.neoforged.neoforge.event.EventHooks.firePlayerSmeltedEvent(this.player, p_39558_); } } diff --git a/patches/net/minecraft/world/item/SpawnEggItem.java.patch b/patches/net/minecraft/world/item/SpawnEggItem.java.patch index b3a50e656b..5154845a82 100644 --- a/patches/net/minecraft/world/item/SpawnEggItem.java.patch +++ b/patches/net/minecraft/world/item/SpawnEggItem.java.patch @@ -1,51 +1,48 @@ --- a/net/minecraft/world/item/SpawnEggItem.java +++ b/net/minecraft/world/item/SpawnEggItem.java -@@ -41,11 +_,14 @@ - private final int highlightColor; - private final EntityType defaultType; - -+ /** @deprecated Forge: Use {@link net.neoforged.neoforge.common.DeferredSpawnEggItem} instead for suppliers */ -+ @Deprecated - public SpawnEggItem(EntityType p_43207_, int p_43208_, int p_43209_, Item.Properties p_43210_) { - super(p_43210_); - this.defaultType = p_43207_; - this.backgroundColor = p_43208_; - this.highlightColor = p_43209_; -+ if (p_43207_ != null) - BY_ID.put(p_43207_, this); - } - -@@ -133,6 +_,8 @@ - - @Nullable - public static SpawnEggItem byId(@Nullable EntityType p_43214_) { -+ var ret = net.neoforged.neoforge.common.DeferredSpawnEggItem.deferredOnlyById(p_43214_); -+ if (ret != null) return ret; - return BY_ID.get(p_43214_); - } - -@@ -142,12 +_,12 @@ - - public EntityType getType(ItemStack p_330335_) { - CustomData customdata = p_330335_.getOrDefault(DataComponents.ENTITY_DATA, CustomData.EMPTY); -- return !customdata.isEmpty() ? customdata.read(ENTITY_TYPE_FIELD_CODEC).result().orElse(this.defaultType) : this.defaultType; -+ return !customdata.isEmpty() ? customdata.read(ENTITY_TYPE_FIELD_CODEC).result().orElse(getDefaultType()) : getDefaultType(); - } - - @Override - public FeatureFlagSet requiredFeatures() { -- return this.defaultType.requiredFeatures(); -+ return this.getDefaultType().requiredFeatures(); - } - - public Optional spawnOffspringFromSpawnEgg( -@@ -178,5 +_,9 @@ - } +@@ -179,4 +_,45 @@ } } + } ++ ++ public static final net.minecraft.core.dispenser.DispenseItemBehavior DEFAULT_DISPENSE_BEHAVIOR = new net.minecraft.core.dispenser.DefaultDispenseItemBehavior() { ++ @Override ++ protected ItemStack execute(net.minecraft.core.dispenser.BlockSource source, ItemStack egg) { ++ Direction direction = source.state().getValue(net.minecraft.world.level.block.DispenserBlock.FACING); ++ EntityType entitytype = ((SpawnEggItem)egg.getItem()).getType(egg); ++ ++ try { ++ entitytype.spawn( ++ source.level(), egg, null, source.pos().relative(direction), EntitySpawnReason.DISPENSER, direction != Direction.UP, false ++ ); ++ } catch (Exception exception) { ++ LOGGER.error("Error while dispensing spawn egg from dispenser at {}", source.pos(), exception); ++ return ItemStack.EMPTY; ++ } ++ ++ egg.shrink(1); ++ source.level().gameEvent(null, GameEvent.ENTITY_PLACE, source.pos()); ++ return egg; ++ } ++ }; ++ ++ /** ++ * {@return the dispense behavior to register by default} ++ */ ++ @Nullable ++ protected net.minecraft.core.dispenser.DispenseItemBehavior createDispenseBehavior() { ++ return DEFAULT_DISPENSE_BEHAVIOR; + } + -+ protected EntityType getDefaultType() { -+ return defaultType; - } ++ @net.neoforged.bus.api.SubscribeEvent(priority = net.neoforged.bus.api.EventPriority.LOWEST) ++ private static void registerDispenseBehavior(final net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent event) { ++ event.enqueueWork(() -> eggs().forEach(egg -> { ++ if (!net.minecraft.world.level.block.DispenserBlock.DISPENSER_REGISTRY.containsKey(egg)) { ++ var beh = egg.createDispenseBehavior(); ++ if (beh != null) { ++ net.minecraft.world.level.block.DispenserBlock.registerBehavior(egg, beh); ++ } ++ } ++ })); ++ } } diff --git a/patches/net/minecraft/world/level/block/Fallable.java.patch b/patches/net/minecraft/world/level/block/Fallable.java.patch new file mode 100644 index 0000000000..4f0be6f7e3 --- /dev/null +++ b/patches/net/minecraft/world/level/block/Fallable.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/level/block/Fallable.java ++++ b/net/minecraft/world/level/block/Fallable.java +@@ -7,7 +_,7 @@ + import net.minecraft.world.level.Level; + import net.minecraft.world.level.block.state.BlockState; + +-public interface Fallable { ++public interface Fallable extends net.neoforged.neoforge.common.extensions.IFallableExtension { + default void onLand(Level p_153220_, BlockPos p_153221_, BlockState p_153222_, BlockState p_153223_, FallingBlockEntity p_153224_) { + } + diff --git a/settings.gradle b/settings.gradle index 74b177945e..4049a3edc6 100644 --- a/settings.gradle +++ b/settings.gradle @@ -10,7 +10,10 @@ plugins { id 'net.neoforged.gradle.platform' version '7.0.163' } -rootProject.name = rootDir.name +if (rootProject.name.toLowerCase() == "neoforge") { + // Solve name clashes between projects/neoforge and the rootProject for Eclipse. + rootProject.name = "NeoForge-Root" +} dynamicProjects { include ':base' diff --git a/src/main/java/net/neoforged/neoforge/client/ClientNeoForgeMod.java b/src/main/java/net/neoforged/neoforge/client/ClientNeoForgeMod.java index c378194405..d55c15caec 100644 --- a/src/main/java/net/neoforged/neoforge/client/ClientNeoForgeMod.java +++ b/src/main/java/net/neoforged/neoforge/client/ClientNeoForgeMod.java @@ -10,9 +10,12 @@ import net.minecraft.client.renderer.RenderType; import net.minecraft.core.BlockPos; import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.ARGB; +import net.minecraft.world.item.SpawnEggItem; import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.material.FluidState; import net.neoforged.api.distmarker.Dist; +import net.neoforged.bus.api.EventPriority; import net.neoforged.bus.api.IEventBus; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.ModContainer; @@ -22,6 +25,7 @@ import net.neoforged.neoforge.client.event.ClientPlayerNetworkEvent; import net.neoforged.neoforge.client.event.ModelEvent; import net.neoforged.neoforge.client.event.RegisterClientReloadListenersEvent; +import net.neoforged.neoforge.client.event.RegisterColorHandlersEvent; import net.neoforged.neoforge.client.event.RegisterNamedRenderTypesEvent; import net.neoforged.neoforge.client.event.RegisterSpriteSourceTypesEvent; import net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions; @@ -157,4 +161,13 @@ public ResourceLocation getFlowingTexture() { } }, milkType)); } + + @SubscribeEvent(priority = EventPriority.LOWEST) + static void registerSpawnEggColors(RegisterColorHandlersEvent.Item event) { + SpawnEggItem.eggs().forEach(egg -> { + if (event.getItemColors().get(egg) == null) { + event.register((stack, layer) -> ARGB.opaque(egg.getColor(layer)), egg); + } + }); + } } diff --git a/src/main/java/net/neoforged/neoforge/client/NeoForgeRenderTypes.java b/src/main/java/net/neoforged/neoforge/client/NeoForgeRenderTypes.java index 98988e55c7..bc467405ce 100644 --- a/src/main/java/net/neoforged/neoforge/client/NeoForgeRenderTypes.java +++ b/src/main/java/net/neoforged/neoforge/client/NeoForgeRenderTypes.java @@ -7,7 +7,6 @@ import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.VertexFormat; -import java.util.function.BooleanSupplier; import java.util.function.Function; import java.util.function.Supplier; import net.minecraft.Util; @@ -32,8 +31,6 @@ public enum NeoForgeRenderTypes { ITEM_UNSORTED_UNLIT_TRANSLUCENT(() -> getUnlitTranslucent(TextureAtlas.LOCATION_BLOCKS, false)), TRANSLUCENT_ON_PARTICLES_TARGET(() -> getTranslucentParticlesTarget(TextureAtlas.LOCATION_BLOCKS)); - public static boolean enableTextTextureLinearFiltering = false; - /** * @return A RenderType fit for multi-layer solid item rendering. */ @@ -94,45 +91,45 @@ public static RenderType getEntityCutoutMipped(ResourceLocation textureLocation) } /** - * @return Replacement of {@link RenderType#text(ResourceLocation)}, but with optional linear texture filtering. + * @return Replacement of {@link RenderType#text(ResourceLocation)}, but with linear texture filtering. */ - public static RenderType getText(ResourceLocation locationIn) { - return Internal.TEXT.apply(locationIn); + public static RenderType getTextFiltered(ResourceLocation locationIn) { + return Internal.TEXT_FILTERED.apply(locationIn); } /** - * @return Replacement of {@link RenderType#textIntensity(ResourceLocation)}, but with optional linear texture filtering. + * @return Replacement of {@link RenderType#textIntensity(ResourceLocation)}, but with linear texture filtering. */ - public static RenderType getTextIntensity(ResourceLocation locationIn) { - return Internal.TEXT_INTENSITY.apply(locationIn); + public static RenderType getTextIntensityFiltered(ResourceLocation locationIn) { + return Internal.TEXT_INTENSITY_FILTERED.apply(locationIn); } /** - * @return Replacement of {@link RenderType#textPolygonOffset(ResourceLocation)}, but with optional linear texture filtering. + * @return Replacement of {@link RenderType#textPolygonOffset(ResourceLocation)}, but with linear texture filtering. */ - public static RenderType getTextPolygonOffset(ResourceLocation locationIn) { - return Internal.TEXT_POLYGON_OFFSET.apply(locationIn); + public static RenderType getTextPolygonOffsetFiltered(ResourceLocation locationIn) { + return Internal.TEXT_POLYGON_OFFSET_FILTERED.apply(locationIn); } /** - * @return Replacement of {@link RenderType#textIntensityPolygonOffset(ResourceLocation)}, but with optional linear texture filtering. + * @return Replacement of {@link RenderType#textIntensityPolygonOffset(ResourceLocation)}, but with linear texture filtering. */ - public static RenderType getTextIntensityPolygonOffset(ResourceLocation locationIn) { - return Internal.TEXT_INTENSITY_POLYGON_OFFSET.apply(locationIn); + public static RenderType getTextIntensityPolygonOffsetFiltered(ResourceLocation locationIn) { + return Internal.TEXT_INTENSITY_POLYGON_OFFSET_FILTERED.apply(locationIn); } /** - * @return Replacement of {@link RenderType#textSeeThrough(ResourceLocation)}, but with optional linear texture filtering. + * @return Replacement of {@link RenderType#textSeeThrough(ResourceLocation)}, but with linear texture filtering. */ - public static RenderType getTextSeeThrough(ResourceLocation locationIn) { - return Internal.TEXT_SEETHROUGH.apply(locationIn); + public static RenderType getTextSeeThroughFiltered(ResourceLocation locationIn) { + return Internal.TEXT_SEETHROUGH_FILTERED.apply(locationIn); } /** - * @return Replacement of {@link RenderType#textIntensitySeeThrough(ResourceLocation)}, but with optional linear texture filtering. + * @return Replacement of {@link RenderType#textIntensitySeeThrough(ResourceLocation)}, but with linear texture filtering. */ - public static RenderType getTextIntensitySeeThrough(ResourceLocation locationIn) { - return Internal.TEXT_INTENSITY_SEETHROUGH.apply(locationIn); + public static RenderType getTextIntensitySeeThroughFiltered(ResourceLocation locationIn) { + return Internal.TEXT_INTENSITY_SEETHROUGH_FILTERED.apply(locationIn); } /** @@ -242,82 +239,82 @@ private static RenderType layeredItemTranslucent(ResourceLocation locationIn) { return RenderType.create("neoforge_item_entity_translucent_cull", DefaultVertexFormat.NEW_ENTITY, VertexFormat.Mode.QUADS, 256, true, true, rendertype$state); } - public static Function TEXT = Util.memoize(Internal::getText); + public static Function TEXT_FILTERED = Util.memoize(Internal::getTextFiltered); - private static RenderType getText(ResourceLocation locationIn) { + private static RenderType getTextFiltered(ResourceLocation locationIn) { var rendertype$state = RenderType.CompositeState.builder() .setShaderState(RenderType.RENDERTYPE_TEXT_SHADER) - .setTextureState(new CustomizableTextureState(locationIn, () -> NeoForgeRenderTypes.enableTextTextureLinearFiltering, () -> false)) + .setTextureState(new RenderStateShard.TextureStateShard(locationIn, TriState.TRUE, false)) .setTransparencyState(RenderType.TRANSLUCENT_TRANSPARENCY) .setLightmapState(RenderType.LIGHTMAP) .createCompositeState(false); - return RenderType.create("neoforge_text", DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP, VertexFormat.Mode.QUADS, 256, false, true, rendertype$state); + return RenderType.create("neoforge_text", DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP, VertexFormat.Mode.QUADS, 256, false, false, rendertype$state); } - public static Function TEXT_INTENSITY = Util.memoize(Internal::getTextIntensity); + public static Function TEXT_INTENSITY_FILTERED = Util.memoize(Internal::getTextIntensityFiltered); - private static RenderType getTextIntensity(ResourceLocation locationIn) { + private static RenderType getTextIntensityFiltered(ResourceLocation locationIn) { var rendertype$state = RenderType.CompositeState.builder() .setShaderState(RenderType.RENDERTYPE_TEXT_INTENSITY_SHADER) - .setTextureState(new CustomizableTextureState(locationIn, () -> NeoForgeRenderTypes.enableTextTextureLinearFiltering, () -> false)) + .setTextureState(new RenderStateShard.TextureStateShard(locationIn, TriState.TRUE, false)) .setTransparencyState(RenderType.TRANSLUCENT_TRANSPARENCY) .setLightmapState(RenderType.LIGHTMAP) .createCompositeState(false); - return RenderType.create("neoforge_text_intensity", DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP, VertexFormat.Mode.QUADS, 256, false, true, rendertype$state); + return RenderType.create("neoforge_text_intensity", DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP, VertexFormat.Mode.QUADS, 256, false, false, rendertype$state); } - public static Function TEXT_POLYGON_OFFSET = Util.memoize(Internal::getTextPolygonOffset); + public static Function TEXT_POLYGON_OFFSET_FILTERED = Util.memoize(Internal::getTextPolygonOffsetFiltered); - private static RenderType getTextPolygonOffset(ResourceLocation locationIn) { + private static RenderType getTextPolygonOffsetFiltered(ResourceLocation locationIn) { var rendertype$state = RenderType.CompositeState.builder() .setShaderState(RenderType.RENDERTYPE_TEXT_SHADER) - .setTextureState(new CustomizableTextureState(locationIn, () -> NeoForgeRenderTypes.enableTextTextureLinearFiltering, () -> false)) + .setTextureState(new RenderStateShard.TextureStateShard(locationIn, TriState.TRUE, false)) .setTransparencyState(RenderType.TRANSLUCENT_TRANSPARENCY) .setLightmapState(RenderType.LIGHTMAP) .setLayeringState(RenderType.POLYGON_OFFSET_LAYERING) .createCompositeState(false); - return RenderType.create("neoforge_text_polygon_offset", DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP, VertexFormat.Mode.QUADS, 256, false, true, rendertype$state); + return RenderType.create("neoforge_text_polygon_offset", DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP, VertexFormat.Mode.QUADS, 256, false, false, rendertype$state); } - public static Function TEXT_INTENSITY_POLYGON_OFFSET = Util.memoize(Internal::getTextIntensityPolygonOffset); + public static Function TEXT_INTENSITY_POLYGON_OFFSET_FILTERED = Util.memoize(Internal::getTextIntensityPolygonOffsetFiltered); - private static RenderType getTextIntensityPolygonOffset(ResourceLocation locationIn) { + private static RenderType getTextIntensityPolygonOffsetFiltered(ResourceLocation locationIn) { var rendertype$state = RenderType.CompositeState.builder() .setShaderState(RenderType.RENDERTYPE_TEXT_INTENSITY_SHADER) - .setTextureState(new CustomizableTextureState(locationIn, () -> NeoForgeRenderTypes.enableTextTextureLinearFiltering, () -> false)) + .setTextureState(new RenderStateShard.TextureStateShard(locationIn, TriState.TRUE, false)) .setTransparencyState(RenderType.TRANSLUCENT_TRANSPARENCY) .setLightmapState(RenderType.LIGHTMAP) .setLayeringState(RenderType.POLYGON_OFFSET_LAYERING) .createCompositeState(false); - return RenderType.create("neoforge_text_intensity_polygon_offset", DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP, VertexFormat.Mode.QUADS, 256, false, true, rendertype$state); + return RenderType.create("neoforge_text_intensity_polygon_offset", DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP, VertexFormat.Mode.QUADS, 256, false, false, rendertype$state); } - public static Function TEXT_SEETHROUGH = Util.memoize(Internal::getTextSeeThrough); + public static Function TEXT_SEETHROUGH_FILTERED = Util.memoize(Internal::getTextSeeThroughFiltered); - private static RenderType getTextSeeThrough(ResourceLocation locationIn) { + private static RenderType getTextSeeThroughFiltered(ResourceLocation locationIn) { var rendertype$state = RenderType.CompositeState.builder() .setShaderState(RenderType.RENDERTYPE_TEXT_SEE_THROUGH_SHADER) - .setTextureState(new CustomizableTextureState(locationIn, () -> NeoForgeRenderTypes.enableTextTextureLinearFiltering, () -> false)) + .setTextureState(new RenderStateShard.TextureStateShard(locationIn, TriState.TRUE, false)) .setTransparencyState(RenderType.TRANSLUCENT_TRANSPARENCY) .setLightmapState(RenderType.LIGHTMAP) .setDepthTestState(RenderType.NO_DEPTH_TEST) .setWriteMaskState(RenderType.COLOR_WRITE) .createCompositeState(false); - return RenderType.create("neoforge_text_see_through", DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP, VertexFormat.Mode.QUADS, 256, false, true, rendertype$state); + return RenderType.create("neoforge_text_see_through", DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP, VertexFormat.Mode.QUADS, 256, false, false, rendertype$state); } - public static Function TEXT_INTENSITY_SEETHROUGH = Util.memoize(Internal::getTextIntensitySeeThrough); + public static Function TEXT_INTENSITY_SEETHROUGH_FILTERED = Util.memoize(Internal::getTextIntensitySeeThroughFiltered); - private static RenderType getTextIntensitySeeThrough(ResourceLocation locationIn) { + private static RenderType getTextIntensitySeeThroughFiltered(ResourceLocation locationIn) { var rendertype$state = RenderType.CompositeState.builder() .setShaderState(RenderType.RENDERTYPE_TEXT_INTENSITY_SEE_THROUGH_SHADER) - .setTextureState(new CustomizableTextureState(locationIn, () -> NeoForgeRenderTypes.enableTextTextureLinearFiltering, () -> false)) + .setTextureState(new RenderStateShard.TextureStateShard(locationIn, TriState.TRUE, false)) .setTransparencyState(RenderType.TRANSLUCENT_TRANSPARENCY) .setLightmapState(RenderType.LIGHTMAP) .setDepthTestState(RenderType.NO_DEPTH_TEST) .setWriteMaskState(RenderType.COLOR_WRITE) .createCompositeState(false); - return RenderType.create("neoforge_text_see_through", DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP, VertexFormat.Mode.QUADS, 256, false, true, rendertype$state); + return RenderType.create("neoforge_text_see_through", DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP, VertexFormat.Mode.QUADS, 256, false, false, rendertype$state); } public static Function TRANSLUCENT_PARTICLES_TARGET = Util.memoize(Internal::getTranslucentParticlesTarget); @@ -333,23 +330,4 @@ private static RenderType getTranslucentParticlesTarget(ResourceLocation locatio return RenderType.create("neoforge_translucent_particles_target", DefaultVertexFormat.BLOCK, VertexFormat.Mode.QUADS, 2097152, true, true, rendertype$state); } } - - private static class CustomizableTextureState extends TextureStateShard { - private final BooleanSupplier blurSupplier; - private final BooleanSupplier mipmapSupplier; - - private CustomizableTextureState(ResourceLocation resLoc, BooleanSupplier blur, BooleanSupplier mipmap) { - super(resLoc, blur.getAsBoolean() ? TriState.TRUE : TriState.DEFAULT, mipmap.getAsBoolean()); - blurSupplier = blur; - mipmapSupplier = mipmap; - } - - @Override - public void setupRenderState() { - // must be done before super call as super uses the `blur` and `mipmap` fields within the `setupState` runnable | See super constructor - blur = blurSupplier.getAsBoolean() ? TriState.TRUE : TriState.DEFAULT; - mipmap = mipmapSupplier.getAsBoolean(); - super.setupRenderState(); - } - } } diff --git a/src/main/java/net/neoforged/neoforge/client/event/RenderLivingEvent.java b/src/main/java/net/neoforged/neoforge/client/event/RenderLivingEvent.java index 5ecbefe370..d705fb1522 100644 --- a/src/main/java/net/neoforged/neoforge/client/event/RenderLivingEvent.java +++ b/src/main/java/net/neoforged/neoforge/client/event/RenderLivingEvent.java @@ -22,9 +22,6 @@ * Fired when a {@link LivingEntity} is rendered. * See the two subclasses to listen for before and after rendering. * - *

Despite this event's use of generic type parameters, this is not a {@link net.neoforged.bus.api.GenericEvent}, - * and should not be treated as such (such as using generic-specific listeners, which may cause a {@link ClassCastException}).

- * * @param the living entity that is being rendered * @param the model for the living entity * @see RenderLivingEvent.Pre @@ -99,11 +96,11 @@ public int getPackedLight() { * Fired before an entity is rendered. * This can be used to render additional effects or suppress rendering. * - *

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

This event is {@linkplain ICancellableEvent cancelable}. * If this event is cancelled, then the entity will not be rendered and the corresponding * {@link RenderLivingEvent.Post} will not be fired.

* - *

This event is fired on the {@linkplain NeoForge#EVENT_BUS main Forge event bus}, + *

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

* * @param the living entity that is being rendered @@ -119,9 +116,9 @@ public Pre(S renderState, LivingEntityRenderer renderer, float partialT /** * Fired after an entity is rendered, if the corresponding {@link RenderLivingEvent.Post} is not cancelled. * - *

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

+ *

This event is not {@linkplain ICancellableEvent cancelable}.

* - *

This event is fired on the {@linkplain NeoForge#EVENT_BUS main Forge event bus}, + *

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

* * @param the living entity that was rendered diff --git a/src/main/java/net/neoforged/neoforge/client/event/RenderPlayerEvent.java b/src/main/java/net/neoforged/neoforge/client/event/RenderPlayerEvent.java index b2fd3652e7..ff8113951f 100644 --- a/src/main/java/net/neoforged/neoforge/client/event/RenderPlayerEvent.java +++ b/src/main/java/net/neoforged/neoforge/client/event/RenderPlayerEvent.java @@ -11,7 +11,6 @@ import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.entity.player.PlayerRenderer; import net.minecraft.client.renderer.entity.state.PlayerRenderState; -import net.neoforged.bus.api.Event; import net.neoforged.bus.api.ICancellableEvent; import net.neoforged.fml.LogicalSide; import net.neoforged.neoforge.common.NeoForge; @@ -31,15 +30,20 @@ protected RenderPlayerEvent(PlayerRenderState renderState, PlayerRenderer render super(renderState, renderer, partialTick, poseStack, multiBufferSource, packedLight); } + @Override + public PlayerRenderer getRenderer() { + return (PlayerRenderer) super.getRenderer(); + } + /** * Fired before the player is rendered. * This can be used for rendering additional effects or suppressing rendering. * - *

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

This event is {@linkplain ICancellableEvent cancellable}. * If this event is cancelled, then the player will not be rendered and the corresponding * {@link RenderPlayerEvent.Post} will not be fired.

* - *

This event is fired on the {@linkplain NeoForge#EVENT_BUS main Forge event bus}, + *

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

*/ public static class Pre extends RenderPlayerEvent implements ICancellableEvent { @@ -52,9 +56,9 @@ public Pre(PlayerRenderState renderState, PlayerRenderer renderer, float partial /** * Fired after the player is rendered, if the corresponding {@link RenderPlayerEvent.Pre} is not cancelled. * - *

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

+ *

This event is not {@linkplain ICancellableEvent cancellable}.

* - *

This event is fired on the {@linkplain NeoForge#EVENT_BUS main Forge event bus}, + *

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

*/ public static class Post extends RenderPlayerEvent { diff --git a/src/main/java/net/neoforged/neoforge/client/gui/ModListScreen.java b/src/main/java/net/neoforged/neoforge/client/gui/ModListScreen.java index fb67ef7d16..8edbbd6572 100644 --- a/src/main/java/net/neoforged/neoforge/client/gui/ModListScreen.java +++ b/src/main/java/net/neoforged/neoforge/client/gui/ModListScreen.java @@ -25,6 +25,7 @@ import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.EditBox; +import net.minecraft.client.gui.components.LogoRenderer; import net.minecraft.client.gui.components.ObjectSelectionList; import net.minecraft.client.gui.narration.NarrationElementOutput; import net.minecraft.client.gui.screens.Screen; @@ -374,30 +375,36 @@ private void updateCache() { VersionChecker.CheckResult vercheck = VersionChecker.getResult(selectedMod); @SuppressWarnings("resource") - Pair logoData = selectedMod.getLogoFile().map(logoFile -> { - TextureManager tm = this.minecraft.getTextureManager(); - final Pack.ResourcesSupplier resourcePack = ResourcePackLoader.getPackFor(selectedMod.getModId()) - .orElse(ResourcePackLoader.getPackFor("neoforge").orElseThrow(() -> new RuntimeException("Can't find neoforge, WHAT!"))); - try (PackResources packResources = resourcePack.openPrimary(new PackLocationInfo("mod/" + selectedMod.getModId(), Component.empty(), PackSource.BUILT_IN, Optional.empty()))) { - NativeImage logo = null; - IoSupplier logoResource = packResources.getRootResource(logoFile.split("[/\\\\]")); - if (logoResource != null) - logo = NativeImage.read(logoResource.get()); - if (logo != null) { - - return Pair.of(tm.register("modlogo", new DynamicTexture(logo) { - @Override - public void upload() { - this.bind(); - NativeImage td = this.getPixels(); - // Use custom "blur" value which controls texture filtering (nearest-neighbor vs linear) - this.getPixels().upload(0, 0, 0, 0, 0, td.getWidth(), td.getHeight(), selectedMod.getLogoBlur(), false, false, false); - } - }), new Size2i(logo.getWidth(), logo.getHeight())); - } - } catch (IOException | IllegalArgumentException e) {} - return Pair.of(null, new Size2i(0, 0)); - }).orElse(Pair.of(null, new Size2i(0, 0))); + Pair logoData; + + if (selectedMod.getModId().equals(ResourceLocation.DEFAULT_NAMESPACE)) { + logoData = Pair.of(LogoRenderer.MINECRAFT_LOGO, new Size2i(LogoRenderer.LOGO_TEXTURE_WIDTH, LogoRenderer.LOGO_TEXTURE_HEIGHT)); + } else { + logoData = selectedMod.getLogoFile().map(logoFile -> { + TextureManager tm = this.minecraft.getTextureManager(); + final Pack.ResourcesSupplier resourcePack = ResourcePackLoader.getPackFor(selectedMod.getModId()) + .orElse(ResourcePackLoader.getPackFor("neoforge").orElseThrow(() -> new RuntimeException("Can't find neoforge, WHAT!"))); + try (PackResources packResources = resourcePack.openPrimary(new PackLocationInfo("mod/" + selectedMod.getModId(), Component.empty(), PackSource.BUILT_IN, Optional.empty()))) { + NativeImage logo = null; + IoSupplier logoResource = packResources.getRootResource(logoFile.split("[/\\\\]")); + if (logoResource != null) + logo = NativeImage.read(logoResource.get()); + if (logo != null) { + + return Pair.of(tm.register("modlogo", new DynamicTexture(logo) { + @Override + public void upload() { + this.bind(); + NativeImage td = this.getPixels(); + // Use custom "blur" value which controls texture filtering (nearest-neighbor vs linear) + this.getPixels().upload(0, 0, 0, 0, 0, td.getWidth(), td.getHeight(), selectedMod.getLogoBlur(), false, false, false); + } + }), new Size2i(logo.getWidth(), logo.getHeight())); + } + } catch (IOException | IllegalArgumentException e) {} + return Pair.of(null, new Size2i(0, 0)); + }).orElse(Pair.of(null, new Size2i(0, 0))); + } lines.add(selectedMod.getDisplayName()); lines.add(FMLTranslations.parseMessage("fml.menu.mods.info.version", MavenVersionTranslator.artifactVersionToString(selectedMod.getVersion()))); diff --git a/src/main/java/net/neoforged/neoforge/client/model/generators/ModelProvider.java b/src/main/java/net/neoforged/neoforge/client/model/generators/ModelProvider.java index e39d3e8e30..f52db6e3c8 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/generators/ModelProvider.java +++ b/src/main/java/net/neoforged/neoforge/client/model/generators/ModelProvider.java @@ -371,6 +371,10 @@ public T leaves(String name, ResourceLocation texture) { return singleTexture(name, BLOCK_FOLDER + "/leaves", "all", texture); } + public T flowerPotCross(String name, ResourceLocation plant) { + return singleTexture(name, BLOCK_FOLDER + "/flower_pot_cross", "plant", plant); + } + /** * {@return a model builder that's not directly saved to disk. Meant for use in custom model loaders.} */ diff --git a/src/main/java/net/neoforged/neoforge/common/DeferredSpawnEggItem.java b/src/main/java/net/neoforged/neoforge/common/DeferredSpawnEggItem.java deleted file mode 100644 index 67c84ef09a..0000000000 --- a/src/main/java/net/neoforged/neoforge/common/DeferredSpawnEggItem.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.common; - -import java.util.ArrayList; -import java.util.IdentityHashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Supplier; -import net.minecraft.core.Direction; -import net.minecraft.core.dispenser.DispenseItemBehavior; -import net.minecraft.util.ARGB; -import net.minecraft.world.entity.EntitySpawnReason; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.Mob; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.SpawnEggItem; -import net.minecraft.world.level.block.DispenserBlock; -import net.minecraft.world.level.gameevent.GameEvent; -import net.neoforged.api.distmarker.Dist; -import net.neoforged.bus.api.EventPriority; -import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.fml.common.EventBusSubscriber; -import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; -import net.neoforged.neoforge.client.event.RegisterColorHandlersEvent; -import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.Nullable; - -public class DeferredSpawnEggItem extends SpawnEggItem { - private static final List MOD_EGGS = new ArrayList<>(); - private static final Map, DeferredSpawnEggItem> TYPE_MAP = new IdentityHashMap<>(); - private final Supplier> typeSupplier; - - public DeferredSpawnEggItem(Supplier> type, int backgroundColor, int highlightColor, Properties props) { - super((EntityType) null, backgroundColor, highlightColor, props); - this.typeSupplier = type; - - MOD_EGGS.add(this); - } - - @Nullable - protected DispenseItemBehavior createDispenseBehavior() { - return DEFAULT_DISPENSE_BEHAVIOR; - } - - @ApiStatus.Internal - @Nullable - public static SpawnEggItem deferredOnlyById(@Nullable EntityType type) { - return TYPE_MAP.get(type); - } - - @Override - protected EntityType getDefaultType() { - return this.typeSupplier.get(); - } - - private static final DispenseItemBehavior DEFAULT_DISPENSE_BEHAVIOR = (source, stack) -> { - Direction face = source.state().getValue(DispenserBlock.FACING); - EntityType type = ((SpawnEggItem) stack.getItem()).getType(stack); - - try { - type.spawn(source.level(), stack, null, source.pos().relative(face), EntitySpawnReason.DISPENSER, face != Direction.UP, false); - } catch (Exception exception) { - DispenseItemBehavior.LOGGER.error("Error while dispensing spawn egg from dispenser at {}", source.pos(), exception); - return ItemStack.EMPTY; - } - - stack.shrink(1); - source.level().gameEvent(GameEvent.ENTITY_PLACE, source.pos(), GameEvent.Context.of(source.state())); - return stack; - }; - - @EventBusSubscriber(modid = "neoforge", bus = EventBusSubscriber.Bus.MOD) - private static class CommonHandler { - @SubscribeEvent - public static void onCommonSetup(FMLCommonSetupEvent event) { - event.enqueueWork(() -> { - MOD_EGGS.forEach(egg -> { - DispenseItemBehavior dispenseBehavior = egg.createDispenseBehavior(); - if (dispenseBehavior != null) { - DispenserBlock.registerBehavior(egg, dispenseBehavior); - } - - TYPE_MAP.put(egg.typeSupplier.get(), egg); - }); - }); - } - } - - @EventBusSubscriber(value = Dist.CLIENT, modid = "neoforge", bus = EventBusSubscriber.Bus.MOD) - private static class ColorRegisterHandler { - @SubscribeEvent(priority = EventPriority.HIGHEST) - public static void registerSpawnEggColors(RegisterColorHandlersEvent.Item event) { - MOD_EGGS.forEach(egg -> event.register((stack, layer) -> ARGB.opaque(egg.getColor(layer)), egg)); - } - } -} diff --git a/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java b/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java index 31a0bebee8..19a9ea79ca 100644 --- a/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java +++ b/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java @@ -52,6 +52,7 @@ import net.minecraft.world.entity.ai.attributes.RangedAttribute; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.item.Items; +import net.minecraft.world.item.SpawnEggItem; import net.minecraft.world.item.crafting.display.SlotDisplay; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.GameRules; @@ -589,6 +590,8 @@ public NeoForgeMod(IEventBus modEventBus, Dist dist, ModContainer container) { modEventBus.register(NeoForgeDataMaps.class); + modEventBus.register(SpawnEggItem.class); // Registers dispenser behaviour for eggs + if (isPRBuild(container.getModInfo().getVersion().toString())) { isPRBuild = true; ModLoader.addLoadingIssue(ModLoadingIssue.warning("loadwarning.neoforge.prbuild").withAffectedMod(container.getModInfo())); diff --git a/src/main/java/net/neoforged/neoforge/common/extensions/IFallableExtension.java b/src/main/java/net/neoforged/neoforge/common/extensions/IFallableExtension.java new file mode 100644 index 0000000000..e4551d4661 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/common/extensions/IFallableExtension.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.common.extensions; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.item.FallingBlockEntity; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Fallable; + +public interface IFallableExtension { + /** + * Called in {@link FallingBlockEntity#tick()} after vanilla processing on both server and client. + *

+ * This is not called in the tick where the entity lands, see {@link Fallable}. + * + * @param level The current level. + * @param currentPosition The current position of the entity as a {@link BlockPos}. + * @param entity The falling entity. + */ + default void fallingTick(Level level, BlockPos currentPosition, FallingBlockEntity entity) {} +} diff --git a/src/main/java/net/neoforged/neoforge/event/EventHooks.java b/src/main/java/net/neoforged/neoforge/event/EventHooks.java index c5109000f3..7529a767d1 100644 --- a/src/main/java/net/neoforged/neoforge/event/EventHooks.java +++ b/src/main/java/net/neoforged/neoforge/event/EventHooks.java @@ -908,8 +908,8 @@ public static void firePlayerCraftingEvent(Player player, ItemStack crafted, Con NeoForge.EVENT_BUS.post(new PlayerEvent.ItemCraftedEvent(player, crafted, craftMatrix)); } - public static void firePlayerSmeltedEvent(Player player, ItemStack smelted) { - NeoForge.EVENT_BUS.post(new PlayerEvent.ItemSmeltedEvent(player, smelted)); + public static void firePlayerSmeltedEvent(Player player, ItemStack smelted, int amountRemoved) { + NeoForge.EVENT_BUS.post(new PlayerEvent.ItemSmeltedEvent(player, smelted, amountRemoved)); } /** diff --git a/src/main/java/net/neoforged/neoforge/event/entity/player/PlayerEvent.java b/src/main/java/net/neoforged/neoforge/event/entity/player/PlayerEvent.java index 020c86cb0e..66c55569e4 100644 --- a/src/main/java/net/neoforged/neoforge/event/entity/player/PlayerEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/entity/player/PlayerEvent.java @@ -408,15 +408,21 @@ public Container getInventory() { public static class ItemSmeltedEvent extends PlayerEvent { private final ItemStack smelting; + private final int amountRemoved; - public ItemSmeltedEvent(Player player, ItemStack crafting) { + public ItemSmeltedEvent(Player player, ItemStack crafting, int amountRemoved) { super(player); this.smelting = crafting; + this.amountRemoved = amountRemoved; } public ItemStack getSmelting() { return this.smelting; } + + public int getAmountRemoved() { + return this.amountRemoved; + } } public static class PlayerLoggedInEvent extends PlayerEvent { diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index a9634170b7..b3c0ef7707 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -494,3 +494,6 @@ public net.minecraft.world.item.enchantment.Enchantment locationContext(Lnet/min public net.minecraft.world.item.enchantment.Enchantment entityContext(Lnet/minecraft/server/level/ServerLevel;ILnet/minecraft/world/entity/Entity;Lnet/minecraft/world/phys/Vec3;)Lnet/minecraft/world/level/storage/loot/LootContext; public net.minecraft.world.item.enchantment.Enchantment blockHitContext(Lnet/minecraft/server/level/ServerLevel;ILnet/minecraft/world/entity/Entity;Lnet/minecraft/world/phys/Vec3;Lnet/minecraft/world/level/block/state/BlockState;)Lnet/minecraft/world/level/storage/loot/LootContext; public net.minecraft.world.item.enchantment.Enchantment applyEffects(Ljava/util/List;Lnet/minecraft/world/level/storage/loot/LootContext;Ljava/util/function/Consumer;)V +# Made public for mc logo render in mods list +public net.minecraft.client.gui.components.LogoRenderer LOGO_TEXTURE_WIDTH +public net.minecraft.client.gui.components.LogoRenderer LOGO_TEXTURE_HEIGHT \ No newline at end of file diff --git a/tests/src/generated/resources/data/neotests_reloadable_reg_data_maps/data_maps/loot_table/effect_grant.json b/tests/src/generated/resources/data/neotests_reloadable_reg_data_maps/data_maps/loot_table/effect_grant.json new file mode 100644 index 0000000000..ff7693fcb2 --- /dev/null +++ b/tests/src/generated/resources/data/neotests_reloadable_reg_data_maps/data_maps/loot_table/effect_grant.json @@ -0,0 +1,9 @@ +{ + "values": { + "minecraft:blocks/copper_block": { + "duration": 100, + "id": "minecraft:nausea", + "show_icon": true + } + } +} \ No newline at end of file diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/client/ClientEventTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/client/ClientEventTests.java index 6b724e66b9..aebcf64746 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/client/ClientEventTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/client/ClientEventTests.java @@ -9,8 +9,13 @@ import java.util.Map; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.core.SectionPos; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.network.chat.Component; +import net.minecraft.world.item.ItemDisplayContext; +import net.minecraft.world.item.Items; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.levelgen.SingleThreadedRandomSource; import net.neoforged.api.distmarker.Dist; @@ -19,6 +24,7 @@ import net.neoforged.neoforge.client.event.ClientPlayerChangeGameTypeEvent; import net.neoforged.neoforge.client.event.RegisterRenderBuffersEvent; import net.neoforged.neoforge.client.event.RenderLevelStageEvent; +import net.neoforged.neoforge.client.event.RenderPlayerEvent; import net.neoforged.neoforge.client.model.data.ModelData; import net.neoforged.neoforge.common.NeoForge; import net.neoforged.testframework.DynamicTest; @@ -103,4 +109,21 @@ static void addSectionGeometryTest(final ClientChatEvent chatEvent, final Dynami test.requestConfirmation(player, Component.literal("Is a diamond block rendered above you?")); } } + + @TestHolder(description = { "Tests that RenderPlayerEvent is fired correctly and functions as expected" }) + static void renderPlayerEvent(final DynamicTest test) { + test.whenEnabled(listeners -> { + var item = Items.IRON_BLOCK; + var itemStack = item.getDefaultInstance(); + var modelId = ModelResourceLocation.inventory(BuiltInRegistries.ITEM.getKey(item)); + listeners.forge().addListener((final RenderPlayerEvent.Post event) -> { + event.getPoseStack().pushPose(); + event.getPoseStack().translate(0, 2, 0); + var model = Minecraft.getInstance().getModelManager().getModel(modelId); + Minecraft.getInstance().getItemRenderer().render(itemStack, ItemDisplayContext.GROUND, false, event.getPoseStack(), event.getMultiBufferSource(), event.getPackedLight(), OverlayTexture.NO_OVERLAY, model); + event.getPoseStack().popPose(); + }); + test.requestConfirmation(Minecraft.getInstance().player, Component.literal("Is an iron block rendered above you in third-person?")); + }); + } } diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/crafting/CraftingEventTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/crafting/CraftingEventTests.java new file mode 100644 index 0000000000..d33eb4eb72 --- /dev/null +++ b/tests/src/main/java/net/neoforged/neoforge/debug/crafting/CraftingEventTests.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.debug.crafting; + +import com.mojang.blaze3d.platform.InputConstants; +import java.util.concurrent.atomic.AtomicInteger; +import net.minecraft.core.BlockPos; +import net.minecraft.gametest.framework.GameTest; +import net.minecraft.world.inventory.ClickType; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.GameType; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.entity.FurnaceBlockEntity; +import net.neoforged.neoforge.event.entity.player.PlayerEvent; +import net.neoforged.testframework.DynamicTest; +import net.neoforged.testframework.annotation.ForEachTest; +import net.neoforged.testframework.annotation.TestHolder; +import net.neoforged.testframework.gametest.EmptyTemplate; + +@ForEachTest(groups = "crafting.event") +public class CraftingEventTests { + @GameTest + @EmptyTemplate + @TestHolder(description = "Tests that ItemSmeltedEvent is fired correctly") + static void itemSmeltedEventTest(final DynamicTest test) { + AtomicInteger timesFired = new AtomicInteger(0); + test.whenEnabled(listeners -> { + listeners.forge().addListener((final PlayerEvent.ItemSmeltedEvent event) -> { + timesFired.incrementAndGet(); + var removed = event.getAmountRemoved(); + if (removed != 32) { + test.fail("Test should be removing half of a stack, yet extracted a different amount"); + } + }); + }); + test.onGameTest(helper -> { + helper.setBlock(BlockPos.ZERO, Blocks.FURNACE); + var be = helper.getBlockEntity(BlockPos.ZERO, FurnaceBlockEntity.class); + helper.assertFalse(be == null, "FurnaceBlockEntity was not found for furnace position"); + // Slot 2 is the result slot + be.setItem(2, new ItemStack(Items.IRON_INGOT, 64)); + var player = helper.makeTickingMockServerPlayerInLevel(GameType.CREATIVE); + player.openMenu(be); + // Test that right-clicking half of the stack out of the FurnaceResultSlot functions as expected + player.containerMenu.clicked(2, InputConstants.MOUSE_BUTTON_RIGHT, ClickType.PICKUP, player); + helper.assertTrue(timesFired.getPlain() == 1, "Event was not fired the expected number of times for right-click pickup. Fired: " + timesFired.getPlain()); + player.containerMenu.setCarried(ItemStack.EMPTY); + // Test that shift-left-clicking the rest of the stack out works (should only fire once, not twice) + player.containerMenu.clicked(2, InputConstants.MOUSE_BUTTON_LEFT, ClickType.QUICK_MOVE, player); + helper.assertTrue(timesFired.getPlain() == 2, "Event was not fired the expected number of times for shift-left-click quick-move. Fired: " + timesFired.getPlain()); + // The slot is now empty, this should not fire the event + player.containerMenu.clicked(2, InputConstants.MOUSE_BUTTON_LEFT, ClickType.QUICK_MOVE, player); + helper.assertTrue(timesFired.getPlain() == 2, "Event fired for an empty slot, which should not happen."); + helper.succeed(); + }); + } +} diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/data/DataMapTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/data/DataMapTests.java index 2e4bf42bd9..4506dfaa09 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/data/DataMapTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/data/DataMapTests.java @@ -33,6 +33,8 @@ import net.minecraft.world.InteractionHand; import net.minecraft.world.damagesource.DamageType; import net.minecraft.world.damagesource.DamageTypes; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.effect.MobEffects; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.HoneycombItem; import net.minecraft.world.item.Item; @@ -43,12 +45,14 @@ import net.minecraft.world.level.block.WeatheringCopper; import net.minecraft.world.level.block.WeatheringCopperFullBlock; import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.storage.loot.LootTable; import net.neoforged.neoforge.common.DataMapHooks; import net.neoforged.neoforge.common.NeoForge; import net.neoforged.neoforge.common.data.DataMapProvider; import net.neoforged.neoforge.debug.EventTests; import net.neoforged.neoforge.event.entity.living.LivingDamageEvent; import net.neoforged.neoforge.event.entity.player.UseItemOnBlockEvent; +import net.neoforged.neoforge.event.level.BlockEvent; import net.neoforged.neoforge.registries.datamaps.AdvancedDataMapType; import net.neoforged.neoforge.registries.datamaps.DataMapType; import net.neoforged.neoforge.registries.datamaps.DataMapValueMerger; @@ -302,6 +306,40 @@ protected void gather(HolderLookup.Provider provider) { }); } + @GameTest + @EmptyTemplate + @TestHolder(description = "Tests if data maps can be successfully attached to reloadable registries") + static void reloadableRegDataMaps(final DynamicTest test, final RegistrationHelper reg) { + final DataMapType effectGrant = reg.registerDataMap(DataMapType.builder( + ResourceLocation.fromNamespaceAndPath(reg.modId(), "effect_grant"), + Registries.LOOT_TABLE, MobEffectInstance.CODEC) + .build()); + + reg.addProvider(event -> new DataMapProvider(event.getGenerator().getPackOutput(), event.getLookupProvider()) { + @Override + protected void gather(HolderLookup.Provider provider) { + builder(effectGrant) + .add(Blocks.COPPER_BLOCK.getLootTable().orElseThrow(), new MobEffectInstance(MobEffects.CONFUSION, 100), false); + } + }); + + test.eventListeners().forge().addListener((final BlockEvent.EntityPlaceEvent event) -> { + var table = event.getPlacedBlock().getBlock().getLootTable(); + if (table.isEmpty()) return; + final var grant = event.getLevel().getServer().reloadableRegistries().lookup().lookupOrThrow(Registries.LOOT_TABLE).getOrThrow(table.get()).getData(effectGrant); + if (grant != null && event.getEntity() instanceof Player player) { + player.addEffect(grant); + } + }); + + test.onGameTest(helper -> { + final Player player = helper.makeMockPlayer(); + helper.useBlock(new BlockPos(0, 1, 0), player, Blocks.COPPER_BLOCK.asItem().getDefaultInstance()); + helper.assertMobEffectPresent(player, MobEffects.CONFUSION, "has confusion"); + helper.succeed(); + }); + } + @GameTest @EmptyTemplate @TestHolder(description = "Tests if custom compostables work") diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/item/ItemTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/item/ItemTests.java index 25954a3f0d..36b4caf085 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/item/ItemTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/item/ItemTests.java @@ -37,6 +37,7 @@ import net.minecraft.world.item.MobBucketItem; import net.minecraft.world.item.PickaxeItem; import net.minecraft.world.item.Rarity; +import net.minecraft.world.item.SpawnEggItem; import net.minecraft.world.item.ToolMaterial; import net.minecraft.world.item.context.UseOnContext; import net.minecraft.world.item.equipment.ArmorMaterials; @@ -48,7 +49,6 @@ import net.minecraft.world.level.material.Fluids; import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; import net.neoforged.neoforge.client.model.generators.ModelFile; -import net.neoforged.neoforge.common.DeferredSpawnEggItem; import net.neoforged.testframework.DynamicTest; import net.neoforged.testframework.annotation.ForEachTest; import net.neoforged.testframework.annotation.TestHolder; @@ -117,7 +117,7 @@ static void forgeSpawnEggTest(final DynamicTest test, final RegistrationHelper r .withRenderer(() -> PigRenderer::new) .withLang("Test Pig spawn egg"); - final var egg = reg.items().registerItem("test_spawn_egg", props -> new DeferredSpawnEggItem(testEntity, 0x0000FF, 0xFF0000, props) { + final var egg = reg.items().registerItem("test_spawn_egg", props -> new SpawnEggItem(testEntity.get(), 0x0000FF, 0xFF0000, props) { @Override public InteractionResult useOn(UseOnContext ctx) { final var result = super.useOn(ctx); diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/client/rendering/LinearTextTextureFilteringTest.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/client/rendering/LinearTextTextureFilteringTest.java index 5cf62659e2..e8da3992f0 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/client/rendering/LinearTextTextureFilteringTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/client/rendering/LinearTextTextureFilteringTest.java @@ -5,12 +5,12 @@ package net.neoforged.neoforge.oldtest.client.rendering; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.TitleScreen; import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.common.Mod; -import net.neoforged.neoforge.client.NeoForgeRenderTypes; import net.neoforged.neoforge.client.event.ScreenEvent.Render; @Mod(LinearTextTextureFilteringTest.MODID) @@ -22,14 +22,14 @@ public class LinearTextTextureFilteringTest { @SubscribeEvent public static void onGuiRenderPre(Render.Pre event) { if (ENABLED && event.getScreen() instanceof TitleScreen) { - NeoForgeRenderTypes.enableTextTextureLinearFiltering = true; + Minecraft.getInstance().font.enableTextTextureLinearFiltering = true; } } @SubscribeEvent public static void onGuiRenderPost(Render.Post event) { if (ENABLED && event.getScreen() instanceof TitleScreen) { - NeoForgeRenderTypes.enableTextTextureLinearFiltering = false; + Minecraft.getInstance().font.enableTextTextureLinearFiltering = false; } } }