From 4a273ae8e5e3bbdb5addce0364f361c68ddc1990 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Sat, 16 Jul 2022 19:08:11 +0100 Subject: [PATCH] Update to latest Forge - Lots of refactoring/cleanup to Forge's events and client APIs. - Render types/layers for blocks are now set on the model rather than in code. - Models now can work with multiple render types. As this would massively complicate the implementation of the turtle item model, we now implement a much simpler version, which makes use of Forge's BakedModel.getRenderPasses to return a separate model for the core turtle and each upgrade. - Send monitor contents to players immediately when they start watching the chunk. ChunkWatchEvent.Watch is now fired from a more sensible location, so this is much easier to implement! --- build.gradle | 10 +- gradle.properties | 4 +- .../api/pocket/PocketUpgradeDataProvider.java | 2 +- .../api/pocket/PocketUpgradeSerialiser.java | 1 + .../api/turtle/ITurtleUpgrade.java | 2 +- .../api/turtle/TurtleUpgradeDataProvider.java | 7 +- .../api/turtle/TurtleUpgradeSerialiser.java | 2 + .../api/upgrades/IUpgradeBase.java | 2 +- .../computercraft/client/ClientHooks.java | 10 +- .../computercraft/client/ClientRegistry.java | 35 ++-- .../client/render/CableHighlightRenderer.java | 4 +- .../client/render/DebugOverlay.java | 4 +- .../render/MonitorHighlightRenderer.java | 4 +- .../render/TileEntityTurtleRenderer.java | 14 +- .../client/render/TransformedBakedModel.java | 60 +++++++ .../client/render/TurtleModelLoader.java | 22 +-- .../client/render/TurtleMultiModel.java | 153 ------------------ .../client/render/TurtleSmartItemModel.java | 152 ++++++----------- .../dan200/computercraft/data/Generators.java | 2 +- .../mixin/BlockRenderDispatcherMixin.java | 10 +- .../computercraft/shared/CommonHooks.java | 2 +- .../dan200/computercraft/shared/Config.java | 4 - .../dan200/computercraft/shared/Registry.java | 11 +- .../shared/network/NetworkHandler.java | 2 +- .../network/container/ContainerData.java | 2 +- .../peripheral/diskdrive/TileDiskDrive.java | 2 +- .../peripheral/generic/GenericPeripheral.java | 2 +- .../peripheral/monitor/MonitorWatcher.java | 52 ++---- .../peripheral/printer/TilePrinter.java | 2 +- .../shared/turtle/FurnaceRefuelHandler.java | 2 +- .../shared/turtle/upgrades/TurtleTool.java | 2 +- .../shared/util/DropConsumer.java | 6 +- src/main/resources/META-INF/mods.toml | 2 +- .../models/block/monitor_base.json | 1 + .../models/block/turtle_base.json | 1 + .../ingame/api/TestExtensions.kt | 2 +- .../computercraft/ingame/mod/ClientHooks.java | 2 +- 37 files changed, 204 insertions(+), 393 deletions(-) create mode 100644 src/main/java/dan200/computercraft/client/render/TransformedBakedModel.java delete mode 100644 src/main/java/dan200/computercraft/client/render/TurtleMultiModel.java diff --git a/build.gradle b/build.gradle index de7b6fd40..bdc5d6603 100644 --- a/build.gradle +++ b/build.gradle @@ -109,8 +109,8 @@ minecraft { } } - // mappings channel: 'parchment', version: "${mapping_version}-${mc_version}" - mappings channel: 'official', version: mc_version + mappings channel: 'parchment', version: "${mapping_version}-${mc_version}" + // mappings channel: 'official', version: mc_version accessTransformer file('src/main/resources/META-INF/accesstransformer.cfg') accessTransformer file('src/testMod/resources/META-INF/accesstransformer.cfg') @@ -149,9 +149,9 @@ dependencies { minecraft "net.minecraftforge:forge:${mc_version}-${forge_version}" annotationProcessor 'org.spongepowered:mixin:0.8.4:processor' - extraModsCompileOnly fg.deobf("mezz.jei:jei-1.19-forge-api:11.0.0.206") - extraModsCompileOnly fg.deobf("mezz.jei:jei-1.19-common-api:11.0.0.206") - extraModsRuntimeOnly fg.deobf("mezz.jei:jei-1.19-forge:11.0.0.206") + extraModsCompileOnly fg.deobf("mezz.jei:jei-1.19-forge-api:11.0.0.211") + extraModsCompileOnly fg.deobf("mezz.jei:jei-1.19-common-api:11.0.0.211") + extraModsRuntimeOnly fg.deobf("mezz.jei:jei-1.19-forge:11.0.0.211") shade 'org.squiddev:Cobalt:0.5.5' shade 'io.netty:netty-codec-http:4.1.76.Final' diff --git a/gradle.properties b/gradle.properties index da8550e54..fcd89bcf4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,6 +6,6 @@ mod_version=1.100.8 # Minecraft properties (update mods.toml when changing) mc_version=1.19 -mapping_version=2022.03.13 -forge_version=41.0.38 +mapping_version=1.18.2-2022.07.03 +forge_version=41.0.98 # NO SERIOUSLY, UPDATE mods.toml WHEN CHANGING diff --git a/src/main/java/dan200/computercraft/api/pocket/PocketUpgradeDataProvider.java b/src/main/java/dan200/computercraft/api/pocket/PocketUpgradeDataProvider.java index d76a1ce6a..8dc679c41 100644 --- a/src/main/java/dan200/computercraft/api/pocket/PocketUpgradeDataProvider.java +++ b/src/main/java/dan200/computercraft/api/pocket/PocketUpgradeDataProvider.java @@ -7,7 +7,7 @@ package dan200.computercraft.api.pocket; import dan200.computercraft.api.upgrades.UpgradeDataProvider; import net.minecraft.data.DataGenerator; -import net.minecraftforge.forge.event.lifecycle.GatherDataEvent; +import net.minecraftforge.data.event.GatherDataEvent; import javax.annotation.Nonnull; import java.util.function.Consumer; diff --git a/src/main/java/dan200/computercraft/api/pocket/PocketUpgradeSerialiser.java b/src/main/java/dan200/computercraft/api/pocket/PocketUpgradeSerialiser.java index 25a4ff297..b4c0f0b1d 100644 --- a/src/main/java/dan200/computercraft/api/pocket/PocketUpgradeSerialiser.java +++ b/src/main/java/dan200/computercraft/api/pocket/PocketUpgradeSerialiser.java @@ -47,6 +47,7 @@ public interface PocketUpgradeSerialiser extends Upgra /** * The associated registry. + * * @return The registry for pocket upgrade serialisers. * @see #REGISTRY_ID */ diff --git a/src/main/java/dan200/computercraft/api/turtle/ITurtleUpgrade.java b/src/main/java/dan200/computercraft/api/turtle/ITurtleUpgrade.java index 5cd5a35f9..d8873cb89 100644 --- a/src/main/java/dan200/computercraft/api/turtle/ITurtleUpgrade.java +++ b/src/main/java/dan200/computercraft/api/turtle/ITurtleUpgrade.java @@ -14,7 +14,7 @@ import net.minecraft.world.item.ItemStack; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.event.entity.player.AttackEntityEvent; -import net.minecraftforge.event.world.BlockEvent; +import net.minecraftforge.event.level.BlockEvent; import javax.annotation.Nonnull; import javax.annotation.Nullable; diff --git a/src/main/java/dan200/computercraft/api/turtle/TurtleUpgradeDataProvider.java b/src/main/java/dan200/computercraft/api/turtle/TurtleUpgradeDataProvider.java index 777ccf4e4..4e1f031fb 100644 --- a/src/main/java/dan200/computercraft/api/turtle/TurtleUpgradeDataProvider.java +++ b/src/main/java/dan200/computercraft/api/turtle/TurtleUpgradeDataProvider.java @@ -14,7 +14,7 @@ import net.minecraft.tags.TagKey; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.item.Item; import net.minecraft.world.level.block.Block; -import net.minecraftforge.forge.event.lifecycle.GatherDataEvent; +import net.minecraftforge.data.event.GatherDataEvent; import net.minecraftforge.registries.ForgeRegistries; import javax.annotation.Nonnull; @@ -140,7 +140,10 @@ public abstract class TurtleUpgradeDataProvider extends UpgradeDataProvider( id, serialiser, s -> { s.addProperty( "item", ForgeRegistries.ITEMS.getKey( toolItem ).toString() ); if( adjective != null ) s.addProperty( "adjective", adjective ); - if( craftingItem != null ) s.addProperty( "craftItem", ForgeRegistries.ITEMS.getKey( craftingItem ).toString() ); + if( craftingItem != null ) + { + s.addProperty( "craftItem", ForgeRegistries.ITEMS.getKey( craftingItem ).toString() ); + } if( damageMultiplier != null ) s.addProperty( "damageMultiplier", damageMultiplier ); if( breakable != null ) s.addProperty( "breakable", breakable.location().toString() ); } ) ); diff --git a/src/main/java/dan200/computercraft/api/turtle/TurtleUpgradeSerialiser.java b/src/main/java/dan200/computercraft/api/turtle/TurtleUpgradeSerialiser.java index 1c2564b4e..181bcffcf 100644 --- a/src/main/java/dan200/computercraft/api/turtle/TurtleUpgradeSerialiser.java +++ b/src/main/java/dan200/computercraft/api/turtle/TurtleUpgradeSerialiser.java @@ -67,12 +67,14 @@ public interface TurtleUpgradeSerialiser extends Upgra * * This is largely intended for use with Forge Registry methods/classes, such as {@link DeferredRegister} and * {@link RegistryManager#getRegistry(ResourceKey)}. + * * @see #registry() */ ResourceKey>> REGISTRY_ID = ResourceKey.createRegistryKey( new ResourceLocation( ComputerCraft.MOD_ID, "turtle_upgrade_serialiser" ) ); /** * The associated registry. + * * @return The registry for pocket upgrade serialisers. * @see #REGISTRY_ID */ diff --git a/src/main/java/dan200/computercraft/api/upgrades/IUpgradeBase.java b/src/main/java/dan200/computercraft/api/upgrades/IUpgradeBase.java index 0932d9a15..ddcd6036c 100644 --- a/src/main/java/dan200/computercraft/api/upgrades/IUpgradeBase.java +++ b/src/main/java/dan200/computercraft/api/upgrades/IUpgradeBase.java @@ -68,7 +68,7 @@ public interface IUpgradeBase * @param stack The stack to check. This is guaranteed to be non-empty and have the same item as * {@link #getCraftingItem()}. * @return If this stack may be used to equip this upgrade. - * @see net.minecraftforge.common.crafting.NBTIngredient#test(ItemStack) For the implementation of the default + * @see net.minecraftforge.common.crafting.StrictNBTIngredient#test(ItemStack) For the implementation of the default * check. */ default boolean isItemSuitable( @Nonnull ItemStack stack ) diff --git a/src/main/java/dan200/computercraft/client/ClientHooks.java b/src/main/java/dan200/computercraft/client/ClientHooks.java index 9d86cfda3..657784d59 100644 --- a/src/main/java/dan200/computercraft/client/ClientHooks.java +++ b/src/main/java/dan200/computercraft/client/ClientHooks.java @@ -10,7 +10,7 @@ import dan200.computercraft.client.sound.SpeakerManager; import dan200.computercraft.shared.peripheral.monitor.ClientMonitor; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.client.event.ClientPlayerNetworkEvent; -import net.minecraftforge.event.world.WorldEvent; +import net.minecraftforge.event.level.LevelEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; @@ -18,9 +18,9 @@ import net.minecraftforge.fml.common.Mod; public class ClientHooks { @SubscribeEvent - public static void onWorldUnload( WorldEvent.Unload event ) + public static void onWorldUnload( LevelEvent.Unload event ) { - if( event.getWorld().isClientSide() ) + if( event.getLevel().isClientSide() ) { ClientMonitor.destroyAll(); SpeakerManager.reset(); @@ -28,13 +28,13 @@ public class ClientHooks } @SubscribeEvent - public static void onLogIn( ClientPlayerNetworkEvent.LoggedInEvent event ) + public static void onLogIn( ClientPlayerNetworkEvent.LoggingIn event ) { ComputerCraft.clientComputerRegistry.reset(); } @SubscribeEvent - public static void onLogOut( ClientPlayerNetworkEvent.LoggedOutEvent event ) + public static void onLogOut( ClientPlayerNetworkEvent.LoggingOut event ) { ComputerCraft.clientComputerRegistry.reset(); } diff --git a/src/main/java/dan200/computercraft/client/ClientRegistry.java b/src/main/java/dan200/computercraft/client/ClientRegistry.java index 2f2ecd25c..7cfc6596b 100644 --- a/src/main/java/dan200/computercraft/client/ClientRegistry.java +++ b/src/main/java/dan200/computercraft/client/ClientRegistry.java @@ -19,8 +19,6 @@ import dan200.computercraft.shared.media.items.ItemTreasureDisk; import dan200.computercraft.shared.pocket.items.ItemPocketComputer; import dan200.computercraft.shared.util.Colour; import net.minecraft.client.gui.screens.MenuScreens; -import net.minecraft.client.renderer.ItemBlockRenderTypes; -import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.blockentity.BlockEntityRenderers; import net.minecraft.client.renderer.item.ItemProperties; import net.minecraft.client.renderer.item.ItemPropertyFunction; @@ -28,10 +26,8 @@ import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.Item; import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.client.event.ColorHandlerEvent; -import net.minecraftforge.client.event.ModelRegistryEvent; -import net.minecraftforge.client.model.ForgeModelBakery; -import net.minecraftforge.client.model.ModelLoaderRegistry; +import net.minecraftforge.client.event.ModelEvent; +import net.minecraftforge.client.event.RegisterColorHandlersEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; @@ -69,17 +65,22 @@ public final class ClientRegistry private ClientRegistry() {} @SubscribeEvent - public static void registerModels( ModelRegistryEvent event ) + public static void registerModelLoaders( ModelEvent.RegisterGeometryLoaders event ) + { + event.register( "turtle", TurtleModelLoader.INSTANCE ); + } + + @SubscribeEvent + public static void registerModels( ModelEvent.RegisterAdditional event ) { - ModelLoaderRegistry.registerLoader( new ResourceLocation( ComputerCraft.MOD_ID, "turtle" ), TurtleModelLoader.INSTANCE ); for( String model : EXTRA_MODELS ) { - ForgeModelBakery.addSpecialModel( new ModelResourceLocation( new ResourceLocation( ComputerCraft.MOD_ID, model ), "inventory" ) ); + event.register( new ModelResourceLocation( new ResourceLocation( ComputerCraft.MOD_ID, model ), "inventory" ) ); } } @SubscribeEvent - public static void onItemColours( ColorHandlerEvent.Item event ) + public static void onItemColours( RegisterColorHandlersEvent.Item event ) { if( Registry.ModItems.DISK == null || Registry.ModBlocks.TURTLE_NORMAL == null ) { @@ -87,17 +88,17 @@ public final class ClientRegistry return; } - event.getItemColors().register( + event.register( ( stack, layer ) -> layer == 1 ? ((ItemDisk) stack.getItem()).getColour( stack ) : 0xFFFFFF, Registry.ModItems.DISK.get() ); - event.getItemColors().register( + event.register( ( stack, layer ) -> layer == 1 ? ItemTreasureDisk.getColour( stack ) : 0xFFFFFF, Registry.ModItems.TREASURE_DISK.get() ); - event.getItemColors().register( ( stack, layer ) -> { + event.register( ( stack, layer ) -> { switch( layer ) { case 0: @@ -123,14 +124,6 @@ public final class ClientRegistry @SubscribeEvent public static void setupClient( FMLClientSetupEvent event ) { - // While turtles themselves are not transparent, their upgrades may be. - ItemBlockRenderTypes.setRenderLayer( Registry.ModBlocks.TURTLE_NORMAL.get(), RenderType.translucent() ); - ItemBlockRenderTypes.setRenderLayer( Registry.ModBlocks.TURTLE_ADVANCED.get(), RenderType.translucent() ); - - // Monitors' textures have transparent fronts and so count as cutouts. - ItemBlockRenderTypes.setRenderLayer( Registry.ModBlocks.MONITOR_NORMAL.get(), RenderType.cutout() ); - ItemBlockRenderTypes.setRenderLayer( Registry.ModBlocks.MONITOR_ADVANCED.get(), RenderType.cutout() ); - // Setup TESRs BlockEntityRenderers.register( Registry.ModBlockEntities.MONITOR_NORMAL.get(), TileEntityMonitorRenderer::new ); BlockEntityRenderers.register( Registry.ModBlockEntities.MONITOR_ADVANCED.get(), TileEntityMonitorRenderer::new ); diff --git a/src/main/java/dan200/computercraft/client/render/CableHighlightRenderer.java b/src/main/java/dan200/computercraft/client/render/CableHighlightRenderer.java index 35fa9fbb4..02cd17e9e 100644 --- a/src/main/java/dan200/computercraft/client/render/CableHighlightRenderer.java +++ b/src/main/java/dan200/computercraft/client/render/CableHighlightRenderer.java @@ -23,7 +23,7 @@ import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.shapes.VoxelShape; import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.client.event.DrawSelectionEvent; +import net.minecraftforge.client.event.RenderHighlightEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; @@ -41,7 +41,7 @@ public final class CableHighlightRenderer * @see net.minecraft.client.renderer.LevelRenderer#renderHitOutline */ @SubscribeEvent - public static void drawHighlight( DrawSelectionEvent.HighlightBlock event ) + public static void drawHighlight( RenderHighlightEvent.Block event ) { BlockHitResult hit = event.getTarget(); BlockPos pos = hit.getBlockPos(); diff --git a/src/main/java/dan200/computercraft/client/render/DebugOverlay.java b/src/main/java/dan200/computercraft/client/render/DebugOverlay.java index 808e9cea5..11a5ab7f0 100644 --- a/src/main/java/dan200/computercraft/client/render/DebugOverlay.java +++ b/src/main/java/dan200/computercraft/client/render/DebugOverlay.java @@ -15,7 +15,7 @@ import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.HitResult; import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.client.event.RenderGameOverlayEvent; +import net.minecraftforge.client.event.CustomizeGuiOverlayEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; @@ -25,7 +25,7 @@ import java.util.List; public class DebugOverlay { @SubscribeEvent - public static void onRenderText( RenderGameOverlayEvent.Text event ) + public static void onRenderText( CustomizeGuiOverlayEvent.DebugText event ) { Minecraft minecraft = Minecraft.getInstance(); if( !minecraft.options.renderDebug || minecraft.level == null ) return; diff --git a/src/main/java/dan200/computercraft/client/render/MonitorHighlightRenderer.java b/src/main/java/dan200/computercraft/client/render/MonitorHighlightRenderer.java index f364a851d..b3f68ff86 100644 --- a/src/main/java/dan200/computercraft/client/render/MonitorHighlightRenderer.java +++ b/src/main/java/dan200/computercraft/client/render/MonitorHighlightRenderer.java @@ -18,7 +18,7 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.phys.Vec3; import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.client.event.DrawSelectionEvent; +import net.minecraftforge.client.event.RenderHighlightEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; @@ -38,7 +38,7 @@ public final class MonitorHighlightRenderer } @SubscribeEvent - public static void drawHighlight( DrawSelectionEvent.HighlightBlock event ) + public static void drawHighlight( RenderHighlightEvent.Block event ) { // Preserve normal behaviour when crouching. if( event.getCamera().getEntity().isCrouching() ) return; diff --git a/src/main/java/dan200/computercraft/client/render/TileEntityTurtleRenderer.java b/src/main/java/dan200/computercraft/client/render/TileEntityTurtleRenderer.java index d7d82918f..b77735ef7 100644 --- a/src/main/java/dan200/computercraft/client/render/TileEntityTurtleRenderer.java +++ b/src/main/java/dan200/computercraft/client/render/TileEntityTurtleRenderer.java @@ -34,7 +34,7 @@ import net.minecraft.util.RandomSource; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; -import net.minecraftforge.client.model.data.EmptyModelData; +import net.minecraftforge.client.model.data.ModelData; import javax.annotation.Nonnull; import java.util.List; @@ -165,10 +165,10 @@ public class TileEntityTurtleRenderer implements BlockEntityRenderer private void renderModel( @Nonnull PoseStack transform, @Nonnull VertexConsumer renderer, int lightmapCoord, int overlayLight, BakedModel model, int[] tints ) { random.setSeed( 0 ); - renderQuads( transform, renderer, lightmapCoord, overlayLight, model.getQuads( null, null, random, EmptyModelData.INSTANCE ), tints ); + renderQuads( transform, renderer, lightmapCoord, overlayLight, model.getQuads( null, null, random, ModelData.EMPTY, null ), tints ); for( Direction facing : DirectionUtil.FACINGS ) { - renderQuads( transform, renderer, lightmapCoord, overlayLight, model.getQuads( null, facing, random, EmptyModelData.INSTANCE ), tints ); + renderQuads( transform, renderer, lightmapCoord, overlayLight, model.getQuads( null, facing, random, ModelData.EMPTY, null ), tints ); } } @@ -185,10 +185,10 @@ public class TileEntityTurtleRenderer implements BlockEntityRenderer if( idx >= 0 && idx < tints.length ) tint = tints[bakedquad.getTintIndex()]; } - float f = (float) (tint >> 16 & 255) / 255.0F; - float f1 = (float) (tint >> 8 & 255) / 255.0F; - float f2 = (float) (tint & 255) / 255.0F; - buffer.putBulkData( matrix, bakedquad, f, f1, f2, lightmapCoord, overlayLight, true ); + float r = (float) (tint >> 16 & 255) / 255.0F; + float g = (float) (tint >> 8 & 255) / 255.0F; + float b = (float) (tint & 255) / 255.0F; + buffer.putBulkData( matrix, bakedquad, r, g, b, lightmapCoord, overlayLight ); } } } diff --git a/src/main/java/dan200/computercraft/client/render/TransformedBakedModel.java b/src/main/java/dan200/computercraft/client/render/TransformedBakedModel.java new file mode 100644 index 000000000..b460fb461 --- /dev/null +++ b/src/main/java/dan200/computercraft/client/render/TransformedBakedModel.java @@ -0,0 +1,60 @@ +/* + * This file is part of ComputerCraft - http://www.computercraft.info + * Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission. + * Send enquiries to dratcliffe@gmail.com + */ +package dan200.computercraft.client.render; + +import com.mojang.math.Transformation; +import dan200.computercraft.api.client.TransformedModel; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraftforge.client.model.BakedModelWrapper; +import net.minecraftforge.client.model.IQuadTransformer; +import net.minecraftforge.client.model.data.ModelData; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.annotation.Nonnull; +import java.util.List; + +public class TransformedBakedModel extends BakedModelWrapper +{ + private final Transformation transformation; + private final boolean isIdentity; + + public TransformedBakedModel( BakedModel model, Transformation transformation ) + { + super( model ); + this.transformation = transformation; + isIdentity = transformation.isIdentity(); + } + + public TransformedBakedModel( TransformedModel model ) + { + this( model.getModel(), model.getMatrix() ); + } + + @Nonnull + @Override + public List getQuads( @Nullable BlockState state, @Nullable Direction side, @Nonnull RandomSource rand ) + { + return getQuads( state, side, rand, ModelData.EMPTY, null ); + } + + @Override + public @NotNull List getQuads( @Nullable BlockState state, @Nullable Direction side, @NotNull RandomSource rand, @NotNull ModelData extraData, @Nullable RenderType renderType ) + { + List quads = originalModel.getQuads( state, side, rand, extraData, renderType ); + return isIdentity ? quads : IQuadTransformer.applying( transformation ).process( quads ); + } + + public TransformedBakedModel composeWith( Transformation other ) + { + return new TransformedBakedModel( originalModel, other.compose( transformation ) ); + } +} diff --git a/src/main/java/dan200/computercraft/client/render/TurtleModelLoader.java b/src/main/java/dan200/computercraft/client/render/TurtleModelLoader.java index 11cab53d0..eca5957a8 100644 --- a/src/main/java/dan200/computercraft/client/render/TurtleModelLoader.java +++ b/src/main/java/dan200/computercraft/client/render/TurtleModelLoader.java @@ -13,11 +13,10 @@ import net.minecraft.client.renderer.block.model.ItemOverrides; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.model.*; import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.packs.resources.ResourceManager; import net.minecraft.util.GsonHelper; -import net.minecraftforge.client.model.IModelConfiguration; -import net.minecraftforge.client.model.IModelLoader; -import net.minecraftforge.client.model.geometry.IModelGeometry; +import net.minecraftforge.client.model.geometry.IGeometryBakingContext; +import net.minecraftforge.client.model.geometry.IGeometryLoader; +import net.minecraftforge.client.model.geometry.IUnbakedGeometry; import javax.annotation.Nonnull; import java.util.Collection; @@ -25,7 +24,7 @@ import java.util.HashSet; import java.util.Set; import java.util.function.Function; -public final class TurtleModelLoader implements IModelLoader +public final class TurtleModelLoader implements IGeometryLoader { private static final ResourceLocation COLOUR_TURTLE_MODEL = new ResourceLocation( ComputerCraft.MOD_ID, "block/turtle_colour" ); @@ -35,20 +34,15 @@ public final class TurtleModelLoader implements IModelLoader + public static final class TurtleModel implements IUnbakedGeometry { private final ResourceLocation family; @@ -58,7 +52,7 @@ public final class TurtleModelLoader implements IModelLoader getTextures( IModelConfiguration owner, Function modelGetter, Set> missingTextureErrors ) + public Collection getMaterials( IGeometryBakingContext context, Function modelGetter, Set> missingTextureErrors ) { Set materials = new HashSet<>(); materials.addAll( modelGetter.apply( family ).getMaterials( modelGetter, missingTextureErrors ) ); @@ -67,7 +61,7 @@ public final class TurtleModelLoader implements IModelLoader spriteGetter, ModelState transform, ItemOverrides overrides, ResourceLocation modelLocation ) + public BakedModel bake( IGeometryBakingContext owner, ModelBakery bakery, Function spriteGetter, ModelState transform, ItemOverrides overrides, ResourceLocation modelLocation ) { return new TurtleSmartItemModel( bakery.bake( family, transform, spriteGetter ), diff --git a/src/main/java/dan200/computercraft/client/render/TurtleMultiModel.java b/src/main/java/dan200/computercraft/client/render/TurtleMultiModel.java deleted file mode 100644 index 478fcdc51..000000000 --- a/src/main/java/dan200/computercraft/client/render/TurtleMultiModel.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * This file is part of ComputerCraft - http://www.computercraft.info - * Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission. - * Send enquiries to dratcliffe@gmail.com - */ -package dan200.computercraft.client.render; - -import com.mojang.math.Transformation; -import dan200.computercraft.api.client.TransformedModel; -import net.minecraft.client.renderer.block.model.BakedQuad; -import net.minecraft.client.renderer.block.model.ItemOverrides; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.core.Direction; -import net.minecraft.util.RandomSource; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraftforge.client.model.data.EmptyModelData; -import net.minecraftforge.client.model.data.IModelData; -import net.minecraftforge.client.model.pipeline.BakedQuadBuilder; -import net.minecraftforge.client.model.pipeline.TRSRTransformer; - -import javax.annotation.Nonnull; -import java.util.ArrayList; -import java.util.EnumMap; -import java.util.List; -import java.util.Map; - -public class TurtleMultiModel implements BakedModel -{ - private final BakedModel baseModel; - private final BakedModel overlayModel; - private final Transformation generalTransform; - private final TransformedModel leftUpgradeModel; - private final TransformedModel rightUpgradeModel; - private List generalQuads = null; - private final Map> faceQuads = new EnumMap<>( Direction.class ); - - public TurtleMultiModel( BakedModel baseModel, BakedModel overlayModel, Transformation generalTransform, TransformedModel leftUpgradeModel, TransformedModel rightUpgradeModel ) - { - // Get the models - this.baseModel = baseModel; - this.overlayModel = overlayModel; - this.leftUpgradeModel = leftUpgradeModel; - this.rightUpgradeModel = rightUpgradeModel; - this.generalTransform = generalTransform; - } - - @Nonnull - @Override - @Deprecated - public List getQuads( BlockState state, Direction side, @Nonnull RandomSource rand ) - { - return getQuads( state, side, rand, EmptyModelData.INSTANCE ); - } - - @Nonnull - @Override - public List getQuads( BlockState state, Direction side, @Nonnull RandomSource rand, @Nonnull IModelData data ) - { - if( side != null ) - { - if( !faceQuads.containsKey( side ) ) faceQuads.put( side, buildQuads( state, side, rand ) ); - return faceQuads.get( side ); - } - else - { - if( generalQuads == null ) generalQuads = buildQuads( state, side, rand ); - return generalQuads; - } - } - - private List buildQuads( BlockState state, Direction side, RandomSource rand ) - { - ArrayList quads = new ArrayList<>(); - - - transformQuadsTo( quads, baseModel.getQuads( state, side, rand, EmptyModelData.INSTANCE ), generalTransform ); - if( overlayModel != null ) - { - transformQuadsTo( quads, overlayModel.getQuads( state, side, rand, EmptyModelData.INSTANCE ), generalTransform ); - } - if( leftUpgradeModel != null ) - { - Transformation upgradeTransform = generalTransform.compose( leftUpgradeModel.getMatrix() ); - transformQuadsTo( quads, leftUpgradeModel.getModel().getQuads( state, side, rand, EmptyModelData.INSTANCE ), upgradeTransform ); - } - if( rightUpgradeModel != null ) - { - Transformation upgradeTransform = generalTransform.compose( rightUpgradeModel.getMatrix() ); - transformQuadsTo( quads, rightUpgradeModel.getModel().getQuads( state, side, rand, EmptyModelData.INSTANCE ), upgradeTransform ); - } - quads.trimToSize(); - return quads; - } - - @Override - public boolean useAmbientOcclusion() - { - return baseModel.useAmbientOcclusion(); - } - - @Override - public boolean isGui3d() - { - return baseModel.isGui3d(); - } - - @Override - public boolean isCustomRenderer() - { - return baseModel.isCustomRenderer(); - } - - @Override - public boolean usesBlockLight() - { - return baseModel.usesBlockLight(); - } - - @Nonnull - @Override - @Deprecated - public TextureAtlasSprite getParticleIcon() - { - return baseModel.getParticleIcon(); - } - - @Nonnull - @Override - @Deprecated - public net.minecraft.client.renderer.block.model.ItemTransforms getTransforms() - { - return baseModel.getTransforms(); - } - - @Nonnull - @Override - public ItemOverrides getOverrides() - { - return ItemOverrides.EMPTY; - } - - private void transformQuadsTo( List output, List quads, Transformation transform ) - { - for( BakedQuad quad : quads ) - { - BakedQuadBuilder builder = new BakedQuadBuilder(); - TRSRTransformer transformer = new TRSRTransformer( builder, transform ); - quad.pipe( transformer ); - output.add( builder.build() ); - } - } -} diff --git a/src/main/java/dan200/computercraft/client/render/TurtleSmartItemModel.java b/src/main/java/dan200/computercraft/client/render/TurtleSmartItemModel.java index 719629d30..c7a8746fd 100644 --- a/src/main/java/dan200/computercraft/client/render/TurtleSmartItemModel.java +++ b/src/main/java/dan200/computercraft/client/render/TurtleSmartItemModel.java @@ -7,35 +7,27 @@ package dan200.computercraft.client.render; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Transformation; -import dan200.computercraft.api.client.TransformedModel; import dan200.computercraft.api.turtle.ITurtleUpgrade; import dan200.computercraft.api.turtle.TurtleSide; import dan200.computercraft.shared.turtle.items.ItemTurtle; import dan200.computercraft.shared.util.Holiday; import dan200.computercraft.shared.util.HolidayUtil; import net.minecraft.client.Minecraft; -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.renderer.block.model.BakedQuad; -import net.minecraft.client.renderer.block.model.ItemOverrides; import net.minecraft.client.renderer.block.model.ItemTransforms; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.model.BakedModel; import net.minecraft.client.resources.model.ModelManager; import net.minecraft.client.resources.model.ModelResourceLocation; -import net.minecraft.core.Direction; import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.RandomSource; -import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraftforge.client.model.data.IModelData; +import net.minecraftforge.client.model.BakedModelWrapper; import javax.annotation.Nonnull; -import javax.annotation.Nullable; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Map; -public class TurtleSmartItemModel implements BakedModel +public class TurtleSmartItemModel extends BakedModelWrapper { private static final Transformation identity, flip; @@ -49,7 +41,7 @@ public class TurtleSmartItemModel implements BakedModel flip = new Transformation( stack.last().pose() ); } - private static record TurtleModelCombination( + private record TurtleModelCombination( boolean colour, ITurtleUpgrade leftUpgrade, ITurtleUpgrade rightUpgrade, @@ -63,112 +55,64 @@ public class TurtleSmartItemModel implements BakedModel private final BakedModel familyModel; private final BakedModel colourModel; - private final HashMap cachedModels = new HashMap<>(); - private final ItemOverrides overrides; + private final Map> cachedModels = new HashMap<>(); public TurtleSmartItemModel( BakedModel familyModel, BakedModel colourModel ) { + super( familyModel ); this.familyModel = familyModel; this.colourModel = colourModel; - - overrides = new ItemOverrides() - { - @Nonnull - @Override - public BakedModel resolve( @Nonnull BakedModel originalModel, @Nonnull ItemStack stack, @Nullable ClientLevel world, @Nullable LivingEntity entity, int random ) - { - ItemTurtle turtle = (ItemTurtle) stack.getItem(); - int colour = turtle.getColour( stack ); - ITurtleUpgrade leftUpgrade = turtle.getUpgrade( stack, TurtleSide.LEFT ); - ITurtleUpgrade rightUpgrade = turtle.getUpgrade( stack, TurtleSide.RIGHT ); - ResourceLocation overlay = turtle.getOverlay( stack ); - boolean christmas = HolidayUtil.getCurrentHoliday() == Holiday.CHRISTMAS; - String label = turtle.getLabel( stack ); - boolean flip = label != null && (label.equals( "Dinnerbone" ) || label.equals( "Grumm" )); - TurtleModelCombination combo = new TurtleModelCombination( colour != -1, leftUpgrade, rightUpgrade, overlay, christmas, flip ); - - BakedModel model = cachedModels.get( combo ); - if( model == null ) cachedModels.put( combo, model = buildModel( combo ) ); - return model; - } - }; } @Nonnull @Override - public ItemOverrides getOverrides() + public BakedModel applyTransform( @Nonnull ItemTransforms.TransformType cameraTransformType, @Nonnull PoseStack poseStack, boolean applyLeftHandTransform ) { - return overrides; + originalModel.applyTransform( cameraTransformType, poseStack, applyLeftHandTransform ); + return this; } - private BakedModel buildModel( TurtleModelCombination combo ) + @Nonnull + @Override + public List getRenderPasses( ItemStack stack, boolean fabulous ) + { + ItemTurtle turtle = (ItemTurtle) stack.getItem(); + + int colour = turtle.getColour( stack ); + ITurtleUpgrade leftUpgrade = turtle.getUpgrade( stack, TurtleSide.LEFT ); + ITurtleUpgrade rightUpgrade = turtle.getUpgrade( stack, TurtleSide.RIGHT ); + ResourceLocation overlay = turtle.getOverlay( stack ); + boolean christmas = HolidayUtil.getCurrentHoliday() == Holiday.CHRISTMAS; + String label = turtle.getLabel( stack ); + boolean flip = label != null && (label.equals( "Dinnerbone" ) || label.equals( "Grumm" )); + + TurtleModelCombination combo = new TurtleModelCombination( colour != -1, leftUpgrade, rightUpgrade, overlay, christmas, flip ); + return cachedModels.computeIfAbsent( combo, this::buildModel ); + } + + private List buildModel( TurtleModelCombination combo ) { Minecraft mc = Minecraft.getInstance(); ModelManager modelManager = mc.getItemRenderer().getItemModelShaper().getModelManager(); - ModelResourceLocation overlayModelLocation = TileEntityTurtleRenderer.getTurtleOverlayModel( combo.overlay, combo.christmas ); - BakedModel baseModel = combo.colour ? colourModel : familyModel; - BakedModel overlayModel = overlayModelLocation != null ? modelManager.getModel( overlayModelLocation ) : null; - Transformation transform = combo.flip ? flip : identity; - TransformedModel leftModel = combo.leftUpgrade != null ? combo.leftUpgrade.getModel( null, TurtleSide.LEFT ) : null; - TransformedModel rightModel = combo.rightUpgrade != null ? combo.rightUpgrade.getModel( null, TurtleSide.RIGHT ) : null; - return new TurtleMultiModel( baseModel, overlayModel, transform, leftModel, rightModel ); + var transformation = combo.flip ? flip : identity; + ArrayList parts = new ArrayList<>( 4 ); + parts.add( new TransformedBakedModel( combo.colour() ? colourModel : familyModel, transformation ) ); + + ModelResourceLocation overlayModelLocation = TileEntityTurtleRenderer.getTurtleOverlayModel( combo.overlay(), combo.christmas() ); + if( overlayModelLocation != null ) + { + parts.add( new TransformedBakedModel( modelManager.getModel( overlayModelLocation ), transformation ) ); + } + if( combo.leftUpgrade() != null ) + { + parts.add( new TransformedBakedModel( combo.leftUpgrade().getModel( null, TurtleSide.LEFT ) ).composeWith( transformation ) ); + } + if( combo.rightUpgrade() != null ) + { + parts.add( new TransformedBakedModel( combo.rightUpgrade().getModel( null, TurtleSide.RIGHT ) ).composeWith( transformation ) ); + } + + return parts; } - - @Nonnull - @Override - @Deprecated - public List getQuads( BlockState state, Direction facing, @Nonnull RandomSource rand ) - { - return familyModel.getQuads( state, facing, rand ); - } - - @Nonnull - @Override - @Deprecated - public List getQuads( BlockState state, Direction facing, @Nonnull RandomSource rand, @Nonnull IModelData data ) - { - return familyModel.getQuads( state, facing, rand, data ); - } - - @Override - public boolean useAmbientOcclusion() - { - return familyModel.useAmbientOcclusion(); - } - - @Override - public boolean isGui3d() - { - return familyModel.isGui3d(); - } - - @Override - public boolean isCustomRenderer() - { - return familyModel.isCustomRenderer(); - } - - @Override - public boolean usesBlockLight() - { - return familyModel.usesBlockLight(); - } - - @Nonnull - @Override - @Deprecated - public TextureAtlasSprite getParticleIcon() - { - return familyModel.getParticleIcon(); - } - - @Nonnull - @Override - @Deprecated - public ItemTransforms getTransforms() - { - return familyModel.getTransforms(); - } - } diff --git a/src/main/java/dan200/computercraft/data/Generators.java b/src/main/java/dan200/computercraft/data/Generators.java index b7827c89d..89f11f8e5 100644 --- a/src/main/java/dan200/computercraft/data/Generators.java +++ b/src/main/java/dan200/computercraft/data/Generators.java @@ -8,9 +8,9 @@ package dan200.computercraft.data; import dan200.computercraft.shared.Registry; import net.minecraft.data.DataGenerator; import net.minecraftforge.common.data.ExistingFileHelper; +import net.minecraftforge.data.event.GatherDataEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.forge.event.lifecycle.GatherDataEvent; @Mod.EventBusSubscriber( bus = Mod.EventBusSubscriber.Bus.MOD ) public class Generators diff --git a/src/main/java/dan200/computercraft/mixin/BlockRenderDispatcherMixin.java b/src/main/java/dan200/computercraft/mixin/BlockRenderDispatcherMixin.java index 273e4414b..7700f7e81 100644 --- a/src/main/java/dan200/computercraft/mixin/BlockRenderDispatcherMixin.java +++ b/src/main/java/dan200/computercraft/mixin/BlockRenderDispatcherMixin.java @@ -24,7 +24,7 @@ import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.HitResult; -import net.minecraftforge.client.model.data.IModelData; +import net.minecraftforge.client.model.data.ModelData; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -35,7 +35,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; /** * Provides custom block breaking progress for modems, so it only applies to the current part. * - * @see BlockRenderDispatcher#renderBreakingTexture(BlockState, BlockPos, BlockAndTintGetter, PoseStack, VertexConsumer, IModelData) + * @see BlockRenderDispatcher#renderBreakingTexture(BlockState, BlockPos, BlockAndTintGetter, PoseStack, VertexConsumer, ModelData) */ @Mixin( BlockRenderDispatcher.class ) public class BlockRenderDispatcherMixin @@ -53,13 +53,13 @@ public class BlockRenderDispatcherMixin private ModelBlockRenderer modelRenderer; @Inject( - method = "name=/^renderBreakingTexture/ desc=/IModelData;\\)V$/", + method = "name=/^renderBreakingTexture/ desc=/ModelData;\\)V$/", at = @At( "HEAD" ), cancellable = true, require = 0 // This isn't critical functionality, so don't worry if we can't apply it. ) public void renderBlockDamage( - BlockState state, BlockPos pos, BlockAndTintGetter world, PoseStack pose, VertexConsumer buffers, IModelData modelData, + BlockState state, BlockPos pos, BlockAndTintGetter world, PoseStack pose, VertexConsumer buffers, ModelData modelData, CallbackInfo info ) { @@ -85,6 +85,6 @@ public class BlockRenderDispatcherMixin BakedModel model = blockModelShaper.getBlockModel( newState ); long seed = newState.getSeed( pos ); - modelRenderer.tesselateBlock( world, model, newState, pos, pose, buffers, true, random, seed, OverlayTexture.NO_OVERLAY, modelData ); + modelRenderer.tesselateBlock( world, model, newState, pos, pose, buffers, true, random, seed, OverlayTexture.NO_OVERLAY, modelData, null ); } } diff --git a/src/main/java/dan200/computercraft/shared/CommonHooks.java b/src/main/java/dan200/computercraft/shared/CommonHooks.java index 06ed3afac..669d40fc1 100644 --- a/src/main/java/dan200/computercraft/shared/CommonHooks.java +++ b/src/main/java/dan200/computercraft/shared/CommonHooks.java @@ -73,7 +73,7 @@ public final class CommonHooks IComputer computer = ((IContainerComputer) container).getComputer(); if( computer instanceof ServerComputer ) { - ((ServerComputer) computer).sendTerminalState( event.getPlayer() ); + ((ServerComputer) computer).sendTerminalState( event.getEntity() ); } } } diff --git a/src/main/java/dan200/computercraft/shared/Config.java b/src/main/java/dan200/computercraft/shared/Config.java index 62a01e951..15a204746 100644 --- a/src/main/java/dan200/computercraft/shared/Config.java +++ b/src/main/java/dan200/computercraft/shared/Config.java @@ -6,8 +6,6 @@ package dan200.computercraft.shared; import com.electronwill.nightconfig.core.UnmodifiableConfig; -import com.google.common.base.CaseFormat; -import com.google.common.base.Converter; import dan200.computercraft.ComputerCraft; import dan200.computercraft.core.apis.http.NetworkUtils; import dan200.computercraft.core.apis.http.options.Action; @@ -367,6 +365,4 @@ public final class Config { sync( event.getConfig() ); } - - private static final Converter converter = CaseFormat.LOWER_CAMEL.converterTo( CaseFormat.UPPER_UNDERSCORE ); } diff --git a/src/main/java/dan200/computercraft/shared/Registry.java b/src/main/java/dan200/computercraft/shared/Registry.java index e625c3b4f..1306fde76 100644 --- a/src/main/java/dan200/computercraft/shared/Registry.java +++ b/src/main/java/dan200/computercraft/shared/Registry.java @@ -13,7 +13,10 @@ import dan200.computercraft.api.network.wired.IWiredElement; import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.pocket.PocketUpgradeSerialiser; import dan200.computercraft.api.turtle.TurtleUpgradeSerialiser; -import dan200.computercraft.shared.command.arguments.*; +import dan200.computercraft.shared.command.arguments.ComputerArgumentType; +import dan200.computercraft.shared.command.arguments.ComputersArgumentType; +import dan200.computercraft.shared.command.arguments.RepeatArgumentType; +import dan200.computercraft.shared.command.arguments.TrackingFieldArgumentType; import dan200.computercraft.shared.common.ColourableRecipe; import dan200.computercraft.shared.common.ContainerHeldItem; import dan200.computercraft.shared.common.DefaultBundledRedstoneProvider; @@ -164,7 +167,7 @@ public final class Registry public static class ModBlockEntities { - static final DeferredRegister> TILES = DeferredRegister.create( ForgeRegistries.BLOCK_ENTITIES, ComputerCraft.MOD_ID ); + static final DeferredRegister> TILES = DeferredRegister.create( ForgeRegistries.BLOCK_ENTITY_TYPES, ComputerCraft.MOD_ID ); private static RegistryObject> ofBlock( RegistryObject block, FixedPointTileEntityType.FixedPointBlockEntitySupplier factory ) { @@ -283,7 +286,7 @@ public final class Registry public static class ModContainers { - static final DeferredRegister> CONTAINERS = DeferredRegister.create( ForgeRegistries.CONTAINERS, ComputerCraft.MOD_ID ); + static final DeferredRegister> CONTAINERS = DeferredRegister.create( ForgeRegistries.MENU_TYPES, ComputerCraft.MOD_ID ); public static final RegistryObject> COMPUTER = CONTAINERS.register( "computer", () -> ContainerData.toType( ComputerContainerData::new, ComputerMenuWithoutInventory::new ) ); @@ -317,7 +320,7 @@ public final class Registry @SuppressWarnings( "unchecked" ) private static > void registerUnsafe( String name, Class type, ArgumentTypeInfo serializer ) { - ARGUMENT_TYPES.register( name, () -> ArgumentTypeInfos.registerByClass( type, (ArgumentTypeInfo)serializer ) ); + ARGUMENT_TYPES.register( name, () -> ArgumentTypeInfos.registerByClass( type, (ArgumentTypeInfo) serializer ) ); } private static > void register( String name, Class type, ArgumentTypeInfo serializer ) diff --git a/src/main/java/dan200/computercraft/shared/network/NetworkHandler.java b/src/main/java/dan200/computercraft/shared/network/NetworkHandler.java index 0472c3498..ec9e63889 100644 --- a/src/main/java/dan200/computercraft/shared/network/NetworkHandler.java +++ b/src/main/java/dan200/computercraft/shared/network/NetworkHandler.java @@ -104,7 +104,7 @@ public final class NetworkHandler network.messageBuilder( type, id, direction ) .encoder( NetworkMessage::toBytes ) .decoder( decoder ) - .consumer( ( packet, contextSup ) -> { + .consumerMainThread( ( packet, contextSup ) -> { NetworkEvent.Context context = contextSup.get(); context.enqueueWork( () -> packet.handle( context ) ); context.setPacketHandled( true ); diff --git a/src/main/java/dan200/computercraft/shared/network/container/ContainerData.java b/src/main/java/dan200/computercraft/shared/network/container/ContainerData.java index 66b00bbbe..6a5300ab2 100644 --- a/src/main/java/dan200/computercraft/shared/network/container/ContainerData.java +++ b/src/main/java/dan200/computercraft/shared/network/container/ContainerData.java @@ -30,7 +30,7 @@ public interface ContainerData default void open( Player player, MenuProvider owner ) { - NetworkHooks.openGui( (ServerPlayer) player, owner, this::toBytes ); + NetworkHooks.openScreen( (ServerPlayer) player, owner, this::toBytes ); } static MenuType toType( Function reader, Factory factory ) diff --git a/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/TileDiskDrive.java b/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/TileDiskDrive.java index 2ec4778a6..90cbb1aa3 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/TileDiskDrive.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/TileDiskDrive.java @@ -120,7 +120,7 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory // Open the GUI if( !getLevel().isClientSide && isUsable( player ) ) { - NetworkHooks.openGui( (ServerPlayer) player, this ); + NetworkHooks.openScreen( (ServerPlayer) player, this ); } return InteractionResult.SUCCESS; } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/generic/GenericPeripheral.java b/src/main/java/dan200/computercraft/shared/peripheral/generic/GenericPeripheral.java index 05bd1e174..cbcf3abce 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/generic/GenericPeripheral.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/generic/GenericPeripheral.java @@ -30,7 +30,7 @@ class GenericPeripheral implements IDynamicPeripheral GenericPeripheral( BlockEntity tile, String name, Set additionalTypes, List methods ) { - ResourceLocation type = ForgeRegistries.BLOCK_ENTITIES.getKey( tile.getType() ); + ResourceLocation type = ForgeRegistries.BLOCK_ENTITY_TYPES.getKey( tile.getType() ); this.tile = tile; this.type = name != null ? name : (type != null ? type.toString() : "unknown"); this.additionalTypes = additionalTypes; diff --git a/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorWatcher.java b/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorWatcher.java index ccc287252..c62f3521b 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorWatcher.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorWatcher.java @@ -11,13 +11,11 @@ import dan200.computercraft.shared.network.client.MonitorClientMessage; import dan200.computercraft.shared.network.client.TerminalState; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraftforge.event.TickEvent; -import net.minecraftforge.event.world.ChunkWatchEvent; +import net.minecraftforge.event.level.ChunkWatchEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; @@ -28,7 +26,6 @@ import java.util.Queue; public final class MonitorWatcher { private static final Queue watching = new ArrayDeque<>(); - private static final Queue playerUpdates = new ArrayDeque<>(); private MonitorWatcher() { @@ -46,47 +43,28 @@ public final class MonitorWatcher @SubscribeEvent public static void onWatch( ChunkWatchEvent.Watch event ) { - // Get the current chunk if it has been loaded. This is safe as, if the chunk hasn't been loaded yet, then the - // monitor will have no contents, and so we won't need to send an update anyway. - ChunkPos chunkPos = event.getPos(); - LevelChunk chunk = event.getWorld().getChunkSource().getChunkNow( chunkPos.x, chunkPos.z ); - if( chunk == null ) return; - - for( BlockEntity te : chunk.getBlockEntities().values() ) + // Find all origin monitors who are not already on the queue and send the + // monitor data to the player. + for( BlockEntity te : event.getChunk().getBlockEntities().values() ) { - // Find all origin monitors who are not already on the queue. if( !(te instanceof TileMonitor monitor) ) continue; ServerMonitor serverMonitor = getMonitor( monitor ); if( serverMonitor == null || monitor.enqueued ) continue; - // The chunk hasn't been sent to the client yet, so we can't send an update. Do it on tick end. - playerUpdates.add( new PlayerUpdate( event.getPlayer(), monitor ) ); + TerminalState state = monitor.cached; + if( state == null ) state = monitor.cached = serverMonitor.write(); + NetworkHandler.sendToPlayer( event.getPlayer(), new MonitorClientMessage( monitor.getBlockPos(), state ) ); } } @SubscribeEvent public static void onTick( TickEvent.ServerTickEvent event ) { + // Find all enqueued monitors and send their contents to all nearby players. + if( event.phase != TickEvent.Phase.END ) return; - PlayerUpdate playerUpdate; - while( (playerUpdate = playerUpdates.poll()) != null ) - { - TileMonitor tile = playerUpdate.monitor; - if( tile.enqueued || tile.isRemoved() ) continue; - - ServerMonitor monitor = getMonitor( tile ); - if( monitor == null ) continue; - - // Some basic sanity checks to the player. It's possible they're no longer within range, but that's harder - // to track efficiently. - ServerPlayer player = playerUpdate.player; - if( !player.isAlive() || player.getLevel() != tile.getLevel() ) continue; - - NetworkHandler.sendToPlayer( playerUpdate.player, new MonitorClientMessage( tile.getBlockPos(), getState( tile, monitor ) ) ); - } - long limit = ComputerCraft.monitorBandwidth; boolean obeyLimit = limit > 0; @@ -125,16 +103,4 @@ public final class MonitorWatcher if( state == null ) state = tile.cached = monitor.write(); return state; } - - private static final class PlayerUpdate - { - final ServerPlayer player; - final TileMonitor monitor; - - private PlayerUpdate( ServerPlayer player, TileMonitor monitor ) - { - this.player = player; - this.monitor = monitor; - } - } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/printer/TilePrinter.java b/src/main/java/dan200/computercraft/shared/peripheral/printer/TilePrinter.java index 51b56b804..958d8d30c 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/printer/TilePrinter.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/printer/TilePrinter.java @@ -99,7 +99,7 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent if( !getLevel().isClientSide && isUsable( player ) ) { - NetworkHooks.openGui( (ServerPlayer) player, this ); + NetworkHooks.openScreen( (ServerPlayer) player, this ); } return InteractionResult.SUCCESS; } diff --git a/src/main/java/dan200/computercraft/shared/turtle/FurnaceRefuelHandler.java b/src/main/java/dan200/computercraft/shared/turtle/FurnaceRefuelHandler.java index 4c6ef06f1..864697b98 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/FurnaceRefuelHandler.java +++ b/src/main/java/dan200/computercraft/shared/turtle/FurnaceRefuelHandler.java @@ -37,7 +37,7 @@ public final class FurnaceRefuelHandler implements TurtleRefuelEvent.Handler ItemStack stack = turtle.getItemHandler().extractItem( slot, limit, false ); int fuelToGive = fuelPerItem * stack.getCount(); // Store the replacement item in the inventory - ItemStack replacementStack = stack.getItem().getContainerItem( stack ); + ItemStack replacementStack = ForgeHooks.getCraftingRemainingItem( stack ); if( !replacementStack.isEmpty() ) { ItemStack remainder = InventoryUtil.storeItems( replacementStack, turtle.getItemHandler(), turtle.getSelectedSlot() ); diff --git a/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleTool.java b/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleTool.java index f9ff18c44..5900542cc 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleTool.java +++ b/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleTool.java @@ -42,7 +42,7 @@ import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.ToolActions; import net.minecraftforge.event.entity.player.AttackEntityEvent; -import net.minecraftforge.event.world.BlockEvent; +import net.minecraftforge.event.level.BlockEvent; import org.apache.commons.lang3.tuple.Pair; import javax.annotation.Nonnull; diff --git a/src/main/java/dan200/computercraft/shared/util/DropConsumer.java b/src/main/java/dan200/computercraft/shared/util/DropConsumer.java index 39a84eb8a..14a4d3761 100644 --- a/src/main/java/dan200/computercraft/shared/util/DropConsumer.java +++ b/src/main/java/dan200/computercraft/shared/util/DropConsumer.java @@ -13,7 +13,7 @@ import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import net.minecraft.world.phys.AABB; -import net.minecraftforge.event.entity.EntityJoinWorldEvent; +import net.minecraftforge.event.entity.EntityJoinLevelEvent; import net.minecraftforge.event.entity.living.LivingDropsEvent; import net.minecraftforge.eventbus.api.EventPriority; import net.minecraftforge.eventbus.api.SubscribeEvent; @@ -80,10 +80,10 @@ public final class DropConsumer } @SubscribeEvent( priority = EventPriority.HIGHEST ) - public static void onEntitySpawn( EntityJoinWorldEvent event ) + public static void onEntitySpawn( EntityJoinLevelEvent event ) { // Capture any nearby item spawns - if( dropWorld == event.getWorld() && event.getEntity() instanceof ItemEntity + if( dropWorld == event.getLevel() && event.getEntity() instanceof ItemEntity && dropBounds.contains( event.getEntity().position() ) ) { handleDrops( ((ItemEntity) event.getEntity()).getItem() ); diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index 40af84e15..45513d892 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -21,6 +21,6 @@ CC: Tweaked is a fork of ComputerCraft, adding programmable computers, turtles a [[dependencies.computercraft]] modId="forge" mandatory=true - versionRange="[41.0.38,42)" + versionRange="[41.0.98,42)" ordering="NONE" side="BOTH" diff --git a/src/main/resources/assets/computercraft/models/block/monitor_base.json b/src/main/resources/assets/computercraft/models/block/monitor_base.json index 06ec832aa..039cac94a 100644 --- a/src/main/resources/assets/computercraft/models/block/monitor_base.json +++ b/src/main/resources/assets/computercraft/models/block/monitor_base.json @@ -1,5 +1,6 @@ { "parent": "block/cube", + "render_type": "cutout", "textures": { "particle": "#front", "down": "#top", diff --git a/src/main/resources/assets/computercraft/models/block/turtle_base.json b/src/main/resources/assets/computercraft/models/block/turtle_base.json index aa3e71418..52ae637d4 100644 --- a/src/main/resources/assets/computercraft/models/block/turtle_base.json +++ b/src/main/resources/assets/computercraft/models/block/turtle_base.json @@ -1,5 +1,6 @@ { "parent": "block/block", + "render_type": "translucent", "textures": { "particle": "#texture" }, diff --git a/src/testMod/java/dan200/computercraft/ingame/api/TestExtensions.kt b/src/testMod/java/dan200/computercraft/ingame/api/TestExtensions.kt index b1da8b113..cc415bde5 100644 --- a/src/testMod/java/dan200/computercraft/ingame/api/TestExtensions.kt +++ b/src/testMod/java/dan200/computercraft/ingame/api/TestExtensions.kt @@ -137,7 +137,7 @@ fun GameTestHelper.sequence(run: GameTestSequence.() -> GameTestSequence) { run(startSequence()).thenSucceed() } -private fun getName(type: BlockEntityType<*>): ResourceLocation = ForgeRegistries.BLOCK_ENTITIES.getKey(type)!! +private fun getName(type: BlockEntityType<*>): ResourceLocation = ForgeRegistries.BLOCK_ENTITY_TYPES.getKey(type)!! fun GameTestHelper.getBlockEntity(pos: BlockPos, type: BlockEntityType): T { val tile = getBlockEntity(pos) diff --git a/src/testMod/java/dan200/computercraft/ingame/mod/ClientHooks.java b/src/testMod/java/dan200/computercraft/ingame/mod/ClientHooks.java index 8d9504560..a946dc107 100644 --- a/src/testMod/java/dan200/computercraft/ingame/mod/ClientHooks.java +++ b/src/testMod/java/dan200/computercraft/ingame/mod/ClientHooks.java @@ -29,7 +29,7 @@ public final class ClientHooks } @SubscribeEvent - public static void onGuiInit( ScreenEvent.InitScreenEvent event ) + public static void onGuiInit( ScreenEvent.Init event ) { if( triggered || !(event.getScreen() instanceof TitleScreen) ) return; triggered = true;