From ef36fc18ae7ad7a345f76cc3b540a6d57134fefe Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Wed, 23 Oct 2024 20:21:04 +0100 Subject: [PATCH] Update to 1.21.3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a very preliminary port. I can get in game and use computers, but I've not tested much beyond that (there's at least one failing game test). == Rendering == - Remove TBO monitor renderer: There was a big overhaul to how shaders are defined and loaded in 1.21.2. It might have been possible to update the monitor shader code to this version, it doesn't see much use nowadays, so let's just delete it. This is a real shame — the TBO renderer was one of my favourite projects I've worked on. Unfortunately, it just doesn't seem worth the ongoing maintenance burden. It lives on in the standalone emulator :D. - Similarly, the VBO rendering code got a bit of an overhaul. We no longer use a custom VBO subclass, and instead just hack vanilla's to support changing the number of vertices rendered. This does mean we need to construct a MeshData, rather than a raw ByteBuffer. This isn't too hard, but not sure how it'll play with Iris. Given recent vanilla performance improvements, maybe we can remove our Unsafe code and use a normal BufferBuilder now. - Move some textures to vanilla's GUI sprite sheet (from our own). We also move the turtle "selected slot" texture to a sprite sheet - would be good to do the other ones (printer progress, maybe printouts) in the future. - Remove our custom emissive model code, now that vanilla supports it. We should add emissive textures to some other models at some point. == Recipes == There were several major changes to ingredients this update. The code here hasn't been very well tested right now — might be nice to add some game tests for this. - Ingredients can no longer be constructed directly from a tag key (it needs to be fetched from the current registries), so the recipe generation code needs a bit of a reshuffle. - DiskRecipe now accepts a custom list of ingredients, rather than being hard-coded (fixes #1755). Recipes can now return custom `RecipeDisplay`s used to show a recipe in the crafting book. We use this to replace the impostor recipes. I'm not entirely sure how well this'll play with other recipe mods. Here's hoping. - Similarly, our recipe mod integration has been updated to use RecipeDisplay. We had to do this as ingredients no longer accept arbitrary ItemStacks (only a specific item), but the design is a little speculative - JEI/REI haven't updated yet. == Misc == - Blocks/items now need to know their ID ahead of time (so they can compute their description). This requires some reshuffling to the registration code, but it's pretty minor. - updateShape and neighborChanged have been tweaked slightly, I assume to work with the upcoming redstone changes. neighborChanged is currently commented out — we need to handle that properly. - All the positions were lowered by one in game tests. It's a good change (they now match the positions in structures), but annoying to update for! --- .../main/kotlin/cc-tweaked.fabric.gradle.kts | 10 +- gradle.properties | 2 +- gradle/libs.versions.toml | 16 +- gradle/wrapper/gradle-wrapper.jar | Bin 43504 -> 43583 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- .../api/client/TransformedModel.java | 2 +- .../client/turtle/TurtleUpgradeModeller.java | 2 +- .../client/turtle/TurtleUpgradeModellers.java | 2 +- projects/common/build.gradle.kts | 6 + .../computercraft/client/ClientHooks.java | 16 +- .../computercraft/client/ClientRegistry.java | 12 +- .../client/gui/AbstractComputerScreen.java | 2 +- .../client/gui/ComputerScreen.java | 19 +- .../client/gui/DiskDriveScreen.java | 3 +- .../computercraft/client/gui/GuiSprites.java | 12 +- .../computercraft/client/gui/ItemToast.java | 63 ++- .../client/gui/NoTermComputerScreen.java | 2 +- .../client/gui/OptionScreen.java | 10 +- .../client/gui/PrinterScreen.java | 7 +- .../client/gui/PrintoutScreen.java | 8 +- .../client/gui/TurtleScreen.java | 26 +- .../gui/widgets/DynamicImageButton.java | 15 +- .../client/gui/widgets/TerminalWidget.java | 13 +- .../client/integration/IrisShaderMod.java | 30 +- .../client/integration/ShaderMod.java | 16 +- .../client/model/turtle/ModelTransformer.java | 2 +- .../client/model/turtle/TurtleModelParts.java | 3 +- .../platform/ClientNetworkContextImpl.java | 10 +- .../client/render/ModelRenderer.java | 2 +- .../client/render/PocketItemRenderer.java | 12 +- .../client/render/PrintoutItemRenderer.java | 7 +- .../client/render/PrintoutRenderer.java | 14 +- .../client/render/RenderTypes.java | 102 ----- .../client/render/SpriteRenderer.java | 14 +- .../render/TurtleBlockEntityRenderer.java | 13 +- .../monitor/MonitorBlockEntityRenderer.java | 245 ++++------- .../render/monitor/MonitorRenderState.java | 76 +--- .../monitor/MonitorTextureBufferShader.java | 127 ------ .../text/DirectFixedWidthFontRenderer.java | 32 +- .../render/text/FixedWidthFontRenderer.java | 36 +- .../client/render/vbo/DirectBuffers.java | 71 ---- .../client/render/vbo/DirectVertexBuffer.java | 77 ---- .../data/client/ClientDataProviders.java | 29 +- .../assets/computercraft/atlases/gui.json | 6 - .../assets/computercraft/lang/en_us.json | 2 - .../redstone/{disk_1.json => disk.json} | 4 +- .../advancement/recipes/redstone/disk_10.json | 12 - .../advancement/recipes/redstone/disk_11.json | 12 - .../advancement/recipes/redstone/disk_12.json | 12 - .../advancement/recipes/redstone/disk_13.json | 12 - .../advancement/recipes/redstone/disk_14.json | 12 - .../advancement/recipes/redstone/disk_15.json | 12 - .../advancement/recipes/redstone/disk_16.json | 12 - .../advancement/recipes/redstone/disk_2.json | 12 - .../advancement/recipes/redstone/disk_3.json | 12 - .../advancement/recipes/redstone/disk_4.json | 12 - .../advancement/recipes/redstone/disk_5.json | 12 - .../advancement/recipes/redstone/disk_6.json | 12 - .../advancement/recipes/redstone/disk_7.json | 12 - .../advancement/recipes/redstone/disk_8.json | 12 - .../advancement/recipes/redstone/disk_9.json | 12 - .../redstone/wired_modem_full_from.json | 15 - .../recipes/redstone/wired_modem_full_to.json | 15 - .../data/computercraft/recipe/cable.json | 2 +- .../recipe/computer_advanced.json | 2 +- .../recipe/computer_advanced_upgrade.json | 4 +- .../recipe/computer_command.json | 6 +- .../computercraft/recipe/computer_normal.json | 2 +- .../data/computercraft/recipe/disk.json | 7 +- .../data/computercraft/recipe/disk_1.json | 11 - .../data/computercraft/recipe/disk_10.json | 11 - .../data/computercraft/recipe/disk_11.json | 11 - .../data/computercraft/recipe/disk_12.json | 11 - .../data/computercraft/recipe/disk_13.json | 15 - .../data/computercraft/recipe/disk_14.json | 11 - .../data/computercraft/recipe/disk_15.json | 11 - .../data/computercraft/recipe/disk_16.json | 11 - .../data/computercraft/recipe/disk_2.json | 11 - .../data/computercraft/recipe/disk_3.json | 11 - .../data/computercraft/recipe/disk_4.json | 11 - .../data/computercraft/recipe/disk_5.json | 11 - .../data/computercraft/recipe/disk_6.json | 11 - .../data/computercraft/recipe/disk_7.json | 11 - .../data/computercraft/recipe/disk_8.json | 15 - .../data/computercraft/recipe/disk_9.json | 11 - .../data/computercraft/recipe/disk_drive.json | 2 +- .../recipe/monitor_advanced.json | 2 +- .../computercraft/recipe/monitor_normal.json | 2 +- .../computercraft/speaker.json | 2 +- .../wireless_modem_advanced.json | 5 +- .../computercraft/wireless_modem_normal.json | 5 +- .../recipe/pocket_computer_advanced.json | 2 +- .../pocket_computer_advanced_upgrade.json | 6 +- .../recipe/pocket_computer_normal.json | 6 +- .../pocket_normal/computercraft/speaker.json | 2 +- .../wireless_modem_advanced.json | 5 +- .../computercraft/wireless_modem_normal.json | 5 +- .../computercraft/recipe/printed_book.json | 8 +- .../computercraft/recipe/printed_pages.json | 8 +- .../data/computercraft/recipe/printer.json | 2 +- .../computercraft/recipe/skull_cloudy.json | 2 +- .../computercraft/recipe/skull_dan200.json | 2 +- .../data/computercraft/recipe/speaker.json | 6 +- .../computercraft/recipe/turtle_advanced.json | 8 +- .../computercraft/speaker.json | 2 +- .../wireless_modem_advanced.json | 2 +- .../computercraft/wireless_modem_normal.json | 2 +- .../minecraft/crafting_table.json | 2 +- .../minecraft/diamond_axe.json | 2 +- .../minecraft/diamond_hoe.json | 2 +- .../minecraft/diamond_pickaxe.json | 2 +- .../minecraft/diamond_shovel.json | 2 +- .../minecraft/diamond_sword.json | 2 +- .../rainbow_flag.json | 18 +- .../turtle_advanced_overlays/trans_flag.json | 12 +- .../recipe/turtle_advanced_upgrade.json | 8 +- .../computercraft/recipe/turtle_normal.json | 8 +- .../turtle_normal/computercraft/speaker.json | 2 +- .../wireless_modem_advanced.json | 2 +- .../computercraft/wireless_modem_normal.json | 2 +- .../minecraft/crafting_table.json | 2 +- .../turtle_normal/minecraft/diamond_axe.json | 2 +- .../turtle_normal/minecraft/diamond_hoe.json | 2 +- .../minecraft/diamond_pickaxe.json | 2 +- .../minecraft/diamond_shovel.json | 2 +- .../minecraft/diamond_sword.json | 2 +- .../turtle_normal_overlays/rainbow_flag.json | 18 +- .../turtle_normal_overlays/trans_flag.json | 12 +- .../computercraft/recipe/wired_modem.json | 2 +- .../recipe/wireless_modem_advanced.json | 2 +- .../recipe/wireless_modem_normal.json | 2 +- .../wired_modem_from_wired_modem_full.json | 15 + .../wired_modem_full_from_wired_modem.json | 15 + .../wired_modem_from_wired_modem_full.json} | 4 +- .../wired_modem_full_from_wired_modem.json} | 4 +- .../computercraft/data/DataProviders.java | 2 +- .../computercraft/data/LanguageProvider.java | 5 +- .../computercraft/data/LootTableProvider.java | 4 +- .../computercraft/data/RecipeProvider.java | 387 ++++++++---------- .../data/recipe/AbstractRecipeBuilder.java | 19 +- .../data/recipe/ShapedSpecBuilder.java | 15 +- .../data/recipe/ShapelessSpecBuilder.java | 21 +- .../computercraft/mixin/V3818_3Mixin.java | 10 +- .../computercraft/shared/ModRegistry.java | 142 ++++--- .../shared/command/CommandComputerCraft.java | 4 +- .../shared/common/ClearColourRecipe.java | 5 - .../shared/common/ColourableRecipe.java | 5 - .../common/HorizontalContainerBlock.java | 5 +- .../blocks/AbstractComputerBlock.java | 17 +- .../blocks/AbstractComputerBlockEntity.java | 4 +- .../shared/computer/blocks/ComputerBlock.java | 3 +- .../computercraft/shared/config/Config.java | 3 - .../shared/config/ConfigSpec.java | 9 - .../data/BlockNamedEntityLootCondition.java | 6 +- .../data/HasComputerIdLootCondition.java | 6 +- .../data/PlayerCreativeLootCondition.java | 6 +- .../integration/UpgradeRecipeGenerator.java | 53 ++- .../shared/lectern/CustomLecternBlock.java | 9 +- .../shared/media/items/PrintoutItem.java | 5 +- .../shared/media/recipes/DiskRecipe.java | 113 +++-- .../shared/media/recipes/PrintoutRecipe.java | 87 ++-- .../peripheral/diskdrive/DiskDriveBlock.java | 8 +- .../peripheral/modem/wired/CableBlock.java | 7 +- .../modem/wired/CableBlockItem.java | 21 +- .../modem/wired/WiredModemFullBlock.java | 9 +- .../modem/wireless/WirelessModemBlock.java | 9 +- .../wireless/WirelessModemPeripheral.java | 2 +- .../peripheral/monitor/MonitorBlock.java | 7 +- .../peripheral/speaker/SpeakerPeripheral.java | 4 +- .../shared/platform/PlatformHelper.java | 11 +- .../shared/platform/RecipeIngredients.java | 23 +- .../shared/platform/RegistryEntry.java | 2 +- .../pocket/items/PocketComputerItem.java | 7 +- .../recipes/PocketComputerUpgradeRecipe.java | 12 +- .../shared/recipe/AbstractCraftingRecipe.java | 34 ++ .../shared/recipe/BasicRecipeSerialiser.java | 6 + .../shared/recipe/CustomShapelessRecipe.java | 57 ++- .../shared/recipe/RecipeProperties.java | 5 +- .../shared/recipe/ShapelessRecipeSpec.java | 17 +- .../recipe/function/CopyComponents.java | 2 +- .../shared/turtle/FurnaceRefuelHandler.java | 8 +- .../shared/turtle/blocks/TurtleBlock.java | 22 +- .../shared/turtle/items/TurtleItem.java | 8 +- .../turtle/recipes/TurtleUpgradeRecipe.java | 12 +- .../upgrades/TurtleInventoryCrafting.java | 12 +- .../shared/turtle/upgrades/TurtleTool.java | 4 +- .../shared/util/ArgumentHelpers.java | 2 +- .../shared/util/ColourUtils.java | 2 +- .../shared/util/ComponentizationFixers.java | 28 +- .../shared/util/RedstoneUtil.java | 4 +- .../shared/util/RegistryHelper.java | 2 +- .../shared/util/WaterloggableHelpers.java | 17 +- .../models/block/computer_on.json | 5 +- .../textures/gui/border_advanced.png | Bin 334 -> 208 bytes .../textures/gui/border_colour.png | Bin 294 -> 199 bytes .../textures/gui/border_command.png | Bin 300 -> 189 bytes .../textures/gui/border_normal.png | Bin 299 -> 198 bytes .../textures/gui/buttons/terminate.png | Bin 145 -> 0 bytes .../textures/gui/buttons/terminate_hover.png | Bin 144 -> 0 bytes .../textures/gui/buttons/turned_off.png | Bin 145 -> 0 bytes .../textures/gui/buttons/turned_off_hover.png | Bin 145 -> 0 bytes .../textures/gui/pocket_bottom_advanced.png | Bin 223 -> 160 bytes .../textures/gui/pocket_bottom_colour.png | Bin 211 -> 157 bytes .../textures/gui/pocket_bottom_normal.png | Bin 216 -> 161 bytes .../textures/gui/sidebar_advanced.png | Bin 148 -> 144 bytes .../textures/gui/sidebar_normal.png | Bin 141 -> 139 bytes .../gui/sprites/buttons/terminate.png | Bin 0 -> 137 bytes .../gui/sprites/buttons/terminate_hover.png | Bin 0 -> 131 bytes .../gui/sprites/buttons/turned_off.png | Bin 0 -> 136 bytes .../gui/sprites/buttons/turned_off_hover.png | Bin 0 -> 135 bytes .../gui/{ => sprites}/buttons/turned_on.png | Bin .../{ => sprites}/buttons/turned_on_hover.png | Bin .../sprites/turtle_advanced_selected_slot.png | Bin 0 -> 461 bytes .../sprites/turtle_normal_selected_slot.png | Bin 0 -> 476 bytes .../textures/gui/turtle_advanced.png | Bin 1455 -> 738 bytes .../textures/gui/turtle_normal.png | Bin 1415 -> 695 bytes .../core/computercraft/monitor_tbo.fsh | 70 ---- .../core/computercraft/monitor_tbo.json | 18 - .../core/computercraft/monitor_tbo.vsh | 26 -- .../computercraft-common.accesswidener | 3 +- .../resources/computercraft.accesswidener | 10 +- .../main/resources/computercraft.mixins.json | 3 +- .../computercraft/TestPlatformHelper.java | 9 +- .../dan200/computercraft/export/Exporter.java | 35 +- .../computercraft/export/ImageRenderer.java | 21 +- .../dan200/computercraft/export/JsonDump.java | 16 +- .../gametest/core/CCTestCommand.java | 13 +- .../mixin/gametest/GameTestServerMixin.java | 40 ++ .../gametest/MinecraftServerAccessor.java | 19 + .../computercraft/gametest/Computer_Test.kt | 24 +- .../computercraft/gametest/Disk_Drive_Test.kt | 20 +- .../computercraft/gametest/Inventory_Test.kt | 8 +- .../computercraft/gametest/Loot_Test.kt | 2 +- .../computercraft/gametest/Modem_Test.kt | 24 +- .../computercraft/gametest/Monitor_Test.kt | 43 +- .../gametest/Pocket_Computer_Test.kt | 10 +- .../computercraft/gametest/Printer_Test.kt | 10 +- .../computercraft/gametest/Turtle_Test.kt | 124 +++--- .../gametest/api/TestExtensions.kt | 2 +- .../gametest/core/ClientTestHooks.kt | 10 +- .../computercraft-gametest.mixins.json | 2 + projects/fabric/build.gradle.kts | 8 + .../client/ComputerCraftClient.java | 1 - .../client/model/CustomModelLoader.java | 42 +- .../client/model/EmissiveBakedModel.java | 84 ---- .../client/model/turtle/TurtleModel.java | 21 +- .../model/turtle/UnbakedTurtleModel.java | 19 +- .../platform/ClientPlatformHelperImpl.java | 2 +- .../mixin/client/DebugScreenOverlayMixin.java | 6 - .../mixin/client/GameRendererMixin.java | 41 -- .../mixin/client/ItemFrameRendererMixin.java | 8 +- .../computercraft-client.fabric.mixins.json | 1 - .../computercraft/mixin/EntityMixin.java | 7 +- .../computercraft/mixin/V3818_3Mixin.java | 27 -- .../computercraft/shared/ComputerCraft.java | 5 +- .../shared/FabricCommonHooks.java | 2 +- .../shared/platform/PlatformHelperImpl.java | 37 +- .../fabric/src/main/resources/fabric.mod.json | 2 +- projects/forge/build.gradle.kts | 4 +- .../client/ForgeClientHooks.java | 3 +- .../client/ForgeClientRegistry.java | 11 +- .../client/model/FoiledModel.java | 4 +- .../client/model/turtle/TurtleModel.java | 2 +- .../model/turtle/TurtleModelLoader.java | 21 +- .../platform/ClientPlatformHelperImpl.java | 2 +- .../shared/platform/PlatformHelperImpl.java | 34 +- .../resources/META-INF/accesstransformer.cfg | 7 +- .../resources/META-INF/neoforge.mods.toml | 5 +- .../resources/computercraft.forge.mixins.json | 12 - 269 files changed, 1486 insertions(+), 2641 deletions(-) delete mode 100644 projects/common/src/client/java/dan200/computercraft/client/render/RenderTypes.java delete mode 100644 projects/common/src/client/java/dan200/computercraft/client/render/monitor/MonitorTextureBufferShader.java delete mode 100644 projects/common/src/client/java/dan200/computercraft/client/render/vbo/DirectBuffers.java delete mode 100644 projects/common/src/client/java/dan200/computercraft/client/render/vbo/DirectVertexBuffer.java rename projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/{disk_1.json => disk.json} (76%) delete mode 100644 projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_10.json delete mode 100644 projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_11.json delete mode 100644 projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_12.json delete mode 100644 projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_13.json delete mode 100644 projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_14.json delete mode 100644 projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_15.json delete mode 100644 projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_16.json delete mode 100644 projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_2.json delete mode 100644 projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_3.json delete mode 100644 projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_4.json delete mode 100644 projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_5.json delete mode 100644 projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_6.json delete mode 100644 projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_7.json delete mode 100644 projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_8.json delete mode 100644 projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_9.json delete mode 100644 projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/wired_modem_full_from.json delete mode 100644 projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/wired_modem_full_to.json delete mode 100644 projects/common/src/generated/resources/data/computercraft/recipe/disk_1.json delete mode 100644 projects/common/src/generated/resources/data/computercraft/recipe/disk_10.json delete mode 100644 projects/common/src/generated/resources/data/computercraft/recipe/disk_11.json delete mode 100644 projects/common/src/generated/resources/data/computercraft/recipe/disk_12.json delete mode 100644 projects/common/src/generated/resources/data/computercraft/recipe/disk_13.json delete mode 100644 projects/common/src/generated/resources/data/computercraft/recipe/disk_14.json delete mode 100644 projects/common/src/generated/resources/data/computercraft/recipe/disk_15.json delete mode 100644 projects/common/src/generated/resources/data/computercraft/recipe/disk_16.json delete mode 100644 projects/common/src/generated/resources/data/computercraft/recipe/disk_2.json delete mode 100644 projects/common/src/generated/resources/data/computercraft/recipe/disk_3.json delete mode 100644 projects/common/src/generated/resources/data/computercraft/recipe/disk_4.json delete mode 100644 projects/common/src/generated/resources/data/computercraft/recipe/disk_5.json delete mode 100644 projects/common/src/generated/resources/data/computercraft/recipe/disk_6.json delete mode 100644 projects/common/src/generated/resources/data/computercraft/recipe/disk_7.json delete mode 100644 projects/common/src/generated/resources/data/computercraft/recipe/disk_8.json delete mode 100644 projects/common/src/generated/resources/data/computercraft/recipe/disk_9.json create mode 100644 projects/common/src/generated/resources/data/minecraft/advancement/recipes/misc/wired_modem_from_wired_modem_full.json create mode 100644 projects/common/src/generated/resources/data/minecraft/advancement/recipes/misc/wired_modem_full_from_wired_modem.json rename projects/common/src/generated/resources/data/{computercraft/recipe/wired_modem_full_to.json => minecraft/recipe/wired_modem_from_wired_modem_full.json} (54%) rename projects/common/src/generated/resources/data/{computercraft/recipe/wired_modem_full_from.json => minecraft/recipe/wired_modem_full_from_wired_modem.json} (56%) rename projects/{forge => common}/src/main/java/dan200/computercraft/mixin/V3818_3Mixin.java (68%) create mode 100644 projects/common/src/main/java/dan200/computercraft/shared/recipe/AbstractCraftingRecipe.java delete mode 100644 projects/common/src/main/resources/assets/computercraft/textures/gui/buttons/terminate.png delete mode 100644 projects/common/src/main/resources/assets/computercraft/textures/gui/buttons/terminate_hover.png delete mode 100644 projects/common/src/main/resources/assets/computercraft/textures/gui/buttons/turned_off.png delete mode 100644 projects/common/src/main/resources/assets/computercraft/textures/gui/buttons/turned_off_hover.png create mode 100644 projects/common/src/main/resources/assets/computercraft/textures/gui/sprites/buttons/terminate.png create mode 100644 projects/common/src/main/resources/assets/computercraft/textures/gui/sprites/buttons/terminate_hover.png create mode 100644 projects/common/src/main/resources/assets/computercraft/textures/gui/sprites/buttons/turned_off.png create mode 100644 projects/common/src/main/resources/assets/computercraft/textures/gui/sprites/buttons/turned_off_hover.png rename projects/common/src/main/resources/assets/computercraft/textures/gui/{ => sprites}/buttons/turned_on.png (100%) rename projects/common/src/main/resources/assets/computercraft/textures/gui/{ => sprites}/buttons/turned_on_hover.png (100%) create mode 100644 projects/common/src/main/resources/assets/computercraft/textures/gui/sprites/turtle_advanced_selected_slot.png create mode 100644 projects/common/src/main/resources/assets/computercraft/textures/gui/sprites/turtle_normal_selected_slot.png delete mode 100644 projects/common/src/main/resources/assets/minecraft/shaders/core/computercraft/monitor_tbo.fsh delete mode 100644 projects/common/src/main/resources/assets/minecraft/shaders/core/computercraft/monitor_tbo.json delete mode 100644 projects/common/src/main/resources/assets/minecraft/shaders/core/computercraft/monitor_tbo.vsh create mode 100644 projects/common/src/testMod/java/dan200/computercraft/mixin/gametest/GameTestServerMixin.java create mode 100644 projects/common/src/testMod/java/dan200/computercraft/mixin/gametest/MinecraftServerAccessor.java delete mode 100644 projects/fabric/src/client/java/dan200/computercraft/client/model/EmissiveBakedModel.java delete mode 100644 projects/fabric/src/client/java/dan200/computercraft/mixin/client/GameRendererMixin.java delete mode 100644 projects/fabric/src/main/java/dan200/computercraft/mixin/V3818_3Mixin.java delete mode 100644 projects/forge/src/main/resources/computercraft.forge.mixins.json diff --git a/buildSrc/src/main/kotlin/cc-tweaked.fabric.gradle.kts b/buildSrc/src/main/kotlin/cc-tweaked.fabric.gradle.kts index 7ef28a271d..2750566fbc 100644 --- a/buildSrc/src/main/kotlin/cc-tweaked.fabric.gradle.kts +++ b/buildSrc/src/main/kotlin/cc-tweaked.fabric.gradle.kts @@ -4,10 +4,8 @@ /** Default configuration for Fabric projects. */ -import cc.tweaked.gradle.CCTweakedExtension -import cc.tweaked.gradle.CCTweakedPlugin +import cc.tweaked.gradle.* import cc.tweaked.gradle.IdeaRunConfigurations -import cc.tweaked.gradle.MinecraftConfigurations plugins { `java-library` @@ -67,3 +65,9 @@ dependencies { tasks.ideaSyncTask { doLast { IdeaRunConfigurations(project).patch() } } + +tasks.named("checkDependencyConsistency", DependencyCheck::class.java) { + val libs = project.extensions.getByType().named("libs") + // Fabric forces asm to a more recent version + override(libs.findLibrary("asm").get(), "9.7.1") +} diff --git a/gradle.properties b/gradle.properties index f7f78fa35c..26ef6f331b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -15,4 +15,4 @@ isUnstable=true modVersion=1.113.1 # Minecraft properties: We want to configure this here so we can read it in settings.gradle -mcVersion=1.21.1 +mcVersion=1.21.3 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e5b6c2fd26..fed8163030 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,14 +7,14 @@ # Minecraft # MC version is specified in gradle.properties, as we need that in settings.gradle. # Remember to update corresponding versions in fabric.mod.json/neoforge.mods.toml -fabric-api = "0.102.1+1.21.1" -fabric-loader = "0.15.11" -neoForge = "21.1.9" +fabric-api = "0.106.1+1.21.3" +fabric-loader = "0.16.7" +neoForge = "21.3.0-beta" neoForgeSpi = "8.0.1" mixin = "0.8.5" parchment = "2024.07.28" parchmentMc = "1.21" -yarn = "1.21.1+build.1" +yarn = "1.21.3+build.1" # Core dependencies (these versions are tied to the version Minecraft uses) fastutil = "8.5.12" @@ -62,14 +62,14 @@ checkstyle = "10.14.1" curseForgeGradle = "1.1.18" errorProne-core = "2.27.0" errorProne-plugin = "3.1.0" -fabric-loom = "1.7.1" +fabric-loom = "1.8.10" githubRelease = "2.5.2" gradleVersions = "0.50.0" ideaExt = "1.1.7" illuaminate = "0.1.0-73-g43ee16c" lwjgl = "3.3.3" minotaur = "2.8.7" -neoGradle = "7.0.152" +neoGradle = "7.0.165" nullAway = "0.10.25" shadow = "8.3.1" spotless = "6.23.3" @@ -186,9 +186,9 @@ kotlin = ["kotlin-stdlib", "kotlin-coroutines"] # Minecraft externalMods-common = ["iris-forge", "jei-api", "nightConfig-core", "nightConfig-toml"] externalMods-forge-compile = ["moreRed", "iris-forge", "jei-api"] -externalMods-forge-runtime = ["jei-forge"] +externalMods-forge-runtime = [] externalMods-fabric-compile = ["fabricPermissions", "iris-fabric", "jei-api", "rei-api", "rei-builtin"] -externalMods-fabric-runtime = ["jei-fabric", "modmenu"] +externalMods-fabric-runtime = [] # Testing test = ["junit-jupiter-api", "junit-jupiter-params", "hamcrest", "jqwik-api"] diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 2c3521197d7c4586c843d1d3e9090525f1898cde..a4b76b9530d66f5e68d973ea569d8e19de379189 100644 GIT binary patch delta 3990 zcmV;H4{7l5(*nQL0Kr1kzC=_KMxQY0|W5(lc#i zH*M1^P4B}|{x<+fkObwl)u#`$GxKKV&3pg*-y6R6txw)0qU|Clf9Uds3x{_-**c=7 z&*)~RHPM>Rw#Hi1R({;bX|7?J@w}DMF>dQQU2}9yj%iLjJ*KD6IEB2^n#gK7M~}6R zkH+)bc--JU^pV~7W=3{E*4|ZFpDpBa7;wh4_%;?XM-5ZgZNnVJ=vm!%a2CdQb?oTa z70>8rTb~M$5Tp!Se+4_OKWOB1LF+7gv~$$fGC95ToUM(I>vrd$>9|@h=O?eARj0MH zT4zo(M>`LWoYvE>pXvqG=d96D-4?VySz~=tPVNyD$XMshoTX(1ZLB5OU!I2OI{kb) zS8$B8Qm>wLT6diNnyJZC?yp{Kn67S{TCOt-!OonOK7$K)e-13U9GlnQXPAb&SJ0#3 z+vs~+4Qovv(%i8g$I#FCpCG^C4DdyQw3phJ(f#y*pvNDQCRZ~MvW<}fUs~PL=4??j zmhPyg<*I4RbTz|NHFE-DC7lf2=}-sGkE5e!RM%3ohM7_I^IF=?O{m*uUPH(V?gqyc(Rp?-Qu(3bBIL4Fz(v?=_Sh?LbK{nqZMD>#9D_hNhaV$0ef3@9V90|0u#|PUNTO>$F=qRhg1duaE z0`v~X3G{8RVT@kOa-pU+z8{JWyP6GF*u2e8eKr7a2t1fuqQy)@d|Qn(%YLZ62TWtoX@$nL}9?atE#Yw`rd(>cr0gY;dT9~^oL;u)zgHUvxc2I*b&ZkGM-iq=&(?kyO(3}=P! zRp=rErEyMT5UE9GjPHZ#T<`cnD)jyIL!8P{H@IU#`e8cAG5jMK zVyKw7--dAC;?-qEu*rMr$5@y535qZ6p(R#+fLA_)G~!wnT~~)|s`}&fA(s6xXN`9j zP#Fd3GBa#HeS{5&8p?%DKUyN^X9cYUc6vq}D_3xJ&d@=6j(6BZKPl?!k1?!`f3z&a zR4ZF60Mx7oBxLSxGuzA*Dy5n-d2K=+)6VMZh_0KetK|{e;E{8NJJ!)=_E~1uu=A=r zrn&gh)h*SFhsQJo!f+wKMIE;-EOaMSMB@aXRU(UcnJhZW^B^mgs|M9@5WF@s6B0p& zm#CTz)yiQCgURE{%hjxHcJ6G&>G9i`7MyftL!QQd5 z@RflRs?7)99?X`kHNt>W3l7YqscBpi*R2+fsgABor>KVOu(i(`03aytf2UA!&SC9v z!E}whj#^9~=XHMinFZ;6UOJjo=mmNaWkv~nC=qH9$s-8roGeyaW-E~SzZ3Gg>j zZ8}<320rg4=$`M0nxN!w(PtHUjeeU?MvYgWKZ6kkzABK;vMN0|U;X9abJleJA(xy<}5h5P(5 z{RzAFPvMnX2m0yH0Jn2Uo-p`daE|(O`YQiC#jB8;6bVIUf?SY(k$#C0`d6qT`>Xe0+0}Oj0=F&*D;PVe=Z<=0AGI<6$gYLwa#r` zm449x*fU;_+J>Mz!wa;T-wldoBB%&OEMJgtm#oaI60TSYCy7;+$5?q!zi5K`u66Wq zvg)Fx$s`V3Em{=OEY{3lmh_7|08ykS&U9w!kp@Ctuzqe1JFOGz6%i5}Kmm9>^=gih z?kRxqLA<3@e=}G4R_?phW{4DVr?`tPfyZSN@R=^;P;?!2bh~F1I|fB7P=V=9a6XU5 z<#0f>RS0O&rhc&nTRFOW7&QhevP0#>j0eq<1@D5yAlgMl5n&O9X|Vq}%RX}iNyRFF z7sX&u#6?E~bm~N|z&YikXC=I0E*8Z$v7PtWfjy)$e_Ez25fnR1Q=q1`;U!~U>|&YS zaOS8y!^ORmr2L4ik!IYR8@Dcx8MTC=(b4P6iE5CnrbI~7j7DmM8em$!da&D!6Xu)!vKPdLG z9f#)se|6=5yOCe)N6xDhPI!m81*dNe7u985zi%IVfOfJh69+#ag4ELzGne?o`eA`42K4T)h3S+s)5IT97%O>du- z0U54L8m4}rkRQ?QBfJ%DLssy^+a7Ajw;0&`NOTY4o;0-ivm9 zBz1C%nr_hQ)X)^QM6T1?=yeLkuG9Lf50(eH}`tFye;01&(p?8i+6h};VV-2B~qdxeC#=X z(JLlzy&fHkyi9Ksbcs~&r^%lh^2COldLz^H@X!s~mr9Dr6z!j+4?zkD@Ls7F8(t(f z9`U?P$Lmn*Y{K}aR4N&1N=?xtQ1%jqf1~pJyQ4SgBrEtR`j4lQuh7cqP49Em5cO=I zB(He2`iPN5M=Y0}h(IU$37ANTGx&|b-u1BYA*#dE(L-lptoOpo&th~E)_)y-`6kSH z3vvyVrcBwW^_XYReJ=JYd9OBQrzv;f2AQdZH#$Y{Y+Oa33M70XFI((fs;mB4e`<<{ ze4dv2B0V_?Ytsi>>g%qs*}oDGd5d(RNZ*6?7qNbdp7wP4T72=F&r?Ud#kZr8Ze5tB z_oNb7{G+(o2ajL$!69FW@jjPQ2a5C)m!MKKRirC$_VYIuVQCpf9rIms0GRDf)8AH${I`q^~5rjot@#3$2#zT2f`(N^P7Z;6(@EK$q*Jgif00I6*^ZGV+XB5uw*1R-@23yTw&WKD{s1;HTL;dO)%5i#`dc6b7;5@^{KU%N|A-$zsYw4)7LA{3`Zp>1 z-?K9_IE&z)dayUM)wd8K^29m-l$lFhi$zj0l!u~4;VGR6Y!?MAfBC^?QD53hy6VdD z@eUZIui}~L%#SmajaRq1J|#> z4m=o$vZ*34=ZWK2!QMNEcp2Lbc5N1q!lEDq(bz0b;WI9;e>l=CG9^n#ro`w>_0F$Q zfZ={2QyTkfByC&gy;x!r*NyXXbk=a%~~(#K?< zTke0HuF5{Q+~?@!KDXR|g+43$+;ab`^flS%miup_0OUTm=nIc%d5nLP)i308PIjl_YMF6cpQ__6&$n6it8K- z8PIjl_YMF6cpQ_!r)L8IivW`WdK8mBs6PXdjR2DYdK8nCs73=4j{uVadK8oNjwX|E wpAeHLsTu^*Y>Trk?aBtSQ(D-o$(D8Px^?ZI-PUB? z*1fv!{YdHme3Fc8%cR@*@zc5A_nq&2=R47Hp@$-JF4Fz*;SLw5}K^y>s-s;V!}b2i=5=M- zComP?ju>8Fe@=H@rlwe1l`J*6BTTo`9b$zjQ@HxrAhp0D#u?M~TxGC_!?ccCHCjt| zF*PgJf@kJB`|Ml}cmsyrAjO#Kjr^E5p29w+#>$C`Q|54BoDv$fQ9D?3n32P9LPMIzu?LjNqggOH=1@T{9bMn*u8(GI z!;MLTtFPHal^S>VcJdiYqX0VU|Rn@A}C1xOlxCribxes0~+n2 z6qDaIA2$?e`opx3_KW!rAgbpzU)gFdjAKXh|5w``#F0R|c)Y)Du0_Ihhz^S?k^pk% zP>9|pIDx)xHH^_~+aA=^$M!<8K~Hy(71nJGf6`HnjtS=4X4=Hk^O71oNia2V{HUCC zoN3RSBS?mZCLw;l4W4a+D8qc)XJS`pUJ5X-f^1ytxwr`@si$lAE?{4G|o; zO0l>`rr?;~c;{ZEFJ!!3=7=FdGJ?Q^xfNQh4A?i;IJ4}B+A?4olTK(fN++3CRBP97 ze~lG9h%oegkn)lpW-4F8o2`*WW0mZHwHez`ko@>U1_;EC_6ig|Drn@=DMV9YEUSCa zIf$kHei3(u#zm9I!Jf(4t`Vm1lltJ&lVHy(eIXE8sy9sUpmz%I_gA#8x^Zv8%w?r2 z{GdkX1SkzRIr>prRK@rqn9j2wG|rUvf6PJbbin=yy-TAXrguvzN8jL$hUrIXzr^s5 zVM?H4;eM-QeRFr06@ifV(ocvk?_)~N@1c2ien56UjWXid6W%6ievIh)>dk|rIs##^kY67ib8Kw%#-oVFaXG7$ERyA9(NSJUvWiOA5H(!{uOpcW zg&-?iqPhds%3%tFspHDqqr;A!e@B#iPQjHd=c>N1LoOEGRehVoPOdxJ>b6>yc#o#+ zl8s8!(|NMeqjsy@0x{8^j0d00SqRZjp{Kj)&4UHYGxG+z9b-)72I*&J70?+8e?p_@ z=>-(>l6z5vYlP~<2%DU02b!mA{7mS)NS_eLe=t)sm&+Pmk?asOEKlkPQ)EUvvfC=;4M&*|I!w}(@V_)eUKLA_t^%`o z0PM9LV|UKTLnk|?M3u!|f2S0?UqZsEIH9*NJS-8lzu;A6-rr-ot=dg9SASoluZUkFH$7X; zP=?kYX!K?JL-b~<#7wU;b;eS)O;@?h%sPPk{4xEBxb{!sm0AY|f9cNvx6>$3F!*0c z75H=dy8JvTyO8}g1w{$9T$p~5en}AeSLoCF>_RT9YPMpChUjl310o*$QocjbH& zbnwg#gssR#jDVN{uEi3n(PZ%PFZ|6J2 z5_rBf0-u>e4sFe0*Km49ATi7>Kn0f9!uc|rRMR1Dtt6m1LW8^>qFlo}h$@br=Rmpi z;mI&>OF64Be{dVeHI8utrh)v^wsZ0jii%x8UgZ8TC%K~@I(4E};GFW&(;WVov}3%H zH;IhRkfD^(vt^DjZz(MyHLZxv8}qzPc(%itBkBwf_fC~sDBgh<3XAv5cxxfF3<2U! z03Xe&z`is!JDHbe;mNmfkH+_LFE*I2^mdL@7(@9DfAcP6O04V-ko;Rpgp<%Cj5r8Z zd0`sXoIjV$j)--;jA6Zy^D5&5v$o^>e%>Q?9GLm{i~p^lAn!%ZtF$I~>39XVZxk0b zROh^Bk9cE0AJBLozZIEmy7xG(yHWGztvfnr0(2ro1%>zsGMS^EMu+S$r=_;9 zWwZkgf7Q7`H9sLf2Go^Xy6&h~a&%s2_T@_Csf19MntF$aVFiFkvE3_hUg(B@&Xw@YJ zpL$wNYf78=0c@!QU6_a$>CPiXT7QAGDM}7Z(0z#_ZA=fmLUj{2z7@Ypo71UDy8GHr z-&TLKf6a5WCf@Adle3VglBt4>Z>;xF}}-S~B7<(%B;Y z0QR55{z-buw>8ilNM3u6I+D$S%?)(p>=eBx-HpvZj{7c*_?K=d()*7q?93us}1dq%FAFYLsW8ZTQ_XZLh`P2*6(NgS}qGcfGXVWpwsp#Rs}IuKbk*`2}&) zI^Vsk6S&Q4@oYS?dJ`NwMVBs6f57+RxdqVub#PvMu?$=^OJy5xEl0<5SLsSRy%%a0 zi}Y#1-F3m;Ieh#Y12UgW?-R)|eX>ZuF-2cc!1>~NS|XSF-6In>zBoZg+ml!6%fk7U zw0LHcz8VQk(jOJ+Yu)|^|15ufl$KQd_1eUZZzj`aC%umU6F1&D5XVWce_wAe(qCSZ zpX-QF4e{EmEVN9~6%bR5U*UT{eMHfcUo`jw*u?4r2s_$`}U{?NjvEm(u&<>B|%mq$Q3weshxk z76<``8vh{+nX`@9CB6IE&z)I%IFjR^LH{s1p|eppv=x za(g_jLU|xjWMAn-V7th$f({|LG8zzIE0g?cyW;%Dmtv%C+0@xVxPE^ zyZzi9P%JAD6ynwHptuzP`Kox7*9h7XSMonCalv;Md0i9Vb-c*!f0ubfk?&T&T}AHh z4m8Bz{JllKcdNg?D^%a5MFQ;#1z|*}H^qHLzW)L}wp?2tY7RejtSh8<;Zw)QGJYUm z|MbTxyj*McKlStlT9I5XlSWtQGN&-LTr2XyNU+`490rg?LYLMRnz-@oKqT1hpCGqP zyRXt4=_Woj$%n5ee<3zhLF>5>`?m9a#xQH+Jk_+|RM8Vi;2*XbK- zEL6sCpaGPzP>k8f4Kh|##_imt#zJMB;ir|JrMPGW`rityK1vHXMLy18%qmMQAm4WZ zP)i30KR&5vs15)C+8dM66&$k~i|ZT;KR&5vs15)C+8dJ(sAmGPijyIz6_bsqKLSFH zlOd=TljEpH0>h4zA*dCTK&emy#FCRCs1=i^sZ9bFmXjf<6_X39E(XY)00000#N437 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 9355b41557..df97d72b8b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/projects/common-api/src/client/java/dan200/computercraft/api/client/TransformedModel.java b/projects/common-api/src/client/java/dan200/computercraft/api/client/TransformedModel.java index a632920b41..8ce025488a 100644 --- a/projects/common-api/src/client/java/dan200/computercraft/api/client/TransformedModel.java +++ b/projects/common-api/src/client/java/dan200/computercraft/api/client/TransformedModel.java @@ -60,7 +60,7 @@ public static TransformedModel of(ResourceLocation location) { } public static TransformedModel of(ItemStack item, Transformation transform) { - var model = Minecraft.getInstance().getItemRenderer().getItemModelShaper().getItemModel(item); + var model = Minecraft.getInstance().getItemRenderer().getModel(item, null, null, 0); return new TransformedModel(model, transform); } } diff --git a/projects/common-api/src/client/java/dan200/computercraft/api/client/turtle/TurtleUpgradeModeller.java b/projects/common-api/src/client/java/dan200/computercraft/api/client/turtle/TurtleUpgradeModeller.java index 4adfc8d919..5b9a4e91eb 100644 --- a/projects/common-api/src/client/java/dan200/computercraft/api/client/turtle/TurtleUpgradeModeller.java +++ b/projects/common-api/src/client/java/dan200/computercraft/api/client/turtle/TurtleUpgradeModeller.java @@ -48,7 +48,7 @@ public interface TurtleUpgradeModeller { * by other means. * * @return A list of models that this modeller depends on. - * @see UnbakedModel#getDependencies() + * @see UnbakedModel#resolveDependencies(UnbakedModel.Resolver) */ default Stream getDependencies() { return Stream.of(); diff --git a/projects/common-api/src/client/java/dan200/computercraft/api/client/turtle/TurtleUpgradeModellers.java b/projects/common-api/src/client/java/dan200/computercraft/api/client/turtle/TurtleUpgradeModellers.java index 644c0a65a0..71066c3340 100644 --- a/projects/common-api/src/client/java/dan200/computercraft/api/client/turtle/TurtleUpgradeModellers.java +++ b/projects/common-api/src/client/java/dan200/computercraft/api/client/turtle/TurtleUpgradeModellers.java @@ -38,7 +38,7 @@ private static final class UpgradeItemModeller implements TurtleUpgradeModeller< @Override public TransformedModel getModel(ITurtleUpgrade upgrade, @Nullable ITurtleAccess turtle, TurtleSide side, DataComponentPatch data) { var stack = upgrade.getUpgradeItem(data); - var model = Minecraft.getInstance().getItemRenderer().getItemModelShaper().getItemModel(stack); + var model = Minecraft.getInstance().getItemRenderer().getModel(stack, null, null, 0); if (stack.hasFoil()) model = ClientPlatformHelper.get().createdFoiledModel(model); return new TransformedModel(model, side == TurtleSide.LEFT ? leftTransform : rightTransform); } diff --git a/projects/common/build.gradle.kts b/projects/common/build.gradle.kts index 952639cbf5..44a4c90749 100644 --- a/projects/common/build.gradle.kts +++ b/projects/common/build.gradle.kts @@ -15,6 +15,12 @@ sourceSets { main { resources.srcDir("src/generated/resources") } + client { + java { + exclude("dan200/computercraft/client/integration/emi") + exclude("dan200/computercraft/client/integration/jei") + } + } } minecraft { diff --git a/projects/common/src/client/java/dan200/computercraft/client/ClientHooks.java b/projects/common/src/client/java/dan200/computercraft/client/ClientHooks.java index bd45f9310a..2bcae77d9f 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/ClientHooks.java +++ b/projects/common/src/client/java/dan200/computercraft/client/ClientHooks.java @@ -11,7 +11,6 @@ import dan200.computercraft.client.render.CableHighlightRenderer; import dan200.computercraft.client.render.PocketItemRenderer; import dan200.computercraft.client.render.PrintoutItemRenderer; -import dan200.computercraft.client.render.monitor.MonitorBlockEntityRenderer; import dan200.computercraft.client.render.monitor.MonitorHighlightRenderer; import dan200.computercraft.client.render.monitor.MonitorRenderState; import dan200.computercraft.client.sound.SpeakerManager; @@ -29,11 +28,11 @@ import net.minecraft.client.Camera; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.entity.state.ItemFrameRenderState; import net.minecraft.client.sounds.AudioStream; import net.minecraft.client.sounds.SoundEngine; import net.minecraft.core.BlockPos; import net.minecraft.world.InteractionHand; -import net.minecraft.world.entity.decoration.ItemFrame; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.BlockHitResult; @@ -88,7 +87,7 @@ public static boolean onRenderHeldItem( return false; } - public static boolean onRenderItemFrame(PoseStack transform, MultiBufferSource render, ItemFrame frame, ItemStack stack, int light) { + public static boolean onRenderItemFrame(PoseStack transform, MultiBufferSource render, ItemFrameRenderState frame, ItemStack stack, int light) { if (stack.getItem() instanceof PrintoutItem) { PrintoutItemRenderer.onRenderInFrame(transform, render, frame, stack, light); return true; @@ -132,17 +131,6 @@ private static void addTurtleUpgrade(Consumer out, TurtleBlockEntity tur if (upgrade != null) out.accept(String.format("Upgrade[%s]: %s", side, upgrade.holder().key().location())); } - /** - * Add additional information about the game to the debug screen. - * - * @param addText A callback which adds a single line of text. - */ - public static void addGameDebugInfo(Consumer addText) { - if (MonitorBlockEntityRenderer.hasRenderedThisFrame() && Minecraft.getInstance().getDebugOverlay().showDebugScreen()) { - addText.accept("[CC:T] Monitor renderer: " + MonitorBlockEntityRenderer.currentRenderer()); - } - } - public static @Nullable BlockState getBlockBreakingState(BlockState state, BlockPos pos) { // Only apply to cables which have both a cable and modem if (state.getBlock() != ModRegistry.Blocks.CABLE.get() diff --git a/projects/common/src/client/java/dan200/computercraft/client/ClientRegistry.java b/projects/common/src/client/java/dan200/computercraft/client/ClientRegistry.java index 46711d7586..3dfb924441 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/ClientRegistry.java +++ b/projects/common/src/client/java/dan200/computercraft/client/ClientRegistry.java @@ -14,7 +14,6 @@ import dan200.computercraft.client.gui.*; import dan200.computercraft.client.pocket.ClientPocketComputers; import dan200.computercraft.client.render.CustomLecternRenderer; -import dan200.computercraft.client.render.RenderTypes; import dan200.computercraft.client.render.TurtleBlockEntityRenderer; import dan200.computercraft.client.render.monitor.MonitorBlockEntityRenderer; import dan200.computercraft.client.turtle.TurtleModemModeller; @@ -34,7 +33,6 @@ import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.inventory.MenuAccess; import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.renderer.ShaderInstance; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; import net.minecraft.client.renderer.blockentity.BlockEntityRenderers; import net.minecraft.client.renderer.item.ClampedItemPropertyFunction; @@ -42,8 +40,7 @@ import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.packs.resources.PreparableReloadListener; -import net.minecraft.server.packs.resources.ResourceProvider; -import net.minecraft.util.FastColor; +import net.minecraft.util.ARGB; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.MenuType; @@ -54,7 +51,6 @@ import javax.annotation.Nullable; import java.io.File; -import java.io.IOException; import java.util.Collection; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -182,7 +178,7 @@ private static int getPocketColour(ItemStack stack, int layer) { case 1 -> DyedItemColor.getOrDefault(stack, -1); // Frame colour case 2 -> { // Light colour var computer = ClientPocketComputers.get(stack); - yield computer == null || computer.getLightState() == -1 ? Colour.BLACK.getARGB() : FastColor.ARGB32.opaque(computer.getLightState()); + yield computer == null || computer.getLightState() == -1 ? Colour.BLACK.getARGB() : ARGB.opaque(computer.getLightState()); } }; } @@ -191,10 +187,6 @@ private static int getTurtleColour(ItemStack stack, int layer) { return layer == 0 ? DyedItemColor.getOrDefault(stack, -1) : -1; } - public static void registerShaders(ResourceProvider resources, BiConsumer> load) throws IOException { - RenderTypes.registerShaders(resources, load); - } - private record UnclampedPropertyFunction( ClampedItemPropertyFunction function ) implements ClampedItemPropertyFunction { diff --git a/projects/common/src/client/java/dan200/computercraft/client/gui/AbstractComputerScreen.java b/projects/common/src/client/java/dan200/computercraft/client/gui/AbstractComputerScreen.java index 6e4f39020d..9d8485bedf 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/gui/AbstractComputerScreen.java +++ b/projects/common/src/client/java/dan200/computercraft/client/gui/AbstractComputerScreen.java @@ -99,7 +99,7 @@ public void containerTick() { if (uploadNagDeadline != Long.MAX_VALUE && Util.getNanos() >= uploadNagDeadline) { new ItemToast(minecraft(), displayStack, NO_RESPONSE_TITLE, NO_RESPONSE_MSG, ItemToast.TRANSFER_NO_RESPONSE_TOKEN) - .showOrReplace(minecraft().getToasts()); + .showOrReplace(minecraft().getToastManager()); uploadNagDeadline = Long.MAX_VALUE; } } diff --git a/projects/common/src/client/java/dan200/computercraft/client/gui/ComputerScreen.java b/projects/common/src/client/java/dan200/computercraft/client/gui/ComputerScreen.java index b398da3421..45896e1516 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/gui/ComputerScreen.java +++ b/projects/common/src/client/java/dan200/computercraft/client/gui/ComputerScreen.java @@ -7,7 +7,6 @@ import dan200.computercraft.client.gui.widgets.ComputerSidebar; import dan200.computercraft.client.gui.widgets.TerminalWidget; import dan200.computercraft.client.render.ComputerBorderRenderer; -import dan200.computercraft.client.render.RenderTypes; import dan200.computercraft.client.render.SpriteRenderer; import dan200.computercraft.shared.computer.inventory.AbstractComputerMenu; import net.minecraft.client.gui.GuiGraphics; @@ -40,14 +39,14 @@ protected TerminalWidget createTerminal() { public void renderBg(GuiGraphics graphics, float partialTicks, int mouseX, int mouseY) { // Draw a border around the terminal var terminal = getTerminal(); - var spriteRenderer = SpriteRenderer.createForGui(graphics, RenderTypes.GUI_SPRITES); - var computerTextures = GuiSprites.getComputerTextures(family); - - ComputerBorderRenderer.render( - spriteRenderer, computerTextures, - terminal.getX(), terminal.getY(), terminal.getWidth(), terminal.getHeight(), false - ); - ComputerSidebar.renderBackground(spriteRenderer, computerTextures, leftPos, topPos + sidebarYOffset); - graphics.flush(); // Flush to ensure background textures are drawn before foreground. + + SpriteRenderer.inGui(graphics, spriteRenderer -> { + var computerTextures = GuiSprites.getComputerTextures(family); + ComputerBorderRenderer.render( + spriteRenderer, computerTextures, + terminal.getX(), terminal.getY(), terminal.getWidth(), terminal.getHeight(), false + ); + ComputerSidebar.renderBackground(spriteRenderer, computerTextures, leftPos, topPos + sidebarYOffset); + }); } } diff --git a/projects/common/src/client/java/dan200/computercraft/client/gui/DiskDriveScreen.java b/projects/common/src/client/java/dan200/computercraft/client/gui/DiskDriveScreen.java index 70a8ed8dba..b9f8d18849 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/gui/DiskDriveScreen.java +++ b/projects/common/src/client/java/dan200/computercraft/client/gui/DiskDriveScreen.java @@ -7,6 +7,7 @@ import dan200.computercraft.shared.peripheral.diskdrive.DiskDriveMenu; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.client.renderer.RenderType; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.player.Inventory; @@ -23,7 +24,7 @@ public DiskDriveScreen(DiskDriveMenu container, Inventory player, Component titl @Override protected void renderBg(GuiGraphics graphics, float partialTicks, int mouseX, int mouseY) { - graphics.blit(BACKGROUND, leftPos, topPos, 0, 0, imageWidth, imageHeight); + graphics.blit(RenderType::guiTextured, BACKGROUND, leftPos, topPos, 0, 0, imageWidth, imageHeight, 256, 256); } @Override diff --git a/projects/common/src/client/java/dan200/computercraft/client/gui/GuiSprites.java b/projects/common/src/client/java/dan200/computercraft/client/gui/GuiSprites.java index e6025c2216..21bebbd72b 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/gui/GuiSprites.java +++ b/projects/common/src/client/java/dan200/computercraft/client/gui/GuiSprites.java @@ -35,8 +35,8 @@ public final class GuiSprites extends TextureAtlasHolder { private static ButtonTextures button(String name) { return new ButtonTextures( - ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "gui/buttons/" + name), - ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "gui/buttons/" + name + "_hover") + ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "buttons/" + name), + ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "buttons/" + name + "_hover") ); } @@ -97,12 +97,8 @@ public static ComputerTextures getComputerTextures(ComputerFamily family) { * @param active The texture for the button when it is active (hovered or focused). */ public record ButtonTextures(ResourceLocation normal, ResourceLocation active) { - public TextureAtlasSprite get(boolean active) { - return GuiSprites.get(active ? this.active : normal); - } - - public Stream textures() { - return Stream.of(normal, active); + public ResourceLocation get(boolean active) { + return active ? this.active : normal; } } diff --git a/projects/common/src/client/java/dan200/computercraft/client/gui/ItemToast.java b/projects/common/src/client/java/dan200/computercraft/client/gui/ItemToast.java index b3bfd42949..9adad3c342 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/gui/ItemToast.java +++ b/projects/common/src/client/java/dan200/computercraft/client/gui/ItemToast.java @@ -5,9 +5,11 @@ package dan200.computercraft.client.gui; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.toasts.Toast; -import net.minecraft.client.gui.components.toasts.ToastComponent; +import net.minecraft.client.gui.components.toasts.ToastManager; +import net.minecraft.client.renderer.RenderType; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.FormattedCharSequence; @@ -35,8 +37,9 @@ public class ItemToast implements Toast { private final Object token; private final int width; - private boolean isNew = true; - private long firstDisplay; + private boolean changed = true; + private long lastChanged; + private Visibility visibility = Visibility.HIDE; public ItemToast(Minecraft minecraft, ItemStack stack, Component title, Component message, Object token) { this.stack = stack; @@ -48,10 +51,10 @@ public ItemToast(Minecraft minecraft, ItemStack stack, Component title, Componen width = Math.max(MAX_LINE_SIZE, this.message.stream().mapToInt(font::width).max().orElse(MAX_LINE_SIZE)) + MARGIN * 3 + IMAGE_SIZE; } - public void showOrReplace(ToastComponent toasts) { + public void showOrReplace(ToastManager toasts) { var existing = toasts.getToast(ItemToast.class, getToken()); if (existing != null) { - existing.isNew = true; + existing.changed = true; } else { toasts.addToast(this); } @@ -73,28 +76,22 @@ public Object getToken() { } @Override - public Visibility render(GuiGraphics graphics, ToastComponent component, long time) { - if (isNew) { + public Visibility getWantedVisibility() { + return visibility; + } - firstDisplay = time; - isNew = false; + @Override + public void update(ToastManager toastManager, long time) { + if (changed) { + lastChanged = time; + changed = false; } + visibility = time - lastChanged < DISPLAY_TIME * toastManager.getNotificationDisplayTimeMultiplier() ? Visibility.SHOW : Visibility.HIDE; + } - if (width == 160 && message.size() <= 1) { - graphics.blitSprite(TEXTURE, 0, 0, width, height()); - } else { - - var height = height(); - - var bottom = Math.min(4, height - 28); - renderBackgroundRow(graphics, width, 0, 0, 28); - - for (var i = 28; i < height - bottom; i += 10) { - renderBackgroundRow(graphics, width, 16, i, Math.min(16, height - i - bottom)); - } - - renderBackgroundRow(graphics, width, 32 - bottom, height - bottom, bottom); - } + @Override + public void render(GuiGraphics graphics, Font font, long time) { + graphics.blitSprite(RenderType::guiTextured, TEXTURE, 0, 0, width(), height()); var textX = MARGIN; if (!stack.isEmpty()) { @@ -102,23 +99,9 @@ public Visibility render(GuiGraphics graphics, ToastComponent component, long ti graphics.renderFakeItem(stack, MARGIN, MARGIN + height() / 2 - IMAGE_SIZE); } - graphics.drawString(component.getMinecraft().font, title, textX, MARGIN, 0xff500050, false); + graphics.drawString(font, title, textX, MARGIN, 0xff500050, false); for (var i = 0; i < message.size(); ++i) { - graphics.drawString(component.getMinecraft().font, message.get(i), textX, LINE_SPACING + (i + 1) * LINE_SPACING, 0xff000000, false); - } - - return time - firstDisplay < DISPLAY_TIME ? Visibility.SHOW : Visibility.HIDE; - } - - private static void renderBackgroundRow(GuiGraphics graphics, int x, int u, int y, int height) { - var leftOffset = u == 0 ? 20 : 5; - var rightOffset = Math.min(60, x - leftOffset); - - graphics.blitSprite(TEXTURE, 160, 32, 0, u, 0, y, leftOffset, height); - for (var k = leftOffset; k < x - rightOffset; k += 64) { - graphics.blitSprite(TEXTURE, 160, 32, 32, u, k, y, Math.min(64, x - k - rightOffset), height); + graphics.drawString(font, message.get(i), textX, LINE_SPACING + (i + 1) * LINE_SPACING, 0xff000000, false); } - - graphics.blitSprite(TEXTURE, 160, 32, 160 - rightOffset, u, x - rightOffset, y, rightOffset, height); } } diff --git a/projects/common/src/client/java/dan200/computercraft/client/gui/NoTermComputerScreen.java b/projects/common/src/client/java/dan200/computercraft/client/gui/NoTermComputerScreen.java index 36467a45a3..5472f9245c 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/gui/NoTermComputerScreen.java +++ b/projects/common/src/client/java/dan200/computercraft/client/gui/NoTermComputerScreen.java @@ -67,7 +67,7 @@ public final void tick() { @Override public boolean mouseScrolled(double mouseX, double mouseY, double scrollX, double scrollY) { - Objects.requireNonNull(minecraft().player).getInventory().swapPaint(scrollY); + // FIXME(1.21.2): Objects.requireNonNull(minecraft().player).getInventory().setSelectedHotbarSlot(scrollY); return super.mouseScrolled(mouseX, mouseY, scrollX, scrollY); } diff --git a/projects/common/src/client/java/dan200/computercraft/client/gui/OptionScreen.java b/projects/common/src/client/java/dan200/computercraft/client/gui/OptionScreen.java index 0cf39fa210..1e2c7bd75d 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/gui/OptionScreen.java +++ b/projects/common/src/client/java/dan200/computercraft/client/gui/OptionScreen.java @@ -10,6 +10,7 @@ import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.MultiLineLabel; import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.renderer.RenderType; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; @@ -87,12 +88,13 @@ public void init() { @Override public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { // Render the actual texture. - graphics.blit(BACKGROUND, x, y, 0, 0, innerWidth, PADDING); - graphics.blit(BACKGROUND, + graphics.blit(RenderType::guiTextured, BACKGROUND, x, y, 0, 0, innerWidth, PADDING, 256, 256); + graphics.blit(RenderType::guiTextured, BACKGROUND, x, y + PADDING, 0, PADDING, innerWidth, innerHeight - PADDING * 2, - innerWidth, PADDING + innerWidth, PADDING, + 256, 256 ); - graphics.blit(BACKGROUND, x, y + innerHeight - PADDING, 0, 256 - PADDING, innerWidth, PADDING); + graphics.blit(RenderType::guiTextured, BACKGROUND, x, y + innerHeight - PADDING, 0, 256 - PADDING, innerWidth, PADDING, 256, 256); assertNonNull(messageRenderer).renderLeftAlignedNoShadow(graphics, x + PADDING, y + PADDING, FONT_HEIGHT, 0x404040); super.render(graphics, mouseX, mouseY, partialTicks); diff --git a/projects/common/src/client/java/dan200/computercraft/client/gui/PrinterScreen.java b/projects/common/src/client/java/dan200/computercraft/client/gui/PrinterScreen.java index 70deac9c2d..7710df1f03 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/gui/PrinterScreen.java +++ b/projects/common/src/client/java/dan200/computercraft/client/gui/PrinterScreen.java @@ -7,6 +7,7 @@ import dan200.computercraft.shared.peripheral.printer.PrinterMenu; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.client.renderer.RenderType; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.player.Inventory; @@ -23,9 +24,11 @@ public PrinterScreen(PrinterMenu container, Inventory player, Component title) { @Override protected void renderBg(GuiGraphics graphics, float partialTicks, int mouseX, int mouseY) { - graphics.blit(BACKGROUND, leftPos, topPos, 0, 0, imageWidth, imageHeight); + graphics.blit(RenderType::guiTextured, BACKGROUND, leftPos, topPos, 0, 0, imageWidth, imageHeight, 256, 256); - if (getMenu().isPrinting()) graphics.blit(BACKGROUND, leftPos + 34, topPos + 21, 176, 0, 25, 45); + if (getMenu().isPrinting()) { + graphics.blit(RenderType::guiTextured, BACKGROUND, leftPos + 34, topPos + 21, 176, 0, 25, 45, 256, 256); + } } @Override diff --git a/projects/common/src/client/java/dan200/computercraft/client/gui/PrintoutScreen.java b/projects/common/src/client/java/dan200/computercraft/client/gui/PrintoutScreen.java index 8df70c395a..c8d1608ee4 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/gui/PrintoutScreen.java +++ b/projects/common/src/client/java/dan200/computercraft/client/gui/PrintoutScreen.java @@ -10,6 +10,7 @@ import dan200.computercraft.shared.media.items.PrintoutData; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.client.renderer.LightTexture; import net.minecraft.network.chat.Component; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.inventory.AbstractContainerMenu; @@ -20,7 +21,6 @@ import java.util.Objects; import static dan200.computercraft.client.render.PrintoutRenderer.*; -import static dan200.computercraft.client.render.RenderTypes.FULL_BRIGHT_LIGHTMAP; /** * The GUI for printed pages and books. @@ -116,8 +116,10 @@ protected void renderBg(GuiGraphics graphics, float partialTicks, int mouseX, in graphics.pose().pushPose(); graphics.pose().translate(0, 0, 1); - drawBorder(graphics.pose(), graphics.bufferSource(), leftPos, topPos, 0, page, printout.pages(), printout.book(), FULL_BRIGHT_LIGHTMAP); - drawText(graphics.pose(), graphics.bufferSource(), leftPos + X_TEXT_MARGIN, topPos + Y_TEXT_MARGIN, PrintoutData.LINES_PER_PAGE * page, FULL_BRIGHT_LIGHTMAP, printout.text(), printout.colour()); + graphics.drawSpecial(bufferSource -> { + drawBorder(graphics.pose(), bufferSource, leftPos, topPos, 0, page, printout.pages(), printout.book(), LightTexture.FULL_BRIGHT); + drawText(graphics.pose(), bufferSource, leftPos + X_TEXT_MARGIN, topPos + Y_TEXT_MARGIN, PrintoutData.LINES_PER_PAGE * page, LightTexture.FULL_BRIGHT, printout.text(), printout.colour()); + }); graphics.pose().popPose(); } diff --git a/projects/common/src/client/java/dan200/computercraft/client/gui/TurtleScreen.java b/projects/common/src/client/java/dan200/computercraft/client/gui/TurtleScreen.java index 381bd62197..2aae0b5e9b 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/gui/TurtleScreen.java +++ b/projects/common/src/client/java/dan200/computercraft/client/gui/TurtleScreen.java @@ -7,12 +7,12 @@ import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.client.gui.widgets.ComputerSidebar; import dan200.computercraft.client.gui.widgets.TerminalWidget; -import dan200.computercraft.client.render.RenderTypes; import dan200.computercraft.client.render.SpriteRenderer; import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.computer.inventory.AbstractComputerMenu; import dan200.computercraft.shared.turtle.inventory.TurtleMenu; import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.renderer.RenderType; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.player.Inventory; @@ -26,6 +26,9 @@ public class TurtleScreen extends AbstractComputerScreen { private static final ResourceLocation BACKGROUND_NORMAL = ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "textures/gui/turtle_normal.png"); private static final ResourceLocation BACKGROUND_ADVANCED = ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "textures/gui/turtle_advanced.png"); + private static final ResourceLocation SELECTED_NORMAL = ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "turtle_normal_selected_slot"); + private static final ResourceLocation SELECTED_ADVANCED = ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "turtle_advanced_selected_slot"); + private static final int TEX_WIDTH = 278; private static final int TEX_HEIGHT = 217; @@ -46,23 +49,28 @@ protected TerminalWidget createTerminal() { @Override protected void renderBg(GuiGraphics graphics, float partialTicks, int mouseX, int mouseY) { var advanced = family == ComputerFamily.ADVANCED; - var texture = advanced ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL; - graphics.blit(texture, leftPos + AbstractComputerMenu.SIDEBAR_WIDTH, topPos, 0, 0, 0, TEX_WIDTH, TEX_HEIGHT, FULL_TEX_SIZE, FULL_TEX_SIZE); + graphics.blit( + RenderType::guiTextured, advanced ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL, + leftPos + AbstractComputerMenu.SIDEBAR_WIDTH, topPos, 0, 0, + TEX_WIDTH, TEX_HEIGHT, FULL_TEX_SIZE, FULL_TEX_SIZE + ); // Render selected slot var slot = getMenu().getSelectedSlot(); if (slot >= 0) { var slotX = slot % 4; var slotY = slot / 4; - graphics.blit(texture, - leftPos + TURTLE_START_X - 2 + slotX * 18, topPos + PLAYER_START_Y - 2 + slotY * 18, 0, - 0, 217, 24, 24, FULL_TEX_SIZE, FULL_TEX_SIZE + + graphics.blitSprite( + RenderType::guiTextured, advanced ? SELECTED_ADVANCED : SELECTED_NORMAL, + leftPos + TURTLE_START_X - 2 + slotX * 18, topPos + PLAYER_START_Y - 2 + slotY * 18, + 22, 22 ); } // Render sidebar - var spriteRenderer = SpriteRenderer.createForGui(graphics, RenderTypes.GUI_SPRITES); - ComputerSidebar.renderBackground(spriteRenderer, GuiSprites.getComputerTextures(family), leftPos, topPos + sidebarYOffset); - graphics.flush(); // Flush to ensure background textures are drawn before foreground. + SpriteRenderer.inGui(graphics, spriteRenderer -> + ComputerSidebar.renderBackground(spriteRenderer, GuiSprites.getComputerTextures(family), leftPos, topPos + sidebarYOffset) + ); } } diff --git a/projects/common/src/client/java/dan200/computercraft/client/gui/widgets/DynamicImageButton.java b/projects/common/src/client/java/dan200/computercraft/client/gui/widgets/DynamicImageButton.java index 88f5f02d7c..31a80922b0 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/gui/widgets/DynamicImageButton.java +++ b/projects/common/src/client/java/dan200/computercraft/client/gui/widgets/DynamicImageButton.java @@ -4,14 +4,14 @@ package dan200.computercraft.client.gui.widgets; -import com.mojang.blaze3d.systems.RenderSystem; import it.unimi.dsi.fastutil.booleans.Boolean2ObjectFunction; import net.minecraft.ChatFormatting; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.Tooltip; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.renderer.RenderType; import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; import javax.annotation.Nullable; import java.util.function.Supplier; @@ -21,11 +21,11 @@ * dynamically. */ public class DynamicImageButton extends Button { - private final Boolean2ObjectFunction texture; + private final Boolean2ObjectFunction texture; private final Supplier message; public DynamicImageButton( - int x, int y, int width, int height, Boolean2ObjectFunction texture, OnPress onPress, + int x, int y, int width, int height, Boolean2ObjectFunction texture, OnPress onPress, HintedMessage message ) { this(x, y, width, height, texture, onPress, () -> message); @@ -33,7 +33,7 @@ public DynamicImageButton( public DynamicImageButton( int x, int y, int width, int height, - Boolean2ObjectFunction texture, + Boolean2ObjectFunction texture, OnPress onPress, Supplier message ) { super(x, y, width, height, Component.empty(), onPress, DEFAULT_NARRATION); @@ -48,10 +48,7 @@ public void renderWidget(GuiGraphics graphics, int mouseX, int mouseY, float par setTooltip(message.tooltip()); var texture = this.texture.get(isHoveredOrFocused()); - - RenderSystem.disableDepthTest(); - graphics.blit(getX(), getY(), 0, width, height, texture); - RenderSystem.enableDepthTest(); + graphics.blitSprite(RenderType::guiTextured, texture, getX(), getY(), width, height); } public record HintedMessage(Component message, Tooltip tooltip) { diff --git a/projects/common/src/client/java/dan200/computercraft/client/gui/widgets/TerminalWidget.java b/projects/common/src/client/java/dan200/computercraft/client/gui/widgets/TerminalWidget.java index 50a0f35d46..0c35fa33b7 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/gui/widgets/TerminalWidget.java +++ b/projects/common/src/client/java/dan200/computercraft/client/gui/widgets/TerminalWidget.java @@ -4,7 +4,6 @@ package dan200.computercraft.client.gui.widgets; -import dan200.computercraft.client.render.RenderTypes; import dan200.computercraft.client.render.text.FixedWidthFontRenderer; import dan200.computercraft.core.terminal.Terminal; import dan200.computercraft.core.util.StringUtil; @@ -257,12 +256,12 @@ public void setFocused(boolean focused) { public void renderWidget(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { if (!visible) return; - var emitter = FixedWidthFontRenderer.toVertexConsumer(graphics.pose(), graphics.bufferSource().getBuffer(RenderTypes.TERMINAL)); - - FixedWidthFontRenderer.drawTerminal( - emitter, - (float) innerX, (float) innerY, terminal, (float) MARGIN, (float) MARGIN, (float) MARGIN, (float) MARGIN - ); + graphics.drawSpecial(bufferSource -> { + FixedWidthFontRenderer.drawTerminal( + FixedWidthFontRenderer.toVertexConsumer(graphics.pose(), bufferSource.getBuffer(FixedWidthFontRenderer.TERMINAL_TEXT)), + (float) innerX, (float) innerY, terminal, (float) MARGIN, (float) MARGIN, (float) MARGIN, (float) MARGIN + ); + }); } @Override diff --git a/projects/common/src/client/java/dan200/computercraft/client/integration/IrisShaderMod.java b/projects/common/src/client/java/dan200/computercraft/client/integration/IrisShaderMod.java index a8241d6437..e9d5046aef 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/integration/IrisShaderMod.java +++ b/projects/common/src/client/java/dan200/computercraft/client/integration/IrisShaderMod.java @@ -5,17 +5,18 @@ package dan200.computercraft.client.integration; import com.google.auto.service.AutoService; +import com.mojang.blaze3d.vertex.ByteBufferBuilder; import com.mojang.blaze3d.vertex.VertexFormat; -import dan200.computercraft.client.render.RenderTypes; import dan200.computercraft.client.render.text.DirectFixedWidthFontRenderer; import dan200.computercraft.shared.platform.PlatformHelper; import net.irisshaders.iris.api.v0.IrisApi; import net.irisshaders.iris.api.v0.IrisTextVertexSink; -import net.minecraft.util.FastColor; +import net.minecraft.client.renderer.LightTexture; +import org.lwjgl.system.MemoryUtil; +import javax.annotation.Nullable; import java.nio.ByteBuffer; import java.util.Optional; -import java.util.function.IntFunction; @AutoService(ShaderMod.Provider.class) public class IrisShaderMod implements ShaderMod.Provider { @@ -31,7 +32,7 @@ public boolean isRenderingShadowPass() { } @Override - public DirectFixedWidthFontRenderer.QuadEmitter getQuadEmitter(int vertexCount, IntFunction makeBuffer) { + public DirectFixedWidthFontRenderer.QuadEmitter getQuadEmitter(int vertexCount, ByteBufferBuilder makeBuffer) { return IrisApi.getInstance().getMinorApiRevision() >= 1 ? new IrisQuadEmitter(vertexCount, makeBuffer) : super.getQuadEmitter(vertexCount, makeBuffer); @@ -39,24 +40,23 @@ public DirectFixedWidthFontRenderer.QuadEmitter getQuadEmitter(int vertexCount, private static final class IrisQuadEmitter implements DirectFixedWidthFontRenderer.QuadEmitter { private final IrisTextVertexSink sink; + private @Nullable ByteBuffer buffer; - private IrisQuadEmitter(int vertexCount, IntFunction makeBuffer) { - sink = IrisApi.getInstance().createTextVertexSink(vertexCount, makeBuffer); + private IrisQuadEmitter(int vertexCount, ByteBufferBuilder builder) { + sink = IrisApi.getInstance().createTextVertexSink(vertexCount, i -> { + if (buffer != null) throw new IllegalStateException("Allocated multiple buffers"); + return buffer = MemoryUtil.memByteBuffer(builder.reserve(i), i); + }); } @Override - public VertexFormat format() { - return sink.getUnderlyingVertexFormat(); - } - - @Override - public ByteBuffer buffer() { - return sink.getUnderlyingByteBuffer(); + public void quad(float x1, float y1, float x2, float y2, float z, int colour, float u1, float v1, float u2, float v2) { + sink.quad(x1, y1, x2, y2, z, colour, u1, v1, u2, v2, LightTexture.FULL_BRIGHT); } @Override - public void quad(float x1, float y1, float x2, float y2, float z, int colour, float u1, float v1, float u2, float v2) { - sink.quad(x1, y1, x2, y2, z, FastColor.ABGR32.fromArgb32(colour), u1, v1, u2, v2, RenderTypes.FULL_BRIGHT_LIGHTMAP); + public VertexFormat format() { + return sink.getUnderlyingVertexFormat(); } } } diff --git a/projects/common/src/client/java/dan200/computercraft/client/integration/ShaderMod.java b/projects/common/src/client/java/dan200/computercraft/client/integration/ShaderMod.java index 9c6a236ad8..122f324890 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/integration/ShaderMod.java +++ b/projects/common/src/client/java/dan200/computercraft/client/integration/ShaderMod.java @@ -4,14 +4,12 @@ package dan200.computercraft.client.integration; -import dan200.computercraft.client.render.RenderTypes; +import com.mojang.blaze3d.vertex.ByteBufferBuilder; +import com.mojang.blaze3d.vertex.VertexBuffer; import dan200.computercraft.client.render.text.DirectFixedWidthFontRenderer; -import dan200.computercraft.client.render.vbo.DirectVertexBuffer; -import java.nio.ByteBuffer; import java.util.Optional; import java.util.ServiceLoader; -import java.util.function.IntFunction; /** * Find the currently loaded shader mod (if present) and provides utilities for interacting with it. @@ -31,16 +29,14 @@ public boolean isRenderingShadowPass() { } /** - * Get an appropriate quad emitter for use with {@link DirectVertexBuffer} and {@link DirectFixedWidthFontRenderer} . + * Get an appropriate quad emitter for use with {@link VertexBuffer} and {@link DirectFixedWidthFontRenderer} . * * @param vertexCount The number of vertices. - * @param makeBuffer A function to allocate a temporary buffer. + * @param buffer A function to allocate a temporary buffer. * @return The quad emitter. */ - public DirectFixedWidthFontRenderer.QuadEmitter getQuadEmitter(int vertexCount, IntFunction makeBuffer) { - return new DirectFixedWidthFontRenderer.ByteBufferEmitter( - makeBuffer.apply(RenderTypes.TERMINAL.format().getVertexSize() * vertexCount * 4) - ); + public DirectFixedWidthFontRenderer.QuadEmitter getQuadEmitter(int vertexCount, ByteBufferBuilder buffer) { + return new DirectFixedWidthFontRenderer.ByteBufferEmitter(buffer); } public interface Provider { diff --git a/projects/common/src/client/java/dan200/computercraft/client/model/turtle/ModelTransformer.java b/projects/common/src/client/java/dan200/computercraft/client/model/turtle/ModelTransformer.java index 72c7e3bd5e..3213c376d3 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/model/turtle/ModelTransformer.java +++ b/projects/common/src/client/java/dan200/computercraft/client/model/turtle/ModelTransformer.java @@ -80,7 +80,7 @@ private BakedQuad transformQuad(BakedQuad quad) { } var direction = Direction.rotate(transformation, quad.getDirection()); - return new BakedQuad(outputData, quad.getTintIndex(), direction, quad.getSprite(), quad.isShade()); + return new BakedQuad(outputData, quad.getTintIndex(), direction, quad.getSprite(), quad.isShade(), 0); } public static int getVertexOffset(int vertex, boolean invert) { diff --git a/projects/common/src/client/java/dan200/computercraft/client/model/turtle/TurtleModelParts.java b/projects/common/src/client/java/dan200/computercraft/client/model/turtle/TurtleModelParts.java index a6ef119ca8..977c673fcd 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/model/turtle/TurtleModelParts.java +++ b/projects/common/src/client/java/dan200/computercraft/client/model/turtle/TurtleModelParts.java @@ -107,8 +107,7 @@ private Combination getCombination(ItemStack stack) { } private List buildModel(Combination combo) { - var mc = Minecraft.getInstance(); - var modelManager = mc.getItemRenderer().getItemModelShaper().getModelManager(); + var modelManager = Minecraft.getInstance().getModelManager(); var transformation = combo.flip ? flip : identity; var parts = new ArrayList(4); diff --git a/projects/common/src/client/java/dan200/computercraft/client/platform/ClientNetworkContextImpl.java b/projects/common/src/client/java/dan200/computercraft/client/platform/ClientNetworkContextImpl.java index 45fc090a20..7b8e3553cc 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/platform/ClientNetworkContextImpl.java +++ b/projects/common/src/client/java/dan200/computercraft/client/platform/ClientNetworkContextImpl.java @@ -22,11 +22,13 @@ import net.minecraft.client.Minecraft; import net.minecraft.core.BlockPos; import net.minecraft.core.Holder; +import net.minecraft.core.registries.Registries; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.JukeboxSong; import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.LevelEvent; import javax.annotation.Nullable; import java.util.UUID; @@ -62,10 +64,14 @@ public void handleMonitorData(BlockPos pos, @Nullable TerminalState terminal) { @Override public void handlePlayRecord(BlockPos pos, @Nullable Holder song) { + var level = Minecraft.getInstance().level; + if (level == null) return; + if (song == null) { - Minecraft.getInstance().levelRenderer.stopJukeboxSongAndNotifyNearby(pos); + level.levelEvent(LevelEvent.SOUND_STOP_JUKEBOX_SONG, pos, 0); } else { - Minecraft.getInstance().levelRenderer.playJukeboxSong(song, pos); + var id = level.registryAccess().lookupOrThrow(Registries.JUKEBOX_SONG).getIdOrThrow(song.value()); + level.levelEvent(LevelEvent.SOUND_PLAY_JUKEBOX_SONG, pos, id); } } diff --git a/projects/common/src/client/java/dan200/computercraft/client/render/ModelRenderer.java b/projects/common/src/client/java/dan200/computercraft/client/render/ModelRenderer.java index 4e40194306..1905bfae21 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/render/ModelRenderer.java +++ b/projects/common/src/client/java/dan200/computercraft/client/render/ModelRenderer.java @@ -70,7 +70,7 @@ private static void putBulkQuad(VertexConsumer buffer, PoseStack.Pose pose, Bake var matrix = pose.pose(); // It's a little dubious to transform using this matrix rather than the normal matrix. This mirrors the logic in // Direction.rotate (so not out of nowhere!), but is a little suspicious. - var dirNormal = quad.getDirection().getNormal(); + var dirNormal = quad.getDirection().getUnitVec3i(); var vector = new Vector4f(); matrix.transform(dirNormal.getX(), dirNormal.getY(), dirNormal.getZ(), 0.0f, vector).normalize(); diff --git a/projects/common/src/client/java/dan200/computercraft/client/render/PocketItemRenderer.java b/projects/common/src/client/java/dan200/computercraft/client/render/PocketItemRenderer.java index 60eaa1bcdd..6fd55cf315 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/render/PocketItemRenderer.java +++ b/projects/common/src/client/java/dan200/computercraft/client/render/PocketItemRenderer.java @@ -13,8 +13,10 @@ import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.config.Config; import dan200.computercraft.shared.pocket.items.PocketComputerItem; +import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.util.FastColor; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.util.ARGB; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.component.DyedItemColor; import org.joml.Matrix4f; @@ -72,7 +74,7 @@ protected void renderItem(PoseStack transform, MultiBufferSource bufferSource, I var lightColour = computer == null || computer.getLightState() == -1 ? Colour.BLACK.getHex() : computer.getLightState(); renderLight(transform, bufferSource, lightColour, width, height); - var quadEmitter = FixedWidthFontRenderer.toVertexConsumer(transform, bufferSource.getBuffer(RenderTypes.TERMINAL)); + var quadEmitter = FixedWidthFontRenderer.toVertexConsumer(transform, bufferSource.getBuffer(FixedWidthFontRenderer.TERMINAL_TEXT)); if (terminal == null) { FixedWidthFontRenderer.drawEmptyTerminal(quadEmitter, 0, 0, width, height); } else { @@ -89,16 +91,16 @@ private static void renderFrame(Matrix4f transform, MultiBufferSource render, Co var g = (colour >>> 8) & 0xFF; var b = colour & 0xFF; - var spriteRenderer = new SpriteRenderer(transform, render.getBuffer(RenderTypes.GUI_SPRITES), 0, light, r, g, b); + var spriteRenderer = new SpriteRenderer(transform, render.getBuffer(RenderType.text(GuiSprites.TEXTURE)), 0, light, r, g, b); ComputerBorderRenderer.render(spriteRenderer, texture, 0, 0, width, height, true); } private static void renderLight(PoseStack transform, MultiBufferSource render, int colour, int width, int height) { - var buffer = render.getBuffer(RenderTypes.TERMINAL); + var buffer = render.getBuffer(FixedWidthFontRenderer.TERMINAL_TEXT); FixedWidthFontRenderer.drawQuad( FixedWidthFontRenderer.toVertexConsumer(transform, buffer), width - LIGHT_HEIGHT * 2, height + BORDER / 2.0f, 0.001f, LIGHT_HEIGHT * 2, LIGHT_HEIGHT, - FastColor.ARGB32.opaque(colour), RenderTypes.FULL_BRIGHT_LIGHTMAP + ARGB.opaque(colour), LightTexture.FULL_BRIGHT ); } } diff --git a/projects/common/src/client/java/dan200/computercraft/client/render/PrintoutItemRenderer.java b/projects/common/src/client/java/dan200/computercraft/client/render/PrintoutItemRenderer.java index 1a4fa829b0..9e6a2046f6 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/render/PrintoutItemRenderer.java +++ b/projects/common/src/client/java/dan200/computercraft/client/render/PrintoutItemRenderer.java @@ -10,8 +10,7 @@ import dan200.computercraft.shared.media.items.PrintoutData; import dan200.computercraft.shared.media.items.PrintoutItem; import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.decoration.ItemFrame; +import net.minecraft.client.renderer.entity.state.ItemFrameRenderState; import net.minecraft.world.item.ItemStack; import static dan200.computercraft.client.render.PrintoutRenderer.*; @@ -38,14 +37,14 @@ protected void renderItem(PoseStack transform, MultiBufferSource render, ItemSta drawPrintout(transform, render, stack, light); } - public static void onRenderInFrame(PoseStack transform, MultiBufferSource render, ItemFrame frame, ItemStack stack, int packedLight) { + public static void onRenderInFrame(PoseStack transform, MultiBufferSource render, ItemFrameRenderState frame, ItemStack stack, int packedLight) { // Move a little bit forward to ensure we're not clipping with the frame transform.translate(0.0f, 0.0f, -0.001f); transform.mulPose(Axis.ZP.rotationDegrees(180f)); transform.scale(0.95f, 0.95f, -0.95f); transform.translate(-0.5f, -0.5f, 0.0f); - var light = frame.getType() == EntityType.GLOW_ITEM_FRAME ? 0xf000d2 : packedLight; // See getLightVal. + var light = frame.isGlowFrame ? 0xf000d2 : packedLight; // See getLightVal. drawPrintout(transform, render, stack, light); } diff --git a/projects/common/src/client/java/dan200/computercraft/client/render/PrintoutRenderer.java b/projects/common/src/client/java/dan200/computercraft/client/render/PrintoutRenderer.java index 68bbfaacf3..821e859e4d 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/render/PrintoutRenderer.java +++ b/projects/common/src/client/java/dan200/computercraft/client/render/PrintoutRenderer.java @@ -11,6 +11,8 @@ import dan200.computercraft.core.terminal.TextBuffer; import dan200.computercraft.shared.media.items.PrintoutData; import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.resources.ResourceLocation; import org.joml.Matrix4f; import java.util.List; @@ -23,6 +25,12 @@ * {@linkplain PrintoutItemRenderer in-hand/item frame printouts}. */ public final class PrintoutRenderer { + /** + * Printout's background texture. {@link RenderType#text(ResourceLocation)} is a little questionable, but + * it is what maps use, so should behave the same as vanilla in both item frames and in-hand. + */ + private static final RenderType BACKGROUND = RenderType.text(ResourceLocation.fromNamespaceAndPath("computercraft", "textures/gui/printout.png")); + private static final float BG_SIZE = 256.0f; /** @@ -62,7 +70,7 @@ private PrintoutRenderer() { } public static void drawText(PoseStack transform, MultiBufferSource bufferSource, int x, int y, int start, int light, TextBuffer[] text, TextBuffer[] colours) { - var buffer = bufferSource.getBuffer(RenderTypes.PRINTOUT_TEXT); + var buffer = bufferSource.getBuffer(FixedWidthFontRenderer.TERMINAL_TEXT); var emitter = FixedWidthFontRenderer.toVertexConsumer(transform, buffer); for (var line = 0; line < LINES_PER_PAGE && line < text.length; line++) { FixedWidthFontRenderer.drawString(emitter, @@ -73,7 +81,7 @@ public static void drawText(PoseStack transform, MultiBufferSource bufferSource, } public static void drawText(PoseStack transform, MultiBufferSource bufferSource, int x, int y, int start, int light, List lines) { - var buffer = bufferSource.getBuffer(RenderTypes.PRINTOUT_TEXT); + var buffer = bufferSource.getBuffer(FixedWidthFontRenderer.TERMINAL_TEXT); var emitter = FixedWidthFontRenderer.toVertexConsumer(transform, buffer); for (var line = 0; line < LINES_PER_PAGE && line < lines.size(); line++) { var lineContents = lines.get(start + line); @@ -90,7 +98,7 @@ public static void drawBorder(PoseStack transform, MultiBufferSource bufferSourc var leftPages = page; var rightPages = pages - page - 1; - var buffer = bufferSource.getBuffer(RenderTypes.PRINTOUT_BACKGROUND); + var buffer = bufferSource.getBuffer(BACKGROUND); if (isBook) { // Border diff --git a/projects/common/src/client/java/dan200/computercraft/client/render/RenderTypes.java b/projects/common/src/client/java/dan200/computercraft/client/render/RenderTypes.java deleted file mode 100644 index 3868c472d9..0000000000 --- a/projects/common/src/client/java/dan200/computercraft/client/render/RenderTypes.java +++ /dev/null @@ -1,102 +0,0 @@ -// SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers -// -// SPDX-License-Identifier: MPL-2.0 - -package dan200.computercraft.client.render; - -import com.mojang.blaze3d.vertex.DefaultVertexFormat; -import com.mojang.blaze3d.vertex.VertexFormat; -import dan200.computercraft.api.ComputerCraftAPI; -import dan200.computercraft.client.gui.GuiSprites; -import dan200.computercraft.client.render.monitor.MonitorTextureBufferShader; -import dan200.computercraft.client.render.text.FixedWidthFontRenderer; -import net.minecraft.client.renderer.GameRenderer; -import net.minecraft.client.renderer.RenderStateShard; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.ShaderInstance; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.packs.resources.ResourceProvider; - -import javax.annotation.Nullable; -import java.io.IOException; -import java.util.Objects; -import java.util.function.BiConsumer; -import java.util.function.Consumer; - -/** - * Shared {@link RenderType}s used throughout the mod. - */ -public class RenderTypes { - public static final int FULL_BRIGHT_LIGHTMAP = (0xF << 4) | (0xF << 20); - - private static @Nullable MonitorTextureBufferShader monitorTboShader; - - /** - * Renders a fullbright terminal. - */ - public static final RenderType TERMINAL = RenderType.text(FixedWidthFontRenderer.FONT); - - /** - * Renders a monitor with the TBO shader. - * - * @see MonitorTextureBufferShader - */ - public static final RenderType MONITOR_TBO = Types.MONITOR_TBO; - - /** - * A variant of {@link #TERMINAL} which uses the lightmap rather than rendering fullbright. - */ - public static final RenderType PRINTOUT_TEXT = RenderType.text(FixedWidthFontRenderer.FONT); - - /** - * Printout's background texture. {@link RenderType#text(ResourceLocation)} is a little questionable, but - * it is what maps use, so should behave the same as vanilla in both item frames and in-hand. - */ - public static final RenderType PRINTOUT_BACKGROUND = RenderType.text(ResourceLocation.fromNamespaceAndPath("computercraft", "textures/gui/printout.png")); - - /** - * Render type for {@linkplain GuiSprites GUI sprites}. - */ - public static final RenderType GUI_SPRITES = RenderType.text(GuiSprites.TEXTURE); - - public static MonitorTextureBufferShader getMonitorTextureBufferShader() { - if (monitorTboShader == null) throw new NullPointerException("MonitorTboShader has not been registered"); - return monitorTboShader; - } - - public static ShaderInstance getTerminalShader() { - return Objects.requireNonNull(GameRenderer.getRendertypeTextShader(), "Text shader has not been registered"); - } - - public static void registerShaders(ResourceProvider resources, BiConsumer> load) throws IOException { - load.accept( - new MonitorTextureBufferShader( - resources, - ComputerCraftAPI.MOD_ID + "/monitor_tbo", - MONITOR_TBO.format() - ), - x -> monitorTboShader = (MonitorTextureBufferShader) x - ); - } - - private static final class Types extends RenderType { - private static final RenderStateShard.TextureStateShard TERM_FONT_TEXTURE = new TextureStateShard( - FixedWidthFontRenderer.FONT, - false, false // blur, minimap - ); - - static final RenderType MONITOR_TBO = RenderType.create( - "monitor_tbo", DefaultVertexFormat.POSITION_TEX, VertexFormat.Mode.TRIANGLE_STRIP, 128, - false, false, // useDelegate, needsSorting - RenderType.CompositeState.builder() - .setTextureState(TERM_FONT_TEXTURE) - .setShaderState(new ShaderStateShard(RenderTypes::getMonitorTextureBufferShader)) - .createCompositeState(false) - ); - - @SuppressWarnings("UnusedMethod") - private Types(String name, VertexFormat format, VertexFormat.Mode mode, int buffer, boolean crumbling, boolean sort, Runnable setup, Runnable teardown) { - super(name, format, mode, buffer, crumbling, sort, setup, teardown); - } - } -} diff --git a/projects/common/src/client/java/dan200/computercraft/client/render/SpriteRenderer.java b/projects/common/src/client/java/dan200/computercraft/client/render/SpriteRenderer.java index bb1a3d02eb..3e39580f01 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/render/SpriteRenderer.java +++ b/projects/common/src/client/java/dan200/computercraft/client/render/SpriteRenderer.java @@ -5,11 +5,15 @@ package dan200.computercraft.client.render; import com.mojang.blaze3d.vertex.VertexConsumer; +import dan200.computercraft.client.gui.GuiSprites; import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import org.joml.Matrix4f; +import java.util.function.Consumer; + /** * A {@link GuiGraphics}-equivalent which is suitable for both rendering in to a GUI and in-world (as part of an entity * renderer). @@ -34,11 +38,11 @@ public SpriteRenderer(Matrix4f transform, VertexConsumer builder, int z, int lig this.b = b; } - public static SpriteRenderer createForGui(GuiGraphics graphics, RenderType renderType) { - return new SpriteRenderer( - graphics.pose().last().pose(), graphics.bufferSource().getBuffer(renderType), - 0, RenderTypes.FULL_BRIGHT_LIGHTMAP, 255, 255, 255 - ); + public static void inGui(GuiGraphics graphics, Consumer renderer) { + graphics.drawSpecial(bufferSource -> renderer.accept(new SpriteRenderer( + graphics.pose().last().pose(), bufferSource.getBuffer(RenderType.guiTextured(GuiSprites.TEXTURE)), + 0, LightTexture.FULL_BRIGHT, 255, 255, 255 + ))); } /** diff --git a/projects/common/src/client/java/dan200/computercraft/client/render/TurtleBlockEntityRenderer.java b/projects/common/src/client/java/dan200/computercraft/client/render/TurtleBlockEntityRenderer.java index 03c2635aa7..94afa48d4d 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/render/TurtleBlockEntityRenderer.java +++ b/projects/common/src/client/java/dan200/computercraft/client/render/TurtleBlockEntityRenderer.java @@ -22,8 +22,9 @@ import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; import net.minecraft.client.resources.model.BakedModel; import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.ARGB; import net.minecraft.util.CommonColors; -import net.minecraft.util.FastColor; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.HitResult; @@ -84,13 +85,13 @@ public void render(TurtleBlockEntity turtle, float partialTicks, PoseStack trans if (colour == -1) { // Render the turtle using its item model. - var modelManager = Minecraft.getInstance().getItemRenderer().getItemModelShaper(); - var model = modelManager.getItemModel(turtle.getBlockState().getBlock().asItem()); - if (model == null) model = modelManager.getModelManager().getMissingModel(); + var model = Minecraft.getInstance().getItemRenderer().getModel( + new ItemStack(turtle.getBlockState().getBlock().asItem()), null, null, 0 + ); renderModel(transform, buffers, lightmapCoord, overlayLight, model, null); } else { // Otherwise render it using the colour item. - renderModel(transform, buffers, lightmapCoord, overlayLight, COLOUR_TURTLE_MODEL, new int[]{ FastColor.ARGB32.opaque(colour) }); + renderModel(transform, buffers, lightmapCoord, overlayLight, COLOUR_TURTLE_MODEL, new int[]{ ARGB.opaque(colour) }); } // Render the overlay @@ -125,7 +126,7 @@ private void renderUpgrade(PoseStack transform, MultiBufferSource buffers, int l } private void renderModel(PoseStack transform, MultiBufferSource buffers, int lightmapCoord, int overlayLight, ResourceLocation modelLocation, @Nullable int[] tints) { - var modelManager = Minecraft.getInstance().getItemRenderer().getItemModelShaper().getModelManager(); + var modelManager = Minecraft.getInstance().getModelManager(); renderModel(transform, buffers, lightmapCoord, overlayLight, ClientPlatformHelper.get().getModel(modelManager, modelLocation), tints); } diff --git a/projects/common/src/client/java/dan200/computercraft/client/render/monitor/MonitorBlockEntityRenderer.java b/projects/common/src/client/java/dan200/computercraft/client/render/monitor/MonitorBlockEntityRenderer.java index ec075f9842..1a2e45fb08 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/render/monitor/MonitorBlockEntityRenderer.java +++ b/projects/common/src/client/java/dan200/computercraft/client/render/monitor/MonitorBlockEntityRenderer.java @@ -4,40 +4,28 @@ package dan200.computercraft.client.render.monitor; -import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.systems.RenderSystem; -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.Tesselator; -import com.mojang.blaze3d.vertex.VertexBuffer; -import com.mojang.blaze3d.vertex.VertexConsumer; +import com.mojang.blaze3d.vertex.*; import com.mojang.math.Axis; import dan200.computercraft.annotations.ForgeOverride; import dan200.computercraft.client.FrameInfo; import dan200.computercraft.client.integration.ShaderMod; -import dan200.computercraft.client.render.RenderTypes; import dan200.computercraft.client.render.text.DirectFixedWidthFontRenderer; import dan200.computercraft.client.render.text.FixedWidthFontRenderer; -import dan200.computercraft.client.render.vbo.DirectBuffers; -import dan200.computercraft.client.render.vbo.DirectVertexBuffer; import dan200.computercraft.core.terminal.Terminal; -import dan200.computercraft.core.util.Nullability; import dan200.computercraft.shared.config.Config; import dan200.computercraft.shared.peripheral.monitor.ClientMonitor; import dan200.computercraft.shared.peripheral.monitor.MonitorBlockEntity; -import dan200.computercraft.shared.peripheral.monitor.MonitorRenderer; import dan200.computercraft.shared.util.DirectionUtil; +import net.minecraft.client.renderer.CompiledShaderProgram; +import net.minecraft.client.renderer.FogParameters; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; import net.minecraft.world.phys.AABB; import org.joml.Matrix4f; -import org.lwjgl.opengl.GL11; -import org.lwjgl.opengl.GL20; -import org.lwjgl.opengl.GL31; -import org.lwjgl.system.MemoryUtil; import javax.annotation.Nullable; -import java.nio.ByteBuffer; import java.util.function.Consumer; import static dan200.computercraft.client.render.text.FixedWidthFontRenderer.FONT_HEIGHT; @@ -51,9 +39,7 @@ public class MonitorBlockEntityRenderer implements BlockEntityRenderer { - if (redraw) { - var terminalBuffer = getBuffer(width * height * 3); - MonitorTextureBufferShader.setTerminalData(terminalBuffer, terminal); - DirectBuffers.setBufferData(GL31.GL_TEXTURE_BUFFER, renderState.tboBuffer, terminalBuffer, GL20.GL_STATIC_DRAW); - - var uniformBuffer = getBuffer(MonitorTextureBufferShader.UNIFORM_SIZE); - MonitorTextureBufferShader.setUniformData(uniformBuffer, terminal); - DirectBuffers.setBufferData(GL31.GL_UNIFORM_BUFFER, renderState.tboUniform, uniformBuffer, GL20.GL_STATIC_DRAW); - } - - // Nobody knows what they're doing! - var active = GlStateManager._getActiveTexture(); - RenderSystem.activeTexture(MonitorTextureBufferShader.TEXTURE_INDEX); - GL11.glBindTexture(GL31.GL_TEXTURE_BUFFER, renderState.tboTexture); - RenderSystem.activeTexture(active); - - var shader = RenderTypes.getMonitorTextureBufferShader(); - shader.setupUniform(renderState.tboUniform); - - var buffer = Tesselator.getInstance().begin(RenderTypes.MONITOR_TBO.mode(), RenderTypes.MONITOR_TBO.format()); - tboVertex(buffer, matrix, -xMargin, -yMargin); - tboVertex(buffer, matrix, -xMargin, pixelHeight + yMargin); - tboVertex(buffer, matrix, pixelWidth + xMargin, -yMargin); - tboVertex(buffer, matrix, pixelWidth + xMargin, pixelHeight + yMargin); - RenderTypes.MONITOR_TBO.draw(Nullability.assertNonNull(buffer.build())); - } - case VBO -> { - var backgroundBuffer = assertNonNull(renderState.backgroundBuffer); - var foregroundBuffer = assertNonNull(renderState.foregroundBuffer); - if (redraw) { - var size = DirectFixedWidthFontRenderer.getVertexCount(terminal); - - // In an ideal world we could upload these both into one buffer. However, we can't render VBOs with - // and starting and ending offset, and so need to use two buffers instead. - - renderToBuffer(backgroundBuffer, size, sink -> - DirectFixedWidthFontRenderer.drawTerminalBackground(sink, 0, 0, terminal, yMargin, yMargin, xMargin, xMargin)); - - renderToBuffer(foregroundBuffer, size, sink -> { - DirectFixedWidthFontRenderer.drawTerminalForeground(sink, 0, 0, terminal); - // If the cursor is visible, we append it to the end of our buffer. When rendering, we can either - // render n or n+1 quads and so toggle the cursor on and off. - DirectFixedWidthFontRenderer.drawCursor(sink, 0, 0, terminal); - }); - } - - // Our VBO renders coordinates in monitor-space rather than world space. A full sized monitor (8x6) will - // use positions from (0, 0) to (164*FONT_WIDTH, 81*FONT_HEIGHT) = (984, 729). This is far outside the - // normal render distance (~200), and the edges of the monitor fade out due to fog. - // There's not really a good way around this, at least without using a custom render type (which the VBO - // renderer is trying to avoid!). Instead, we just disable fog entirely by setting the fog start to an - // absurdly high value. - var oldFogStart = RenderSystem.getShaderFogStart(); - RenderSystem.setShaderFogStart(1e4f); - - RenderTypes.TERMINAL.setupRenderState(); - - // Compose the existing model view matrix with our transformation matrix. - var modelView = new Matrix4f(RenderSystem.getModelViewMatrix()).mul(matrix); - - // Render background geometry - backgroundBuffer.bind(); - backgroundBuffer.drawWithShader(modelView, RenderSystem.getProjectionMatrix(), RenderTypes.getTerminalShader()); - - // Render foreground geometry with glPolygonOffset enabled. - RenderSystem.polygonOffset(-1.0f, -10.0f); - RenderSystem.enablePolygonOffset(); - - foregroundBuffer.bind(); - foregroundBuffer.drawWithShader( - modelView, RenderSystem.getProjectionMatrix(), RenderTypes.getTerminalShader(), - // As mentioned in the above comment, render the extra cursor quad if it is visible this frame. Each - // // quad has an index count of 6. - FixedWidthFontRenderer.isCursorVisible(terminal) && FrameInfo.getGlobalCursorBlink() - ? foregroundBuffer.getIndexCount() + 6 : foregroundBuffer.getIndexCount() - ); - - // Clear state - RenderSystem.polygonOffset(0.0f, -0.0f); - RenderSystem.disablePolygonOffset(); - RenderTypes.TERMINAL.clearRenderState(); - VertexBuffer.unbind(); - - RenderSystem.setShaderFogStart(oldFogStart); - } - case BEST -> throw new IllegalStateException("Impossible: Should never use BEST renderer"); + if (renderState.createBuffer()) redraw = true; + + var backgroundBuffer = assertNonNull(renderState.backgroundBuffer); + var foregroundBuffer = assertNonNull(renderState.foregroundBuffer); + if (redraw) { + var size = DirectFixedWidthFontRenderer.getVertexCount(terminal); + + // In an ideal world we could upload these both into one buffer. However, we can't render VBOs with + // and starting and ending offset, and so need to use two buffers instead. + + renderToBuffer(backgroundBuffer, size, sink -> + DirectFixedWidthFontRenderer.drawTerminalBackground(sink, 0, 0, terminal, yMargin, yMargin, xMargin, xMargin)); + + renderToBuffer(foregroundBuffer, size + 4, sink -> { + DirectFixedWidthFontRenderer.drawTerminalForeground(sink, 0, 0, terminal); + // If the cursor is visible, we append it to the end of our buffer. When rendering, we can either + // render n or n+1 quads and so toggle the cursor on and off. + DirectFixedWidthFontRenderer.drawCursor(sink, 0, 0, terminal); + }); } - } - private static void renderToBuffer(DirectVertexBuffer vbo, int size, Consumer draw) { - var sink = ShaderMod.get().getQuadEmitter(size, MonitorBlockEntityRenderer::getBuffer); - var buffer = sink.buffer(); + // Our VBO renders coordinates in monitor-space rather than world space. A full sized monitor (8x6) will + // use positions from (0, 0) to (164*FONT_WIDTH, 81*FONT_HEIGHT) = (984, 729). This is far outside the + // normal render distance (~200), and the edges of the monitor fade out due to fog. + // There's not really a good way around this, at least without using a custom render type (which the VBO + // renderer is trying to avoid!). Instead, we just disable fog entirely by setting the fog start to an + // absurdly high value. + var oldFog = RenderSystem.getShaderFog(); + RenderSystem.setShaderFog(FogParameters.NO_FOG); + + FixedWidthFontRenderer.TERMINAL_TEXT.setupRenderState(); + + // Compose the existing model view matrix with our transformation matrix. + var modelView = new Matrix4f(RenderSystem.getModelViewMatrix()).mul(matrix); + + // Render background geometry + backgroundBuffer.bind(); + backgroundBuffer.drawWithShader(modelView, RenderSystem.getProjectionMatrix(), RenderSystem.getShader()); + + // Render foreground geometry with glPolygonOffset enabled. + RenderSystem.polygonOffset(-1.0f, -10.0f); + RenderSystem.enablePolygonOffset(); + + foregroundBuffer.bind(); + drawWithShader( + foregroundBuffer, modelView, RenderSystem.getProjectionMatrix(), RenderSystem.getShader(), + // As mentioned in the above comment, render the extra cursor quad if it is visible this frame. + FixedWidthFontRenderer.isCursorVisible(terminal) && FrameInfo.getGlobalCursorBlink() + ? foregroundBuffer.indexCount + : foregroundBuffer.indexCount - FixedWidthFontRenderer.TERMINAL_TEXT.mode().indexCount(4) + ); - draw.accept(sink); - buffer.flip(); - vbo.upload(buffer.limit() / sink.format().getVertexSize(), RenderTypes.TERMINAL.mode(), sink.format(), buffer); - } + // Clear state + RenderSystem.polygonOffset(0.0f, -0.0f); + RenderSystem.disablePolygonOffset(); + FixedWidthFontRenderer.TERMINAL_TEXT.clearRenderState(); + VertexBuffer.unbind(); - private static void tboVertex(VertexConsumer builder, Matrix4f matrix, float x, float y) { - // We encode position in the UV, as that's not transformed by the matrix. - builder.addVertex(matrix, x, y, 0).setUv(x, y); + RenderSystem.setShaderFog(oldFog); } - private static ByteBuffer getBuffer(int capacity) { - var buffer = backingBuffer; - if (buffer == null || buffer.capacity() < capacity) { - buffer = backingBuffer = buffer == null ? MemoryUtil.memAlloc(capacity) : MemoryUtil.memRealloc(buffer, capacity); + private static void renderToBuffer(VertexBuffer vbo, int size, Consumer draw) { + var sink = ShaderMod.get().getQuadEmitter(size, backingBufferBuilder); + draw.accept(sink); + + var result = backingBufferBuilder.build(); + if (result == null) { + // If we have nothing to draw, just mark it as empty. We'll skip drawing in drawWithShader. + vbo.indexCount = 0; + return; } - buffer.clear(); - return buffer; + var buffer = result.byteBuffer(); + var vertices = buffer.limit() / sink.format().getVertexSize(); + + vbo.bind(); + vbo.upload(new MeshData(result, new MeshData.DrawState( + sink.format(), + vertices, FixedWidthFontRenderer.TERMINAL_TEXT.mode().indexCount(vertices), + FixedWidthFontRenderer.TERMINAL_TEXT.mode(), VertexFormat.IndexType.least(vertices) + ))); + } + + private static void drawWithShader(VertexBuffer buffer, Matrix4f modelView, Matrix4f projection, @Nullable CompiledShaderProgram compiledShaderProgram, int indicies) { + var originalIndexCount = buffer.indexCount; + if (originalIndexCount == 0) return; + + try { + buffer.indexCount = indicies; + buffer.drawWithShader(modelView, projection, compiledShaderProgram); + } finally { + buffer.indexCount = originalIndexCount; + } } @Override @@ -267,28 +226,4 @@ public int getViewDistance() { public AABB getRenderBoundingBox(MonitorBlockEntity monitor) { return monitor.getRenderBoundingBox(); } - - /** - * Determine if any monitors were rendered this frame. - * - * @return Whether any monitors were rendered. - */ - public static boolean hasRenderedThisFrame() { - return FrameInfo.getRenderFrame() == lastFrame; - } - - /** - * Get the current renderer to use. - * - * @return The current renderer. Will not return {@link MonitorRenderer#BEST}. - */ - public static MonitorRenderer currentRenderer() { - var current = Config.monitorRenderer; - if (current == MonitorRenderer.BEST) current = Config.monitorRenderer = bestRenderer(); - return current; - } - - private static MonitorRenderer bestRenderer() { - return MonitorRenderer.VBO; - } } diff --git a/projects/common/src/client/java/dan200/computercraft/client/render/monitor/MonitorRenderState.java b/projects/common/src/client/java/dan200/computercraft/client/render/monitor/MonitorRenderState.java index 7e8439666b..08e847864d 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/render/monitor/MonitorRenderState.java +++ b/projects/common/src/client/java/dan200/computercraft/client/render/monitor/MonitorRenderState.java @@ -5,16 +5,10 @@ package dan200.computercraft.client.render.monitor; import com.google.errorprone.annotations.concurrent.GuardedBy; -import com.mojang.blaze3d.platform.GlStateManager; -import dan200.computercraft.client.render.vbo.DirectBuffers; -import dan200.computercraft.client.render.vbo.DirectVertexBuffer; +import com.mojang.blaze3d.buffers.BufferUsage; +import com.mojang.blaze3d.vertex.VertexBuffer; import dan200.computercraft.shared.peripheral.monitor.ClientMonitor; -import dan200.computercraft.shared.peripheral.monitor.MonitorRenderer; import net.minecraft.core.BlockPos; -import org.lwjgl.opengl.GL11; -import org.lwjgl.opengl.GL15; -import org.lwjgl.opengl.GL30; -import org.lwjgl.opengl.GL31; import javax.annotation.Nullable; import java.util.HashSet; @@ -34,52 +28,23 @@ public class MonitorRenderState implements ClientMonitor.RenderState { public long lastRenderFrame = -1; public @Nullable BlockPos lastRenderPos = null; - public int tboBuffer; - public int tboTexture; - public int tboUniform; - public @Nullable DirectVertexBuffer backgroundBuffer; - public @Nullable DirectVertexBuffer foregroundBuffer; + public @Nullable VertexBuffer backgroundBuffer; + public @Nullable VertexBuffer foregroundBuffer; /** * Create the appropriate buffer if needed. * - * @param renderer The renderer to use. * @return If a buffer was created. This will return {@code false} if we already have an appropriate buffer, * or this mode does not require one. */ - public boolean createBuffer(MonitorRenderer renderer) { - switch (renderer) { - case TBO: { - if (tboBuffer != 0) return false; - - deleteBuffers(); - - tboBuffer = DirectBuffers.createBuffer(); - DirectBuffers.setEmptyBufferData(GL31.GL_TEXTURE_BUFFER, tboBuffer, GL15.GL_STATIC_DRAW); - tboTexture = GlStateManager._genTexture(); - GL11.glBindTexture(GL31.GL_TEXTURE_BUFFER, tboTexture); - GL31.glTexBuffer(GL31.GL_TEXTURE_BUFFER, GL30.GL_R8UI, tboBuffer); - GL11.glBindTexture(GL31.GL_TEXTURE_BUFFER, 0); - - tboUniform = DirectBuffers.createBuffer(); - DirectBuffers.setEmptyBufferData(GL31.GL_UNIFORM_BUFFER, tboUniform, GL15.GL_STATIC_DRAW); - - addMonitor(); - return true; - } - - case VBO: - if (backgroundBuffer != null) return false; - - deleteBuffers(); - backgroundBuffer = new DirectVertexBuffer(); - foregroundBuffer = new DirectVertexBuffer(); - addMonitor(); - return true; - - default: - return false; - } + public boolean createBuffer() { + if (backgroundBuffer != null) return false; + + deleteBuffers(); + backgroundBuffer = new VertexBuffer(BufferUsage.STATIC_WRITE); + foregroundBuffer = new VertexBuffer(BufferUsage.STATIC_WRITE); + addMonitor(); + return true; } private void addMonitor() { @@ -89,21 +54,6 @@ private void addMonitor() { } private void deleteBuffers() { - if (tboBuffer != 0) { - DirectBuffers.deleteBuffer(GL31.GL_TEXTURE_BUFFER, tboBuffer); - tboBuffer = 0; - } - - if (tboTexture != 0) { - GlStateManager._deleteTexture(tboTexture); - tboTexture = 0; - } - - if (tboUniform != 0) { - DirectBuffers.deleteBuffer(GL31.GL_UNIFORM_BUFFER, tboUniform); - tboUniform = 0; - } - if (backgroundBuffer != null) { backgroundBuffer.close(); backgroundBuffer = null; @@ -117,7 +67,7 @@ private void deleteBuffers() { @Override public void close() { - if (tboBuffer != 0 || backgroundBuffer != null) { + if (backgroundBuffer != null) { synchronized (allMonitors) { allMonitors.remove(this); } diff --git a/projects/common/src/client/java/dan200/computercraft/client/render/monitor/MonitorTextureBufferShader.java b/projects/common/src/client/java/dan200/computercraft/client/render/monitor/MonitorTextureBufferShader.java deleted file mode 100644 index 9d0b5ef965..0000000000 --- a/projects/common/src/client/java/dan200/computercraft/client/render/monitor/MonitorTextureBufferShader.java +++ /dev/null @@ -1,127 +0,0 @@ -// SPDX-FileCopyrightText: 2020 The CC: Tweaked Developers -// -// SPDX-License-Identifier: MPL-2.0 - -package dan200.computercraft.client.render.monitor; - -import com.mojang.blaze3d.shaders.Uniform; -import com.mojang.blaze3d.vertex.VertexFormat; -import dan200.computercraft.client.FrameInfo; -import dan200.computercraft.client.render.RenderTypes; -import dan200.computercraft.client.render.text.FixedWidthFontRenderer; -import dan200.computercraft.core.terminal.Terminal; -import dan200.computercraft.core.terminal.TextBuffer; -import dan200.computercraft.core.util.Colour; -import net.minecraft.client.renderer.ShaderInstance; -import net.minecraft.server.packs.resources.ResourceProvider; -import org.lwjgl.opengl.GL13; -import org.lwjgl.opengl.GL31; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.annotation.Nullable; -import java.io.IOException; -import java.nio.ByteBuffer; - -import static dan200.computercraft.client.render.text.FixedWidthFontRenderer.getColour; - -/** - * The shader used for the monitor TBO renderer. - *

- * This extends Minecraft's default shader loading code to extract out the TBO buffer and handle our custom uniforms - * ({@code MonitorData}, {@code CursorBlink}). - *

- * See also {@code monitor_tbo.fsh} and {@code monitor_tbo.vsh} in the mod's resources. - * - * @see RenderTypes#getMonitorTextureBufferShader() - */ -public class MonitorTextureBufferShader extends ShaderInstance { - private static final Logger LOG = LoggerFactory.getLogger(MonitorTextureBufferShader.class); - - public static final int UNIFORM_SIZE = 4 * 4 * 16 + 4 + 4 + 2 * 4 + 4; - - static final int TEXTURE_INDEX = GL13.GL_TEXTURE3; - - private final int monitorData; - private int uniformBuffer = 0; - - private final @Nullable Uniform cursorBlink; - - public MonitorTextureBufferShader(ResourceProvider provider, String location, VertexFormat format) throws IOException { - super(provider, location, format); - monitorData = GL31.glGetUniformBlockIndex(getId(), "MonitorData"); - if (monitorData == -1) throw new IllegalStateException("Could not find MonitorData uniform."); - - cursorBlink = getUniformChecked("CursorBlink"); - - var tbo = getUniformChecked("Tbo"); - if (tbo != null) tbo.set(TEXTURE_INDEX - GL13.GL_TEXTURE0); - } - - public void setupUniform(int buffer) { - uniformBuffer = buffer; - - var cursorAlpha = FrameInfo.getGlobalCursorBlink() ? 1 : 0; - if (cursorBlink != null && cursorBlink.getIntBuffer().get(0) != cursorAlpha) cursorBlink.set(cursorAlpha); - } - - @Override - public void apply() { - super.apply(); - GL31.glBindBufferBase(GL31.GL_UNIFORM_BUFFER, monitorData, uniformBuffer); - } - - @Nullable - private Uniform getUniformChecked(String name) { - var uniform = getUniform(name); - if (uniform == null) { - LOG.warn("Monitor shader {} should have uniform {}, but it was not present.", getName(), name); - } - - return uniform; - } - - public static void setTerminalData(ByteBuffer buffer, Terminal terminal) { - int width = terminal.getWidth(), height = terminal.getHeight(); - - var pos = 0; - for (var y = 0; y < height; y++) { - TextBuffer text = terminal.getLine(y), textColour = terminal.getTextColourLine(y), background = terminal.getBackgroundColourLine(y); - for (var x = 0; x < width; x++) { - buffer.put(pos, (byte) (text.charAt(x) & 0xFF)); - buffer.put(pos + 1, (byte) getColour(textColour.charAt(x), Colour.WHITE)); - buffer.put(pos + 2, (byte) getColour(background.charAt(x), Colour.BLACK)); - pos += 3; - } - } - - buffer.limit(pos); - } - - public static void setUniformData(ByteBuffer buffer, Terminal terminal) { - var pos = 0; - var palette = terminal.getPalette(); - for (var i = 0; i < 16; i++) { - { - var colour = palette.getColour(i); - if (!terminal.isColour()) { - var f = FixedWidthFontRenderer.toGreyscale(colour); - buffer.putFloat(pos, f).putFloat(pos + 4, f).putFloat(pos + 8, f); - } else { - buffer.putFloat(pos, (float) colour[0]).putFloat(pos + 4, (float) colour[1]).putFloat(pos + 8, (float) colour[2]); - } - } - - pos += 4 * 4; // std140 requires these are 4-wide - } - - var showCursor = FixedWidthFontRenderer.isCursorVisible(terminal); - buffer - .putInt(pos, terminal.getWidth()).putInt(pos + 4, terminal.getHeight()) - .putInt(pos + 8, showCursor ? terminal.getCursorX() : -2) - .putInt(pos + 12, showCursor ? terminal.getCursorY() : -2) - .putInt(pos + 16, 15 - terminal.getTextColour()); - - buffer.limit(UNIFORM_SIZE); - } -} diff --git a/projects/common/src/client/java/dan200/computercraft/client/render/text/DirectFixedWidthFontRenderer.java b/projects/common/src/client/java/dan200/computercraft/client/render/text/DirectFixedWidthFontRenderer.java index 59c12f61b2..6bb344868f 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/render/text/DirectFixedWidthFontRenderer.java +++ b/projects/common/src/client/java/dan200/computercraft/client/render/text/DirectFixedWidthFontRenderer.java @@ -4,18 +4,17 @@ package dan200.computercraft.client.render.text; +import com.mojang.blaze3d.vertex.ByteBufferBuilder; import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.blaze3d.vertex.VertexFormat; -import dan200.computercraft.client.render.RenderTypes; import dan200.computercraft.core.terminal.Palette; import dan200.computercraft.core.terminal.Terminal; import dan200.computercraft.core.terminal.TextBuffer; import dan200.computercraft.core.util.Colour; -import net.minecraft.util.FastColor; +import net.minecraft.util.ARGB; import org.lwjgl.system.MemoryUtil; -import java.nio.ByteBuffer; import java.nio.ByteOrder; import static dan200.computercraft.client.render.text.FixedWidthFontRenderer.*; @@ -168,40 +167,38 @@ private static void quad(QuadEmitter buffer, float x1, float y1, float x2, float public interface QuadEmitter { VertexFormat format(); - ByteBuffer buffer(); - void quad(float x1, float y1, float x2, float y2, float z, int colour, float u1, float v1, float u2, float v2); } - public record ByteBufferEmitter(ByteBuffer buffer) implements QuadEmitter { + public record ByteBufferEmitter(ByteBufferBuilder builder) implements QuadEmitter { @Override public VertexFormat format() { - return RenderTypes.TERMINAL.format(); + return TERMINAL_TEXT.format(); } @Override public void quad(float x1, float y1, float x2, float y2, float z, int colour, float u1, float v1, float u2, float v2) { - DirectFixedWidthFontRenderer.quad(buffer, x1, y1, x2, y2, z, colour, u1, v1, u2, v2); + DirectFixedWidthFontRenderer.quad(builder, x1, y1, x2, y2, z, colour, u1, v1, u2, v2); } } - static void quad(ByteBuffer buffer, float x1, float y1, float x2, float y2, float z, int colour, float u1, float v1, float u2, float v2) { + static void quad(ByteBufferBuilder builder, float x1, float y1, float x2, float y2, float z, int colour, float u1, float v1, float u2, float v2) { // Emit a single quad to our buffer. This uses Unsafe (well, LWJGL's MemoryUtil) to directly blit bytes to the // underlying buffer. This allows us to have a single bounds check up-front, rather than one for every write. // This provides significant performance gains, at the cost of well, using Unsafe. - // Each vertex is 28 bytes, giving 112 bytes in total. Vertices are of the form (xyz:FFF)(rgba:BBBB)(uv1:FF)(uv2:SS), + // Each vertex is 28 bytes, giving 112 bytes in total. Vertices are of the form (xyz:FFF)(abgr:BBBB)(uv1:FF)(uv2:SS), // which matches the POSITION_COLOR_TEX_LIGHTMAP vertex format. - - var position = buffer.position(); - var addr = MemoryUtil.memAddress(buffer); + var addr = builder.reserve(112); // We're doing terrible unsafe hacks below, so let's be really sure that what we're doing is reasonable. - if (position < 0 || 112 > buffer.limit() - position) throw new IndexOutOfBoundsException(); // Require the pointer to be aligned to a 32-bit boundary. if ((addr & 3) != 0) throw new IllegalStateException("Memory is not aligned"); + if (TERMINAL_TEXT.format().getVertexSize() != 28) { + throw new IllegalStateException("Incorrect vertex size"); + } - // Pack colour so it is equivalent to rgba:BBBB. This matches the logic in BufferBuilder. - var colourAbgr = FastColor.ABGR32.fromArgb32(colour); + var colourAbgr = ARGB.toABGR(colour); + // Pack colour so it is equivalent to abgr:BBBB. This matches the logic in BufferBuilder. var nativeColour = IS_LITTLE_ENDIAN ? colourAbgr : Integer.reverseBytes(colourAbgr); memPutFloat(addr + 0, x1); @@ -240,9 +237,6 @@ static void quad(ByteBuffer buffer, float x1, float y1, float x2, float y2, floa memPutShort(addr + 108, (short) 0xF0); memPutShort(addr + 110, (short) 0xF0); - // Finally increment the position. - buffer.position(position + 112); - // Well done for getting to the end of this method. I recommend you take a break and go look at cute puppies. } } diff --git a/projects/common/src/client/java/dan200/computercraft/client/render/text/FixedWidthFontRenderer.java b/projects/common/src/client/java/dan200/computercraft/client/render/text/FixedWidthFontRenderer.java index 7c6e1ed216..44d11bb556 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/render/text/FixedWidthFontRenderer.java +++ b/projects/common/src/client/java/dan200/computercraft/client/render/text/FixedWidthFontRenderer.java @@ -11,13 +11,13 @@ import dan200.computercraft.core.terminal.Terminal; import dan200.computercraft.core.terminal.TextBuffer; import dan200.computercraft.core.util.Colour; +import net.minecraft.client.renderer.LightTexture; +import net.minecraft.client.renderer.RenderType; import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.FastColor; +import net.minecraft.util.ARGB; import org.joml.Matrix4f; import org.joml.Vector3f; -import static dan200.computercraft.client.render.RenderTypes.FULL_BRIGHT_LIGHTMAP; - /** * Handles rendering fixed width text and computer terminals. *

@@ -33,7 +33,12 @@ * {@link DirectFixedWidthFontRenderer}. */ public final class FixedWidthFontRenderer { - public static final ResourceLocation FONT = ResourceLocation.fromNamespaceAndPath("computercraft", "textures/gui/term_font.png"); + private static final ResourceLocation FONT = ResourceLocation.fromNamespaceAndPath("computercraft", "textures/gui/term_font.png"); + + /** + * A render type for terminal text. + */ + public static final RenderType TERMINAL_TEXT = RenderType.text(FONT); public static final int FONT_HEIGHT = 9; public static final int FONT_WIDTH = 6; @@ -42,7 +47,7 @@ public final class FixedWidthFontRenderer { static final float BACKGROUND_START = (WIDTH - 6.0f) / WIDTH; static final float BACKGROUND_END = (WIDTH - 4.0f) / WIDTH; - private static final int BLACK = FastColor.ARGB32.color(255, byteColour(Colour.BLACK.getR()), byteColour(Colour.BLACK.getR()), byteColour(Colour.BLACK.getR())); + private static final int BLACK = ARGB.color(255, byteColour(Colour.BLACK.getR()), byteColour(Colour.BLACK.getR()), byteColour(Colour.BLACK.getR())); private static final float Z_OFFSET = 1e-3f; private FixedWidthFontRenderer() { @@ -137,7 +142,7 @@ public static void drawTerminalForeground(QuadEmitter emitter, float x, float y, var rowY = y + FONT_HEIGHT * i; drawString( emitter, x, rowY, terminal.getLine(i), terminal.getTextColourLine(i), - palette, FULL_BRIGHT_LIGHTMAP + palette, LightTexture.FULL_BRIGHT ); } } @@ -152,12 +157,12 @@ public static void drawTerminalBackground( // Top and bottom margins drawBackground( emitter, x, y - topMarginSize, terminal.getBackgroundColourLine(0), palette, - leftMarginSize, rightMarginSize, topMarginSize, FULL_BRIGHT_LIGHTMAP + leftMarginSize, rightMarginSize, topMarginSize, LightTexture.FULL_BRIGHT ); drawBackground( emitter, x, y + height * FONT_HEIGHT, terminal.getBackgroundColourLine(height - 1), palette, - leftMarginSize, rightMarginSize, bottomMarginSize, FULL_BRIGHT_LIGHTMAP + leftMarginSize, rightMarginSize, bottomMarginSize, LightTexture.FULL_BRIGHT ); // The main text @@ -165,7 +170,7 @@ public static void drawTerminalBackground( var rowY = y + FONT_HEIGHT * i; drawBackground( emitter, x, rowY, terminal.getBackgroundColourLine(i), palette, - leftMarginSize, rightMarginSize, FONT_HEIGHT, FULL_BRIGHT_LIGHTMAP + leftMarginSize, rightMarginSize, FONT_HEIGHT, LightTexture.FULL_BRIGHT ); } } @@ -181,7 +186,7 @@ public static boolean isCursorVisible(Terminal terminal) { public static void drawCursor(QuadEmitter emitter, float x, float y, Terminal terminal) { if (isCursorVisible(terminal) && FrameInfo.getGlobalCursorBlink()) { var colour = terminal.getPalette().getRenderColours(15 - terminal.getTextColour()); - drawChar(emitter, x + terminal.getCursorX() * FONT_WIDTH, y + terminal.getCursorY() * FONT_HEIGHT, '_', colour, FULL_BRIGHT_LIGHTMAP); + drawChar(emitter, x + terminal.getCursorX() * FONT_WIDTH, y + terminal.getCursorY() * FONT_HEIGHT, '_', colour, LightTexture.FULL_BRIGHT); } } @@ -207,7 +212,7 @@ public static void drawTerminal( } public static void drawEmptyTerminal(QuadEmitter emitter, float x, float y, float width, float height) { - drawQuad(emitter, x, y, 0, width, height, BLACK, FULL_BRIGHT_LIGHTMAP); + drawQuad(emitter, x, y, 0, width, height, BLACK, LightTexture.FULL_BRIGHT); } public record QuadEmitter(Matrix4f poseMatrix, VertexConsumer consumer) { @@ -220,11 +225,10 @@ public static QuadEmitter toVertexConsumer(PoseStack transform, VertexConsumer c private static void quad(QuadEmitter c, float x1, float y1, float x2, float y2, float z, int colour, float u1, float v1, float u2, float v2, int light) { var poseMatrix = c.poseMatrix(); var consumer = c.consumer(); - int r = FastColor.ARGB32.red(colour), g = FastColor.ARGB32.green(colour), b = FastColor.ARGB32.blue(colour), a = FastColor.ARGB32.alpha(colour); - consumer.addVertex(poseMatrix, x1, y1, z).setColor(r, g, b, a).setUv(u1, v1).setLight(light); - consumer.addVertex(poseMatrix, x1, y2, z).setColor(r, g, b, a).setUv(u1, v2).setLight(light); - consumer.addVertex(poseMatrix, x2, y2, z).setColor(r, g, b, a).setUv(u2, v2).setLight(light); - consumer.addVertex(poseMatrix, x2, y1, z).setColor(r, g, b, a).setUv(u2, v1).setLight(light); + consumer.addVertex(poseMatrix, x1, y1, z).setColor(colour).setUv(u1, v1).setLight(light); + consumer.addVertex(poseMatrix, x1, y2, z).setColor(colour).setUv(u1, v2).setLight(light); + consumer.addVertex(poseMatrix, x2, y2, z).setColor(colour).setUv(u2, v2).setLight(light); + consumer.addVertex(poseMatrix, x2, y1, z).setColor(colour).setUv(u2, v1).setLight(light); } } diff --git a/projects/common/src/client/java/dan200/computercraft/client/render/vbo/DirectBuffers.java b/projects/common/src/client/java/dan200/computercraft/client/render/vbo/DirectBuffers.java deleted file mode 100644 index 0c04be3268..0000000000 --- a/projects/common/src/client/java/dan200/computercraft/client/render/vbo/DirectBuffers.java +++ /dev/null @@ -1,71 +0,0 @@ -// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers -// -// SPDX-License-Identifier: MPL-2.0 - -package dan200.computercraft.client.render.vbo; - -import com.mojang.blaze3d.platform.GlStateManager; -import com.mojang.blaze3d.systems.RenderSystem; -import com.mojang.blaze3d.vertex.BufferUploader; -import net.minecraft.Util; -import org.lwjgl.opengl.GL; -import org.lwjgl.opengl.GL15C; -import org.lwjgl.opengl.GL45C; - -import java.nio.ByteBuffer; - -/** - * Provides utilities to interact with OpenGL's buffer objects, either using direct state access or binding/unbinding - * it. - */ -public class DirectBuffers { - public static final boolean HAS_DSA; - static final boolean ON_LINUX = Util.getPlatform() == Util.OS.LINUX; - - static { - var capabilities = GL.getCapabilities(); - HAS_DSA = capabilities.OpenGL45 || capabilities.GL_ARB_direct_state_access; - } - - public static int createBuffer() { - return HAS_DSA ? GL45C.glCreateBuffers() : GL15C.glGenBuffers(); - } - - /** - * Delete a previously created buffer. - *

- * On Linux, {@link GlStateManager#_glDeleteBuffers(int)} clears a buffer before deleting it. However, this involves - * binding and unbinding the buffer, conflicting with {@link BufferUploader}'s cache. This deletion method uses - * our existing {@link #setEmptyBufferData(int, int, int)}, which correctly handles clearing the buffer. - * - * @param type The buffer's type. - * @param id The buffer's ID. - */ - public static void deleteBuffer(int type, int id) { - RenderSystem.assertOnRenderThread(); - if (ON_LINUX) DirectBuffers.setEmptyBufferData(type, id, GL15C.GL_DYNAMIC_DRAW); - GL15C.glDeleteBuffers(id); - } - - public static void setBufferData(int type, int id, ByteBuffer buffer, int flags) { - if (HAS_DSA) { - GL45C.glNamedBufferData(id, buffer, flags); - } else { - if (type == GL15C.GL_ARRAY_BUFFER) BufferUploader.reset(); - GlStateManager._glBindBuffer(type, id); - GlStateManager._glBufferData(type, buffer, flags); - GlStateManager._glBindBuffer(type, 0); - } - } - - public static void setEmptyBufferData(int type, int id, int flags) { - if (HAS_DSA) { - GL45C.glNamedBufferData(id, 0, flags); - } else { - if (type == GL15C.GL_ARRAY_BUFFER) BufferUploader.reset(); - GlStateManager._glBindBuffer(type, id); - GlStateManager._glBufferData(type, 0, flags); - GlStateManager._glBindBuffer(type, 0); - } - } -} diff --git a/projects/common/src/client/java/dan200/computercraft/client/render/vbo/DirectVertexBuffer.java b/projects/common/src/client/java/dan200/computercraft/client/render/vbo/DirectVertexBuffer.java deleted file mode 100644 index 958ddfa0c3..0000000000 --- a/projects/common/src/client/java/dan200/computercraft/client/render/vbo/DirectVertexBuffer.java +++ /dev/null @@ -1,77 +0,0 @@ -// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers -// -// SPDX-License-Identifier: MPL-2.0 - -package dan200.computercraft.client.render.vbo; - -import com.mojang.blaze3d.systems.RenderSystem; -import com.mojang.blaze3d.vertex.BufferUploader; -import com.mojang.blaze3d.vertex.VertexBuffer; -import com.mojang.blaze3d.vertex.VertexFormat; -import net.minecraft.client.renderer.ShaderInstance; -import org.joml.Matrix4f; -import org.lwjgl.opengl.GL15; -import org.lwjgl.opengl.GL15C; -import org.lwjgl.opengl.GL45C; - -import java.nio.ByteBuffer; - -/** - * A version of {@link VertexBuffer} which allows uploading {@link ByteBuffer}s directly. - *

- * This should probably be its own class (rather than subclassing), but I need access to {@link VertexBuffer#drawWithShader}. - */ -public class DirectVertexBuffer extends VertexBuffer { - private int actualIndexCount; - - public DirectVertexBuffer() { - super(Usage.STATIC); - if (DirectBuffers.HAS_DSA) { - RenderSystem.glDeleteBuffers(vertexBufferId); - if (DirectBuffers.ON_LINUX) BufferUploader.reset(); // See comment on DirectBuffers.deleteBuffer. - vertexBufferId = GL45C.glCreateBuffers(); - } - } - - public void upload(int vertexCount, VertexFormat.Mode mode, VertexFormat format, ByteBuffer buffer) { - bind(); - - this.mode = mode; - actualIndexCount = indexCount = mode.indexCount(vertexCount); - indexType = VertexFormat.IndexType.SHORT; - - RenderSystem.assertOnRenderThread(); - - DirectBuffers.setBufferData(GL15.GL_ARRAY_BUFFER, vertexBufferId, buffer, GL15.GL_STATIC_DRAW); - if (format != this.format) { - if (this.format != null) this.format.clearBufferState(); - this.format = format; - - GL15C.glBindBuffer(GL15C.GL_ARRAY_BUFFER, vertexBufferId); - format.setupBufferState(); - GL15C.glBindBuffer(GL15C.GL_ARRAY_BUFFER, 0); - } - - var indexBuffer = RenderSystem.getSequentialBuffer(mode); - if (indexBuffer != sequentialIndices || !indexBuffer.hasStorage(indexCount)) { - indexBuffer.bind(indexCount); - sequentialIndices = indexBuffer; - } - } - - public void drawWithShader(Matrix4f modelView, Matrix4f projection, ShaderInstance shader, int indexCount) { - this.indexCount = indexCount; - drawWithShader(modelView, projection, shader); - this.indexCount = actualIndexCount; - } - - public int getIndexCount() { - return actualIndexCount; - } - - @Override - public void close() { - super.close(); - if (DirectBuffers.ON_LINUX) BufferUploader.reset(); // See comment on DirectBuffers.deleteBuffer. - } -} diff --git a/projects/common/src/client/java/dan200/computercraft/data/client/ClientDataProviders.java b/projects/common/src/client/java/dan200/computercraft/data/client/ClientDataProviders.java index 5d7b1a084a..c3712a0fd9 100644 --- a/projects/common/src/client/java/dan200/computercraft/data/client/ClientDataProviders.java +++ b/projects/common/src/client/java/dan200/computercraft/data/client/ClientDataProviders.java @@ -16,9 +16,11 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.server.packs.PackType; +import java.util.Arrays; import java.util.List; import java.util.Optional; import java.util.concurrent.CompletableFuture; +import java.util.function.Function; import java.util.stream.Stream; /** @@ -32,22 +34,21 @@ private ClientDataProviders() { public static void add(DataProviders.GeneratorSink generator, CompletableFuture registries) { generator.addFromCodec("Block atlases", PackType.CLIENT_RESOURCES, "atlases", SpriteSources.FILE_CODEC, out -> { - out.accept(ResourceLocation.withDefaultNamespace("blocks"), List.of( - new SingleFile(UpgradeSlot.LEFT_UPGRADE, Optional.empty()), - new SingleFile(UpgradeSlot.RIGHT_UPGRADE, Optional.empty()), - new SingleFile(LecternPrintoutModel.TEXTURE, Optional.empty()) - )); - out.accept(GuiSprites.SPRITE_SHEET, Stream.of( - // Buttons - GuiSprites.TURNED_OFF.textures(), - GuiSprites.TURNED_ON.textures(), - GuiSprites.TERMINATE.textures(), + out.accept(ResourceLocation.withDefaultNamespace("blocks"), makeSprites(Stream.of( + // Upgrade slot backgrounds + UpgradeSlot.LEFT_UPGRADE, + UpgradeSlot.RIGHT_UPGRADE, + // Texture for lectern printouts + LecternPrintoutModel.TEXTURE + ))); + + out.accept(GuiSprites.SPRITE_SHEET, makeSprites( // Computers GuiSprites.COMPUTER_NORMAL.textures(), GuiSprites.COMPUTER_ADVANCED.textures(), GuiSprites.COMPUTER_COMMAND.textures(), GuiSprites.COMPUTER_COLOUR.textures() - ).flatMap(x -> x).map(x -> new SingleFile(x, Optional.empty())).toList()); + )); }); generator.add(pack -> new ExtraModelsProvider(pack, registries) { @@ -57,4 +58,10 @@ public Stream getModels(HolderLookup.Provider registries) { } }); } + + @SafeVarargs + @SuppressWarnings("varargs") + private static List makeSprites(final Stream... files) { + return Arrays.stream(files).flatMap(Function.identity()).map(x -> new SingleFile(x, Optional.empty())).toList(); + } } diff --git a/projects/common/src/generated/resources/assets/computercraft/atlases/gui.json b/projects/common/src/generated/resources/assets/computercraft/atlases/gui.json index 8ad965c9d0..cbb2c9ee1e 100644 --- a/projects/common/src/generated/resources/assets/computercraft/atlases/gui.json +++ b/projects/common/src/generated/resources/assets/computercraft/atlases/gui.json @@ -1,11 +1,5 @@ { "sources": [ - {"type": "minecraft:single", "resource": "computercraft:gui/buttons/turned_off"}, - {"type": "minecraft:single", "resource": "computercraft:gui/buttons/turned_off_hover"}, - {"type": "minecraft:single", "resource": "computercraft:gui/buttons/turned_on"}, - {"type": "minecraft:single", "resource": "computercraft:gui/buttons/turned_on_hover"}, - {"type": "minecraft:single", "resource": "computercraft:gui/buttons/terminate"}, - {"type": "minecraft:single", "resource": "computercraft:gui/buttons/terminate_hover"}, {"type": "minecraft:single", "resource": "computercraft:gui/border_normal"}, {"type": "minecraft:single", "resource": "computercraft:gui/pocket_bottom_normal"}, {"type": "minecraft:single", "resource": "computercraft:gui/sidebar_normal"}, diff --git a/projects/common/src/generated/resources/assets/computercraft/lang/en_us.json b/projects/common/src/generated/resources/assets/computercraft/lang/en_us.json index db6f6b97e1..4dd4ab3289 100644 --- a/projects/common/src/generated/resources/assets/computercraft/lang/en_us.json +++ b/projects/common/src/generated/resources/assets/computercraft/lang/en_us.json @@ -124,8 +124,6 @@ "gui.computercraft.config.maximum_open_files.tooltip": "Set how many files a computer can have open at the same time. Set to 0 for unlimited.\nRange: > 0", "gui.computercraft.config.monitor_distance": "Monitor distance", "gui.computercraft.config.monitor_distance.tooltip": "The maximum distance monitors will render at. This defaults to the standard tile\nentity limit, but may be extended if you wish to build larger monitors.\nRange: 16 ~ 1024", - "gui.computercraft.config.monitor_renderer": "Monitor renderer", - "gui.computercraft.config.monitor_renderer.tooltip": "The renderer to use for monitors. Generally this should be kept at \"best\" - if\nmonitors have performance issues, you may wish to experiment with alternative\nrenderers.\nAllowed Values: BEST, TBO, VBO", "gui.computercraft.config.peripheral": "Peripherals", "gui.computercraft.config.peripheral.command_block_enabled": "Enable command block peripheral", "gui.computercraft.config.peripheral.command_block_enabled.tooltip": "Enable Command Block peripheral support", diff --git a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_1.json b/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk.json similarity index 76% rename from projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_1.json rename to projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk.json index 2a7291ff15..d23d78065f 100644 --- a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_1.json +++ b/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk.json @@ -5,8 +5,8 @@ "conditions": {"items": [{"items": "computercraft:disk_drive"}]}, "trigger": "minecraft:inventory_changed" }, - "has_the_recipe": {"conditions": {"recipe": "computercraft:disk_1"}, "trigger": "minecraft:recipe_unlocked"} + "has_the_recipe": {"conditions": {"recipe": "computercraft:disk"}, "trigger": "minecraft:recipe_unlocked"} }, "requirements": [["has_the_recipe", "has_drive"]], - "rewards": {"recipes": ["computercraft:disk_1"]} + "rewards": {"recipes": ["computercraft:disk"]} } diff --git a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_10.json b/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_10.json deleted file mode 100644 index 742dc3be75..0000000000 --- a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_10.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "criteria": { - "has_drive": { - "conditions": {"items": [{"items": "computercraft:disk_drive"}]}, - "trigger": "minecraft:inventory_changed" - }, - "has_the_recipe": {"conditions": {"recipe": "computercraft:disk_10"}, "trigger": "minecraft:recipe_unlocked"} - }, - "requirements": [["has_the_recipe", "has_drive"]], - "rewards": {"recipes": ["computercraft:disk_10"]} -} diff --git a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_11.json b/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_11.json deleted file mode 100644 index 86873eb079..0000000000 --- a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_11.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "criteria": { - "has_drive": { - "conditions": {"items": [{"items": "computercraft:disk_drive"}]}, - "trigger": "minecraft:inventory_changed" - }, - "has_the_recipe": {"conditions": {"recipe": "computercraft:disk_11"}, "trigger": "minecraft:recipe_unlocked"} - }, - "requirements": [["has_the_recipe", "has_drive"]], - "rewards": {"recipes": ["computercraft:disk_11"]} -} diff --git a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_12.json b/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_12.json deleted file mode 100644 index d200eec09a..0000000000 --- a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_12.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "criteria": { - "has_drive": { - "conditions": {"items": [{"items": "computercraft:disk_drive"}]}, - "trigger": "minecraft:inventory_changed" - }, - "has_the_recipe": {"conditions": {"recipe": "computercraft:disk_12"}, "trigger": "minecraft:recipe_unlocked"} - }, - "requirements": [["has_the_recipe", "has_drive"]], - "rewards": {"recipes": ["computercraft:disk_12"]} -} diff --git a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_13.json b/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_13.json deleted file mode 100644 index c8e8dbec09..0000000000 --- a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_13.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "criteria": { - "has_drive": { - "conditions": {"items": [{"items": "computercraft:disk_drive"}]}, - "trigger": "minecraft:inventory_changed" - }, - "has_the_recipe": {"conditions": {"recipe": "computercraft:disk_13"}, "trigger": "minecraft:recipe_unlocked"} - }, - "requirements": [["has_the_recipe", "has_drive"]], - "rewards": {"recipes": ["computercraft:disk_13"]} -} diff --git a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_14.json b/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_14.json deleted file mode 100644 index b08657cbfc..0000000000 --- a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_14.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "criteria": { - "has_drive": { - "conditions": {"items": [{"items": "computercraft:disk_drive"}]}, - "trigger": "minecraft:inventory_changed" - }, - "has_the_recipe": {"conditions": {"recipe": "computercraft:disk_14"}, "trigger": "minecraft:recipe_unlocked"} - }, - "requirements": [["has_the_recipe", "has_drive"]], - "rewards": {"recipes": ["computercraft:disk_14"]} -} diff --git a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_15.json b/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_15.json deleted file mode 100644 index 56444f5278..0000000000 --- a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_15.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "criteria": { - "has_drive": { - "conditions": {"items": [{"items": "computercraft:disk_drive"}]}, - "trigger": "minecraft:inventory_changed" - }, - "has_the_recipe": {"conditions": {"recipe": "computercraft:disk_15"}, "trigger": "minecraft:recipe_unlocked"} - }, - "requirements": [["has_the_recipe", "has_drive"]], - "rewards": {"recipes": ["computercraft:disk_15"]} -} diff --git a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_16.json b/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_16.json deleted file mode 100644 index b4a5255b34..0000000000 --- a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_16.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "criteria": { - "has_drive": { - "conditions": {"items": [{"items": "computercraft:disk_drive"}]}, - "trigger": "minecraft:inventory_changed" - }, - "has_the_recipe": {"conditions": {"recipe": "computercraft:disk_16"}, "trigger": "minecraft:recipe_unlocked"} - }, - "requirements": [["has_the_recipe", "has_drive"]], - "rewards": {"recipes": ["computercraft:disk_16"]} -} diff --git a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_2.json b/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_2.json deleted file mode 100644 index e96d9280a6..0000000000 --- a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_2.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "criteria": { - "has_drive": { - "conditions": {"items": [{"items": "computercraft:disk_drive"}]}, - "trigger": "minecraft:inventory_changed" - }, - "has_the_recipe": {"conditions": {"recipe": "computercraft:disk_2"}, "trigger": "minecraft:recipe_unlocked"} - }, - "requirements": [["has_the_recipe", "has_drive"]], - "rewards": {"recipes": ["computercraft:disk_2"]} -} diff --git a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_3.json b/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_3.json deleted file mode 100644 index d63ba41717..0000000000 --- a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_3.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "criteria": { - "has_drive": { - "conditions": {"items": [{"items": "computercraft:disk_drive"}]}, - "trigger": "minecraft:inventory_changed" - }, - "has_the_recipe": {"conditions": {"recipe": "computercraft:disk_3"}, "trigger": "minecraft:recipe_unlocked"} - }, - "requirements": [["has_the_recipe", "has_drive"]], - "rewards": {"recipes": ["computercraft:disk_3"]} -} diff --git a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_4.json b/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_4.json deleted file mode 100644 index dffcef4394..0000000000 --- a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_4.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "criteria": { - "has_drive": { - "conditions": {"items": [{"items": "computercraft:disk_drive"}]}, - "trigger": "minecraft:inventory_changed" - }, - "has_the_recipe": {"conditions": {"recipe": "computercraft:disk_4"}, "trigger": "minecraft:recipe_unlocked"} - }, - "requirements": [["has_the_recipe", "has_drive"]], - "rewards": {"recipes": ["computercraft:disk_4"]} -} diff --git a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_5.json b/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_5.json deleted file mode 100644 index 488c1220d8..0000000000 --- a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_5.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "criteria": { - "has_drive": { - "conditions": {"items": [{"items": "computercraft:disk_drive"}]}, - "trigger": "minecraft:inventory_changed" - }, - "has_the_recipe": {"conditions": {"recipe": "computercraft:disk_5"}, "trigger": "minecraft:recipe_unlocked"} - }, - "requirements": [["has_the_recipe", "has_drive"]], - "rewards": {"recipes": ["computercraft:disk_5"]} -} diff --git a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_6.json b/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_6.json deleted file mode 100644 index 1feaae00cc..0000000000 --- a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_6.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "criteria": { - "has_drive": { - "conditions": {"items": [{"items": "computercraft:disk_drive"}]}, - "trigger": "minecraft:inventory_changed" - }, - "has_the_recipe": {"conditions": {"recipe": "computercraft:disk_6"}, "trigger": "minecraft:recipe_unlocked"} - }, - "requirements": [["has_the_recipe", "has_drive"]], - "rewards": {"recipes": ["computercraft:disk_6"]} -} diff --git a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_7.json b/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_7.json deleted file mode 100644 index 6498b602ab..0000000000 --- a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_7.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "criteria": { - "has_drive": { - "conditions": {"items": [{"items": "computercraft:disk_drive"}]}, - "trigger": "minecraft:inventory_changed" - }, - "has_the_recipe": {"conditions": {"recipe": "computercraft:disk_7"}, "trigger": "minecraft:recipe_unlocked"} - }, - "requirements": [["has_the_recipe", "has_drive"]], - "rewards": {"recipes": ["computercraft:disk_7"]} -} diff --git a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_8.json b/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_8.json deleted file mode 100644 index ff252f7326..0000000000 --- a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_8.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "criteria": { - "has_drive": { - "conditions": {"items": [{"items": "computercraft:disk_drive"}]}, - "trigger": "minecraft:inventory_changed" - }, - "has_the_recipe": {"conditions": {"recipe": "computercraft:disk_8"}, "trigger": "minecraft:recipe_unlocked"} - }, - "requirements": [["has_the_recipe", "has_drive"]], - "rewards": {"recipes": ["computercraft:disk_8"]} -} diff --git a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_9.json b/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_9.json deleted file mode 100644 index 2500947557..0000000000 --- a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/disk_9.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "criteria": { - "has_drive": { - "conditions": {"items": [{"items": "computercraft:disk_drive"}]}, - "trigger": "minecraft:inventory_changed" - }, - "has_the_recipe": {"conditions": {"recipe": "computercraft:disk_9"}, "trigger": "minecraft:recipe_unlocked"} - }, - "requirements": [["has_the_recipe", "has_drive"]], - "rewards": {"recipes": ["computercraft:disk_9"]} -} diff --git a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/wired_modem_full_from.json b/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/wired_modem_full_from.json deleted file mode 100644 index 66f22c8788..0000000000 --- a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/wired_modem_full_from.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "criteria": { - "has_modem": { - "conditions": {"items": [{"items": "#computercraft:wired_modem"}]}, - "trigger": "minecraft:inventory_changed" - }, - "has_the_recipe": { - "conditions": {"recipe": "computercraft:wired_modem_full_from"}, - "trigger": "minecraft:recipe_unlocked" - } - }, - "requirements": [["has_the_recipe", "has_modem"]], - "rewards": {"recipes": ["computercraft:wired_modem_full_from"]} -} diff --git a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/wired_modem_full_to.json b/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/wired_modem_full_to.json deleted file mode 100644 index e6ce46a27b..0000000000 --- a/projects/common/src/generated/resources/data/computercraft/advancement/recipes/redstone/wired_modem_full_to.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "criteria": { - "has_modem": { - "conditions": {"items": [{"items": "#computercraft:wired_modem"}]}, - "trigger": "minecraft:inventory_changed" - }, - "has_the_recipe": { - "conditions": {"recipe": "computercraft:wired_modem_full_to"}, - "trigger": "minecraft:recipe_unlocked" - } - }, - "requirements": [["has_the_recipe", "has_modem"]], - "rewards": {"recipes": ["computercraft:wired_modem_full_to"]} -} diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/cable.json b/projects/common/src/generated/resources/data/computercraft/recipe/cable.json index 89384fc4c7..51017970a3 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/cable.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/cable.json @@ -1,7 +1,7 @@ { "type": "minecraft:crafting_shaped", "category": "redstone", - "key": {"#": {"item": "minecraft:stone"}, "R": {"tag": "c:dusts/redstone"}}, + "key": {"#": "minecraft:stone", "R": "#c:dusts/redstone"}, "pattern": [" # ", "#R#", " # "], "result": {"count": 6, "id": "computercraft:cable"} } diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/computer_advanced.json b/projects/common/src/generated/resources/data/computercraft/recipe/computer_advanced.json index 9a335214fa..863ffe6537 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/computer_advanced.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/computer_advanced.json @@ -1,7 +1,7 @@ { "type": "minecraft:crafting_shaped", "category": "redstone", - "key": {"#": {"tag": "c:ingots/gold"}, "G": {"tag": "c:glass_panes"}, "R": {"tag": "c:dusts/redstone"}}, + "key": {"#": "#c:ingots/gold", "G": "#c:glass_panes", "R": "#c:dusts/redstone"}, "pattern": ["###", "#R#", "#G#"], "result": {"count": 1, "id": "computercraft:computer_advanced"} } diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/computer_advanced_upgrade.json b/projects/common/src/generated/resources/data/computercraft/recipe/computer_advanced_upgrade.json index 9af31459c5..c6c0bb3f57 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/computer_advanced_upgrade.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/computer_advanced_upgrade.json @@ -1,8 +1,8 @@ { "type": "computercraft:transform_shaped", "category": "redstone", - "function": [{"type": "computercraft:copy_components", "from": {"item": "computercraft:computer_normal"}}], - "key": {"#": {"tag": "c:ingots/gold"}, "C": {"item": "computercraft:computer_normal"}}, + "function": [{"type": "computercraft:copy_components", "from": "computercraft:computer_normal"}], + "key": {"#": "#c:ingots/gold", "C": "computercraft:computer_normal"}, "pattern": ["###", "#C#", "# #"], "result": {"count": 1, "id": "computercraft:computer_advanced"} } diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/computer_command.json b/projects/common/src/generated/resources/data/computercraft/recipe/computer_command.json index 4ad39c5494..e24028d81f 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/computer_command.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/computer_command.json @@ -1,11 +1,7 @@ { "type": "minecraft:crafting_shaped", "category": "redstone", - "key": { - "#": {"tag": "c:ingots/gold"}, - "G": {"tag": "c:glass_panes"}, - "R": {"item": "minecraft:command_block"} - }, + "key": {"#": "#c:ingots/gold", "G": "#c:glass_panes", "R": "minecraft:command_block"}, "pattern": ["###", "#R#", "#G#"], "result": {"count": 1, "id": "computercraft:computer_command"} } diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/computer_normal.json b/projects/common/src/generated/resources/data/computercraft/recipe/computer_normal.json index 84117ee954..ebccce53a0 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/computer_normal.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/computer_normal.json @@ -1,7 +1,7 @@ { "type": "minecraft:crafting_shaped", "category": "redstone", - "key": {"#": {"item": "minecraft:stone"}, "G": {"tag": "c:glass_panes"}, "R": {"tag": "c:dusts/redstone"}}, + "key": {"#": "minecraft:stone", "G": "#c:glass_panes", "R": "#c:dusts/redstone"}, "pattern": ["###", "#R#", "#G#"], "result": {"count": 1, "id": "computercraft:computer_normal"} } diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/disk.json b/projects/common/src/generated/resources/data/computercraft/recipe/disk.json index 1c2e811fee..09c15083f6 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/disk.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/disk.json @@ -1 +1,6 @@ -{"type": "computercraft:disk", "category": "misc"} +{ + "type": "computercraft:disk", + "category": "redstone", + "group": "computercraft:disk", + "ingredients": ["#c:dusts/redstone", "minecraft:paper"] +} diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/disk_1.json b/projects/common/src/generated/resources/data/computercraft/recipe/disk_1.json deleted file mode 100644 index b7f19e31b8..0000000000 --- a/projects/common/src/generated/resources/data/computercraft/recipe/disk_1.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "type": "computercraft:impostor_shapeless", - "category": "redstone", - "group": "computercraft:disk", - "ingredients": [{"tag": "c:dusts/redstone"}, {"item": "minecraft:paper"}, {"item": "minecraft:black_dye"}], - "result": { - "components": {"minecraft:dyed_color": {"rgb": 1118481, "show_in_tooltip": false}}, - "count": 1, - "id": "computercraft:disk" - } -} diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/disk_10.json b/projects/common/src/generated/resources/data/computercraft/recipe/disk_10.json deleted file mode 100644 index b427391b17..0000000000 --- a/projects/common/src/generated/resources/data/computercraft/recipe/disk_10.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "type": "computercraft:impostor_shapeless", - "category": "redstone", - "group": "computercraft:disk", - "ingredients": [{"tag": "c:dusts/redstone"}, {"item": "minecraft:paper"}, {"item": "minecraft:pink_dye"}], - "result": { - "components": {"minecraft:dyed_color": {"rgb": 15905484, "show_in_tooltip": false}}, - "count": 1, - "id": "computercraft:disk" - } -} diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/disk_11.json b/projects/common/src/generated/resources/data/computercraft/recipe/disk_11.json deleted file mode 100644 index fcc0b9b38a..0000000000 --- a/projects/common/src/generated/resources/data/computercraft/recipe/disk_11.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "type": "computercraft:impostor_shapeless", - "category": "redstone", - "group": "computercraft:disk", - "ingredients": [{"tag": "c:dusts/redstone"}, {"item": "minecraft:paper"}, {"item": "minecraft:lime_dye"}], - "result": { - "components": {"minecraft:dyed_color": {"rgb": 8375321, "show_in_tooltip": false}}, - "count": 1, - "id": "computercraft:disk" - } -} diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/disk_12.json b/projects/common/src/generated/resources/data/computercraft/recipe/disk_12.json deleted file mode 100644 index 615cb1ddd9..0000000000 --- a/projects/common/src/generated/resources/data/computercraft/recipe/disk_12.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "type": "computercraft:impostor_shapeless", - "category": "redstone", - "group": "computercraft:disk", - "ingredients": [{"tag": "c:dusts/redstone"}, {"item": "minecraft:paper"}, {"item": "minecraft:yellow_dye"}], - "result": { - "components": {"minecraft:dyed_color": {"rgb": 14605932, "show_in_tooltip": false}}, - "count": 1, - "id": "computercraft:disk" - } -} diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/disk_13.json b/projects/common/src/generated/resources/data/computercraft/recipe/disk_13.json deleted file mode 100644 index 50d462d737..0000000000 --- a/projects/common/src/generated/resources/data/computercraft/recipe/disk_13.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "type": "computercraft:impostor_shapeless", - "category": "redstone", - "group": "computercraft:disk", - "ingredients": [ - {"tag": "c:dusts/redstone"}, - {"item": "minecraft:paper"}, - {"item": "minecraft:light_blue_dye"} - ], - "result": { - "components": {"minecraft:dyed_color": {"rgb": 10072818, "show_in_tooltip": false}}, - "count": 1, - "id": "computercraft:disk" - } -} diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/disk_14.json b/projects/common/src/generated/resources/data/computercraft/recipe/disk_14.json deleted file mode 100644 index 3b1301f5b3..0000000000 --- a/projects/common/src/generated/resources/data/computercraft/recipe/disk_14.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "type": "computercraft:impostor_shapeless", - "category": "redstone", - "group": "computercraft:disk", - "ingredients": [{"tag": "c:dusts/redstone"}, {"item": "minecraft:paper"}, {"item": "minecraft:magenta_dye"}], - "result": { - "components": {"minecraft:dyed_color": {"rgb": 15040472, "show_in_tooltip": false}}, - "count": 1, - "id": "computercraft:disk" - } -} diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/disk_15.json b/projects/common/src/generated/resources/data/computercraft/recipe/disk_15.json deleted file mode 100644 index 83beaae216..0000000000 --- a/projects/common/src/generated/resources/data/computercraft/recipe/disk_15.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "type": "computercraft:impostor_shapeless", - "category": "redstone", - "group": "computercraft:disk", - "ingredients": [{"tag": "c:dusts/redstone"}, {"item": "minecraft:paper"}, {"item": "minecraft:orange_dye"}], - "result": { - "components": {"minecraft:dyed_color": {"rgb": 15905331, "show_in_tooltip": false}}, - "count": 1, - "id": "computercraft:disk" - } -} diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/disk_16.json b/projects/common/src/generated/resources/data/computercraft/recipe/disk_16.json deleted file mode 100644 index 1d49329a25..0000000000 --- a/projects/common/src/generated/resources/data/computercraft/recipe/disk_16.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "type": "computercraft:impostor_shapeless", - "category": "redstone", - "group": "computercraft:disk", - "ingredients": [{"tag": "c:dusts/redstone"}, {"item": "minecraft:paper"}, {"item": "minecraft:white_dye"}], - "result": { - "components": {"minecraft:dyed_color": {"rgb": 15790320, "show_in_tooltip": false}}, - "count": 1, - "id": "computercraft:disk" - } -} diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/disk_2.json b/projects/common/src/generated/resources/data/computercraft/recipe/disk_2.json deleted file mode 100644 index 232d5ea43b..0000000000 --- a/projects/common/src/generated/resources/data/computercraft/recipe/disk_2.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "type": "computercraft:impostor_shapeless", - "category": "redstone", - "group": "computercraft:disk", - "ingredients": [{"tag": "c:dusts/redstone"}, {"item": "minecraft:paper"}, {"item": "minecraft:red_dye"}], - "result": { - "components": {"minecraft:dyed_color": {"rgb": 13388876, "show_in_tooltip": false}}, - "count": 1, - "id": "computercraft:disk" - } -} diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/disk_3.json b/projects/common/src/generated/resources/data/computercraft/recipe/disk_3.json deleted file mode 100644 index 08da162d86..0000000000 --- a/projects/common/src/generated/resources/data/computercraft/recipe/disk_3.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "type": "computercraft:impostor_shapeless", - "category": "redstone", - "group": "computercraft:disk", - "ingredients": [{"tag": "c:dusts/redstone"}, {"item": "minecraft:paper"}, {"item": "minecraft:green_dye"}], - "result": { - "components": {"minecraft:dyed_color": {"rgb": 5744206, "show_in_tooltip": false}}, - "count": 1, - "id": "computercraft:disk" - } -} diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/disk_4.json b/projects/common/src/generated/resources/data/computercraft/recipe/disk_4.json deleted file mode 100644 index 795b1c0a6e..0000000000 --- a/projects/common/src/generated/resources/data/computercraft/recipe/disk_4.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "type": "computercraft:impostor_shapeless", - "category": "redstone", - "group": "computercraft:disk", - "ingredients": [{"tag": "c:dusts/redstone"}, {"item": "minecraft:paper"}, {"item": "minecraft:brown_dye"}], - "result": { - "components": {"minecraft:dyed_color": {"rgb": 8349260, "show_in_tooltip": false}}, - "count": 1, - "id": "computercraft:disk" - } -} diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/disk_5.json b/projects/common/src/generated/resources/data/computercraft/recipe/disk_5.json deleted file mode 100644 index cd3c6716ac..0000000000 --- a/projects/common/src/generated/resources/data/computercraft/recipe/disk_5.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "type": "computercraft:impostor_shapeless", - "category": "redstone", - "group": "computercraft:disk", - "ingredients": [{"tag": "c:dusts/redstone"}, {"item": "minecraft:paper"}, {"item": "minecraft:blue_dye"}], - "result": { - "components": {"minecraft:dyed_color": {"rgb": 3368652, "show_in_tooltip": false}}, - "count": 1, - "id": "computercraft:disk" - } -} diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/disk_6.json b/projects/common/src/generated/resources/data/computercraft/recipe/disk_6.json deleted file mode 100644 index 0832d11bb4..0000000000 --- a/projects/common/src/generated/resources/data/computercraft/recipe/disk_6.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "type": "computercraft:impostor_shapeless", - "category": "redstone", - "group": "computercraft:disk", - "ingredients": [{"tag": "c:dusts/redstone"}, {"item": "minecraft:paper"}, {"item": "minecraft:purple_dye"}], - "result": { - "components": {"minecraft:dyed_color": {"rgb": 11691749, "show_in_tooltip": false}}, - "count": 1, - "id": "computercraft:disk" - } -} diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/disk_7.json b/projects/common/src/generated/resources/data/computercraft/recipe/disk_7.json deleted file mode 100644 index 3ba73a7ddc..0000000000 --- a/projects/common/src/generated/resources/data/computercraft/recipe/disk_7.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "type": "computercraft:impostor_shapeless", - "category": "redstone", - "group": "computercraft:disk", - "ingredients": [{"tag": "c:dusts/redstone"}, {"item": "minecraft:paper"}, {"item": "minecraft:cyan_dye"}], - "result": { - "components": {"minecraft:dyed_color": {"rgb": 5020082, "show_in_tooltip": false}}, - "count": 1, - "id": "computercraft:disk" - } -} diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/disk_8.json b/projects/common/src/generated/resources/data/computercraft/recipe/disk_8.json deleted file mode 100644 index c1b111e672..0000000000 --- a/projects/common/src/generated/resources/data/computercraft/recipe/disk_8.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "type": "computercraft:impostor_shapeless", - "category": "redstone", - "group": "computercraft:disk", - "ingredients": [ - {"tag": "c:dusts/redstone"}, - {"item": "minecraft:paper"}, - {"item": "minecraft:light_gray_dye"} - ], - "result": { - "components": {"minecraft:dyed_color": {"rgb": 10066329, "show_in_tooltip": false}}, - "count": 1, - "id": "computercraft:disk" - } -} diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/disk_9.json b/projects/common/src/generated/resources/data/computercraft/recipe/disk_9.json deleted file mode 100644 index b6a22ced87..0000000000 --- a/projects/common/src/generated/resources/data/computercraft/recipe/disk_9.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "type": "computercraft:impostor_shapeless", - "category": "redstone", - "group": "computercraft:disk", - "ingredients": [{"tag": "c:dusts/redstone"}, {"item": "minecraft:paper"}, {"item": "minecraft:gray_dye"}], - "result": { - "components": {"minecraft:dyed_color": {"rgb": 5000268, "show_in_tooltip": false}}, - "count": 1, - "id": "computercraft:disk" - } -} diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/disk_drive.json b/projects/common/src/generated/resources/data/computercraft/recipe/disk_drive.json index 3a00260160..166f6231e2 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/disk_drive.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/disk_drive.json @@ -1,7 +1,7 @@ { "type": "minecraft:crafting_shaped", "category": "redstone", - "key": {"#": {"item": "minecraft:stone"}, "R": {"tag": "c:dusts/redstone"}}, + "key": {"#": "minecraft:stone", "R": "#c:dusts/redstone"}, "pattern": ["###", "#R#", "#R#"], "result": {"count": 1, "id": "computercraft:disk_drive"} } diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/monitor_advanced.json b/projects/common/src/generated/resources/data/computercraft/recipe/monitor_advanced.json index 070392fe25..c999417c76 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/monitor_advanced.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/monitor_advanced.json @@ -1,7 +1,7 @@ { "type": "minecraft:crafting_shaped", "category": "redstone", - "key": {"#": {"tag": "c:ingots/gold"}, "G": {"tag": "c:glass_panes"}}, + "key": {"#": "#c:ingots/gold", "G": "#c:glass_panes"}, "pattern": ["###", "#G#", "###"], "result": {"count": 4, "id": "computercraft:monitor_advanced"} } diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/monitor_normal.json b/projects/common/src/generated/resources/data/computercraft/recipe/monitor_normal.json index a52103dd7c..89f691cf8b 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/monitor_normal.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/monitor_normal.json @@ -1,7 +1,7 @@ { "type": "minecraft:crafting_shaped", "category": "redstone", - "key": {"#": {"item": "minecraft:stone"}, "G": {"tag": "c:glass_panes"}}, + "key": {"#": "minecraft:stone", "G": "#c:glass_panes"}, "pattern": ["###", "#G#", "###"], "result": {"count": 1, "id": "computercraft:monitor_normal"} } diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/pocket_advanced/computercraft/speaker.json b/projects/common/src/generated/resources/data/computercraft/recipe/pocket_advanced/computercraft/speaker.json index 5848ae4c30..de0c09b5cd 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/pocket_advanced/computercraft/speaker.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/pocket_advanced/computercraft/speaker.json @@ -2,7 +2,7 @@ "type": "computercraft:impostor_shaped", "category": "redstone", "group": "computercraft:pocket_advanced", - "key": {"#": {"item": "computercraft:speaker"}, "P": {"item": "computercraft:pocket_computer_advanced"}}, + "key": {"#": "computercraft:speaker", "P": "computercraft:pocket_computer_advanced"}, "pattern": ["#", "P"], "result": { "components": {"computercraft:pocket_upgrade": {"id": "computercraft:speaker"}}, diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/pocket_advanced/computercraft/wireless_modem_advanced.json b/projects/common/src/generated/resources/data/computercraft/recipe/pocket_advanced/computercraft/wireless_modem_advanced.json index c88b008783..d6798f026c 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/pocket_advanced/computercraft/wireless_modem_advanced.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/pocket_advanced/computercraft/wireless_modem_advanced.json @@ -2,10 +2,7 @@ "type": "computercraft:impostor_shaped", "category": "redstone", "group": "computercraft:pocket_advanced", - "key": { - "#": {"item": "computercraft:wireless_modem_advanced"}, - "P": {"item": "computercraft:pocket_computer_advanced"} - }, + "key": {"#": "computercraft:wireless_modem_advanced", "P": "computercraft:pocket_computer_advanced"}, "pattern": ["#", "P"], "result": { "components": {"computercraft:pocket_upgrade": {"id": "computercraft:wireless_modem_advanced"}}, diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/pocket_advanced/computercraft/wireless_modem_normal.json b/projects/common/src/generated/resources/data/computercraft/recipe/pocket_advanced/computercraft/wireless_modem_normal.json index 43180d4ffd..f86914d726 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/pocket_advanced/computercraft/wireless_modem_normal.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/pocket_advanced/computercraft/wireless_modem_normal.json @@ -2,10 +2,7 @@ "type": "computercraft:impostor_shaped", "category": "redstone", "group": "computercraft:pocket_advanced", - "key": { - "#": {"item": "computercraft:wireless_modem_normal"}, - "P": {"item": "computercraft:pocket_computer_advanced"} - }, + "key": {"#": "computercraft:wireless_modem_normal", "P": "computercraft:pocket_computer_advanced"}, "pattern": ["#", "P"], "result": { "components": {"computercraft:pocket_upgrade": {"id": "computercraft:wireless_modem_normal"}}, diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/pocket_computer_advanced.json b/projects/common/src/generated/resources/data/computercraft/recipe/pocket_computer_advanced.json index 911f07c811..1636bb255f 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/pocket_computer_advanced.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/pocket_computer_advanced.json @@ -1,7 +1,7 @@ { "type": "minecraft:crafting_shaped", "category": "redstone", - "key": {"#": {"tag": "c:ingots/gold"}, "A": {"item": "minecraft:golden_apple"}, "G": {"tag": "c:glass_panes"}}, + "key": {"#": "#c:ingots/gold", "A": "minecraft:golden_apple", "G": "#c:glass_panes"}, "pattern": ["###", "#A#", "#G#"], "result": {"count": 1, "id": "computercraft:pocket_computer_advanced"} } diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/pocket_computer_advanced_upgrade.json b/projects/common/src/generated/resources/data/computercraft/recipe/pocket_computer_advanced_upgrade.json index 52649787f0..f008963b3f 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/pocket_computer_advanced_upgrade.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/pocket_computer_advanced_upgrade.json @@ -1,10 +1,8 @@ { "type": "computercraft:transform_shaped", "category": "redstone", - "function": [ - {"type": "computercraft:copy_components", "from": {"item": "computercraft:pocket_computer_normal"}} - ], - "key": {"#": {"tag": "c:ingots/gold"}, "C": {"item": "computercraft:pocket_computer_normal"}}, + "function": [{"type": "computercraft:copy_components", "from": "computercraft:pocket_computer_normal"}], + "key": {"#": "#c:ingots/gold", "C": "computercraft:pocket_computer_normal"}, "pattern": ["###", "#C#", "# #"], "result": {"count": 1, "id": "computercraft:pocket_computer_advanced"} } diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/pocket_computer_normal.json b/projects/common/src/generated/resources/data/computercraft/recipe/pocket_computer_normal.json index 4bef87ac86..079c9752cb 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/pocket_computer_normal.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/pocket_computer_normal.json @@ -1,11 +1,7 @@ { "type": "minecraft:crafting_shaped", "category": "redstone", - "key": { - "#": {"item": "minecraft:stone"}, - "A": {"item": "minecraft:golden_apple"}, - "G": {"tag": "c:glass_panes"} - }, + "key": {"#": "minecraft:stone", "A": "minecraft:golden_apple", "G": "#c:glass_panes"}, "pattern": ["###", "#A#", "#G#"], "result": {"count": 1, "id": "computercraft:pocket_computer_normal"} } diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/pocket_normal/computercraft/speaker.json b/projects/common/src/generated/resources/data/computercraft/recipe/pocket_normal/computercraft/speaker.json index f13b2cafab..3836d300c1 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/pocket_normal/computercraft/speaker.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/pocket_normal/computercraft/speaker.json @@ -2,7 +2,7 @@ "type": "computercraft:impostor_shaped", "category": "redstone", "group": "computercraft:pocket_normal", - "key": {"#": {"item": "computercraft:speaker"}, "P": {"item": "computercraft:pocket_computer_normal"}}, + "key": {"#": "computercraft:speaker", "P": "computercraft:pocket_computer_normal"}, "pattern": ["#", "P"], "result": { "components": {"computercraft:pocket_upgrade": {"id": "computercraft:speaker"}}, diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/pocket_normal/computercraft/wireless_modem_advanced.json b/projects/common/src/generated/resources/data/computercraft/recipe/pocket_normal/computercraft/wireless_modem_advanced.json index 63f38c6187..90ca2f8bb9 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/pocket_normal/computercraft/wireless_modem_advanced.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/pocket_normal/computercraft/wireless_modem_advanced.json @@ -2,10 +2,7 @@ "type": "computercraft:impostor_shaped", "category": "redstone", "group": "computercraft:pocket_normal", - "key": { - "#": {"item": "computercraft:wireless_modem_advanced"}, - "P": {"item": "computercraft:pocket_computer_normal"} - }, + "key": {"#": "computercraft:wireless_modem_advanced", "P": "computercraft:pocket_computer_normal"}, "pattern": ["#", "P"], "result": { "components": {"computercraft:pocket_upgrade": {"id": "computercraft:wireless_modem_advanced"}}, diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/pocket_normal/computercraft/wireless_modem_normal.json b/projects/common/src/generated/resources/data/computercraft/recipe/pocket_normal/computercraft/wireless_modem_normal.json index a875e74132..906bece74d 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/pocket_normal/computercraft/wireless_modem_normal.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/pocket_normal/computercraft/wireless_modem_normal.json @@ -2,10 +2,7 @@ "type": "computercraft:impostor_shaped", "category": "redstone", "group": "computercraft:pocket_normal", - "key": { - "#": {"item": "computercraft:wireless_modem_normal"}, - "P": {"item": "computercraft:pocket_computer_normal"} - }, + "key": {"#": "computercraft:wireless_modem_normal", "P": "computercraft:pocket_computer_normal"}, "pattern": ["#", "P"], "result": { "components": {"computercraft:pocket_upgrade": {"id": "computercraft:wireless_modem_normal"}}, diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/printed_book.json b/projects/common/src/generated/resources/data/computercraft/recipe/printed_book.json index 1f9d9b36b0..8efc4f70a8 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/printed_book.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/printed_book.json @@ -1,12 +1,8 @@ { "type": "computercraft:printout", "category": "redstone", - "ingredients": [{"tag": "c:leathers"}, {"tag": "c:strings"}], + "ingredients": ["#c:leathers", "#c:strings"], "min_printouts": 1, - "printout": [ - {"item": "computercraft:printed_page"}, - {"item": "computercraft:printed_pages"}, - {"item": "minecraft:paper"} - ], + "printout": ["computercraft:printed_page", "computercraft:printed_pages", "minecraft:paper"], "result": {"count": 1, "id": "computercraft:printed_book"} } diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/printed_pages.json b/projects/common/src/generated/resources/data/computercraft/recipe/printed_pages.json index 6b8f2a00b2..173aff16ff 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/printed_pages.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/printed_pages.json @@ -1,12 +1,8 @@ { "type": "computercraft:printout", "category": "redstone", - "ingredients": [{"tag": "c:strings"}], + "ingredients": ["#c:strings"], "min_printouts": 2, - "printout": [ - {"item": "computercraft:printed_page"}, - {"item": "computercraft:printed_pages"}, - {"item": "minecraft:paper"} - ], + "printout": ["computercraft:printed_page", "computercraft:printed_pages", "minecraft:paper"], "result": {"count": 1, "id": "computercraft:printed_pages"} } diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/printer.json b/projects/common/src/generated/resources/data/computercraft/recipe/printer.json index 6fb87d2c38..9b658c1ac9 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/printer.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/printer.json @@ -1,7 +1,7 @@ { "type": "minecraft:crafting_shaped", "category": "redstone", - "key": {"#": {"item": "minecraft:stone"}, "D": {"tag": "c:dyes"}, "R": {"tag": "c:dusts/redstone"}}, + "key": {"#": "minecraft:stone", "D": "#c:dyes", "R": "#c:dusts/redstone"}, "pattern": ["###", "#R#", "#D#"], "result": {"count": 1, "id": "computercraft:printer"} } diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/skull_cloudy.json b/projects/common/src/generated/resources/data/computercraft/recipe/skull_cloudy.json index 6b32018d35..23d7b36f44 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/skull_cloudy.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/skull_cloudy.json @@ -1,7 +1,7 @@ { "type": "minecraft:crafting_shapeless", "category": "misc", - "ingredients": [{"tag": "minecraft:skulls"}, {"item": "computercraft:monitor_normal"}], + "ingredients": ["#minecraft:skulls", "computercraft:monitor_normal"], "result": { "components": { "minecraft:profile": {"id": [1829193526, -1310112904, -1449411193, 2005015708], "name": "Cloudhunter"} diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/skull_dan200.json b/projects/common/src/generated/resources/data/computercraft/recipe/skull_dan200.json index 38dd3a1355..517f7b4856 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/skull_dan200.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/skull_dan200.json @@ -1,7 +1,7 @@ { "type": "minecraft:crafting_shapeless", "category": "misc", - "ingredients": [{"tag": "minecraft:skulls"}, {"item": "computercraft:computer_advanced"}], + "ingredients": ["#minecraft:skulls", "computercraft:computer_advanced"], "result": { "components": {"minecraft:profile": {"id": [-204941669, 125191442, -2076913230, 374933995], "name": "dan200"}}, "count": 1, diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/speaker.json b/projects/common/src/generated/resources/data/computercraft/recipe/speaker.json index 0e61faa47b..08dd768b03 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/speaker.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/speaker.json @@ -1,11 +1,7 @@ { "type": "minecraft:crafting_shaped", "category": "redstone", - "key": { - "#": {"item": "minecraft:stone"}, - "N": {"item": "minecraft:note_block"}, - "R": {"tag": "c:dusts/redstone"} - }, + "key": {"#": "minecraft:stone", "N": "minecraft:note_block", "R": "#c:dusts/redstone"}, "pattern": ["###", "#N#", "#R#"], "result": {"count": 1, "id": "computercraft:speaker"} } diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced.json b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced.json index 4e86b03161..5f9e88bf65 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced.json @@ -1,12 +1,8 @@ { "type": "computercraft:transform_shaped", "category": "redstone", - "function": [{"type": "computercraft:copy_components", "from": {"item": "computercraft:computer_advanced"}}], - "key": { - "#": {"tag": "c:ingots/gold"}, - "C": {"item": "computercraft:computer_advanced"}, - "I": {"tag": "c:chests/wooden"} - }, + "function": [{"type": "computercraft:copy_components", "from": "computercraft:computer_advanced"}], + "key": {"#": "#c:ingots/gold", "C": "computercraft:computer_advanced", "I": "#c:chests/wooden"}, "pattern": ["###", "#C#", "#I#"], "result": {"count": 1, "id": "computercraft:turtle_advanced"} } diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/computercraft/speaker.json b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/computercraft/speaker.json index 521802cc82..b52ab3e1b9 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/computercraft/speaker.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/computercraft/speaker.json @@ -2,7 +2,7 @@ "type": "computercraft:impostor_shaped", "category": "redstone", "group": "computercraft:turtle_advanced", - "key": {"#": {"item": "computercraft:speaker"}, "T": {"item": "computercraft:turtle_advanced"}}, + "key": {"#": "computercraft:speaker", "T": "computercraft:turtle_advanced"}, "pattern": ["#T"], "result": { "components": {"computercraft:right_turtle_upgrade": {"id": "computercraft:speaker"}}, diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/computercraft/wireless_modem_advanced.json b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/computercraft/wireless_modem_advanced.json index a6cda706d0..47a4b7343d 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/computercraft/wireless_modem_advanced.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/computercraft/wireless_modem_advanced.json @@ -2,7 +2,7 @@ "type": "computercraft:impostor_shaped", "category": "redstone", "group": "computercraft:turtle_advanced", - "key": {"#": {"item": "computercraft:wireless_modem_advanced"}, "T": {"item": "computercraft:turtle_advanced"}}, + "key": {"#": "computercraft:wireless_modem_advanced", "T": "computercraft:turtle_advanced"}, "pattern": ["#T"], "result": { "components": {"computercraft:right_turtle_upgrade": {"id": "computercraft:wireless_modem_advanced"}}, diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/computercraft/wireless_modem_normal.json b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/computercraft/wireless_modem_normal.json index 166cff86eb..bb7db95823 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/computercraft/wireless_modem_normal.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/computercraft/wireless_modem_normal.json @@ -2,7 +2,7 @@ "type": "computercraft:impostor_shaped", "category": "redstone", "group": "computercraft:turtle_advanced", - "key": {"#": {"item": "computercraft:wireless_modem_normal"}, "T": {"item": "computercraft:turtle_advanced"}}, + "key": {"#": "computercraft:wireless_modem_normal", "T": "computercraft:turtle_advanced"}, "pattern": ["#T"], "result": { "components": {"computercraft:right_turtle_upgrade": {"id": "computercraft:wireless_modem_normal"}}, diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/minecraft/crafting_table.json b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/minecraft/crafting_table.json index 8866543baf..fc776b66a4 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/minecraft/crafting_table.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/minecraft/crafting_table.json @@ -2,7 +2,7 @@ "type": "computercraft:impostor_shaped", "category": "redstone", "group": "computercraft:turtle_advanced", - "key": {"#": {"item": "minecraft:crafting_table"}, "T": {"item": "computercraft:turtle_advanced"}}, + "key": {"#": "minecraft:crafting_table", "T": "computercraft:turtle_advanced"}, "pattern": ["#T"], "result": { "components": {"computercraft:right_turtle_upgrade": {"id": "minecraft:crafting_table"}}, diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/minecraft/diamond_axe.json b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/minecraft/diamond_axe.json index f7c255e296..7ec583c011 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/minecraft/diamond_axe.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/minecraft/diamond_axe.json @@ -2,7 +2,7 @@ "type": "computercraft:impostor_shaped", "category": "redstone", "group": "computercraft:turtle_advanced", - "key": {"#": {"item": "minecraft:diamond_axe"}, "T": {"item": "computercraft:turtle_advanced"}}, + "key": {"#": "minecraft:diamond_axe", "T": "computercraft:turtle_advanced"}, "pattern": ["#T"], "result": { "components": {"computercraft:right_turtle_upgrade": {"id": "minecraft:diamond_axe"}}, diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/minecraft/diamond_hoe.json b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/minecraft/diamond_hoe.json index e921bba79a..34e80ec031 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/minecraft/diamond_hoe.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/minecraft/diamond_hoe.json @@ -2,7 +2,7 @@ "type": "computercraft:impostor_shaped", "category": "redstone", "group": "computercraft:turtle_advanced", - "key": {"#": {"item": "minecraft:diamond_hoe"}, "T": {"item": "computercraft:turtle_advanced"}}, + "key": {"#": "minecraft:diamond_hoe", "T": "computercraft:turtle_advanced"}, "pattern": ["#T"], "result": { "components": {"computercraft:right_turtle_upgrade": {"id": "minecraft:diamond_hoe"}}, diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/minecraft/diamond_pickaxe.json b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/minecraft/diamond_pickaxe.json index fc267afc03..a7cc3bab72 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/minecraft/diamond_pickaxe.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/minecraft/diamond_pickaxe.json @@ -2,7 +2,7 @@ "type": "computercraft:impostor_shaped", "category": "redstone", "group": "computercraft:turtle_advanced", - "key": {"#": {"item": "minecraft:diamond_pickaxe"}, "T": {"item": "computercraft:turtle_advanced"}}, + "key": {"#": "minecraft:diamond_pickaxe", "T": "computercraft:turtle_advanced"}, "pattern": ["#T"], "result": { "components": {"computercraft:right_turtle_upgrade": {"id": "minecraft:diamond_pickaxe"}}, diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/minecraft/diamond_shovel.json b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/minecraft/diamond_shovel.json index 77bba7a395..cf622099e3 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/minecraft/diamond_shovel.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/minecraft/diamond_shovel.json @@ -2,7 +2,7 @@ "type": "computercraft:impostor_shaped", "category": "redstone", "group": "computercraft:turtle_advanced", - "key": {"#": {"item": "minecraft:diamond_shovel"}, "T": {"item": "computercraft:turtle_advanced"}}, + "key": {"#": "minecraft:diamond_shovel", "T": "computercraft:turtle_advanced"}, "pattern": ["#T"], "result": { "components": {"computercraft:right_turtle_upgrade": {"id": "minecraft:diamond_shovel"}}, diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/minecraft/diamond_sword.json b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/minecraft/diamond_sword.json index 53078aa9aa..22ea4ad9bd 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/minecraft/diamond_sword.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced/minecraft/diamond_sword.json @@ -2,7 +2,7 @@ "type": "computercraft:impostor_shaped", "category": "redstone", "group": "computercraft:turtle_advanced", - "key": {"#": {"item": "minecraft:diamond_sword"}, "T": {"item": "computercraft:turtle_advanced"}}, + "key": {"#": "minecraft:diamond_sword", "T": "computercraft:turtle_advanced"}, "pattern": ["#T"], "result": { "components": {"computercraft:right_turtle_upgrade": {"id": "minecraft:diamond_sword"}}, diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced_overlays/rainbow_flag.json b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced_overlays/rainbow_flag.json index 03790f7331..4bfbc5f854 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced_overlays/rainbow_flag.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced_overlays/rainbow_flag.json @@ -5,19 +5,19 @@ { "type": "computercraft:copy_components", "exclude": ["computercraft:overlay"], - "from": {"item": "computercraft:turtle_advanced"} + "from": "computercraft:turtle_advanced" } ], "group": "computercraft:turtle_advanced_overlay", "ingredients": [ - {"tag": "c:dyes/red"}, - {"tag": "c:dyes/orange"}, - {"tag": "c:dyes/yellow"}, - {"tag": "c:dyes/green"}, - {"tag": "c:dyes/blue"}, - {"tag": "c:dyes/purple"}, - {"item": "minecraft:stick"}, - {"item": "computercraft:turtle_advanced"} + "#c:dyes/red", + "#c:dyes/orange", + "#c:dyes/yellow", + "#c:dyes/green", + "#c:dyes/blue", + "#c:dyes/purple", + "minecraft:stick", + "computercraft:turtle_advanced" ], "result": { "components": {"computercraft:overlay": "computercraft:rainbow_flag"}, diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced_overlays/trans_flag.json b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced_overlays/trans_flag.json index 9bd4591245..dab1cbb2da 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced_overlays/trans_flag.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced_overlays/trans_flag.json @@ -5,16 +5,16 @@ { "type": "computercraft:copy_components", "exclude": ["computercraft:overlay"], - "from": {"item": "computercraft:turtle_advanced"} + "from": "computercraft:turtle_advanced" } ], "group": "computercraft:turtle_advanced_overlay", "ingredients": [ - {"tag": "c:dyes/light_blue"}, - {"tag": "c:dyes/pink"}, - {"tag": "c:dyes/white"}, - {"item": "minecraft:stick"}, - {"item": "computercraft:turtle_advanced"} + "#c:dyes/light_blue", + "#c:dyes/pink", + "#c:dyes/white", + "minecraft:stick", + "computercraft:turtle_advanced" ], "result": { "components": {"computercraft:overlay": "computercraft:trans_flag"}, diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced_upgrade.json b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced_upgrade.json index 34e7941275..ec6e869792 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced_upgrade.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_advanced_upgrade.json @@ -1,12 +1,8 @@ { "type": "computercraft:transform_shaped", "category": "redstone", - "function": [{"type": "computercraft:copy_components", "from": {"item": "computercraft:turtle_normal"}}], - "key": { - "#": {"tag": "c:ingots/gold"}, - "B": {"tag": "c:storage_blocks/gold"}, - "C": {"item": "computercraft:turtle_normal"} - }, + "function": [{"type": "computercraft:copy_components", "from": "computercraft:turtle_normal"}], + "key": {"#": "#c:ingots/gold", "B": "#c:storage_blocks/gold", "C": "computercraft:turtle_normal"}, "pattern": ["###", "#C#", " B "], "result": {"count": 1, "id": "computercraft:turtle_advanced"} } diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal.json b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal.json index 8c8312083e..8fbd8c1e5c 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal.json @@ -1,12 +1,8 @@ { "type": "computercraft:transform_shaped", "category": "redstone", - "function": [{"type": "computercraft:copy_components", "from": {"item": "computercraft:computer_normal"}}], - "key": { - "#": {"tag": "c:ingots/iron"}, - "C": {"item": "computercraft:computer_normal"}, - "I": {"tag": "c:chests/wooden"} - }, + "function": [{"type": "computercraft:copy_components", "from": "computercraft:computer_normal"}], + "key": {"#": "#c:ingots/iron", "C": "computercraft:computer_normal", "I": "#c:chests/wooden"}, "pattern": ["###", "#C#", "#I#"], "result": {"count": 1, "id": "computercraft:turtle_normal"} } diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/computercraft/speaker.json b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/computercraft/speaker.json index cda30b3495..ce89bd0e53 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/computercraft/speaker.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/computercraft/speaker.json @@ -2,7 +2,7 @@ "type": "computercraft:impostor_shaped", "category": "redstone", "group": "computercraft:turtle_normal", - "key": {"#": {"item": "computercraft:speaker"}, "T": {"item": "computercraft:turtle_normal"}}, + "key": {"#": "computercraft:speaker", "T": "computercraft:turtle_normal"}, "pattern": ["#T"], "result": { "components": {"computercraft:right_turtle_upgrade": {"id": "computercraft:speaker"}}, diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/computercraft/wireless_modem_advanced.json b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/computercraft/wireless_modem_advanced.json index ee6fa8db1a..5240838ba2 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/computercraft/wireless_modem_advanced.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/computercraft/wireless_modem_advanced.json @@ -2,7 +2,7 @@ "type": "computercraft:impostor_shaped", "category": "redstone", "group": "computercraft:turtle_normal", - "key": {"#": {"item": "computercraft:wireless_modem_advanced"}, "T": {"item": "computercraft:turtle_normal"}}, + "key": {"#": "computercraft:wireless_modem_advanced", "T": "computercraft:turtle_normal"}, "pattern": ["#T"], "result": { "components": {"computercraft:right_turtle_upgrade": {"id": "computercraft:wireless_modem_advanced"}}, diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/computercraft/wireless_modem_normal.json b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/computercraft/wireless_modem_normal.json index 845f475796..bf52ce69ac 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/computercraft/wireless_modem_normal.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/computercraft/wireless_modem_normal.json @@ -2,7 +2,7 @@ "type": "computercraft:impostor_shaped", "category": "redstone", "group": "computercraft:turtle_normal", - "key": {"#": {"item": "computercraft:wireless_modem_normal"}, "T": {"item": "computercraft:turtle_normal"}}, + "key": {"#": "computercraft:wireless_modem_normal", "T": "computercraft:turtle_normal"}, "pattern": ["#T"], "result": { "components": {"computercraft:right_turtle_upgrade": {"id": "computercraft:wireless_modem_normal"}}, diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/minecraft/crafting_table.json b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/minecraft/crafting_table.json index 06d5e6e271..911f7b77d1 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/minecraft/crafting_table.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/minecraft/crafting_table.json @@ -2,7 +2,7 @@ "type": "computercraft:impostor_shaped", "category": "redstone", "group": "computercraft:turtle_normal", - "key": {"#": {"item": "minecraft:crafting_table"}, "T": {"item": "computercraft:turtle_normal"}}, + "key": {"#": "minecraft:crafting_table", "T": "computercraft:turtle_normal"}, "pattern": ["#T"], "result": { "components": {"computercraft:right_turtle_upgrade": {"id": "minecraft:crafting_table"}}, diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/minecraft/diamond_axe.json b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/minecraft/diamond_axe.json index 471d4ae222..c9a22f8a01 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/minecraft/diamond_axe.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/minecraft/diamond_axe.json @@ -2,7 +2,7 @@ "type": "computercraft:impostor_shaped", "category": "redstone", "group": "computercraft:turtle_normal", - "key": {"#": {"item": "minecraft:diamond_axe"}, "T": {"item": "computercraft:turtle_normal"}}, + "key": {"#": "minecraft:diamond_axe", "T": "computercraft:turtle_normal"}, "pattern": ["#T"], "result": { "components": {"computercraft:right_turtle_upgrade": {"id": "minecraft:diamond_axe"}}, diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/minecraft/diamond_hoe.json b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/minecraft/diamond_hoe.json index cca3c656af..0e4625798a 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/minecraft/diamond_hoe.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/minecraft/diamond_hoe.json @@ -2,7 +2,7 @@ "type": "computercraft:impostor_shaped", "category": "redstone", "group": "computercraft:turtle_normal", - "key": {"#": {"item": "minecraft:diamond_hoe"}, "T": {"item": "computercraft:turtle_normal"}}, + "key": {"#": "minecraft:diamond_hoe", "T": "computercraft:turtle_normal"}, "pattern": ["#T"], "result": { "components": {"computercraft:right_turtle_upgrade": {"id": "minecraft:diamond_hoe"}}, diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/minecraft/diamond_pickaxe.json b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/minecraft/diamond_pickaxe.json index 7d9dd4e05f..1f1c683ca4 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/minecraft/diamond_pickaxe.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/minecraft/diamond_pickaxe.json @@ -2,7 +2,7 @@ "type": "computercraft:impostor_shaped", "category": "redstone", "group": "computercraft:turtle_normal", - "key": {"#": {"item": "minecraft:diamond_pickaxe"}, "T": {"item": "computercraft:turtle_normal"}}, + "key": {"#": "minecraft:diamond_pickaxe", "T": "computercraft:turtle_normal"}, "pattern": ["#T"], "result": { "components": {"computercraft:right_turtle_upgrade": {"id": "minecraft:diamond_pickaxe"}}, diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/minecraft/diamond_shovel.json b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/minecraft/diamond_shovel.json index b358bb1fb4..a02472c211 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/minecraft/diamond_shovel.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/minecraft/diamond_shovel.json @@ -2,7 +2,7 @@ "type": "computercraft:impostor_shaped", "category": "redstone", "group": "computercraft:turtle_normal", - "key": {"#": {"item": "minecraft:diamond_shovel"}, "T": {"item": "computercraft:turtle_normal"}}, + "key": {"#": "minecraft:diamond_shovel", "T": "computercraft:turtle_normal"}, "pattern": ["#T"], "result": { "components": {"computercraft:right_turtle_upgrade": {"id": "minecraft:diamond_shovel"}}, diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/minecraft/diamond_sword.json b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/minecraft/diamond_sword.json index 145a44b993..ea860023fc 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/minecraft/diamond_sword.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal/minecraft/diamond_sword.json @@ -2,7 +2,7 @@ "type": "computercraft:impostor_shaped", "category": "redstone", "group": "computercraft:turtle_normal", - "key": {"#": {"item": "minecraft:diamond_sword"}, "T": {"item": "computercraft:turtle_normal"}}, + "key": {"#": "minecraft:diamond_sword", "T": "computercraft:turtle_normal"}, "pattern": ["#T"], "result": { "components": {"computercraft:right_turtle_upgrade": {"id": "minecraft:diamond_sword"}}, diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal_overlays/rainbow_flag.json b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal_overlays/rainbow_flag.json index 0e269ef6e9..d9b21c9b5d 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal_overlays/rainbow_flag.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal_overlays/rainbow_flag.json @@ -5,19 +5,19 @@ { "type": "computercraft:copy_components", "exclude": ["computercraft:overlay"], - "from": {"item": "computercraft:turtle_normal"} + "from": "computercraft:turtle_normal" } ], "group": "computercraft:turtle_normal_overlay", "ingredients": [ - {"tag": "c:dyes/red"}, - {"tag": "c:dyes/orange"}, - {"tag": "c:dyes/yellow"}, - {"tag": "c:dyes/green"}, - {"tag": "c:dyes/blue"}, - {"tag": "c:dyes/purple"}, - {"item": "minecraft:stick"}, - {"item": "computercraft:turtle_normal"} + "#c:dyes/red", + "#c:dyes/orange", + "#c:dyes/yellow", + "#c:dyes/green", + "#c:dyes/blue", + "#c:dyes/purple", + "minecraft:stick", + "computercraft:turtle_normal" ], "result": { "components": {"computercraft:overlay": "computercraft:rainbow_flag"}, diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal_overlays/trans_flag.json b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal_overlays/trans_flag.json index 76b8115ee9..7981def31b 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal_overlays/trans_flag.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/turtle_normal_overlays/trans_flag.json @@ -5,16 +5,16 @@ { "type": "computercraft:copy_components", "exclude": ["computercraft:overlay"], - "from": {"item": "computercraft:turtle_normal"} + "from": "computercraft:turtle_normal" } ], "group": "computercraft:turtle_normal_overlay", "ingredients": [ - {"tag": "c:dyes/light_blue"}, - {"tag": "c:dyes/pink"}, - {"tag": "c:dyes/white"}, - {"item": "minecraft:stick"}, - {"item": "computercraft:turtle_normal"} + "#c:dyes/light_blue", + "#c:dyes/pink", + "#c:dyes/white", + "minecraft:stick", + "computercraft:turtle_normal" ], "result": { "components": {"computercraft:overlay": "computercraft:trans_flag"}, diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/wired_modem.json b/projects/common/src/generated/resources/data/computercraft/recipe/wired_modem.json index 77c138e223..b37833ccda 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/wired_modem.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/wired_modem.json @@ -1,7 +1,7 @@ { "type": "minecraft:crafting_shaped", "category": "redstone", - "key": {"#": {"item": "minecraft:stone"}, "R": {"tag": "c:dusts/redstone"}}, + "key": {"#": "minecraft:stone", "R": "#c:dusts/redstone"}, "pattern": ["###", "#R#", "###"], "result": {"count": 1, "id": "computercraft:wired_modem"} } diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/wireless_modem_advanced.json b/projects/common/src/generated/resources/data/computercraft/recipe/wireless_modem_advanced.json index 0b1f48f574..05d5f9dd06 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/wireless_modem_advanced.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/wireless_modem_advanced.json @@ -1,7 +1,7 @@ { "type": "minecraft:crafting_shaped", "category": "redstone", - "key": {"#": {"tag": "c:ingots/gold"}, "E": {"item": "minecraft:ender_eye"}}, + "key": {"#": "#c:ingots/gold", "E": "minecraft:ender_eye"}, "pattern": ["###", "#E#", "###"], "result": {"count": 1, "id": "computercraft:wireless_modem_advanced"} } diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/wireless_modem_normal.json b/projects/common/src/generated/resources/data/computercraft/recipe/wireless_modem_normal.json index 1002c7bac4..2cced2b4dd 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/wireless_modem_normal.json +++ b/projects/common/src/generated/resources/data/computercraft/recipe/wireless_modem_normal.json @@ -1,7 +1,7 @@ { "type": "minecraft:crafting_shaped", "category": "redstone", - "key": {"#": {"item": "minecraft:stone"}, "E": {"tag": "c:ender_pearls"}}, + "key": {"#": "minecraft:stone", "E": "#c:ender_pearls"}, "pattern": ["###", "#E#", "###"], "result": {"count": 1, "id": "computercraft:wireless_modem_normal"} } diff --git a/projects/common/src/generated/resources/data/minecraft/advancement/recipes/misc/wired_modem_from_wired_modem_full.json b/projects/common/src/generated/resources/data/minecraft/advancement/recipes/misc/wired_modem_from_wired_modem_full.json new file mode 100644 index 0000000000..87859d8bcf --- /dev/null +++ b/projects/common/src/generated/resources/data/minecraft/advancement/recipes/misc/wired_modem_from_wired_modem_full.json @@ -0,0 +1,15 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_the_recipe": { + "conditions": {"recipe": "minecraft:wired_modem_from_wired_modem_full"}, + "trigger": "minecraft:recipe_unlocked" + }, + "has_wired_modem_full": { + "conditions": {"items": [{"items": "computercraft:wired_modem_full"}]}, + "trigger": "minecraft:inventory_changed" + } + }, + "requirements": [["has_the_recipe", "has_wired_modem_full"]], + "rewards": {"recipes": ["minecraft:wired_modem_from_wired_modem_full"]} +} diff --git a/projects/common/src/generated/resources/data/minecraft/advancement/recipes/misc/wired_modem_full_from_wired_modem.json b/projects/common/src/generated/resources/data/minecraft/advancement/recipes/misc/wired_modem_full_from_wired_modem.json new file mode 100644 index 0000000000..1bb4011821 --- /dev/null +++ b/projects/common/src/generated/resources/data/minecraft/advancement/recipes/misc/wired_modem_full_from_wired_modem.json @@ -0,0 +1,15 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_the_recipe": { + "conditions": {"recipe": "minecraft:wired_modem_full_from_wired_modem"}, + "trigger": "minecraft:recipe_unlocked" + }, + "has_wired_modem": { + "conditions": {"items": [{"items": "computercraft:wired_modem"}]}, + "trigger": "minecraft:inventory_changed" + } + }, + "requirements": [["has_the_recipe", "has_wired_modem"]], + "rewards": {"recipes": ["minecraft:wired_modem_full_from_wired_modem"]} +} diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/wired_modem_full_to.json b/projects/common/src/generated/resources/data/minecraft/recipe/wired_modem_from_wired_modem_full.json similarity index 54% rename from projects/common/src/generated/resources/data/computercraft/recipe/wired_modem_full_to.json rename to projects/common/src/generated/resources/data/minecraft/recipe/wired_modem_from_wired_modem_full.json index 45c7673c0d..ea7933ee88 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/wired_modem_full_to.json +++ b/projects/common/src/generated/resources/data/minecraft/recipe/wired_modem_from_wired_modem_full.json @@ -1,6 +1,6 @@ { "type": "minecraft:crafting_shapeless", - "category": "redstone", - "ingredients": [{"item": "computercraft:wired_modem_full"}], + "category": "misc", + "ingredients": ["computercraft:wired_modem_full"], "result": {"count": 1, "id": "computercraft:wired_modem"} } diff --git a/projects/common/src/generated/resources/data/computercraft/recipe/wired_modem_full_from.json b/projects/common/src/generated/resources/data/minecraft/recipe/wired_modem_full_from_wired_modem.json similarity index 56% rename from projects/common/src/generated/resources/data/computercraft/recipe/wired_modem_full_from.json rename to projects/common/src/generated/resources/data/minecraft/recipe/wired_modem_full_from_wired_modem.json index 342c81ea39..09a9174f47 100644 --- a/projects/common/src/generated/resources/data/computercraft/recipe/wired_modem_full_from.json +++ b/projects/common/src/generated/resources/data/minecraft/recipe/wired_modem_full_from_wired_modem.json @@ -1,6 +1,6 @@ { "type": "minecraft:crafting_shapeless", - "category": "redstone", - "ingredients": [{"item": "computercraft:wired_modem"}], + "category": "misc", + "ingredients": ["computercraft:wired_modem"], "result": {"count": 1, "id": "computercraft:wired_modem_full"} } diff --git a/projects/common/src/main/java/dan200/computercraft/data/DataProviders.java b/projects/common/src/main/java/dan200/computercraft/data/DataProviders.java index dd68cf5b72..4459a95dd4 100644 --- a/projects/common/src/main/java/dan200/computercraft/data/DataProviders.java +++ b/projects/common/src/main/java/dan200/computercraft/data/DataProviders.java @@ -44,7 +44,7 @@ public static void add(GeneratorSink generator) { var fullRegistries = fullRegistryPatch.thenApply(RegistrySetBuilder.PatchedRegistries::full); generator.registries(fullRegistryPatch); - generator.add(out -> new RecipeProvider(out, fullRegistries)); + generator.add(out -> new RecipeProvider.Runner(out, fullRegistries)); var blockTags = generator.blockTags(TagProvider::blockTags); generator.itemTags(TagProvider::itemTags, blockTags); diff --git a/projects/common/src/main/java/dan200/computercraft/data/LanguageProvider.java b/projects/common/src/main/java/dan200/computercraft/data/LanguageProvider.java index 35a59652fd..f691725456 100644 --- a/projects/common/src/main/java/dan200/computercraft/data/LanguageProvider.java +++ b/projects/common/src/main/java/dan200/computercraft/data/LanguageProvider.java @@ -279,19 +279,18 @@ private void addTranslations() { addConfigEntry(ConfigSpec.monitorWidth, "Max monitor width"); addConfigEntry(ConfigSpec.monitorHeight, "Max monitor height"); - addConfigEntry(ConfigSpec.monitorRenderer, "Monitor renderer"); addConfigEntry(ConfigSpec.monitorDistance, "Monitor distance"); addConfigEntry(ConfigSpec.uploadNagDelay, "Upload nag delay"); } private Stream getExpectedKeys(HolderLookup.Provider registries) { return Stream.of( - BuiltInRegistries.BLOCK.holders() + BuiltInRegistries.BLOCK.listElements() .filter(x -> x.key().location().getNamespace().equals(ComputerCraftAPI.MOD_ID)) .map(x -> x.value().getDescriptionId()) // Exclude blocks that just reuse vanilla translations, such as the lectern. .filter(x -> !x.startsWith("block.minecraft.")), - BuiltInRegistries.ITEM.holders() + BuiltInRegistries.ITEM.listElements() .filter(x -> x.key().location().getNamespace().equals(ComputerCraftAPI.MOD_ID)) .map(x -> x.value().getDescriptionId()), registries.lookupOrThrow(ITurtleUpgrade.REGISTRY).listElements().flatMap(x -> getTranslationKeys(x.value().getAdjective())), diff --git a/projects/common/src/main/java/dan200/computercraft/data/LootTableProvider.java b/projects/common/src/main/java/dan200/computercraft/data/LootTableProvider.java index fab4164b1e..4da833bfd4 100644 --- a/projects/common/src/main/java/dan200/computercraft/data/LootTableProvider.java +++ b/projects/common/src/main/java/dan200/computercraft/data/LootTableProvider.java @@ -59,7 +59,7 @@ private static void registerBlocks(BiConsumer, LootTable. blockDrop(add, ModRegistry.Blocks.LECTERN, LootItem.lootTableItem(Items.LECTERN), ExplosionCondition.survivesExplosion()); - add.accept(ModRegistry.Blocks.CABLE.get().getLootTable(), LootTable + add.accept(ModRegistry.Blocks.CABLE.get().getLootTable().orElseThrow(), LootTable .lootTable() .withPool(LootPool.lootPool() .setRolls(ConstantValue.exactly(1)) @@ -114,7 +114,7 @@ private static void blockDrop( LootItemCondition.Builder condition ) { var block = wrapper.get(); - add.accept(block.getLootTable(), LootTable + add.accept(block.getLootTable().orElseThrow(), LootTable .lootTable() .withPool(LootPool.lootPool() .setRolls(ConstantValue.exactly(1)) diff --git a/projects/common/src/main/java/dan200/computercraft/data/RecipeProvider.java b/projects/common/src/main/java/dan200/computercraft/data/RecipeProvider.java index 257b0a8817..c2a669565e 100644 --- a/projects/common/src/main/java/dan200/computercraft/data/RecipeProvider.java +++ b/projects/common/src/main/java/dan200/computercraft/data/RecipeProvider.java @@ -4,14 +4,11 @@ package dan200.computercraft.data; -import com.google.gson.JsonObject; import com.mojang.authlib.GameProfile; -import com.mojang.serialization.JsonOps; import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.api.pocket.IPocketUpgrade; import dan200.computercraft.api.turtle.ITurtleUpgrade; import dan200.computercraft.api.upgrades.UpgradeData; -import dan200.computercraft.core.util.Colour; import dan200.computercraft.data.recipe.ShapedSpecBuilder; import dan200.computercraft.data.recipe.ShapelessSpecBuilder; import dan200.computercraft.shared.ModRegistry; @@ -24,7 +21,6 @@ import dan200.computercraft.shared.pocket.items.PocketComputerItem; import dan200.computercraft.shared.pocket.recipes.PocketComputerUpgradeRecipe; import dan200.computercraft.shared.recipe.ImpostorShapedRecipe; -import dan200.computercraft.shared.recipe.ImpostorShapelessRecipe; import dan200.computercraft.shared.recipe.TransformShapedRecipe; import dan200.computercraft.shared.recipe.TransformShapelessRecipe; import dan200.computercraft.shared.recipe.function.CopyComponents; @@ -37,6 +33,7 @@ import net.minecraft.advancements.Criterion; import net.minecraft.advancements.critereon.InventoryChangeTrigger; import net.minecraft.advancements.critereon.ItemPredicate; +import net.minecraft.core.HolderGetter; import net.minecraft.core.HolderLookup; import net.minecraft.core.component.DataComponents; import net.minecraft.core.registries.BuiltInRegistries; @@ -44,15 +41,14 @@ import net.minecraft.data.PackOutput; import net.minecraft.data.recipes.RecipeCategory; import net.minecraft.data.recipes.RecipeOutput; -import net.minecraft.data.recipes.ShapedRecipeBuilder; -import net.minecraft.data.recipes.ShapelessRecipeBuilder; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.ItemTags; import net.minecraft.tags.TagKey; -import net.minecraft.util.GsonHelper; -import net.minecraft.world.item.*; -import net.minecraft.world.item.component.DyedItemColor; +import net.minecraft.world.item.DyeColor; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; import net.minecraft.world.item.component.ResolvableProfile; import net.minecraft.world.item.crafting.CraftingBookCategory; import net.minecraft.world.item.crafting.Ingredient; @@ -62,68 +58,46 @@ import java.util.List; import java.util.UUID; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; import java.util.function.Consumer; import static dan200.computercraft.api.ComputerCraftTags.Items.COMPUTER; import static dan200.computercraft.api.ComputerCraftTags.Items.WIRED_MODEM; final class RecipeProvider extends net.minecraft.data.recipes.RecipeProvider { - private final RecipeIngredients ingredients = PlatformHelper.get().getRecipeIngredients(); + private final RecipeIngredients ingredients; + private final HolderGetter items; - private final CompletableFuture registries; - - RecipeProvider(PackOutput output, CompletableFuture registries) { - super(output, registries); - this.registries = registries; - } - - private HolderLookup.Provider registries() { - try { - return registries.get(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new RuntimeException("Interrupted"); - } catch (ExecutionException e) { - var cause = e.getCause(); - throw cause instanceof RuntimeException rt ? rt : new RuntimeException("Unexpected error", cause); - } + RecipeProvider(HolderLookup.Provider registries, RecipeOutput recipeOutput) { + super(registries, recipeOutput); + this.items = registries.lookupOrThrow(Registries.ITEM); + ingredients = PlatformHelper.get().getRecipeIngredients(); } @Override - public void buildRecipes(RecipeOutput add) { - var registries = registries(); - - basicRecipes(add); - diskColours(add); - pocketUpgrades(add, registries); - turtleUpgrades(add, registries); - turtleOverlays(add, registries); - - addSpecial(add, new DiskRecipe(CraftingBookCategory.MISC)); - addSpecial(add, new ColourableRecipe(CraftingBookCategory.MISC)); - addSpecial(add, new ClearColourRecipe(CraftingBookCategory.MISC)); - addSpecial(add, new TurtleUpgradeRecipe(CraftingBookCategory.MISC)); - addSpecial(add, new PocketComputerUpgradeRecipe(CraftingBookCategory.MISC)); + public void buildRecipes() { + basicRecipes(); + diskColours(); + pocketUpgrades(); + turtleUpgrades(); + turtleOverlays(); + + special(new ColourableRecipe(CraftingBookCategory.MISC)); + special(new ClearColourRecipe(CraftingBookCategory.MISC)); + special(new TurtleUpgradeRecipe(CraftingBookCategory.MISC)); + special(new PocketComputerUpgradeRecipe(CraftingBookCategory.MISC)); } /** - * Register a crafting recipe for a disk of every dye colour. - * - * @param output The callback to add recipes. + * Register a disk recipe. */ - private void diskColours(RecipeOutput output) { - for (var colour : Colour.VALUES) { - ShapelessSpecBuilder - .shapeless(RecipeCategory.REDSTONE, DataComponentUtil.createStack(ModRegistry.Items.DISK.get(), DataComponents.DYED_COLOR, new DyedItemColor(colour.getHex(), false))) - .requires(ingredients.redstone()) - .requires(Items.PAPER) - .requires(DyeItem.byColor(ofColour(colour))) - .group("computercraft:disk") - .unlockedBy("has_drive", inventoryChange(ModRegistry.Items.DISK_DRIVE.get())) - .build(ImpostorShapelessRecipe::new) - .save(output, ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "disk_" + (colour.ordinal() + 1))); - } + private void diskColours() { + customShapeless(RecipeCategory.REDSTONE, ModRegistry.Items.DISK.get()) + .requires(ingredients.redstone()) + .requires(Items.PAPER) + .group("computercraft:disk") + .unlockedBy("has_drive", has(ModRegistry.Items.DISK_DRIVE.get())) + .build(d -> new DiskRecipe(d.properties(), d.ingredients())) + .save(output, ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "disk")); } private static List turtleItems() { @@ -132,26 +106,22 @@ private static List turtleItems() { /** * Register a crafting recipe for each turtle upgrade. - * - * @param add The callback to add recipes. - * @param registries The currently available registries. */ - private void turtleUpgrades(RecipeOutput add, HolderLookup.Provider registries) { + private void turtleUpgrades() { for (var turtleItem : turtleItems()) { var name = RegistryHelper.getKeyOrThrow(BuiltInRegistries.ITEM, turtleItem); registries.lookupOrThrow(ITurtleUpgrade.REGISTRY).listElements().forEach(upgradeHolder -> { var upgrade = upgradeHolder.value(); - ShapedSpecBuilder - .shaped(RecipeCategory.REDSTONE, DataComponentUtil.createStack(turtleItem, ModRegistry.DataComponents.RIGHT_TURTLE_UPGRADE.get(), UpgradeData.ofDefault(upgradeHolder))) + customShaped(RecipeCategory.REDSTONE, DataComponentUtil.createStack(turtleItem, ModRegistry.DataComponents.RIGHT_TURTLE_UPGRADE.get(), UpgradeData.ofDefault(upgradeHolder))) .group(name.toString()) .pattern("#T") .define('T', turtleItem) .define('#', upgrade.getCraftingItem().getItem()) - .unlockedBy("has_items", inventoryChange(turtleItem, upgrade.getCraftingItem().getItem())) + .unlockedBy("has_items", has(turtleItem, upgrade.getCraftingItem().getItem())) .build(ImpostorShapedRecipe::new) .save( - add, + output, name.withSuffix(String.format("/%s/%s", upgradeHolder.key().location().getNamespace(), upgradeHolder.key().location().getPath())) ); }); @@ -164,44 +134,40 @@ private static List pocketComputerItems() { /** * Register a crafting recipe for each pocket upgrade. - * - * @param add The callback to add recipes. - * @param registries The currently available registries. */ - private void pocketUpgrades(RecipeOutput add, HolderLookup.Provider registries) { + private void pocketUpgrades() { for (var pocket : pocketComputerItems()) { var name = RegistryHelper.getKeyOrThrow(BuiltInRegistries.ITEM, pocket).withPath(x -> x.replace("pocket_computer_", "pocket_")); registries.lookupOrThrow(IPocketUpgrade.REGISTRY).listElements().forEach(upgradeHolder -> { var upgrade = upgradeHolder.value(); - ShapedSpecBuilder - .shaped(RecipeCategory.REDSTONE, DataComponentUtil.createStack(pocket, ModRegistry.DataComponents.POCKET_UPGRADE.get(), UpgradeData.ofDefault(upgradeHolder))) + customShaped(RecipeCategory.REDSTONE, DataComponentUtil.createStack(pocket, ModRegistry.DataComponents.POCKET_UPGRADE.get(), UpgradeData.ofDefault(upgradeHolder))) .group(name.toString()) .pattern("#") .pattern("P") .define('P', pocket) .define('#', upgrade.getCraftingItem().getItem()) - .unlockedBy("has_items", inventoryChange(pocket, upgrade.getCraftingItem().getItem())) + .unlockedBy("has_items", has(pocket, upgrade.getCraftingItem().getItem())) .build(ImpostorShapedRecipe::new) .save( - add, + output, name.withSuffix(String.format("/%s/%s", upgradeHolder.key().location().getNamespace(), upgradeHolder.key().location().getPath())) ); }); } } - private void turtleOverlays(RecipeOutput add, HolderLookup.Provider registries) { - turtleOverlay(add, registries, TurtleOverlays.TRANS_FLAG, x -> x - .unlockedBy("has_dye", inventoryChange(itemPredicate(ingredients.dye()))) + private void turtleOverlays() { + turtleOverlay(TurtleOverlays.TRANS_FLAG, x -> x + .unlockedBy("has_dye", has(ingredients.dye())) .requires(ColourUtils.getDyeTag(DyeColor.LIGHT_BLUE)) .requires(ColourUtils.getDyeTag(DyeColor.PINK)) .requires(ColourUtils.getDyeTag(DyeColor.WHITE)) .requires(Items.STICK) ); - turtleOverlay(add, registries, TurtleOverlays.RAINBOW_FLAG, x -> x - .unlockedBy("has_dye", inventoryChange(itemPredicate(ingredients.dye()))) + turtleOverlay(TurtleOverlays.RAINBOW_FLAG, x -> x + .unlockedBy("has_dye", has(ingredients.dye())) .requires(ColourUtils.getDyeTag(DyeColor.RED)) .requires(ColourUtils.getDyeTag(DyeColor.ORANGE)) .requires(ColourUtils.getDyeTag(DyeColor.YELLOW)) @@ -212,264 +178,234 @@ private void turtleOverlays(RecipeOutput add, HolderLookup.Provider registries) ); } - private void turtleOverlay(RecipeOutput add, HolderLookup.Provider registries, ResourceKey overlay, Consumer build) { + private void turtleOverlay(ResourceKey overlay, Consumer build) { var holder = registries.lookupOrThrow(overlay.registryKey()).getOrThrow(overlay); for (var turtleItem : turtleItems()) { var name = RegistryHelper.getKeyOrThrow(BuiltInRegistries.ITEM, turtleItem); - var builder = ShapelessSpecBuilder - .shapeless(RecipeCategory.REDSTONE, DataComponentUtil.createStack(turtleItem, ModRegistry.DataComponents.OVERLAY.get(), holder)) + var builder = customShapeless(RecipeCategory.REDSTONE, DataComponentUtil.createStack(turtleItem, ModRegistry.DataComponents.OVERLAY.get(), holder)) .group(name.withSuffix("_overlay").toString()) - .unlockedBy("has_turtle", inventoryChange(turtleItem)); + .unlockedBy("has_turtle", has(turtleItem)); build.accept(builder); builder .requires(turtleItem) .build(s -> new TransformShapelessRecipe(s, List.of( CopyComponents.builder(turtleItem).exclude(ModRegistry.DataComponents.OVERLAY.get()).build() ))) - .save(add, name.withSuffix("_overlays/" + overlay.location().getPath())); + .save(output, name.withSuffix("_overlays/" + overlay.location().getPath())); } } - private void basicRecipes(RecipeOutput add) { - ShapedRecipeBuilder - .shaped(RecipeCategory.REDSTONE, ModRegistry.Items.CABLE.get(), 6) + private void basicRecipes() { + shaped(RecipeCategory.REDSTONE, ModRegistry.Items.CABLE.get(), 6) .pattern(" # ") .pattern("#R#") .pattern(" # ") .define('#', Items.STONE) .define('R', ingredients.redstone()) - .unlockedBy("has_computer", inventoryChange(COMPUTER)) - .unlockedBy("has_modem", inventoryChange(WIRED_MODEM)) - .save(add); + .unlockedBy("has_computer", has(COMPUTER)) + .unlockedBy("has_modem", has(WIRED_MODEM)) + .save(output); - ShapedRecipeBuilder - .shaped(RecipeCategory.REDSTONE, ModRegistry.Items.COMPUTER_NORMAL.get()) + shaped(RecipeCategory.REDSTONE, ModRegistry.Items.COMPUTER_NORMAL.get()) .pattern("###") .pattern("#R#") .pattern("#G#") .define('#', Items.STONE) .define('R', ingredients.redstone()) .define('G', ingredients.glassPane()) - .unlockedBy("has_redstone", inventoryChange(itemPredicate(ingredients.redstone()))) - .save(add); + .unlockedBy("has_redstone", has(ingredients.redstone())) + .save(output); - ShapedRecipeBuilder - .shaped(RecipeCategory.REDSTONE, ModRegistry.Items.COMPUTER_ADVANCED.get()) + shaped(RecipeCategory.REDSTONE, ModRegistry.Items.COMPUTER_ADVANCED.get()) .pattern("###") .pattern("#R#") .pattern("#G#") .define('#', ingredients.goldIngot()) .define('R', ingredients.redstone()) .define('G', ingredients.glassPane()) - .unlockedBy("has_components", inventoryChange(itemPredicate(ingredients.redstone()), itemPredicate(ingredients.goldIngot()))) - .save(add); + .unlockedBy("has_components", inventoryTrigger(itemPredicate(ingredients.redstone()), itemPredicate(ingredients.goldIngot()))) + .save(output); - ShapedSpecBuilder - .shaped(RecipeCategory.REDSTONE, ModRegistry.Items.COMPUTER_ADVANCED.get()) + customShaped(RecipeCategory.REDSTONE, ModRegistry.Items.COMPUTER_ADVANCED.get()) .pattern("###") .pattern("#C#") .pattern("# #") .define('#', ingredients.goldIngot()) .define('C', ModRegistry.Items.COMPUTER_NORMAL.get()) - .unlockedBy("has_components", inventoryChange(itemPredicate(ModRegistry.Items.COMPUTER_NORMAL.get()), itemPredicate(ingredients.goldIngot()))) + .unlockedBy("has_components", inventoryTrigger(itemPredicate(ModRegistry.Items.COMPUTER_NORMAL.get()), itemPredicate(ingredients.goldIngot()))) .build(x -> new TransformShapedRecipe(x, List.of(new CopyComponents(ModRegistry.Items.COMPUTER_NORMAL.get())))) - .save(add, ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "computer_advanced_upgrade")); + .save(output, ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "computer_advanced_upgrade")); - ShapedRecipeBuilder - .shaped(RecipeCategory.REDSTONE, ModRegistry.Items.COMPUTER_COMMAND.get()) + shaped(RecipeCategory.REDSTONE, ModRegistry.Items.COMPUTER_COMMAND.get()) .pattern("###") .pattern("#R#") .pattern("#G#") .define('#', ingredients.goldIngot()) .define('R', Items.COMMAND_BLOCK) .define('G', ingredients.glassPane()) - .unlockedBy("has_components", inventoryChange(Items.COMMAND_BLOCK)) - .save(add); + .unlockedBy("has_components", has(Items.COMMAND_BLOCK)) + .save(output); - ShapedSpecBuilder - .shaped(RecipeCategory.REDSTONE, ModRegistry.Items.TURTLE_NORMAL.get()) + customShaped(RecipeCategory.REDSTONE, ModRegistry.Items.TURTLE_NORMAL.get()) .pattern("###") .pattern("#C#") .pattern("#I#") .define('#', ingredients.ironIngot()) .define('C', ModRegistry.Items.COMPUTER_NORMAL.get()) .define('I', ingredients.woodenChest()) - .unlockedBy("has_computer", inventoryChange(ModRegistry.Items.COMPUTER_NORMAL.get())) + .unlockedBy("has_computer", has(ModRegistry.Items.COMPUTER_NORMAL.get())) .build(x -> new TransformShapedRecipe(x, List.of(new CopyComponents(ModRegistry.Items.COMPUTER_NORMAL.get())))) - .save(add); + .save(output); - ShapedSpecBuilder - .shaped(RecipeCategory.REDSTONE, ModRegistry.Items.TURTLE_ADVANCED.get()) + customShaped(RecipeCategory.REDSTONE, ModRegistry.Items.TURTLE_ADVANCED.get()) .pattern("###") .pattern("#C#") .pattern("#I#") .define('#', ingredients.goldIngot()) .define('C', ModRegistry.Items.COMPUTER_ADVANCED.get()) .define('I', ingredients.woodenChest()) - .unlockedBy("has_computer", inventoryChange(ModRegistry.Items.COMPUTER_NORMAL.get())) + .unlockedBy("has_computer", has(ModRegistry.Items.COMPUTER_NORMAL.get())) .build(x -> new TransformShapedRecipe(x, List.of(new CopyComponents(ModRegistry.Items.COMPUTER_ADVANCED.get())))) - .save(add); + .save(output); - ShapedSpecBuilder - .shaped(RecipeCategory.REDSTONE, ModRegistry.Items.TURTLE_ADVANCED.get()) + customShaped(RecipeCategory.REDSTONE, ModRegistry.Items.TURTLE_ADVANCED.get()) .pattern("###") .pattern("#C#") .pattern(" B ") .define('#', ingredients.goldIngot()) .define('C', ModRegistry.Items.TURTLE_NORMAL.get()) .define('B', ingredients.goldBlock()) - .unlockedBy("has_components", inventoryChange(itemPredicate(ModRegistry.Items.TURTLE_NORMAL.get()), itemPredicate(ingredients.goldIngot()))) + .unlockedBy("has_components", inventoryTrigger(itemPredicate(ModRegistry.Items.TURTLE_NORMAL.get()), itemPredicate(ingredients.goldIngot()))) .build(x -> new TransformShapedRecipe(x, List.of(new CopyComponents(ModRegistry.Items.TURTLE_NORMAL.get())))) - .save(add, ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "turtle_advanced_upgrade")); + .save(output, ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "turtle_advanced_upgrade")); - ShapedRecipeBuilder - .shaped(RecipeCategory.REDSTONE, ModRegistry.Items.DISK_DRIVE.get()) + shaped(RecipeCategory.REDSTONE, ModRegistry.Items.DISK_DRIVE.get()) .pattern("###") .pattern("#R#") .pattern("#R#") .define('#', Items.STONE) .define('R', ingredients.redstone()) - .unlockedBy("has_computer", inventoryChange(COMPUTER)) - .save(add); + .unlockedBy("has_computer", has(COMPUTER)) + .save(output); - ShapedRecipeBuilder - .shaped(RecipeCategory.REDSTONE, ModRegistry.Items.MONITOR_NORMAL.get()) + shaped(RecipeCategory.REDSTONE, ModRegistry.Items.MONITOR_NORMAL.get()) .pattern("###") .pattern("#G#") .pattern("###") .define('#', Items.STONE) .define('G', ingredients.glassPane()) - .unlockedBy("has_computer", inventoryChange(COMPUTER)) - .save(add); + .unlockedBy("has_computer", has(COMPUTER)) + .save(output); - ShapedRecipeBuilder - .shaped(RecipeCategory.REDSTONE, ModRegistry.Items.MONITOR_ADVANCED.get(), 4) + shaped(RecipeCategory.REDSTONE, ModRegistry.Items.MONITOR_ADVANCED.get(), 4) .pattern("###") .pattern("#G#") .pattern("###") .define('#', ingredients.goldIngot()) .define('G', ingredients.glassPane()) - .unlockedBy("has_computer", inventoryChange(COMPUTER)) - .save(add); + .unlockedBy("has_computer", has(COMPUTER)) + .save(output); - ShapedRecipeBuilder - .shaped(RecipeCategory.REDSTONE, ModRegistry.Items.POCKET_COMPUTER_NORMAL.get()) + shaped(RecipeCategory.REDSTONE, ModRegistry.Items.POCKET_COMPUTER_NORMAL.get()) .pattern("###") .pattern("#A#") .pattern("#G#") .define('#', Items.STONE) .define('A', Items.GOLDEN_APPLE) .define('G', ingredients.glassPane()) - .unlockedBy("has_computer", inventoryChange(COMPUTER)) - .unlockedBy("has_apple", inventoryChange(Items.GOLDEN_APPLE)) - .save(add); + .unlockedBy("has_computer", has(COMPUTER)) + .unlockedBy("has_apple", has(Items.GOLDEN_APPLE)) + .save(output); - ShapedRecipeBuilder - .shaped(RecipeCategory.REDSTONE, ModRegistry.Items.POCKET_COMPUTER_ADVANCED.get()) + shaped(RecipeCategory.REDSTONE, ModRegistry.Items.POCKET_COMPUTER_ADVANCED.get()) .pattern("###") .pattern("#A#") .pattern("#G#") .define('#', ingredients.goldIngot()) .define('A', Items.GOLDEN_APPLE) .define('G', ingredients.glassPane()) - .unlockedBy("has_computer", inventoryChange(COMPUTER)) - .unlockedBy("has_apple", inventoryChange(Items.GOLDEN_APPLE)) - .save(add); + .unlockedBy("has_computer", has(COMPUTER)) + .unlockedBy("has_apple", has(Items.GOLDEN_APPLE)) + .save(output); - ShapedSpecBuilder - .shaped(RecipeCategory.REDSTONE, ModRegistry.Items.POCKET_COMPUTER_ADVANCED.get()) + customShaped(RecipeCategory.REDSTONE, ModRegistry.Items.POCKET_COMPUTER_ADVANCED.get()) .pattern("###") .pattern("#C#") .pattern("# #") .define('#', ingredients.goldIngot()) .define('C', ModRegistry.Items.POCKET_COMPUTER_NORMAL.get()) - .unlockedBy("has_components", inventoryChange(itemPredicate(ModRegistry.Items.POCKET_COMPUTER_NORMAL.get()), itemPredicate(ingredients.goldIngot()))) + .unlockedBy("has_components", inventoryTrigger(itemPredicate(ModRegistry.Items.POCKET_COMPUTER_NORMAL.get()), itemPredicate(ingredients.goldIngot()))) .build(x -> new TransformShapedRecipe(x, List.of(new CopyComponents(ModRegistry.Items.POCKET_COMPUTER_NORMAL.get())))) - .save(add, ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "pocket_computer_advanced_upgrade")); + .save(output, ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "pocket_computer_advanced_upgrade")); - ShapedRecipeBuilder - .shaped(RecipeCategory.REDSTONE, ModRegistry.Items.PRINTER.get()) + shaped(RecipeCategory.REDSTONE, ModRegistry.Items.PRINTER.get()) .pattern("###") .pattern("#R#") .pattern("#D#") .define('#', Items.STONE) .define('R', ingredients.redstone()) .define('D', ingredients.dye()) - .unlockedBy("has_computer", inventoryChange(COMPUTER)) - .save(add); + .unlockedBy("has_computer", has(COMPUTER)) + .save(output); - ShapedRecipeBuilder - .shaped(RecipeCategory.REDSTONE, ModRegistry.Items.SPEAKER.get()) + shaped(RecipeCategory.REDSTONE, ModRegistry.Items.SPEAKER.get()) .pattern("###") .pattern("#N#") .pattern("#R#") .define('#', Items.STONE) .define('N', Items.NOTE_BLOCK) .define('R', ingredients.redstone()) - .unlockedBy("has_computer", inventoryChange(COMPUTER)) - .save(add); + .unlockedBy("has_computer", has(COMPUTER)) + .save(output); - ShapedRecipeBuilder - .shaped(RecipeCategory.REDSTONE, ModRegistry.Items.WIRED_MODEM.get()) + shaped(RecipeCategory.REDSTONE, ModRegistry.Items.WIRED_MODEM.get()) .pattern("###") .pattern("#R#") .pattern("###") .define('#', Items.STONE) .define('R', ingredients.redstone()) - .unlockedBy("has_computer", inventoryChange(COMPUTER)) - .unlockedBy("has_cable", inventoryChange(ModRegistry.Items.CABLE.get())) - .save(add); - - ShapelessRecipeBuilder - .shapeless(RecipeCategory.REDSTONE, ModRegistry.Items.WIRED_MODEM_FULL.get()) - .requires(ModRegistry.Items.WIRED_MODEM.get()) - .unlockedBy("has_modem", inventoryChange(WIRED_MODEM)) - .save(add, ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "wired_modem_full_from")); - ShapelessRecipeBuilder - .shapeless(RecipeCategory.REDSTONE, ModRegistry.Items.WIRED_MODEM.get()) - .requires(ModRegistry.Items.WIRED_MODEM_FULL.get()) - .unlockedBy("has_modem", inventoryChange(WIRED_MODEM)) - .save(add, ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "wired_modem_full_to")); - - ShapedRecipeBuilder - .shaped(RecipeCategory.REDSTONE, ModRegistry.Items.WIRELESS_MODEM_NORMAL.get()) + .unlockedBy("has_computer", has(COMPUTER)) + .unlockedBy("has_cable", has(ModRegistry.Items.CABLE.get())) + .save(output); + + oneToOneConversionRecipe(ModRegistry.Items.WIRED_MODEM.get(), ModRegistry.Items.WIRED_MODEM_FULL.get(), null); + oneToOneConversionRecipe(ModRegistry.Items.WIRED_MODEM_FULL.get(), ModRegistry.Items.WIRED_MODEM.get(), null); + + shaped(RecipeCategory.REDSTONE, ModRegistry.Items.WIRELESS_MODEM_NORMAL.get()) .pattern("###") .pattern("#E#") .pattern("###") .define('#', Items.STONE) .define('E', ingredients.enderPearl()) - .unlockedBy("has_computer", inventoryChange(COMPUTER)) - .save(add); + .unlockedBy("has_computer", has(COMPUTER)) + .save(output); - ShapedRecipeBuilder - .shaped(RecipeCategory.REDSTONE, ModRegistry.Items.WIRELESS_MODEM_ADVANCED.get()) + shaped(RecipeCategory.REDSTONE, ModRegistry.Items.WIRELESS_MODEM_ADVANCED.get()) .pattern("###") .pattern("#E#") .pattern("###") .define('#', ingredients.goldIngot()) .define('E', Items.ENDER_EYE) - .unlockedBy("has_computer", inventoryChange(COMPUTER)) - .unlockedBy("has_wireless", inventoryChange(ModRegistry.Items.WIRELESS_MODEM_NORMAL.get())) - .save(add); + .unlockedBy("has_computer", has(COMPUTER)) + .unlockedBy("has_wireless", has(ModRegistry.Items.WIRELESS_MODEM_NORMAL.get())) + .save(output); - ShapelessSpecBuilder - .shapeless(RecipeCategory.DECORATIONS, playerHead("Cloudhunter", "6d074736-b1e9-4378-a99b-bd8777821c9c")) + customShapeless(RecipeCategory.DECORATIONS, playerHead("Cloudhunter", "6d074736-b1e9-4378-a99b-bd8777821c9c")) .requires(ItemTags.SKULLS) .requires(ModRegistry.Items.MONITOR_NORMAL.get()) - .unlockedBy("has_monitor", inventoryChange(ModRegistry.Items.MONITOR_NORMAL.get())) + .unlockedBy("has_monitor", has(ModRegistry.Items.MONITOR_NORMAL.get())) .build() - .save(add, ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "skull_cloudy")); + .save(output, ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "skull_cloudy")); - ShapelessSpecBuilder - .shapeless(RecipeCategory.DECORATIONS, playerHead("dan200", "f3c8d69b-0776-4512-8434-d1b2165909eb")) + customShapeless(RecipeCategory.DECORATIONS, playerHead("dan200", "f3c8d69b-0776-4512-8434-d1b2165909eb")) .requires(ItemTags.SKULLS) .requires(ModRegistry.Items.COMPUTER_ADVANCED.get()) - .unlockedBy("has_computer", inventoryChange(ModRegistry.Items.COMPUTER_ADVANCED.get())) + .unlockedBy("has_computer", has(ModRegistry.Items.COMPUTER_ADVANCED.get())) .build() - .save(add, ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "skull_dan200")); + .save(output, ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "skull_dan200")); var pages = Ingredient.of( ModRegistry.Items.PRINTED_PAGE.get(), @@ -477,65 +413,74 @@ private void basicRecipes(RecipeOutput add) { Items.PAPER ); - ShapelessSpecBuilder - .shapeless(RecipeCategory.REDSTONE, ModRegistry.Items.PRINTED_PAGES.get()) + customShapeless(RecipeCategory.REDSTONE, ModRegistry.Items.PRINTED_PAGES.get()) .requires(ingredients.string()) - .unlockedBy("has_printer", inventoryChange(ModRegistry.Items.PRINTER.get())) + .unlockedBy("has_printer", has(ModRegistry.Items.PRINTER.get())) .build(x -> new PrintoutRecipe(x, pages, 2)) - .save(add); + .save(output); - ShapelessSpecBuilder - .shapeless(RecipeCategory.REDSTONE, ModRegistry.Items.PRINTED_BOOK.get()) + customShapeless(RecipeCategory.REDSTONE, ModRegistry.Items.PRINTED_BOOK.get()) .requires(ingredients.leather()) .requires(ingredients.string()) - .unlockedBy("has_printer", inventoryChange(ModRegistry.Items.PRINTER.get())) + .unlockedBy("has_printer", has(ModRegistry.Items.PRINTER.get())) .build(x -> new PrintoutRecipe(x, pages, 1)) - .save(add); + .save(output); } - private static DyeColor ofColour(Colour colour) { - return DyeColor.byId(15 - colour.ordinal()); + private static Criterion has(ItemLike... items) { + return InventoryChangeTrigger.TriggerInstance.hasItems(items); } - private static Criterion inventoryChange(TagKey stack) { - return InventoryChangeTrigger.TriggerInstance.hasItems(itemPredicate(stack)); + private ItemPredicate itemPredicate(ItemLike item) { + return ItemPredicate.Builder.item().of(items, item).build(); } - private static Criterion inventoryChange(ItemLike... stack) { - return InventoryChangeTrigger.TriggerInstance.hasItems(stack); + private ItemPredicate itemPredicate(TagKey item) { + return ItemPredicate.Builder.item().of(items, item).build(); } - private static Criterion inventoryChange(ItemPredicate... items) { - return InventoryChangeTrigger.TriggerInstance.hasItems(items); + private static ItemStack playerHead(String name, String uuid) { + return DataComponentUtil.createStack(Items.PLAYER_HEAD, DataComponents.PROFILE, new ResolvableProfile(new GameProfile(UUID.fromString(uuid), name))); } - private static ItemPredicate itemPredicate(ItemLike item) { - return ItemPredicate.Builder.item().of(item).build(); + private ShapedSpecBuilder customShaped(RecipeCategory category, ItemStack result) { + return new ShapedSpecBuilder(items, category, result); } - private static ItemPredicate itemPredicate(TagKey item) { - return ItemPredicate.Builder.item().of(item).build(); + private ShapedSpecBuilder customShaped(RecipeCategory category, ItemLike result) { + return new ShapedSpecBuilder(items, category, new ItemStack(result)); } - private static ItemPredicate itemPredicate(Ingredient ingredient) { - var json = Ingredient.CODEC_NONEMPTY.encodeStart(JsonOps.INSTANCE, ingredient).getOrThrow(); - if (!(json instanceof JsonObject object)) throw new IllegalStateException("Unknown ingredient " + json); - - if (object.has("item")) { - var item = ItemStack.SIMPLE_ITEM_CODEC.parse(JsonOps.INSTANCE, object).getOrThrow(); - return itemPredicate(item.getItem()); - } else if (object.has("tag")) { - return itemPredicate(TagKey.create(Registries.ITEM, ResourceLocation.parse(GsonHelper.getAsString(object, "tag")))); - } else { - throw new IllegalArgumentException("Unknown ingredient " + json); - } + private ShapelessSpecBuilder customShapeless(RecipeCategory category, ItemStack result) { + return new ShapelessSpecBuilder(items, category, result); } - private static ItemStack playerHead(String name, String uuid) { - return DataComponentUtil.createStack(Items.PLAYER_HEAD, DataComponents.PROFILE, new ResolvableProfile(new GameProfile(UUID.fromString(uuid), name))); + private ShapelessSpecBuilder customShapeless(RecipeCategory category, ItemLike result) { + return new ShapelessSpecBuilder(items, category, new ItemStack(result)); + } + + private void special(Recipe recipe) { + var key = RegistryHelper.getKeyOrThrow(BuiltInRegistries.RECIPE_SERIALIZER, recipe.getSerializer()); + output.accept(recipeKey(key), recipe, null); + } + + public static ResourceKey> recipeKey(ResourceLocation key) { + return ResourceKey.create(Registries.RECIPE, key); } - private static void addSpecial(RecipeOutput add, Recipe recipe) { - add.accept(RegistryHelper.getKeyOrThrow(BuiltInRegistries.RECIPE_SERIALIZER, recipe.getSerializer()), recipe, null); + static class Runner extends net.minecraft.data.recipes.RecipeProvider.Runner { + protected Runner(PackOutput output, CompletableFuture registries) { + super(output, registries); + } + + @Override + protected RecipeProvider createRecipeProvider(HolderLookup.Provider registries, RecipeOutput output) { + return new RecipeProvider(registries, output); + } + + @Override + public String getName() { + return "Recipes"; + } } } diff --git a/projects/common/src/main/java/dan200/computercraft/data/recipe/AbstractRecipeBuilder.java b/projects/common/src/main/java/dan200/computercraft/data/recipe/AbstractRecipeBuilder.java index 3b1e55590a..5648d17318 100644 --- a/projects/common/src/main/java/dan200/computercraft/data/recipe/AbstractRecipeBuilder.java +++ b/projects/common/src/main/java/dan200/computercraft/data/recipe/AbstractRecipeBuilder.java @@ -10,9 +10,12 @@ import net.minecraft.advancements.AdvancementRewards; import net.minecraft.advancements.Criterion; import net.minecraft.advancements.critereon.RecipeUnlockedTrigger; +import net.minecraft.core.HolderGetter; +import net.minecraft.core.registries.Registries; import net.minecraft.data.recipes.RecipeBuilder; import net.minecraft.data.recipes.RecipeCategory; import net.minecraft.data.recipes.RecipeOutput; +import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; @@ -30,12 +33,14 @@ * @see ShapelessSpecBuilder */ public abstract class AbstractRecipeBuilder, O> { + protected final HolderGetter items; private final RecipeCategory category; protected final ItemStack result; private String group = ""; private final Map> criteria = new LinkedHashMap<>(); - protected AbstractRecipeBuilder(RecipeCategory category, ItemStack result) { + protected AbstractRecipeBuilder(HolderGetter items, RecipeCategory category, ItemStack result) { + this.items = items; this.category = category; this.result = result; } @@ -112,17 +117,23 @@ private FinishedRecipe(Recipe recipe, Item result, RecipeCategory category, M public void save(RecipeOutput output, ResourceLocation id) { if (criteria.isEmpty()) throw new IllegalStateException("No way of obtaining recipe " + id); + + var key = recipeKey(id); var advancement = output.advancement() - .addCriterion("has_the_recipe", RecipeUnlockedTrigger.unlocked(id)) - .rewards(AdvancementRewards.Builder.recipe(id)) + .addCriterion("has_the_recipe", RecipeUnlockedTrigger.unlocked(key)) + .rewards(AdvancementRewards.Builder.recipe(key)) .requirements(AdvancementRequirements.Strategy.OR); for (var entry : criteria.entrySet()) advancement.addCriterion(entry.getKey(), entry.getValue()); - output.accept(id, recipe, advancement.build(id.withPrefix("recipes/" + category.getFolderName() + "/"))); + output.accept(key, recipe, advancement.build(id.withPrefix("recipes/" + category.getFolderName() + "/"))); } public void save(RecipeOutput output) { save(output, RecipeBuilder.getDefaultRecipeId(result)); } } + + protected static ResourceKey> recipeKey(ResourceLocation key) { + return ResourceKey.create(Registries.RECIPE, key); + } } diff --git a/projects/common/src/main/java/dan200/computercraft/data/recipe/ShapedSpecBuilder.java b/projects/common/src/main/java/dan200/computercraft/data/recipe/ShapedSpecBuilder.java index fbb2e97f58..200008a784 100644 --- a/projects/common/src/main/java/dan200/computercraft/data/recipe/ShapedSpecBuilder.java +++ b/projects/common/src/main/java/dan200/computercraft/data/recipe/ShapedSpecBuilder.java @@ -6,6 +6,7 @@ import dan200.computercraft.shared.recipe.RecipeProperties; import dan200.computercraft.shared.recipe.ShapedRecipeSpec; +import net.minecraft.core.HolderGetter; import net.minecraft.data.recipes.RecipeCategory; import net.minecraft.data.recipes.ShapedRecipeBuilder; import net.minecraft.tags.TagKey; @@ -27,16 +28,8 @@ public final class ShapedSpecBuilder extends AbstractRecipeBuilder rows = new ArrayList<>(); private final Map key = new LinkedHashMap<>(); - private ShapedSpecBuilder(RecipeCategory category, ItemStack result) { - super(category, result); - } - - public static ShapedSpecBuilder shaped(RecipeCategory category, ItemStack result) { - return new ShapedSpecBuilder(category, result); - } - - public static ShapedSpecBuilder shaped(RecipeCategory category, ItemLike result) { - return new ShapedSpecBuilder(category, new ItemStack(result)); + public ShapedSpecBuilder(HolderGetter items, RecipeCategory category, ItemStack result) { + super(items, category, result); } public ShapedSpecBuilder define(char key, Ingredient ingredient) { @@ -48,7 +41,7 @@ public ShapedSpecBuilder define(char key, Ingredient ingredient) { } public ShapedSpecBuilder define(char key, TagKey tag) { - return this.define(key, Ingredient.of(tag)); + return this.define(key, Ingredient.of(items.getOrThrow(tag))); } public ShapedSpecBuilder define(char key, ItemLike item) { diff --git a/projects/common/src/main/java/dan200/computercraft/data/recipe/ShapelessSpecBuilder.java b/projects/common/src/main/java/dan200/computercraft/data/recipe/ShapelessSpecBuilder.java index 245eeb01a4..f3932f68c3 100644 --- a/projects/common/src/main/java/dan200/computercraft/data/recipe/ShapelessSpecBuilder.java +++ b/projects/common/src/main/java/dan200/computercraft/data/recipe/ShapelessSpecBuilder.java @@ -6,6 +6,7 @@ import dan200.computercraft.shared.recipe.RecipeProperties; import dan200.computercraft.shared.recipe.ShapelessRecipeSpec; +import net.minecraft.core.HolderGetter; import net.minecraft.core.NonNullList; import net.minecraft.data.recipes.RecipeCategory; import net.minecraft.data.recipes.ShapelessRecipeBuilder; @@ -21,20 +22,12 @@ public final class ShapelessSpecBuilder extends AbstractRecipeBuilder { private final NonNullList ingredients = NonNullList.create(); - private ShapelessSpecBuilder(RecipeCategory category, ItemStack result) { - super(category, result); - } - - public static ShapelessSpecBuilder shapeless(RecipeCategory category, ItemStack result) { - return new ShapelessSpecBuilder(category, result); - } - - public static ShapelessSpecBuilder shapeless(RecipeCategory category, ItemLike result) { - return new ShapelessSpecBuilder(category, new ItemStack(result)); + public ShapelessSpecBuilder(HolderGetter items, RecipeCategory category, ItemStack result) { + super(items, category, result); } public ShapelessSpecBuilder requires(Ingredient ingredient, int count) { - for (int i = 0; i < count; i++) ingredients.add(ingredient); + for (var i = 0; i < count; i++) ingredients.add(ingredient); return this; } @@ -43,15 +36,15 @@ public ShapelessSpecBuilder requires(Ingredient ingredient) { } public ShapelessSpecBuilder requires(ItemLike item) { - return requires(Ingredient.of(new ItemStack(item))); + return requires(Ingredient.of(item)); } public ShapelessSpecBuilder requires(ItemLike item, int count) { - return requires(Ingredient.of(new ItemStack(item)), count); + return requires(Ingredient.of(item), count); } public ShapelessSpecBuilder requires(TagKey item) { - return requires(Ingredient.of(item)); + return requires(Ingredient.of(items.getOrThrow(item))); } @Override diff --git a/projects/forge/src/main/java/dan200/computercraft/mixin/V3818_3Mixin.java b/projects/common/src/main/java/dan200/computercraft/mixin/V3818_3Mixin.java similarity index 68% rename from projects/forge/src/main/java/dan200/computercraft/mixin/V3818_3Mixin.java rename to projects/common/src/main/java/dan200/computercraft/mixin/V3818_3Mixin.java index 710f5c0563..f93ead5508 100644 --- a/projects/forge/src/main/java/dan200/computercraft/mixin/V3818_3Mixin.java +++ b/projects/common/src/main/java/dan200/computercraft/mixin/V3818_3Mixin.java @@ -12,6 +12,9 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; +import java.util.SequencedMap; +import java.util.function.Supplier; + /** * Add our custom data components to the datafixer system. *

@@ -19,9 +22,10 @@ */ @Mixin(V3818_3.class) class V3818_3Mixin { - @ModifyReturnValue(method = "lambda$registerTypes$0", at = @At("TAIL")) + @ModifyReturnValue(method = "components", at = @At("TAIL")) @SuppressWarnings("UnusedMethod") - private static TypeTemplate addExtraTypes(TypeTemplate type, Schema schema) { - return ComponentizationFixers.addExtraTypes(type, schema); + private static SequencedMap> components(SequencedMap> types, Schema schema) { + ComponentizationFixers.addExtraTypes(types, schema); + return types; } } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/ModRegistry.java b/projects/common/src/main/java/dan200/computercraft/shared/ModRegistry.java index 72388e40db..56c56c1b56 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/ModRegistry.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/ModRegistry.java @@ -103,6 +103,8 @@ import net.minecraft.network.chat.Component; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; import net.minecraft.world.flag.FeatureFlags; import net.minecraft.world.inventory.MenuType; import net.minecraft.world.item.BlockItem; @@ -113,20 +115,16 @@ import net.minecraft.world.item.crafting.CustomRecipe; import net.minecraft.world.item.crafting.Recipe; import net.minecraft.world.item.crafting.RecipeSerializer; -import net.minecraft.world.item.crafting.SimpleCraftingRecipeSerializer; import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.SoundType; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.properties.NoteBlockInstrument; import net.minecraft.world.level.material.MapColor; import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType; import java.util.Objects; -import java.util.function.BiFunction; -import java.util.function.Predicate; -import java.util.function.UnaryOperator; +import java.util.Set; +import java.util.function.*; /** * Registers ComputerCraft's registry entries and additional objects, such as {@link CauldronInteraction}s and @@ -141,6 +139,13 @@ private ModRegistry() { public static final class Blocks { static final RegistrationHelper REGISTRY = PlatformHelper.get().createRegistrationHelper(Registries.BLOCK); + private static RegistryEntry register(String name, Function build, BlockBehaviour.Properties properties) { + return REGISTRY.register(name, () -> { + properties.setId(ResourceKey.create(Registries.BLOCK, ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, name))); + return build.apply(properties); + }); + } + private static BlockBehaviour.Properties properties() { return BlockBehaviour.Properties.of().strength(2); } @@ -159,46 +164,47 @@ private static BlockBehaviour.Properties modemProperties() { return BlockBehaviour.Properties.of().strength(1.5f); } - public static final RegistryEntry> COMPUTER_NORMAL = REGISTRY.register("computer_normal", - () -> new ComputerBlock<>(computerProperties().mapColor(MapColor.STONE), BlockEntities.COMPUTER_NORMAL)); - public static final RegistryEntry> COMPUTER_ADVANCED = REGISTRY.register("computer_advanced", - () -> new ComputerBlock<>(computerProperties().mapColor(MapColor.GOLD), BlockEntities.COMPUTER_ADVANCED)); - public static final RegistryEntry> COMPUTER_COMMAND = REGISTRY.register("computer_command", - () -> new CommandComputerBlock<>(computerProperties().strength(-1, 6000000.0F), BlockEntities.COMPUTER_COMMAND)); - - public static final RegistryEntry TURTLE_NORMAL = REGISTRY.register("turtle_normal", - () -> new TurtleBlock(turtleProperties().mapColor(MapColor.STONE), BlockEntities.TURTLE_NORMAL)); - public static final RegistryEntry TURTLE_ADVANCED = REGISTRY.register("turtle_advanced", - () -> new TurtleBlock(turtleProperties().mapColor(MapColor.GOLD).explosionResistance(TurtleBlock.IMMUNE_EXPLOSION_RESISTANCE), BlockEntities.TURTLE_ADVANCED)); - - public static final RegistryEntry SPEAKER = REGISTRY.register("speaker", () -> new SpeakerBlock(properties().mapColor(MapColor.STONE))); - public static final RegistryEntry DISK_DRIVE = REGISTRY.register("disk_drive", () -> new DiskDriveBlock(properties().mapColor(MapColor.STONE))); - public static final RegistryEntry PRINTER = REGISTRY.register("printer", () -> new PrinterBlock(properties().mapColor(MapColor.STONE))); - - public static final RegistryEntry MONITOR_NORMAL = REGISTRY.register("monitor_normal", - () -> new MonitorBlock(properties().mapColor(MapColor.STONE), BlockEntities.MONITOR_NORMAL)); - public static final RegistryEntry MONITOR_ADVANCED = REGISTRY.register("monitor_advanced", - () -> new MonitorBlock(properties().mapColor(MapColor.GOLD), BlockEntities.MONITOR_ADVANCED)); - - public static final RegistryEntry WIRELESS_MODEM_NORMAL = REGISTRY.register("wireless_modem_normal", - () -> new WirelessModemBlock(properties().mapColor(MapColor.STONE), BlockEntities.WIRELESS_MODEM_NORMAL)); - public static final RegistryEntry WIRELESS_MODEM_ADVANCED = REGISTRY.register("wireless_modem_advanced", - () -> new WirelessModemBlock(properties().mapColor(MapColor.GOLD), BlockEntities.WIRELESS_MODEM_ADVANCED)); - - public static final RegistryEntry WIRED_MODEM_FULL = REGISTRY.register("wired_modem_full", - () -> new WiredModemFullBlock(modemProperties().mapColor(MapColor.STONE))); - public static final RegistryEntry CABLE = REGISTRY.register("cable", () -> new CableBlock(modemProperties().mapColor(MapColor.STONE))); - - public static final RegistryEntry LECTERN = REGISTRY.register("lectern", () -> new CustomLecternBlock( - BlockBehaviour.Properties.of().mapColor(MapColor.WOOD).instrument(NoteBlockInstrument.BASS).strength(2.5F).sound(SoundType.WOOD).ignitedByLava() - )); + public static final RegistryEntry> COMPUTER_NORMAL = register("computer_normal", + p -> new ComputerBlock<>(p, BlockEntities.COMPUTER_NORMAL), computerProperties().mapColor(MapColor.STONE)); + public static final RegistryEntry> COMPUTER_ADVANCED = register("computer_advanced", + p -> new ComputerBlock<>(p, BlockEntities.COMPUTER_ADVANCED), computerProperties().mapColor(MapColor.GOLD)); + public static final RegistryEntry> COMPUTER_COMMAND = register("computer_command", + p -> new CommandComputerBlock<>(p, BlockEntities.COMPUTER_COMMAND), computerProperties().strength(-1, 6000000.0F)); + + public static final RegistryEntry TURTLE_NORMAL = register("turtle_normal", + p -> new TurtleBlock(p, BlockEntities.TURTLE_NORMAL), turtleProperties().mapColor(MapColor.STONE)); + public static final RegistryEntry TURTLE_ADVANCED = register("turtle_advanced", + p -> new TurtleBlock(p, BlockEntities.TURTLE_ADVANCED), turtleProperties().mapColor(MapColor.GOLD).explosionResistance(TurtleBlock.IMMUNE_EXPLOSION_RESISTANCE)); + + public static final RegistryEntry SPEAKER = register("speaker", SpeakerBlock::new, properties().mapColor(MapColor.STONE)); + public static final RegistryEntry DISK_DRIVE = register("disk_drive", DiskDriveBlock::new, properties().mapColor(MapColor.STONE)); + public static final RegistryEntry PRINTER = register("printer", PrinterBlock::new, properties().mapColor(MapColor.STONE)); + + public static final RegistryEntry MONITOR_NORMAL = register("monitor_normal", + p -> new MonitorBlock(p, BlockEntities.MONITOR_NORMAL), properties().mapColor(MapColor.STONE)); + public static final RegistryEntry MONITOR_ADVANCED = register("monitor_advanced", + p -> new MonitorBlock(p, BlockEntities.MONITOR_ADVANCED), properties().mapColor(MapColor.GOLD)); + + public static final RegistryEntry WIRELESS_MODEM_NORMAL = register("wireless_modem_normal", + p -> new WirelessModemBlock(p, BlockEntities.WIRELESS_MODEM_NORMAL), properties().mapColor(MapColor.STONE)); + public static final RegistryEntry WIRELESS_MODEM_ADVANCED = register("wireless_modem_advanced", + p -> new WirelessModemBlock(p, BlockEntities.WIRELESS_MODEM_ADVANCED), properties().mapColor(MapColor.GOLD)); + + public static final RegistryEntry WIRED_MODEM_FULL = register("wired_modem_full", + WiredModemFullBlock::new, modemProperties().mapColor(MapColor.STONE)); + public static final RegistryEntry CABLE = register("cable", CableBlock::new, modemProperties().mapColor(MapColor.STONE)); + + public static final RegistryEntry LECTERN = register("lectern", CustomLecternBlock::new, + BlockBehaviour.Properties.ofFullCopy(net.minecraft.world.level.block.Blocks.LECTERN) + .overrideDescription(net.minecraft.world.level.block.Blocks.LECTERN.getDescriptionId()) + ); } public static class BlockEntities { static final RegistrationHelper> REGISTRY = PlatformHelper.get().createRegistrationHelper(Registries.BLOCK_ENTITY_TYPE); private static RegistryEntry> ofBlock(RegistryEntry block, BlockEntityType.BlockEntitySupplier factory) { - return REGISTRY.register(block.id().getPath(), () -> BlockEntityType.Builder.of(factory, block.get()).build(null)); + return REGISTRY.register(block.id().getPath(), () -> new BlockEntityType<>(factory, Set.of(block.get()))); } public static final RegistryEntry> MONITOR_NORMAL = @@ -244,37 +250,45 @@ private static Item.Properties properties() { return new Item.Properties(); } + private static RegistryEntry register(String name, Function build, Supplier properties) { + return REGISTRY.register(name, () -> build.apply(properties.get().setId(ResourceKey.create(Registries.ITEM, ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, name))))); + } + + private static RegistryEntry register(String name, Function build, Item.Properties properties) { + return register(name, build, () -> properties); + } + private static RegistryEntry ofBlock(RegistryEntry parent, BiFunction supplier) { - return REGISTRY.register(parent.id().getPath(), () -> supplier.apply(parent.get(), properties())); + return register(parent.id().getPath(), p -> supplier.apply(parent.get(), p), properties().useBlockDescriptionPrefix()); } public static final RegistryEntry COMPUTER_NORMAL = ofBlock(Blocks.COMPUTER_NORMAL, ComputerItem::new); public static final RegistryEntry COMPUTER_ADVANCED = ofBlock(Blocks.COMPUTER_ADVANCED, ComputerItem::new); public static final RegistryEntry COMPUTER_COMMAND = ofBlock(Blocks.COMPUTER_COMMAND, CommandComputerItem::new); - public static final RegistryEntry POCKET_COMPUTER_NORMAL = REGISTRY.register("pocket_computer_normal", - () -> new PocketComputerItem(properties().stacksTo(1), ComputerFamily.NORMAL)); - public static final RegistryEntry POCKET_COMPUTER_ADVANCED = REGISTRY.register("pocket_computer_advanced", - () -> new PocketComputerItem(properties().stacksTo(1), ComputerFamily.ADVANCED)); + public static final RegistryEntry POCKET_COMPUTER_NORMAL = register("pocket_computer_normal", + p -> new PocketComputerItem(p, ComputerFamily.NORMAL), properties().stacksTo(1)); + public static final RegistryEntry POCKET_COMPUTER_ADVANCED = register("pocket_computer_advanced", + p -> new PocketComputerItem(p, ComputerFamily.ADVANCED), properties().stacksTo(1)); public static final RegistryEntry TURTLE_NORMAL = ofBlock(Blocks.TURTLE_NORMAL, TurtleItem::new); public static final RegistryEntry TURTLE_ADVANCED = ofBlock(Blocks.TURTLE_ADVANCED, TurtleItem::new); public static final RegistryEntry DISK = - REGISTRY.register("disk", () -> new DiskItem(properties().stacksTo(1))); + register("disk", DiskItem::new, properties().stacksTo(1)); public static final RegistryEntry TREASURE_DISK = - REGISTRY.register("treasure_disk", () -> new TreasureDiskItem(properties().stacksTo(1))); + register("treasure_disk", TreasureDiskItem::new, properties().stacksTo(1)); private static Item.Properties printoutProperties() { return properties().stacksTo(1).component(DataComponents.PRINTOUT.get(), PrintoutData.EMPTY); } - public static final RegistryEntry PRINTED_PAGE = REGISTRY.register("printed_page", - () -> new PrintoutItem(printoutProperties(), PrintoutItem.Type.PAGE)); - public static final RegistryEntry PRINTED_PAGES = REGISTRY.register("printed_pages", - () -> new PrintoutItem(printoutProperties(), PrintoutItem.Type.PAGES)); - public static final RegistryEntry PRINTED_BOOK = REGISTRY.register("printed_book", - () -> new PrintoutItem(printoutProperties(), PrintoutItem.Type.BOOK)); + public static final RegistryEntry PRINTED_PAGE = register("printed_page", + p -> new PrintoutItem(p, PrintoutItem.Type.PAGE), Items::printoutProperties); + public static final RegistryEntry PRINTED_PAGES = register("printed_pages", + p -> new PrintoutItem(p, PrintoutItem.Type.PAGES), Items::printoutProperties); + public static final RegistryEntry PRINTED_BOOK = register("printed_book", + p -> new PrintoutItem(p, PrintoutItem.Type.BOOK), Items::printoutProperties); public static final RegistryEntry SPEAKER = ofBlock(Blocks.SPEAKER, BlockItem::new); public static final RegistryEntry DISK_DRIVE = ofBlock(Blocks.DISK_DRIVE, BlockItem::new); @@ -285,10 +299,10 @@ private static Item.Properties printoutProperties() { public static final RegistryEntry WIRELESS_MODEM_ADVANCED = ofBlock(Blocks.WIRELESS_MODEM_ADVANCED, BlockItem::new); public static final RegistryEntry WIRED_MODEM_FULL = ofBlock(Blocks.WIRED_MODEM_FULL, BlockItem::new); - public static final RegistryEntry CABLE = REGISTRY.register("cable", - () -> new CableBlockItem.Cable(Blocks.CABLE.get(), properties())); - public static final RegistryEntry WIRED_MODEM = REGISTRY.register("wired_modem", - () -> new CableBlockItem.WiredModem(Blocks.CABLE.get(), properties())); + public static final RegistryEntry CABLE = register("cable", + p -> new CableBlockItem.Cable(Blocks.CABLE.get(), p), properties().useBlockDescriptionPrefix()); + public static final RegistryEntry WIRED_MODEM = register("wired_modem", + p -> new CableBlockItem.WiredModem(Blocks.CABLE.get(), p), properties().useBlockDescriptionPrefix()); } public static final class DataComponents { @@ -481,8 +495,8 @@ public static class LootItemConditionTypes { public static class RecipeSerializers { static final RegistrationHelper> REGISTRY = PlatformHelper.get().createRegistrationHelper(Registries.RECIPE_SERIALIZER); - private static RegistryEntry> simple(String name, SimpleCraftingRecipeSerializer.Factory factory) { - return REGISTRY.register(name, () -> new SimpleCraftingRecipeSerializer<>(factory)); + private static RegistryEntry> simple(String name, CustomRecipe.Serializer.Factory factory) { + return REGISTRY.register(name, () -> new CustomRecipe.Serializer<>(factory)); } private static > RegistryEntry> register(String name, MapCodec codec, StreamCodec streamCodec) { @@ -495,12 +509,12 @@ private static > RegistryEntry> register public static final RegistryEntry> TRANSFORM_SHAPED = register("transform_shaped", TransformShapedRecipe.CODEC, TransformShapedRecipe.STREAM_CODEC); public static final RegistryEntry> TRANSFORM_SHAPELESS = register("transform_shapeless", TransformShapelessRecipe.CODEC, TransformShapelessRecipe.STREAM_CODEC); - public static final RegistryEntry> DYEABLE_ITEM = simple("colour", ColourableRecipe::new); - public static final RegistryEntry> DYEABLE_ITEM_CLEAR = simple("clear_colour", ClearColourRecipe::new); - public static final RegistryEntry> TURTLE_UPGRADE = simple("turtle_upgrade", TurtleUpgradeRecipe::new); - public static final RegistryEntry> POCKET_COMPUTER_UPGRADE = simple("pocket_computer_upgrade", PocketComputerUpgradeRecipe::new); + public static final RegistryEntry> DYEABLE_ITEM = simple("colour", ColourableRecipe::new); + public static final RegistryEntry> DYEABLE_ITEM_CLEAR = simple("clear_colour", ClearColourRecipe::new); + public static final RegistryEntry> TURTLE_UPGRADE = simple("turtle_upgrade", TurtleUpgradeRecipe::new); + public static final RegistryEntry> POCKET_COMPUTER_UPGRADE = simple("pocket_computer_upgrade", PocketComputerUpgradeRecipe::new); public static final RegistryEntry> PRINTOUT = register("printout", PrintoutRecipe.CODEC, PrintoutRecipe.STREAM_CODEC); - public static final RegistryEntry> DISK = simple("disk", DiskRecipe::new); + public static final RegistryEntry> DISK = register("disk", DiskRecipe.CODEC, DiskRecipe.STREAM_CODEC); } public static class RecipeFunctions { diff --git a/projects/common/src/main/java/dan200/computercraft/shared/command/CommandComputerCraft.java b/projects/common/src/main/java/dan200/computercraft/shared/command/CommandComputerCraft.java index 5311b60634..04416698ce 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/command/CommandComputerCraft.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/command/CommandComputerCraft.java @@ -29,7 +29,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; import net.minecraft.world.MenuProvider; -import net.minecraft.world.entity.RelativeMovement; +import net.minecraft.world.entity.Relative; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; @@ -225,7 +225,7 @@ private static int turnOn(CommandSourceStack source, Collection private static int teleport(CommandSourceStack source, ServerComputer computer) throws CommandSyntaxException { var world = computer.getLevel(); var pos = Vec3.atBottomCenterOf(computer.getPosition()); - source.getEntityOrException().teleportTo(world, pos.x(), pos.y(), pos.z(), EnumSet.noneOf(RelativeMovement.class), 0, 0); + source.getEntityOrException().teleportTo(world, pos.x(), pos.y(), pos.z(), EnumSet.noneOf(Relative.class), 0, 0, true); return 1; } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/common/ClearColourRecipe.java b/projects/common/src/main/java/dan200/computercraft/shared/common/ClearColourRecipe.java index 396c30a9fb..98436c763e 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/common/ClearColourRecipe.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/common/ClearColourRecipe.java @@ -72,11 +72,6 @@ public NonNullList getRemainingItems(CraftingInput container) { return remaining; } - @Override - public boolean canCraftInDimensions(int x, int y) { - return x * y >= 2; - } - @Override public RecipeSerializer getSerializer() { return ModRegistry.RecipeSerializers.DYEABLE_ITEM_CLEAR.get(); diff --git a/projects/common/src/main/java/dan200/computercraft/shared/common/ColourableRecipe.java b/projects/common/src/main/java/dan200/computercraft/shared/common/ColourableRecipe.java index e643b8a41a..cda3a7e212 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/common/ColourableRecipe.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/common/ColourableRecipe.java @@ -70,11 +70,6 @@ public ItemStack assemble(CraftingInput inv, HolderLookup.Provider registryAcces } - @Override - public boolean canCraftInDimensions(int x, int y) { - return x >= 2 && y >= 2; - } - @Override public RecipeSerializer getSerializer() { return ModRegistry.RecipeSerializers.DYEABLE_ITEM.get(); diff --git a/projects/common/src/main/java/dan200/computercraft/shared/common/HorizontalContainerBlock.java b/projects/common/src/main/java/dan200/computercraft/shared/common/HorizontalContainerBlock.java index 07a1f5472d..8268e2f1d9 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/common/HorizontalContainerBlock.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/common/HorizontalContainerBlock.java @@ -5,6 +5,7 @@ package dan200.computercraft.shared.common; import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; import net.minecraft.world.Containers; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.player.Player; @@ -18,7 +19,7 @@ import net.minecraft.world.level.block.entity.BaseContainerBlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import net.minecraft.world.level.block.state.properties.DirectionProperty; +import net.minecraft.world.level.block.state.properties.EnumProperty; import net.minecraft.world.phys.BlockHitResult; @@ -28,7 +29,7 @@ * @see AbstractContainerBlockEntity The container class which should be used on the block entity. */ public abstract class HorizontalContainerBlock extends BaseEntityBlock { - public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING; + public static final EnumProperty FACING = BlockStateProperties.HORIZONTAL_FACING; public HorizontalContainerBlock(Properties properties) { super(properties); diff --git a/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/AbstractComputerBlock.java b/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/AbstractComputerBlock.java index 23c4d5c9c1..8bbcedcb8d 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/AbstractComputerBlock.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/AbstractComputerBlock.java @@ -11,13 +11,14 @@ import dan200.computercraft.shared.util.BlockEntityHelpers; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.ScheduledTickAccess; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.EntityBlock; @@ -26,6 +27,7 @@ import net.minecraft.world.level.block.entity.BlockEntityTicker; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.redstone.Orientation; import net.minecraft.world.phys.BlockHitResult; import javax.annotation.Nullable; @@ -123,16 +125,23 @@ protected InteractionResult useWithoutItem(BlockState state, Level level, BlockP new ComputerContainerData(serverComputer, getItem(computer)).open(player, computer); } - return InteractionResult.sidedSuccess(level.isClientSide); + return InteractionResult.SUCCESS; } return super.useWithoutItem(state, level, pos, player, hit); } + /* @Override protected final void neighborChanged(BlockState state, Level world, BlockPos pos, Block neighbourBlock, BlockPos neighbourPos, boolean isMoving) { + // TODO: Add back var be = world.getBlockEntity(pos); if (be instanceof AbstractComputerBlockEntity computer) computer.neighborChanged(neighbourPos); + }*/ + + @Override + protected void neighborChanged(BlockState blockState, Level level, BlockPos blockPos, Block block, @org.jetbrains.annotations.Nullable Orientation orientation, boolean bl) { + super.neighborChanged(blockState, level, blockPos, block, orientation, bl); } @ForgeOverride @@ -142,11 +151,11 @@ public final void onNeighborChange(BlockState state, LevelReader world, BlockPos } @Override - protected BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor level, BlockPos pos, BlockPos neighborPos) { + protected BlockState updateShape(BlockState state, LevelReader level, ScheduledTickAccess ticker, BlockPos pos, Direction direction, BlockPos neighborPos, BlockState neighborState, RandomSource randomSource) { var be = level.getBlockEntity(pos); if (be instanceof AbstractComputerBlockEntity computer) computer.neighbourShapeChanged(direction); - return super.updateShape(state, direction, neighborState, level, pos, neighborPos); + return super.updateShape(state, level, ticker, pos, direction, neighborPos, neighborState, randomSource); } @Override diff --git a/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/AbstractComputerBlockEntity.java b/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/AbstractComputerBlockEntity.java index 803009ebad..c3eb471cf7 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/AbstractComputerBlockEntity.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/AbstractComputerBlockEntity.java @@ -145,7 +145,7 @@ public void saveAdditional(CompoundTag nbt, HolderLookup.Provider registries) { if (label != null) nbt.putString(NBT_LABEL, label); nbt.putBoolean(NBT_ON, on); - lockCode.addToTag(nbt); + lockCode.addToTag(nbt, registries); super.saveAdditional(nbt, registries); } @@ -166,7 +166,7 @@ protected void loadServer(CompoundTag nbt, HolderLookup.Provider registries) { label = nbt.contains(NBT_LABEL) ? nbt.getString(NBT_LABEL) : null; on = startOn = nbt.getBoolean(NBT_ON); - lockCode = LockCode.fromTag(nbt); + lockCode = LockCode.fromTag(nbt, registries); } @Override diff --git a/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/ComputerBlock.java b/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/ComputerBlock.java index 417834708a..c858fe97ce 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/ComputerBlock.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/ComputerBlock.java @@ -16,7 +16,6 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.StateDefinition; import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import net.minecraft.world.level.block.state.properties.DirectionProperty; import net.minecraft.world.level.block.state.properties.EnumProperty; import javax.annotation.Nullable; @@ -28,7 +27,7 @@ public class ComputerBlock extends AbstractComput ).apply(instance, ComputerBlock::new)); public static final EnumProperty STATE = EnumProperty.create("state", ComputerState.class); - public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING; + public static final EnumProperty FACING = BlockStateProperties.HORIZONTAL_FACING; public ComputerBlock(Properties settings, RegistryEntry> type) { super(settings, type); diff --git a/projects/common/src/main/java/dan200/computercraft/shared/config/Config.java b/projects/common/src/main/java/dan200/computercraft/shared/config/Config.java index b18d7cafd7..7c3dbc1a8c 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/config/Config.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/config/Config.java @@ -4,8 +4,6 @@ package dan200.computercraft.shared.config; -import dan200.computercraft.shared.peripheral.monitor.MonitorRenderer; - /** * ComputerCraft's global config. * @@ -23,7 +21,6 @@ public final class Config { public static int modemRangeDuringStorm = 64; public static int modemHighAltitudeRangeDuringStorm = 384; public static int maxNotesPerTick = 8; - public static MonitorRenderer monitorRenderer = MonitorRenderer.BEST; public static int monitorDistance = 65; public static long monitorBandwidth = 1_000_000; diff --git a/projects/common/src/main/java/dan200/computercraft/shared/config/ConfigSpec.java b/projects/common/src/main/java/dan200/computercraft/shared/config/ConfigSpec.java index 1d28130e46..7c168137f9 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/config/ConfigSpec.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/config/ConfigSpec.java @@ -11,7 +11,6 @@ import dan200.computercraft.core.apis.http.NetworkUtils; import dan200.computercraft.core.apis.http.options.ProxyType; import dan200.computercraft.core.computer.mainthread.MainThreadConfig; -import dan200.computercraft.shared.peripheral.monitor.MonitorRenderer; import dan200.computercraft.shared.platform.PlatformHelper; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.core.Filter; @@ -78,7 +77,6 @@ public final class ConfigSpec { public static final ConfigFile clientSpec; - public static final ConfigFile.Value monitorRenderer; public static final ConfigFile.Value monitorDistance; public static final ConfigFile.Value uploadNagDelay; @@ -364,12 +362,6 @@ or a single method (computercraft:inventory#pushItems). serverSpec = builder.build(ConfigSpec::syncServer); var clientBuilder = PlatformHelper.get().createConfigBuilder(); - monitorRenderer = clientBuilder - .comment(""" - The renderer to use for monitors. Generally this should be kept at "best" - if - monitors have performance issues, you may wish to experiment with alternative - renderers.""") - .defineEnum("monitor_renderer", MonitorRenderer.BEST); monitorDistance = clientBuilder .comment(""" The maximum distance monitors will render at. This defaults to the standard tile @@ -446,7 +438,6 @@ public static void syncServer(@Nullable Path path) { } public static void syncClient(@Nullable Path path) { - Config.monitorRenderer = monitorRenderer.get(); Config.monitorDistance = monitorDistance.get(); Config.uploadNagDelay = uploadNagDelay.get(); } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/data/BlockNamedEntityLootCondition.java b/projects/common/src/main/java/dan200/computercraft/shared/data/BlockNamedEntityLootCondition.java index bec825a0ec..686046439f 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/data/BlockNamedEntityLootCondition.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/data/BlockNamedEntityLootCondition.java @@ -5,9 +5,9 @@ package dan200.computercraft.shared.data; import dan200.computercraft.shared.ModRegistry; +import net.minecraft.util.context.ContextKey; import net.minecraft.world.Nameable; import net.minecraft.world.level.storage.loot.LootContext; -import net.minecraft.world.level.storage.loot.parameters.LootContextParam; import net.minecraft.world.level.storage.loot.parameters.LootContextParams; import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType; @@ -26,12 +26,12 @@ private BlockNamedEntityLootCondition() { @Override public boolean test(LootContext lootContext) { - var tile = lootContext.getParamOrNull(LootContextParams.BLOCK_ENTITY); + var tile = lootContext.getOptionalParameter(LootContextParams.BLOCK_ENTITY); return tile instanceof Nameable nameable && nameable.hasCustomName(); } @Override - public Set> getReferencedContextParams() { + public Set> getReferencedContextParams() { return Set.of(LootContextParams.BLOCK_ENTITY); } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/data/HasComputerIdLootCondition.java b/projects/common/src/main/java/dan200/computercraft/shared/data/HasComputerIdLootCondition.java index cb1f4f3192..b507b8dff5 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/data/HasComputerIdLootCondition.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/data/HasComputerIdLootCondition.java @@ -6,8 +6,8 @@ import dan200.computercraft.shared.ModRegistry; import dan200.computercraft.shared.computer.blocks.AbstractComputerBlockEntity; +import net.minecraft.util.context.ContextKey; import net.minecraft.world.level.storage.loot.LootContext; -import net.minecraft.world.level.storage.loot.parameters.LootContextParam; import net.minecraft.world.level.storage.loot.parameters.LootContextParams; import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType; @@ -26,12 +26,12 @@ private HasComputerIdLootCondition() { @Override public boolean test(LootContext lootContext) { - var tile = lootContext.getParamOrNull(LootContextParams.BLOCK_ENTITY); + var tile = lootContext.getOptionalParameter(LootContextParams.BLOCK_ENTITY); return tile instanceof AbstractComputerBlockEntity computer && computer.getComputerID() >= 0; } @Override - public Set> getReferencedContextParams() { + public Set> getReferencedContextParams() { return Set.of(LootContextParams.BLOCK_ENTITY); } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/data/PlayerCreativeLootCondition.java b/projects/common/src/main/java/dan200/computercraft/shared/data/PlayerCreativeLootCondition.java index db8bfc85dc..7bb697ef55 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/data/PlayerCreativeLootCondition.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/data/PlayerCreativeLootCondition.java @@ -5,9 +5,9 @@ package dan200.computercraft.shared.data; import dan200.computercraft.shared.ModRegistry; +import net.minecraft.util.context.ContextKey; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.storage.loot.LootContext; -import net.minecraft.world.level.storage.loot.parameters.LootContextParam; import net.minecraft.world.level.storage.loot.parameters.LootContextParams; import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType; @@ -26,12 +26,12 @@ private PlayerCreativeLootCondition() { @Override public boolean test(LootContext lootContext) { - var entity = lootContext.getParamOrNull(LootContextParams.THIS_ENTITY); + var entity = lootContext.getOptionalParameter(LootContextParams.THIS_ENTITY); return entity instanceof Player player && player.isCreative(); } @Override - public Set> getReferencedContextParams() { + public Set> getReferencedContextParams() { return Set.of(LootContextParams.THIS_ENTITY); } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/integration/UpgradeRecipeGenerator.java b/projects/common/src/main/java/dan200/computercraft/shared/integration/UpgradeRecipeGenerator.java index 792721c6ab..d6b299c932 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/integration/UpgradeRecipeGenerator.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/integration/UpgradeRecipeGenerator.java @@ -15,13 +15,12 @@ import dan200.computercraft.shared.util.DataComponentUtil; import net.minecraft.core.Holder; import net.minecraft.core.HolderLookup; -import net.minecraft.core.NonNullList; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.crafting.CraftingBookCategory; -import net.minecraft.world.item.crafting.Ingredient; -import net.minecraft.world.item.crafting.ShapedRecipe; -import net.minecraft.world.item.crafting.ShapedRecipePattern; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.crafting.display.RecipeDisplay; +import net.minecraft.world.item.crafting.display.ShapedCraftingRecipeDisplay; +import net.minecraft.world.item.crafting.display.SlotDisplay; import javax.annotation.Nullable; import java.util.*; @@ -37,7 +36,9 @@ * @see RecipeModHelpers */ public class UpgradeRecipeGenerator { - private final Function wrap; + private static final SlotDisplay CRAFTING_STATION = new SlotDisplay.ItemSlotDisplay(Items.CRAFTING_TABLE); + + private final Function wrap; private final HolderLookup.Provider registries; private final Map> upgradeItemLookup = new HashMap<>(); @@ -45,7 +46,7 @@ public class UpgradeRecipeGenerator { private final List turtleUpgrades = new ArrayList<>(); private boolean initialised = false; - public UpgradeRecipeGenerator(Function wrap, HolderLookup.Provider registries) { + public UpgradeRecipeGenerator(Function wrap, HolderLookup.Provider registries) { this.wrap = wrap; this.registries = registries; } @@ -117,7 +118,7 @@ public List findRecipesWithInput(ItemStack stack) { if (left != null && right != null) return List.of(); List recipes = new ArrayList<>(); - var ingredient = Ingredient.of(stack); + var ingredient = new SlotDisplay.ItemStackSlotDisplay(stack); for (var upgrade : turtleUpgrades) { if (upgrade.turtle == null) throw new NullPointerException(); @@ -138,7 +139,7 @@ public List findRecipesWithInput(ItemStack stack) { if (back != null) return List.of(); List recipes = new ArrayList<>(); - var ingredient = Ingredient.of(stack); + var ingredient = new SlotDisplay.ItemStackSlotDisplay(stack); for (var upgrade : pocketUpgrades) { if (upgrade.pocket == null) throw new NullPointerException(); recipes.add(pocket(upgrade.ingredient, ingredient, pocketWith(stack, UpgradeData.ofDefault(upgrade.pocket)))); @@ -190,16 +191,16 @@ public List findRecipesWithOutput(ItemStack stack) { // The turtle is facing towards us, so upgrades on the left are actually crafted on the right. if (left != null) { recipes.add(turtle( - Ingredient.of(turtleWith(stack, null, right)), - Ingredient.of(left.getUpgradeItem()), + new SlotDisplay.ItemStackSlotDisplay(turtleWith(stack, null, right)), + new SlotDisplay.ItemStackSlotDisplay(left.getUpgradeItem()), stack )); } if (right != null) { recipes.add(turtle( - Ingredient.of(right.getUpgradeItem()), - Ingredient.of(turtleWith(stack, left, null)), + new SlotDisplay.ItemStackSlotDisplay(right.getUpgradeItem()), + new SlotDisplay.ItemStackSlotDisplay(turtleWith(stack, left, null)), stack )); } @@ -210,7 +211,7 @@ public List findRecipesWithOutput(ItemStack stack) { var back = PocketComputerItem.getUpgradeWithData(stack); if (back != null) { - recipes.add(pocket(Ingredient.of(back.getUpgradeItem()), Ingredient.of(pocketWith(stack, null)), stack)); + recipes.add(pocket(new SlotDisplay.ItemStackSlotDisplay(back.getUpgradeItem()), new SlotDisplay.ItemStackSlotDisplay(pocketWith(stack, null)), stack)); } return Collections.unmodifiableList(recipes); @@ -232,25 +233,21 @@ private static ItemStack pocketWith(ItemStack stack, @Nullable UpgradeData turtle; final @Nullable Holder.Reference pocket; final UpgradeBase upgrade; @@ -258,7 +255,7 @@ private class UpgradeInfo { UpgradeInfo(ItemStack stack, UpgradeBase upgrade, @Nullable Holder.Reference turtle, @Nullable Holder.Reference pocket) { this.stack = stack; - ingredient = Ingredient.of(stack); + ingredient = new SlotDisplay.ItemStackSlotDisplay(stack); this.turtle = turtle; this.pocket = pocket; this.upgrade = upgrade; @@ -275,7 +272,7 @@ List getRecipes() { var turtleItem = turtleSupplier.get(); recipes.add(turtle( ingredient, // Right upgrade, recipe on left - Ingredient.of(new ItemStack(turtleItem)), + new SlotDisplay.ItemSlotDisplay(turtleItem), DataComponentUtil.createStack(turtleItem, ModRegistry.DataComponents.RIGHT_TURTLE_UPGRADE.get(), UpgradeData.ofDefault(turtle)) )); } @@ -286,7 +283,7 @@ List getRecipes() { var pocketItem = pocketSupplier.get(); recipes.add(pocket( ingredient, - Ingredient.of(pocketItem), + new SlotDisplay.ItemSlotDisplay(pocketItem), DataComponentUtil.createStack(pocketItem, ModRegistry.DataComponents.POCKET_UPGRADE.get(), UpgradeData.ofDefault(pocket)) )); } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/lectern/CustomLecternBlock.java b/projects/common/src/main/java/dan200/computercraft/shared/lectern/CustomLecternBlock.java index b3e0e1814d..c2e1b34e35 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/lectern/CustomLecternBlock.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/lectern/CustomLecternBlock.java @@ -50,7 +50,7 @@ public CustomLecternBlock(Properties properties) { public static InteractionResult tryPlaceItem(Player player, Level level, BlockPos pos, BlockState blockState, ItemStack item) { if (item.getItem() instanceof PrintoutItem) { if (!level.isClientSide) replaceLectern(player, level, pos, blockState, item); - return InteractionResult.sidedSuccess(level.isClientSide); + return InteractionResult.SUCCESS; } return InteractionResult.PASS; @@ -129,11 +129,6 @@ private static void dropItem(Level level, BlockPos pos, BlockState state, ItemSt level.addFreshEntity(entity); } - @Override - public String getDescriptionId() { - return Blocks.LECTERN.getDescriptionId(); - } - @Override public CustomLecternBlockEntity newBlockEntity(BlockPos pos, BlockState state) { return new CustomLecternBlockEntity(pos, state); @@ -158,6 +153,6 @@ public InteractionResult useWithoutItem(BlockState state, Level level, BlockPos player.awardStat(Stats.INTERACT_WITH_LECTERN); } - return InteractionResult.sidedSuccess(level.isClientSide); + return InteractionResult.SUCCESS; } } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/media/items/PrintoutItem.java b/projects/common/src/main/java/dan200/computercraft/shared/media/items/PrintoutItem.java index 0838e4de7a..199107bf93 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/media/items/PrintoutItem.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/media/items/PrintoutItem.java @@ -9,7 +9,6 @@ import net.minecraft.network.chat.Component; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; -import net.minecraft.world.InteractionResultHolder; import net.minecraft.world.SimpleMenuProvider; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.Item; @@ -40,14 +39,14 @@ public void appendHoverText(ItemStack stack, TooltipContext context, List use(Level world, Player player, InteractionHand hand) { + public InteractionResult use(Level world, Player player, InteractionHand hand) { var stack = player.getItemInHand(hand); if (!world.isClientSide) { var title = PrintoutData.getOrEmpty(stack).title(); var displayTitle = Strings.isNullOrEmpty(title) ? stack.getDisplayName() : Component.literal(title); player.openMenu(new SimpleMenuProvider((id, playerInventory, p) -> PrintoutMenu.createInHand(id, p, hand), displayTitle)); } - return new InteractionResultHolder<>(InteractionResult.sidedSuccess(world.isClientSide), stack); + return InteractionResult.SUCCESS; } public Type getType() { diff --git a/projects/common/src/main/java/dan200/computercraft/shared/media/recipes/DiskRecipe.java b/projects/common/src/main/java/dan200/computercraft/shared/media/recipes/DiskRecipe.java index 1c7586bed2..ea7eb23a23 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/media/recipes/DiskRecipe.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/media/recipes/DiskRecipe.java @@ -4,50 +4,101 @@ package dan200.computercraft.shared.media.recipes; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import dan200.computercraft.core.util.Colour; import dan200.computercraft.shared.ModRegistry; -import dan200.computercraft.shared.platform.PlatformHelper; +import dan200.computercraft.shared.recipe.AbstractCraftingRecipe; +import dan200.computercraft.shared.recipe.RecipeProperties; +import dan200.computercraft.shared.recipe.ShapelessRecipeSpec; import dan200.computercraft.shared.util.ColourTracker; import dan200.computercraft.shared.util.ColourUtils; import dan200.computercraft.shared.util.DataComponentUtil; import net.minecraft.core.HolderLookup; import net.minecraft.core.component.DataComponents; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.world.entity.player.StackedItemContents; +import net.minecraft.world.item.DyeColor; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.item.component.DyedItemColor; -import net.minecraft.world.item.crafting.*; +import net.minecraft.world.item.crafting.CraftingInput; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.PlacementInfo; +import net.minecraft.world.item.crafting.RecipeSerializer; +import net.minecraft.world.item.crafting.display.RecipeDisplay; +import net.minecraft.world.item.crafting.display.ShapelessCraftingRecipeDisplay; +import net.minecraft.world.item.crafting.display.SlotDisplay; import net.minecraft.world.level.Level; -public class DiskRecipe extends CustomRecipe { - private final Ingredient redstone; +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; + +public class DiskRecipe extends AbstractCraftingRecipe { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + RecipeProperties.CODEC.forGetter(x -> x.properties), + ShapelessRecipeSpec.INGREDIENT_CODEC.fieldOf("ingredients").forGetter(x -> x.ingredients) + ).apply(instance, DiskRecipe::new)); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + RecipeProperties.STREAM_CODEC, x -> x.properties, + Ingredient.CONTENTS_STREAM_CODEC.apply(ByteBufCodecs.list()), x -> x.ingredients, + DiskRecipe::new + ); + + private final List ingredients; + private @Nullable PlacementInfo placementInfo; + + public DiskRecipe(RecipeProperties properties, List ingredients) { + super(properties); + this.ingredients = ingredients; + } + + @Override + public PlacementInfo placementInfo() { + if (placementInfo == null) placementInfo = PlacementInfo.create(ingredients); + return placementInfo; + } - public DiskRecipe(CraftingBookCategory category) { - super(category); - redstone = PlatformHelper.get().getRecipeIngredients().redstone(); + @Override + public List display() { + var dyes = ColourUtils.DYES; + List out = new ArrayList<>(dyes.size()); + for (var i = 0; i < dyes.size(); i++) { + var tracker = new ColourTracker(); + tracker.addColour(DyeColor.byId(i)); + + out.add(new ShapelessCraftingRecipeDisplay( + Stream.concat(ingredients.stream(), Stream.of(Ingredient.of(BuiltInRegistries.ITEM.getOrThrow(dyes.get(i))))) + .map(Ingredient::display).toList(), + new SlotDisplay.ItemStackSlotDisplay(DataComponentUtil.createStack( + ModRegistry.Items.DISK.get(), DataComponents.DYED_COLOR, new DyedItemColor(tracker.getColour(), false) + )), + new SlotDisplay.ItemSlotDisplay(Items.CRAFTING_TABLE) + )); + } + return out; } @Override public boolean matches(CraftingInput inv, Level world) { - var paperFound = false; - var redstoneFound = false; + var inputs = 0; + var stackedContents = new StackedItemContents(); - for (var i = 0; i < inv.size(); i++) { + for (var i = 0; i < inv.size(); ++i) { var stack = inv.getItem(i); - - if (!stack.isEmpty()) { - if (stack.getItem() == Items.PAPER) { - if (paperFound) return false; - paperFound = true; - } else if (redstone.test(stack)) { - if (redstoneFound) return false; - redstoneFound = true; - } else if (ColourUtils.getStackColour(stack) == null) { - return false; - } + if (stack.isEmpty()) continue; + if (ColourUtils.getStackColour(stack) == null) { + stackedContents.accountStack(stack, 1); } } - return redstoneFound && paperFound; + return inputs == ingredients.size() && stackedContents.canCraft(placementInfo().unpackedIngredients(), null); } @Override @@ -59,27 +110,15 @@ public ItemStack assemble(CraftingInput inv, HolderLookup.Provider registryAcces if (stack.isEmpty()) continue; - if (stack.getItem() != Items.PAPER && !redstone.test(stack)) { - var dye = ColourUtils.getStackColour(stack); - if (dye != null) tracker.addColour(dye); - } + var dye = ColourUtils.getStackColour(stack); + if (dye != null) tracker.addColour(dye); } return DataComponentUtil.createStack(ModRegistry.Items.DISK.get(), DataComponents.DYED_COLOR, new DyedItemColor(tracker.hasColour() ? tracker.getColour() : Colour.BLUE.getHex(), false)); } @Override - public boolean canCraftInDimensions(int x, int y) { - return x >= 2 && y >= 2; - } - - @Override - public ItemStack getResultItem(HolderLookup.Provider registryAccess) { - return DataComponentUtil.createStack(ModRegistry.Items.DISK.get(), DataComponents.DYED_COLOR, new DyedItemColor(Colour.BLUE.getHex(), false)); - } - - @Override - public RecipeSerializer getSerializer() { + public RecipeSerializer getSerializer() { return ModRegistry.RecipeSerializers.DISK.get(); } } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/media/recipes/PrintoutRecipe.java b/projects/common/src/main/java/dan200/computercraft/shared/media/recipes/PrintoutRecipe.java index 8837e32561..e9715b50bc 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/media/recipes/PrintoutRecipe.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/media/recipes/PrintoutRecipe.java @@ -9,22 +9,23 @@ import dan200.computercraft.shared.ModRegistry; import dan200.computercraft.shared.media.items.PrintoutData; import dan200.computercraft.shared.media.items.PrintoutItem; -import dan200.computercraft.shared.recipe.RecipeProperties; +import dan200.computercraft.shared.recipe.AbstractCraftingRecipe; import dan200.computercraft.shared.recipe.ShapelessRecipeSpec; import net.minecraft.core.HolderLookup; -import net.minecraft.core.NonNullList; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; import net.minecraft.util.ExtraCodecs; -import net.minecraft.world.entity.player.StackedContents; +import net.minecraft.world.entity.player.StackedItemContents; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.crafting.CraftingInput; -import net.minecraft.world.item.crafting.Ingredient; -import net.minecraft.world.item.crafting.RecipeSerializer; -import net.minecraft.world.item.crafting.ShapelessRecipe; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.crafting.*; +import net.minecraft.world.item.crafting.display.RecipeDisplay; +import net.minecraft.world.item.crafting.display.ShapelessCraftingRecipeDisplay; +import net.minecraft.world.item.crafting.display.SlotDisplay; import net.minecraft.world.level.Level; +import javax.annotation.Nullable; import java.util.ArrayList; import java.util.List; @@ -36,10 +37,10 @@ * @see PrintoutItem * @see PrintoutData */ -public final class PrintoutRecipe extends ShapelessRecipe { +public final class PrintoutRecipe extends AbstractCraftingRecipe { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( ShapelessRecipeSpec.CODEC.forGetter(PrintoutRecipe::toSpec), - Ingredient.CODEC_NONEMPTY.fieldOf("printout").forGetter(x -> x.printout), + Ingredient.CODEC.fieldOf("printout").forGetter(x -> x.printout), ExtraCodecs.POSITIVE_INT.fieldOf("min_printouts").forGetter(x -> x.minPrintouts) ).apply(instance, PrintoutRecipe::new)); @@ -50,12 +51,15 @@ public final class PrintoutRecipe extends ShapelessRecipe { PrintoutRecipe::new ); - private final NonNullList ingredients; + private final ShapelessRecipeSpec spec; + private final List ingredients; + private @Nullable PlacementInfo ingredientInfo; + + private final List placementIngredients; + private @Nullable PlacementInfo placementInfo; + private final Ingredient printout; private final int minPrintouts; - private final ShapelessRecipe innerRecipe; - - private final ItemStack result; /** * Construct a new {@link PrintoutRecipe}. @@ -67,34 +71,44 @@ public final class PrintoutRecipe extends ShapelessRecipe { public PrintoutRecipe( ShapelessRecipeSpec spec, Ingredient printout, int minPrintouts ) { - // We use the full list of ingredients in the recipe itself, so that it behaves sensibly with recipe mods. - super(spec.properties().group(), spec.properties().category(), spec.result(), concat(spec.ingredients(), printout, minPrintouts)); + super(spec.properties()); + this.spec = spec; this.ingredients = spec.ingredients(); + // We use the full list of ingredients for the display/placement information. + this.placementIngredients = concat(spec.ingredients(), printout, minPrintouts); + this.printout = printout; this.minPrintouts = minPrintouts; - this.result = spec.result(); - - // However, when testing whether the recipe matches, we only want to use the non-printout ingredients. To do - // that, we create a hidden recipe with the main ingredients. - this.innerRecipe = spec.create(); } - private static NonNullList concat(NonNullList first, Ingredient pages, int pagesRequired) { - var result = NonNullList.withSize(first.size() + pagesRequired, Ingredient.EMPTY); - var idx = 0; - for (var ingredient : first) result.set(idx++, ingredient); - for (var i = 0; i < pagesRequired; i++) result.set(idx++, pages); + private static List concat(List first, Ingredient pages, int pagesRequired) { + var result = new ArrayList(first.size() + pagesRequired); + result.addAll(first); + for (var i = 0; i < pagesRequired; i++) result.add(pages); return result; } - private ShapelessRecipeSpec toSpec() { - return new ShapelessRecipeSpec(RecipeProperties.of(this), ingredients, result); + @Override + public PlacementInfo placementInfo() { + if (placementInfo == null) placementInfo = PlacementInfo.create(placementIngredients); + return placementInfo; + } + + @Override + public List display() { + return List.of( + new ShapelessCraftingRecipeDisplay( + placementIngredients.stream().map(Ingredient::display).toList(), + new SlotDisplay.ItemStackSlotDisplay(spec.result()), + new SlotDisplay.ItemSlotDisplay(Items.CRAFTING_TABLE) + ) + ); } @Override public boolean matches(CraftingInput inv, Level world) { - var stackedContents = new StackedContents(); + var stackedContents = new StackedItemContents(); var inputs = 0; var printouts = 0; @@ -121,7 +135,14 @@ public boolean matches(CraftingInput inv, Level world) { } return hasPrintout && printouts >= minPrintouts && pages <= PrintoutData.MAX_PAGES - && inputs == ingredients.size() && stackedContents.canCraft(innerRecipe, null); + && inputs == ingredients.size() && stackedContents.canCraft(getIngredientInfo().unpackedIngredients(), null); + } + + private PlacementInfo getIngredientInfo() { + // However, when testing whether the recipe matches, we only want to use the non-printout ingredients. To do + // that, we create a hidden recipe with the main ingredients. + if (ingredientInfo == null) ingredientInfo = PlacementInfo.create(ingredients); + return ingredientInfo; } @Override @@ -136,13 +157,17 @@ public ItemStack assemble(CraftingInput inv, HolderLookup.Provider registries) { var lines = data.stream().flatMap(x -> x.lines().stream()).toList(); - var result = super.assemble(inv, registries); + var result = spec.result().copy(); result.set(ModRegistry.DataComponents.PRINTOUT.get(), new PrintoutData(data.getFirst().title(), lines)); return result; } + private ShapelessRecipeSpec toSpec() { + return spec; + } + @Override - public RecipeSerializer getSerializer() { + public RecipeSerializer getSerializer() { return ModRegistry.RecipeSerializers.PRINTOUT.get(); } } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/DiskDriveBlock.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/DiskDriveBlock.java index ffab6ad799..ffeda0b8c2 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/DiskDriveBlock.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/DiskDriveBlock.java @@ -11,7 +11,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.world.InteractionHand; -import net.minecraft.world.ItemInteractionResult; +import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; @@ -52,15 +52,15 @@ protected MapCodec codec() { } @Override - protected ItemInteractionResult useItemOn(ItemStack stack, BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { + protected InteractionResult useItemOn(ItemStack stack, BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { if (player.isCrouching() && level.getBlockEntity(pos) instanceof DiskDriveBlockEntity drive) { // Try to put a disk into the drive - if (stack.isEmpty()) return ItemInteractionResult.SKIP_DEFAULT_BLOCK_INTERACTION; + if (stack.isEmpty()) return InteractionResult.TRY_WITH_EMPTY_HAND; if (!level.isClientSide && drive.getDiskStack().isEmpty() && MediaProviders.get(stack) != null) { drive.setDiskStack(stack.split(1)); } - return ItemInteractionResult.sidedSuccess(level.isClientSide); + return InteractionResult.SUCCESS; } return super.useItemOn(stack, state, level, pos, player, hand, hit); diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableBlock.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableBlock.java index b23cd3d852..686d92d829 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableBlock.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableBlock.java @@ -169,8 +169,8 @@ protected FluidState getFluidState(BlockState state) { } @Override - protected BlockState updateShape(BlockState state, Direction side, BlockState otherState, LevelAccessor level, BlockPos pos, BlockPos otherPos) { - WaterloggableHelpers.updateShape(state, level, pos); + protected BlockState updateShape(BlockState state, LevelReader level, ScheduledTickAccess ticker, BlockPos pos, Direction side, BlockPos otherPos, BlockState neighborState, RandomSource randomSource) { + WaterloggableHelpers.updateShape(state, level, ticker, pos); // Should never happen, but handle the case where we've no modem or cable. if (!state.getValue(CABLE) && state.getValue(MODEM) == CableModemVariant.None) { @@ -247,10 +247,11 @@ protected final InteractionResult useWithoutItem(BlockState state, Level world, return world.getBlockEntity(pos) instanceof CableBlockEntity modem ? modem.use(player) : InteractionResult.PASS; } + /* @Override protected final void neighborChanged(BlockState state, Level world, BlockPos pos, Block neighbourBlock, BlockPos neighbourPos, boolean isMoving) { if (world.getBlockEntity(pos) instanceof CableBlockEntity modem) modem.neighborChanged(neighbourPos); - } + }*/ @ForgeOverride public final void onNeighborChange(BlockState state, LevelReader world, BlockPos pos, BlockPos neighbour) { diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableBlockItem.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableBlockItem.java index 3878f681e0..ea1443c6c9 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableBlockItem.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableBlockItem.java @@ -4,11 +4,8 @@ package dan200.computercraft.shared.peripheral.modem.wired; -import dan200.computercraft.shared.util.RegistryHelper; import dan200.computercraft.shared.ModRegistry; -import net.minecraft.Util; import net.minecraft.core.BlockPos; -import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.sounds.SoundSource; import net.minecraft.world.InteractionResult; import net.minecraft.world.item.BlockItem; @@ -16,13 +13,9 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.block.state.BlockState; -import javax.annotation.Nullable; - import static dan200.computercraft.shared.peripheral.modem.wired.CableBlock.*; public abstract class CableBlockItem extends BlockItem { - private @Nullable String translationKey; - public CableBlockItem(CableBlock block, Properties settings) { super(block, settings); } @@ -45,14 +38,6 @@ boolean placeAtCorrected(Level world, BlockPos pos, BlockState state) { return placeAt(world, pos, correctConnections(world, pos, state)); } - @Override - public String getDescriptionId() { - if (translationKey == null) { - translationKey = Util.makeDescriptionId("block", RegistryHelper.getKeyOrThrow(BuiltInRegistries.ITEM, this)); - } - return translationKey; - } - public static class WiredModem extends CableBlockItem { public WiredModem(CableBlock block, Properties settings) { super(block, settings); @@ -75,7 +60,7 @@ public InteractionResult place(BlockPlaceContext context) { .setValue(CONNECTIONS.get(side), existingState.getValue(CABLE)); if (placeAt(world, pos, newState)) { stack.shrink(1); - return InteractionResult.sidedSuccess(world.isClientSide); + return InteractionResult.SUCCESS; } } @@ -102,7 +87,7 @@ public InteractionResult place(BlockPlaceContext context) { if (insideState.getBlock() == ModRegistry.Blocks.CABLE.get() && !insideState.getValue(CableBlock.CABLE) && placeAtCorrected(world, insidePos, insideState.setValue(CableBlock.CABLE, true))) { stack.shrink(1); - return InteractionResult.sidedSuccess(world.isClientSide); + return InteractionResult.SUCCESS; } // Try to add a cable to a modem adjacent to this block @@ -110,7 +95,7 @@ && placeAtCorrected(world, insidePos, insideState.setValue(CableBlock.CABLE, tru if (existingState.getBlock() == ModRegistry.Blocks.CABLE.get() && !existingState.getValue(CableBlock.CABLE) && placeAtCorrected(world, pos, existingState.setValue(CableBlock.CABLE, true))) { stack.shrink(1); - return InteractionResult.sidedSuccess(world.isClientSide); + return InteractionResult.SUCCESS; } return super.place(context); diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemFullBlock.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemFullBlock.java index 0ddc145233..749d3551e3 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemFullBlock.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemFullBlock.java @@ -13,8 +13,8 @@ import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.ScheduledTickAccess; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.EntityBlock; import net.minecraft.world.level.block.entity.BlockEntity; @@ -48,20 +48,21 @@ protected final InteractionResult useWithoutItem(BlockState state, Level world, } @Override - protected BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor level, BlockPos pos, BlockPos neighborPos) { + protected BlockState updateShape(BlockState state, LevelReader level, ScheduledTickAccess ticker, BlockPos pos, Direction direction, BlockPos otherPos, BlockState neighborState, RandomSource randomSource) { if (state.getValue(PERIPHERAL_ON) && level.getBlockEntity(pos) instanceof WiredModemFullBlockEntity modem) { modem.queueRefreshPeripheral(direction); } - return super.updateShape(state, direction, neighborState, level, pos, neighborPos); + return super.updateShape(state, level, ticker, pos, direction, otherPos, neighborState, randomSource); } + /* @Override protected final void neighborChanged(BlockState state, Level level, BlockPos pos, Block neighbourBlock, BlockPos neighbourPos, boolean isMoving) { if (state.getValue(PERIPHERAL_ON) && level.getBlockEntity(pos) instanceof WiredModemFullBlockEntity modem) { modem.neighborChanged(neighbourPos); } - } + }*/ @ForgeOverride public final void onNeighborChange(BlockState state, LevelReader level, BlockPos pos, BlockPos neighbour) { diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wireless/WirelessModemBlock.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wireless/WirelessModemBlock.java index f9c90612a9..1bbe07949d 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wireless/WirelessModemBlock.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wireless/WirelessModemBlock.java @@ -15,8 +15,8 @@ import net.minecraft.util.RandomSource; import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.ScheduledTickAccess; import net.minecraft.world.level.block.*; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; @@ -69,10 +69,11 @@ protected FluidState getFluidState(BlockState state) { return WaterloggableHelpers.getFluidState(state); } + @Override - protected BlockState updateShape(BlockState state, Direction side, BlockState otherState, LevelAccessor world, BlockPos pos, BlockPos otherPos) { - WaterloggableHelpers.updateShape(state, world, pos); - return side == state.getValue(FACING) && !state.canSurvive(world, pos) + protected BlockState updateShape(BlockState state, LevelReader level, ScheduledTickAccess ticker, BlockPos pos, Direction side, BlockPos otherPos, BlockState neighborState, RandomSource randomSource) { + WaterloggableHelpers.updateShape(state, level, ticker, pos); + return side == state.getValue(FACING) && !state.canSurvive(level, pos) ? state.getFluidState().createLegacyBlock() : state; } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wireless/WirelessModemPeripheral.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wireless/WirelessModemPeripheral.java index 3b0d7fa143..6a6e09172a 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wireless/WirelessModemPeripheral.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wireless/WirelessModemPeripheral.java @@ -42,7 +42,7 @@ public double getRange() { maxRange = Config.modemHighAltitudeRangeDuringStorm; } if (position.y > 96.0 && maxRange > minRange) { - return minRange + (position.y - 96.0) * ((maxRange - minRange) / ((world.getMaxBuildHeight() - 1) - 96.0)); + return minRange + (position.y - 96.0) * ((maxRange - minRange) / (world.getMaxY() - 96.0)); } return minRange; } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorBlock.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorBlock.java index 36dee39b0c..9c14386ccc 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorBlock.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorBlock.java @@ -27,7 +27,6 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.StateDefinition; import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import net.minecraft.world.level.block.state.properties.DirectionProperty; import net.minecraft.world.level.block.state.properties.EnumProperty; import net.minecraft.world.phys.BlockHitResult; @@ -36,10 +35,10 @@ public class MonitorBlock extends HorizontalDirectionalBlock implements EntityBlock { private static final MapCodec CODEC = BlockCodecs.blockWithBlockEntityCodec(MonitorBlock::new, x -> x.type); - public static final DirectionProperty ORIENTATION = DirectionProperty.create("orientation", + public static final EnumProperty ORIENTATION = EnumProperty.create("orientation", Direction.class, Direction.UP, Direction.DOWN, Direction.NORTH); - public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING; + public static final EnumProperty FACING = BlockStateProperties.HORIZONTAL_FACING; public static final EnumProperty STATE = EnumProperty.create("state", MonitorEdgeState.class); private final RegistryEntry> type; @@ -114,7 +113,7 @@ protected final InteractionResult useWithoutItem(BlockState state, Level level, ); } - return InteractionResult.sidedSuccess(level.isClientSide); + return InteractionResult.SUCCESS; } @Override diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPeripheral.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPeripheral.java index c57ed92055..a07af4b56a 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPeripheral.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPeripheral.java @@ -257,10 +257,10 @@ public final boolean playSound(ILuaContext context, String name, Optional x.soundEvent().value() == soundEvent)) { + if (soundEvent != null && level.registryAccess().lookupOrThrow(Registries.JUKEBOX_SONG).stream().anyMatch(x -> x.soundEvent().value() == soundEvent)) { return false; } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/platform/PlatformHelper.java b/projects/common/src/main/java/dan200/computercraft/shared/platform/PlatformHelper.java index 2892a8c8e2..755593cc4f 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/platform/PlatformHelper.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/platform/PlatformHelper.java @@ -19,6 +19,7 @@ import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.ResourceKey; +import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayerGameMode; @@ -34,7 +35,7 @@ import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.CraftingInput; -import net.minecraft.world.item.crafting.Recipe; +import net.minecraft.world.item.crafting.CraftingRecipe; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; @@ -195,10 +196,12 @@ default void invalidateComponent(BlockEntity owner) { /** * Get the amount of fuel an item provides. * - * @param stack The item to burn. + * @param server The current server. + * @param stack The item to burn. * @return The amount of fuel it provides. + * @see MinecraftServer#fuelValues() */ - int getBurnTime(ItemStack stack); + int getBurnTime(MinecraftServer server, ItemStack stack); /** * Create a builder for a new creative tab. @@ -225,7 +228,7 @@ default void invalidateComponent(BlockEntity owner) { * @param container The crafting container. * @return A list of items to return to the player after crafting. */ - List getRecipeRemainingItems(ServerPlayer player, Recipe recipe, CraftingInput container); + List getRecipeRemainingItems(ServerPlayer player, CraftingRecipe recipe, CraftingInput container); /** * Fire an event after crafting has occurred. diff --git a/projects/common/src/main/java/dan200/computercraft/shared/platform/RecipeIngredients.java b/projects/common/src/main/java/dan200/computercraft/shared/platform/RecipeIngredients.java index b35cff0fd8..fac69b2b84 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/platform/RecipeIngredients.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/platform/RecipeIngredients.java @@ -4,8 +4,9 @@ package dan200.computercraft.shared.platform; +import net.minecraft.tags.TagKey; +import net.minecraft.world.item.Item; import net.minecraft.world.item.Items; -import net.minecraft.world.item.crafting.Ingredient; /** * Loader-specific recipe ingredients. These may either be tags or items, depending on which mod loader we're using. @@ -22,15 +23,15 @@ * @param woodenChest All wooden chests (both normal and trapped chests). */ public record RecipeIngredients( - Ingredient redstone, - Ingredient string, - Ingredient leather, - Ingredient glassPane, - Ingredient goldIngot, - Ingredient goldBlock, - Ingredient ironIngot, - Ingredient dye, - Ingredient enderPearl, - Ingredient woodenChest + TagKey redstone, + TagKey string, + TagKey leather, + TagKey glassPane, + TagKey goldIngot, + TagKey goldBlock, + TagKey ironIngot, + TagKey dye, + TagKey enderPearl, + TagKey woodenChest ) { } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/platform/RegistryEntry.java b/projects/common/src/main/java/dan200/computercraft/shared/platform/RegistryEntry.java index d2556bb567..703417607d 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/platform/RegistryEntry.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/platform/RegistryEntry.java @@ -37,7 +37,7 @@ public T get() { return ResourceLocation.CODEC.flatXmap( id -> registry - .getHolder(ResourceKey.create(registry.key(), id)) + .get(ResourceKey.create(registry.key(), id)) .map(x -> DataResult.success(new HolderEntry<>(id, x))) .orElseGet(() -> DataResult.error(() -> "Unknown registry key in " + registry.key() + ": " + id)), holder -> DataResult.success(holder.id()) diff --git a/projects/common/src/main/java/dan200/computercraft/shared/pocket/items/PocketComputerItem.java b/projects/common/src/main/java/dan200/computercraft/shared/pocket/items/PocketComputerItem.java index a3d9eaecc7..6cb7ce3427 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/pocket/items/PocketComputerItem.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/pocket/items/PocketComputerItem.java @@ -36,7 +36,6 @@ import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; -import net.minecraft.world.InteractionResultHolder; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.player.Player; @@ -132,7 +131,7 @@ public boolean onEntityItemUpdate(ItemStack stack, ItemEntity entity) { } @Override - public InteractionResultHolder use(Level world, Player player, InteractionHand hand) { + public InteractionResult use(Level world, Player player, InteractionHand hand) { var stack = player.getItemInHand(hand); if (!world.isClientSide) { var holder = new PocketHolder.PlayerHolder((ServerPlayer) player, InventoryUtil.getHandSlot(player, hand)); @@ -154,12 +153,12 @@ public InteractionResultHolder use(Level world, Player player, Intera new ComputerContainerData(computer, stack).open(player, new PocketComputerMenuProvider(computer, stack, this, hand, isTypingOnly)); } } - return new InteractionResultHolder<>(InteractionResult.sidedSuccess(world.isClientSide), stack); + return InteractionResult.SUCCESS; } @Override public Component getName(ItemStack stack) { - var baseString = getDescriptionId(stack); + var baseString = getDescriptionId(); var upgrade = getUpgrade(stack); if (upgrade != null) { return Component.translatable(baseString + ".upgraded", upgrade.getAdjective()); diff --git a/projects/common/src/main/java/dan200/computercraft/shared/pocket/recipes/PocketComputerUpgradeRecipe.java b/projects/common/src/main/java/dan200/computercraft/shared/pocket/recipes/PocketComputerUpgradeRecipe.java index 89927be377..2ca44bd312 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/pocket/recipes/PocketComputerUpgradeRecipe.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/pocket/recipes/PocketComputerUpgradeRecipe.java @@ -22,16 +22,6 @@ public PocketComputerUpgradeRecipe(CraftingBookCategory category) { super(category); } - @Override - public boolean canCraftInDimensions(int x, int y) { - return x >= 2 && y >= 2; - } - - @Override - public ItemStack getResultItem(HolderLookup.Provider registryAccess) { - return new ItemStack(ModRegistry.Items.POCKET_COMPUTER_NORMAL.get()); - } - @Override public boolean matches(CraftingInput inventory, Level world) { return !assemble(inventory, world.registryAccess()).isEmpty(); @@ -85,7 +75,7 @@ public ItemStack assemble(CraftingInput inventory, HolderLookup.Provider registr } @Override - public RecipeSerializer getSerializer() { + public RecipeSerializer getSerializer() { return ModRegistry.RecipeSerializers.POCKET_COMPUTER_UPGRADE.get(); } } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/recipe/AbstractCraftingRecipe.java b/projects/common/src/main/java/dan200/computercraft/shared/recipe/AbstractCraftingRecipe.java new file mode 100644 index 0000000000..2e01672944 --- /dev/null +++ b/projects/common/src/main/java/dan200/computercraft/shared/recipe/AbstractCraftingRecipe.java @@ -0,0 +1,34 @@ +// SPDX-FileCopyrightText: 2024 The CC: Tweaked Developers +// +// SPDX-License-Identifier: MPL-2.0 + +package dan200.computercraft.shared.recipe; + +import net.minecraft.world.item.crafting.CraftingBookCategory; +import net.minecraft.world.item.crafting.CraftingRecipe; + +/** + * An abstract {@link CraftingRecipe} that provides a skeleton implementation. + */ +public abstract class AbstractCraftingRecipe implements CraftingRecipe { + protected final RecipeProperties properties; + + protected AbstractCraftingRecipe(RecipeProperties properties) { + this.properties = properties; + } + + @Override + public final boolean showNotification() { + return properties.showNotification(); + } + + @Override + public final String group() { + return properties.group(); + } + + @Override + public final CraftingBookCategory category() { + return properties.category(); + } +} diff --git a/projects/common/src/main/java/dan200/computercraft/shared/recipe/BasicRecipeSerialiser.java b/projects/common/src/main/java/dan200/computercraft/shared/recipe/BasicRecipeSerialiser.java index b3bda8f9fc..95eab70492 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/recipe/BasicRecipeSerialiser.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/recipe/BasicRecipeSerialiser.java @@ -38,4 +38,10 @@ private DataResult check(T recipe) { + ", but was " + RegistryHelper.getKeyOrThrow(BuiltInRegistries.RECIPE_SERIALIZER, recipe.getSerializer()) ); } + + @Override + @Deprecated + public StreamCodec streamCodec() { + return streamCodec; + } } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/recipe/CustomShapelessRecipe.java b/projects/common/src/main/java/dan200/computercraft/shared/recipe/CustomShapelessRecipe.java index b413008d96..c68cd59f01 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/recipe/CustomShapelessRecipe.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/recipe/CustomShapelessRecipe.java @@ -4,32 +4,65 @@ package dan200.computercraft.shared.recipe; +import net.minecraft.core.HolderLookup; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.crafting.RecipeSerializer; -import net.minecraft.world.item.crafting.ShapelessRecipe; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.crafting.*; +import net.minecraft.world.item.crafting.display.RecipeDisplay; +import net.minecraft.world.item.crafting.display.ShapelessCraftingRecipeDisplay; +import net.minecraft.world.item.crafting.display.SlotDisplay; +import net.minecraft.world.level.Level; +import javax.annotation.Nullable; +import java.util.List; import java.util.function.Function; /** * A custom version of {@link ShapelessRecipe}, which can be converted to and from a {@link ShapelessRecipeSpec}. */ -public abstract class CustomShapelessRecipe extends ShapelessRecipe { - private final ItemStack result; - private final boolean showNotification; +public abstract class CustomShapelessRecipe extends AbstractCraftingRecipe { + private final ShapelessRecipeSpec spec; + private @Nullable PlacementInfo placementInfo; protected CustomShapelessRecipe(ShapelessRecipeSpec recipe) { - super(recipe.properties().group(), recipe.properties().category(), recipe.result(), recipe.ingredients()); - this.result = recipe.result(); - this.showNotification = recipe.properties().showNotification(); + super(recipe.properties()); + this.spec = recipe; } - public final ShapelessRecipeSpec toSpec() { - return new ShapelessRecipeSpec(RecipeProperties.of(this), getIngredients(), result); + @Override + public PlacementInfo placementInfo() { + if (placementInfo == null) placementInfo = PlacementInfo.create(spec.ingredients()); + return placementInfo; + } + + @Override + public List display() { + return List.of( + new ShapelessCraftingRecipeDisplay( + spec.ingredients().stream().map(Ingredient::display).toList(), + new SlotDisplay.ItemStackSlotDisplay(spec.result()), + new SlotDisplay.ItemSlotDisplay(Items.CRAFTING_TABLE) + ) + ); } @Override - public final boolean showNotification() { - return showNotification; + public boolean matches(CraftingInput input, Level level) { + var ingredients = spec.ingredients(); + if (input.ingredientCount() != ingredients.size()) return false; + // Fast-path with a single item - just check the ingredient matches. + if (input.size() == 1 && ingredients.size() == 1) return ingredients.getFirst().test(input.getItem(0)); + // Otherwise check the stacked contents. + return input.stackedContents().canCraft(placementInfo().unpackedIngredients(), null); + } + + @Override + public ItemStack assemble(CraftingInput input, HolderLookup.Provider registries) { + return spec.result().copy(); + } + + protected final ShapelessRecipeSpec toSpec() { + return spec; } @Override diff --git a/projects/common/src/main/java/dan200/computercraft/shared/recipe/RecipeProperties.java b/projects/common/src/main/java/dan200/computercraft/shared/recipe/RecipeProperties.java index 459a34d29e..5444b8d4d6 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/recipe/RecipeProperties.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/recipe/RecipeProperties.java @@ -16,9 +16,10 @@ /** * Common properties that appear in all {@link CraftingRecipe}s. * - * @param group The (optional) group of the recipe, see {@link CraftingRecipe#getGroup()}. + * @param group The (optional) group of the recipe, see {@link CraftingRecipe#group()}. * @param category The category the recipe appears in, see {@link CraftingRecipe#category()}. * @param showNotification Show notifications when the recipe is unlocked, see {@link CraftingRecipe#showNotification()}. + * @see AbstractCraftingRecipe */ public record RecipeProperties(String group, CraftingBookCategory category, boolean showNotification) { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( @@ -35,6 +36,6 @@ public record RecipeProperties(String group, CraftingBookCategory category, bool ); public static RecipeProperties of(CraftingRecipe recipe) { - return new RecipeProperties(recipe.getGroup(), recipe.category(), recipe.showNotification()); + return new RecipeProperties(recipe.group(), recipe.category(), recipe.showNotification()); } } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/recipe/ShapelessRecipeSpec.java b/projects/common/src/main/java/dan200/computercraft/shared/recipe/ShapelessRecipeSpec.java index ebf165556f..20604dd29f 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/recipe/ShapelessRecipeSpec.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/recipe/ShapelessRecipeSpec.java @@ -5,17 +5,17 @@ package dan200.computercraft.shared.recipe; import com.mojang.serialization.Codec; -import com.mojang.serialization.DataResult; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import dan200.computercraft.shared.network.codec.MoreStreamCodecs; -import net.minecraft.core.NonNullList; import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.item.crafting.ShapelessRecipe; +import java.util.List; + /** * A description of a {@link ShapelessRecipe}. *

@@ -26,16 +26,11 @@ * @param ingredients The ingredients of the recipe. * @param result The result of the recipe. */ -public record ShapelessRecipeSpec(RecipeProperties properties, NonNullList ingredients, ItemStack result) { +public record ShapelessRecipeSpec(RecipeProperties properties, List ingredients, ItemStack result) { /** * A list of {@link Ingredient}s, usable in a {@linkplain ShapelessRecipe shapeless recipe}. */ - private static final Codec> INGREDIENT_CODEC = Ingredient.CODEC_NONEMPTY.listOf().flatXmap(list -> { - var ingredients = list.stream().filter(ingredient -> !ingredient.isEmpty()).toArray(Ingredient[]::new); - if (ingredients.length == 0) return DataResult.error(() -> "No ingredients for shapeless recipe"); - if (ingredients.length > 9) return DataResult.error(() -> "Too many ingredients for shapeless recipe"); - return DataResult.success(NonNullList.of(Ingredient.EMPTY, ingredients)); - }, DataResult::success); + public static final Codec> INGREDIENT_CODEC = Ingredient.CODEC.listOf(1, 9); public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( RecipeProperties.CODEC.forGetter(ShapelessRecipeSpec::properties), @@ -45,7 +40,7 @@ public record ShapelessRecipeSpec(RecipeProperties properties, NonNullList STREAM_CODEC = StreamCodec.composite( RecipeProperties.STREAM_CODEC, ShapelessRecipeSpec::properties, - MoreStreamCodecs.nonNullList(Ingredient.CONTENTS_STREAM_CODEC, Ingredient.EMPTY), ShapelessRecipeSpec::ingredients, + Ingredient.CONTENTS_STREAM_CODEC.apply(ByteBufCodecs.list()), ShapelessRecipeSpec::ingredients, ItemStack.STREAM_CODEC, ShapelessRecipeSpec::result, ShapelessRecipeSpec::new ); diff --git a/projects/common/src/main/java/dan200/computercraft/shared/recipe/function/CopyComponents.java b/projects/common/src/main/java/dan200/computercraft/shared/recipe/function/CopyComponents.java index 8d7425304d..ce2b019087 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/recipe/function/CopyComponents.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/recipe/function/CopyComponents.java @@ -31,7 +31,7 @@ */ public final class CopyComponents implements RecipeFunction { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - Ingredient.CODEC_NONEMPTY.fieldOf("from").forGetter(x -> x.from), + Ingredient.CODEC.fieldOf("from").forGetter(x -> x.from), DataComponentType.CODEC.listOf().optionalFieldOf("include").forGetter(x -> x.include), DataComponentType.CODEC.listOf().optionalFieldOf("exclude").forGetter(x -> x.exclude) ).apply(instance, CopyComponents::new)); diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/FurnaceRefuelHandler.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/FurnaceRefuelHandler.java index 6a5abe38e3..a1119f0758 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/FurnaceRefuelHandler.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/FurnaceRefuelHandler.java @@ -7,6 +7,8 @@ import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.TurtleRefuelHandler; import dan200.computercraft.shared.platform.PlatformHelper; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.item.ItemStack; import java.util.OptionalInt; @@ -14,7 +16,7 @@ public final class FurnaceRefuelHandler implements TurtleRefuelHandler { @Override public OptionalInt refuel(ITurtleAccess turtle, ItemStack currentStack, int slot, int limit) { - var fuelPerItem = getFuelPerItem(currentStack); + var fuelPerItem = getFuelPerItem(((ServerLevel) turtle.getLevel()).getServer(), currentStack); if (fuelPerItem <= 0) return OptionalInt.empty(); if (limit == 0) return OptionalInt.of(0); @@ -33,7 +35,7 @@ public OptionalInt refuel(ITurtleAccess turtle, ItemStack currentStack, int slot return OptionalInt.of(fuelToGive); } - private static int getFuelPerItem(ItemStack stack) { - return (PlatformHelper.get().getBurnTime(stack) * 5) / 100; + private static int getFuelPerItem(MinecraftServer server, ItemStack stack) { + return (PlatformHelper.get().getBurnTime(server, stack) * 5) / 100; } } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/blocks/TurtleBlock.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/blocks/TurtleBlock.java index f879fe3ddd..17d33391fd 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/blocks/TurtleBlock.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/blocks/TurtleBlock.java @@ -16,19 +16,17 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.component.DataComponents; +import net.minecraft.util.RandomSource; import net.minecraft.world.Containers; import net.minecraft.world.InteractionHand; -import net.minecraft.world.ItemInteractionResult; +import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.projectile.AbstractHurtingProjectile; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.item.context.BlockPlaceContext; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Explosion; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.*; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.RenderShape; import net.minecraft.world.level.block.SimpleWaterloggedBlock; @@ -38,7 +36,7 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.StateDefinition; import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import net.minecraft.world.level.block.state.properties.DirectionProperty; +import net.minecraft.world.level.block.state.properties.EnumProperty; import net.minecraft.world.level.material.FluidState; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.Vec3; @@ -57,7 +55,7 @@ public class TurtleBlock extends AbstractComputerBlock implem BlockCodecs.blockEntityCodec(x -> x.type) ).apply(instance, TurtleBlock::new)); - public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING; + public static final EnumProperty FACING = BlockStateProperties.HORIZONTAL_FACING; /** * The explosion resistance to use when a turtle is "immune" to explosions. @@ -120,9 +118,9 @@ protected FluidState getFluidState(BlockState state) { } @Override - protected BlockState updateShape(BlockState state, Direction side, BlockState otherState, LevelAccessor world, BlockPos pos, BlockPos otherPos) { - WaterloggableHelpers.updateShape(state, world, pos); - return state; + protected BlockState updateShape(BlockState state, LevelReader level, ScheduledTickAccess ticker, BlockPos pos, Direction side, BlockPos otherPos, BlockState neighborState, RandomSource randomSource) { + WaterloggableHelpers.updateShape(state, level, ticker, pos); + return super.updateShape(state, level, ticker, pos, side, otherPos, neighborState, randomSource); } @Override @@ -150,14 +148,14 @@ public void setPlacedBy(Level level, BlockPos pos, BlockState state, @Nullable L } @Override - protected ItemInteractionResult useItemOn(ItemStack currentItem, BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { + protected InteractionResult useItemOn(ItemStack currentItem, BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { if (currentItem.getItem() == Items.NAME_TAG && currentItem.has(DataComponents.CUSTOM_NAME) && level.getBlockEntity(pos) instanceof AbstractComputerBlockEntity computer) { // Label to rename computer if (!level.isClientSide) { computer.setLabel(currentItem.getHoverName().getString()); currentItem.shrink(1); } - return ItemInteractionResult.sidedSuccess(level.isClientSide); + return InteractionResult.SUCCESS; } return super.useItemOn(currentItem, state, level, pos, player, hand, hit); diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/items/TurtleItem.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/items/TurtleItem.java index 0b73f436e4..0c6e2c1002 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/items/TurtleItem.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/items/TurtleItem.java @@ -17,7 +17,7 @@ import net.minecraft.core.cauldron.CauldronInteraction; import net.minecraft.core.component.DataComponents; import net.minecraft.network.chat.Component; -import net.minecraft.world.ItemInteractionResult; +import net.minecraft.world.InteractionResult; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.LayeredCauldronBlock; @@ -30,7 +30,7 @@ public TurtleItem(TurtleBlock block, Properties settings) { @Override public Component getName(ItemStack stack) { - var baseString = getDescriptionId(stack); + var baseString = descriptionId; var left = getUpgrade(stack, TurtleSide.LEFT); var right = getUpgrade(stack, TurtleSide.RIGHT); if (left != null && right != null) { @@ -85,12 +85,12 @@ public static int getFuelLevel(ItemStack stack) { } public static final CauldronInteraction CAULDRON_INTERACTION = (blockState, level, pos, player, hand, stack) -> { - if (!stack.has(DataComponents.DYED_COLOR)) return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; + if (!stack.has(DataComponents.DYED_COLOR)) return InteractionResult.TRY_WITH_EMPTY_HAND; if (!level.isClientSide) { stack.remove(DataComponents.DYED_COLOR); LayeredCauldronBlock.lowerFillLevel(blockState, level, pos); } - return ItemInteractionResult.sidedSuccess(level.isClientSide); + return InteractionResult.SUCCESS; }; } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/recipes/TurtleUpgradeRecipe.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/recipes/TurtleUpgradeRecipe.java index 095bb29b6e..5e137f72fd 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/recipes/TurtleUpgradeRecipe.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/recipes/TurtleUpgradeRecipe.java @@ -23,16 +23,6 @@ public TurtleUpgradeRecipe(CraftingBookCategory category) { super(category); } - @Override - public boolean canCraftInDimensions(int x, int y) { - return x >= 3 && y >= 1; - } - - @Override - public ItemStack getResultItem(HolderLookup.Provider registryAccess) { - return new ItemStack(ModRegistry.Items.TURTLE_NORMAL.get()); - } - @Override public boolean matches(CraftingInput inventory, Level world) { return !assemble(inventory, world.registryAccess()).isEmpty(); @@ -126,7 +116,7 @@ public ItemStack assemble(CraftingInput inventory, HolderLookup.Provider registr } @Override - public RecipeSerializer getSerializer() { + public RecipeSerializer getSerializer() { return ModRegistry.RecipeSerializers.TURTLE_UPGRADE.get(); } } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleInventoryCrafting.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleInventoryCrafting.java index 1e66b71af3..dad336fe00 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleInventoryCrafting.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleInventoryCrafting.java @@ -12,9 +12,8 @@ import net.minecraft.world.Container; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.CraftingInput; -import net.minecraft.world.item.crafting.Recipe; +import net.minecraft.world.item.crafting.CraftingRecipe; import net.minecraft.world.item.crafting.RecipeType; -import net.minecraft.world.level.Level; import javax.annotation.Nullable; import java.util.AbstractList; @@ -29,7 +28,7 @@ public final class TurtleInventoryCrafting { private TurtleInventoryCrafting() { } - private static @Nullable FoundRecipe tryCrafting(Level level, Container inventory, int xStart, int yStart) { + private static @Nullable FoundRecipe tryCrafting(ServerLevel level, Container inventory, int xStart, int yStart) { // Check the non-relevant parts of the inventory are empty for (var x = 0; x < TurtleBlockEntity.INVENTORY_WIDTH; x++) { for (var y = 0; y < TurtleBlockEntity.INVENTORY_HEIGHT; y++) { @@ -56,14 +55,13 @@ public int size() { return WIDTH * HEIGHT; } }); - var recipe = level.getRecipeManager().getRecipeFor(RecipeType.CRAFTING, input.input(), level).orElse(null); + var recipe = level.recipeAccess().getRecipeFor(RecipeType.CRAFTING, input.input(), level).orElse(null); return recipe == null ? null : new FoundRecipe(recipe.value(), input.input(), input.left() + xStart, input.top() + yStart); } @Nullable public static List craft(ITurtleAccess turtle, int maxCount) { - var level = turtle.getLevel(); - if (level.isClientSide || !(level instanceof ServerLevel)) return null; + if (!(turtle.getLevel() instanceof ServerLevel level)) return null; var inventory = turtle.getInventory(); @@ -124,6 +122,6 @@ public static List craft(ITurtleAccess turtle, int maxCount) { return Collections.unmodifiableList(results); } - private record FoundRecipe(Recipe recipe, CraftingInput input, int xStart, int yStart) { + private record FoundRecipe(CraftingRecipe recipe, CraftingInput input, int xStart, int yStart) { } } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleTool.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleTool.java index afac649d51..af60437227 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleTool.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleTool.java @@ -228,10 +228,10 @@ private boolean attack(ServerPlayer player, Direction direction, Entity entity) // Compute the total damage, and deal it out. var damage = baseDamage + bonusDamage + tool.getItem().getAttackDamageBonus(entity, baseDamage, source); - if (!entity.hurt(source, damage)) return false; + if (!entity.hurtServer(player.serverLevel(), source, damage)) return false; // Special case for armor stands: attack twice to guarantee destroy - if (entity.isAlive() && entity instanceof ArmorStand) entity.hurt(source, damage); + if (entity.isAlive() && entity instanceof ArmorStand) entity.hurtServer(player.serverLevel(), source, damage); // Apply knockback var knockBack = EnchantmentHelper.modifyKnockback(player.serverLevel(), tool, entity, source, (float) player.getAttributeValue(Attributes.ATTACK_KNOCKBACK)); diff --git a/projects/common/src/main/java/dan200/computercraft/shared/util/ArgumentHelpers.java b/projects/common/src/main/java/dan200/computercraft/shared/util/ArgumentHelpers.java index f4c4fb2578..fce4b32a28 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/util/ArgumentHelpers.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/util/ArgumentHelpers.java @@ -28,7 +28,7 @@ public static T getRegistryEntry(String name, String typeName, Registry r } T value; - if (id == null || (value = registry.get(id)) == null) { + if (id == null || (value = registry.getValue(id)) == null) { throw new LuaException(String.format("Unknown %s '%s'", typeName, name)); } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/util/ColourUtils.java b/projects/common/src/main/java/dan200/computercraft/shared/util/ColourUtils.java index 8f66a6a0a4..cdc607b822 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/util/ColourUtils.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/util/ColourUtils.java @@ -14,7 +14,7 @@ import java.util.List; public final class ColourUtils { - private static final List> DYES = PlatformHelper.get().getDyeTags(); + public static final List> DYES = PlatformHelper.get().getDyeTags(); private ColourUtils() { } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/util/ComponentizationFixers.java b/projects/common/src/main/java/dan200/computercraft/shared/util/ComponentizationFixers.java index 83baa98689..b0560e4abc 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/util/ComponentizationFixers.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/util/ComponentizationFixers.java @@ -8,7 +8,6 @@ import com.mojang.datafixers.Typed; import com.mojang.datafixers.schemas.Schema; import com.mojang.datafixers.types.templates.TypeTemplate; -import com.mojang.datafixers.util.Pair; import com.mojang.serialization.Dynamic; import com.mojang.serialization.OptionalDynamic; import dan200.computercraft.api.upgrades.UpgradeData; @@ -19,10 +18,11 @@ import net.minecraft.util.datafix.fixes.References; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.function.Function; +import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -207,31 +207,19 @@ private static Dynamic createUpgradeData(Dynamic ops, String upgradeId, Op /** * Add our custom data components to the datafixer system. * - * @param type The existing component type definition. + * @param types The component type definition. * @param schema The current schema. - * @return The new component type definition. * @see UpgradeManager#upgradeDataCodec() * @see ModRegistry.DataComponents#POCKET_UPGRADE * @see ModRegistry.DataComponents#LEFT_TURTLE_UPGRADE * @see ModRegistry.DataComponents#RIGHT_TURTLE_UPGRADE */ - public static TypeTemplate addExtraTypes(TypeTemplate type, Schema schema) { + public static void addExtraTypes(Map> types, Schema schema) { // Create a codec for UpgradeData - var upgradeData = DSL.optionalFields("components", References.DATA_COMPONENTS.in(schema)); + Supplier upgradeData = () -> DSL.optionalFields("components", References.DATA_COMPONENTS.in(schema)); - return extraOptionalFields(type, - Pair.of("computercraft:pocket_upgrade", upgradeData), - Pair.of("computercraft:left_turtle_upgrade", upgradeData), - Pair.of("computercraft:right_turtle_upgrade", upgradeData) - ); - } - - @SafeVarargs - @SuppressWarnings("varargs") - private static TypeTemplate extraOptionalFields(TypeTemplate base, Pair... fields) { - return DSL.and(Stream.concat( - Arrays.stream(fields).map(entry -> DSL.optional(DSL.field(entry.getFirst(), entry.getSecond()))), - Stream.of(base) - ).toList()); + types.put("computercraft:pocket_upgrade", upgradeData); + types.put("computercraft:left_turtle_upgrade", upgradeData); + types.put("computercraft:right_turtle_upgrade", upgradeData); } } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/util/RedstoneUtil.java b/projects/common/src/main/java/dan200/computercraft/shared/util/RedstoneUtil.java index 457fb444b2..6a55e344c1 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/util/RedstoneUtil.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/util/RedstoneUtil.java @@ -12,6 +12,7 @@ import net.minecraft.world.level.block.DiodeBlock; import net.minecraft.world.level.block.RedStoneWireBlock; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.redstone.ExperimentalRedstoneUtils; public final class RedstoneUtil { private RedstoneUtil() { @@ -49,7 +50,8 @@ public static void propagateRedstoneOutput(Level world, BlockPos pos, Direction if (!PlatformHelper.get().onNotifyNeighbour(world, pos, block, side)) return; var neighbourPos = pos.relative(side); - world.neighborChanged(neighbourPos, block.getBlock(), pos); + var orientation = ExperimentalRedstoneUtils.initialOrientation(world, side, Direction.UP); + world.neighborChanged(neighbourPos, block.getBlock(), orientation); // We intentionally use updateNeighborsAt here instead of updateNeighborsAtExceptFromFacing, as computers can // both send and receive redstone, and so also need to be updated. world.updateNeighborsAt(neighbourPos, block.getBlock()); diff --git a/projects/common/src/main/java/dan200/computercraft/shared/util/RegistryHelper.java b/projects/common/src/main/java/dan200/computercraft/shared/util/RegistryHelper.java index 9d07a63e3e..902c47d45d 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/util/RegistryHelper.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/util/RegistryHelper.java @@ -27,7 +27,7 @@ private RegistryHelper() { */ @SuppressWarnings("unchecked") public static Registry getRegistry(ResourceKey> id) { - var registry = (Registry) BuiltInRegistries.REGISTRY.get(id.location()); + var registry = (Registry) BuiltInRegistries.REGISTRY.getValue(id.location()); if (registry == null) throw new IllegalArgumentException("Unknown registry " + id); return registry; } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/util/WaterloggableHelpers.java b/projects/common/src/main/java/dan200/computercraft/shared/util/WaterloggableHelpers.java index eb2fd652f5..05a3308d85 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/util/WaterloggableHelpers.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/util/WaterloggableHelpers.java @@ -6,8 +6,10 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; import net.minecraft.world.item.context.BlockPlaceContext; -import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.ScheduledTickAccess; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.BooleanProperty; @@ -34,15 +36,16 @@ public static FluidState getFluidState(BlockState state) { } /** - * Call from {@link net.minecraft.world.level.block.Block#updateShape(BlockState, Direction, BlockState, LevelAccessor, BlockPos, BlockPos)}. + * Call from {@link net.minecraft.world.level.block.Block#updateShape(BlockState, LevelReader, ScheduledTickAccess, BlockPos, Direction, BlockPos, BlockState, RandomSource)}. * - * @param state The current state - * @param world The position of this block - * @param pos The world this block exists in + * @param state The current state + * @param level The position of this block + * @param ticker The ticker to schedule with. + * @param pos The world this block exists in */ - public static void updateShape(BlockState state, LevelAccessor world, BlockPos pos) { + public static void updateShape(BlockState state, LevelReader level, ScheduledTickAccess ticker, BlockPos pos) { if (state.getValue(WATERLOGGED)) { - world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world)); + ticker.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(level)); } } diff --git a/projects/common/src/main/resources/assets/computercraft/models/block/computer_on.json b/projects/common/src/main/resources/assets/computercraft/models/block/computer_on.json index a8518a768e..2382269970 100644 --- a/projects/common/src/main/resources/assets/computercraft/models/block/computer_on.json +++ b/projects/common/src/main/resources/assets/computercraft/models/block/computer_on.json @@ -1,7 +1,6 @@ { "parent": "minecraft:block/orientable", "render_type": "cutout", - "computercraft:emissive_texture": "cursor", "elements": [ { "from": [ 0, 0, 0 ], @@ -18,11 +17,11 @@ { "from": [ 0, 0, 0 ], "to": [ 16, 16, 16 ], + "light_emission": 15, "faces": { "north": { "texture": "#cursor", - "cullface": "north", - "neoforge_data": {"block_light": 15, "sky_light": 15} + "cullface": "north" } } } diff --git a/projects/common/src/main/resources/assets/computercraft/textures/gui/border_advanced.png b/projects/common/src/main/resources/assets/computercraft/textures/gui/border_advanced.png index 06394a48f8808bc1b992742b9bad73f3e9bfbaa3..324503f7a74c97b613990e2e07871f21642ff0c6 100644 GIT binary patch delta 192 zcmX@dbb)b#L_G^L0|SGwUh8TgB^}@s;tHf05G9d{Qk}x3&6Ou3?2?ywZ20(so$|bAXulxD6JPxRZLYSzZ5SK8zGh{*% zCL~c@==?Y1I5;p(XN%Nz9iE;a3uzsxfUgc#UDriL+GYz5Ofvt&!KbD*O^^8(FT6BL^l e7(|^CVPRM|{l#>abrOp~uJLsBb6Mw<&;$Sidpx}W delta 279 zcmV+y0qFk60j2_w7=H)`0002t0GOBn008YtL_t(|ob8xB4udcZM!!U;*Qij~xl!(x z+=D}~2UXcScB(4UA>v0YHb@W#za>cV@P^<|wyG-t0QA!&6k?2nn!Z(C0k0oY`V{j) z(>Ak|0?NuvOj61ilR_Wni};S0%Xser0M0q+^+gGpEt)R57Jm_<5Fv_+TR8oiN3qtj z>exa+?h{7{ePFi~zR))x!?5HI2V?eSEaloaXvXAz=@TMho>iVg+gbeBag3!Z=<8Gt_UlOwBd@Sd>s=E zMHDzC9c>o3=^SBTI~>h%`F7d`4(SULPE5z#c+`B(9b3WhLO9h#F~KOs$$KUbLrTEn U>HyIYL69>%UHx3vIVCg!02k3T3IG5A delta 285 zcmV+&0pk9>0jvU$7=H)`0002t0GOBn008qzL_t(|obA{l4udch#__L&E5HSw!*K~N zFpcK`^9y=nb{b~60FyfaQxi*i0r0a-Y>-hXqAndk9S)=fZM0^;&b zC)SVduNNgzU^LGd1OR2z{)DOW%y>(&0s+%=$0XY`a&v1)KwJXi5)hYwxCF#yeU>eK zf3pHrdA5{e%ovnJ!78_s&8;B;aS4daIcR>HQNU-jD~bZw)7}YcsBGHthZTsZPvg)j jMr*AmSDG#S))spMm7_!)f_6nu00000NkvXXu0mjfigSFR diff --git a/projects/common/src/main/resources/assets/computercraft/textures/gui/border_normal.png b/projects/common/src/main/resources/assets/computercraft/textures/gui/border_normal.png index 7c47d250bf035cc4647efddae2552ebcaeb9c522..eb9b946e12511da61deb035d83dd5ffaa999f7b8 100644 GIT binary patch delta 182 zcmZ3@bc}I=L_G^L0|SGwUh8TgB^uxp;tHgJKv`KiBqSs%D(dLbqyPT>oB8qGOQ0xY zNswPKgTu2MX+TcAr;B5V#`)xg04G*19-f}e6$+h=jy%2^p^c8Zx+1JB(uOOR@^wt$ z7E$1|bhKIArgMaWO<|$H@`qY2FLTW^dU!K<6!jUCmD!dhBr7x=k?ddRxj d+cM=O1H;Kr%Vu44x%e979#2<4mvv4FO#r`dItBm$ delta 284 zcmV+%0ptG00jmO#7=H)`0002t0GOBn008nyL_t(|ob8xFu7n^AhJTImA`J)dTpWg# z7vM6+l?Ncbhzofehm3Dt(mFFwT=ZL&(1b66P)dUxBFd-)GdGX;5#(*#D(L{uxgyop zmH~hmW7(mOhz^s}G+izfLclN#0Fc|-GQVl%lxr~|2@{g&w10`?IDWK{_gv{7Bw<1l)rCR`hjGWujdL!?7+)s;;`u?Y;rY_jP&x=A%KMi{6`^HW iz|75|rMbhm-W3nacTNObmLzKc0000Nn>NP zjqK$>A;yv*zhDN3XE)M-90N}m$B>FSs%H-JGB|KBIXbDf{Oh*4bNRT0@~K$YrEN=; oA2hv7$bGh!Nv}iZ2I^(-boFyt=akR{0LdRKbN~PV diff --git a/projects/common/src/main/resources/assets/computercraft/textures/gui/buttons/terminate_hover.png b/projects/common/src/main/resources/assets/computercraft/textures/gui/buttons/terminate_hover.png deleted file mode 100644 index c14a278061db7b6e0c949d0da8fe5df8f87017b8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 144 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=%3?!FCJ6-`&`~f~8u0UEuL_}Fxd1*<>Nn>NP zjqK$>A;yv*zhDN3XE)M-9DPq0$B>FSs%H)gG8k|$Ilf@{m2XyY@wio=M!D!zsY!he n+`F2$&fLzmL!s!%|IO^3R?JRag|GU7S{XcD{an^LB{Ts5Z)GWX diff --git a/projects/common/src/main/resources/assets/computercraft/textures/gui/buttons/turned_off.png b/projects/common/src/main/resources/assets/computercraft/textures/gui/buttons/turned_off.png deleted file mode 100644 index bb556653efc5e29fc3304fabbe06566fb24bd89c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=%3?!FCJ6-`&`~f~8u0UEuL_}Fxd1*<>Nn>NP zjqK$>A;yv*zhDN3XE)M-90N}m$B>FSrDrzsG8phMIZp9Zy20>%|Ll#y&u6b@xU*o= nX@S%>?fLpon0PkxP3Nn>NP zjqK$>A;yv*zhDN3XE)M-90N}m$B>FSrDrzsG8phMIc{?fLpon0PkxP32 delta 207 zcmV;=05Jcc0p9_T7=H)`0002xdY?4_005>*L_t(|obA@V4Z<)GhT-p`Y+{Kqu7fcw zF$1i@0Ct%XC<&DXGk~zJ=Vu60MX6#FiO9`8r7fLbcSpvU)Sq?$fY;}aDIq-IU7Wnn zIrn=!-?!{+0PrrNojZ7GKL;_dvcLS7X7Lwh(x4IzD$$@44M-}{pb`x#sU9@!LW5RV zXuUb4uIq5Q9xG*y8UPR$ves4&@h(DGh_D?GO)#lekgyN{d;#%oF4eEvLH7Uv002ov JPDHLkV1h@HRj4#O}Eh2iI@_n4-X??ypA z)`&xLgrOdyJOSoCLo!rtr1dJT3h_rH*?*YHd*AYs0RXZJ_QYodC*FNOl9#N`1^`Zs z;q2h6{TvjgaQMrAahGp6$$~T%q_H541!*iuV?mnkLE9~~89b^K8XseeF=Bqrow7b0 x08}XyLg*U8iBY8x-M>yWck``RP?bUe@CMDkFt{0`X+8h|002ovPDHLkV1jSvQ?md7 diff --git a/projects/common/src/main/resources/assets/computercraft/textures/gui/pocket_bottom_normal.png b/projects/common/src/main/resources/assets/computercraft/textures/gui/pocket_bottom_normal.png index 0699e8a18d3fc418e1b0b98c010ea99a33d5c8e7..8b02335019d6d6bae957478a852b793d37419f97 100644 GIT binary patch delta 145 zcmcb?xR7yzL_G^L0|SG2ND~{75(@AMaRt)K%E}=jAyH9LM~@!;_wQf!?eFh_qKqX$ ze!&b5&u*jvIkuiIjv*44lLdGS3kwZJSeOG9E_+U7)Jc)zV)StGNC@Fzn<649F?UMC u0SO)lodp8T0<$JCFf%V!&`MxnIJ+qD`TkR$RtyYW3=E#GelF{r5}E))t}C(t delta 200 zcmV;(05|`k0oVbM7=H)`0002xdY?4_005s!L_t(|obA@J2?QY!h2iJ1*vMc3)@3n9 zHefSiGzG{sV&X-@!QJW!yKLeY$tuoowu*>aDFpzKQo@-K0&>o$`y-{4;oaVQ001-N zSiSgee+N0|hOfNJ>-GtYcF@cYn%O}!J7{JH&Fr9=$AkL6P(gQyh%&~s7~|LGFIwxR zfwk79^Qte1s99?t3u0!7h*F;)iKs12yO4+|0C)qkoiqV;#9Jx=00009!zjhUIv&7#|plSxG4 b0RzL2DKaH1LOlb3`WQT2{an^LB{Ts5>Q5uD delta 131 zcmbQhIE8V7L=6WU0|Ud!x8Jt_sc26Z$B>FS$tfNw2?;aKfB1jzZYIwYCO0;=Q#=VE z5EvHbCRp+F7u(4;gTO3?HpM4RfzBBz9H;N@E`K=3xjk><%SkS5ZmLgpx?&EUn81;! iAs_V5f1~0Q28N4E#C#(wi|zoeVeoYIb6Mw<&;$T+95iMC diff --git a/projects/common/src/main/resources/assets/computercraft/textures/gui/sidebar_normal.png b/projects/common/src/main/resources/assets/computercraft/textures/gui/sidebar_normal.png index 495c031a04e29819964ec8780b88eed7e0894f72..2e6f469dea17bef65384b78ef0fcf453c76cceca 100644 GIT binary patch delta 122 zcmeBW>}H%GQOv^3z`$UA_*FZQ;t%i%aRt)K%E}=jAxDoM{rB(RpL;4CKq1DGAirP+ zhi5m^fE+DP7sn8e>&XcMEewooZsHsT2?CBulFf~b%^k*}5q@3?3l1FMNIw|Mz~Hb- VblQc8Z*4$b44$rjF6*2UngHs^Cb|Fs delta 124 zcmeBX>}8xFQOd!_z`$_w?e{G}D#X*pF{ENna!LbJYUaWjEq{M6H6%22=?T>y12$Dj a0R|~vUuO@t6~BPyGkCiCxvXfiWE|9}m z666=m;PC858jz#s>Eal|ASXYA^>bP0l+XkK+Z`l4 literal 0 HcmV?d00001 diff --git a/projects/common/src/main/resources/assets/computercraft/textures/gui/sprites/buttons/terminate_hover.png b/projects/common/src/main/resources/assets/computercraft/textures/gui/sprites/buttons/terminate_hover.png new file mode 100644 index 0000000000000000000000000000000000000000..79f491e0a2bb8c71f9312ae8d5018e8867c1c74a GIT binary patch literal 131 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=-3?y@QpIZW?*aCb)T!FNRh)9>sMsFaCu_VYZ zn8D%MjWi%f+tbA{gyVYhiuwZ|{xctDXKs^c<0zopr0QROO`Tzg` literal 0 HcmV?d00001 diff --git a/projects/common/src/main/resources/assets/computercraft/textures/gui/buttons/turned_on.png b/projects/common/src/main/resources/assets/computercraft/textures/gui/sprites/buttons/turned_on.png similarity index 100% rename from projects/common/src/main/resources/assets/computercraft/textures/gui/buttons/turned_on.png rename to projects/common/src/main/resources/assets/computercraft/textures/gui/sprites/buttons/turned_on.png diff --git a/projects/common/src/main/resources/assets/computercraft/textures/gui/buttons/turned_on_hover.png b/projects/common/src/main/resources/assets/computercraft/textures/gui/sprites/buttons/turned_on_hover.png similarity index 100% rename from projects/common/src/main/resources/assets/computercraft/textures/gui/buttons/turned_on_hover.png rename to projects/common/src/main/resources/assets/computercraft/textures/gui/sprites/buttons/turned_on_hover.png diff --git a/projects/common/src/main/resources/assets/computercraft/textures/gui/sprites/turtle_advanced_selected_slot.png b/projects/common/src/main/resources/assets/computercraft/textures/gui/sprites/turtle_advanced_selected_slot.png new file mode 100644 index 0000000000000000000000000000000000000000..1550ea4c6e1dfffe0fffc85e8f0552a606b266f5 GIT binary patch literal 461 zcmV;;0W$uHP)M*O1uQklWgk+uM`f+>@M3$%y~}00DGTPE!Ct=GbNc006;BL_t&- z8EwHmPQySHM$tRpJbUa!A{}KKw!!{4LW@8+277*u5Zxr_xL1nH(@Gkguc+-4@L|Ur zq!Et!EBu^dh=C!$TjR5(F`I*}?%A4ncFv6UO(yX#0_O$YMtWyPk?2L5c%*3K5zX8) zgwa#kMWJV04q4ZEbCCZf=;-Y1?DqEd`1ttw`T6|({Qdp?|Ns9{Wh%x10004WQchCvx)bA*%UAHV8(>8AwFeYm9Z zRM}orm+7iz+*i>T#?1_;PcZDZYG;U@^UbW8!J3gp!`9*UksB$(3NPXv=KD6x=nhnE zU|`};tjyIR-xkQMBjYTpQ6cNfDT8 zu+zMF3c`dJS~5NP`$>h7MZ!|l?yud!&0GQZxUaAXC`@MXWn)|wDy-4W@Y2f2VXk9C kmY@bBEL~AbADFX`(Qk#6&>f|DKR{-Ay85}Sb4q9e01)EIga7~l literal 1455 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k7&w@L)Zt|+CxF!L0G|+7APoWW@wN$xwuwo0 zNy+xfN%qOf_9?0Msc8;rsZQysjv47r85vF)na){RF1gvRxp{7Rxo-LS?!`r(on0Qi zy)F|b#7vnSH)DFj%o&L@XC}^?l{9;H^6WV&b7m*ao$EVyZtA?bY4he~%%7jWU_r*h z1(^#MWG`BnvuIJ?;zhYjmK3aB9kP2@?Y_Nr`}WuG-&cQNf5X88jfW049Xix>_;B-) zBP~adwjMjycKk%%iQ{c2Pqv>r*>?I=`?<4S*RD>uaecy#8xwBdnt1#6+RjMe!_tg4G;5|U6v0J5$55v z781|9Tgmv!^)>H~&uj*Tj}I;3v=@Ex{z~hn1+qykNfP^>NBT`}v;16kF0(kJyTfSG zs%DKveexE(DG@eu8>TxACJLg6Q0R|=@a$w+KU{qjWX#nx5%XuKj6p?24*NGvH znaUhCYz%kKBCE@qqXK5m12zEpqxs$kX+zfA-7od5pmzND#q{cp=aM%SN; z=gzcTmpN+S&nVV-k5z%;(tci>sM>_@Pa0)!-hOg_=l;uoa_aliYovGV{&e8sboR28 zEhqPXe$bX~Ein^UFv&Hp{>!kteRaRh7UloXZ(iDYOLR_-`vu?g+x82eEMrx_D_D}@ zKEV_etXTa2Va83tDKYP49nZeu=sK}UnIoHlaf20eN({@cEAJTA{h#WRec*|`gkg@| zoY&u(f>tYAcRMiNxp(QuQ@#ZTb;}r7pfR@PjBFW;?(O}`9oPOAy-+J>S$gZ|=k3-G z**64JcpDgQd=V*Fz4PnIpKWPRcE5Z4^j&ttwl`eIL@?s}|B~F_jBhx+(-eZ2Xz`s0HY0()QbGf!4)uxk6d#e8*F z$LFI**Q`2ip;7ZcdLF~774C*R%ig@~EIj$y@<3$$+Z&f(NX{@}T(jqwveL0>$7eES z7?~SnGVL&7+sS+*%i@NqUgxrgud8Fv9b;4TXV}~(eV`a*cvkIEbI;xG8p#Zw+oB!5 z@cPVRsQP$DBZV(PYVOwN%PSjC7PCjJiGMp!Q^B8M`P}*0-3K-$CtPB=us>q=t>#I0s31_&V+CwExS_3Omf<^J5d7u79lC@5mbK z*XMK@g;))2<{nvdukU2x))&_%*G+j^^w2z!kzr7P2D9I+3hvyWEB`eA06ECh)z4*} HQ$iB}5aAYx diff --git a/projects/common/src/main/resources/assets/computercraft/textures/gui/turtle_normal.png b/projects/common/src/main/resources/assets/computercraft/textures/gui/turtle_normal.png index f676c56b20d2173381b54b6ecef670edc0c0b78c..9426aa22025285bfb41aa83b5649219b7c89e098 100644 GIT binary patch literal 695 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k7+9Er6kFKIlR!#3z$e5NNCSbHnOR6kNLN?a z(W6Iy|Ni~=@85s_{-szaivi^rOM?7@862M7NCO(+<>}%WQgQ3;UBkRX1|kiK&)FPh zPo3e_$_o%(Y5YLBKwwqWqZ_dSh1+>N=Qr=qKP8a*Lv`{C%_Ew*Oud@-3b;#h6%Lpg zIY>rxOn5x!o)kv_i@<{K498=8oQ)Zq<}rC0GbZJ^H8U`AC^S%uIP=t0?|>@^nTY=3mVlmwH~V4Z1&Tx&w>WF-)2+uPUI zH!(3WJ3A|pNap9~7Zw&47Z;b7mZVatOeR}iUS3&Qk;~<)tE&oyVr^|rsZ^>|s*Q~e zjYhM#w|8)GaCmsA*Xs=igVAU-nM`K0nHM%wYgr89UMG?OUOCSI08I%d_>pfdYGtw; z(m-c;m3>-UR*mOGp8XwlB?2{UL(R-_2|vlXF*P%p8Jg8QP?2LF<`nu6jhj^Ozh4+1 zEvPy_BXCwYUci13aNN+lUl)?3Q6M3aqMkq$6h^_S$~VaRVs#T~~L^ z@>;)Ux|C;r3r?VxbZT;4kC*dd`l=SP2Pk{k)8g^K8bIy<4TFC@kQ<;EUCs`ObX!Ln z|ACBaaHU>1Ju5GN8?H#(EhuUK@tMS*4=$ZCtVazOn5y@GK|1q8$#_r6O(gi>PTy0N z=P33`A3)=ucYextHOVvdZ?@^&-G)e;X}2Itq6os{}}Y5p1qn%&=C z1~&8bI{+bxBUo!UFP*8?lf*={(Wg#Le&pm=iR}H;RYgidWX9tNbT|j|I%c}qT?3&< z$2{Fs?u0)LDmQ>Qp0J zK(tCI_XQ}qv`$pr)UEE%M z>5zf;v2O6hcSFvlzGZicgPri2!1&xHBn%3>P-Usp{N%RmM-}+ z>vmy3?#*OWv^LOZI8zmsUI+MdNp|T^b1&BflK51$mzpxitxq%joYCt26$2Xz{G~#3 ztX)?@*X4H|D6+XBE5BmYylHOop`dYy)gMq0ONg?q-2wj-8?7-~ - -#define FONT_WIDTH 6.0 -#define FONT_HEIGHT 9.0 - -uniform sampler2D Sampler0; // Font -uniform usamplerBuffer Tbo; - -layout(std140) uniform MonitorData { - vec3 Palette[16]; - int Width; - int Height; - ivec2 CursorPos; - int CursorColour; -}; -uniform int CursorBlink; - -uniform vec4 ColorModulator; -uniform float FogStart; -uniform float FogEnd; -uniform vec4 FogColor; - -in float vertexDistance; -in vec2 fontPos; - -out vec4 fragColor; - -vec2 texture_corner(int index) { - float x = 1.0 + float(index % 16) * (FONT_WIDTH + 2.0); - float y = 1.0 + float(index / 16) * (FONT_HEIGHT + 2.0); - return vec2(x, y); -} - -vec4 recolour(vec4 texture, int colour) { - return vec4(texture.rgb * Palette[colour], texture.rgba); -} - -void main() { - vec2 term_pos = vec2(fontPos.x / FONT_WIDTH, fontPos.y / FONT_HEIGHT); - vec2 corner = floor(term_pos); - - ivec2 cell = ivec2(corner); - int index = 3 * (clamp(cell.x, 0, Width - 1) + clamp(cell.y, 0, Height - 1) * Width); - - // 1 if 0 <= x, y < Width, Height, 0 otherwise - vec2 outside = step(vec2(0.0, 0.0), vec2(cell)) * step(vec2(cell), vec2(float(Width) - 1.0, float(Height) - 1.0)); - float mult = outside.x * outside.y; - - int character = int(texelFetch(Tbo, index).r); - int fg = int(texelFetch(Tbo, index + 1).r); - int bg = int(texelFetch(Tbo, index + 2).r); - - vec2 pos = (term_pos - corner) * vec2(FONT_WIDTH, FONT_HEIGHT); - vec4 charTex = recolour(texture(Sampler0, (texture_corner(character) + pos) / 256.0), fg); - - // Applies the cursor on top of the current character if we're blinking and in the current cursor's cell. We do it - // this funky way to avoid branches. - vec4 cursorTex = recolour(texture(Sampler0, (texture_corner(95) + pos) / 256.0), CursorColour); // 95 = '_' - vec4 img = mix(charTex, cursorTex, cursorTex.a * float(CursorBlink) * (CursorPos == cell ? 1.0 : 0.0)); - - vec4 colour = vec4(mix(Palette[bg], img.rgb, img.a * mult), 1.0) * ColorModulator; - - fragColor = linear_fog(colour, vertexDistance, FogStart, FogEnd, FogColor); -} diff --git a/projects/common/src/main/resources/assets/minecraft/shaders/core/computercraft/monitor_tbo.json b/projects/common/src/main/resources/assets/minecraft/shaders/core/computercraft/monitor_tbo.json deleted file mode 100644 index e29e42e1e9..0000000000 --- a/projects/common/src/main/resources/assets/minecraft/shaders/core/computercraft/monitor_tbo.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "vertex": "computercraft/monitor_tbo", - "fragment": "computercraft/monitor_tbo", - "attributes": [ "Position" ], - "samplers": [ { "name": "Sampler0" } ], - "uniforms": [ - { "name": "ModelViewMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, - { "name": "ProjMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, - { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] }, - { "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] }, - { "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] }, - { "name": "FogColor", "type": "float", "count": 4, "values": [ 0.0, 0.0, 0.0, 0.0 ] }, - { "name": "FogShape", "type": "int", "count": 1, "values": [ 0 ] }, - - { "name": "Tbo", "type": "int", "count": 1, "values": [ 3 ] }, - { "name": "CursorBlink", "type": "int", "count": 1, "values": [ 0 ] } - ] -} diff --git a/projects/common/src/main/resources/assets/minecraft/shaders/core/computercraft/monitor_tbo.vsh b/projects/common/src/main/resources/assets/minecraft/shaders/core/computercraft/monitor_tbo.vsh deleted file mode 100644 index 681f36cc3d..0000000000 --- a/projects/common/src/main/resources/assets/minecraft/shaders/core/computercraft/monitor_tbo.vsh +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-FileCopyrightText: 2020 The CC: Tweaked Developers -// -// SPDX-License-Identifier: MPL-2.0 - -#version 150 - -#moj_import - -in vec3 Position; -in vec2 UV0; - -uniform mat4 ModelViewMat; -uniform mat4 ProjMat; -uniform vec3 ChunkOffset; -uniform int FogShape; - -out float vertexDistance; -out vec2 fontPos; - -void main() { - vec3 pos = Position + ChunkOffset; - gl_Position = ProjMat * ModelViewMat * vec4(pos, 1.0); - - vertexDistance = fog_distance(pos, FogShape); - fontPos = UV0; -} diff --git a/projects/common/src/main/resources/computercraft-common.accesswidener b/projects/common/src/main/resources/computercraft-common.accesswidener index a0ffacef95..7ce5c025d9 100644 --- a/projects/common/src/main/resources/computercraft-common.accesswidener +++ b/projects/common/src/main/resources/computercraft-common.accesswidener @@ -7,8 +7,6 @@ accessWidener v1 named # Additional access wideners for vanilla code. This is a effectively the subset of Fabric's transitive access wideners # that we actually use -accessible class net/minecraft/world/level/block/entity/BlockEntityType$BlockEntitySupplier - accessible method net/minecraft/client/renderer/blockentity/BlockEntityRenderers register (Lnet/minecraft/world/level/block/entity/BlockEntityType;Lnet/minecraft/client/renderer/blockentity/BlockEntityRendererProvider;)V accessible class net/minecraft/world/item/CreativeModeTab$Output accessible field net/minecraft/world/item/CreativeModeTabs OP_BLOCKS Lnet/minecraft/resources/ResourceKey; @@ -30,3 +28,4 @@ accessible field net/minecraft/data/models/ItemModelGenerators output Ljava/util accessible method net/minecraft/data/models/ItemModelGenerators generateFlatItem (Lnet/minecraft/world/item/Item;Lnet/minecraft/data/models/model/ModelTemplate;)V accessible method net/minecraft/data/models/ItemModelGenerators generateFlatItem (Lnet/minecraft/world/item/Item;Ljava/lang/String;Lnet/minecraft/data/models/model/ModelTemplate;)V accessible method net/minecraft/data/models/model/TextureSlot create (Ljava/lang/String;)Lnet/minecraft/data/models/model/TextureSlot; +accessible method net/minecraft/data/recipes/RecipeProvider inventoryTrigger ([Lnet/minecraft/advancements/critereon/ItemPredicate;)Lnet/minecraft/advancements/Criterion; diff --git a/projects/common/src/main/resources/computercraft.accesswidener b/projects/common/src/main/resources/computercraft.accesswidener index 081b21533c..704b863c9f 100644 --- a/projects/common/src/main/resources/computercraft.accesswidener +++ b/projects/common/src/main/resources/computercraft.accesswidener @@ -7,16 +7,14 @@ accessWidener v1 named # Shared vanilla and Fabric access wideners. This should not include things already exposed by Fabric's transitive # wideners. +accessible class net/minecraft/world/level/block/entity/BlockEntityType$BlockEntitySupplier +accessible method net/minecraft/world/level/block/entity/BlockEntityType (Lnet/minecraft/world/level/block/entity/BlockEntityType$BlockEntitySupplier;Ljava/util/Set;)V + accessible method net/minecraft/client/renderer/RenderType create (Ljava/lang/String;Lcom/mojang/blaze3d/vertex/VertexFormat;Lcom/mojang/blaze3d/vertex/VertexFormat$Mode;IZZLnet/minecraft/client/renderer/RenderType$CompositeState;)Lnet/minecraft/client/renderer/RenderType$CompositeRenderType; accessible method net/minecraft/world/level/storage/LevelResource (Ljava/lang/String;)V # DirectVertexBuffer -accessible field com/mojang/blaze3d/vertex/VertexBuffer vertexBufferId I -accessible field com/mojang/blaze3d/vertex/VertexBuffer indexType Lcom/mojang/blaze3d/vertex/VertexFormat$IndexType; accessible field com/mojang/blaze3d/vertex/VertexBuffer indexCount I -accessible field com/mojang/blaze3d/vertex/VertexBuffer mode Lcom/mojang/blaze3d/vertex/VertexFormat$Mode; -accessible field com/mojang/blaze3d/vertex/VertexBuffer sequentialIndices Lcom/mojang/blaze3d/systems/RenderSystem$AutoStorageIndexBuffer; -accessible field com/mojang/blaze3d/vertex/VertexBuffer format Lcom/mojang/blaze3d/vertex/VertexFormat; # ClientTableFormatter accessible field net/minecraft/client/gui/components/ChatComponent allMessages Ljava/util/List; @@ -31,6 +29,4 @@ accessible method com/mojang/blaze3d/audio/Channel pumpBuffers (I)V accessible field net/minecraft/client/sounds/SoundEngine executor Lnet/minecraft/client/sounds/SoundEngineExecutor; # Turtle model -accessible method net/minecraft/client/renderer/block/model/ItemOverrides ()V - accessible class net/minecraft/util/datafix/fixes/ItemStackComponentizationFix$ItemStackData diff --git a/projects/common/src/main/resources/computercraft.mixins.json b/projects/common/src/main/resources/computercraft.mixins.json index 84cd676128..4118cfb5a5 100644 --- a/projects/common/src/main/resources/computercraft.mixins.json +++ b/projects/common/src/main/resources/computercraft.mixins.json @@ -8,6 +8,7 @@ }, "mixins": [ "ItemStackComponentizationFixMixin", - "V1460Mixin" + "V1460Mixin", + "V3818_3Mixin" ] } diff --git a/projects/common/src/test/java/dan200/computercraft/TestPlatformHelper.java b/projects/common/src/test/java/dan200/computercraft/TestPlatformHelper.java index fae335b787..9c30345ec3 100644 --- a/projects/common/src/test/java/dan200/computercraft/TestPlatformHelper.java +++ b/projects/common/src/test/java/dan200/computercraft/TestPlatformHelper.java @@ -21,6 +21,7 @@ import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.ResourceKey; +import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.tags.TagKey; @@ -35,7 +36,7 @@ import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.CraftingInput; -import net.minecraft.world.item.crafting.Recipe; +import net.minecraft.world.item.crafting.CraftingRecipe; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; @@ -115,13 +116,13 @@ public RecipeIngredients getRecipeIngredients() { } @Override - public int getBurnTime(ItemStack stack) { + public int getBurnTime(MinecraftServer server, ItemStack stack) { throw new UnsupportedOperationException("Cannot get burn time inside tests"); } @Override public ItemStack getCraftingRemainingItem(ItemStack stack) { - return new ItemStack(stack.getItem().getCraftingRemainingItem()); + return stack.getItem().getCraftingRemainder(); } @Override @@ -161,7 +162,7 @@ public ContainerTransfer getContainer(ServerLevel level, BlockPos pos, Direction } @Override - public List getRecipeRemainingItems(ServerPlayer player, Recipe recipe, CraftingInput container) { + public List getRecipeRemainingItems(ServerPlayer player, CraftingRecipe recipe, CraftingInput container) { throw new UnsupportedOperationException("Cannot query recipes inside tests"); } diff --git a/projects/common/src/testMod/java/dan200/computercraft/export/Exporter.java b/projects/common/src/testMod/java/dan200/computercraft/export/Exporter.java index 43b2b80a99..d223f1a00b 100644 --- a/projects/common/src/testMod/java/dan200/computercraft/export/Exporter.java +++ b/projects/common/src/testMod/java/dan200/computercraft/export/Exporter.java @@ -24,8 +24,9 @@ import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.RecipeType; -import net.minecraft.world.item.crafting.ShapedRecipe; -import net.minecraft.world.item.crafting.ShapelessRecipe; +import net.minecraft.world.item.crafting.display.ShapedCraftingRecipeDisplay; +import net.minecraft.world.item.crafting.display.ShapelessCraftingRecipeDisplay; +import net.minecraft.world.item.crafting.display.SlotDisplay; import java.io.File; import java.io.IOException; @@ -83,34 +84,36 @@ private static void export(Path root, ImageRenderer renderer) throws IOException } // Now find all CC recipes. - var level = Objects.requireNonNull(Minecraft.getInstance().level); - for (var recipe : level.getRecipeManager().getAllRecipesFor(RecipeType.CRAFTING)) { - var result = recipe.value().getResultItem(level.registryAccess()); - if (!RegistryHelper.getKeyOrThrow(BuiltInRegistries.ITEM, result.getItem()).getNamespace().equals(ComputerCraftAPI.MOD_ID)) { - continue; - } + var server = Objects.requireNonNull(Minecraft.getInstance().getSingleplayerServer()); + for (var recipe : server.getRecipeManager().getRecipes()) { + if (recipe.value().getType() != RecipeType.CRAFTING) continue; + if (!recipe.id().location().getNamespace().equals(ComputerCraftAPI.MOD_ID)) continue; + + var displayInfos = recipe.value().display(); + if (displayInfos.isEmpty()) continue; + var displayInfo = displayInfos.getFirst(); + + var result = ((SlotDisplay.ItemStackSlotDisplay) displayInfo.result()).stack(); if (!result.getComponentsPatch().isEmpty()) { TestHooks.LOG.warn("Skipping recipe {} as it has NBT", recipe.id()); continue; } - if (recipe.value() instanceof ShapedRecipe shaped) { + if (displayInfo instanceof ShapedCraftingRecipeDisplay shaped) { var converted = new JsonDump.Recipe(result); - for (var x = 0; x < shaped.getWidth(); x++) { - for (var y = 0; y < shaped.getHeight(); y++) { - var ingredient = shaped.getIngredients().get(x + y * shaped.getWidth()); - if (ingredient.isEmpty()) continue; - + for (var x = 0; x < shaped.width(); x++) { + for (var y = 0; y < shaped.height(); y++) { + var ingredient = shaped.ingredients().get(x + y * shaped.width()); converted.setInput(x + y * 3, ingredient, items); } } dump.recipes.put(recipe.id().toString(), converted); - } else if (recipe.value() instanceof ShapelessRecipe shapeless) { + } else if (displayInfo instanceof ShapelessCraftingRecipeDisplay shapeless) { var converted = new JsonDump.Recipe(result); - var ingredients = shapeless.getIngredients(); + var ingredients = shapeless.ingredients(); for (var i = 0; i < ingredients.size(); i++) { converted.setInput(i, ingredients.get(i), items); } diff --git a/projects/common/src/testMod/java/dan200/computercraft/export/ImageRenderer.java b/projects/common/src/testMod/java/dan200/computercraft/export/ImageRenderer.java index 0212ec0f55..995709f01e 100644 --- a/projects/common/src/testMod/java/dan200/computercraft/export/ImageRenderer.java +++ b/projects/common/src/testMod/java/dan200/computercraft/export/ImageRenderer.java @@ -4,12 +4,10 @@ package dan200.computercraft.export; +import com.mojang.blaze3d.ProjectionType; import com.mojang.blaze3d.pipeline.TextureTarget; import com.mojang.blaze3d.platform.NativeImage; import com.mojang.blaze3d.systems.RenderSystem; -import com.mojang.blaze3d.vertex.VertexSorting; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.FogRenderer; import org.joml.Matrix4f; import org.lwjgl.opengl.GL12; @@ -25,39 +23,38 @@ public class ImageRenderer implements AutoCloseable { public static final int WIDTH = 64; public static final int HEIGHT = 64; - private final TextureTarget framebuffer = new TextureTarget(WIDTH, HEIGHT, true, Minecraft.ON_OSX); - private final NativeImage image = new NativeImage(WIDTH, HEIGHT, Minecraft.ON_OSX); + private final TextureTarget framebuffer = new TextureTarget(WIDTH, HEIGHT, true); + private final NativeImage image = new NativeImage(WIDTH, HEIGHT, true); private @Nullable Matrix4f projectionMatrix; public ImageRenderer() { framebuffer.setClearColor(0, 0, 0, 0); - framebuffer.clear(Minecraft.ON_OSX); + framebuffer.clear(); } public void setupState() { - projectionMatrix = RenderSystem.getProjectionMatrix(); - RenderSystem.setProjectionMatrix(new Matrix4f().identity().ortho(0, 16, 0, 16, 1000, 3000), VertexSorting.DISTANCE_TO_ORIGIN); + RenderSystem.backupProjectionMatrix(); + RenderSystem.setProjectionMatrix(new Matrix4f().identity().ortho(0, 16, 0, 16, 1000, 3000), ProjectionType.ORTHOGRAPHIC); var transform = RenderSystem.getModelViewStack(); transform.pushMatrix(); transform.identity(); transform.translate(0.0f, 0.0f, -2000.0f); - FogRenderer.setupNoFog(); + // FIXME: FogRenderer.toggleFog() } public void clearState() { if (projectionMatrix == null) throw new IllegalStateException("Not currently rendering"); - RenderSystem.setProjectionMatrix(projectionMatrix, VertexSorting.DISTANCE_TO_ORIGIN); - RenderSystem.getModelViewStack().popMatrix(); + RenderSystem.restoreProjectionMatrix(); } public void captureRender(Path output, Runnable render) throws IOException { Files.createDirectories(output.getParent()); framebuffer.bindWrite(true); - RenderSystem.clear(GL12.GL_COLOR_BUFFER_BIT | GL12.GL_DEPTH_BUFFER_BIT, Minecraft.ON_OSX); + RenderSystem.clear(GL12.GL_COLOR_BUFFER_BIT | GL12.GL_DEPTH_BUFFER_BIT); render.run(); framebuffer.unbindWrite(); diff --git a/projects/common/src/testMod/java/dan200/computercraft/export/JsonDump.java b/projects/common/src/testMod/java/dan200/computercraft/export/JsonDump.java index fcad316ab0..c773a4906e 100644 --- a/projects/common/src/testMod/java/dan200/computercraft/export/JsonDump.java +++ b/projects/common/src/testMod/java/dan200/computercraft/export/JsonDump.java @@ -6,10 +6,12 @@ import dan200.computercraft.shared.util.RegistryHelper; import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.util.context.ContextMap; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; -import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.display.SlotDisplay; +import net.minecraft.world.item.crafting.display.SlotDisplayContext; import java.util.Arrays; import java.util.Map; @@ -30,10 +32,10 @@ public Recipe(ItemStack output) { count = output.getCount(); } - public void setInput(int pos, Ingredient ingredient, Set trackedItems) { - if (ingredient.isEmpty()) return; + public void setInput(int pos, SlotDisplay ingredient, Set trackedItems) { + if (ingredient instanceof SlotDisplay.Empty) return; - var items = ingredient.getItems(); + var items = ingredient.resolveForStacks(new ContextMap.Builder().create(SlotDisplayContext.CONTEXT)); // First try to simplify some tags to something easier. for (var stack : items) { @@ -45,9 +47,9 @@ public void setInput(int pos, Ingredient ingredient, Set trackedItems) { return; } - var itemIds = new String[items.length]; - for (var i = 0; i < items.length; i++) { - var item = items[i].getItem(); + var itemIds = new String[items.size()]; + for (var i = 0; i < items.size(); i++) { + var item = items.get(i).getItem(); trackedItems.add(item); itemIds[i] = RegistryHelper.getKeyOrThrow(BuiltInRegistries.ITEM, item).toString(); } diff --git a/projects/common/src/testMod/java/dan200/computercraft/gametest/core/CCTestCommand.java b/projects/common/src/testMod/java/dan200/computercraft/gametest/core/CCTestCommand.java index 3b44cedb4f..05672d0027 100644 --- a/projects/common/src/testMod/java/dan200/computercraft/gametest/core/CCTestCommand.java +++ b/projects/common/src/testMod/java/dan200/computercraft/gametest/core/CCTestCommand.java @@ -17,8 +17,8 @@ import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.server.MinecraftServer; -import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.decoration.ArmorStand; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.entity.StructureBlockEntity; import net.minecraft.world.level.storage.LevelResource; @@ -27,7 +27,6 @@ import java.io.UncheckedIOException; import java.nio.file.Path; -import static dan200.computercraft.core.util.Nullability.assertNonNull; import static dan200.computercraft.shared.command.builder.HelpingArgumentBuilder.choice; import static net.minecraft.commands.Commands.literal; @@ -69,19 +68,19 @@ public static void register(CommandDispatcher dispatcher) { var info = GameTestRegistry.getTestFunction(structureBlock.getMetaData()); // Kill the existing armor stand - player - .serverLevel().getEntities(EntityType.ARMOR_STAND, x -> x.isAlive() && x.getName().getString().equals(info.testName())) - .forEach(Entity::kill); + var level = player.serverLevel(); + level.getEntities(EntityType.ARMOR_STAND, x -> x.isAlive() && x.getName().getString().equals(info.testName())) + .forEach(e -> e.kill(level)); // And create a new one var nbt = new CompoundTag(); nbt.putBoolean("Marker", true); nbt.putBoolean("Invisible", true); - var armorStand = assertNonNull(EntityType.ARMOR_STAND.create(player.level())); + var armorStand = new ArmorStand(EntityType.ARMOR_STAND, level); armorStand.readAdditionalSaveData(nbt); armorStand.copyPosition(player); armorStand.setCustomName(Component.literal(info.testName())); - player.level().addFreshEntity(armorStand); + level.addFreshEntity(armorStand); return 0; })) diff --git a/projects/common/src/testMod/java/dan200/computercraft/mixin/gametest/GameTestServerMixin.java b/projects/common/src/testMod/java/dan200/computercraft/mixin/gametest/GameTestServerMixin.java new file mode 100644 index 0000000000..7efa7e9600 --- /dev/null +++ b/projects/common/src/testMod/java/dan200/computercraft/mixin/gametest/GameTestServerMixin.java @@ -0,0 +1,40 @@ +// SPDX-FileCopyrightText: 2024 The CC: Tweaked Developers +// +// SPDX-License-Identifier: MPL-2.0 + +package dan200.computercraft.mixin.gametest; + +import com.mojang.datafixers.DataFixer; +import net.minecraft.gametest.framework.GameTestServer; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.Services; +import net.minecraft.server.WorldStem; +import net.minecraft.server.level.progress.ChunkProgressListenerFactory; +import net.minecraft.server.packs.repository.PackRepository; +import net.minecraft.world.level.storage.LevelStorageSource; +import org.spongepowered.asm.mixin.Mixin; + +import java.net.Proxy; + +@Mixin(GameTestServer.class) +abstract class GameTestServerMixin extends MinecraftServer implements MinecraftServerAccessor { + GameTestServerMixin(Thread serverThread, LevelStorageSource.LevelStorageAccess storageSource, PackRepository packRepository, WorldStem worldStem, Proxy proxy, DataFixer fixerUpper, Services services, ChunkProgressListenerFactory progressListenerFactory) { + super(serverThread, storageSource, packRepository, worldStem, proxy, fixerUpper, services, progressListenerFactory); + } + + /** + * {@link GameTestServer} overrides {@code waitUntilNextTick} to tick as quickly as possible. This does not play + * well with computers, so we add back {@link MinecraftServer}'s implementation. + */ + @Override + public void waitUntilNextTick() { + runAllTasks(); + computercraft$setWaitingForNextTick(true); + + try { + this.managedBlock(() -> !computercraft$haveTime()); + } finally { + computercraft$setWaitingForNextTick(false); + } + } +} diff --git a/projects/common/src/testMod/java/dan200/computercraft/mixin/gametest/MinecraftServerAccessor.java b/projects/common/src/testMod/java/dan200/computercraft/mixin/gametest/MinecraftServerAccessor.java new file mode 100644 index 0000000000..19aac4d3d4 --- /dev/null +++ b/projects/common/src/testMod/java/dan200/computercraft/mixin/gametest/MinecraftServerAccessor.java @@ -0,0 +1,19 @@ +// SPDX-FileCopyrightText: 2024 The CC: Tweaked Developers +// +// SPDX-License-Identifier: MPL-2.0 + +package dan200.computercraft.mixin.gametest; + +import net.minecraft.server.MinecraftServer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(MinecraftServer.class) +public interface MinecraftServerAccessor { + @Accessor("waitingForNextTick") + void computercraft$setWaitingForNextTick(boolean value); + + @Invoker("haveTime") + boolean computercraft$haveTime(); +} diff --git a/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Computer_Test.kt b/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Computer_Test.kt index 7a21696de0..fcf4968625 100644 --- a/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Computer_Test.kt +++ b/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Computer_Test.kt @@ -37,8 +37,8 @@ class Computer_Test { */ @GameTest fun No_through_signal(context: GameTestHelper) = context.sequence { - val lamp = BlockPos(2, 2, 4) - val lever = BlockPos(2, 2, 0) + val lamp = BlockPos(2, 1, 4) + val lever = BlockPos(2, 1, 0) thenExecute { context.assertBlockHas(lamp, RedstoneLampBlock.LIT, false, "Lamp should not be lit") context.modifyBlock(lever) { x -> x.setValue(LeverBlock.POWERED, true) } @@ -52,8 +52,8 @@ class Computer_Test { */ @GameTest fun No_through_signal_reverse(context: GameTestHelper) = context.sequence { - val lamp = BlockPos(2, 2, 4) - val lever = BlockPos(2, 2, 0) + val lamp = BlockPos(2, 1, 4) + val lever = BlockPos(2, 1, 0) thenExecute { context.assertBlockHas(lamp, RedstoneLampBlock.LIT, false, "Lamp should not be lit") context.modifyBlock(lever) { x -> x.setValue(LeverBlock.POWERED, true) } @@ -67,12 +67,12 @@ class Computer_Test { */ @GameTest fun Set_and_destroy(context: GameTestHelper) = context.sequence { - val lamp = BlockPos(2, 2, 3) + val lamp = BlockPos(2, 1, 3) thenOnComputer { getApi().setOutput(ComputerSide.BACK, true) } thenIdle(3) thenExecute { context.assertBlockHas(lamp, RedstoneLampBlock.LIT, true, "Lamp should be lit") } - thenExecute { context.setBlock(BlockPos(2, 2, 2), Blocks.AIR) } + thenExecute { context.setBlock(BlockPos(2, 1, 2), Blocks.AIR) } thenIdle(4) thenExecute { context.assertBlockHas(lamp, RedstoneLampBlock.LIT, false, "Lamp should not be lit") } } @@ -101,8 +101,8 @@ class Computer_Test { @GameTest fun Computer_peripheral(context: GameTestHelper) = context.sequence { thenExecute { - context.assertPeripheral(BlockPos(3, 2, 2), type = "computer") - context.assertPeripheral(BlockPos(1, 2, 2), type = "turtle") + context.assertPeripheral(BlockPos(3, 1, 2), type = "computer") + context.assertPeripheral(BlockPos(1, 1, 2), type = "turtle") } } @@ -112,7 +112,7 @@ class Computer_Test { @GameTest fun Chest_resizes_on_change(context: GameTestHelper) = context.sequence { thenOnComputer { callPeripheral("right", "size").assertArrayEquals(27) } - thenExecute { context.placeItemAt(ItemStack(Items.CHEST), BlockPos(2, 2, 2), Direction.WEST) } + thenExecute { context.placeItemAt(ItemStack(Items.CHEST), BlockPos(2, 1, 2), Direction.WEST) } thenIdle(1) thenOnComputer { callPeripheral("right", "size").assertArrayEquals(54) } } @@ -123,7 +123,7 @@ class Computer_Test { @GameTest fun Drops_on_explosion(context: GameTestHelper) = context.sequence { thenExecute { - val explosionPos = Vec3.atCenterOf(context.absolutePos(BlockPos(2, 2, 2))) + val explosionPos = Vec3.atCenterOf(context.absolutePos(BlockPos(2, 1, 2))) context.level.explode(null, explosionPos.x, explosionPos.y, explosionPos.z, 2.0f, Level.ExplosionInteraction.TNT) context.assertItemEntityCountIs(ModRegistry.Items.COMPUTER_NORMAL.get(), 1) @@ -153,8 +153,8 @@ class Computer_Test { } // Teleport the player to the computer and then open it. thenExecute { - context.positionAt(BlockPos(2, 2, 1)) - context.useBlock(BlockPos(2, 2, 2), context.level.randomPlayer!!) + context.positionAt(BlockPos(2, 1, 1)) + context.useBlock(BlockPos(2, 1, 2), context.level.randomPlayer!!) } // Assert the terminal is synced to the client. thenIdle(2) diff --git a/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Disk_Drive_Test.kt b/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Disk_Drive_Test.kt index 4dfad1ac15..60e6ecbd23 100644 --- a/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Disk_Drive_Test.kt +++ b/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Disk_Drive_Test.kt @@ -60,7 +60,7 @@ class Disk_Drive_Test { @GameTest fun Ejects_disk(helper: GameTestHelper) = helper.sequence { - val stackAt = BlockPos(2, 2, 2) + val stackAt = BlockPos(2, 1, 2) thenOnComputer { callPeripheral("right", "ejectDisk") } thenWaitUntil { helper.assertItemEntityPresent(Items.MUSIC_DISC_13, stackAt, 0.0) } } @@ -70,7 +70,7 @@ class Disk_Drive_Test { */ @GameTest fun Queues_event(helper: GameTestHelper) = helper.sequence { - val pos = BlockPos(1, 2, 2) + val pos = BlockPos(1, 1, 2) var started = false var disk = false @@ -104,7 +104,7 @@ class Disk_Drive_Test { fun Adds_removes_mount(helper: GameTestHelper) = helper.sequence { thenOnComputer { } // Wait for the computer to start up thenExecute { - helper.setContainerItem(BlockPos(1, 2, 2), 0, ItemStack(ModRegistry.Items.DISK.get())) + helper.setContainerItem(BlockPos(1, 1, 2), 0, ItemStack(ModRegistry.Items.DISK.get())) } thenOnComputer { getApi().getDrive("disk").assertArrayEquals("right") @@ -119,7 +119,7 @@ class Disk_Drive_Test { */ @GameTest fun Creates_disk_id(helper: GameTestHelper) = helper.sequence { - val drivePos = BlockPos(2, 2, 2) + val drivePos = BlockPos(2, 1, 2) thenWaitUntil { val drive = helper.getBlockEntity(drivePos, ModRegistry.BlockEntities.DISK_DRIVE.get()) if (!drive.getItem(0).has(ModRegistry.DataComponents.DISK_ID.get())) { @@ -133,8 +133,8 @@ class Disk_Drive_Test { */ @GameTest fun Comparator(helper: GameTestHelper) = helper.sequence { - val drivePos = BlockPos(2, 2, 2) - val dustPos = BlockPos(2, 2, 4) + val drivePos = BlockPos(2, 1, 2) + val dustPos = BlockPos(2, 1, 4) // Adding items should provide power thenExecute { @@ -160,7 +160,7 @@ class Disk_Drive_Test { */ @GameTest fun Contents_updates_state(helper: GameTestHelper) = helper.sequence { - val pos = BlockPos(2, 2, 2) + val pos = BlockPos(2, 1, 2) thenExecute { val drive = helper.getBlockEntity(pos, ModRegistry.BlockEntities.DISK_DRIVE.get()) @@ -185,7 +185,7 @@ class Disk_Drive_Test { @GameTest fun Drops_contents(helper: GameTestHelper) = helper.sequence { thenExecute { - helper.level.destroyBlock(helper.absolutePos(BlockPos(2, 2, 2)), true) + helper.level.destroyBlock(helper.absolutePos(BlockPos(2, 1, 2)), true) helper.assertExactlyItems( DataComponentUtil.createStack(ModRegistry.Items.DISK_DRIVE.get(), DataComponents.CUSTOM_NAME, Component.literal("My Disk Drive")), ItemStack(ModRegistry.Items.TREASURE_DISK.get()), @@ -201,7 +201,7 @@ class Disk_Drive_Test { fun Data_fixers(helper: GameTestHelper) = helper.sequence { thenExecute { helper.assertContainerExactly( - BlockPos(1, 2, 2), + BlockPos(1, 1, 2), listOf( ItemStack(ModRegistry.Items.DISK.get()).also { it.applyComponents( @@ -215,7 +215,7 @@ class Disk_Drive_Test { ) helper.assertContainerExactly( - BlockPos(3, 2, 2), + BlockPos(3, 1, 2), listOf( ItemStack(ModRegistry.Items.TREASURE_DISK.get()).also { it.applyComponents( diff --git a/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Inventory_Test.kt b/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Inventory_Test.kt index 6fc9cad2fa..1401db6152 100644 --- a/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Inventory_Test.kt +++ b/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Inventory_Test.kt @@ -40,8 +40,8 @@ class Inventory_Test { ).await().assertArrayEquals(0, message = "Does not move items") } thenExecute { - helper.assertContainerExactly(BlockPos(1, 2, 2), listOf()) - helper.assertContainerExactly(BlockPos(3, 2, 2), listOf(ItemStack(Items.SHULKER_BOX))) + helper.assertContainerExactly(BlockPos(1, 1, 2), listOf()) + helper.assertContainerExactly(BlockPos(3, 1, 2), listOf(ItemStack(Items.SHULKER_BOX))) } } @@ -66,8 +66,8 @@ class Inventory_Test { ).await().assertArrayEquals(0, message = "Does not move items") } thenExecute { - helper.assertContainerExactly(BlockPos(1, 2, 2), listOf(ItemStack.EMPTY, ItemStack.EMPTY, ItemStack(Items.IRON_INGOT))) - helper.assertContainerExactly(BlockPos(3, 2, 2), NonNullList.withSize(27, ItemStack(Items.POLISHED_ANDESITE))) + helper.assertContainerExactly(BlockPos(1, 1, 2), listOf(ItemStack.EMPTY, ItemStack.EMPTY, ItemStack(Items.IRON_INGOT))) + helper.assertContainerExactly(BlockPos(3, 1, 2), NonNullList.withSize(27, ItemStack(Items.POLISHED_ANDESITE))) } } diff --git a/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Loot_Test.kt b/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Loot_Test.kt index 0d83941898..9c68f24667 100644 --- a/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Loot_Test.kt +++ b/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Loot_Test.kt @@ -21,7 +21,7 @@ class Loot_Test { @GameTest(template = Structures.DEFAULT, required = false) // FIXME: We may need to inject this as a datapack instead fun Chest_contains_disk(context: GameTestHelper) = context.sequence { thenExecute { - val pos = BlockPos(2, 2, 2) + val pos = BlockPos(2, 1, 2) context.setBlock(pos, Blocks.CHEST) val chest = context.getBlockEntity(pos) as ChestBlockEntity diff --git a/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Modem_Test.kt b/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Modem_Test.kt index 01170422f0..be645d86e8 100644 --- a/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Modem_Test.kt +++ b/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Modem_Test.kt @@ -35,7 +35,7 @@ class Modem_Test { @GameTest fun Gains_peripherals(helper: GameTestHelper) = helper.sequence { - val position = BlockPos(2, 2, 2) + val position = BlockPos(2, 1, 2) thenOnComputer { assertEquals(listOf("back"), getPeripheralNames(), "Starts with peripherals") } @@ -84,8 +84,8 @@ class Modem_Test { @GameTest(setupTicks = 1) fun Full_modems_form_networks(helper: GameTestHelper) = helper.sequence { thenExecute { - val modem1 = helper.getBlockEntity(BlockPos(1, 2, 1), ModRegistry.BlockEntities.WIRED_MODEM_FULL.get()) - val modem2 = helper.getBlockEntity(BlockPos(3, 2, 1), ModRegistry.BlockEntities.WIRED_MODEM_FULL.get()) + val modem1 = helper.getBlockEntity(BlockPos(1, 1, 1), ModRegistry.BlockEntities.WIRED_MODEM_FULL.get()) + val modem2 = helper.getBlockEntity(BlockPos(3, 1, 1), ModRegistry.BlockEntities.WIRED_MODEM_FULL.get()) assertEquals((modem1.element.node as WiredNodeImpl).network, (modem2.element.node as WiredNodeImpl).network, "On the same network") } } @@ -101,7 +101,7 @@ class Modem_Test { // However, if we connect the network, the other modem does. thenExecute { helper.setBlock( - BlockPos(1, 2, 3), + BlockPos(1, 1, 3), ModRegistry.Blocks.CABLE.get().defaultBlockState().setValue(CableBlock.CABLE, true), ) } @@ -120,7 +120,7 @@ class Modem_Test { // However, if we connect the network, the other modem does. thenExecute { helper.setBlock( - BlockPos(1, 2, 3), + BlockPos(1, 1, 3), ModRegistry.Blocks.CABLE.get().defaultBlockState().setValue(CableBlock.CABLE, true), ) } @@ -134,9 +134,9 @@ class Modem_Test { @GameTest fun Modem_drops_when_neighbour_removed(helper: GameTestHelper) = helper.sequence { thenExecute { - helper.setBlock(BlockPos(2, 3, 2), Blocks.AIR) - helper.assertItemEntityPresent(ModRegistry.Items.WIRED_MODEM.get(), BlockPos(2, 2, 2), 0.0) - helper.assertBlockPresent(Blocks.AIR, BlockPos(2, 2, 2)) + helper.setBlock(BlockPos(2, 2, 2), Blocks.AIR) + helper.assertItemEntityPresent(ModRegistry.Items.WIRED_MODEM.get(), BlockPos(2, 1, 2), 0.0) + helper.assertBlockPresent(Blocks.AIR, BlockPos(2, 1, 2)) } } @@ -146,9 +146,9 @@ class Modem_Test { @GameTest fun Modem_keeps_cable_when_neighbour_removed(helper: GameTestHelper) = helper.sequence { thenExecute { - helper.setBlock(BlockPos(2, 3, 2), Blocks.AIR) - helper.assertItemEntityPresent(ModRegistry.Items.WIRED_MODEM.get(), BlockPos(2, 2, 2), 0.0) - helper.assertBlockIs(BlockPos(2, 2, 2)) { + helper.setBlock(BlockPos(2, 2, 2), Blocks.AIR) + helper.assertItemEntityPresent(ModRegistry.Items.WIRED_MODEM.get(), BlockPos(2, 1, 2), 0.0) + helper.assertBlockIs(BlockPos(2, 1, 2)) { it.block == ModRegistry.Blocks.CABLE.get() && it.getValue(CableBlock.MODEM) == CableModemVariant.None && it.getValue(CableBlock.CABLE) } } @@ -162,7 +162,7 @@ class Modem_Test { thenOnComputer { callRemotePeripheral("minecraft:chest_0", "size").assertArrayEquals(27) } - thenExecute { context.placeItemAt(ItemStack(Items.CHEST), BlockPos(2, 2, 2), Direction.WEST) } + thenExecute { context.placeItemAt(ItemStack(Items.CHEST), BlockPos(2, 1, 2), Direction.WEST) } thenIdle(1) thenOnComputer { callRemotePeripheral("minecraft:chest_0", "size").assertArrayEquals(54) diff --git a/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Monitor_Test.kt b/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Monitor_Test.kt index afbf8d4003..0d00484b81 100644 --- a/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Monitor_Test.kt +++ b/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Monitor_Test.kt @@ -6,10 +6,8 @@ package dan200.computercraft.gametest import dan200.computercraft.gametest.api.* import dan200.computercraft.shared.ModRegistry -import dan200.computercraft.shared.config.Config import dan200.computercraft.shared.peripheral.monitor.MonitorBlock import dan200.computercraft.shared.peripheral.monitor.MonitorEdgeState -import dan200.computercraft.shared.peripheral.monitor.MonitorRenderer import net.minecraft.commands.arguments.blocks.BlockInput import net.minecraft.core.BlockPos import net.minecraft.gametest.framework.GameTest @@ -17,15 +15,15 @@ import net.minecraft.gametest.framework.GameTestGenerator import net.minecraft.gametest.framework.GameTestHelper import net.minecraft.gametest.framework.TestFunction import net.minecraft.nbt.CompoundTag -import net.minecraft.world.entity.EntityType import net.minecraft.world.item.ItemStack +import net.minecraft.world.level.GameType import net.minecraft.world.level.block.Blocks import org.junit.jupiter.api.Assertions.* class Monitor_Test { @GameTest fun Ensures_valid_on_place(context: GameTestHelper) = context.sequence { - val pos = BlockPos(2, 2, 2) + val pos = BlockPos(2, 1, 2) thenExecute { val tag = CompoundTag() @@ -57,9 +55,9 @@ class Monitor_Test { @GameTest fun Contract_on_destroy(helper: GameTestHelper) = helper.sequence { thenExecute { - helper.setBlock(BlockPos(2, 2, 2), Blocks.AIR.defaultBlockState()) - helper.assertBlockHas(BlockPos(1, 2, 2), MonitorBlock.STATE, MonitorEdgeState.NONE) - helper.assertBlockHas(BlockPos(3, 2, 2), MonitorBlock.STATE, MonitorEdgeState.NONE) + helper.setBlock(BlockPos(2, 1, 2), Blocks.AIR.defaultBlockState()) + helper.assertBlockHas(BlockPos(1, 1, 2), MonitorBlock.STATE, MonitorEdgeState.NONE) + helper.assertBlockHas(BlockPos(3, 1, 2), MonitorBlock.STATE, MonitorEdgeState.NONE) } } @@ -69,7 +67,7 @@ class Monitor_Test { @GameTest fun Creates_terminal(helper: GameTestHelper) = helper.sequence { fun monitorAt(x: Int) = - helper.getBlockEntity(BlockPos(x, 2, 2), ModRegistry.BlockEntities.MONITOR_ADVANCED.get()) + helper.getBlockEntity(BlockPos(x, 1, 2), ModRegistry.BlockEntities.MONITOR_ADVANCED.get()) thenExecute { for (i in 1..3) { @@ -80,20 +78,20 @@ class Monitor_Test { assertNotNull(monitorAt(1).cachedServerMonitor?.terminal, "Creating a peripheral creates a terminal") // Then remove the middle monitor and check it splits into two. - helper.setBlock(BlockPos(2, 2, 2), Blocks.AIR.defaultBlockState()) + helper.setBlock(BlockPos(2, 1, 2), Blocks.AIR.defaultBlockState()) assertNotNull(monitorAt(3).cachedServerMonitor, "Origin retains its monitor") assertNull(monitorAt(3).cachedServerMonitor!!.terminal, "Origin deletes the terminal") assertNotEquals(monitorAt(1).cachedServerMonitor, monitorAt(3).cachedServerMonitor, "Monitors are different") // Then set the monitor, check it rejoins and recreates the terminal. - val pos = BlockPos(2, 2, 2) + val pos = BlockPos(2, 1, 2) helper.setBlock(pos, ModRegistry.Blocks.MONITOR_ADVANCED.get()) ModRegistry.Blocks.MONITOR_ADVANCED.get().setPlacedBy( helper.level, helper.absolutePos(pos), helper.getBlockState(pos), - EntityType.COW.create(helper.level), + helper.makeMockPlayer(GameType.SURVIVAL), ItemStack.EMPTY, ) monitorAt(2).peripheral() @@ -109,7 +107,7 @@ class Monitor_Test { fun Render_monitor_tests(): List { val tests = mutableListOf() - fun addTest(label: String, renderer: MonitorRenderer, time: Long = Times.NOON, tag: String = TestTags.CLIENT) { + fun addTest(label: String, time: Long = Times.NOON, tag: String = TestTags.CLIENT) { if (!TestTags.isEnabled(tag)) return val className = this::class.java.simpleName.lowercase() @@ -123,32 +121,29 @@ class Monitor_Test { Timeouts.DEFAULT, 0, true, - ) { renderMonitor(it, renderer, time) }, + ) { renderMonitor(it, time) }, ) } - addTest("tbo_noon", MonitorRenderer.TBO, Times.NOON) - addTest("tbo_midnight", MonitorRenderer.TBO, Times.MIDNIGHT) - addTest("vbo_noon", MonitorRenderer.VBO, Times.NOON) - addTest("vbo_midnight", MonitorRenderer.VBO, Times.MIDNIGHT) + addTest("noon", Times.NOON) + addTest("midnight", Times.MIDNIGHT) - addTest("sodium_tbo", MonitorRenderer.TBO, tag = "sodium") - addTest("sodium_vbo", MonitorRenderer.VBO, tag = "sodium") + addTest("sodium_tbo", tag = "sodium") + addTest("sodium_vbo", tag = "sodium") - addTest("iris_noon", MonitorRenderer.BEST, Times.NOON, tag = "iris") - addTest("iris_midnight", MonitorRenderer.BEST, Times.MIDNIGHT, tag = "iris") + addTest("iris_noon", Times.NOON, tag = "iris") + addTest("iris_midnight", Times.MIDNIGHT, tag = "iris") return tests } - private fun renderMonitor(helper: GameTestHelper, renderer: MonitorRenderer, time: Long) = helper.sequence { + private fun renderMonitor(helper: GameTestHelper, time: Long) = helper.sequence { thenExecute { - Config.monitorRenderer = renderer helper.level.dayTime = time helper.positionAtArmorStand() // Get the monitor and peripheral. This forces us to create a server monitor at this location. - val monitor = helper.getBlockEntity(BlockPos(2, 2, 3), ModRegistry.BlockEntities.MONITOR_ADVANCED.get()) + val monitor = helper.getBlockEntity(BlockPos(2, 1, 3), ModRegistry.BlockEntities.MONITOR_ADVANCED.get()) monitor.peripheral() val terminal = monitor.cachedServerMonitor!!.terminal!! diff --git a/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Pocket_Computer_Test.kt b/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Pocket_Computer_Test.kt index f396a8599a..e6297f9484 100644 --- a/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Pocket_Computer_Test.kt +++ b/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Pocket_Computer_Test.kt @@ -40,7 +40,7 @@ class Pocket_Computer_Test { // Give the player a pocket computer. thenExecute { - context.positionAt(BlockPos(2, 2, 2)) + context.positionAt(BlockPos(2, 1, 2)) context.givePocketComputer(unique) } // Write some text to the computer. @@ -82,7 +82,7 @@ class Pocket_Computer_Test { // Give the player a pocket computer. thenExecute { - context.positionAt(BlockPos(2, 2, 2), xRot = 90.0f) + context.positionAt(BlockPos(2, 1, 2), xRot = 90.0f) context.givePocketComputer(unique) } thenOnComputer(unique) { @@ -119,12 +119,12 @@ class Pocket_Computer_Test { @GameTest fun Data_fixers(helper: GameTestHelper) = helper.sequence { thenExecute { - val upgrade = helper.level.registryAccess().registryOrThrow(IPocketUpgrade.REGISTRY) - .getHolder(ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "wireless_modem_normal")) + val upgrade = helper.level.registryAccess().lookupOrThrow(IPocketUpgrade.REGISTRY) + .get(ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "wireless_modem_normal")) .orElseThrow() helper.assertContainerExactly( - BlockPos(2, 2, 2), + BlockPos(2, 1, 2), listOf( ItemStack(ModRegistry.Items.POCKET_COMPUTER_ADVANCED.get()).also { DataComponentUtil.setCustomName(it, "Test") diff --git a/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Printer_Test.kt b/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Printer_Test.kt index 4034bba06f..8e6789cf65 100644 --- a/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Printer_Test.kt +++ b/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Printer_Test.kt @@ -28,8 +28,8 @@ class Printer_Test { */ @GameTest fun Comparator(helper: GameTestHelper) = helper.sequence { - val printerPos = BlockPos(2, 2, 2) - val dustPos = BlockPos(2, 2, 4) + val printerPos = BlockPos(2, 1, 2) + val dustPos = BlockPos(2, 1, 4) // Adding items should provide power thenExecute { @@ -56,7 +56,7 @@ class Printer_Test { */ @GameTest fun Contents_updates_state(helper: GameTestHelper) = helper.sequence { - val pos = BlockPos(2, 2, 2) + val pos = BlockPos(2, 1, 2) thenExecute { val drive = helper.getBlockEntity(pos, ModRegistry.BlockEntities.PRINTER.get()) @@ -89,7 +89,7 @@ class Printer_Test { @GameTest fun Drops_contents(helper: GameTestHelper) = helper.sequence { thenExecute { - helper.level.destroyBlock(helper.absolutePos(BlockPos(2, 2, 2)), true) + helper.level.destroyBlock(helper.absolutePos(BlockPos(2, 1, 2)), true) helper.assertExactlyItems( DataComponentUtil.createStack(ModRegistry.Items.PRINTER.get(), DataComponents.CUSTOM_NAME, Component.literal("My Printer")), ItemStack(Items.PAPER), @@ -105,7 +105,7 @@ class Printer_Test { @GameTest fun Data_fixers(helper: GameTestHelper) = helper.sequence { thenExecute { - val container = helper.getBlockEntity(BlockPos(2, 2, 2), ModRegistry.BlockEntities.PRINTER.get()) + val container = helper.getBlockEntity(BlockPos(2, 1, 2), ModRegistry.BlockEntities.PRINTER.get()) val contents = container.getItem(1) assertEquals(ModRegistry.Items.PRINTED_PAGE.get(), contents.item) diff --git a/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Turtle_Test.kt b/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Turtle_Test.kt index 191152e748..e47d6214c2 100644 --- a/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Turtle_Test.kt +++ b/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Turtle_Test.kt @@ -88,7 +88,7 @@ class Turtle_Test { turtle.placeDown(ObjectArguments()).await() .assertArrayEquals(true, message = "Placed lava") } - thenExecute { helper.assertBlockPresent(Blocks.LAVA, BlockPos(2, 2, 2)) } + thenExecute { helper.assertBlockPresent(Blocks.LAVA, BlockPos(2, 1, 2)) } } /** @@ -103,7 +103,7 @@ class Turtle_Test { .assertArrayEquals(true, message = "Placed sign") } thenExecute { - val sign = helper.getBlockEntity(BlockPos(2, 2, 1), BlockEntityType.SIGN) + val sign = helper.getBlockEntity(BlockPos(2, 1, 1), BlockEntityType.SIGN) val lines = listOf("", "Test", "message", "") for ((i, line) in lines.withIndex()) { assertEquals(line, sign.frontText.getMessage(i, false).string, "Line $i") @@ -126,8 +126,8 @@ class Turtle_Test { .assertArrayEquals(true, message = "Placed water") } thenExecute { - helper.assertBlockPresent(Blocks.AIR, BlockPos(2, 2, 2)) - helper.assertBlockHas(BlockPos(2, 5, 2), BlockStateProperties.WATERLOGGED, true) + helper.assertBlockPresent(Blocks.AIR, BlockPos(2, 1, 2)) + helper.assertBlockHas(BlockPos(2, 4, 2), BlockStateProperties.WATERLOGGED, true) } } @@ -143,7 +143,7 @@ class Turtle_Test { .assertArrayEquals(true, message = "Placed oak fence") } thenExecute { - helper.assertBlockIs(BlockPos(2, 2, 2)) { it.block == Blocks.OAK_FENCE && it.getValue(FenceBlock.WATERLOGGED) } + helper.assertBlockIs(BlockPos(2, 1, 2)) { it.block == Blocks.OAK_FENCE && it.getValue(FenceBlock.WATERLOGGED) } } } @@ -160,7 +160,7 @@ class Turtle_Test { assertEquals("minecraft:lava_bucket", getTurtleItemDetail()["name"]) } - thenExecute { helper.assertBlockPresent(Blocks.AIR, BlockPos(2, 2, 2)) } + thenExecute { helper.assertBlockPresent(Blocks.AIR, BlockPos(2, 1, 2)) } } /** @@ -171,7 +171,7 @@ class Turtle_Test { @GameTest fun Hoe_dirt(helper: GameTestHelper) = helper.sequence { thenOnComputer { turtle.dig(Optional.empty()).await().assertArrayEquals(true, message = "Dug with hoe") } - thenExecute { helper.assertBlockPresent(Blocks.FARMLAND, BlockPos(1, 2, 1)) } + thenExecute { helper.assertBlockPresent(Blocks.FARMLAND, BlockPos(1, 1, 1)) } } /** @@ -182,7 +182,7 @@ class Turtle_Test { @GameTest fun Hoe_dirt_below(helper: GameTestHelper) = helper.sequence { thenOnComputer { turtle.digDown(Optional.empty()).await().assertArrayEquals(true, message = "Dug with hoe") } - thenExecute { helper.assertBlockPresent(Blocks.FARMLAND, BlockPos(1, 1, 1)) } + thenExecute { helper.assertBlockPresent(Blocks.FARMLAND, BlockPos(1, 0, 1)) } } /** @@ -194,7 +194,7 @@ class Turtle_Test { turtle.dig(Optional.empty()).await() .assertArrayEquals(false, "Nothing to dig here", message = "Dug with hoe") } - thenExecute { helper.assertBlockPresent(Blocks.DIRT, BlockPos(1, 2, 2)) } + thenExecute { helper.assertBlockPresent(Blocks.DIRT, BlockPos(1, 1, 2)) } } /** @@ -204,18 +204,18 @@ class Turtle_Test { fun Break_cable(helper: GameTestHelper) = helper.sequence { thenOnComputer { turtle.dig(Optional.empty()).await() } thenExecute { - helper.assertBlockIs(BlockPos(2, 2, 3)) { + helper.assertBlockIs(BlockPos(2, 1, 3)) { it.block == ModRegistry.Blocks.CABLE.get() && !it.getValue(CableBlock.CABLE) && it.getValue(CableBlock.MODEM) == CableModemVariant.DownOff } - helper.assertContainerExactly(BlockPos(2, 2, 2), listOf(ItemStack(ModRegistry.Items.CABLE.get()))) + helper.assertContainerExactly(BlockPos(2, 1, 2), listOf(ItemStack(ModRegistry.Items.CABLE.get()))) } thenOnComputer { turtle.dig(Optional.empty()).await().assertArrayEquals(true) } thenExecute { - helper.assertBlockPresent(Blocks.AIR, BlockPos(2, 2, 3)) + helper.assertBlockPresent(Blocks.AIR, BlockPos(2, 1, 3)) helper.assertContainerExactly( - BlockPos(2, 2, 2), + BlockPos(2, 1, 2), listOf( ItemStack(ModRegistry.Items.CABLE.get()), ItemStack(ModRegistry.Items.WIRED_MODEM.get()), @@ -231,14 +231,14 @@ class Turtle_Test { fun Dig_consume_durability(helper: GameTestHelper) = helper.sequence { thenOnComputer { turtle.dig(Optional.empty()).await() } thenExecute { - helper.assertBlockPresent(Blocks.AIR, BlockPos(2, 2, 3)) - helper.assertContainerExactly(BlockPos(2, 2, 2), listOf(ItemStack(Items.COBBLESTONE))) + helper.assertBlockPresent(Blocks.AIR, BlockPos(2, 1, 3)) + helper.assertContainerExactly(BlockPos(2, 1, 2), listOf(ItemStack(Items.COBBLESTONE))) - val turtle = helper.getBlockEntity(BlockPos(2, 2, 2), ModRegistry.BlockEntities.TURTLE_NORMAL.get()).access + val turtle = helper.getBlockEntity(BlockPos(2, 1, 2), ModRegistry.BlockEntities.TURTLE_NORMAL.get()).access val upgrade = turtle.getUpgrade(TurtleSide.LEFT) assertEquals( - helper.level.registryAccess().registryOrThrow(ITurtleUpgrade.REGISTRY) - .get(ResourceLocation.fromNamespaceAndPath("cctest", "wooden_pickaxe")), + helper.level.registryAccess().lookupOrThrow(ITurtleUpgrade.REGISTRY) + .getValue(ResourceLocation.fromNamespaceAndPath("cctest", "wooden_pickaxe")), upgrade, "Upgrade is a wooden pickaxe", ) @@ -256,18 +256,18 @@ class Turtle_Test { fun Dig_breaks_tool(helper: GameTestHelper) = helper.sequence { thenOnComputer { turtle.dig(Optional.empty()).await() } thenExecute { - helper.assertBlockPresent(Blocks.AIR, BlockPos(2, 2, 3)) - helper.assertContainerExactly(BlockPos(2, 2, 2), listOf(ItemStack(Items.COBBLESTONE))) + helper.assertBlockPresent(Blocks.AIR, BlockPos(2, 1, 3)) + helper.assertContainerExactly(BlockPos(2, 1, 2), listOf(ItemStack(Items.COBBLESTONE))) - val turtle = helper.getBlockEntity(BlockPos(2, 2, 2), ModRegistry.BlockEntities.TURTLE_NORMAL.get()).access + val turtle = helper.getBlockEntity(BlockPos(2, 1, 2), ModRegistry.BlockEntities.TURTLE_NORMAL.get()).access val upgrade = turtle.getUpgrade(TurtleSide.LEFT) assertEquals(null, upgrade, "Upgrade broke") helper.assertUpgradeItem( ItemStack(Items.WOODEN_PICKAXE), UpgradeData.ofDefault( - helper.level.registryAccess().registryOrThrow(ITurtleUpgrade.REGISTRY) - .getHolder(ResourceLocation.fromNamespaceAndPath("cctest", "wooden_pickaxe")).orElseThrow(), + helper.level.registryAccess().lookupOrThrow(ITurtleUpgrade.REGISTRY) + .get(ResourceLocation.fromNamespaceAndPath("cctest", "wooden_pickaxe")).orElseThrow(), ), ) } @@ -281,14 +281,14 @@ class Turtle_Test { fun Dig_enchanted_consume_durability(helper: GameTestHelper) = helper.sequence { thenOnComputer { turtle.dig(Optional.empty()).await() } thenExecute { - helper.assertBlockPresent(Blocks.AIR, BlockPos(2, 2, 3)) - helper.assertContainerExactly(BlockPos(2, 2, 2), listOf(ItemStack(Items.STONE))) + helper.assertBlockPresent(Blocks.AIR, BlockPos(2, 1, 3)) + helper.assertContainerExactly(BlockPos(2, 1, 2), listOf(ItemStack(Items.STONE))) - val turtle = helper.getBlockEntity(BlockPos(2, 2, 2), ModRegistry.BlockEntities.TURTLE_NORMAL.get()).access + val turtle = helper.getBlockEntity(BlockPos(2, 1, 2), ModRegistry.BlockEntities.TURTLE_NORMAL.get()).access val upgrade = turtle.getUpgrade(TurtleSide.LEFT) assertEquals( - helper.level.registryAccess().registryOrThrow(ITurtleUpgrade.REGISTRY) - .get(ResourceLocation.fromNamespaceAndPath("cctest", "netherite_pickaxe")), + helper.level.registryAccess().lookupOrThrow(ITurtleUpgrade.REGISTRY) + .getValue(ResourceLocation.fromNamespaceAndPath("cctest", "netherite_pickaxe")), upgrade, "Upgrade is a netherite pickaxe", ) @@ -296,8 +296,8 @@ class Turtle_Test { val item = ItemStack(Items.NETHERITE_PICKAXE) item.damageValue = 1 item.enchant( - helper.level.registryAccess().registryOrThrow(Registries.ENCHANTMENT) - .getHolderOrThrow(Enchantments.SILK_TOUCH), + helper.level.registryAccess().lookupOrThrow(Registries.ENCHANTMENT) + .getOrThrow(Enchantments.SILK_TOUCH), 1, ) @@ -327,7 +327,7 @@ class Turtle_Test { .assertArrayEquals(true, message = "Block was placed") } thenIdle(1) - thenExecute { helper.assertBlockHas(BlockPos(1, 2, 3), MonitorBlock.STATE, MonitorEdgeState.LR) } + thenExecute { helper.assertBlockHas(BlockPos(1, 1, 3), MonitorBlock.STATE, MonitorEdgeState.LR) } } /** @@ -389,15 +389,15 @@ class Turtle_Test { @GameTest fun Resists_explosions(helper: GameTestHelper) = helper.sequence { thenExecute { - val pos = helper.absolutePos(BlockPos(2, 2, 2)) + val pos = helper.absolutePos(BlockPos(2, 1, 2)) val tnt = PrimedTnt(helper.level, pos.x + 0.5, pos.y + 1.0, pos.z + 0.5, null) tnt.fuse = 1 helper.level.addFreshEntity(tnt) } thenWaitUntil { helper.assertEntityNotPresent(EntityType.TNT) } thenExecute { - helper.assertBlockPresent(ModRegistry.Blocks.TURTLE_ADVANCED.get(), BlockPos(2, 2, 2)) - helper.assertBlockPresent(Blocks.AIR, BlockPos(2, 2, 1)) + helper.assertBlockPresent(ModRegistry.Blocks.TURTLE_ADVANCED.get(), BlockPos(2, 1, 2)) + helper.assertBlockPresent(Blocks.AIR, BlockPos(2, 1, 1)) } } @@ -409,8 +409,8 @@ class Turtle_Test { thenExecute { helper.getEntity(EntityType.CREEPER).ignite() } thenWaitUntil { helper.assertEntityNotPresent(EntityType.CREEPER) } thenExecute { - helper.assertBlockPresent(ModRegistry.Blocks.TURTLE_ADVANCED.get(), BlockPos(2, 2, 2)) - helper.assertBlockPresent(ModRegistry.Blocks.TURTLE_NORMAL.get(), BlockPos(2, 2, 1)) + helper.assertBlockPresent(ModRegistry.Blocks.TURTLE_ADVANCED.get(), BlockPos(2, 1, 2)) + helper.assertBlockPresent(ModRegistry.Blocks.TURTLE_NORMAL.get(), BlockPos(2, 1, 1)) } } @@ -419,8 +419,8 @@ class Turtle_Test { */ @GameTest fun Drop_into_chest(helper: GameTestHelper) = helper.sequence { - val turtlePos = BlockPos(2, 2, 2) - val chest = BlockPos(2, 2, 3) + val turtlePos = BlockPos(2, 1, 2) + val chest = BlockPos(2, 1, 3) thenOnComputer { turtle.drop(Optional.of(32)).await() @@ -445,7 +445,7 @@ class Turtle_Test { .assertArrayEquals(true, message = "Could not drop items") } thenExecute { - helper.assertContainerExactly(BlockPos(2, 2, 2), listOf(ItemStack(Blocks.DIRT, 32))) + helper.assertContainerExactly(BlockPos(2, 1, 2), listOf(ItemStack(Blocks.DIRT, 32))) helper.assertContainerExactly(helper.getEntity(EntityType.CHEST_MINECART), listOf(ItemStack(Blocks.DIRT, 48))) helper.assertEntityNotPresent(EntityType.ITEM) } @@ -456,7 +456,7 @@ class Turtle_Test { */ @GameTest fun Refuel_basic(helper: GameTestHelper) = helper.sequence { - val turtlePos = BlockPos(2, 2, 2) + val turtlePos = BlockPos(2, 1, 2) // Test refueling from slot 1 with no limit. thenOnComputer { @@ -484,7 +484,7 @@ class Turtle_Test { */ @GameTest fun Refuel_fail(helper: GameTestHelper) = helper.sequence { - val turtlePos = BlockPos(2, 2, 2) + val turtlePos = BlockPos(2, 1, 2) thenOnComputer { assertEquals(0, turtle.fuelLevel) @@ -501,7 +501,7 @@ class Turtle_Test { */ @GameTest fun Refuel_container(helper: GameTestHelper) = helper.sequence { - val turtlePos = BlockPos(2, 2, 2) + val turtlePos = BlockPos(2, 1, 2) // Test refueling from slot 1 with no limit. thenOnComputer { @@ -523,9 +523,9 @@ class Turtle_Test { fun Move_preserves_state(helper: GameTestHelper) = helper.sequence { thenOnComputer { turtle.forward().await().assertArrayEquals(true, message = "Turtle moved forward") } thenExecute { - helper.assertContainerExactly(BlockPos(2, 2, 3), listOf(ItemStack(Items.DIRT, 32))) + helper.assertContainerExactly(BlockPos(2, 1, 3), listOf(ItemStack(Items.DIRT, 32))) - val turtle = helper.getBlockEntity(BlockPos(2, 2, 3), ModRegistry.BlockEntities.TURTLE_NORMAL.get()) + val turtle = helper.getBlockEntity(BlockPos(2, 1, 3), ModRegistry.BlockEntities.TURTLE_NORMAL.get()) assertEquals(1, turtle.computerID) assertEquals("turtle_test.move_preserves_state", turtle.label) assertEquals(79, turtle.access.fuelLevel) @@ -540,7 +540,7 @@ class Turtle_Test { @GameTest fun Move_replace(helper: GameTestHelper) = helper.sequence { thenOnComputer { turtle.forward().await().assertArrayEquals(true, message = "Turtle moved forward") } - thenExecute { helper.assertBlockPresent(ModRegistry.Blocks.TURTLE_NORMAL.get(), BlockPos(2, 2, 3)) } + thenExecute { helper.assertBlockPresent(ModRegistry.Blocks.TURTLE_NORMAL.get(), BlockPos(2, 1, 3)) } } /** @@ -551,13 +551,13 @@ class Turtle_Test { thenOnComputer { turtle.forward().await().assertArrayEquals(true, message = "Turtle moved forward") } thenExecute { // Assert we're waterlogged. - helper.assertBlockHas(BlockPos(2, 2, 2), WaterloggableHelpers.WATERLOGGED, true) + helper.assertBlockHas(BlockPos(2, 1, 2), WaterloggableHelpers.WATERLOGGED, true) } thenOnComputer { turtle.forward().await().assertArrayEquals(true, message = "Turtle moved forward") } thenExecute { // Assert we're no longer waterlogged and we've left a source block. - helper.assertBlockIs(BlockPos(2, 2, 2)) { it.block == Blocks.WATER && it.fluidState.isSource } - helper.assertBlockHas(BlockPos(2, 2, 3), WaterloggableHelpers.WATERLOGGED, false) + helper.assertBlockIs(BlockPos(2, 1, 2)) { it.block == Blocks.WATER && it.fluidState.isSource } + helper.assertBlockHas(BlockPos(2, 1, 3), WaterloggableHelpers.WATERLOGGED, false) } } @@ -568,8 +568,8 @@ class Turtle_Test { fun Move_obstruct(helper: GameTestHelper) = helper.sequence { thenOnComputer { turtle.forward().await().assertArrayEquals(false, "Movement obstructed") } thenExecute { - helper.assertBlockPresent(ModRegistry.Blocks.TURTLE_NORMAL.get(), BlockPos(2, 2, 2)) - helper.assertBlockPresent(Blocks.DIRT, BlockPos(2, 2, 3)) + helper.assertBlockPresent(ModRegistry.Blocks.TURTLE_NORMAL.get(), BlockPos(2, 1, 2)) + helper.assertBlockPresent(Blocks.DIRT, BlockPos(2, 1, 3)) } } @@ -578,7 +578,7 @@ class Turtle_Test { */ @GameTest fun Attack_entity(helper: GameTestHelper) = helper.sequence { - val turtlePos = BlockPos(2, 2, 2) + val turtlePos = BlockPos(2, 1, 2) thenOnComputer { turtle.attack(Optional.empty()).await().assertArrayEquals(true, message = "Attacked entity") } @@ -598,7 +598,7 @@ class Turtle_Test { @GameTest fun Attack_entity_destroy(helper: GameTestHelper) = helper.sequence { thenStartComputer { turtle.attack(Optional.empty()) } - thenWaitUntil { helper.assertBlockPresent(Blocks.AIR, BlockPos(2, 2, 2)) } + thenWaitUntil { helper.assertBlockPresent(Blocks.AIR, BlockPos(2, 1, 2)) } } /** @@ -663,12 +663,12 @@ class Turtle_Test { @GameTest fun Data_fixers(helper: GameTestHelper) = helper.sequence { thenExecute { - val overlay = helper.level.registryAccess().registryOrThrow(TurtleOverlay.REGISTRY) - .get(ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "trans_flag"))!! - val upgrade = helper.level.registryAccess().registryOrThrow(ITurtleUpgrade.REGISTRY) - .get(ResourceLocation.withDefaultNamespace("diamond_pickaxe"))!! + val overlay = helper.level.registryAccess().lookupOrThrow(TurtleOverlay.REGISTRY) + .getValue(ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "trans_flag"))!! + val upgrade = helper.level.registryAccess().lookupOrThrow(ITurtleUpgrade.REGISTRY) + .getValue(ResourceLocation.withDefaultNamespace("diamond_pickaxe"))!! - val turtleBe = helper.getBlockEntity(BlockPos(1, 2, 1), ModRegistry.BlockEntities.TURTLE_NORMAL.get()) + val turtleBe = helper.getBlockEntity(BlockPos(1, 1, 1), ModRegistry.BlockEntities.TURTLE_NORMAL.get()) assertEquals(overlay, turtleBe.overlay) assertEquals(upgrade, turtleBe.getUpgrade(TurtleSide.LEFT)) @@ -702,7 +702,7 @@ class Turtle_Test { callPeripheral("left", "craft", 1).assertArrayEquals(true) } thenExecute { - val turtle = helper.getBlockEntity(BlockPos(2, 2, 2), ModRegistry.BlockEntities.TURTLE_NORMAL.get()) + val turtle = helper.getBlockEntity(BlockPos(2, 1, 2), ModRegistry.BlockEntities.TURTLE_NORMAL.get()) assertThat( "Inventory is as expected.", turtle.items, @@ -725,10 +725,10 @@ class Turtle_Test { turtle.equipLeft().await().assertArrayEquals(true) } thenExecute { - val turtle = helper.getBlockEntity(BlockPos(2, 2, 2), ModRegistry.BlockEntities.TURTLE_NORMAL.get()) + val turtle = helper.getBlockEntity(BlockPos(2, 1, 2), ModRegistry.BlockEntities.TURTLE_NORMAL.get()) assertEquals( - helper.level.registryAccess().registryOrThrow(ITurtleUpgrade.REGISTRY) - .get(ResourceLocation.withDefaultNamespace("diamond_pickaxe")), + helper.level.registryAccess().lookupOrThrow(ITurtleUpgrade.REGISTRY) + .getValue(ResourceLocation.withDefaultNamespace("diamond_pickaxe")), turtle.getUpgrade(TurtleSide.LEFT), ) } @@ -742,7 +742,7 @@ class Turtle_Test { @GameTest fun Breaks_exploding_block(context: GameTestHelper) = context.sequence { thenOnComputer { turtle.dig(Optional.empty()) } - thenWaitUntil { context.assertBlockPresent(Blocks.AIR, BlockPos(2, 2, 2)) } + thenWaitUntil { context.assertBlockPresent(Blocks.AIR, BlockPos(2, 1, 2)) } thenExecute { context.assertItemEntityCountIs(ModRegistry.Items.TURTLE_NORMAL.get(), 1) context.assertItemEntityCountIs(Items.BONE_BLOCK, 65) diff --git a/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/api/TestExtensions.kt b/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/api/TestExtensions.kt index 43d046ff90..58e5d967de 100644 --- a/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/api/TestExtensions.kt +++ b/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/api/TestExtensions.kt @@ -264,7 +264,7 @@ fun GameTestHelper.assertExactlyItems(vararg expected: ItemStack, message: Strin fun GameTestHelper.assertItemEntityCountIs(expected: Item, count: Int) { val actualCount = getEntities(EntityType.ITEM).sumOf { if (it.item.`is`(expected)) it.item.count else 0 } if (actualCount != count) { - throw GameTestAssertException("Expected $count ${expected.description.string} items to exist (found $actualCount)") + throw GameTestAssertException("Expected $count ${ItemStack(expected).itemName.string} items to exist (found $actualCount)") } } diff --git a/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/core/ClientTestHooks.kt b/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/core/ClientTestHooks.kt index d410a1b9c1..32fc729dbe 100644 --- a/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/core/ClientTestHooks.kt +++ b/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/core/ClientTestHooks.kt @@ -9,7 +9,6 @@ import dan200.computercraft.gametest.api.isRenderingStable import dan200.computercraft.gametest.api.setupForTest import net.minecraft.client.CloudStatus import net.minecraft.client.Minecraft -import net.minecraft.client.ParticleStatus import net.minecraft.client.gui.screens.AccessibilityOnboardingScreen import net.minecraft.client.gui.screens.Screen import net.minecraft.client.gui.screens.TitleScreen @@ -17,8 +16,10 @@ import net.minecraft.client.tutorial.TutorialSteps import net.minecraft.core.registries.Registries import net.minecraft.gametest.framework.* import net.minecraft.server.MinecraftServer +import net.minecraft.server.level.ParticleStatus import net.minecraft.sounds.SoundSource import net.minecraft.world.Difficulty +import net.minecraft.world.flag.FeatureFlagSet import net.minecraft.world.level.GameRules import net.minecraft.world.level.GameType import net.minecraft.world.level.LevelSettings @@ -84,7 +85,7 @@ object ClientTestHooks { minecraft.createWorldOpenFlows().openWorld(LEVEL_NAME) { minecraft.setScreen(screen) } } else { LOG.info("World does not exist, creating it.") - val rules = GameRules() + val rules = GameRules(FeatureFlagSet.of()) rules.getRule(GameRules.RULE_DOMOBSPAWNING).set(false, null) rules.getRule(GameRules.RULE_DAYLIGHT).set(false, null) rules.getRule(GameRules.RULE_WEATHER_CYCLE).set(false, null) @@ -93,7 +94,10 @@ object ClientTestHooks { LEVEL_NAME, LevelSettings("Test Level", GameType.CREATIVE, false, Difficulty.EASY, true, rules, WorldDataConfiguration.DEFAULT), WorldOptions(WorldOptions.randomSeed(), false, false), - { it.registryOrThrow(Registries.WORLD_PRESET).getOrThrow(WorldPresets.FLAT).createWorldDimensions() }, + { + it.lookupOrThrow(Registries.WORLD_PRESET).getOrThrow(WorldPresets.FLAT).value() + .createWorldDimensions() + }, screen, ) } diff --git a/projects/common/src/testMod/resources/computercraft-gametest.mixins.json b/projects/common/src/testMod/resources/computercraft-gametest.mixins.json index 803991da5c..3f2053cb8c 100644 --- a/projects/common/src/testMod/resources/computercraft-gametest.mixins.json +++ b/projects/common/src/testMod/resources/computercraft-gametest.mixins.json @@ -11,6 +11,8 @@ "GameTestInfoAccessor", "GameTestSequenceAccessor", "GameTestSequenceMixin", + "GameTestServerMixin", + "MinecraftServerAccessor", "StructureTemplateManagerMixin", "TestCommandAccessor" ], diff --git a/projects/fabric/build.gradle.kts b/projects/fabric/build.gradle.kts index 21ce836b3b..0a328504e6 100644 --- a/projects/fabric/build.gradle.kts +++ b/projects/fabric/build.gradle.kts @@ -20,6 +20,14 @@ cct { allProjects.forEach { externalSources(it) } } +sourceSets { + client { + java { + exclude("dan200/computercraft/client/integration/rei") + } + } +} + fun addRemappedConfiguration(name: String) { // There was a regression in Loom 1.1 which means that targetConfigurationName doesn't do anything, and remap // configurations just get added to the main source set (https://github.com/FabricMC/fabric-loom/issues/843). diff --git a/projects/fabric/src/client/java/dan200/computercraft/client/ComputerCraftClient.java b/projects/fabric/src/client/java/dan200/computercraft/client/ComputerCraftClient.java index 224ac9bc5b..2774d27ad0 100644 --- a/projects/fabric/src/client/java/dan200/computercraft/client/ComputerCraftClient.java +++ b/projects/fabric/src/client/java/dan200/computercraft/client/ComputerCraftClient.java @@ -55,7 +55,6 @@ public static void init() { PreparableModelLoadingPlugin.register(CustomModelLoader::prepare, (state, context) -> { ClientRegistry.registerExtraModels(context::addModels, state.getExtraModels()); context.resolveModel().register(ctx -> state.loadModel(ctx.id())); - context.modifyModelAfterBake().register((model, ctx) -> model == null ? null : state.wrapModel(ctx, model)); }); BlockRenderLayerMap.INSTANCE.putBlock(ModRegistry.Blocks.COMPUTER_NORMAL.get(), RenderType.cutout()); diff --git a/projects/fabric/src/client/java/dan200/computercraft/client/model/CustomModelLoader.java b/projects/fabric/src/client/java/dan200/computercraft/client/model/CustomModelLoader.java index 7addcdced5..62dea29d77 100644 --- a/projects/fabric/src/client/java/dan200/computercraft/client/model/CustomModelLoader.java +++ b/projects/fabric/src/client/java/dan200/computercraft/client/model/CustomModelLoader.java @@ -8,11 +8,7 @@ import com.google.gson.JsonParseException; import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.client.model.turtle.UnbakedTurtleModel; -import dan200.computercraft.mixin.client.BlockModelAccessor; -import net.fabricmc.fabric.api.client.model.loading.v1.ModelModifier; import net.fabricmc.fabric.api.client.model.loading.v1.PreparableModelLoadingPlugin; -import net.minecraft.client.renderer.block.model.BlockModel; -import net.minecraft.client.resources.model.BakedModel; import net.minecraft.client.resources.model.UnbakedModel; import net.minecraft.resources.FileToIdConverter; import net.minecraft.resources.ResourceLocation; @@ -36,9 +32,8 @@ *

* This is used from a {@link PreparableModelLoadingPlugin}, which {@linkplain #prepare(ResourceManager, Executor) loads * data from disk} in parallel with other loader plugins, and then hooks into the model loading pipeline - * ({@link #loadModel(ResourceLocation)}, {@link #wrapModel(ModelModifier.AfterBake.Context, BakedModel)}). + * ({@link #loadModel(ResourceLocation)}). * - * @see EmissiveBakedModel * @see UnbakedTurtleModel */ public final class CustomModelLoader { @@ -46,7 +41,6 @@ public final class CustomModelLoader { private static final FileToIdConverter converter = FileToIdConverter.json("models"); private final Map models = new HashMap<>(); - private final Map emissiveModels = new HashMap<>(); private final Collection extraModels; private CustomModelLoader(Collection extraModels) { @@ -80,9 +74,6 @@ private void loadModel(ResourceLocation path, Resource resource) { }; models.put(id, unbaked); } - - var emissive = GsonHelper.getAsString(model, "computercraft:emissive_texture", null); - if (emissive != null) emissiveModels.put(id, emissive); } catch (IllegalArgumentException | IOException | JsonParseException e) { LOG.error("Couldn't parse model file {} from {}", id, path, e); } @@ -101,35 +92,4 @@ public Collection getExtraModels() { public @Nullable UnbakedModel loadModel(ResourceLocation path) { return path.getNamespace().equals(ComputerCraftAPI.MOD_ID) ? models.get(path) : null; } - - /** - * Wrap a baked model. - *

- * This just finds models which specify an emissive texture ({@code computercraft:emissive_texture} in the JSON) and - * wraps them in a {@link EmissiveBakedModel}. - * - * @param ctx The current model loading context. - * @param baked The baked model to wrap. - * @return The wrapped model. - */ - public BakedModel wrapModel(ModelModifier.AfterBake.Context ctx, BakedModel baked) { - var id = ctx.resourceId(); - if (id == null || !id.getNamespace().equals(ComputerCraftAPI.MOD_ID)) return baked; - if (!(ctx.sourceModel() instanceof BlockModel model)) return baked; - - var emissive = getEmissive(id, model); - return emissive == null ? baked : EmissiveBakedModel.wrap(baked, ctx.textureGetter().apply(model.getMaterial(emissive))); - } - - private @Nullable String getEmissive(ResourceLocation id, BlockModel model) { - while (true) { - var emissive = emissiveModels.get(id); - if (emissive != null) return emissive; - - id = ((BlockModelAccessor) model).computercraft$getParentLocation(); - model = ((BlockModelAccessor) model).computercraft$getParent(); - - if (id == null || model == null) return null; - } - } } diff --git a/projects/fabric/src/client/java/dan200/computercraft/client/model/EmissiveBakedModel.java b/projects/fabric/src/client/java/dan200/computercraft/client/model/EmissiveBakedModel.java deleted file mode 100644 index 3512eb896d..0000000000 --- a/projects/fabric/src/client/java/dan200/computercraft/client/model/EmissiveBakedModel.java +++ /dev/null @@ -1,84 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The CC: Tweaked Developers -// -// SPDX-License-Identifier: MPL-2.0 - -package dan200.computercraft.client.model; - -import net.fabricmc.fabric.api.renderer.v1.RendererAccess; -import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; -import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel; -import net.fabricmc.fabric.api.renderer.v1.model.ModelHelper; -import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.core.BlockPos; -import net.minecraft.util.RandomSource; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.BlockAndTintGetter; -import net.minecraft.world.level.block.state.BlockState; - -import javax.annotation.Nullable; -import java.util.function.Supplier; - -/** - * Wraps an arbitrary {@link BakedModel} to render a single texture as emissive. - *

- * While Fabric has a quite advanced rendering extension API (including support for custom materials), but unlike Forge - * it doesn't expose this in the model JSON (though externals mods like JMX - * do handle this). - *

- * Instead, we support emissive quads by injecting a {@linkplain CustomModelLoader custom model loader} which wraps the - * baked model in a {@link EmissiveBakedModel}, which renders specific quads as emissive. - */ -public final class EmissiveBakedModel extends ForwardingBakedModel { - private final TextureAtlasSprite emissiveTexture; - private final RenderMaterial defaultMaterial; - private final RenderMaterial emissiveMaterial; - - private EmissiveBakedModel(BakedModel wrapped, TextureAtlasSprite emissiveTexture, RenderMaterial defaultMaterial, RenderMaterial emissiveMaterial) { - this.wrapped = wrapped; - this.emissiveTexture = emissiveTexture; - this.defaultMaterial = defaultMaterial; - this.emissiveMaterial = emissiveMaterial; - } - - public static BakedModel wrap(BakedModel model, TextureAtlasSprite emissiveTexture) { - var renderer = RendererAccess.INSTANCE.getRenderer(); - return renderer == null ? model : new EmissiveBakedModel( - model, - emissiveTexture, - renderer.materialFinder().find(), - renderer.materialFinder().emissive(true).find() - ); - } - - @Override - public boolean isVanillaAdapter() { - return false; - } - - @Override - public void emitBlockQuads(BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext context) { - emitQuads(context, state, randomSupplier.get()); - } - - @Override - public void emitItemQuads(ItemStack stack, Supplier randomSupplier, RenderContext context) { - emitQuads(context, null, randomSupplier.get()); - } - - private void emitQuads(RenderContext context, @Nullable BlockState state, RandomSource random) { - var emitter = context.getEmitter(); - for (var faceIdx = 0; faceIdx <= ModelHelper.NULL_FACE_ID; faceIdx++) { - var cullFace = ModelHelper.faceFromIndex(faceIdx); - var quads = wrapped.getQuads(state, cullFace, random); - - var count = quads.size(); - for (var i = 0; i < count; i++) { - final var q = quads.get(i); - emitter.fromVanilla(q, q.getSprite() == emissiveTexture ? emissiveMaterial : defaultMaterial, cullFace); - emitter.emit(); - } - } - } -} diff --git a/projects/fabric/src/client/java/dan200/computercraft/client/model/turtle/TurtleModel.java b/projects/fabric/src/client/java/dan200/computercraft/client/model/turtle/TurtleModel.java index 704350b1ab..87f9137866 100644 --- a/projects/fabric/src/client/java/dan200/computercraft/client/model/turtle/TurtleModel.java +++ b/projects/fabric/src/client/java/dan200/computercraft/client/model/turtle/TurtleModel.java @@ -8,12 +8,14 @@ import dan200.computercraft.client.model.TransformedBakedModel; import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel; import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.renderer.block.model.ItemOverrides; +import net.minecraft.client.renderer.block.model.BakedOverrides; import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.client.resources.model.ModelBaker; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.item.ItemStack; import javax.annotation.Nullable; +import java.util.List; /** * The custom model for turtle items, which renders tools and overlays as part of the model. @@ -23,20 +25,21 @@ public class TurtleModel extends ForwardingBakedModel { private final TurtleModelParts parts; - private final ItemOverrides overrides = new ItemOverrides() { - @Override - public BakedModel resolve(BakedModel model, ItemStack stack, @Nullable ClientLevel level, @Nullable LivingEntity entity, int seed) { - return parts.getModel(stack); - } - }; + private final BakedOverrides overrides; - public TurtleModel(BakedModel familyModel, BakedModel colourModel) { + public TurtleModel(ModelBaker baker, BakedModel familyModel, BakedModel colourModel) { wrapped = familyModel; parts = new TurtleModelParts<>(familyModel, colourModel, TransformedBakedModel::new, CompositeBakedModel::of); + overrides = new BakedOverrides(baker, List.of()) { + @Override + public @Nullable BakedModel findOverride(ItemStack stack, @Nullable ClientLevel clientLevel, @Nullable LivingEntity entity, int seed) { + return parts.getModel(stack); + } + }; } @Override - public ItemOverrides getOverrides() { + public BakedOverrides overrides() { return overrides; } } diff --git a/projects/fabric/src/client/java/dan200/computercraft/client/model/turtle/UnbakedTurtleModel.java b/projects/fabric/src/client/java/dan200/computercraft/client/model/turtle/UnbakedTurtleModel.java index e04a7da2c8..2d3afbe8fa 100644 --- a/projects/fabric/src/client/java/dan200/computercraft/client/model/turtle/UnbakedTurtleModel.java +++ b/projects/fabric/src/client/java/dan200/computercraft/client/model/turtle/UnbakedTurtleModel.java @@ -11,8 +11,6 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.util.GsonHelper; -import java.util.Collection; -import java.util.List; import java.util.function.Function; /** @@ -36,24 +34,15 @@ public static UnbakedModel parse(JsonObject json) { } @Override - public Collection getDependencies() { - return List.of(model, COLOUR_TURTLE_MODEL); - } - - @Override - public void resolveParents(Function function) { - function.apply(model).resolveParents(function); - function.apply(COLOUR_TURTLE_MODEL).resolveParents(function); + public void resolveDependencies(Resolver resolver) { + resolver.resolve(model); + resolver.resolve(COLOUR_TURTLE_MODEL); } @Override public BakedModel bake(ModelBaker bakery, Function spriteGetter, ModelState transform) { var mainModel = bakery.bake(model, transform); - if (mainModel == null) throw new NullPointerException(model + " failed to bake"); - var colourModel = bakery.bake(COLOUR_TURTLE_MODEL, transform); - if (colourModel == null) throw new NullPointerException(COLOUR_TURTLE_MODEL + " failed to bake"); - - return new TurtleModel(mainModel, colourModel); + return new TurtleModel(bakery, mainModel, colourModel); } } diff --git a/projects/fabric/src/client/java/dan200/computercraft/client/platform/ClientPlatformHelperImpl.java b/projects/fabric/src/client/java/dan200/computercraft/client/platform/ClientPlatformHelperImpl.java index b8eaee2d2a..21e9334256 100644 --- a/projects/fabric/src/client/java/dan200/computercraft/client/platform/ClientPlatformHelperImpl.java +++ b/projects/fabric/src/client/java/dan200/computercraft/client/platform/ClientPlatformHelperImpl.java @@ -44,7 +44,7 @@ public BakedModel createdFoiledModel(BakedModel model) { public void renderBakedModel(PoseStack transform, MultiBufferSource buffers, BakedModel model, int lightmapCoord, int overlayLight, @Nullable int[] tints) { // Unfortunately we can't call Fabric's emitItemQuads here, as there's no way to obtain a RenderContext via the // API. Instead, we special case our FoiledModel, and just render everything else normally. - var buffer = ItemRenderer.getFoilBuffer(buffers, Sheets.translucentCullBlockSheet(), true, model instanceof FoiledModel); + var buffer = ItemRenderer.getFoilBuffer(buffers, Sheets.translucentItemSheet(), true, model instanceof FoiledModel); for (var faceIdx = 0; faceIdx <= ModelHelper.NULL_FACE_ID; faceIdx++) { var face = ModelHelper.faceFromIndex(faceIdx); diff --git a/projects/fabric/src/client/java/dan200/computercraft/mixin/client/DebugScreenOverlayMixin.java b/projects/fabric/src/client/java/dan200/computercraft/mixin/client/DebugScreenOverlayMixin.java index 301043a8a7..ea92430f24 100644 --- a/projects/fabric/src/client/java/dan200/computercraft/mixin/client/DebugScreenOverlayMixin.java +++ b/projects/fabric/src/client/java/dan200/computercraft/mixin/client/DebugScreenOverlayMixin.java @@ -20,10 +20,4 @@ class DebugScreenOverlayMixin { private void appendBlockDebugInfo(CallbackInfoReturnable> cir) { ClientHooks.addBlockDebugInfo(cir.getReturnValue()::add); } - - @Inject(method = "getGameInformation", at = @At("RETURN")) - @SuppressWarnings("UnusedMethod") - private void appendGameDebugInfo(CallbackInfoReturnable> cir) { - ClientHooks.addGameDebugInfo(cir.getReturnValue()::add); - } } diff --git a/projects/fabric/src/client/java/dan200/computercraft/mixin/client/GameRendererMixin.java b/projects/fabric/src/client/java/dan200/computercraft/mixin/client/GameRendererMixin.java deleted file mode 100644 index a7d123974e..0000000000 --- a/projects/fabric/src/client/java/dan200/computercraft/mixin/client/GameRendererMixin.java +++ /dev/null @@ -1,41 +0,0 @@ -// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers -// -// SPDX-License-Identifier: MPL-2.0 - -package dan200.computercraft.mixin.client; - -import dan200.computercraft.client.ClientRegistry; -import net.minecraft.client.renderer.GameRenderer; -import net.minecraft.client.renderer.ShaderInstance; -import net.minecraft.server.packs.resources.ResourceProvider; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import java.io.IOException; -import java.io.UncheckedIOException; -import java.util.Map; - -@Mixin(GameRenderer.class) -class GameRendererMixin { - @Final - @Shadow - @SuppressWarnings("NullAway") - private Map shaders; - - @Inject(method = "reloadShaders", at = @At(value = "TAIL")) - @SuppressWarnings("unused") - private void onReloadShaders(ResourceProvider resourceManager, CallbackInfo ci) { - try { - ClientRegistry.registerShaders(resourceManager, (shader, callback) -> { - shaders.put(shader.getName(), shader); - callback.accept(shader); - }); - } catch (IOException e) { - throw new UncheckedIOException("Could not reload shaders", e); - } - } -} diff --git a/projects/fabric/src/client/java/dan200/computercraft/mixin/client/ItemFrameRendererMixin.java b/projects/fabric/src/client/java/dan200/computercraft/mixin/client/ItemFrameRendererMixin.java index 5be6df1b98..7b1ec3212a 100644 --- a/projects/fabric/src/client/java/dan200/computercraft/mixin/client/ItemFrameRendererMixin.java +++ b/projects/fabric/src/client/java/dan200/computercraft/mixin/client/ItemFrameRendererMixin.java @@ -8,7 +8,7 @@ import dan200.computercraft.client.ClientHooks; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.entity.ItemFrameRenderer; -import net.minecraft.world.entity.decoration.ItemFrame; +import net.minecraft.client.renderer.entity.state.ItemFrameRenderState; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -18,13 +18,13 @@ @SuppressWarnings("UnusedMethod") class ItemFrameRendererMixin { @Inject( - method = "render(Lnet/minecraft/world/entity/decoration/ItemFrame;FFLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;I)V", + method = "render(Lnet/minecraft/client/renderer/entity/state/ItemFrameRenderState;Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;I)V", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/vertex/PoseStack;mulPose(Lorg/joml/Quaternionf;)V", ordinal = 2, shift = At.Shift.AFTER), cancellable = true ) @SuppressWarnings("unused") - private void render(ItemFrame entity, float yaw, float partialTicks, PoseStack pose, MultiBufferSource buffers, int light, CallbackInfo ci) { - if (ClientHooks.onRenderItemFrame(pose, buffers, entity, entity.getItem(), light)) { + private void render(ItemFrameRenderState frame, PoseStack pose, MultiBufferSource buffers, int light, CallbackInfo ci) { + if (ClientHooks.onRenderItemFrame(pose, buffers, frame, frame.itemStack, light)) { ci.cancel(); pose.popPose(); } diff --git a/projects/fabric/src/client/resources/computercraft-client.fabric.mixins.json b/projects/fabric/src/client/resources/computercraft-client.fabric.mixins.json index a39cbc195a..cb1d0660e0 100644 --- a/projects/fabric/src/client/resources/computercraft-client.fabric.mixins.json +++ b/projects/fabric/src/client/resources/computercraft-client.fabric.mixins.json @@ -10,7 +10,6 @@ "BlockModelAccessor", "BlockRenderDispatcherMixin", "DebugScreenOverlayMixin", - "GameRendererMixin", "ItemFrameRendererMixin", "ItemInHandRendererMixin", "MinecraftMixin", diff --git a/projects/fabric/src/main/java/dan200/computercraft/mixin/EntityMixin.java b/projects/fabric/src/main/java/dan200/computercraft/mixin/EntityMixin.java index 8014b5deef..be503bbf63 100644 --- a/projects/fabric/src/main/java/dan200/computercraft/mixin/EntityMixin.java +++ b/projects/fabric/src/main/java/dan200/computercraft/mixin/EntityMixin.java @@ -5,6 +5,7 @@ package dan200.computercraft.mixin; import dan200.computercraft.shared.CommonHooks; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.item.ItemStack; @@ -16,12 +17,12 @@ @Mixin(Entity.class) class EntityMixin { @Inject( - method = "spawnAtLocation(Lnet/minecraft/world/item/ItemStack;F)Lnet/minecraft/world/entity/item/ItemEntity;", - at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;addFreshEntity(Lnet/minecraft/world/entity/Entity;)Z"), + method = "spawnAtLocation(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/item/ItemStack;F)Lnet/minecraft/world/entity/item/ItemEntity;", + at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;addFreshEntity(Lnet/minecraft/world/entity/Entity;)Z"), cancellable = true ) @SuppressWarnings("unused") - private void spawnAtLocation(ItemStack stack, float yOffset, CallbackInfoReturnable cb) { + private void spawnAtLocation(ServerLevel level, ItemStack stack, float yOffset, CallbackInfoReturnable cb) { if (CommonHooks.onLivingDrop((Entity) (Object) this, stack)) cb.setReturnValue(null); } } diff --git a/projects/fabric/src/main/java/dan200/computercraft/mixin/V3818_3Mixin.java b/projects/fabric/src/main/java/dan200/computercraft/mixin/V3818_3Mixin.java deleted file mode 100644 index 26b7806dbe..0000000000 --- a/projects/fabric/src/main/java/dan200/computercraft/mixin/V3818_3Mixin.java +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-FileCopyrightText: 2024 The CC: Tweaked Developers -// -// SPDX-License-Identifier: MPL-2.0 - -package dan200.computercraft.mixin; - -import com.llamalad7.mixinextras.injector.ModifyReturnValue; -import com.mojang.datafixers.schemas.Schema; -import com.mojang.datafixers.types.templates.TypeTemplate; -import dan200.computercraft.shared.util.ComponentizationFixers; -import net.minecraft.util.datafix.schemas.V3818_3; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -/** - * Add our custom data components to the datafixer system. - *

- * This mixin is identical between Fabric and NeoForge aside from using a different method name. - */ -@Mixin(V3818_3.class) -class V3818_3Mixin { - @ModifyReturnValue(method = "method_57277", at = @At("TAIL")) - @SuppressWarnings("UnusedMethod") - private static TypeTemplate addExtraTypes(TypeTemplate type, Schema schema) { - return ComponentizationFixers.addExtraTypes(type, schema); - } -} diff --git a/projects/fabric/src/main/java/dan200/computercraft/shared/ComputerCraft.java b/projects/fabric/src/main/java/dan200/computercraft/shared/ComputerCraft.java index f1ad204115..e0cd05dc18 100644 --- a/projects/fabric/src/main/java/dan200/computercraft/shared/ComputerCraft.java +++ b/projects/fabric/src/main/java/dan200/computercraft/shared/ComputerCraft.java @@ -50,7 +50,6 @@ import net.minecraft.server.packs.PackType; import net.minecraft.server.packs.resources.PreparableReloadListener; import net.minecraft.server.packs.resources.ResourceManager; -import net.minecraft.util.profiling.ProfilerFiller; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.storage.LevelResource; @@ -158,8 +157,8 @@ public ResourceLocation getFabricId() { } @Override - public CompletableFuture reload(PreparationBarrier preparationBarrier, ResourceManager resourceManager, ProfilerFiller preparationsProfiler, ProfilerFiller reloadProfiler, Executor backgroundExecutor, Executor gameExecutor) { - return listener.reload(preparationBarrier, resourceManager, preparationsProfiler, reloadProfiler, backgroundExecutor, gameExecutor); + public CompletableFuture reload(PreparationBarrier preparationBarrier, ResourceManager resourceManager, Executor backgroundExecutor, Executor gameExecutor) { + return listener.reload(preparationBarrier, resourceManager, backgroundExecutor, gameExecutor); } } } diff --git a/projects/fabric/src/main/java/dan200/computercraft/shared/FabricCommonHooks.java b/projects/fabric/src/main/java/dan200/computercraft/shared/FabricCommonHooks.java index bfcbf2b0c7..a48681dce0 100644 --- a/projects/fabric/src/main/java/dan200/computercraft/shared/FabricCommonHooks.java +++ b/projects/fabric/src/main/java/dan200/computercraft/shared/FabricCommonHooks.java @@ -44,7 +44,7 @@ public static InteractionResult useOnBlock(Player player, Level level, Interacti if (player.isSecondaryUseActive() && doesSneakBypassUse(player.getMainHandItem()) && doesSneakBypassUse(player.getOffhandItem())) { var result = block.useItemOn(player.getMainHandItem(), level, player, hand, hitResult); - if (result.consumesAction()) return result.result(); + if (result.consumesAction()) return result; } return InteractionResult.PASS; diff --git a/projects/fabric/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java b/projects/fabric/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java index 35568523dc..1a18ab647c 100644 --- a/projects/fabric/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java +++ b/projects/fabric/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java @@ -23,7 +23,6 @@ import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup; import net.fabricmc.fabric.api.lookup.v1.block.BlockApiCache; import net.fabricmc.fabric.api.lookup.v1.block.BlockApiLookup; -import net.fabricmc.fabric.api.registry.FuelRegistry; import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory; import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerType; import net.fabricmc.fabric.api.tag.convention.v2.ConventionalItemTags; @@ -40,6 +39,7 @@ import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.tags.ItemTags; @@ -56,8 +56,7 @@ import net.minecraft.world.item.*; import net.minecraft.world.item.context.UseOnContext; import net.minecraft.world.item.crafting.CraftingInput; -import net.minecraft.world.item.crafting.Ingredient; -import net.minecraft.world.item.crafting.Recipe; +import net.minecraft.world.item.crafting.CraftingRecipe; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; @@ -87,7 +86,7 @@ public ConfigFile.Builder createConfigBuilder() { @SuppressWarnings("unchecked") private static Registry getRegistry(ResourceKey> id) { - var registry = (Registry) BuiltInRegistries.REGISTRY.get(id.location()); + var registry = (Registry) BuiltInRegistries.REGISTRY.getValue(id.location()); if (registry == null) throw new IllegalArgumentException("Unknown registry " + id); return registry; } @@ -146,16 +145,16 @@ public ContainerTransfer.Slotted wrapContainer(Container container) { @Override public RecipeIngredients getRecipeIngredients() { return new RecipeIngredients( - Ingredient.of(ConventionalItemTags.REDSTONE_DUSTS), - Ingredient.of(ConventionalItemTags.STRINGS), - Ingredient.of(ConventionalItemTags.LEATHERS), - Ingredient.of(ConventionalItemTags.GLASS_PANES), - Ingredient.of(ConventionalItemTags.GOLD_INGOTS), - Ingredient.of(ConventionalItemTags.STORAGE_BLOCKS_GOLD), - Ingredient.of(ConventionalItemTags.IRON_INGOTS), - Ingredient.of(ConventionalItemTags.DYES), - Ingredient.of(ConventionalItemTags.ENDER_PEARLS), - Ingredient.of(ConventionalItemTags.WOODEN_CHESTS) + ConventionalItemTags.REDSTONE_DUSTS, + ConventionalItemTags.STRINGS, + ConventionalItemTags.LEATHERS, + ConventionalItemTags.GLASS_PANES, + ConventionalItemTags.GOLD_INGOTS, + ConventionalItemTags.STORAGE_BLOCKS_GOLD, + ConventionalItemTags.IRON_INGOTS, + ConventionalItemTags.DYES, + ConventionalItemTags.ENDER_PEARLS, + ConventionalItemTags.WOODEN_CHESTS ); } @@ -182,9 +181,8 @@ public List> getDyeTags() { } @Override - public int getBurnTime(ItemStack stack) { - @Nullable var fuel = FuelRegistry.INSTANCE.get(stack.getItem()); - return fuel == null ? 0 : fuel; + public int getBurnTime(MinecraftServer server, ItemStack stack) { + return server.fuelValues().burnDuration(stack); } @Override @@ -198,7 +196,7 @@ public ItemStack getCraftingRemainingItem(ItemStack stack) { } @Override - public List getRecipeRemainingItems(ServerPlayer player, Recipe recipe, CraftingInput container) { + public List getRecipeRemainingItems(ServerPlayer player, CraftingRecipe recipe, CraftingInput container) { return recipe.getRemainingItems(container); } @@ -230,6 +228,7 @@ public InteractionResult canAttackEntity(ServerPlayer player, Entity entity) { @Override public boolean interactWithEntity(ServerPlayer player, Entity entity, Vec3 hitPos) { + // TODO: Properly handle return UseEntityCallback.EVENT.invoker().interact(player, entity.level(), InteractionHand.MAIN_HAND, entity, new EntityHitResult(entity, hitPos)).consumesAction() || entity.interactAt(player, hitPos.subtract(entity.position()), InteractionHand.MAIN_HAND).consumesAction() || player.interactOn(entity, InteractionHand.MAIN_HAND).consumesAction(); @@ -243,7 +242,7 @@ public InteractionResult useOn(ServerPlayer player, ItemStack stack, BlockHitRes var block = player.level().getBlockState(hit.getBlockPos()); if (!block.isAir() && canUseBlock.test(block)) { var useResult = block.useItemOn(stack, player.level(), player, InteractionHand.MAIN_HAND, hit); - if (useResult.consumesAction()) return useResult.result(); + if (useResult.consumesAction()) return useResult; // TODO(1.20.5): Should we do this unconditionally now? Or at least a better way of configuring it. // TODO(1.20.5: What to do with useWithoutItem diff --git a/projects/fabric/src/main/resources/fabric.mod.json b/projects/fabric/src/main/resources/fabric.mod.json index 0e3f19a7ef..fd5036d0db 100644 --- a/projects/fabric/src/main/resources/fabric.mod.json +++ b/projects/fabric/src/main/resources/fabric.mod.json @@ -47,7 +47,7 @@ "depends": { "fabricloader": ">=0.15.10", "fabric-api": ">=0.102.1", - "minecraft": "=1.21.1" + "minecraft": "=1.21.3" }, "accessWidener": "computercraft.accesswidener" } diff --git a/projects/forge/build.gradle.kts b/projects/forge/build.gradle.kts index 2b8f2feda0..343de48e27 100644 --- a/projects/forge/build.gradle.kts +++ b/projects/forge/build.gradle.kts @@ -54,12 +54,12 @@ runs { val server by registering { workingDirectory(file("run/server")) - programArgument("--nogui") + argument("--nogui") } val data by registering { workingDirectory(file("run")) - programArguments.addAll( + arguments.addAll( "--mod", "computercraft", "--all", "--output", layout.buildDirectory.dir("generatedResources").getAbsolutePath(), "--existing", project(":common").file("src/main/resources/").absolutePath, diff --git a/projects/forge/src/client/java/dan200/computercraft/client/ForgeClientHooks.java b/projects/forge/src/client/java/dan200/computercraft/client/ForgeClientHooks.java index 722dbb2032..221368fb38 100644 --- a/projects/forge/src/client/java/dan200/computercraft/client/ForgeClientHooks.java +++ b/projects/forge/src/client/java/dan200/computercraft/client/ForgeClientHooks.java @@ -47,7 +47,6 @@ public static void drawHighlight(RenderHighlightEvent.Block event) { @SubscribeEvent public static void onRenderText(CustomizeGuiOverlayEvent.DebugText event) { - ClientHooks.addGameDebugInfo(event.getLeft()::add); ClientHooks.addBlockDebugInfo(event.getRight()::add); } @@ -64,7 +63,7 @@ public static void onRenderInHand(RenderHandEvent event) { @SubscribeEvent public static void onRenderInFrame(RenderItemInFrameEvent event) { if (ClientHooks.onRenderItemFrame( - event.getPoseStack(), event.getMultiBufferSource(), event.getItemFrameEntity(), event.getItemStack(), event.getPackedLight() + event.getPoseStack(), event.getMultiBufferSource(), event.getItemFrameRenderState(), event.getItemStack(), event.getPackedLight() )) { event.setCanceled(true); } diff --git a/projects/forge/src/client/java/dan200/computercraft/client/ForgeClientRegistry.java b/projects/forge/src/client/java/dan200/computercraft/client/ForgeClientRegistry.java index 84704d7dab..7023a622fe 100644 --- a/projects/forge/src/client/java/dan200/computercraft/client/ForgeClientRegistry.java +++ b/projects/forge/src/client/java/dan200/computercraft/client/ForgeClientRegistry.java @@ -18,9 +18,11 @@ import net.neoforged.fml.ModLoader; import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent; -import net.neoforged.neoforge.client.event.*; +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.RegisterMenuScreensEvent; -import java.io.IOException; /** * Registers textures and models for items. @@ -62,11 +64,6 @@ public static void registerModels(ModelEvent.RegisterAdditional event) { ClientRegistry.registerExtraModels(x -> event.register(ModelResourceLocation.standalone(x)), extraModels); } - @SubscribeEvent - public static void registerShaders(RegisterShadersEvent event) throws IOException { - ClientRegistry.registerShaders(event.getResourceProvider(), event::registerShader); - } - @SubscribeEvent public static void onTurtleModellers(RegisterTurtleModellersEvent event) { ClientRegistry.registerTurtleModellers(event); diff --git a/projects/forge/src/client/java/dan200/computercraft/client/model/FoiledModel.java b/projects/forge/src/client/java/dan200/computercraft/client/model/FoiledModel.java index 430582937a..9ac3eec758 100644 --- a/projects/forge/src/client/java/dan200/computercraft/client/model/FoiledModel.java +++ b/projects/forge/src/client/java/dan200/computercraft/client/model/FoiledModel.java @@ -34,8 +34,8 @@ public List getQuads(@Nullable BlockState state, @Nullable Direction } @Override - public List getRenderTypes(ItemStack itemStack, boolean fabulous) { - return new ConsList<>(fabulous ? RenderType.glintTranslucent() : RenderType.glint(), super.getRenderTypes(itemStack, fabulous)); + public List getRenderTypes(ItemStack itemStack) { + return new ConsList<>(RenderType.glint(), super.getRenderTypes(itemStack)); } @Override diff --git a/projects/forge/src/client/java/dan200/computercraft/client/model/turtle/TurtleModel.java b/projects/forge/src/client/java/dan200/computercraft/client/model/turtle/TurtleModel.java index d1eec732bf..76fb34dd38 100644 --- a/projects/forge/src/client/java/dan200/computercraft/client/model/turtle/TurtleModel.java +++ b/projects/forge/src/client/java/dan200/computercraft/client/model/turtle/TurtleModel.java @@ -34,7 +34,7 @@ public BakedModel applyTransform(ItemDisplayContext transform, PoseStack poseSta } @Override - public List getRenderPasses(ItemStack stack, boolean fabulous) { + public List getRenderPasses(ItemStack stack) { return parts.getModel(stack); } } diff --git a/projects/forge/src/client/java/dan200/computercraft/client/model/turtle/TurtleModelLoader.java b/projects/forge/src/client/java/dan200/computercraft/client/model/turtle/TurtleModelLoader.java index 34a0424287..bd0e9401d2 100644 --- a/projects/forge/src/client/java/dan200/computercraft/client/model/turtle/TurtleModelLoader.java +++ b/projects/forge/src/client/java/dan200/computercraft/client/model/turtle/TurtleModelLoader.java @@ -7,18 +7,16 @@ import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonObject; import dan200.computercraft.api.ComputerCraftAPI; -import net.minecraft.client.renderer.block.model.ItemOverrides; +import net.minecraft.client.renderer.block.model.ItemOverride; import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.client.resources.model.Material; -import net.minecraft.client.resources.model.ModelBaker; -import net.minecraft.client.resources.model.ModelState; +import net.minecraft.client.resources.model.*; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.GsonHelper; import net.neoforged.neoforge.client.model.geometry.IGeometryBakingContext; import net.neoforged.neoforge.client.model.geometry.IGeometryLoader; import net.neoforged.neoforge.client.model.geometry.IUnbakedGeometry; +import java.util.List; import java.util.function.Function; /** @@ -49,13 +47,16 @@ private Unbaked(ResourceLocation family) { } @Override - public BakedModel bake(IGeometryBakingContext owner, ModelBaker bakery, Function spriteGetter, ModelState transform, ItemOverrides overrides) { - var mainModel = bakery.bake(family, transform, spriteGetter); - if (mainModel == null) throw new NullPointerException(family + " failed to bake"); + public void resolveDependencies(UnbakedModel.Resolver modelGetter, IGeometryBakingContext context) { + IUnbakedGeometry.super.resolveDependencies(modelGetter, context); + modelGetter.resolve(family); + modelGetter.resolve(COLOUR_TURTLE_MODEL); + } + @Override + public BakedModel bake(IGeometryBakingContext context, ModelBaker bakery, Function spriteGetter, ModelState transform, List overrides) { + var mainModel = bakery.bake(family, transform, spriteGetter); var colourModel = bakery.bake(COLOUR_TURTLE_MODEL, transform, spriteGetter); - if (colourModel == null) throw new NullPointerException(COLOUR_TURTLE_MODEL + " failed to bake"); - return new TurtleModel(mainModel, colourModel); } } diff --git a/projects/forge/src/client/java/dan200/computercraft/client/platform/ClientPlatformHelperImpl.java b/projects/forge/src/client/java/dan200/computercraft/client/platform/ClientPlatformHelperImpl.java index 2e1c72ed6c..08ef1c0043 100644 --- a/projects/forge/src/client/java/dan200/computercraft/client/platform/ClientPlatformHelperImpl.java +++ b/projects/forge/src/client/java/dan200/computercraft/client/platform/ClientPlatformHelperImpl.java @@ -43,7 +43,7 @@ public BakedModel createdFoiledModel(BakedModel model) { @Override public void renderBakedModel(PoseStack transform, MultiBufferSource buffers, BakedModel model, int lightmapCoord, int overlayLight, @Nullable int[] tints) { - for (var renderType : model.getRenderTypes(ItemStack.EMPTY, true)) { + for (var renderType : model.getRenderTypes(ItemStack.EMPTY)) { var buffer = buffers.getBuffer(renderType); for (var face : directions) { random.setSeed(42); diff --git a/projects/forge/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java b/projects/forge/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java index d0698b5769..ca77202922 100644 --- a/projects/forge/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java +++ b/projects/forge/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java @@ -27,6 +27,7 @@ import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.tags.TagKey; @@ -43,8 +44,7 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.context.UseOnContext; import net.minecraft.world.item.crafting.CraftingInput; -import net.minecraft.world.item.crafting.Ingredient; -import net.minecraft.world.item.crafting.Recipe; +import net.minecraft.world.item.crafting.CraftingRecipe; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; @@ -142,16 +142,16 @@ public ContainerTransfer getContainer(ServerLevel level, BlockPos pos, Direction @Override public RecipeIngredients getRecipeIngredients() { return new RecipeIngredients( - Ingredient.of(Tags.Items.DUSTS_REDSTONE), - Ingredient.of(Tags.Items.STRINGS), - Ingredient.of(Tags.Items.LEATHERS), - Ingredient.of(Tags.Items.GLASS_PANES), - Ingredient.of(Tags.Items.INGOTS_GOLD), - Ingredient.of(Tags.Items.STORAGE_BLOCKS_GOLD), - Ingredient.of(Tags.Items.INGOTS_IRON), - Ingredient.of(Tags.Items.DYES), - Ingredient.of(Tags.Items.ENDER_PEARLS), - Ingredient.of(Tags.Items.CHESTS_WOODEN) + Tags.Items.DUSTS_REDSTONE, + Tags.Items.STRINGS, + Tags.Items.LEATHERS, + Tags.Items.GLASS_PANES, + Tags.Items.INGOTS_GOLD, + Tags.Items.STORAGE_BLOCKS_GOLD, + Tags.Items.INGOTS_IRON, + Tags.Items.DYES, + Tags.Items.ENDER_PEARLS, + Tags.Items.CHESTS_WOODEN ); } @@ -178,8 +178,8 @@ public List> getDyeTags() { } @Override - public int getBurnTime(ItemStack stack) { - return stack.getBurnTime(null); + public int getBurnTime(MinecraftServer server, ItemStack stack) { + return stack.getBurnTime(null, server.fuelValues()); } @Override @@ -189,11 +189,11 @@ public CreativeModeTab.Builder newCreativeModeTab() { @Override public ItemStack getCraftingRemainingItem(ItemStack stack) { - return stack.getCraftingRemainingItem(); + return stack.getCraftingRemainder(); } @Override - public List getRecipeRemainingItems(ServerPlayer player, Recipe recipe, CraftingInput container) { + public List getRecipeRemainingItems(ServerPlayer player, CraftingRecipe recipe, CraftingInput container) { CommonHooks.setCraftingPlayer(player); var result = recipe.getRemainingItems(container); CommonHooks.setCraftingPlayer(null); @@ -253,7 +253,7 @@ public InteractionResult useOn(ServerPlayer player, ItemStack stack, BlockHitRes var block = level.getBlockState(hit.getBlockPos()); if (!event.getUseBlock().isFalse() && !block.isAir() && canUseBlock.test(block)) { var useResult = block.useItemOn(stack, level, player, InteractionHand.MAIN_HAND, hit); - if (useResult.consumesAction()) return useResult.result(); + if (useResult.consumesAction()) return useResult; } return event.getUseItem().isFalse() ? InteractionResult.PASS : stack.useOn(context); diff --git a/projects/forge/src/main/resources/META-INF/accesstransformer.cfg b/projects/forge/src/main/resources/META-INF/accesstransformer.cfg index dcfea532f5..11db6ffede 100644 --- a/projects/forge/src/main/resources/META-INF/accesstransformer.cfg +++ b/projects/forge/src/main/resources/META-INF/accesstransformer.cfg @@ -3,12 +3,7 @@ # SPDX-License-Identifier: MPL-2.0 # DirectVertexBuffer -protected com.mojang.blaze3d.vertex.VertexBuffer vertexBufferId -protected com.mojang.blaze3d.vertex.VertexBuffer indexType -protected com.mojang.blaze3d.vertex.VertexBuffer indexCount -protected com.mojang.blaze3d.vertex.VertexBuffer mode -protected com.mojang.blaze3d.vertex.VertexBuffer sequentialIndices -protected com.mojang.blaze3d.vertex.VertexBuffer format +public com.mojang.blaze3d.vertex.VertexBuffer indexCount # ClientTableFormatter public net.minecraft.client.gui.components.ChatComponent allMessages diff --git a/projects/forge/src/main/resources/META-INF/neoforge.mods.toml b/projects/forge/src/main/resources/META-INF/neoforge.mods.toml index 23444c070a..d5ec86e854 100644 --- a/projects/forge/src/main/resources/META-INF/neoforge.mods.toml +++ b/projects/forge/src/main/resources/META-INF/neoforge.mods.toml @@ -26,15 +26,12 @@ CC: Tweaked is a fork of ComputerCraft, adding programmable computers, turtles a [[dependencies.computercraft]] modId="neoforge" type="required" - versionRange="[${neoVersion},21.2)" + versionRange="[${neoVersion},21.4)" ordering="NONE" side="BOTH" [[mixins]] config = "computercraft.mixins.json" -[[mixins]] -config = "computercraft.forge.mixins.json" - [[mixins]] config = "computercraft-client.forge.mixins.json" diff --git a/projects/forge/src/main/resources/computercraft.forge.mixins.json b/projects/forge/src/main/resources/computercraft.forge.mixins.json deleted file mode 100644 index d6200c7709..0000000000 --- a/projects/forge/src/main/resources/computercraft.forge.mixins.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "required": true, - "package": "dan200.computercraft.mixin", - "minVersion": "0.8", - "compatibilityLevel": "JAVA_21", - "injectors": { - "defaultRequire": 1 - }, - "mixins": [ - "V3818_3Mixin" - ] -}