From 11c75cc19d8a2e1f28c4a205d1778997062db43e Mon Sep 17 00:00:00 2001 From: njoyshadow Date: Sun, 12 Apr 2026 22:08:16 +0900 Subject: [PATCH 01/11] fort et terminals --- .gitignore | 5 +- build.gradle | 41 +- gradle.properties | 17 +- .../extendedterminal/ExtendedTerminal.java | 14 +- .../extendedterminal/api/ModAccessor.java | 2 +- .../api/SubscribeLoadEvent.java | 10 - .../api/host/IETTerminalHost.java | 17 + .../extendedterminal/client/ETClient.java | 60 ++- .../client/screen/ETTerminalBaseScreen.java | 10 +- .../extendedterminal/ETTerminalScreen.java | 63 +++ .../gui/ETTerminalModePanel.java | 63 +++ .../extendedterminal/gui/XPLabelWidget.java | 61 +++ .../gui/panels/AnvilPanel.java | 69 +++ .../gui/panels/CraftingPanel.java | 47 ++ .../gui/panels/SmithingTablePanel.java | 59 +++ .../gui/panels/StoneCutterPanel.java | 159 +++++++ .../extendedterminal/wt/ETWTScreen.java | 27 ++ .../extendedterminal/datagen/ETDataGen.java | 6 +- .../datagen/condition/ETModCondition.java | 12 +- .../extendedterminal/init/ETCondition.java | 5 + .../extendedterminal/init/ETCreativeTab.java | 10 +- .../myogoo/extendedterminal/init/ETMenus.java | 2 + .../init/ETModIntegration.java | 28 ++ .../extendedterminal/init/ETNetwork.java | 44 +- .../myogoo/extendedterminal/init/ETParts.java | 2 + .../extendedterminal/init/wt/WTInit.java | 59 +++ .../extendedterminal/init/wt/WTItems.java | 41 ++ .../extendedterminal/init/wt/WTMenus.java | 22 + .../integration/ItemListModLoadHelper.java | 15 +- .../emi/avaritiaNeo/AVNeoRecipeHandler.java | 4 +- .../emi/avaritiaNeo/AVNeoWorkstation.java | 4 +- .../emi/avaritiaRe/AVRecipeHandler.java | 4 +- .../emi/avaritiaRe/AVWorkstation.java | 4 +- .../emi/extendedterminal/ETRecipeHandler.java | 31 ++ .../emi/extendedterminal/ETWorkstation.java | 19 + .../handler/AbstractETRecipeHandler.java | 83 ++++ .../handler/ETCraftingRecipeHandler.java | 45 ++ .../handler/ETSmithingRecipeHandler.java | 51 +++ .../handler/ETStonecutterRecipeHandler.java | 47 ++ .../wt/ETWTRecipeCategory.java | 21 + .../wt/ETWTRecipeHandler.java | 21 + .../handler/AbstractTableRecipeHandler.java | 4 +- .../integration/guideme/ConditionTag.java | 51 +-- .../jei/avaritiaNeo/AVNeoGuiHandler.java | 4 +- .../jei/avaritiaNeo/AVNeoRecipeCatalyst.java | 4 +- .../AVNeoRecipeTransferHandler.java | 4 +- .../jei/avaritiaRe/AVGuiHandler.java | 4 +- .../jei/avaritiaRe/AVRecipeCatalyst.java | 4 +- .../avaritiaRe/AVRecipeTransferHandler.java | 4 +- .../jei/extendedcrafting/ECGuiHandler.java | 4 +- .../extendedcrafting/ECRecipeCatalyst.java | 4 +- .../ECRecipeTransferHandler.java | 4 +- .../jei/extendedcrafting/EXCGuiHandler.java | 4 +- .../extendedcrafting/EXCRecipeCatalyst.java | 4 +- .../EXCRecipeTransferHandler.java | 4 +- .../extendedterminal/ETRecipeCatalyst.java | 32 ++ .../ETRecipeTransferHandler.java | 40 ++ .../handler/ETCraftingRecipeTransfer.java | 68 +++ .../handler/ETSmithingRecipeTransfer.java | 65 +++ .../handler/ETStonecutterRecipeTransfer.java | 65 +++ .../wt/ETWTRecipeCatalyst.java | 20 + .../wt/ETWTRecipeTransferHandler.java | 23 + .../handler/AbstractTableRecipeHandler.java | 4 +- .../ETCraftingRecipeTransferHelper.java | 60 +++ .../ETSmithingRecipeTransferHelper.java | 53 +++ .../ETStoneCutterRecipeTransferHelper.java | 47 ++ .../item/wtitem/ETWTItem.java | 17 + .../extendedterminal/me/host/ETWTHost.java | 127 ++++++ .../extendedterminal/menu/ETMenuType.java | 9 +- .../menu/ETSlotSemantics.java | 12 + .../menu/ETTerminalBaseMenu.java | 16 +- .../menu/extendedterminal/ETTerminalMenu.java | 406 ++++++++++++++++++ .../menu/extendedterminal/ETTerminalMode.java | 57 +++ .../menu/extendedterminal/FakeAnvilMenu.java | 29 ++ .../extendedterminal/slot/ETAnvilSlot.java | 44 ++ .../extendedterminal/slot/ETSmithingSlot.java | 175 ++++++++ .../slot/ETStoneCutterSlot.java | 162 +++++++ .../menu/extendedterminal/wt/ETWTMenu.java | 35 ++ .../menu/slot/ETCraftingBaseSlot.java | 3 +- .../mixin/GuideMeAddonMixin.java | 25 -- .../mixin/NetworkHandlerMixin.java | 34 -- .../network/NetworkPacketType.java | 43 -- .../ETFillCraftingGridFromRecipePacket.java | 59 ++- .../ETFillSmithingGridFromRecipePacket.java | 207 +++++++++ ...ETFillStonecutterGridFromRecipePacket.java | 200 +++++++++ .../serverbound/FillRecipeBasePacket.java | 3 +- .../serverbound/IETFillRecipeBasePacket.java | 35 ++ .../part/extendedterminal/ETTerminalPart.java | 174 ++++++++ .../extendedterminal/util/SafeClass.java | 2 +- .../util/mod/ModIntegrationManager.java | 66 --- .../util/mod/SupportedMod.java | 50 --- src/main/resources/META-INF/mods.toml | 7 + .../assets/ae2/screens/et_terminal.json | 90 ++++ .../assets/ae2/screens/panels/anvil.json | 38 ++ .../assets/ae2/screens/panels/crafting.json | 33 ++ .../ae2/screens/panels/smithingtable.json | 40 ++ .../ae2/screens/panels/stonecutter.json | 29 ++ .../ae2/screens/wireless_et_terminal.json | 6 + .../ae2/textures/guis/et_terminal_panel.png | Bin 0 -> 2797 bytes .../recipes/ae2wtlib/etc.json | 17 + .../recipes/ae2wtlib/etp.json | 17 + .../upgrade_wireless_et_terminal.json | 13 + .../recipes/avaritianeo/extreme_terminal.json | 6 +- .../extendedcrafting/advanced_terminal.json | 6 +- .../extendedcrafting/basic_terminal.json | 6 +- .../extendedcrafting/elite_terminal.json | 6 +- .../extendedcrafting/epic_terminal.json | 6 +- .../extendedcrafting/ultimate_terminal.json | 6 +- .../recipes/extendedterminal/et_terminal.json | 30 ++ .../wt/wireless_et_terminal.json | 6 +- .../recipes/reavaritia/end_terminal.json | 6 +- .../recipes/reavaritia/extreme_terminal.json | 4 +- .../recipes/reavaritia/nether_terminal.json | 6 +- .../recipes/reavaritia/sculk_terminal.json | 6 +- .../resources/extendedterminal.mixins.json | 10 +- 115 files changed, 3824 insertions(+), 444 deletions(-) delete mode 100644 src/main/java/me/myogoo/extendedterminal/api/SubscribeLoadEvent.java create mode 100644 src/main/java/me/myogoo/extendedterminal/api/host/IETTerminalHost.java create mode 100644 src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/ETTerminalScreen.java create mode 100644 src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/ETTerminalModePanel.java create mode 100644 src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/XPLabelWidget.java create mode 100644 src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/panels/AnvilPanel.java create mode 100644 src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/panels/CraftingPanel.java create mode 100644 src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/panels/SmithingTablePanel.java create mode 100644 src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/panels/StoneCutterPanel.java create mode 100644 src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/wt/ETWTScreen.java create mode 100644 src/main/java/me/myogoo/extendedterminal/init/ETModIntegration.java create mode 100644 src/main/java/me/myogoo/extendedterminal/init/wt/WTInit.java create mode 100644 src/main/java/me/myogoo/extendedterminal/init/wt/WTItems.java create mode 100644 src/main/java/me/myogoo/extendedterminal/init/wt/WTMenus.java create mode 100644 src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/ETRecipeHandler.java create mode 100644 src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/ETWorkstation.java create mode 100644 src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/AbstractETRecipeHandler.java create mode 100644 src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETCraftingRecipeHandler.java create mode 100644 src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETSmithingRecipeHandler.java create mode 100644 src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETStonecutterRecipeHandler.java create mode 100644 src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/wt/ETWTRecipeCategory.java create mode 100644 src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/wt/ETWTRecipeHandler.java create mode 100644 src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/ETRecipeCatalyst.java create mode 100644 src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/ETRecipeTransferHandler.java create mode 100644 src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/handler/ETCraftingRecipeTransfer.java create mode 100644 src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/handler/ETSmithingRecipeTransfer.java create mode 100644 src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/handler/ETStonecutterRecipeTransfer.java create mode 100644 src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/wt/ETWTRecipeCatalyst.java create mode 100644 src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/wt/ETWTRecipeTransferHandler.java create mode 100644 src/main/java/me/myogoo/extendedterminal/integration/module/extendedterminal/ETCraftingRecipeTransferHelper.java create mode 100644 src/main/java/me/myogoo/extendedterminal/integration/module/extendedterminal/ETSmithingRecipeTransferHelper.java create mode 100644 src/main/java/me/myogoo/extendedterminal/integration/module/extendedterminal/ETStoneCutterRecipeTransferHelper.java create mode 100644 src/main/java/me/myogoo/extendedterminal/item/wtitem/ETWTItem.java create mode 100644 src/main/java/me/myogoo/extendedterminal/me/host/ETWTHost.java create mode 100644 src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/ETTerminalMenu.java create mode 100644 src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/ETTerminalMode.java create mode 100644 src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/FakeAnvilMenu.java create mode 100644 src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/slot/ETAnvilSlot.java create mode 100644 src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/slot/ETSmithingSlot.java create mode 100644 src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/slot/ETStoneCutterSlot.java create mode 100644 src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/wt/ETWTMenu.java delete mode 100644 src/main/java/me/myogoo/extendedterminal/mixin/GuideMeAddonMixin.java delete mode 100644 src/main/java/me/myogoo/extendedterminal/mixin/NetworkHandlerMixin.java delete mode 100644 src/main/java/me/myogoo/extendedterminal/network/NetworkPacketType.java create mode 100644 src/main/java/me/myogoo/extendedterminal/network/serverbound/ETFillSmithingGridFromRecipePacket.java create mode 100644 src/main/java/me/myogoo/extendedterminal/network/serverbound/ETFillStonecutterGridFromRecipePacket.java create mode 100644 src/main/java/me/myogoo/extendedterminal/network/serverbound/IETFillRecipeBasePacket.java create mode 100644 src/main/java/me/myogoo/extendedterminal/part/extendedterminal/ETTerminalPart.java delete mode 100644 src/main/java/me/myogoo/extendedterminal/util/mod/ModIntegrationManager.java delete mode 100644 src/main/java/me/myogoo/extendedterminal/util/mod/SupportedMod.java create mode 100644 src/main/resources/assets/ae2/screens/et_terminal.json create mode 100644 src/main/resources/assets/ae2/screens/panels/anvil.json create mode 100644 src/main/resources/assets/ae2/screens/panels/crafting.json create mode 100644 src/main/resources/assets/ae2/screens/panels/smithingtable.json create mode 100644 src/main/resources/assets/ae2/screens/panels/stonecutter.json create mode 100644 src/main/resources/assets/ae2/screens/wireless_et_terminal.json create mode 100644 src/main/resources/assets/ae2/textures/guis/et_terminal_panel.png create mode 100644 src/main/resources/data/extendedterminal/recipes/ae2wtlib/etc.json create mode 100644 src/main/resources/data/extendedterminal/recipes/ae2wtlib/etp.json create mode 100644 src/main/resources/data/extendedterminal/recipes/ae2wtlib/upgrade_wireless_et_terminal.json create mode 100644 src/main/resources/data/extendedterminal/recipes/extendedterminal/et_terminal.json diff --git a/.gitignore b/.gitignore index b8f8e70..2049d2c 100644 --- a/.gitignore +++ b/.gitignore @@ -118,4 +118,7 @@ run-data/ # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) !gradle-wrapper.jar -*.pdn \ No newline at end of file +*.pdn + +.codex +.idea \ No newline at end of file diff --git a/build.gradle b/build.gradle index cfec4b9..7c57f64 100644 --- a/build.gradle +++ b/build.gradle @@ -176,6 +176,9 @@ repositories { maven { url "https://cursemaven.com" } + maven { + url = "https://api.modrinth.com/maven" + } } dependencies { @@ -186,34 +189,41 @@ dependencies { implementation(jarJar("io.github.llamalad7:mixinextras-forge:0.5.0")) { jarJar.ranged(it, "[0.5.0,)") } - - - compileOnly fg.deobf("appeng:appliedenergistics2-forge:${AE2_version}") - runtimeOnly fg.deobf("appeng:appliedenergistics2-forge:${AE2_version}") - + implementation(fg.deobf("appeng:appliedenergistics2-forge:${AE2_version}")) { + exclude group: "mezz.jei" + exclude group: "me.shedaniel" + exclude group: "dev.emi" + } + implementation(fg.deobf("me.myogoo:myotus:${Myotus_version}")) { + exclude group: "appeng" + exclude group: "org.appliedenergistics" + } implementation fg.deobf("com.blakebr0.cucumber:Cucumber:${minecraft_version}-${Cucumber_version}") compileOnly fg.deobf("curse.maven:extended-crafting-expanded-1017786:5613251") + compileOnly fg.deobf("maven.modrinth:applied-energistics-2-wireless-terminals:${AE2WTLib_version}") + runtimeOnly fg.deobf("dev.architectury:architectury-forge:${architectury_version}") + runtimeOnly fg.deobf("me.shedaniel.cloth:cloth-config-forge:${cloth_config_version}") + runtimeOnly fg.deobf("top.theillusivec4.curios:curios-forge:${curios_version}") - //compileOnly "top.theillusivec4.curios:curios-forge:${curios_version}:api" - //runtimeOnly "top.theillusivec4.curios:curios-forge:${curios_version}" - - //implementation "de.mari_023:ae2wtlib_api:${project.AE2WTLib_version}" - //runtimeOnly "de.mari_023:ae2wtlib:${project.AE2WTLib_version}" compileOnly fg.deobf("org.appliedenergistics:guideme:${guideME_version}:api") runtimeOnly fg.deobf("org.appliedenergistics:guideme:${guideME_version}") //Re:Avaritia 1.3.9.4-fix-release - compileOnly fg.deobf("curse.maven:re-avaritia-623969:7229795") + compileOnly fg.deobf("maven.modrinth:re-avaritia:${ReAvaritia_version}") //AvaritiaNeo 1.1.2 - compileOnly fg.deobf("curse.maven:avaritianeo-1083158:7089389") + compileOnly fg.deobf("curse.maven:avaritianeo-1083158:7570043") - //compileOnly "mezz.jei:jei-${minecraft_version}-neoforge-api:${JEI_version}" compileOnly fg.deobf("mezz.jei:jei-${minecraft_version}-common-api:${JEI_version}") compileOnly fg.deobf("mezz.jei:jei-${minecraft_version}-forge-api:${JEI_version}") compileOnly fg.deobf("me.shedaniel:RoughlyEnoughItems-forge:${REI_version}") compileOnly fg.deobf("dev.emi:emi-forge:${EMI_version}:api") + + if(project.enable_wtlib == "true") { + runtimeOnly fg.deobf("maven.modrinth:applied-energistics-2-wireless-terminals:${AE2WTLib_version}") + } + switch (project.itemListMod) { case "jei": runtimeOnly fg.deobf("mezz.jei:jei-${minecraft_version}-forge:${JEI_version}") @@ -244,10 +254,10 @@ dependencies { switch (project.enable_avaritia) { case "re": - runtimeOnly fg.deobf("curse.maven:re-avaritia-623969:7229795") + runtimeOnly fg.deobf("maven.modrinth:re-avaritia:${ReAvaritia_version}") break; case "neo": - runtimeOnly fg.deobf("curse.maven:avaritianeo-1083158:7089389") + runtimeOnly fg.deobf("curse.maven:avaritianeo-1083158:7570043") break; default: break; @@ -263,6 +273,7 @@ tasks.named('processResources', ProcessResources).configure { var replaceProperties = [minecraft_version : minecraft_version, minecraft_version_range: minecraft_version_range, forge_version : forge_version, forge_version_range: forge_version_range, loader_version_range: loader_version_range, + myotus_version_range: myotus_version_range, mod_id : mod_id, mod_name: mod_name, mod_license: mod_license, mod_version: mod_version, mod_authors : mod_authors, mod_description: mod_description,] diff --git a/gradle.properties b/gradle.properties index 4361bf4..477ee76 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx3G org.gradle.daemon=false minecraft_version=1.20.1 minecraft_version_range=[1.20.1,1.21) -forge_version=47.4.3 +forge_version=47.4.17 forge_version_range=[47,) loader_version_range=[47,) mapping_channel=official @@ -11,7 +11,7 @@ mod_id=extendedterminal mod_name=Extended Terminal mod_license=GNU LGPL 3.0 mod_loader=forge -mod_version=0.2.1 +mod_version=15.0.1 mod_group_id=me.myogoo java_version=17 mod_version_type=beta @@ -19,17 +19,26 @@ mod_version_type=beta mod_authors=NJoyShadow mod_description=Add some terminal like extended crafting +Myotus_version=15.0.3 +myotus_version_range=[0.3-SNAPSHOT,) AE2_version=15.4.10 -AE2WTLib_version=15.2.3 +AE2WTLib_version=15.3.3-forge + +AvaritiaNeo_version=1.1.3 +ReAvaritia_version=1.3.9.8 + JEI_version=15.20.0.112 REI_version=12.1.785 EMI_version=1.1.22+1.20.1 curios_version=5.14.1+1.20.1 +architectury_version=9.0.7 +cloth_config_version=11.0.99 Cucumber_version=7.0.14 ExtendedCrafting_version=6.0.9 guideME_version=20.1.11 itemListMod=emi -enable_avaritia=neo +enable_avaritia=re enable_excrafting=exex +enable_wtlib=true \ No newline at end of file diff --git a/src/main/java/me/myogoo/extendedterminal/ExtendedTerminal.java b/src/main/java/me/myogoo/extendedterminal/ExtendedTerminal.java index b70de8a..61beb82 100644 --- a/src/main/java/me/myogoo/extendedterminal/ExtendedTerminal.java +++ b/src/main/java/me/myogoo/extendedterminal/ExtendedTerminal.java @@ -3,13 +3,14 @@ import com.mojang.logging.LogUtils; import me.myogoo.extendedterminal.init.*; -import me.myogoo.extendedterminal.util.mod.ModIntegrationManager; +import me.myogoo.extendedterminal.init.wt.WTItems; +import me.myogoo.extendedterminal.init.wt.WTMenus; +import me.myogoo.myotus.api.annotation.wt.AE2WTLib; +import me.myogoo.myotus.util.mod.ModIntegrationManager; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.eventbus.api.IEventBus; -import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import org.slf4j.Logger; @@ -21,7 +22,8 @@ public class ExtendedTerminal { public ExtendedTerminal() { ETConfig.init(); - ModIntegrationManager.initialize(); + ETModIntegration.initialize(); + ETNetwork.register(); IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus(); ETBlocks.REGISTER.register(modEventBus); @@ -29,6 +31,10 @@ public ExtendedTerminal() { ETParts.REGISTER.register(modEventBus); ETMenus.REGISTER.register(modEventBus); ETCreativeTab.REGISTER.register(modEventBus); + if (ModIntegrationManager.isLoaded(AE2WTLib.class)) { + WTItems.register(); + WTMenus.register(); + } MinecraftForge.EVENT_BUS.register(this); } diff --git a/src/main/java/me/myogoo/extendedterminal/api/ModAccessor.java b/src/main/java/me/myogoo/extendedterminal/api/ModAccessor.java index eae2a6e..0cdef83 100644 --- a/src/main/java/me/myogoo/extendedterminal/api/ModAccessor.java +++ b/src/main/java/me/myogoo/extendedterminal/api/ModAccessor.java @@ -22,4 +22,4 @@ public class ModAccessor { @Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface AvaritiaNeo {} -} \ No newline at end of file +} diff --git a/src/main/java/me/myogoo/extendedterminal/api/SubscribeLoadEvent.java b/src/main/java/me/myogoo/extendedterminal/api/SubscribeLoadEvent.java deleted file mode 100644 index 5b3e707..0000000 --- a/src/main/java/me/myogoo/extendedterminal/api/SubscribeLoadEvent.java +++ /dev/null @@ -1,10 +0,0 @@ -package me.myogoo.extendedterminal.api; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target({ElementType.METHOD}) -@Retention(RetentionPolicy.RUNTIME) -public @interface SubscribeLoadEvent { } diff --git a/src/main/java/me/myogoo/extendedterminal/api/host/IETTerminalHost.java b/src/main/java/me/myogoo/extendedterminal/api/host/IETTerminalHost.java new file mode 100644 index 0000000..c2d3788 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/api/host/IETTerminalHost.java @@ -0,0 +1,17 @@ +package me.myogoo.extendedterminal.api.host; + +import appeng.api.storage.ITerminalHost; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMode; +import net.minecraft.resources.ResourceLocation; +import org.jetbrains.annotations.Nullable; + +public interface IETTerminalHost extends ITerminalHost { + ETTerminalMode getMode(); + + void setMode(ETTerminalMode mode); + + @Nullable + ResourceLocation getStoneCutterRecipeId(); + + void setStoneCutterRecipeId(@Nullable ResourceLocation stonecuttingRecipeId); +} diff --git a/src/main/java/me/myogoo/extendedterminal/client/ETClient.java b/src/main/java/me/myogoo/extendedterminal/client/ETClient.java index 6bcfe13..300d37e 100644 --- a/src/main/java/me/myogoo/extendedterminal/client/ETClient.java +++ b/src/main/java/me/myogoo/extendedterminal/client/ETClient.java @@ -3,13 +3,14 @@ import appeng.api.util.AEColor; import appeng.client.render.StaticItemColor; import appeng.init.client.InitScreens; -import me.myogoo.extendedterminal.ExtendedTerminal; import me.myogoo.extendedterminal.client.screen.avaritiaNeo.NeoExtremeTerminalScreen; import me.myogoo.extendedterminal.client.screen.avaritiaRe.EndTerminalScreen; import me.myogoo.extendedterminal.client.screen.avaritiaRe.ExtremeTerminalScreen; import me.myogoo.extendedterminal.client.screen.avaritiaRe.NetherTerminalScreen; import me.myogoo.extendedterminal.client.screen.avaritiaRe.SculkTerminalScreen; import me.myogoo.extendedterminal.client.screen.extendedcrafting.*; +import me.myogoo.extendedterminal.client.screen.extendedterminal.ETTerminalScreen; +import me.myogoo.extendedterminal.client.screen.extendedterminal.wt.ETWTScreen; import me.myogoo.extendedterminal.init.ETParts; import me.myogoo.extendedterminal.menu.avaritiaNeo.NeoExtremeTerminalMenu; import me.myogoo.extendedterminal.menu.avaritiaRe.EndTerminalMenu; @@ -17,16 +18,16 @@ import me.myogoo.extendedterminal.menu.avaritiaRe.NetherTerminalMenu; import me.myogoo.extendedterminal.menu.avaritiaRe.SculkTerminalMenu; import me.myogoo.extendedterminal.menu.extendedcrafting.*; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; +import me.myogoo.extendedterminal.menu.extendedterminal.wt.ETWTMenu; +import me.myogoo.myotus.api.annotation.wt.AE2WTLib; +import me.myogoo.myotus.util.mod.ModIntegrationManager; import net.minecraft.world.level.ItemLike; import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.client.event.RegisterColorHandlersEvent; -import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; import static me.myogoo.extendedterminal.ExtendedTerminal.MODID; @@ -36,28 +37,47 @@ public class ETClient { @SubscribeEvent public static void init(RegisterColorHandlersEvent.Item event) { initColorParts(event); - initScreens(); + } + + @SubscribeEvent + public static void clientSetup(FMLClientSetupEvent event) { + event.enqueueWork(ETClient::initScreens); + + event.enqueueWork(() -> { + if (ModIntegrationManager.isLoaded(AE2WTLib.class)) { + initWTScreen(); + } + }); } public static void initScreens() { - InitScreens.register(BasicTerminalMenu.TYPE, BasicTerminalScreen::new, "/screens/extended_terminal/basic_terminal.json"); - InitScreens.register(AdvancedTerminalMenu.TYPE, AdvancedTerminalScreen::new, "/screens/extended_terminal/advanced_terminal.json"); - InitScreens.register(EliteTerminalMenu.TYPE, EliteTerminalScreen::new, "/screens/extended_terminal/elite_terminal.json"); - InitScreens.register(UltimateTerminalMenu.TYPE, UltimateTerminalScreen::new, "/screens/extended_terminal/ultimate_terminal.json"); - InitScreens.register(EpicTerminalMenu.TYPE, EpicTerminalScreen::new, "/screens/extended_terminal/epic_terminal.json"); - - InitScreens.register(SculkTerminalMenu.TYPE, SculkTerminalScreen::new, "/screens/avaritia/sculk_terminal.json"); - InitScreens.register(NetherTerminalMenu.TYPE, NetherTerminalScreen::new, "/screens/avaritia/nether_terminal.json"); - InitScreens.register(EndTerminalMenu.TYPE, EndTerminalScreen::new, "/screens/avaritia/end_terminal.json"); - InitScreens.register(ExtremeTerminalMenu.TYPE,ExtremeTerminalScreen::new, "/screens/avaritia/extreme_terminal.json"); - - InitScreens.register(NeoExtremeTerminalMenu.TYPE, NeoExtremeTerminalScreen::new, "/screens/avaritia/extreme_terminal.json"); + InitScreens.>register(ETTerminalMenu.TYPE, + (menu, playerInventory, title, style) -> new ETTerminalScreen<>(menu, playerInventory, title, style), + "/screens/et_terminal.json"); + + InitScreens.register(BasicTerminalMenu.TYPE,BasicTerminalScreen::new,"/screens/extended_terminal/basic_terminal.json"); + InitScreens.register(AdvancedTerminalMenu.TYPE,AdvancedTerminalScreen::new,"/screens/extended_terminal/advanced_terminal.json"); + InitScreens.register(EliteTerminalMenu.TYPE,EliteTerminalScreen::new,"/screens/extended_terminal/elite_terminal.json"); + InitScreens.register(UltimateTerminalMenu.TYPE,UltimateTerminalScreen::new,"/screens/extended_terminal/ultimate_terminal.json"); + InitScreens.register(EpicTerminalMenu.TYPE,EpicTerminalScreen::new,"/screens/extended_terminal/epic_terminal.json"); + + InitScreens.register(SculkTerminalMenu.TYPE,SculkTerminalScreen::new,"/screens/avaritia/sculk_terminal.json"); + InitScreens.register(NetherTerminalMenu.TYPE,NetherTerminalScreen::new,"/screens/avaritia/nether_terminal.json"); + InitScreens.register(EndTerminalMenu.TYPE,EndTerminalScreen::new,"/screens/avaritia/end_terminal.json"); + InitScreens.register(ExtremeTerminalMenu.TYPE,ExtremeTerminalScreen::new,"/screens/avaritia/extreme_terminal.json"); + + InitScreens.register(NeoExtremeTerminalMenu.TYPE,NeoExtremeTerminalScreen::new,"/screens/avaritia/extreme_terminal.json"); } + public static void initWTScreen() { + InitScreens.register(ETWTMenu.TYPE, ETWTScreen::new, "/screens/wireless_et_terminal.json"); + } + + public static void initColorParts(RegisterColorHandlersEvent.Item event) { event.register((stack, tintIndex) -> (new StaticItemColor(AEColor.TRANSPARENT).getColor(stack, tintIndex) | 0xFF000000), - ETParts.TERMINAL_PARTS.stream().map(x -> (ItemLike)x).toArray(ItemLike[]::new)); + ETParts.TERMINAL_PARTS.stream().map(x -> (ItemLike) x).toArray(ItemLike[]::new)); } } diff --git a/src/main/java/me/myogoo/extendedterminal/client/screen/ETTerminalBaseScreen.java b/src/main/java/me/myogoo/extendedterminal/client/screen/ETTerminalBaseScreen.java index 18afc6f..4a4e4a3 100644 --- a/src/main/java/me/myogoo/extendedterminal/client/screen/ETTerminalBaseScreen.java +++ b/src/main/java/me/myogoo/extendedterminal/client/screen/ETTerminalBaseScreen.java @@ -25,14 +25,17 @@ import java.util.List; public class ETTerminalBaseScreen,T extends ETTerminalBaseMenu> extends MEStorageScreen { + protected final ActionButton clearBtn; + protected final ActionButton clearToPlayerInvBtn; + public ETTerminalBaseScreen(T menu, Inventory playerInventory, Component title, ScreenStyle style) { super(menu, playerInventory, title, style); - ActionButton clearBtn = new ActionButton(ActionItems.STASH, btn -> menu.clearCraftingGrid()); + this.clearBtn = new ActionButton(ActionItems.STASH, btn -> menu.clearCraftingGrid()); clearBtn.setHalfSize(true); widgets.add("clearCraftingGrid", clearBtn); - ActionButton clearToPlayerInvBtn = new ActionButton(ActionItems.STASH_TO_PLAYER_INV, + this.clearToPlayerInvBtn = new ActionButton(ActionItems.STASH_TO_PLAYER_INV, btn -> menu.clearToPlayerInventory()); clearToPlayerInvBtn.setHalfSize(true); widgets.add("clearToPlayerInv",clearToPlayerInvBtn); @@ -68,6 +71,9 @@ protected void slotClicked(Slot slot, int slotIdx, int mouseButton, ClickType cl @Override public void init() { super.init(); + if (this.getMenu().getETMenuType() == ETMenuType.ET_TERMINAL) { + return; + } ETMenuType menuType = this.getMenu().getETMenuType(); drawCraftingSlot(menuType.getSlotSemanticGrid(),menuType.getGridSideLength()); } diff --git a/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/ETTerminalScreen.java b/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/ETTerminalScreen.java new file mode 100644 index 0000000..d1b238f --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/ETTerminalScreen.java @@ -0,0 +1,63 @@ +package me.myogoo.extendedterminal.client.screen.extendedterminal; + +import appeng.client.gui.style.ScreenStyle; +import appeng.client.gui.widgets.TabButton; +import me.myogoo.extendedterminal.client.screen.ETTerminalBaseScreen; +import me.myogoo.extendedterminal.client.screen.extendedterminal.gui.ETTerminalModePanel; +import me.myogoo.extendedterminal.client.screen.extendedterminal.gui.panels.AnvilPanel; +import me.myogoo.extendedterminal.client.screen.extendedterminal.gui.panels.CraftingPanel; +import me.myogoo.extendedterminal.client.screen.extendedterminal.gui.panels.SmithingTablePanel; +import me.myogoo.extendedterminal.client.screen.extendedterminal.gui.panels.StoneCutterPanel; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMode; +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.CraftingRecipe; + +import java.util.EnumMap; +import java.util.List; +import java.util.Map; + +public class ETTerminalScreen extends ETTerminalBaseScreen { + private final Map modePanels = new EnumMap<>(ETTerminalMode.class); + private final Map modeTabButtons = new EnumMap<>(ETTerminalMode.class); + + public ETTerminalScreen(T menu, Inventory playerInventory, Component title, ScreenStyle style) { + super(menu, playerInventory, title, style); + + for (var mode : ETTerminalMode.values()) { + ETTerminalModePanel panel = switch (mode) { + case CRAFTING -> new CraftingPanel(this, widgets, clearBtn, clearToPlayerInvBtn); + case SMITHING -> new SmithingTablePanel(this, widgets); + case STONECUTTING -> new StoneCutterPanel(this, widgets); + case ANVIL -> new AnvilPanel(this, widgets); + }; + + var tabButton = new TabButton(panel.getIcon(), panel.getTabTooltip(), btn -> getMenu().setMode(mode)); + tabButton.setStyle(TabButton.Style.HORIZONTAL); + + if (mode.canLoad()) { + widgets.add(panel.getWidgetId(), panel); + widgets.add(panel.getModeTabButtonId(), tabButton); + this.modePanels.put(mode, panel); + this.modeTabButtons.put(mode, tabButton); + } + } + } + + @Override + protected void updateBeforeRender() { + super.updateBeforeRender(); + + for (var mode : ETTerminalMode.loadableValues()) { + boolean selected = menu.getMode() == mode; + this.modeTabButtons.get(mode).setSelected(selected); + this.modePanels.get(mode).setVisible(selected); + } + } + + public List getTerminalTooltip(ItemStack stack) { + return this.getTooltipFromContainerItem(stack); + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/ETTerminalModePanel.java b/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/ETTerminalModePanel.java new file mode 100644 index 0000000..8b9c38c --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/ETTerminalModePanel.java @@ -0,0 +1,63 @@ +package me.myogoo.extendedterminal.client.screen.extendedterminal.gui; + +import appeng.client.Point; +import appeng.client.gui.ICompositeWidget; +import appeng.client.gui.WidgetContainer; +import me.myogoo.extendedterminal.client.screen.extendedterminal.ETTerminalScreen; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; +import net.minecraft.client.renderer.Rect2i; +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.ItemStack; + +public abstract class ETTerminalModePanel implements ICompositeWidget { + protected final ETTerminalScreen screen; + protected final ETTerminalMenu menu; + protected final WidgetContainer widgets; + protected boolean visible; + protected int x; + protected int y; + + protected ETTerminalModePanel(ETTerminalScreen screen, WidgetContainer widgets) { + this.screen = screen; + this.menu = screen.getMenu(); + this.widgets = widgets; + } + + public abstract ItemStack getIcon(); + + public Component getTabTooltip() { + return Component.translatable("gui.extendedterminal." + getClass().getSimpleName().toLowerCase()); + } + + public String getWidgetId() { + return "modePanel" + getClass().getSimpleName(); + } + + public String getModeTabButtonId() { + return "modeTabButton" + getClass().getSimpleName(); + } + + @Override + public void setPosition(Point position) { + this.x = position.getX(); + this.y = position.getY(); + } + + @Override + public void setSize(int width, int height) { + } + + @Override + public Rect2i getBounds() { + return new Rect2i(this.x, this.y, 124, 66); + } + + @Override + public boolean isVisible() { + return this.visible; + } + + public void setVisible(boolean visible) { + this.visible = visible; + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/XPLabelWidget.java b/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/XPLabelWidget.java new file mode 100644 index 0000000..b995fd5 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/XPLabelWidget.java @@ -0,0 +1,61 @@ +package me.myogoo.extendedterminal.client.screen.extendedterminal.gui; + +import appeng.client.Point; +import appeng.client.gui.ICompositeWidget; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.renderer.Rect2i; +import net.minecraft.network.chat.Component; + +public class XPLabelWidget implements ICompositeWidget { + private static final int RED_COLOR = 0xFF6060; + private static final int GREEN_COLOR = 0x80FF20; + + private Component text = Component.translatable("gui.extendedterminal.anvilpanel.xpcost", 0); + private boolean visible; + private int x; + private int y; + private int color = RED_COLOR; + private int cost; + + @Override + public void setPosition(Point position) { + this.x = position.getX(); + this.y = position.getY(); + } + + @Override + public void setSize(int width, int height) { + } + + @Override + public Rect2i getBounds() { + return new Rect2i(this.x, this.y, 0, 0); + } + + @Override + public boolean isVisible() { + return this.visible; + } + + public void setVisible(boolean visible) { + this.visible = visible; + } + + public void setCost(int cost) { + if (this.cost == cost) { + return; + } + this.cost = cost; + this.text = Component.translatable("gui.extendedterminal.anvilpanel.xpcost", this.cost); + this.color = this.cost > 0 ? GREEN_COLOR : RED_COLOR; + } + + @Override + public void drawForegroundLayer(GuiGraphics guiGraphics, Rect2i bounds, Point mouse) { + if (!this.visible || this.cost <= 0) { + return; + } + guiGraphics.drawString(Minecraft.getInstance().font, this.text, this.x, this.y, this.color); + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/panels/AnvilPanel.java b/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/panels/AnvilPanel.java new file mode 100644 index 0000000..1d7aecf --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/panels/AnvilPanel.java @@ -0,0 +1,69 @@ +package me.myogoo.extendedterminal.client.screen.extendedterminal.gui.panels; + +import appeng.client.Point; +import appeng.client.gui.WidgetContainer; +import appeng.client.gui.style.Blitter; +import appeng.client.gui.widgets.AETextField; +import me.myogoo.extendedterminal.client.screen.extendedterminal.ETTerminalScreen; +import me.myogoo.extendedterminal.client.screen.extendedterminal.gui.ETTerminalModePanel; +import me.myogoo.extendedterminal.client.screen.extendedterminal.gui.XPLabelWidget; +import me.myogoo.extendedterminal.menu.ETSlotSemantics; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.renderer.Rect2i; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.Blocks; + +public class AnvilPanel extends ETTerminalModePanel { + private static final Blitter BG = Blitter.texture("guis/et_terminal_panel.png", 512, 512).src(0, 201, 159, 65); + + private final AETextField textField; + private final XPLabelWidget enchantCostLabel; + + public AnvilPanel(ETTerminalScreen screen, WidgetContainer widgets) { + super(screen, widgets); + this.textField = widgets.addTextField("ET_ANVIL_NAME_FIELD"); + this.textField.setMaxLength(50); + this.textField.setResponder(this::onNameChanged); + + this.enchantCostLabel = new XPLabelWidget(); + widgets.add("ET_ANVIL_COST_LABEL", this.enchantCostLabel); + setVisible(false); + } + + @Override + public ItemStack getIcon() { + return new ItemStack(Blocks.ANVIL); + } + + @Override + public void setVisible(boolean visible) { + super.setVisible(visible); + screen.setSlotsHidden(ETSlotSemantics.ANVIL_RIGHT_INPUT, !visible); + screen.setSlotsHidden(ETSlotSemantics.ANVIL_LEFT_INPUT, !visible); + screen.setSlotsHidden(ETSlotSemantics.ANVIL_RESULT, !visible); + this.enchantCostLabel.setVisible(visible); + this.textField.setVisible(visible); + } + + @Override + public void drawBackgroundLayer(GuiGraphics guiGraphics, Rect2i bounds, Point mouse) { + BG.dest(bounds.getX() + 8, bounds.getY() + bounds.getHeight() - 165).blit(guiGraphics); + } + + @Override + public void updateBeforeRender() { + var resultSlot = menu.getSlots(ETSlotSemantics.ANVIL_RESULT).get(0); + this.enchantCostLabel.setCost(resultSlot.hasItem() ? menu.getAnvilCost() : 0); + } + + private void onNameChanged(String input) { + var slot = menu.getSlots(ETSlotSemantics.ANVIL_LEFT_INPUT).get(0); + if (slot.hasItem()) { + String name = input; + if (!slot.getItem().hasCustomHoverName() && input.equals(slot.getItem().getHoverName().getString())) { + name = ""; + } + menu.setAnvilItemName(name); + } + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/panels/CraftingPanel.java b/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/panels/CraftingPanel.java new file mode 100644 index 0000000..7aadec1 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/panels/CraftingPanel.java @@ -0,0 +1,47 @@ +package me.myogoo.extendedterminal.client.screen.extendedterminal.gui.panels; + +import appeng.client.Point; +import appeng.client.gui.WidgetContainer; +import appeng.client.gui.style.Blitter; +import appeng.client.gui.widgets.ActionButton; +import appeng.menu.SlotSemantics; +import me.myogoo.extendedterminal.client.screen.extendedterminal.ETTerminalScreen; +import me.myogoo.extendedterminal.client.screen.extendedterminal.gui.ETTerminalModePanel; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.renderer.Rect2i; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.Blocks; + +public class CraftingPanel extends ETTerminalModePanel { + private static final Blitter BG = Blitter.texture("guis/et_terminal_panel.png", 512, 512).src(0, 0, 159, 65); + + private final ActionButton clearToStorage; + private final ActionButton clearToInv; + + public CraftingPanel(ETTerminalScreen screen, WidgetContainer widgets, ActionButton clearToStorage, + ActionButton clearToInv) { + super(screen, widgets); + this.clearToStorage = clearToStorage; + this.clearToInv = clearToInv; + setVisible(false); + } + + @Override + public ItemStack getIcon() { + return new ItemStack(Blocks.CRAFTING_TABLE); + } + + @Override + public void setVisible(boolean visible) { + super.setVisible(visible); + this.clearToInv.setVisibility(visible); + this.clearToStorage.setVisibility(visible); + screen.setSlotsHidden(SlotSemantics.CRAFTING_GRID, !visible); + screen.setSlotsHidden(SlotSemantics.CRAFTING_RESULT, !visible); + } + + @Override + public void drawBackgroundLayer(GuiGraphics guiGraphics, Rect2i bounds, Point mouse) { + BG.dest(bounds.getX() + 8, bounds.getY() + bounds.getHeight() - 165).blit(guiGraphics); + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/panels/SmithingTablePanel.java b/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/panels/SmithingTablePanel.java new file mode 100644 index 0000000..75e07ee --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/panels/SmithingTablePanel.java @@ -0,0 +1,59 @@ +package me.myogoo.extendedterminal.client.screen.extendedterminal.gui.panels; + +import appeng.api.config.ActionItems; +import appeng.client.Point; +import appeng.client.gui.WidgetContainer; +import appeng.client.gui.style.Blitter; +import appeng.client.gui.widgets.ActionButton; +import me.myogoo.extendedterminal.client.screen.extendedterminal.ETTerminalScreen; +import me.myogoo.extendedterminal.client.screen.extendedterminal.gui.ETTerminalModePanel; +import me.myogoo.extendedterminal.menu.ETSlotSemantics; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.renderer.Rect2i; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.Blocks; + +import static me.myogoo.extendedterminal.part.extendedterminal.ETTerminalPart.SMITHING_INVENTORY; + +public class SmithingTablePanel extends ETTerminalModePanel { + private static final Blitter BG = Blitter.texture("guis/et_terminal_panel.png", 512, 512).src(0, 67, 159, 65); + + private final ActionButton clearBtn; + private final ActionButton clearToPlayerInvBtn; + + public SmithingTablePanel(ETTerminalScreen screen, WidgetContainer widgets) { + super(screen, widgets); + + this.clearBtn = new ActionButton(ActionItems.STASH, btn -> menu.clearSmithingGrid()); + this.clearBtn.setHalfSize(true); + widgets.add("clearSmithingGrid", this.clearBtn); + + this.clearToPlayerInvBtn = new ActionButton(ActionItems.STASH_TO_PLAYER_INV, + btn -> menu.clearToPlayerInventory(SMITHING_INVENTORY)); + this.clearToPlayerInvBtn.setHalfSize(true); + widgets.add("clearSmithingGridToPlayerInv", this.clearToPlayerInvBtn); + + setVisible(false); + } + + @Override + public ItemStack getIcon() { + return new ItemStack(Blocks.SMITHING_TABLE); + } + + @Override + public void setVisible(boolean visible) { + super.setVisible(visible); + screen.setSlotsHidden(ETSlotSemantics.SMITHING_TABLE_TEMPLATE, !visible); + screen.setSlotsHidden(ETSlotSemantics.SMITHING_TABLE_BASE, !visible); + screen.setSlotsHidden(ETSlotSemantics.SMITHING_TABLE_ADDITION, !visible); + screen.setSlotsHidden(ETSlotSemantics.SMITHING_TABLE_RESULT, !visible); + this.clearBtn.setVisibility(visible); + this.clearToPlayerInvBtn.setVisibility(visible); + } + + @Override + public void drawBackgroundLayer(GuiGraphics guiGraphics, Rect2i bounds, Point mouse) { + BG.dest(bounds.getX() + 8, bounds.getY() + bounds.getHeight() - 165).blit(guiGraphics); + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/panels/StoneCutterPanel.java b/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/panels/StoneCutterPanel.java new file mode 100644 index 0000000..d3caab6 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/panels/StoneCutterPanel.java @@ -0,0 +1,159 @@ +package me.myogoo.extendedterminal.client.screen.extendedterminal.gui.panels; + +import appeng.client.Point; +import appeng.client.gui.Tooltip; +import appeng.client.gui.WidgetContainer; +import appeng.client.gui.style.Blitter; +import appeng.client.gui.widgets.Scrollbar; +import me.myogoo.extendedterminal.client.screen.extendedterminal.ETTerminalScreen; +import me.myogoo.extendedterminal.client.screen.extendedterminal.gui.ETTerminalModePanel; +import me.myogoo.extendedterminal.menu.ETSlotSemantics; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.renderer.Rect2i; +import net.minecraft.client.resources.sounds.SimpleSoundInstance; +import net.minecraft.core.RegistryAccess; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.StonecutterRecipe; +import net.minecraft.world.level.block.Blocks; +import org.jetbrains.annotations.Nullable; + +import java.util.Objects; + +public class StoneCutterPanel extends ETTerminalModePanel { + private static final Blitter BG = Blitter.texture("guis/et_terminal_panel.png", 512, 512).src(0, 134, 159, 65); + private static final Blitter AE_BG = Blitter.texture("guis/pattern_modes.png").src(0, 140, 124, 66); + private static final Blitter BG_SLOT = AE_BG.copy().src(124, 140, 20, 22); + private static final Blitter BG_SLOT_SELECTED = AE_BG.copy().src(124, 162, 20, 22); + private static final Blitter BG_SLOT_HOVER = AE_BG.copy().src(124, 184, 20, 22); + + private static final int COLS = 4; + private static final int ROWS = 2; + + private final Scrollbar scrollbar; + + public StoneCutterPanel(ETTerminalScreen screen, WidgetContainer widgets) { + super(screen, widgets); + this.scrollbar = widgets.addScrollBar("stonecuttingPatternModeScrollbar", Scrollbar.SMALL); + this.scrollbar.setRange(0, 0, COLS); + this.scrollbar.setCaptureMouseWheel(false); + setVisible(false); + } + + @Override + public void updateBeforeRender() { + menu.updateStonecutterRecipes(); + var totalRows = (menu.getStoneCutterRecipes().size() + COLS - 1) / COLS; + this.scrollbar.setRange(0, totalRows - ROWS, ROWS); + } + + @Override + public ItemStack getIcon() { + return new ItemStack(Blocks.STONECUTTER); + } + + @Override + public boolean onMouseWheel(Point mousePos, double delta) { + return this.scrollbar.onMouseWheel(mousePos, delta); + } + + @Override + public void setVisible(boolean visible) { + super.setVisible(visible); + screen.setSlotsHidden(ETSlotSemantics.STONECUTTING_INPUT, !visible); + screen.setSlotsHidden(ETSlotSemantics.STONECUTTING_RESULT, !visible); + this.scrollbar.setVisible(visible); + } + + @Override + public void drawBackgroundLayer(GuiGraphics guiGraphics, Rect2i bounds, Point mouse) { + BG.dest(bounds.getX() + 8, bounds.getY() + bounds.getHeight() - 165).blit(guiGraphics); + drawRecipes(guiGraphics, bounds, mouse); + } + + @Override + public boolean onMouseDown(Point mousePos, int button) { + var recipe = getRecipeAt(mousePos); + if (recipe != null) { + menu.setStoneCutterRecipeId(recipe.getId()); + Minecraft.getInstance().getSoundManager() + .play(SimpleSoundInstance.forUI(SoundEvents.UI_STONECUTTER_SELECT_RECIPE, 1.0F)); + return true; + } + return false; + } + + @Nullable + @Override + public Tooltip getTooltip(int mouseX, int mouseY) { + var recipe = getRecipeAt(new Point(mouseX, mouseY)); + if (recipe != null) { + return new Tooltip(screen.getTerminalTooltip(recipe.getResultItem(getRegistryAccess()))); + } + return null; + } + + private RegistryAccess getRegistryAccess() { + return Objects.requireNonNull(Minecraft.getInstance().level).registryAccess(); + } + + private void drawRecipes(GuiGraphics guiGraphics, Rect2i bounds, Point mouse) { + var recipes = menu.getStoneCutterRecipes(); + int startIndex = this.scrollbar.getCurrentScroll() * COLS; + int endIndex = startIndex + ROWS * COLS; + var selectedRecipe = menu.getStoneCutterRecipeId(); + + for (int i = startIndex; i < endIndex && i < recipes.size(); i++) { + var slotBounds = getRecipeBounds(i - startIndex); + var recipe = recipes.get(i); + boolean selected = selectedRecipe != null && selectedRecipe.equals(recipe.getId()); + + Blitter blitter = BG_SLOT; + if (selected) { + blitter = BG_SLOT_SELECTED; + } else if (mouse.isIn(slotBounds)) { + blitter = BG_SLOT_HOVER; + } + + int renderX = bounds.getX() + slotBounds.getX(); + int renderY = bounds.getY() + slotBounds.getY(); + blitter.dest(renderX, renderY).blit(guiGraphics); + + var resultItem = recipe.getResultItem(getRegistryAccess()); + if (selected || mouse.isIn(slotBounds)) { + guiGraphics.renderItem(resultItem, renderX + 2, renderY + 3); + guiGraphics.renderItemDecorations(Minecraft.getInstance().font, resultItem, renderX + 2, renderY + 3); + } else { + guiGraphics.renderItem(resultItem, renderX + 2, renderY + 2); + guiGraphics.renderItemDecorations(Minecraft.getInstance().font, resultItem, renderX + 2, renderY + 2); + } + } + } + + @Nullable + private StonecutterRecipe getRecipeAt(Point point) { + var recipes = menu.getStoneCutterRecipes(); + if (recipes.isEmpty()) { + return null; + } + + int startIndex = this.scrollbar.getCurrentScroll() * COLS; + int endIndex = startIndex + COLS * ROWS; + for (int i = startIndex; i < endIndex && i < recipes.size(); i++) { + var slotBounds = getRecipeBounds(i - startIndex); + if (point.isIn(slotBounds)) { + return recipes.get(i); + } + } + return null; + } + + private Rect2i getRecipeBounds(int index) { + int col = index % COLS; + int row = index / COLS; + int slotX = this.x + 26 + col * BG_SLOT.getSrcWidth(); + int slotY = this.y + 12 + row * BG_SLOT.getSrcHeight(); + return new Rect2i(slotX, slotY, BG_SLOT.getSrcWidth(), BG_SLOT.getSrcHeight()); + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/wt/ETWTScreen.java b/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/wt/ETWTScreen.java new file mode 100644 index 0000000..43e3f86 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/wt/ETWTScreen.java @@ -0,0 +1,27 @@ +package me.myogoo.extendedterminal.client.screen.extendedterminal.wt; + +import appeng.client.gui.style.ScreenStyle; +import appeng.client.gui.widgets.BackgroundPanel; +import de.mari_023.ae2wtlib.wut.CycleTerminalButton; +import de.mari_023.ae2wtlib.wut.IUniversalTerminalCapable; +import me.myogoo.extendedterminal.client.screen.extendedterminal.ETTerminalScreen; +import me.myogoo.extendedterminal.me.host.ETWTHost; +import me.myogoo.extendedterminal.menu.extendedterminal.wt.ETWTMenu; +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.player.Inventory; + +public class ETWTScreen extends ETTerminalScreen implements IUniversalTerminalCapable { + public ETWTScreen(ETWTMenu menu, Inventory playerInventory, Component title, ScreenStyle style) { + super(menu, playerInventory, title, style); + + if (menu.isWUT()) { + addToLeftToolbar(new CycleTerminalButton(btn -> cycleTerminal())); + } + + widgets.add("singularityBackground", new BackgroundPanel(style.getImage("singularityBackground"))); + } + + public ETWTHost getHost() { + return (ETWTHost) this.menu.getHost(); + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/datagen/ETDataGen.java b/src/main/java/me/myogoo/extendedterminal/datagen/ETDataGen.java index 2a782ea..24d0081 100644 --- a/src/main/java/me/myogoo/extendedterminal/datagen/ETDataGen.java +++ b/src/main/java/me/myogoo/extendedterminal/datagen/ETDataGen.java @@ -3,7 +3,7 @@ import appeng.datagen.providers.localization.LocalizationProvider; import me.myogoo.extendedterminal.ExtendedTerminal; import me.myogoo.extendedterminal.datagen.provider.InscriberRecipeProvider; -import me.myogoo.extendedterminal.util.mod.ModIntegrationManager; +import me.myogoo.extendedterminal.init.ETModIntegration; import net.minecraft.core.RegistryAccess; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraftforge.data.event.GatherDataEvent; @@ -15,7 +15,7 @@ public class ETDataGen { @SubscribeEvent public static void onGatherData(GatherDataEvent event) { - ModIntegrationManager.initialize(); + ETModIntegration.initialize(); var registryAccess = RegistryAccess.fromRegistryOfRegistries(BuiltInRegistries.REGISTRY); var registries = new LocalizationProvider(event.getGenerator()); @@ -23,4 +23,4 @@ public static void onGatherData(GatherDataEvent event) { var pack = generator.getVanillaPack(true); pack.addProvider(InscriberRecipeProvider::new); } -} \ No newline at end of file +} diff --git a/src/main/java/me/myogoo/extendedterminal/datagen/condition/ETModCondition.java b/src/main/java/me/myogoo/extendedterminal/datagen/condition/ETModCondition.java index 1a3acf0..215ab8a 100644 --- a/src/main/java/me/myogoo/extendedterminal/datagen/condition/ETModCondition.java +++ b/src/main/java/me/myogoo/extendedterminal/datagen/condition/ETModCondition.java @@ -1,24 +1,18 @@ package me.myogoo.extendedterminal.datagen.condition; import me.myogoo.extendedterminal.ExtendedTerminal; -import me.myogoo.extendedterminal.util.mod.ModIntegrationManager; +import me.myogoo.myotus.util.mod.ModIntegrationManager; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.common.crafting.conditions.ICondition; -import org.jetbrains.annotations.Nullable; - -import java.lang.annotation.Annotation; public class ETModCondition implements ICondition { public static final String NAME = "et_mod"; public static final ResourceLocation ID = new ResourceLocation(ExtendedTerminal.MODID, NAME); - @Nullable - private Class modId = null; private final String modIdString; public ETModCondition(String modId) { this.modIdString = modId; - this.modId = ModIntegrationManager.getClass(modId); } @Override @@ -28,8 +22,8 @@ public ResourceLocation getID() { @Override public boolean test(IContext context) { - if(this.modId == null) return false; - return ModIntegrationManager.isLoaded(this.modId); + var annotationClass = ModIntegrationManager.getClass(this.modIdString); + return annotationClass != null && ModIntegrationManager.isLoaded(annotationClass); } public String getModId() { diff --git a/src/main/java/me/myogoo/extendedterminal/init/ETCondition.java b/src/main/java/me/myogoo/extendedterminal/init/ETCondition.java index 7ec219d..b798b82 100644 --- a/src/main/java/me/myogoo/extendedterminal/init/ETCondition.java +++ b/src/main/java/me/myogoo/extendedterminal/init/ETCondition.java @@ -9,6 +9,7 @@ @Mod.EventBusSubscriber(modid = ExtendedTerminal.MODID, bus = Mod.EventBusSubscriber.Bus.MOD) public class ETCondition { + private static boolean registered; @SubscribeEvent public static void onCommonFMLSetupEvent(FMLCommonSetupEvent event) { @@ -16,6 +17,10 @@ public static void onCommonFMLSetupEvent(FMLCommonSetupEvent event) { } public static void register() { + if (registered) { + return; + } + registered = true; CraftingHelper.register(ETModConditionSerializer.INSTANCE); } } diff --git a/src/main/java/me/myogoo/extendedterminal/init/ETCreativeTab.java b/src/main/java/me/myogoo/extendedterminal/init/ETCreativeTab.java index 2a174b7..07b51bf 100644 --- a/src/main/java/me/myogoo/extendedterminal/init/ETCreativeTab.java +++ b/src/main/java/me/myogoo/extendedterminal/init/ETCreativeTab.java @@ -3,6 +3,9 @@ import appeng.core.definitions.AEParts; import appeng.core.definitions.ItemDefinition; import me.myogoo.extendedterminal.ExtendedTerminal; +import me.myogoo.extendedterminal.init.wt.WTItems; +import me.myogoo.myotus.api.annotation.wt.AE2WTLib; +import me.myogoo.myotus.util.mod.ModIntegrationManager; import net.minecraft.core.registries.Registries; import net.minecraft.network.chat.Component; import net.minecraft.world.item.CreativeModeTab; @@ -19,7 +22,12 @@ public class ETCreativeTab { for (ItemDefinition item : ETItems.ITEMS) { output.accept(item.stack()); } + if (ModIntegrationManager.isLoaded(AE2WTLib.class)) { + for (ItemDefinition item : WTItems.WT_ITEMS) { + output.accept(item.stack()); + } + } }) .build()); } -} \ No newline at end of file +} diff --git a/src/main/java/me/myogoo/extendedterminal/init/ETMenus.java b/src/main/java/me/myogoo/extendedterminal/init/ETMenus.java index 9a01e4f..2c12d89 100644 --- a/src/main/java/me/myogoo/extendedterminal/init/ETMenus.java +++ b/src/main/java/me/myogoo/extendedterminal/init/ETMenus.java @@ -5,6 +5,7 @@ import me.myogoo.extendedterminal.menu.avaritiaNeo.NeoExtremeTerminalMenu; import me.myogoo.extendedterminal.menu.avaritiaRe.*; import me.myogoo.extendedterminal.menu.extendedcrafting.*; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; import net.minecraft.core.registries.Registries; import net.minecraft.world.inventory.MenuType; import net.minecraftforge.registries.DeferredRegister; @@ -14,6 +15,7 @@ public final class ETMenus { public static final DeferredRegister> REGISTER = DeferredRegister.create(Registries.MENU, AppEng.MOD_ID); + public static final Supplier> ET_TERMINAL = REGISTER.register(ETMenuType.ET_TERMINAL.getIdAsString(), () -> ETTerminalMenu.TYPE); public static final Supplier> BASIC_TERMINAL = REGISTER.register(ETMenuType.BASIC_TERMINAL.getIdAsString(), () -> BasicTerminalMenu.TYPE); public static final Supplier> ADVANCED_TERMINAL = REGISTER.register(ETMenuType.ADVANCED_TERMINAL.getIdAsString(), () -> AdvancedTerminalMenu.TYPE); public static final Supplier> ELITE_TERMINAL = REGISTER.register(ETMenuType.ELITE_TERMINAL.getIdAsString(), () -> EliteTerminalMenu.TYPE); diff --git a/src/main/java/me/myogoo/extendedterminal/init/ETModIntegration.java b/src/main/java/me/myogoo/extendedterminal/init/ETModIntegration.java new file mode 100644 index 0000000..072a1d9 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/init/ETModIntegration.java @@ -0,0 +1,28 @@ +package me.myogoo.extendedterminal.init; + +import me.myogoo.extendedterminal.api.ModAccessor; +import me.myogoo.myotus.api.MyotusAPI; +import me.myogoo.myotus.api.annotation.wt.AE2WTLib; + +public final class ETModIntegration { + private static boolean initialized; + + private ETModIntegration() { + } + + public static synchronized void initialize() { + if (initialized || !MyotusAPI.isInitialized()) { + return; + } + + initialized = true; + + var registrar = MyotusAPI.modRegistrar(); + registrar.registerLoadableMod(ModAccessor.ExtendedCrafting.class, "extendedcrafting", "*"); + registrar.registerLoadableMod(ModAccessor.EpicExCrafting.class, "extendedcrafting", + "Extended Crafting: Expanded", "*"); + registrar.registerLoadableMod(ModAccessor.ReAvaritia.class, "avaritia", "Re-Avaritia", "*"); + registrar.registerLoadableMod(ModAccessor.AvaritiaNeo.class, "avaritia", "Avaritia", "*"); + registrar.registerLoadableMod(AE2WTLib.class, "ae2wtlib", "*"); + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/init/ETNetwork.java b/src/main/java/me/myogoo/extendedterminal/init/ETNetwork.java index ac02289..d60995b 100644 --- a/src/main/java/me/myogoo/extendedterminal/init/ETNetwork.java +++ b/src/main/java/me/myogoo/extendedterminal/init/ETNetwork.java @@ -1,26 +1,38 @@ package me.myogoo.extendedterminal.init; -import me.myogoo.extendedterminal.ExtendedTerminal; import me.myogoo.extendedterminal.network.serverbound.ETFillCraftingGridFromRecipePacket; -import net.minecraft.resources.ResourceLocation; -import net.minecraftforge.network.NetworkRegistry; -import net.minecraftforge.network.simple.SimpleChannel; +import me.myogoo.extendedterminal.network.serverbound.ETFillSmithingGridFromRecipePacket; +import me.myogoo.extendedterminal.network.serverbound.ETFillStonecutterGridFromRecipePacket; +import me.myogoo.myotus.api.MyotusAPI; -public class ETNetwork { - private static final String PROTOCOL_VERSION = "1"; - public static final SimpleChannel INSTANCE = NetworkRegistry.newSimpleChannel( - new ResourceLocation(ExtendedTerminal.MODID, "main"), - () -> PROTOCOL_VERSION, - PROTOCOL_VERSION::equals, - PROTOCOL_VERSION::equals - ); +public final class ETNetwork { + public static final int TABLE_FILL_CRAFTING_GRID_PACKET_ID = 10000; + public static final int SMITHING_FILL_CRAFTING_GRID_PACKET_ID = 10001; + public static final int STONECUTTER_FILL_CRAFTING_GRID_PACKET_ID = 10002; - private static int packetId = 0; - private static int id() { - return packetId++; + private static boolean registered; + + private ETNetwork() { } - public static void register() { + public static synchronized void register() { + if (registered) { + return; + } + registered = true; + var network = MyotusAPI.network(); + network.registerServerbound(TABLE_FILL_CRAFTING_GRID_PACKET_ID, + ETFillCraftingGridFromRecipePacket.class, + ETFillCraftingGridFromRecipePacket::new, + ETFillCraftingGridFromRecipePacket::handle); + network.registerServerbound(SMITHING_FILL_CRAFTING_GRID_PACKET_ID, + ETFillSmithingGridFromRecipePacket.class, + ETFillSmithingGridFromRecipePacket::new, + ETFillSmithingGridFromRecipePacket::handle); + network.registerServerbound(STONECUTTER_FILL_CRAFTING_GRID_PACKET_ID, + ETFillStonecutterGridFromRecipePacket.class, + ETFillStonecutterGridFromRecipePacket::new, + ETFillStonecutterGridFromRecipePacket::handle); } } diff --git a/src/main/java/me/myogoo/extendedterminal/init/ETParts.java b/src/main/java/me/myogoo/extendedterminal/init/ETParts.java index 2b376a7..c9648ec 100644 --- a/src/main/java/me/myogoo/extendedterminal/init/ETParts.java +++ b/src/main/java/me/myogoo/extendedterminal/init/ETParts.java @@ -16,6 +16,7 @@ import me.myogoo.extendedterminal.part.avaritiaRe.ExtremeTerminalPart; import me.myogoo.extendedterminal.part.avaritiaRe.NetherTerminalPart; import me.myogoo.extendedterminal.part.avaritiaRe.SculkTerminalPart; +import me.myogoo.extendedterminal.part.extendedterminal.ETTerminalPart; import me.myogoo.extendedterminal.part.extendedcrafting.*; import net.minecraft.core.registries.Registries; import net.minecraft.world.item.Item; @@ -33,6 +34,7 @@ public class ETParts { public static final List>> PARTS = new ArrayList<>(); public static final List>> TERMINAL_PARTS = new ArrayList<>(); + public static final ItemDefinition> ET_TERMINAL_PART = createTerminalPart(ETMenuType.ET_TERMINAL, ETTerminalPart.class, ETTerminalPart::new); public static final ItemDefinition> BASIC_TERMINAL_PART = createExtendedCraftingPart(ETMenuType.BASIC_TERMINAL, BasicExtendedTerminalPart.class, BasicExtendedTerminalPart::new); public static final ItemDefinition> ADVANCED_TERMINAL_PART = createExtendedCraftingPart(ETMenuType.ADVANCED_TERMINAL, AdvancedTerminalPart.class, AdvancedTerminalPart::new); public static final ItemDefinition> ELITE_TERMINAL_PART = createExtendedCraftingPart(ETMenuType.ELITE_TERMINAL, EliteTerminalPart.class, EliteTerminalPart::new); diff --git a/src/main/java/me/myogoo/extendedterminal/init/wt/WTInit.java b/src/main/java/me/myogoo/extendedterminal/init/wt/WTInit.java new file mode 100644 index 0000000..9c3cc75 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/init/wt/WTInit.java @@ -0,0 +1,59 @@ +package me.myogoo.extendedterminal.init.wt; + +import appeng.api.features.GridLinkables; +import appeng.items.tools.powered.WirelessTerminalItem; +import de.mari_023.ae2wtlib.terminal.ItemWT; +import de.mari_023.ae2wtlib.wut.WUTHandler; +import me.myogoo.extendedterminal.ExtendedTerminal; +import me.myogoo.extendedterminal.me.host.ETWTHost; +import me.myogoo.extendedterminal.menu.ETMenuType; +import me.myogoo.extendedterminal.menu.extendedterminal.wt.ETWTMenu; +import me.myogoo.myotus.api.annotation.wt.AE2WTLib; +import me.myogoo.myotus.util.mod.ModIntegrationManager; +import net.minecraft.core.registries.Registries; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.common.capabilities.RegisterCapabilitiesEvent; +import net.minecraftforge.registries.RegisterEvent; + +@Mod.EventBusSubscriber(modid = ExtendedTerminal.MODID, bus = Mod.EventBusSubscriber.Bus.MOD) +public final class WTInit { + private WTInit() { + } + + @SubscribeEvent + public static void init(RegisterEvent event) { + WTItems.register(); + WTMenus.register(); + + if (!event.getRegistryKey().equals(Registries.ITEM)) { + return; + } + + if (!ModIntegrationManager.isLoaded(AE2WTLib.class)) { + ExtendedTerminal.LOGGER.warn("[ET] AE2WTLib not loaded, skipping wireless terminal registration"); + return; + } + + if (WTItems.WIRELESS_ET_TERMINAL == null) { + ExtendedTerminal.LOGGER.warn("[ET] WIRELESS_ET_TERMINAL is null, skipping wireless terminal registration"); + return; + } + + var terminal = (ItemWT) WTItems.WIRELESS_ET_TERMINAL.asItem(); + WUTHandler.addTerminal( + ETMenuType.ET_TERMINAL.getWTIdAsString(), + terminal::tryOpen, + ETWTHost::new, + ETWTMenu.TYPE, + terminal, + ETMenuType.ET_TERMINAL.getWTIdAsString(), + "item.extendedterminal.wireless_et_terminal"); + GridLinkables.register(terminal, WirelessTerminalItem.LINKABLE_HANDLER); + } + + @SubscribeEvent + public static void initCapabilities(RegisterCapabilitiesEvent event) { + // WT-specific capability wiring is handled by AE2WTLib when present. + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/init/wt/WTItems.java b/src/main/java/me/myogoo/extendedterminal/init/wt/WTItems.java new file mode 100644 index 0000000..c31ab46 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/init/wt/WTItems.java @@ -0,0 +1,41 @@ +package me.myogoo.extendedterminal.init.wt; + +import appeng.core.definitions.ItemDefinition; +import me.myogoo.extendedterminal.ExtendedTerminal; +import me.myogoo.extendedterminal.init.ETItems; +import me.myogoo.extendedterminal.item.wtitem.ETWTItem; +import me.myogoo.myotus.api.annotation.wt.AE2WTLib; +import me.myogoo.myotus.util.mod.ModIntegrationManager; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Item; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Function; + +public final class WTItems { + public static final List> WT_ITEMS = new ArrayList<>(); + + public static final ItemDefinition WIRELESS_ET_TERMINAL = createWTItem( + "Extended Wireless Terminal", + ExtendedTerminal.makeId("wireless_et_terminal"), + ETWTItem::new + ); + + private WTItems() { + } + + private static ItemDefinition createWTItem(String name, ResourceLocation id, + Function itemFactory) { + if (!ModIntegrationManager.isLoaded(AE2WTLib.class)) { + return null; + } + + var definition = ETItems.createItem(name, id, itemFactory); + WT_ITEMS.add(definition); + return definition; + } + + public static void register() { + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/init/wt/WTMenus.java b/src/main/java/me/myogoo/extendedterminal/init/wt/WTMenus.java new file mode 100644 index 0000000..ce76449 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/init/wt/WTMenus.java @@ -0,0 +1,22 @@ +package me.myogoo.extendedterminal.init.wt; + +import me.myogoo.extendedterminal.menu.ETMenuType; +import me.myogoo.extendedterminal.menu.extendedterminal.wt.ETWTMenu; +import net.minecraft.world.inventory.MenuType; + +import java.util.function.Supplier; + +import static me.myogoo.extendedterminal.init.ETMenus.REGISTER; + +public final class WTMenus { + public static final Supplier> ET_WT = REGISTER.register( + ETMenuType.ET_TERMINAL.getWTIdAsString(), + () -> ETWTMenu.TYPE + ); + + private WTMenus() { + } + + public static void register() { + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/integration/ItemListModLoadHelper.java b/src/main/java/me/myogoo/extendedterminal/integration/ItemListModLoadHelper.java index a8c44c7..beba604 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/ItemListModLoadHelper.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/ItemListModLoadHelper.java @@ -1,10 +1,10 @@ package me.myogoo.extendedterminal.integration; import me.myogoo.extendedterminal.ExtendedTerminal; -import me.myogoo.extendedterminal.api.SubscribeLoadEvent; import me.myogoo.extendedterminal.util.SafeClass; import me.myogoo.extendedterminal.util.mod.AnnotationScanner; -import me.myogoo.extendedterminal.util.mod.ModIntegrationManager; +import me.myogoo.myotus.api.annotation.MyotusSubscriber; +import me.myogoo.myotus.util.mod.ModIntegrationManager; import org.objectweb.asm.Type; import java.lang.reflect.InvocationTargetException; @@ -23,7 +23,10 @@ public static void invokeItemListMod( .stream() .filter(a -> a.annotationType().equals(markerAnnotation)) .map(a -> SafeClass.forType(a.clazz())) - .filter(c -> c.getDeclaredAnnotations().length == 0 || Arrays.stream(c.getDeclaredAnnotations()).anyMatch(a -> ModIntegrationManager.isLoaded(a.annotationType()))) + .filter(c -> c != null + && (c.getDeclaredAnnotations().length == 0 + || Arrays.stream(c.getDeclaredAnnotations()) + .allMatch(a -> ModIntegrationManager.isLoaded(a.annotationType())))) .forEach(clazz -> invokeMethod(clazz,parameterType, parameter)); } @@ -43,16 +46,16 @@ private static void invokeMethod(Class clazz, Class parameterType, R r try { Method[] methods = clazz.getDeclaredMethods(); for(var method: methods) { - if(method.isAnnotationPresent(SubscribeLoadEvent.class)) { + if(method.isAnnotationPresent(MyotusSubscriber.class)) { if(!Modifier.isStatic(method.getModifiers())) { - ExtendedTerminal.LOGGER.warn("Method {} in class {} is annotated with @SubscribeLoadEvent but is not static.", method.getName(), clazz.getName()); + ExtendedTerminal.LOGGER.warn("Method {} in class {} is annotated as a subscriber but is not static.", method.getName(), clazz.getName()); continue; } if(method.getParameterCount() == 1 && method.getParameterTypes()[0] == parameterType) { method.setAccessible(true); method.invoke(null, registration); } else { - ExtendedTerminal.LOGGER.warn("Method {} in class {} is annotated with @SubscribeLoadEvent but does not have the correct parameters.", method.getName(), clazz.getName()); + ExtendedTerminal.LOGGER.warn("Method {} in class {} is annotated as a subscriber but does not have the correct parameters.", method.getName(), clazz.getName()); } } } diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/avaritiaNeo/AVNeoRecipeHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/avaritiaNeo/AVNeoRecipeHandler.java index 71cc357..cb746dd 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/emi/avaritiaNeo/AVNeoRecipeHandler.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/avaritiaNeo/AVNeoRecipeHandler.java @@ -3,7 +3,7 @@ import dev.emi.emi.api.EmiRegistry; import dev.emi.emi.api.stack.EmiStack; import me.myogoo.extendedterminal.api.ModAccessor; -import me.myogoo.extendedterminal.api.SubscribeLoadEvent; +import me.myogoo.myotus.api.annotation.MyotusSubscriber; import me.myogoo.extendedterminal.api.integration.emi.ETEmiRecipeHandler; import me.myogoo.extendedterminal.init.ETParts; import me.myogoo.extendedterminal.integration.emi.avaritiaNeo.handler.AVNeoEmiRecipeHandler; @@ -14,7 +14,7 @@ @ModAccessor.AvaritiaNeo @ETEmiRecipeHandler public class AVNeoRecipeHandler { - @SubscribeLoadEvent + @MyotusSubscriber public static void init(EmiRegistry registry) { registry.addRecipeHandler(NeoExtremeTerminalMenu.TYPE, new AVNeoEmiRecipeHandler(AvaritiaEMIPlugin.EXTREME_CRAFTING, NeoExtremeTerminalMenu.class, ETMenuType.NEO_EXTREME_TERMINAL)); } diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/avaritiaNeo/AVNeoWorkstation.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/avaritiaNeo/AVNeoWorkstation.java index 7f379a8..7c17619 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/emi/avaritiaNeo/AVNeoWorkstation.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/avaritiaNeo/AVNeoWorkstation.java @@ -3,7 +3,7 @@ import dev.emi.emi.api.EmiRegistry; import dev.emi.emi.api.stack.EmiStack; import me.myogoo.extendedterminal.api.ModAccessor; -import me.myogoo.extendedterminal.api.SubscribeLoadEvent; +import me.myogoo.myotus.api.annotation.MyotusSubscriber; import me.myogoo.extendedterminal.api.integration.emi.ETEmiWorkstation; import me.myogoo.extendedterminal.init.ETParts; import net.byAqua3.avaritia.compat.emi.AvaritiaEMIPlugin; @@ -11,7 +11,7 @@ @ModAccessor.AvaritiaNeo @ETEmiWorkstation public class AVNeoWorkstation { - @SubscribeLoadEvent + @MyotusSubscriber public static void init(EmiRegistry registry) { registry.addWorkstation(AvaritiaEMIPlugin.EXTREME_CRAFTING, EmiStack.of(ETParts.NEO_EXTREME_TERMINAL_PART)); } diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/avaritiaRe/AVRecipeHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/avaritiaRe/AVRecipeHandler.java index df8033c..a12dbd1 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/emi/avaritiaRe/AVRecipeHandler.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/avaritiaRe/AVRecipeHandler.java @@ -6,7 +6,7 @@ import committee.nova.mods.avaritia.init.compat.emi.category.tables.SculkCraftingTableCategory; import dev.emi.emi.api.EmiRegistry; import me.myogoo.extendedterminal.api.ModAccessor; -import me.myogoo.extendedterminal.api.SubscribeLoadEvent; +import me.myogoo.myotus.api.annotation.MyotusSubscriber; import me.myogoo.extendedterminal.api.integration.emi.ETEmiRecipeHandler; import me.myogoo.extendedterminal.integration.emi.avaritiaRe.handler.AVTerminalRecipeHandler; import me.myogoo.extendedterminal.menu.ETMenuType; @@ -19,7 +19,7 @@ @ModAccessor.ReAvaritia @ETEmiRecipeHandler public class AVRecipeHandler { - @SubscribeLoadEvent + @MyotusSubscriber public static void init(EmiRegistry registry) { if(!ModList.get().isLoaded("jei")) { registry.addRecipeHandler(SculkTerminalMenu.TYPE, new AVTerminalRecipeHandler<>(SculkCraftingTableCategory.CATEGORY, SculkTerminalMenu.class, ETMenuType.SCULK_TERMINAL)); diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/avaritiaRe/AVWorkstation.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/avaritiaRe/AVWorkstation.java index d91ea64..ed7e6af 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/emi/avaritiaRe/AVWorkstation.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/avaritiaRe/AVWorkstation.java @@ -7,7 +7,7 @@ import dev.emi.emi.api.EmiRegistry; import dev.emi.emi.api.stack.EmiStack; import me.myogoo.extendedterminal.api.ModAccessor; -import me.myogoo.extendedterminal.api.SubscribeLoadEvent; +import me.myogoo.myotus.api.annotation.MyotusSubscriber; import me.myogoo.extendedterminal.api.integration.emi.ETEmiWorkstation; import me.myogoo.extendedterminal.init.ETParts; import net.minecraftforge.fml.ModList; @@ -15,7 +15,7 @@ @ModAccessor.ReAvaritia @ETEmiWorkstation public class AVWorkstation { - @SubscribeLoadEvent + @MyotusSubscriber public static void init(EmiRegistry registry) { if(!ModList.get().isLoaded("jei")) { registry.addWorkstation(SculkCraftingTableCategory.CATEGORY, EmiStack.of(ETParts.SCULK_TERMINAL_PART)); diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/ETRecipeHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/ETRecipeHandler.java new file mode 100644 index 0000000..6d88276 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/ETRecipeHandler.java @@ -0,0 +1,31 @@ +package me.myogoo.extendedterminal.integration.emi.extendedterminal; + +import dev.emi.emi.api.EmiRegistry; +import me.myogoo.extendedterminal.api.integration.emi.ETEmiRecipeHandler; +import me.myogoo.extendedterminal.config.ExtendedTerminalConfig; +import me.myogoo.extendedterminal.integration.emi.extendedterminal.handler.ETCraftingRecipeHandler; +import me.myogoo.extendedterminal.integration.emi.extendedterminal.handler.ETSmithingRecipeHandler; +import me.myogoo.extendedterminal.integration.emi.extendedterminal.handler.ETStonecutterRecipeHandler; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; +import me.myogoo.myotus.api.annotation.MyotusSubscriber; + +@ETEmiRecipeHandler +public class ETRecipeHandler { + @MyotusSubscriber + public static void init(EmiRegistry registry) { + var config = ExtendedTerminalConfig.INSTANCE.getExtendedTerminalConfig(); + if (!config.enableTerminal()) { + return; + } + + if (config.enableCraftingPanel()) { + registry.addRecipeHandler(ETTerminalMenu.TYPE, new ETCraftingRecipeHandler()); + } + if (config.enableSmithingPanel()) { + registry.addRecipeHandler(ETTerminalMenu.TYPE, new ETSmithingRecipeHandler()); + } + if (config.enableStonecutterPanel()) { + registry.addRecipeHandler(ETTerminalMenu.TYPE, new ETStonecutterRecipeHandler()); + } + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/ETWorkstation.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/ETWorkstation.java new file mode 100644 index 0000000..f08f55e --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/ETWorkstation.java @@ -0,0 +1,19 @@ +package me.myogoo.extendedterminal.integration.emi.extendedterminal; + +import dev.emi.emi.api.EmiRegistry; +import dev.emi.emi.api.recipe.VanillaEmiRecipeCategories; +import dev.emi.emi.api.stack.EmiStack; +import me.myogoo.extendedterminal.api.integration.emi.ETEmiWorkstation; +import me.myogoo.extendedterminal.init.ETParts; +import me.myogoo.myotus.api.annotation.MyotusSubscriber; + +@ETEmiWorkstation +public class ETWorkstation { + @MyotusSubscriber + public static void init(EmiRegistry registry) { + registry.addWorkstation(VanillaEmiRecipeCategories.CRAFTING, EmiStack.of(ETParts.ET_TERMINAL_PART)); + registry.addWorkstation(VanillaEmiRecipeCategories.SMITHING, EmiStack.of(ETParts.ET_TERMINAL_PART)); + registry.addWorkstation(VanillaEmiRecipeCategories.STONECUTTING, EmiStack.of(ETParts.ET_TERMINAL_PART)); + registry.addWorkstation(VanillaEmiRecipeCategories.ANVIL_REPAIRING, EmiStack.of(ETParts.ET_TERMINAL_PART)); + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/AbstractETRecipeHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/AbstractETRecipeHandler.java new file mode 100644 index 0000000..8ec79b2 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/AbstractETRecipeHandler.java @@ -0,0 +1,83 @@ +package me.myogoo.extendedterminal.integration.emi.extendedterminal.handler; + +import appeng.menu.SlotSemantics; +import dev.emi.emi.api.recipe.EmiPlayerInventory; +import dev.emi.emi.api.recipe.EmiRecipe; +import dev.emi.emi.api.recipe.handler.EmiCraftContext; +import dev.emi.emi.api.recipe.handler.StandardRecipeHandler; +import dev.emi.emi.api.stack.EmiStack; +import me.myogoo.extendedterminal.menu.ETSlotSemantics; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.Recipe; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public abstract class AbstractETRecipeHandler implements StandardRecipeHandler { + @Override + public List getInputSources(T menu) { + var slots = new ArrayList(); + slots.addAll(menu.getSlots(SlotSemantics.PLAYER_HOTBAR)); + slots.addAll(menu.getSlots(SlotSemantics.PLAYER_INVENTORY)); + slots.addAll(menu.getSlots(menu.getCraftingGridSlotSemantic())); + slots.addAll(menu.getSlots(ETSlotSemantics.SMITHING_TABLE_TEMPLATE)); + slots.addAll(menu.getSlots(ETSlotSemantics.SMITHING_TABLE_BASE)); + slots.addAll(menu.getSlots(ETSlotSemantics.SMITHING_TABLE_ADDITION)); + slots.addAll(menu.getSlots(ETSlotSemantics.STONECUTTING_INPUT)); + return slots; + } + + @Override + public EmiPlayerInventory getInventory(AbstractContainerScreen screen) { + var list = new ArrayList(); + for (Slot slot : getInputSources(screen.getMenu())) { + list.add(EmiStack.of(slot.getItem())); + } + return new EmiPlayerInventory(list); + } + + @Override + public boolean canCraft(EmiRecipe recipe, EmiCraftContext context) { + return transferRecipe(recipe, context, false); + } + + @Override + public boolean craft(EmiRecipe recipe, EmiCraftContext context) { + return transferRecipe(recipe, context, true); + } + + private boolean transferRecipe(EmiRecipe emiRecipe, EmiCraftContext context, boolean doTransfer) { + var menu = context.getScreenHandler(); + if (menu == null) { + return false; + } + + var recipe = emiRecipe.getBackingRecipe(); + if (!supportsRecipe(recipe, emiRecipe)) { + return false; + } + + var slotToIngredientMap = getGuiSlotToIngredientMap(menu, recipe); + if (!slotToIngredientMap.isEmpty() + && menu.findMissingIngredients(slotToIngredientMap).missingSlots().size() == slotToIngredientMap.size()) { + return false; + } + + if (doTransfer) { + performTransfer(menu, recipe, AbstractContainerScreen.hasControlDown()); + Minecraft.getInstance().setScreen(context.getScreen()); + } + return true; + } + + protected abstract boolean supportsRecipe(Recipe recipe, EmiRecipe emiRecipe); + + protected abstract Map getGuiSlotToIngredientMap(T menu, Recipe recipe); + + protected abstract void performTransfer(T menu, Recipe recipe, boolean craftMissing); +} diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETCraftingRecipeHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETCraftingRecipeHandler.java new file mode 100644 index 0000000..0a7ca5d --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETCraftingRecipeHandler.java @@ -0,0 +1,45 @@ +package me.myogoo.extendedterminal.integration.emi.extendedterminal.handler; + +import dev.emi.emi.api.recipe.EmiRecipe; +import dev.emi.emi.api.recipe.VanillaEmiRecipeCategories; +import me.myogoo.extendedterminal.integration.module.extendedterminal.ETCraftingRecipeTransferHelper; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.crafting.CraftingRecipe; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.Recipe; + +import java.util.List; +import java.util.Map; + +public class ETCraftingRecipeHandler extends AbstractETRecipeHandler { + @Override + public boolean supportsRecipe(EmiRecipe recipe) { + return recipe.getCategory().equals(VanillaEmiRecipeCategories.CRAFTING); + } + + @Override + public List getCraftingSlots(T menu) { + return menu.getSlots(menu.getCraftingGridSlotSemantic()); + } + + @Override + public Slot getOutputSlot(T menu) { + return menu.getSlots(menu.getOutputSlotSemantic()).get(0); + } + + @Override + protected boolean supportsRecipe(Recipe recipe, EmiRecipe emiRecipe) { + return recipe instanceof CraftingRecipe && emiRecipe.getCategory().equals(VanillaEmiRecipeCategories.CRAFTING); + } + + @Override + protected Map getGuiSlotToIngredientMap(T menu, Recipe recipe) { + return ETCraftingRecipeTransferHelper.getGuiSlotToIngredientMap(menu, (CraftingRecipe) recipe); + } + + @Override + protected void performTransfer(T menu, Recipe recipe, boolean craftMissing) { + ETCraftingRecipeTransferHelper.performTransfer(menu, (CraftingRecipe) recipe, null, craftMissing); + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETSmithingRecipeHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETSmithingRecipeHandler.java new file mode 100644 index 0000000..f2c07f1 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETSmithingRecipeHandler.java @@ -0,0 +1,51 @@ +package me.myogoo.extendedterminal.integration.emi.extendedterminal.handler; + +import dev.emi.emi.api.recipe.EmiRecipe; +import dev.emi.emi.api.recipe.VanillaEmiRecipeCategories; +import me.myogoo.extendedterminal.integration.module.extendedterminal.ETSmithingRecipeTransferHelper; +import me.myogoo.extendedterminal.menu.ETSlotSemantics; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.Recipe; +import net.minecraft.world.item.crafting.SmithingRecipe; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class ETSmithingRecipeHandler extends AbstractETRecipeHandler { + @Override + public boolean supportsRecipe(EmiRecipe recipe) { + return recipe.getCategory().equals(VanillaEmiRecipeCategories.SMITHING); + } + + @Override + public List getCraftingSlots(T menu) { + var slots = new ArrayList(); + slots.addAll(menu.getSlots(ETSlotSemantics.SMITHING_TABLE_TEMPLATE)); + slots.addAll(menu.getSlots(ETSlotSemantics.SMITHING_TABLE_BASE)); + slots.addAll(menu.getSlots(ETSlotSemantics.SMITHING_TABLE_ADDITION)); + return slots; + } + + @Override + public Slot getOutputSlot(T menu) { + return menu.getSlots(ETSlotSemantics.SMITHING_TABLE_RESULT).get(0); + } + + @Override + protected boolean supportsRecipe(Recipe recipe, EmiRecipe emiRecipe) { + return recipe instanceof SmithingRecipe && emiRecipe.getCategory().equals(VanillaEmiRecipeCategories.SMITHING); + } + + @Override + protected Map getGuiSlotToIngredientMap(T menu, Recipe recipe) { + return ETSmithingRecipeTransferHelper.getGuiSlotToIngredientMap((SmithingRecipe) recipe); + } + + @Override + protected void performTransfer(T menu, Recipe recipe, boolean craftMissing) { + ETSmithingRecipeTransferHelper.performTransfer(menu, (SmithingRecipe) recipe, craftMissing); + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETStonecutterRecipeHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETStonecutterRecipeHandler.java new file mode 100644 index 0000000..c260236 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETStonecutterRecipeHandler.java @@ -0,0 +1,47 @@ +package me.myogoo.extendedterminal.integration.emi.extendedterminal.handler; + +import dev.emi.emi.api.recipe.EmiRecipe; +import dev.emi.emi.api.recipe.VanillaEmiRecipeCategories; +import me.myogoo.extendedterminal.integration.module.extendedterminal.ETStoneCutterRecipeTransferHelper; +import me.myogoo.extendedterminal.menu.ETSlotSemantics; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.Recipe; +import net.minecraft.world.item.crafting.StonecutterRecipe; + +import java.util.List; +import java.util.Map; + +public class ETStonecutterRecipeHandler extends AbstractETRecipeHandler { + @Override + public boolean supportsRecipe(EmiRecipe recipe) { + return recipe.getCategory().equals(VanillaEmiRecipeCategories.STONECUTTING); + } + + @Override + public List getCraftingSlots(T menu) { + return menu.getSlots(ETSlotSemantics.STONECUTTING_INPUT); + } + + @Override + public Slot getOutputSlot(T menu) { + return menu.getSlots(ETSlotSemantics.STONECUTTING_RESULT).get(0); + } + + @Override + protected boolean supportsRecipe(Recipe recipe, EmiRecipe emiRecipe) { + return recipe instanceof StonecutterRecipe + && emiRecipe.getCategory().equals(VanillaEmiRecipeCategories.STONECUTTING); + } + + @Override + protected Map getGuiSlotToIngredientMap(T menu, Recipe recipe) { + return ETStoneCutterRecipeTransferHelper.getGuiSlotToIngredientMap((StonecutterRecipe) recipe); + } + + @Override + protected void performTransfer(T menu, Recipe recipe, boolean craftMissing) { + ETStoneCutterRecipeTransferHelper.performTransfer(menu, (StonecutterRecipe) recipe, craftMissing); + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/wt/ETWTRecipeCategory.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/wt/ETWTRecipeCategory.java new file mode 100644 index 0000000..c6a1dac --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/wt/ETWTRecipeCategory.java @@ -0,0 +1,21 @@ +package me.myogoo.extendedterminal.integration.emi.extendedterminal.wt; + +import dev.emi.emi.api.EmiRegistry; +import dev.emi.emi.api.recipe.VanillaEmiRecipeCategories; +import dev.emi.emi.api.stack.EmiStack; +import me.myogoo.extendedterminal.api.integration.emi.ETEmiWorkstation; +import me.myogoo.extendedterminal.init.wt.WTItems; +import me.myogoo.myotus.api.annotation.MyotusSubscriber; +import me.myogoo.myotus.api.annotation.wt.AE2WTLib; + +@ETEmiWorkstation +@AE2WTLib +public class ETWTRecipeCategory { + @MyotusSubscriber + public static void init(EmiRegistry registry) { + registry.addWorkstation(VanillaEmiRecipeCategories.CRAFTING, EmiStack.of(WTItems.WIRELESS_ET_TERMINAL.asItem())); + registry.addWorkstation(VanillaEmiRecipeCategories.SMITHING, EmiStack.of(WTItems.WIRELESS_ET_TERMINAL.asItem())); + registry.addWorkstation(VanillaEmiRecipeCategories.STONECUTTING, EmiStack.of(WTItems.WIRELESS_ET_TERMINAL.asItem())); + registry.addWorkstation(VanillaEmiRecipeCategories.ANVIL_REPAIRING, EmiStack.of(WTItems.WIRELESS_ET_TERMINAL.asItem())); + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/wt/ETWTRecipeHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/wt/ETWTRecipeHandler.java new file mode 100644 index 0000000..cf0ac2e --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/wt/ETWTRecipeHandler.java @@ -0,0 +1,21 @@ +package me.myogoo.extendedterminal.integration.emi.extendedterminal.wt; + +import dev.emi.emi.api.EmiRegistry; +import me.myogoo.extendedterminal.api.integration.emi.ETEmiRecipeHandler; +import me.myogoo.extendedterminal.integration.emi.extendedterminal.handler.ETCraftingRecipeHandler; +import me.myogoo.extendedterminal.integration.emi.extendedterminal.handler.ETSmithingRecipeHandler; +import me.myogoo.extendedterminal.integration.emi.extendedterminal.handler.ETStonecutterRecipeHandler; +import me.myogoo.extendedterminal.menu.extendedterminal.wt.ETWTMenu; +import me.myogoo.myotus.api.annotation.MyotusSubscriber; +import me.myogoo.myotus.api.annotation.wt.AE2WTLib; + +@ETEmiRecipeHandler +@AE2WTLib +public class ETWTRecipeHandler { + @MyotusSubscriber + public static void init(EmiRegistry registry) { + registry.addRecipeHandler(ETWTMenu.TYPE, new ETCraftingRecipeHandler<>()); + registry.addRecipeHandler(ETWTMenu.TYPE, new ETSmithingRecipeHandler<>()); + registry.addRecipeHandler(ETWTMenu.TYPE, new ETStonecutterRecipeHandler<>()); + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/handler/AbstractTableRecipeHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/handler/AbstractTableRecipeHandler.java index a55c4f0..23edb49 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/emi/handler/AbstractTableRecipeHandler.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/handler/AbstractTableRecipeHandler.java @@ -3,7 +3,6 @@ import appeng.api.stacks.AEKey; import appeng.api.stacks.GenericStack; import appeng.core.AEConfig; -import appeng.core.sync.network.NetworkHandler; import appeng.integration.modules.emi.EmiStackHelper; import appeng.integration.modules.jeirei.TransferHelper; import appeng.menu.AEBaseMenu; @@ -22,6 +21,7 @@ import me.myogoo.extendedterminal.api.adapter.recipe.ITableRecipeAdapter; import me.myogoo.extendedterminal.menu.ETTerminalBaseMenu; import me.myogoo.extendedterminal.network.serverbound.ETFillCraftingGridFromRecipePacket; +import me.myogoo.myotus.api.MyotusAPI; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; @@ -375,7 +375,7 @@ protected void performTransfer(T menu, ResourceLocation recipeId, ITableRecipeAd } var message = new ETFillCraftingGridFromRecipePacket(recipe.recipeId(), templateItems, craftMissing, recipeWidth, recipeHeight); - NetworkHandler.instance().sendToServer(message); + MyotusAPI.network().sendToServer(message); } } diff --git a/src/main/java/me/myogoo/extendedterminal/integration/guideme/ConditionTag.java b/src/main/java/me/myogoo/extendedterminal/integration/guideme/ConditionTag.java index 3ebd8b9..8648ae6 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/guideme/ConditionTag.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/guideme/ConditionTag.java @@ -7,7 +7,7 @@ import guideme.document.flow.LytFlowText; import guideme.libs.mdast.mdx.model.MdxJsxFlowElement; import guideme.style.TextStyle; -import me.myogoo.extendedterminal.util.mod.SupportedMod; +import me.myogoo.myotus.util.mod.ModIntegrationManager; import java.util.Set; @@ -19,31 +19,34 @@ public void compileBlockContext(PageCompiler compiler, LytBlockContainer parent, if (condition.isEmpty()) { compiler.compileBlockContext(el, parent); } else { - try { - var mod = SupportedMod.valueOf(condition); - if (mod.isLoaded()) { - compiler.compileBlockContext(el, parent); - } else { - if (silently.equals("true")) { - return; - } - var heading = new LytHeading(); - var frontText = new LytFlowText(); - frontText.setText("This content is hidden because the mod "); - var boldText = new LytFlowText(); - boldText.setStyle(TextStyle.builder().bold(true).build()); - boldText.setText(mod.name()); - var endText = new LytFlowText(); - endText.setText(" is not loaded."); - heading.setDepth(2); - heading.append(frontText); - heading.append(boldText); - heading.append(endText); - parent.append(heading); - } - } catch (IllegalArgumentException e) { + var annotationClass = ModIntegrationManager.getClass(condition); + if (annotationClass == null) { parent.appendError(compiler, condition + "is not loaded", el); + return; } + + if (ModIntegrationManager.isLoaded(annotationClass)) { + compiler.compileBlockContext(el, parent); + return; + } + + if (silently.equals("true")) { + return; + } + + var heading = new LytHeading(); + var frontText = new LytFlowText(); + frontText.setText("This content is hidden because the mod "); + var boldText = new LytFlowText(); + boldText.setStyle(TextStyle.builder().bold(true).build()); + boldText.setText(condition); + var endText = new LytFlowText(); + endText.setText(" is not loaded."); + heading.setDepth(2); + heading.append(frontText); + heading.append(boldText); + heading.append(endText); + parent.append(heading); } } diff --git a/src/main/java/me/myogoo/extendedterminal/integration/jei/avaritiaNeo/AVNeoGuiHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/jei/avaritiaNeo/AVNeoGuiHandler.java index 7a3fa55..8880f13 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/jei/avaritiaNeo/AVNeoGuiHandler.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/jei/avaritiaNeo/AVNeoGuiHandler.java @@ -1,7 +1,7 @@ package me.myogoo.extendedterminal.integration.jei.avaritiaNeo; import me.myogoo.extendedterminal.api.ModAccessor; -import me.myogoo.extendedterminal.api.SubscribeLoadEvent; +import me.myogoo.myotus.api.annotation.MyotusSubscriber; import me.myogoo.extendedterminal.api.integration.jei.ETJeiGuiHandler; import me.myogoo.extendedterminal.client.screen.avaritiaNeo.NeoExtremeTerminalScreen; import me.myogoo.extendedterminal.integration.jei.handler.JeiTableGuiHandler; @@ -11,7 +11,7 @@ @ETJeiGuiHandler @ModAccessor.AvaritiaNeo public class AVNeoGuiHandler { - @SubscribeLoadEvent + @MyotusSubscriber public static void init(IGuiHandlerRegistration registration) { registration.addGuiContainerHandler(NeoExtremeTerminalScreen.class, new JeiTableGuiHandler<>(AvaritiaJEIPlugin.EXTREME_CRAFTING)); } diff --git a/src/main/java/me/myogoo/extendedterminal/integration/jei/avaritiaNeo/AVNeoRecipeCatalyst.java b/src/main/java/me/myogoo/extendedterminal/integration/jei/avaritiaNeo/AVNeoRecipeCatalyst.java index 3d4ac94..7676fdd 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/jei/avaritiaNeo/AVNeoRecipeCatalyst.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/jei/avaritiaNeo/AVNeoRecipeCatalyst.java @@ -1,7 +1,7 @@ package me.myogoo.extendedterminal.integration.jei.avaritiaNeo; import me.myogoo.extendedterminal.api.ModAccessor; -import me.myogoo.extendedterminal.api.SubscribeLoadEvent; +import me.myogoo.myotus.api.annotation.MyotusSubscriber; import me.myogoo.extendedterminal.api.integration.jei.ETJeiRecipeCatalyst; import me.myogoo.extendedterminal.config.avaritiaNeo.AvaritiaNeoConfig; import me.myogoo.extendedterminal.init.ETParts; @@ -11,7 +11,7 @@ @ETJeiRecipeCatalyst @ModAccessor.AvaritiaNeo public class AVNeoRecipeCatalyst { - @SubscribeLoadEvent + @MyotusSubscriber public static void init(IRecipeCatalystRegistration registration) { if(AvaritiaNeoConfig.INSTANCE.getExtremeConfig().enableTerminal()) { registration.addRecipeCatalyst(ETParts.NEO_EXTREME_TERMINAL_PART, AvaritiaJEIPlugin.EXTREME_CRAFTING); diff --git a/src/main/java/me/myogoo/extendedterminal/integration/jei/avaritiaNeo/AVNeoRecipeTransferHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/jei/avaritiaNeo/AVNeoRecipeTransferHandler.java index 7dcdab2..d488c1b 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/jei/avaritiaNeo/AVNeoRecipeTransferHandler.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/jei/avaritiaNeo/AVNeoRecipeTransferHandler.java @@ -1,7 +1,7 @@ package me.myogoo.extendedterminal.integration.jei.avaritiaNeo; import me.myogoo.extendedterminal.api.ModAccessor; -import me.myogoo.extendedterminal.api.SubscribeLoadEvent; +import me.myogoo.myotus.api.annotation.MyotusSubscriber; import me.myogoo.extendedterminal.api.integration.jei.ETJeiRecipeTransfer; import me.myogoo.extendedterminal.integration.jei.avaritiaNeo.handler.AVNeoJeiRecipeTransferHandler; import me.myogoo.extendedterminal.menu.avaritiaNeo.NeoExtremeTerminalMenu; @@ -11,7 +11,7 @@ @ETJeiRecipeTransfer @ModAccessor.AvaritiaNeo public class AVNeoRecipeTransferHandler { - @SubscribeLoadEvent + @MyotusSubscriber public static void init(IRecipeTransferRegistration registration) { var helper = registration.getTransferHelper(); diff --git a/src/main/java/me/myogoo/extendedterminal/integration/jei/avaritiaRe/AVGuiHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/jei/avaritiaRe/AVGuiHandler.java index 358b97b..3566c17 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/jei/avaritiaRe/AVGuiHandler.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/jei/avaritiaRe/AVGuiHandler.java @@ -5,7 +5,7 @@ import committee.nova.mods.avaritia.init.compat.jei.category.tables.NetherCraftingTableCategory; import committee.nova.mods.avaritia.init.compat.jei.category.tables.SculkCraftingTableCategory; import me.myogoo.extendedterminal.api.ModAccessor; -import me.myogoo.extendedterminal.api.SubscribeLoadEvent; +import me.myogoo.myotus.api.annotation.MyotusSubscriber; import me.myogoo.extendedterminal.api.integration.jei.ETJeiGuiHandler; import me.myogoo.extendedterminal.client.screen.avaritiaRe.EndTerminalScreen; import me.myogoo.extendedterminal.client.screen.avaritiaRe.ExtremeTerminalScreen; @@ -17,7 +17,7 @@ @ModAccessor.ReAvaritia @ETJeiGuiHandler public class AVGuiHandler { - @SubscribeLoadEvent + @MyotusSubscriber public static void init(IGuiHandlerRegistration registration) { registration.addGuiContainerHandler(SculkTerminalScreen.class, new JeiTableGuiHandler<>(SculkCraftingTableCategory.RECIPE_TYPE)); registration.addGuiContainerHandler(NetherTerminalScreen.class, new JeiTableGuiHandler<>(NetherCraftingTableCategory.RECIPE_TYPE)); diff --git a/src/main/java/me/myogoo/extendedterminal/integration/jei/avaritiaRe/AVRecipeCatalyst.java b/src/main/java/me/myogoo/extendedterminal/integration/jei/avaritiaRe/AVRecipeCatalyst.java index 8c10d40..dec448d 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/jei/avaritiaRe/AVRecipeCatalyst.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/jei/avaritiaRe/AVRecipeCatalyst.java @@ -5,7 +5,7 @@ import committee.nova.mods.avaritia.init.compat.jei.category.tables.NetherCraftingTableCategory; import committee.nova.mods.avaritia.init.compat.jei.category.tables.SculkCraftingTableCategory; import me.myogoo.extendedterminal.api.ModAccessor; -import me.myogoo.extendedterminal.api.SubscribeLoadEvent; +import me.myogoo.myotus.api.annotation.MyotusSubscriber; import me.myogoo.extendedterminal.api.integration.jei.ETJeiRecipeCatalyst; import me.myogoo.extendedterminal.config.avaritiaRe.AvaritiaReConfig; import me.myogoo.extendedterminal.init.ETParts; @@ -14,7 +14,7 @@ @ETJeiRecipeCatalyst @ModAccessor.ReAvaritia public class AVRecipeCatalyst { - @SubscribeLoadEvent + @MyotusSubscriber public static void init(IRecipeCatalystRegistration registration) { var instance = AvaritiaReConfig.INSTANCE; if(instance.getSculkConfig().enableTerminal()) registration.addRecipeCatalyst(ETParts.SCULK_TERMINAL_PART, SculkCraftingTableCategory.RECIPE_TYPE); diff --git a/src/main/java/me/myogoo/extendedterminal/integration/jei/avaritiaRe/AVRecipeTransferHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/jei/avaritiaRe/AVRecipeTransferHandler.java index a71f895..06b8e73 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/jei/avaritiaRe/AVRecipeTransferHandler.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/jei/avaritiaRe/AVRecipeTransferHandler.java @@ -5,7 +5,7 @@ import committee.nova.mods.avaritia.init.compat.jei.category.tables.NetherCraftingTableCategory; import committee.nova.mods.avaritia.init.compat.jei.category.tables.SculkCraftingTableCategory; import me.myogoo.extendedterminal.api.ModAccessor; -import me.myogoo.extendedterminal.api.SubscribeLoadEvent; +import me.myogoo.myotus.api.annotation.MyotusSubscriber; import me.myogoo.extendedterminal.api.integration.jei.ETJeiRecipeTransfer; import me.myogoo.extendedterminal.integration.jei.avaritiaRe.handler.AVJeiRecipeTransferHandler; import me.myogoo.extendedterminal.menu.avaritiaRe.EndTerminalMenu; @@ -17,7 +17,7 @@ @ETJeiRecipeTransfer @ModAccessor.ReAvaritia public class AVRecipeTransferHandler { - @SubscribeLoadEvent + @MyotusSubscriber public static void init(IRecipeTransferRegistration registration) { var helper = registration.getTransferHelper(); diff --git a/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedcrafting/ECGuiHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedcrafting/ECGuiHandler.java index 28fd00f..4fa05cf 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedcrafting/ECGuiHandler.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedcrafting/ECGuiHandler.java @@ -5,7 +5,7 @@ import com.blakebr0.extendedcrafting.compat.jei.category.table.EliteTableCategory; import com.blakebr0.extendedcrafting.compat.jei.category.table.UltimateTableCategory; import me.myogoo.extendedterminal.api.ModAccessor; -import me.myogoo.extendedterminal.api.SubscribeLoadEvent; +import me.myogoo.myotus.api.annotation.MyotusSubscriber; import me.myogoo.extendedterminal.api.integration.jei.ETJeiGuiHandler; import me.myogoo.extendedterminal.client.screen.extendedcrafting.AdvancedTerminalScreen; import me.myogoo.extendedterminal.client.screen.extendedcrafting.BasicTerminalScreen; @@ -17,7 +17,7 @@ @ModAccessor.ExtendedCrafting @ETJeiGuiHandler public class ECGuiHandler { - @SubscribeLoadEvent + @MyotusSubscriber public static void init(IGuiHandlerRegistration registration) { registration.addGuiContainerHandler(BasicTerminalScreen.class, new JeiTableGuiHandler<>(BasicTableCategory.RECIPE_TYPE)); registration.addGuiContainerHandler(AdvancedTerminalScreen.class, new JeiTableGuiHandler<>(AdvancedTableCategory.RECIPE_TYPE)); diff --git a/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedcrafting/ECRecipeCatalyst.java b/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedcrafting/ECRecipeCatalyst.java index 9a21680..0dbba60 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedcrafting/ECRecipeCatalyst.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedcrafting/ECRecipeCatalyst.java @@ -5,7 +5,7 @@ import com.blakebr0.extendedcrafting.compat.jei.category.table.EliteTableCategory; import com.blakebr0.extendedcrafting.compat.jei.category.table.UltimateTableCategory; import me.myogoo.extendedterminal.api.ModAccessor; -import me.myogoo.extendedterminal.api.SubscribeLoadEvent; +import me.myogoo.myotus.api.annotation.MyotusSubscriber; import me.myogoo.extendedterminal.api.integration.jei.ETJeiRecipeCatalyst; import me.myogoo.extendedterminal.config.extendedcrafting.ExtendedCraftingConfig; import me.myogoo.extendedterminal.init.ETParts; @@ -14,7 +14,7 @@ @ModAccessor.ExtendedCrafting @ETJeiRecipeCatalyst public class ECRecipeCatalyst{ - @SubscribeLoadEvent + @MyotusSubscriber public static void init(IRecipeCatalystRegistration registration) { var instance = ExtendedCraftingConfig.INSTANCE; if (instance.getBasicConfig().enableTerminal()) diff --git a/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedcrafting/ECRecipeTransferHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedcrafting/ECRecipeTransferHandler.java index 8d0668c..f0aef2d 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedcrafting/ECRecipeTransferHandler.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedcrafting/ECRecipeTransferHandler.java @@ -5,7 +5,7 @@ import com.blakebr0.extendedcrafting.compat.jei.category.table.EliteTableCategory; import com.blakebr0.extendedcrafting.compat.jei.category.table.UltimateTableCategory; import me.myogoo.extendedterminal.api.ModAccessor; -import me.myogoo.extendedterminal.api.SubscribeLoadEvent; +import me.myogoo.myotus.api.annotation.MyotusSubscriber; import me.myogoo.extendedterminal.api.integration.jei.ETJeiRecipeTransfer; import me.myogoo.extendedterminal.integration.jei.extendedcrafting.handler.ECJeiRecipeTransferHandler; import me.myogoo.extendedterminal.menu.extendedcrafting.AdvancedTerminalMenu; @@ -17,7 +17,7 @@ @ModAccessor.ExtendedCrafting @ETJeiRecipeTransfer public class ECRecipeTransferHandler { - @SubscribeLoadEvent + @MyotusSubscriber public static void init(IRecipeTransferRegistration registration) { var helper = registration.getTransferHelper(); diff --git a/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedcrafting/EXCGuiHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedcrafting/EXCGuiHandler.java index 43f0ca9..1dd3825 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedcrafting/EXCGuiHandler.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedcrafting/EXCGuiHandler.java @@ -2,7 +2,7 @@ import com.blakebr0.extendedcrafting.compat.jei.category.table.EpicTableCategory; import me.myogoo.extendedterminal.api.ModAccessor; -import me.myogoo.extendedterminal.api.SubscribeLoadEvent; +import me.myogoo.myotus.api.annotation.MyotusSubscriber; import me.myogoo.extendedterminal.api.integration.jei.ETJeiGuiHandler; import me.myogoo.extendedterminal.client.screen.extendedcrafting.EpicTerminalScreen; import me.myogoo.extendedterminal.integration.jei.handler.JeiTableGuiHandler; @@ -11,7 +11,7 @@ @ModAccessor.EpicExCrafting @ETJeiGuiHandler public class EXCGuiHandler { - @SubscribeLoadEvent + @MyotusSubscriber public static void init(IGuiHandlerRegistration registration) { registration.addGuiContainerHandler(EpicTerminalScreen.class, new JeiTableGuiHandler<>(EpicTableCategory.RECIPE_TYPE)); } diff --git a/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedcrafting/EXCRecipeCatalyst.java b/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedcrafting/EXCRecipeCatalyst.java index 542ecaa..6f7427d 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedcrafting/EXCRecipeCatalyst.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedcrafting/EXCRecipeCatalyst.java @@ -2,7 +2,7 @@ import com.blakebr0.extendedcrafting.compat.jei.category.table.EpicTableCategory; import me.myogoo.extendedterminal.api.ModAccessor; -import me.myogoo.extendedterminal.api.SubscribeLoadEvent; +import me.myogoo.myotus.api.annotation.MyotusSubscriber; import me.myogoo.extendedterminal.api.integration.jei.ETJeiRecipeCatalyst; import me.myogoo.extendedterminal.config.extendedcrafting.ExtendedCraftingConfig; import me.myogoo.extendedterminal.init.ETParts; @@ -11,7 +11,7 @@ @ModAccessor.EpicExCrafting @ETJeiRecipeCatalyst public class EXCRecipeCatalyst { - @SubscribeLoadEvent + @MyotusSubscriber public static void init(IRecipeCatalystRegistration registration) { if(ExtendedCraftingConfig.INSTANCE.getEpicConfig().enableTerminal()) { registration.addRecipeCatalyst(ETParts.EPIC_TERMINAL_PART, EpicTableCategory.RECIPE_TYPE); diff --git a/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedcrafting/EXCRecipeTransferHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedcrafting/EXCRecipeTransferHandler.java index 7b9e249..ff79577 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedcrafting/EXCRecipeTransferHandler.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedcrafting/EXCRecipeTransferHandler.java @@ -2,7 +2,7 @@ import com.blakebr0.extendedcrafting.compat.jei.category.table.EpicTableCategory; import me.myogoo.extendedterminal.api.ModAccessor; -import me.myogoo.extendedterminal.api.SubscribeLoadEvent; +import me.myogoo.myotus.api.annotation.MyotusSubscriber; import me.myogoo.extendedterminal.api.integration.jei.ETJeiRecipeTransfer; import me.myogoo.extendedterminal.integration.jei.extendedcrafting.handler.ECJeiRecipeTransferHandler; import me.myogoo.extendedterminal.menu.extendedcrafting.*; @@ -11,7 +11,7 @@ @ModAccessor.EpicExCrafting @ETJeiRecipeTransfer public class EXCRecipeTransferHandler { - @SubscribeLoadEvent + @MyotusSubscriber public static void init(IRecipeTransferRegistration registration) { var helper = registration.getTransferHelper(); registration.addRecipeTransferHandler(new ECJeiRecipeTransferHandler<>(EpicTerminalMenu.class, EpicTerminalMenu.TYPE, EpicTableCategory.RECIPE_TYPE, helper), EpicTableCategory.RECIPE_TYPE); diff --git a/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/ETRecipeCatalyst.java b/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/ETRecipeCatalyst.java new file mode 100644 index 0000000..44d2936 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/ETRecipeCatalyst.java @@ -0,0 +1,32 @@ +package me.myogoo.extendedterminal.integration.jei.extendedterminal; + +import me.myogoo.extendedterminal.api.integration.jei.ETJeiRecipeCatalyst; +import me.myogoo.extendedterminal.config.ExtendedTerminalConfig; +import me.myogoo.extendedterminal.init.ETParts; +import me.myogoo.myotus.api.annotation.MyotusSubscriber; +import mezz.jei.api.constants.RecipeTypes; +import mezz.jei.api.registration.IRecipeCatalystRegistration; + +@ETJeiRecipeCatalyst +public class ETRecipeCatalyst { + @MyotusSubscriber + public static void init(IRecipeCatalystRegistration registration) { + var config = ExtendedTerminalConfig.INSTANCE.getExtendedTerminalConfig(); + if (!config.enableTerminal()) { + return; + } + + if (config.enableCraftingPanel()) { + registration.addRecipeCatalyst(ETParts.ET_TERMINAL_PART, RecipeTypes.CRAFTING); + } + if (config.enableSmithingPanel()) { + registration.addRecipeCatalyst(ETParts.ET_TERMINAL_PART, RecipeTypes.SMITHING); + } + if (config.enableStonecutterPanel()) { + registration.addRecipeCatalyst(ETParts.ET_TERMINAL_PART, RecipeTypes.STONECUTTING); + } + if (config.enableAnvilPanel()) { + registration.addRecipeCatalyst(ETParts.ET_TERMINAL_PART, RecipeTypes.ANVIL); + } + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/ETRecipeTransferHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/ETRecipeTransferHandler.java new file mode 100644 index 0000000..274a9a2 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/ETRecipeTransferHandler.java @@ -0,0 +1,40 @@ +package me.myogoo.extendedterminal.integration.jei.extendedterminal; + +import me.myogoo.extendedterminal.api.integration.jei.ETJeiRecipeTransfer; +import me.myogoo.extendedterminal.config.ExtendedTerminalConfig; +import me.myogoo.extendedterminal.integration.jei.extendedterminal.handler.ETCraftingRecipeTransfer; +import me.myogoo.extendedterminal.integration.jei.extendedterminal.handler.ETSmithingRecipeTransfer; +import me.myogoo.extendedterminal.integration.jei.extendedterminal.handler.ETStonecutterRecipeTransfer; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; +import me.myogoo.myotus.api.annotation.MyotusSubscriber; +import mezz.jei.api.constants.RecipeTypes; +import mezz.jei.api.registration.IRecipeTransferRegistration; + +@ETJeiRecipeTransfer +public class ETRecipeTransferHandler { + @MyotusSubscriber + public static void init(IRecipeTransferRegistration registration) { + var config = ExtendedTerminalConfig.INSTANCE.getExtendedTerminalConfig(); + var helper = registration.getTransferHelper(); + + if (!config.enableTerminal()) { + return; + } + + if (config.enableCraftingPanel()) { + registration.addRecipeTransferHandler( + new ETCraftingRecipeTransfer(ETTerminalMenu.TYPE, ETTerminalMenu.class, helper), + RecipeTypes.CRAFTING); + } + if (config.enableSmithingPanel()) { + registration.addRecipeTransferHandler( + new ETSmithingRecipeTransfer(ETTerminalMenu.TYPE, ETTerminalMenu.class, helper), + RecipeTypes.SMITHING); + } + if (config.enableStonecutterPanel()) { + registration.addRecipeTransferHandler( + new ETStonecutterRecipeTransfer(ETTerminalMenu.TYPE, ETTerminalMenu.class, helper), + RecipeTypes.STONECUTTING); + } + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/handler/ETCraftingRecipeTransfer.java b/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/handler/ETCraftingRecipeTransfer.java new file mode 100644 index 0000000..8143be5 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/handler/ETCraftingRecipeTransfer.java @@ -0,0 +1,68 @@ +package me.myogoo.extendedterminal.integration.jei.extendedterminal.handler; + +import appeng.core.localization.ItemModText; +import me.myogoo.extendedterminal.integration.module.extendedterminal.ETCraftingRecipeTransferHelper; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; +import mezz.jei.api.constants.RecipeTypes; +import mezz.jei.api.gui.ingredient.IRecipeSlotsView; +import mezz.jei.api.recipe.RecipeType; +import mezz.jei.api.recipe.transfer.IRecipeTransferError; +import mezz.jei.api.recipe.transfer.IRecipeTransferHandler; +import mezz.jei.api.recipe.transfer.IRecipeTransferHandlerHelper; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.item.crafting.CraftingRecipe; +import org.jetbrains.annotations.Nullable; + +import java.util.Optional; + +public class ETCraftingRecipeTransfer implements IRecipeTransferHandler { + private final MenuType menuType; + private final Class containerClass; + private final IRecipeTransferHandlerHelper helper; + + public ETCraftingRecipeTransfer(MenuType menuType, Class containerClass, + IRecipeTransferHandlerHelper helper) { + this.menuType = menuType; + this.containerClass = containerClass; + this.helper = helper; + } + + @Override + public Class getContainerClass() { + return containerClass; + } + + @Override + public Optional> getMenuType() { + return Optional.of(menuType); + } + + @Override + public RecipeType getRecipeType() { + return RecipeTypes.CRAFTING; + } + + @Override + public @Nullable IRecipeTransferError transferRecipe(T menu, CraftingRecipe recipe, + IRecipeSlotsView recipeSlots, Player player, boolean maxTransfer, boolean doTransfer) { + if (recipe.getIngredients().isEmpty()) { + return helper.createUserErrorWithTooltip(ItemModText.INCOMPATIBLE_RECIPE.text()); + } + if (!recipe.canCraftInDimensions(menu.getCraftingGridWidth(), menu.getCraftingGridHeight())) { + return helper.createUserErrorWithTooltip(ItemModText.RECIPE_TOO_LARGE.text()); + } + + var slotToIngredientMap = ETCraftingRecipeTransferHelper.getGuiSlotToIngredientMap(menu, recipe); + if (!slotToIngredientMap.isEmpty() + && menu.findMissingIngredients(slotToIngredientMap).missingSlots().size() == slotToIngredientMap.size()) { + return helper.createUserErrorWithTooltip(ItemModText.NO_ITEMS.text()); + } + + if (doTransfer) { + ETCraftingRecipeTransferHelper.performTransfer(menu, recipe, null, AbstractContainerScreen.hasControlDown()); + } + return null; + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/handler/ETSmithingRecipeTransfer.java b/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/handler/ETSmithingRecipeTransfer.java new file mode 100644 index 0000000..63d7951 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/handler/ETSmithingRecipeTransfer.java @@ -0,0 +1,65 @@ +package me.myogoo.extendedterminal.integration.jei.extendedterminal.handler; + +import appeng.core.localization.ItemModText; +import me.myogoo.extendedterminal.integration.module.extendedterminal.ETSmithingRecipeTransferHelper; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; +import mezz.jei.api.constants.RecipeTypes; +import mezz.jei.api.gui.ingredient.IRecipeSlotsView; +import mezz.jei.api.recipe.RecipeType; +import mezz.jei.api.recipe.transfer.IRecipeTransferError; +import mezz.jei.api.recipe.transfer.IRecipeTransferHandler; +import mezz.jei.api.recipe.transfer.IRecipeTransferHandlerHelper; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.item.crafting.SmithingRecipe; +import org.jetbrains.annotations.Nullable; + +import java.util.Optional; + +public class ETSmithingRecipeTransfer implements IRecipeTransferHandler { + private final MenuType menuType; + private final Class containerClass; + private final IRecipeTransferHandlerHelper helper; + + public ETSmithingRecipeTransfer(MenuType menuType, Class containerClass, + IRecipeTransferHandlerHelper helper) { + this.menuType = menuType; + this.containerClass = containerClass; + this.helper = helper; + } + + @Override + public Class getContainerClass() { + return containerClass; + } + + @Override + public Optional> getMenuType() { + return Optional.of(menuType); + } + + @Override + public RecipeType getRecipeType() { + return RecipeTypes.SMITHING; + } + + @Override + public @Nullable IRecipeTransferError transferRecipe(T menu, SmithingRecipe recipe, + IRecipeSlotsView recipeSlots, Player player, boolean maxTransfer, boolean doTransfer) { + if (!recipe.canCraftInDimensions(3, 1)) { + return helper.createUserErrorWithTooltip(ItemModText.RECIPE_TOO_LARGE.text()); + } + + var slotToIngredientMap = ETSmithingRecipeTransferHelper.getGuiSlotToIngredientMap(recipe); + if (!slotToIngredientMap.isEmpty() + && menu.findMissingIngredients(slotToIngredientMap).missingSlots().size() == slotToIngredientMap.size()) { + return helper.createUserErrorWithTooltip(ItemModText.NO_ITEMS.text()); + } + + if (doTransfer) { + ETSmithingRecipeTransferHelper.performTransfer(menu, recipe, AbstractContainerScreen.hasControlDown()); + } + return null; + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/handler/ETStonecutterRecipeTransfer.java b/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/handler/ETStonecutterRecipeTransfer.java new file mode 100644 index 0000000..fec437e --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/handler/ETStonecutterRecipeTransfer.java @@ -0,0 +1,65 @@ +package me.myogoo.extendedterminal.integration.jei.extendedterminal.handler; + +import appeng.core.localization.ItemModText; +import me.myogoo.extendedterminal.integration.module.extendedterminal.ETStoneCutterRecipeTransferHelper; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; +import mezz.jei.api.constants.RecipeTypes; +import mezz.jei.api.gui.ingredient.IRecipeSlotsView; +import mezz.jei.api.recipe.RecipeType; +import mezz.jei.api.recipe.transfer.IRecipeTransferError; +import mezz.jei.api.recipe.transfer.IRecipeTransferHandler; +import mezz.jei.api.recipe.transfer.IRecipeTransferHandlerHelper; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.item.crafting.StonecutterRecipe; +import org.jetbrains.annotations.Nullable; + +import java.util.Optional; + +public class ETStonecutterRecipeTransfer implements IRecipeTransferHandler { + private final MenuType menuType; + private final Class containerClass; + private final IRecipeTransferHandlerHelper helper; + + public ETStonecutterRecipeTransfer(MenuType menuType, Class containerClass, + IRecipeTransferHandlerHelper helper) { + this.menuType = menuType; + this.containerClass = containerClass; + this.helper = helper; + } + + @Override + public Class getContainerClass() { + return containerClass; + } + + @Override + public Optional> getMenuType() { + return Optional.of(menuType); + } + + @Override + public RecipeType getRecipeType() { + return RecipeTypes.STONECUTTING; + } + + @Override + public @Nullable IRecipeTransferError transferRecipe(T menu, StonecutterRecipe recipe, + IRecipeSlotsView recipeSlots, Player player, boolean maxTransfer, boolean doTransfer) { + if (!recipe.canCraftInDimensions(1, 1)) { + return helper.createUserErrorWithTooltip(ItemModText.RECIPE_TOO_LARGE.text()); + } + + var slotToIngredientMap = ETStoneCutterRecipeTransferHelper.getGuiSlotToIngredientMap(recipe); + if (!slotToIngredientMap.isEmpty() + && menu.findMissingIngredients(slotToIngredientMap).missingSlots().size() == slotToIngredientMap.size()) { + return helper.createUserErrorWithTooltip(ItemModText.NO_ITEMS.text()); + } + + if (doTransfer) { + ETStoneCutterRecipeTransferHelper.performTransfer(menu, recipe, AbstractContainerScreen.hasControlDown()); + } + return null; + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/wt/ETWTRecipeCatalyst.java b/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/wt/ETWTRecipeCatalyst.java new file mode 100644 index 0000000..f49a9a5 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/wt/ETWTRecipeCatalyst.java @@ -0,0 +1,20 @@ +package me.myogoo.extendedterminal.integration.jei.extendedterminal.wt; + +import me.myogoo.extendedterminal.api.integration.jei.ETJeiRecipeCatalyst; +import me.myogoo.extendedterminal.init.wt.WTItems; +import me.myogoo.myotus.api.annotation.MyotusSubscriber; +import me.myogoo.myotus.api.annotation.wt.AE2WTLib; +import mezz.jei.api.constants.RecipeTypes; +import mezz.jei.api.registration.IRecipeCatalystRegistration; + +@AE2WTLib +@ETJeiRecipeCatalyst +public class ETWTRecipeCatalyst { + @MyotusSubscriber + public static void init(IRecipeCatalystRegistration registration) { + registration.addRecipeCatalyst(WTItems.WIRELESS_ET_TERMINAL, RecipeTypes.CRAFTING); + registration.addRecipeCatalyst(WTItems.WIRELESS_ET_TERMINAL, RecipeTypes.SMITHING); + registration.addRecipeCatalyst(WTItems.WIRELESS_ET_TERMINAL, RecipeTypes.STONECUTTING); + registration.addRecipeCatalyst(WTItems.WIRELESS_ET_TERMINAL, RecipeTypes.ANVIL); + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/wt/ETWTRecipeTransferHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/wt/ETWTRecipeTransferHandler.java new file mode 100644 index 0000000..9da0205 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/wt/ETWTRecipeTransferHandler.java @@ -0,0 +1,23 @@ +package me.myogoo.extendedterminal.integration.jei.extendedterminal.wt; + +import me.myogoo.extendedterminal.api.integration.jei.ETJeiRecipeTransfer; +import me.myogoo.extendedterminal.integration.jei.extendedterminal.handler.ETCraftingRecipeTransfer; +import me.myogoo.extendedterminal.integration.jei.extendedterminal.handler.ETSmithingRecipeTransfer; +import me.myogoo.extendedterminal.integration.jei.extendedterminal.handler.ETStonecutterRecipeTransfer; +import me.myogoo.extendedterminal.menu.extendedterminal.wt.ETWTMenu; +import me.myogoo.myotus.api.annotation.MyotusSubscriber; +import me.myogoo.myotus.api.annotation.wt.AE2WTLib; +import mezz.jei.api.constants.RecipeTypes; +import mezz.jei.api.registration.IRecipeTransferRegistration; + +@AE2WTLib +@ETJeiRecipeTransfer +public class ETWTRecipeTransferHandler { + @MyotusSubscriber + public static void init(IRecipeTransferRegistration registration) { + var helper = registration.getTransferHelper(); + registration.addRecipeTransferHandler(new ETCraftingRecipeTransfer<>(ETWTMenu.TYPE, ETWTMenu.class, helper), RecipeTypes.CRAFTING); + registration.addRecipeTransferHandler(new ETSmithingRecipeTransfer<>(ETWTMenu.TYPE, ETWTMenu.class, helper), RecipeTypes.SMITHING); + registration.addRecipeTransferHandler(new ETStonecutterRecipeTransfer<>(ETWTMenu.TYPE, ETWTMenu.class, helper), RecipeTypes.STONECUTTING); + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/integration/jei/handler/AbstractTableRecipeHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/jei/handler/AbstractTableRecipeHandler.java index 98a9cba..fb61104 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/jei/handler/AbstractTableRecipeHandler.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/jei/handler/AbstractTableRecipeHandler.java @@ -1,7 +1,6 @@ package me.myogoo.extendedterminal.integration.jei.handler; import appeng.core.localization.ItemModText; -import appeng.core.sync.network.NetworkHandler; import appeng.integration.modules.jeirei.TransferHelper; import appeng.menu.me.items.CraftingTermMenu; import com.blakebr0.extendedcrafting.api.crafting.ITableRecipe; @@ -10,6 +9,7 @@ import me.myogoo.extendedterminal.menu.ETTerminalBaseMenu; import me.myogoo.extendedterminal.menu.extendedcrafting.ExtendedTerminalBaseMenu; import me.myogoo.extendedterminal.network.serverbound.ETFillCraftingGridFromRecipePacket; +import me.myogoo.myotus.api.MyotusAPI; import mezz.jei.api.gui.builder.ITooltipBuilder; import mezz.jei.api.gui.ingredient.IRecipeSlotsView; import mezz.jei.api.recipe.RecipeIngredientRole; @@ -68,7 +68,7 @@ protected static void performTransfer(ETTerminalBaseMenu menu, @Nullable ITab recipeHeight = shapedRecipe.height(); } var message = new ETFillCraftingGridFromRecipePacket(recipe.recipeId(), templateItems, craftMissing, recipeWidth, recipeHeight); - NetworkHandler.instance().sendToServer(message); + MyotusAPI.network().sendToServer(message); } protected static abstract class Result implements IRecipeTransferError { diff --git a/src/main/java/me/myogoo/extendedterminal/integration/module/extendedterminal/ETCraftingRecipeTransferHelper.java b/src/main/java/me/myogoo/extendedterminal/integration/module/extendedterminal/ETCraftingRecipeTransferHelper.java new file mode 100644 index 0000000..ea711c5 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/integration/module/extendedterminal/ETCraftingRecipeTransferHelper.java @@ -0,0 +1,60 @@ +package me.myogoo.extendedterminal.integration.module.extendedterminal; + +import appeng.api.stacks.AEItemKey; +import appeng.core.sync.network.NetworkHandler; +import appeng.core.sync.packets.FillCraftingGridFromRecipePacket; +import appeng.integration.modules.jeirei.EncodingHelper; +import appeng.menu.me.common.GridInventoryEntry; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; +import net.minecraft.core.NonNullList; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.CraftingRecipe; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.ShapedRecipe; +import org.jetbrains.annotations.Nullable; + +import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; + +public final class ETCraftingRecipeTransferHelper { + private static final Comparator ENTRY_COMPARATOR = Comparator + .comparing(GridInventoryEntry::getStoredAmount); + + private ETCraftingRecipeTransferHelper() { + } + + public static Map getGuiSlotToIngredientMap(ETTerminalMenu menu, CraftingRecipe recipe) { + var ingredients = recipe.getIngredients(); + int gridWidth = menu.getCraftingGridWidth(); + int recipeWidth = recipe instanceof ShapedRecipe shapedRecipe ? shapedRecipe.getWidth() : gridWidth; + + var result = new HashMap(ingredients.size()); + for (int i = 0; i < ingredients.size(); i++) { + int guiSlot = (i / recipeWidth) * gridWidth + (i % recipeWidth); + var ingredient = ingredients.get(i); + if (!ingredient.isEmpty()) { + result.put(guiSlot, ingredient); + } + } + return result; + } + + public static void performTransfer(ETTerminalMenu menu, CraftingRecipe recipe, @Nullable ResourceLocation recipeId, + boolean craftMissing) { + var ingredientPriorities = EncodingHelper.getIngredientPriorities(menu, ENTRY_COMPARATOR); + var templateItems = NonNullList.withSize(menu.getCraftingGridSize(), ItemStack.EMPTY); + for (var entry : getGuiSlotToIngredientMap(menu, recipe).entrySet()) { + var ingredient = entry.getValue(); + var stack = ingredientPriorities.entrySet().stream() + .filter(priority -> priority.getKey() instanceof AEItemKey itemKey && itemKey.matches(ingredient)) + .max(Comparator.comparingInt(Map.Entry::getValue)) + .map(priority -> ((AEItemKey) priority.getKey()).toStack()) + .orElse(ingredient.getItems()[0]); + templateItems.set(entry.getKey(), stack); + } + + NetworkHandler.instance().sendToServer(new FillCraftingGridFromRecipePacket(recipeId, templateItems, craftMissing)); + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/integration/module/extendedterminal/ETSmithingRecipeTransferHelper.java b/src/main/java/me/myogoo/extendedterminal/integration/module/extendedterminal/ETSmithingRecipeTransferHelper.java new file mode 100644 index 0000000..00c4f9b --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/integration/module/extendedterminal/ETSmithingRecipeTransferHelper.java @@ -0,0 +1,53 @@ +package me.myogoo.extendedterminal.integration.module.extendedterminal; + +import appeng.api.stacks.AEItemKey; +import appeng.integration.modules.jeirei.EncodingHelper; +import appeng.menu.me.common.GridInventoryEntry; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; +import me.myogoo.extendedterminal.network.serverbound.ETFillSmithingGridFromRecipePacket; +import me.myogoo.myotus.api.MyotusAPI; +import net.minecraft.core.NonNullList; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.SmithingRecipe; + +import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; + +public final class ETSmithingRecipeTransferHelper { + private static final Comparator ENTRY_COMPARATOR = Comparator + .comparing(GridInventoryEntry::getStoredAmount); + + private ETSmithingRecipeTransferHelper() { + } + + public static Map getGuiSlotToIngredientMap(SmithingRecipe recipe) { + var ingredients = recipe.getIngredients(); + var result = new HashMap(ingredients.size()); + for (int i = 0; i < ingredients.size(); i++) { + var ingredient = ingredients.get(i); + if (!ingredient.isEmpty()) { + result.put(i, ingredient); + } + } + return result; + } + + public static void performTransfer(ETTerminalMenu menu, SmithingRecipe recipe, boolean craftMissing) { + var ingredientPriorities = EncodingHelper.getIngredientPriorities(menu, ENTRY_COMPARATOR); + var templateItems = NonNullList.withSize(3, ItemStack.EMPTY); + for (var entry : getGuiSlotToIngredientMap(recipe).entrySet()) { + var ingredient = entry.getValue(); + var stack = ingredientPriorities.entrySet().stream() + .filter(priority -> priority.getKey() instanceof AEItemKey itemKey && itemKey.matches(ingredient)) + .max(Comparator.comparingInt(Map.Entry::getValue)) + .map(priority -> ((AEItemKey) priority.getKey()).toStack()) + .orElse(ingredient.getItems()[0]); + templateItems.set(entry.getKey(), stack); + } + + MyotusAPI.network().sendToServer(new ETFillSmithingGridFromRecipePacket(recipe.getId(), templateItems, + craftMissing)); + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/integration/module/extendedterminal/ETStoneCutterRecipeTransferHelper.java b/src/main/java/me/myogoo/extendedterminal/integration/module/extendedterminal/ETStoneCutterRecipeTransferHelper.java new file mode 100644 index 0000000..d85e490 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/integration/module/extendedterminal/ETStoneCutterRecipeTransferHelper.java @@ -0,0 +1,47 @@ +package me.myogoo.extendedterminal.integration.module.extendedterminal; + +import appeng.api.stacks.AEItemKey; +import appeng.integration.modules.jeirei.EncodingHelper; +import appeng.menu.me.common.GridInventoryEntry; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; +import me.myogoo.extendedterminal.network.serverbound.ETFillStonecutterGridFromRecipePacket; +import me.myogoo.myotus.api.MyotusAPI; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.StonecutterRecipe; + +import java.util.Comparator; +import java.util.Map; + +public final class ETStoneCutterRecipeTransferHelper { + private static final Comparator ENTRY_COMPARATOR = Comparator + .comparing(GridInventoryEntry::getStoredAmount); + + private ETStoneCutterRecipeTransferHelper() { + } + + public static Map getGuiSlotToIngredientMap(StonecutterRecipe recipe) { + var ingredients = recipe.getIngredients(); + if (ingredients.isEmpty() || ingredients.get(0).isEmpty()) { + return Map.of(); + } + return Map.of(0, ingredients.get(0)); + } + + public static void performTransfer(ETTerminalMenu menu, StonecutterRecipe recipe, boolean craftMissing) { + var ingredient = recipe.getIngredients().isEmpty() ? Ingredient.EMPTY : recipe.getIngredients().get(0); + if (ingredient.isEmpty()) { + return; + } + + var ingredientPriorities = EncodingHelper.getIngredientPriorities(menu, ENTRY_COMPARATOR); + var templateItem = ingredientPriorities.entrySet().stream() + .filter(priority -> priority.getKey() instanceof AEItemKey itemKey && itemKey.matches(ingredient)) + .max(Comparator.comparingInt(Map.Entry::getValue)) + .map(priority -> ((AEItemKey) priority.getKey()).toStack()) + .orElse(ingredient.getItems()[0]); + + MyotusAPI.network().sendToServer(new ETFillStonecutterGridFromRecipePacket(recipe.getId(), templateItem, + craftMissing)); + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/item/wtitem/ETWTItem.java b/src/main/java/me/myogoo/extendedterminal/item/wtitem/ETWTItem.java new file mode 100644 index 0000000..0b71d09 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/item/wtitem/ETWTItem.java @@ -0,0 +1,17 @@ +package me.myogoo.extendedterminal.item.wtitem; + +import de.mari_023.ae2wtlib.terminal.ItemWT; +import me.myogoo.extendedterminal.menu.extendedterminal.wt.ETWTMenu; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.item.ItemStack; + +public class ETWTItem extends ItemWT { + public ETWTItem(Properties properties) { + super(); + } + + @Override + public MenuType getMenuType(ItemStack stack) { + return ETWTMenu.TYPE; + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/me/host/ETWTHost.java b/src/main/java/me/myogoo/extendedterminal/me/host/ETWTHost.java new file mode 100644 index 0000000..a695ede --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/me/host/ETWTHost.java @@ -0,0 +1,127 @@ +package me.myogoo.extendedterminal.me.host; + +import appeng.api.implementations.blockentities.IViewCellStorage; +import appeng.api.inventories.InternalInventory; +import appeng.menu.ISubMenu; +import appeng.util.inv.AppEngInternalInventory; +import de.mari_023.ae2wtlib.terminal.WTMenuHost; +import me.myogoo.extendedterminal.api.host.IETTerminalHost; +import me.myogoo.extendedterminal.menu.ETMenuType; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMode; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.Tag; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import org.jetbrains.annotations.Nullable; + +import java.util.function.BiConsumer; + +import static me.myogoo.extendedterminal.part.extendedterminal.ETTerminalPart.ANVIL_INVENTORY; +import static me.myogoo.extendedterminal.part.extendedterminal.ETTerminalPart.SMITHING_INVENTORY; +import static me.myogoo.extendedterminal.part.extendedterminal.ETTerminalPart.STONECUTTER_INVENTORY; + +public class ETWTHost extends WTMenuHost implements IViewCellStorage, IETTerminalHost { + private static final String MODE_TAG = "mode"; + private static final String RECIPE_TAG = "stonecuttingRecipeId"; + private static final String CRAFTING_GRID_TAG = "craftingGrid"; + private static final String SMITHING_GRID_TAG = "smithingGrid"; + private static final String STONECUTTER_GRID_TAG = "stoneCutterGrid"; + private static final String ANVIL_GRID_TAG = "anvilInv"; + + private final AppEngInternalInventory craftingGrid; + private final AppEngInternalInventory smithingGrid; + private final AppEngInternalInventory stoneCutterGrid; + private final AppEngInternalInventory anvilInv; + + private ETTerminalMode mode = ETTerminalMode.loadableValues().get(0); + @Nullable + private ResourceLocation stonecuttingRecipeId; + + public ETWTHost(Player player, @Nullable Integer inventorySlot, ItemStack itemStack, + BiConsumer returnToMainMenu) { + super(player, inventorySlot, itemStack, returnToMainMenu); + this.craftingGrid = new AppEngInternalInventory(this, ETMenuType.ET_TERMINAL.getGridSize()); + this.smithingGrid = new AppEngInternalInventory(this, 3); + this.stoneCutterGrid = new AppEngInternalInventory(this, 1); + this.anvilInv = new AppEngInternalInventory(this, 2); + readFromNbt(); + } + + @Override + protected void readFromNbt() { + super.readFromNbt(); + + CompoundTag tag = getItemStack().getOrCreateTag(); + try { + if (tag.contains(MODE_TAG, Tag.TAG_STRING)) { + this.mode = ETTerminalMode.valueOf(tag.getString(MODE_TAG)); + } + } catch (IllegalArgumentException ignored) { + this.mode = ETTerminalMode.loadableValues().get(0); + } + + this.stonecuttingRecipeId = tag.contains(RECIPE_TAG, Tag.TAG_STRING) + ? ResourceLocation.tryParse(tag.getString(RECIPE_TAG)) + : null; + + this.craftingGrid.readFromNBT(tag, CRAFTING_GRID_TAG); + this.smithingGrid.readFromNBT(tag, SMITHING_GRID_TAG); + this.stoneCutterGrid.readFromNBT(tag, STONECUTTER_GRID_TAG); + this.anvilInv.readFromNBT(tag, ANVIL_GRID_TAG); + } + + @Override + public void saveChanges() { + super.saveChanges(); + + CompoundTag tag = getItemStack().getOrCreateTag(); + tag.putString(MODE_TAG, this.mode.name()); + if (this.stonecuttingRecipeId != null) { + tag.putString(RECIPE_TAG, this.stonecuttingRecipeId.toString()); + } else { + tag.remove(RECIPE_TAG); + } + + this.craftingGrid.writeToNBT(tag, CRAFTING_GRID_TAG); + this.smithingGrid.writeToNBT(tag, SMITHING_GRID_TAG); + this.stoneCutterGrid.writeToNBT(tag, STONECUTTER_GRID_TAG); + this.anvilInv.writeToNBT(tag, ANVIL_GRID_TAG); + } + + @Override + public @Nullable InternalInventory getSubInventory(ResourceLocation id) { + if (id.equals(ETMenuType.ET_TERMINAL.getCraftingInventory())) { + return this.craftingGrid; + } else if (id.equals(SMITHING_INVENTORY)) { + return this.smithingGrid; + } else if (id.equals(STONECUTTER_INVENTORY)) { + return this.stoneCutterGrid; + } else if (id.equals(ANVIL_INVENTORY)) { + return this.anvilInv; + } + return super.getSubInventory(id); + } + + @Override + public ETTerminalMode getMode() { + return this.mode; + } + + @Override + public void setMode(ETTerminalMode mode) { + this.mode = mode; + saveChanges(); + } + + @Override + public @Nullable ResourceLocation getStoneCutterRecipeId() { + return this.stonecuttingRecipeId; + } + + @Override + public void setStoneCutterRecipeId(@Nullable ResourceLocation stonecuttingRecipeId) { + this.stonecuttingRecipeId = stonecuttingRecipeId; + saveChanges(); + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/menu/ETMenuType.java b/src/main/java/me/myogoo/extendedterminal/menu/ETMenuType.java index 4e78a07..a1963bf 100644 --- a/src/main/java/me/myogoo/extendedterminal/menu/ETMenuType.java +++ b/src/main/java/me/myogoo/extendedterminal/menu/ETMenuType.java @@ -1,9 +1,10 @@ package me.myogoo.extendedterminal.menu; import appeng.menu.SlotSemantic; +import appeng.menu.SlotSemantics; import me.myogoo.extendedterminal.ExtendedTerminal; import me.myogoo.extendedterminal.api.ModAccessor.*; -import me.myogoo.extendedterminal.util.mod.ModIntegrationManager; +import me.myogoo.myotus.util.mod.ModIntegrationManager; import net.minecraft.resources.ResourceLocation; import java.lang.annotation.Annotation; @@ -12,7 +13,7 @@ public enum ETMenuType { - ET_TERMINAL(3,-1, ETSlotSemantics.BASIC_CRAFTING_GRID, ETSlotSemantics.BASIC_CRAFTING_RESULT), + ET_TERMINAL(3, -1, SlotSemantics.CRAFTING_GRID, SlotSemantics.CRAFTING_RESULT), @ExtendedCrafting BASIC_TERMINAL(3,1, ETSlotSemantics.BASIC_CRAFTING_GRID, ETSlotSemantics.BASIC_CRAFTING_RESULT), @@ -87,6 +88,10 @@ public String getIdAsString() { return this.name().toLowerCase(); } + public String getWTIdAsString() { + return "wireless_" + this.name().toLowerCase(); + } + public String getEnglishName() { return this.name().toLowerCase().replace("_", " "); } diff --git a/src/main/java/me/myogoo/extendedterminal/menu/ETSlotSemantics.java b/src/main/java/me/myogoo/extendedterminal/menu/ETSlotSemantics.java index 37dbe2f..553db04 100644 --- a/src/main/java/me/myogoo/extendedterminal/menu/ETSlotSemantics.java +++ b/src/main/java/me/myogoo/extendedterminal/menu/ETSlotSemantics.java @@ -7,6 +7,18 @@ public final class ETSlotSemantics { public static final SlotSemantic PLAYER_ARMOR = SlotSemantics.register("PLAYER_ARMOR", true); public static final SlotSemantic PLAYER_CURIOS = SlotSemantics.register("PLAYER_CURIOS", true); + public static final SlotSemantic SMITHING_TABLE_TEMPLATE = SlotSemantics.register("ET_SMITHING_TABLE_TEMPLATE", true); + public static final SlotSemantic SMITHING_TABLE_BASE = SlotSemantics.register("ET_SMITHING_TABLE_BASE", true); + public static final SlotSemantic SMITHING_TABLE_ADDITION = SlotSemantics.register("ET_SMITHING_TABLE_ADDITION", true); + public static final SlotSemantic SMITHING_TABLE_RESULT = SlotSemantics.register("ET_SMITHING_TABLE_RESULT", false); + + public static final SlotSemantic STONECUTTING_INPUT = SlotSemantics.register("ET_STONECUTTING_INPUT", true); + public static final SlotSemantic STONECUTTING_RESULT = SlotSemantics.register("STONECUTTING_RESULT", false); + + public static final SlotSemantic ANVIL_LEFT_INPUT = SlotSemantics.register("ET_ANVIL_LEFT_INPUT", true); + public static final SlotSemantic ANVIL_RIGHT_INPUT = SlotSemantics.register("ET_ANVIL_RIGHT_INPUT", true); + public static final SlotSemantic ANVIL_RESULT = SlotSemantics.register("ANVIL_RESULT", false); + public static final SlotSemantic BASIC_CRAFTING_GRID = SlotSemantics.register("BASIC_CRAFTING_GRID", true); public static final SlotSemantic BASIC_CRAFTING_RESULT = SlotSemantics.register("BASIC_CRAFTING_RESULT", false); diff --git a/src/main/java/me/myogoo/extendedterminal/menu/ETTerminalBaseMenu.java b/src/main/java/me/myogoo/extendedterminal/menu/ETTerminalBaseMenu.java index 7b26a6b..2d789b4 100644 --- a/src/main/java/me/myogoo/extendedterminal/menu/ETTerminalBaseMenu.java +++ b/src/main/java/me/myogoo/extendedterminal/menu/ETTerminalBaseMenu.java @@ -7,9 +7,11 @@ import appeng.menu.me.common.MEStorageMenu; import appeng.menu.me.crafting.CraftConfirmMenu; import appeng.menu.me.items.CraftingTermMenu; +import appeng.api.inventories.ISegmentedInventory; import appeng.util.inv.PlayerInternalInventory; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import me.myogoo.extendedterminal.api.config.IETTerminalConfig; +import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.Container; import net.minecraft.world.entity.player.Inventory; @@ -161,15 +163,19 @@ public CraftingTermMenu.MissingIngredientSlots findMissingIngredients(Map 0; ) { if (playerInv.getStackInSlot(j).isEmpty() == allowEmpty) { - craftingGridInv.setItemDirect(i, playerInv.getSlotInv(j).addItems(craftingGridInv.getStackInSlot(i))); + inv.setItemDirect(i, playerInv.getSlotInv(j).addItems(inv.getStackInSlot(i))); } } // Rest of inventory for (int j = HOTBAR_SIZE; j < Inventory.INVENTORY_SIZE; ++j) { if (playerInv.getStackInSlot(j).isEmpty() == allowEmpty) { - craftingGridInv.setItemDirect(i, playerInv.getSlotInv(j).addItems(craftingGridInv.getStackInSlot(i))); + inv.setItemDirect(i, playerInv.getSlotInv(j).addItems(inv.getStackInSlot(i))); } } } diff --git a/src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/ETTerminalMenu.java b/src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/ETTerminalMenu.java new file mode 100644 index 0000000..d7ed64f --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/ETTerminalMenu.java @@ -0,0 +1,406 @@ +package me.myogoo.extendedterminal.menu.extendedterminal; + +import appeng.api.inventories.ISegmentedInventory; +import appeng.api.inventories.InternalInventory; +import appeng.api.storage.ITerminalHost; +import appeng.core.sync.network.NetworkHandler; +import appeng.core.sync.packets.InventoryActionPacket; +import appeng.helpers.InventoryAction; +import appeng.menu.implementations.MenuTypeBuilder; +import appeng.menu.slot.AppEngSlot; +import appeng.menu.slot.CraftingMatrixSlot; +import appeng.menu.slot.CraftingTermSlot; +import com.google.common.base.Preconditions; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import me.myogoo.extendedterminal.api.host.IETTerminalHost; +import me.myogoo.extendedterminal.config.ExtendedTerminalConfig; +import me.myogoo.extendedterminal.menu.ETMenuType; +import me.myogoo.extendedterminal.menu.ETSlotSemantics; +import me.myogoo.extendedterminal.menu.ETTerminalBaseMenu; +import me.myogoo.extendedterminal.menu.extendedterminal.slot.ETAnvilSlot; +import me.myogoo.extendedterminal.menu.extendedterminal.slot.ETSmithingSlot; +import me.myogoo.extendedterminal.menu.extendedterminal.slot.ETStoneCutterSlot; +import me.myogoo.extendedterminal.menu.slot.ETCraftingBaseSlot; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.inventory.CraftingContainer; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.inventory.TransientCraftingContainer; +import net.minecraft.world.SimpleContainer; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.CraftingRecipe; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.RecipeType; +import net.minecraft.world.item.crafting.SmithingRecipe; +import net.minecraft.world.item.crafting.StonecutterRecipe; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import static me.myogoo.extendedterminal.part.extendedterminal.ETTerminalPart.ANVIL_INVENTORY; +import static me.myogoo.extendedterminal.part.extendedterminal.ETTerminalPart.SMITHING_INVENTORY; +import static me.myogoo.extendedterminal.part.extendedterminal.ETTerminalPart.STONECUTTER_INVENTORY; + +public class ETTerminalMenu extends ETTerminalBaseMenu { + public static final MenuType TYPE = MenuTypeBuilder + .create(ETTerminalMenu::new, IETTerminalHost.class) + .build(ETMenuType.ET_TERMINAL.getIdAsString()); + + private static final String ACTION_SET_STONECUTTING_RECIPE_ID = "setStonecuttingRecipeId"; + private static final String ACTION_SET_MODE = "setMode"; + private static final String ACTION_SET_ANVIL_ITEM_NAME = "setAnvilItemName"; + + private final ISegmentedInventory craftingInventoryHost; + private final IETTerminalHost host; + + private ETTerminalMode currentMode; + + private final CraftingMatrixSlot[] craftingSlots; + private final CraftingTermSlot outputSlot; + private final CraftingContainer craftingRecipeContainer; + private CraftingRecipe craftingRecipe; + + private final CraftingMatrixSlot smithingTemplateSlot; + private final CraftingMatrixSlot smithingBaseSlot; + private final CraftingMatrixSlot smithingAdditionSlot; + private final ETSmithingSlot smithingOutputSlot; + private SmithingRecipe smithingRecipe; + + private final CraftingMatrixSlot stonecuttingSlot; + private final ETStoneCutterSlot stoneCutterOutputSlot; + private final List stoneCutterRecipes = new ArrayList<>(); + @Nullable + private ResourceLocation stoneCutterRecipeId; + + private final CraftingMatrixSlot anvilLeftSlot; + private final CraftingMatrixSlot anvilRightSlot; + private final ETAnvilSlot anvilOutputSlot; + private final FakeAnvilMenu anvilDelegate; + private int anvilCost; + private boolean handlingAnvilTake; + + public ETTerminalMenu(MenuType menuType, int id, Inventory ip, IETTerminalHost host) { + super(menuType, id, ip, host, ETMenuType.ET_TERMINAL, + ExtendedTerminalConfig.INSTANCE.getExtendedTerminalConfig()); + this.host = host; + this.currentMode = host.getMode(); + this.craftingInventoryHost = (ISegmentedInventory) host; + this.craftingSlots = new CraftingMatrixSlot[this.menuType.getGridSize()]; + this.craftingRecipeContainer = new TransientCraftingContainer(this, + this.menuType.getGridSideLength(), this.menuType.getGridSideLength()); + + var craftingGridInv = this.craftingInventoryHost.getSubInventory(this.menuType.getCraftingInventory()); + for (int i = 0; i < this.menuType.getGridSize(); i++) { + this.addSlot(this.craftingSlots[i] = new CraftingMatrixSlot(this, craftingGridInv, i), + this.menuType.getSlotSemanticGrid()); + } + + this.addSlot(this.outputSlot = new CraftingTermSlot(this.getPlayerInventory().player, this.getActionSource(), + this.powerSource, host.getInventory(), craftingGridInv, craftingGridInv, this), + this.menuType.getSlotSemanticResult()); + + var smithingInv = this.craftingInventoryHost.getSubInventory(SMITHING_INVENTORY); + this.addSlot(this.smithingTemplateSlot = new CraftingMatrixSlot(this, smithingInv, 0), + ETSlotSemantics.SMITHING_TABLE_TEMPLATE); + this.addSlot(this.smithingBaseSlot = new CraftingMatrixSlot(this, smithingInv, 1), + ETSlotSemantics.SMITHING_TABLE_BASE); + this.addSlot(this.smithingAdditionSlot = new CraftingMatrixSlot(this, smithingInv, 2), + ETSlotSemantics.SMITHING_TABLE_ADDITION); + this.addSlot(this.smithingOutputSlot = new ETSmithingSlot(this.getPlayerInventory().player, + this.getActionSource(), this.powerSource, host.getInventory(), smithingInv, smithingInv, this), + ETSlotSemantics.SMITHING_TABLE_RESULT); + + var stonecuttingInv = this.craftingInventoryHost.getSubInventory(STONECUTTER_INVENTORY); + this.addSlot(this.stonecuttingSlot = new CraftingMatrixSlot(this, stonecuttingInv, 0), + ETSlotSemantics.STONECUTTING_INPUT); + this.addSlot(this.stoneCutterOutputSlot = new ETStoneCutterSlot(this.getPlayerInventory().player, + this.getActionSource(), this.powerSource, host.getInventory(), stonecuttingInv, stonecuttingInv, this), + ETSlotSemantics.STONECUTTING_RESULT); + + var anvilInv = this.craftingInventoryHost.getSubInventory(ANVIL_INVENTORY); + this.anvilDelegate = new FakeAnvilMenu(0, this.getPlayerInventory()); + this.addSlot(this.anvilLeftSlot = new CraftingMatrixSlot(this, anvilInv, 0), ETSlotSemantics.ANVIL_LEFT_INPUT); + this.addSlot(this.anvilRightSlot = new CraftingMatrixSlot(this, anvilInv, 1), ETSlotSemantics.ANVIL_RIGHT_INPUT); + this.addSlot(this.anvilOutputSlot = new ETAnvilSlot(this.getPlayerInventory().player, anvilInv, this.anvilDelegate, this), + ETSlotSemantics.ANVIL_RESULT); + + this.stoneCutterRecipeId = host.getStoneCutterRecipeId(); + registerClientAction(ACTION_SET_STONECUTTING_RECIPE_ID, ResourceLocation.class, this::setStoneCutterRecipeId); + registerClientAction(ACTION_SET_MODE, ETTerminalMode.class, this::setMode); + registerClientAction(ACTION_SET_ANVIL_ITEM_NAME, String.class, this::setAnvilItemName); + + updateCurrentRecipeAndOutput(true); + } + + public ETTerminalMode getMode() { + return this.currentMode; + } + + public void setMode(ETTerminalMode mode) { + if (isClientSide()) { + this.currentMode = mode; + sendClientAction(ACTION_SET_MODE, mode); + } else { + this.currentMode = mode; + this.host.setMode(mode); + updateCurrentRecipeAndOutput(true); + } + } + + @Override + protected void updateCurrentRecipeAndOutput(boolean forceUpdate) { + switch (this.currentMode) { + case CRAFTING -> updateCraftingOutput(forceUpdate); + case SMITHING -> updateSmithingOutput(forceUpdate); + case STONECUTTING -> updateStonecuttingOutput(forceUpdate); + case ANVIL -> updateAnvilOutput(forceUpdate); + } + } + + @Override + public void clearCraftingGrid() { + clearInventory(this.craftingSlots[0]); + } + + @Override + public appeng.menu.SlotSemantic getCraftingGridSlotSemantic() { + return this.menuType.getSlotSemanticGrid(); + } + + @Override + public appeng.menu.SlotSemantic getOutputSlotSemantic() { + return this.menuType.getSlotSemanticResult(); + } + + @Override + public int getCraftingGridSize() { + return this.menuType.getGridSize(); + } + + @Override + public int getCraftingGridWidth() { + return this.menuType.getGridSideLength(); + } + + @Override + public int getCraftingGridHeight() { + return this.menuType.getGridSideLength(); + } + + public void clearSmithingGrid() { + clearInventory(this.smithingTemplateSlot); + clearInventory(this.smithingBaseSlot); + clearInventory(this.smithingAdditionSlot); + } + + private void clearInventory(AppEngSlot slot) { + Preconditions.checkState(isClientSide()); + var packet = new InventoryActionPacket(InventoryAction.MOVE_REGION, slot.index, 0); + NetworkHandler.instance().sendToServer(packet); + } + + @Override + public InternalInventory getCraftingMatrix() { + return getInventory(this.menuType.getCraftingInventory()); + } + + public InternalInventory getSmithingInventory() { + return getInventory(SMITHING_INVENTORY); + } + + public InternalInventory getStoneCutterInventory() { + return getInventory(STONECUTTER_INVENTORY); + } + + public InternalInventory getInventory(ResourceLocation id) { + return this.craftingInventoryHost.getSubInventory(id); + } + + @Override + public void doAction(ServerPlayer player, InventoryAction action, int slot, long id) { + if (this.getSlot(slot) instanceof ETCraftingBaseSlot craftingSlot) { + switch (action) { + case CRAFT_SHIFT, CRAFT_ALL, CRAFT_ITEM, CRAFT_STACK -> craftingSlot.doClick(action, player); + default -> { + } + } + return; + } + if (this.getSlot(slot) instanceof ETAnvilSlot) { + return; + } + super.doAction(player, action, slot, id); + } + + private void updateCraftingOutput(boolean forceUpdate) { + if (checkCraftingOnlyActive()) { + return; + } + + boolean changed = forceUpdate; + for (int i = 0; i < this.craftingSlots.length; i++) { + var stack = this.craftingSlots[i].getItem(); + if (!ItemStack.isSameItemSameTags(stack, this.craftingRecipeContainer.getItem(i))) { + this.craftingRecipeContainer.setItem(i, stack.copy()); + changed = true; + } + } + + if (!changed) { + return; + } + + var level = this.getPlayerInventory().player.level(); + this.currentRecipe = level.getRecipeManager().getRecipeFor(RecipeType.CRAFTING, this.craftingRecipeContainer, level) + .orElse(null); + this.craftingRecipe = this.currentRecipe; + if (this.craftingRecipe == null) { + this.outputSlot.set(ItemStack.EMPTY); + } else { + this.outputSlot.set(this.craftingRecipe.assemble(this.craftingRecipeContainer, level.registryAccess())); + } + } + + public @Nullable SmithingRecipe getSmithingRecipe() { + return this.smithingRecipe; + } + + private void updateSmithingOutput(boolean forceUpdate) { + var input = new SimpleContainer( + this.smithingTemplateSlot.getItem().copy(), + this.smithingBaseSlot.getItem().copy(), + this.smithingAdditionSlot.getItem().copy()); + var level = getPlayer().level(); + this.smithingRecipe = level.getRecipeManager().getRecipeFor(RecipeType.SMITHING, input, level).orElse(null); + if (this.smithingRecipe == null) { + this.smithingOutputSlot.set(ItemStack.EMPTY); + } else { + this.smithingOutputSlot.set(this.smithingRecipe.assemble(input, level.registryAccess())); + } + } + + private void updateStonecuttingOutput(boolean forceUpdate) { + this.stoneCutterRecipes.clear(); + var input = this.stonecuttingSlot.getItem(); + if (input.isEmpty()) { + this.stoneCutterRecipeId = null; + this.stoneCutterOutputSlot.set(ItemStack.EMPTY); + return; + } + updateStonecutterRecipes(); + if (this.stoneCutterRecipeId != null) { + var recipe = this.getPlayer().level().getRecipeManager().byKey(this.stoneCutterRecipeId); + if (recipe.isPresent() && recipe.get() instanceof StonecutterRecipe stonecutterRecipe) { + this.stoneCutterOutputSlot.set(stonecutterRecipe.getResultItem(this.getPlayer().level().registryAccess())); + return; + } + } + this.stoneCutterOutputSlot.set(ItemStack.EMPTY); + } + + public void updateStonecutterRecipes() { + this.stoneCutterRecipes.clear(); + var input = this.stonecuttingSlot.getItem(); + if (input.isEmpty()) { + return; + } + + var level = this.getPlayer().level(); + this.stoneCutterRecipes.addAll(level.getRecipeManager().getRecipesFor(RecipeType.STONECUTTING, new SimpleContainer(input), level)); + if (this.stoneCutterRecipeId != null + && this.stoneCutterRecipes.stream().noneMatch(recipe -> recipe.getId().equals(this.stoneCutterRecipeId))) { + this.stoneCutterRecipeId = null; + } + } + + public void setStoneCutterRecipeId(ResourceLocation stoneCutterRecipeId) { + if (isClientSide()) { + this.stoneCutterRecipeId = stoneCutterRecipeId; + sendClientAction(ACTION_SET_STONECUTTING_RECIPE_ID, stoneCutterRecipeId); + return; + } + + this.stoneCutterRecipeId = stoneCutterRecipeId; + this.host.setStoneCutterRecipeId(stoneCutterRecipeId); + var recipe = getPlayer().level().getRecipeManager().byKey(stoneCutterRecipeId); + if (recipe.isPresent() && recipe.get() instanceof StonecutterRecipe stonecutterRecipe) { + this.stoneCutterOutputSlot.set(stonecutterRecipe.getResultItem(getPlayer().level().registryAccess())); + } else { + this.stoneCutterOutputSlot.set(ItemStack.EMPTY); + } + } + + public @Nullable ResourceLocation getStoneCutterRecipeId() { + return this.stoneCutterRecipeId; + } + + public List getStoneCutterRecipes() { + return this.stoneCutterRecipes; + } + + private void updateAnvilOutput(boolean forceUpdate) { + if (this.handlingAnvilTake) { + return; + } + this.anvilDelegate.slots.get(0).set(this.anvilLeftSlot.getItem()); + this.anvilDelegate.slots.get(1).set(this.anvilRightSlot.getItem()); + this.anvilDelegate.createResult(); + this.anvilOutputSlot.set(this.anvilDelegate.getResultItem()); + this.anvilCost = this.anvilDelegate.getCost(); + } + + public int getAnvilCost() { + return this.anvilCost; + } + + public void setAnvilItemName(String name) { + if (isServerSide()) { + this.anvilDelegate.slots.get(0).set(this.anvilLeftSlot.getItem()); + this.anvilDelegate.slots.get(1).set(this.anvilRightSlot.getItem()); + if (this.anvilDelegate.setItemName(name)) { + updateCurrentRecipeAndOutput(true); + } + } else { + sendClientAction(ACTION_SET_ANVIL_ITEM_NAME, name); + } + } + + public void onAnvilTake(Runnable updateLogic) { + this.handlingAnvilTake = true; + try { + updateLogic.run(); + } finally { + this.handlingAnvilTake = false; + } + updateAnvilOutput(true); + } + + @Override + public boolean hasIngredient(Ingredient ingredient, Object2IntOpenHashMap reservedAmounts) { + List slots = ETTerminalMode.loadableValues().stream() + .map(ETTerminalMode::getSlotSemantics) + .flatMap(Collection::stream) + .map(this::getSlots) + .flatMap(Collection::stream) + .toList(); + + for (var slot : slots) { + var stackInSlot = slot.getItem(); + if (!stackInSlot.isEmpty() && ingredient.test(stackInSlot)) { + var reservedAmount = reservedAmounts.getOrDefault(slot, 0); + if (stackInSlot.getCount() > reservedAmount) { + reservedAmounts.merge(slot, 1, Integer::sum); + return true; + } + } + } + + return super.hasIngredient(ingredient, reservedAmounts); + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/ETTerminalMode.java b/src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/ETTerminalMode.java new file mode 100644 index 0000000..ffea21b --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/ETTerminalMode.java @@ -0,0 +1,57 @@ +package me.myogoo.extendedterminal.menu.extendedterminal; + +import appeng.menu.SlotSemantic; +import me.myogoo.extendedterminal.config.ExtendedTerminalConfig; +import me.myogoo.extendedterminal.menu.ETMenuType; +import me.myogoo.extendedterminal.menu.ETSlotSemantics; +import me.myogoo.extendedterminal.part.extendedterminal.ETTerminalPart; +import net.minecraft.resources.ResourceLocation; + +import java.util.Arrays; +import java.util.List; + +public enum ETTerminalMode { + CRAFTING(ExtendedTerminalConfig.INSTANCE.getExtendedTerminalConfig().enableCraftingPanel()), + STONECUTTING(ExtendedTerminalConfig.INSTANCE.getExtendedTerminalConfig().enableStonecutterPanel()), + SMITHING(ExtendedTerminalConfig.INSTANCE.getExtendedTerminalConfig().enableSmithingPanel()), + ANVIL(ExtendedTerminalConfig.INSTANCE.getExtendedTerminalConfig().enableAnvilPanel()); + + private final boolean enabled; + + ETTerminalMode(boolean enabled) { + this.enabled = enabled; + } + + public boolean canLoad() { + return this.enabled; + } + + public ResourceLocation getInventoryId() { + return switch (this) { + case CRAFTING -> ETMenuType.ET_TERMINAL.getCraftingInventory(); + case STONECUTTING -> ETTerminalPart.STONECUTTER_INVENTORY; + case SMITHING -> ETTerminalPart.SMITHING_INVENTORY; + case ANVIL -> ETTerminalPart.ANVIL_INVENTORY; + }; + } + + public List getSlotSemantics() { + return switch (this) { + case CRAFTING -> List.of(ETMenuType.ET_TERMINAL.getSlotSemanticGrid()); + case STONECUTTING -> List.of(ETSlotSemantics.STONECUTTING_INPUT); + case SMITHING -> List.of( + ETSlotSemantics.SMITHING_TABLE_TEMPLATE, + ETSlotSemantics.SMITHING_TABLE_BASE, + ETSlotSemantics.SMITHING_TABLE_ADDITION); + case ANVIL -> List.of(ETSlotSemantics.ANVIL_LEFT_INPUT, ETSlotSemantics.ANVIL_RIGHT_INPUT); + }; + } + + public static List loadableValues() { + var list = Arrays.stream(values()).filter(ETTerminalMode::canLoad).toList(); + if (list.isEmpty()) { + throw new IllegalStateException("No ETTerminalModes are loadable"); + } + return list; + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/FakeAnvilMenu.java b/src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/FakeAnvilMenu.java new file mode 100644 index 0000000..14607dc --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/FakeAnvilMenu.java @@ -0,0 +1,29 @@ +package me.myogoo.extendedterminal.menu.extendedterminal; + +import net.minecraft.world.Container; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AnvilMenu; +import net.minecraft.world.item.ItemStack; + +public class FakeAnvilMenu extends AnvilMenu { + public FakeAnvilMenu(int containerId, Inventory playerInventory) { + super(containerId, playerInventory); + } + + public ItemStack getResultItem() { + return slots.get(2).getItem(); + } + + public Container getInputSlots() { + return this.inputSlots; + } + + public void et$onTake(Player player, ItemStack stack) { + super.onTake(player, stack); + } + + public boolean et$mayPickup(Player player, boolean stack) { + return super.mayPickup(player, stack); + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/slot/ETAnvilSlot.java b/src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/slot/ETAnvilSlot.java new file mode 100644 index 0000000..e921a20 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/slot/ETAnvilSlot.java @@ -0,0 +1,44 @@ +package me.myogoo.extendedterminal.menu.extendedterminal.slot; + +import appeng.api.inventories.InternalInventory; +import appeng.menu.slot.AppEngCraftingSlot; +import me.myogoo.extendedterminal.menu.ETSlotSemantics; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; +import me.myogoo.extendedterminal.menu.extendedterminal.FakeAnvilMenu; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; + +public class ETAnvilSlot extends AppEngCraftingSlot { + private final FakeAnvilMenu anvilDelegate; + private final Slot leftInput; + private final Slot rightInput; + + public ETAnvilSlot(Player player, InternalInventory anvilInv, FakeAnvilMenu anvilDelegate, ETTerminalMenu menu) { + super(player, anvilInv); + this.anvilDelegate = anvilDelegate; + this.setMenu(menu); + this.leftInput = getMenu().getSlots(ETSlotSemantics.ANVIL_LEFT_INPUT).get(0); + this.rightInput = getMenu().getSlots(ETSlotSemantics.ANVIL_RIGHT_INPUT).get(0); + } + + @Override + public void onTake(Player player, ItemStack stack) { + anvilDelegate.et$onTake(player, stack); + + ItemStack newLeft = anvilDelegate.slots.get(0).getItem().copy(); + ItemStack newRight = anvilDelegate.slots.get(1).getItem().copy(); + + if (this.getMenu() instanceof ETTerminalMenu terminalMenu) { + terminalMenu.onAnvilTake(() -> { + leftInput.set(newLeft); + rightInput.set(newRight); + }); + } + } + + @Override + public boolean mayPickup(Player player) { + return anvilDelegate.et$mayPickup(player, super.mayPickup(player)); + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/slot/ETSmithingSlot.java b/src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/slot/ETSmithingSlot.java new file mode 100644 index 0000000..ad4ff87 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/slot/ETSmithingSlot.java @@ -0,0 +1,175 @@ +package me.myogoo.extendedterminal.menu.extendedterminal.slot; + +import appeng.api.config.Actionable; +import appeng.api.config.PowerMultiplier; +import appeng.api.inventories.InternalInventory; +import appeng.api.networking.energy.IEnergySource; +import appeng.api.networking.security.IActionSource; +import appeng.api.stacks.AEItemKey; +import appeng.api.stacks.KeyCounter; +import appeng.api.storage.MEStorage; +import appeng.helpers.IMenuCraftingPacket; +import appeng.items.storage.ViewCellItem; +import appeng.util.prioritylist.IPartitionList; +import me.myogoo.extendedterminal.menu.ETMenuType; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; +import me.myogoo.extendedterminal.menu.slot.ETCraftingBaseSlot; +import net.minecraft.core.NonNullList; +import net.minecraft.world.SimpleContainer; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.SmithingRecipe; +import net.minecraft.world.item.crafting.RecipeType; +import net.minecraft.world.level.Level; +import net.minecraftforge.common.ForgeHooks; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class ETSmithingSlot extends ETCraftingBaseSlot { + private static final int SMITHING_SLOT_SIZE = 3; + + public ETSmithingSlot(Player player, IActionSource mySrc, IEnergySource energySrc, MEStorage storage, + InternalInventory cMatrix, InternalInventory secondMatrix, IMenuCraftingPacket ccp) { + super(player, mySrc, energySrc, storage, cMatrix, secondMatrix, ccp, ETMenuType.ET_TERMINAL); + } + + @Override + protected SmithingRecipe findRecipe(SimpleContainer ic, Level level) { + if (this.menu instanceof ETTerminalMenu terminalMenu) { + var recipe = terminalMenu.getSmithingRecipe(); + if (recipe != null && recipe.matches(ic, level)) { + return recipe; + } + } + return level.getRecipeManager().getRecipeFor(RecipeType.SMITHING, ic, level).orElse(null); + } + + protected NonNullList getETRemainingItems(SimpleContainer ic, Level level) { + var recipe = findRecipe(ic, level); + if (recipe != null && recipe.matches(ic, level)) { + return recipe.getRemainingItems(ic); + } + return NonNullList.create(); + } + + @Override + protected void makeItem(Player player, ItemStack stack) { + this.checkTakeAchievements(stack); + + var input = new SimpleContainer( + this.craftInv.getStackInSlot(0), + this.craftInv.getStackInSlot(1), + this.craftInv.getStackInSlot(2)); + + ForgeHooks.setCraftingPlayer(player); + var remainingItems = this.getETRemainingItems(input, player.level()); + ForgeHooks.setCraftingPlayer(null); + + for (int i = 0; i < SMITHING_SLOT_SIZE; i++) { + this.craftInv.extractItem(i, 1, false); + if (i < remainingItems.size()) { + var remainingInSlot = remainingItems.get(i); + if (!remainingInSlot.isEmpty()) { + if (this.craftInv.getStackInSlot(i).isEmpty()) { + this.craftInv.setItemDirect(i, remainingInSlot); + } else if (!player.getInventory().add(remainingInSlot)) { + player.drop(remainingInSlot, false); + } + } + } + } + } + + @Override + protected ItemStack craftItem(Player player, MEStorage inv, KeyCounter all) { + var result = this.getItem().copy(); + if (result.isEmpty()) { + return ItemStack.EMPTY; + } + + final var extractedInputs = new ItemStack[this.getPattern().size()]; + Arrays.fill(extractedInputs, ItemStack.EMPTY); + + var level = player.level(); + if (!level.isClientSide()) { + var input = new SimpleContainer( + this.getPattern().getStackInSlot(0).copy(), + this.getPattern().getStackInSlot(1).copy(), + this.getPattern().getStackInSlot(2).copy()); + var recipe = this.findRecipe(input, level); + if (recipe == null) { + return ItemStack.EMPTY; + } + + result = recipe.assemble(input, level.registryAccess()); + if (inv != null) { + var filter = ViewCellItem.createItemFilter(this.menu.getViewCells()); + for (var slot = 0; slot < this.getPattern().size(); slot++) { + if (!this.getPattern().getStackInSlot(slot).isEmpty()) { + extractedInputs[slot] = extractItemsByRecipe(this.energySrc, this.mySrc, inv, level, recipe, + result, List.of( + this.getPattern().getStackInSlot(0).copy(), + this.getPattern().getStackInSlot(1).copy(), + this.getPattern().getStackInSlot(2).copy()), + this.getPattern().getStackInSlot(slot), slot, all, filter); + } + } + } + } + + this.makeItem(player, result); + this.postCraft(player, inv, extractedInputs, result); + player.containerMenu.slotsChanged(this.craftInv.toContainer()); + return result; + } + + private static ItemStack extractItemsByRecipe(IEnergySource energySrc, IActionSource mySrc, MEStorage src, + Level level, SmithingRecipe recipe, ItemStack output, List craftingItems, + ItemStack providedTemplate, int slot, KeyCounter items, IPartitionList filter) { + if (energySrc.extractAEPower(1, Actionable.SIMULATE, PowerMultiplier.CONFIG) <= 0.9) { + return ItemStack.EMPTY; + } + if (providedTemplate == null) { + return ItemStack.EMPTY; + } + + var requested = AEItemKey.of(providedTemplate); + if (filter == null || filter.isListed(requested)) { + var extracted = src.extract(requested, 1, Actionable.MODULATE, mySrc); + if (extracted > 0) { + energySrc.extractAEPower(1, Actionable.MODULATE, PowerMultiplier.CONFIG); + return requested.toStack(); + } + } + + var checkFuzzy = providedTemplate.getTags().findAny().isEmpty() || providedTemplate.isDamageableItem(); + if (items != null && checkFuzzy) { + var craftingInputItems = new ArrayList<>(craftingItems); + for (var entry : items) { + if (entry.getKey() instanceof AEItemKey itemKey) { + if (providedTemplate.getItem() == itemKey.getItem() && !itemKey.matches(output)) { + craftingInputItems.set(slot, itemKey.toStack()); + var adjustedCraftingInput = new SimpleContainer( + craftingInputItems.get(0), + craftingInputItems.get(1), + craftingInputItems.get(2)); + if (recipe.matches(adjustedCraftingInput, level) + && ItemStack.matches(recipe.assemble(adjustedCraftingInput, level.registryAccess()), output)) { + if (filter == null || filter.isListed(itemKey)) { + var extracted = src.extract(itemKey, 1, Actionable.MODULATE, mySrc); + if (extracted > 0) { + energySrc.extractAEPower(1, Actionable.MODULATE, PowerMultiplier.CONFIG); + return itemKey.toStack(); + } + } + } + } + } + } + } + + return ItemStack.EMPTY; + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/slot/ETStoneCutterSlot.java b/src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/slot/ETStoneCutterSlot.java new file mode 100644 index 0000000..d7733e9 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/slot/ETStoneCutterSlot.java @@ -0,0 +1,162 @@ +package me.myogoo.extendedterminal.menu.extendedterminal.slot; + +import appeng.api.config.Actionable; +import appeng.api.config.PowerMultiplier; +import appeng.api.inventories.InternalInventory; +import appeng.api.networking.energy.IEnergySource; +import appeng.api.networking.security.IActionSource; +import appeng.api.stacks.AEItemKey; +import appeng.api.stacks.KeyCounter; +import appeng.api.storage.MEStorage; +import appeng.helpers.IMenuCraftingPacket; +import appeng.items.storage.ViewCellItem; +import appeng.util.prioritylist.IPartitionList; +import me.myogoo.extendedterminal.menu.ETMenuType; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; +import me.myogoo.extendedterminal.menu.slot.ETCraftingBaseSlot; +import net.minecraft.core.NonNullList; +import net.minecraft.world.SimpleContainer; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.StonecutterRecipe; +import net.minecraft.world.item.crafting.RecipeType; +import net.minecraft.world.level.Level; +import net.minecraftforge.common.ForgeHooks; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class ETStoneCutterSlot extends ETCraftingBaseSlot { + public ETStoneCutterSlot(Player player, IActionSource mySrc, IEnergySource energySrc, MEStorage storage, + InternalInventory cMatrix, InternalInventory secondMatrix, IMenuCraftingPacket ccp) { + super(player, mySrc, energySrc, storage, cMatrix, secondMatrix, ccp, ETMenuType.ET_TERMINAL); + } + + @Override + protected StonecutterRecipe findRecipe(SimpleContainer ic, Level level) { + if (!(menu instanceof ETTerminalMenu terminalMenu)) { + return null; + } + + var recipeId = terminalMenu.getStoneCutterRecipeId(); + if (recipeId == null) { + return null; + } + + var recipe = level.getRecipeManager().byKey(recipeId); + if (recipe.isPresent() && recipe.get() instanceof StonecutterRecipe stonecutterRecipe) { + return stonecutterRecipe; + } + return null; + } + + protected NonNullList getETRemainingItems(SimpleContainer ic, Level level) { + var recipe = findRecipe(ic, level); + if (recipe != null && recipe.matches(ic, level)) { + return recipe.getRemainingItems(ic); + } + return NonNullList.of(ItemStack.EMPTY); + } + + @Override + protected void makeItem(Player player, ItemStack stack) { + this.checkTakeAchievements(stack); + + var input = new SimpleContainer(this.craftInv.getStackInSlot(0)); + ForgeHooks.setCraftingPlayer(player); + var remainingItems = this.getETRemainingItems(input, player.level()); + ForgeHooks.setCraftingPlayer(null); + + this.craftInv.extractItem(0, 1, false); + if (!remainingItems.isEmpty()) { + var remainingInSlot = remainingItems.get(0); + if (!remainingInSlot.isEmpty()) { + if (this.craftInv.getStackInSlot(0).isEmpty()) { + this.craftInv.setItemDirect(0, remainingInSlot); + } else if (!player.getInventory().add(remainingInSlot)) { + player.drop(remainingInSlot, false); + } + } + } + } + + @Override + protected ItemStack craftItem(Player player, MEStorage inv, KeyCounter all) { + var result = this.getItem().copy(); + if (result.isEmpty()) { + return ItemStack.EMPTY; + } + + final var extractedInputs = new ItemStack[this.getPattern().size()]; + Arrays.fill(extractedInputs, ItemStack.EMPTY); + + var level = player.level(); + if (!level.isClientSide()) { + var input = new SimpleContainer(this.getPattern().getStackInSlot(0).copy()); + var recipe = this.findRecipe(input, level); + if (recipe == null) { + return ItemStack.EMPTY; + } + + result = recipe.assemble(input, level.registryAccess()); + if (inv != null && !this.getPattern().getStackInSlot(0).isEmpty()) { + var filter = ViewCellItem.createItemFilter(this.menu.getViewCells()); + extractedInputs[0] = extractItemsByRecipe(this.energySrc, this.mySrc, inv, level, recipe, result, + List.of(this.getPattern().getStackInSlot(0).copy()), this.getPattern().getStackInSlot(0), 0, all, + filter); + } + } + + this.makeItem(player, result); + this.postCraft(player, inv, extractedInputs, result); + player.containerMenu.slotsChanged(this.craftInv.toContainer()); + return result; + } + + private static ItemStack extractItemsByRecipe(IEnergySource energySrc, IActionSource mySrc, MEStorage src, + Level level, StonecutterRecipe recipe, ItemStack output, List craftingItems, + ItemStack providedTemplate, int slot, KeyCounter items, IPartitionList filter) { + if (energySrc.extractAEPower(1, Actionable.SIMULATE, PowerMultiplier.CONFIG) <= 0.9) { + return ItemStack.EMPTY; + } + if (providedTemplate == null) { + return ItemStack.EMPTY; + } + + var requested = AEItemKey.of(providedTemplate); + if (filter == null || filter.isListed(requested)) { + var extracted = src.extract(requested, 1, Actionable.MODULATE, mySrc); + if (extracted > 0) { + energySrc.extractAEPower(1, Actionable.MODULATE, PowerMultiplier.CONFIG); + return requested.toStack(); + } + } + + var checkFuzzy = providedTemplate.getTags().findAny().isEmpty() || providedTemplate.isDamageableItem(); + if (items != null && checkFuzzy) { + var craftingInputItems = new ArrayList<>(craftingItems); + for (var entry : items) { + if (entry.getKey() instanceof AEItemKey itemKey) { + if (providedTemplate.getItem() == itemKey.getItem() && !itemKey.matches(output)) { + craftingInputItems.set(slot, itemKey.toStack()); + var adjustedCraftingInput = new SimpleContainer(craftingInputItems.get(0)); + if (recipe.matches(adjustedCraftingInput, level) + && ItemStack.matches(recipe.assemble(adjustedCraftingInput, level.registryAccess()), output)) { + if (filter == null || filter.isListed(itemKey)) { + var extracted = src.extract(itemKey, 1, Actionable.MODULATE, mySrc); + if (extracted > 0) { + energySrc.extractAEPower(1, Actionable.MODULATE, PowerMultiplier.CONFIG); + return itemKey.toStack(); + } + } + } + } + } + } + } + + return ItemStack.EMPTY; + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/wt/ETWTMenu.java b/src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/wt/ETWTMenu.java new file mode 100644 index 0000000..24ec9c7 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/wt/ETWTMenu.java @@ -0,0 +1,35 @@ +package me.myogoo.extendedterminal.menu.extendedterminal.wt; + +import appeng.menu.slot.RestrictedInputSlot; +import de.mari_023.ae2wtlib.AE2wtlibSlotSemantics; +import de.mari_023.ae2wtlib.terminal.WTMenuHost; +import de.mari_023.ae2wtlib.wut.ItemWUT; +import appeng.menu.implementations.MenuTypeBuilder; +import me.myogoo.extendedterminal.me.host.ETWTHost; +import me.myogoo.extendedterminal.menu.ETMenuType; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.inventory.MenuType; + +public class ETWTMenu extends ETTerminalMenu { + public static final MenuType TYPE = MenuTypeBuilder + .create(ETWTMenu::new, ETWTHost.class) + .build(ETMenuType.ET_TERMINAL.getWTIdAsString()); + + public ETWTMenu(int id, Inventory ip, ETWTHost host) { + super(TYPE, id, ip, host); + addSlot(new RestrictedInputSlot( + RestrictedInputSlot.PlacableItemType.QE_SINGULARITY, + host.getSubInventory(WTMenuHost.INV_SINGULARITY), + 0), AE2wtlibSlotSemantics.SINGULARITY); + } + + @Override + public ETWTHost getHost() { + return (ETWTHost) super.getHost(); + } + + public boolean isWUT() { + return ((WTMenuHost) getHost()).getItemStack().getItem() instanceof ItemWUT; + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/menu/slot/ETCraftingBaseSlot.java b/src/main/java/me/myogoo/extendedterminal/menu/slot/ETCraftingBaseSlot.java index fb47e57..a2fede0 100644 --- a/src/main/java/me/myogoo/extendedterminal/menu/slot/ETCraftingBaseSlot.java +++ b/src/main/java/me/myogoo/extendedterminal/menu/slot/ETCraftingBaseSlot.java @@ -19,7 +19,6 @@ import net.minecraft.core.NonNullList; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; -import net.minecraft.world.inventory.CraftingContainer; import net.minecraft.world.inventory.TransientCraftingContainer; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Recipe; @@ -29,7 +28,7 @@ import java.util.ArrayList; import java.util.List; -public abstract class ETCraftingBaseSlot,I extends CraftingContainer> extends AppEngCraftingSlot { +public abstract class ETCraftingBaseSlot, I> extends AppEngCraftingSlot { protected final InternalInventory craftInv; private final InternalInventory pattern; diff --git a/src/main/java/me/myogoo/extendedterminal/mixin/GuideMeAddonMixin.java b/src/main/java/me/myogoo/extendedterminal/mixin/GuideMeAddonMixin.java deleted file mode 100644 index 83ecf22..0000000 --- a/src/main/java/me/myogoo/extendedterminal/mixin/GuideMeAddonMixin.java +++ /dev/null @@ -1,25 +0,0 @@ -package me.myogoo.extendedterminal.mixin; - -import appeng.core.AppEngClient; -import com.llamalad7.mixinextras.injector.wrapoperation.Operation; -import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; -import guideme.Guide; -import guideme.GuideBuilder; -import guideme.compiler.TagCompiler; -import me.myogoo.extendedterminal.integration.guideme.ConditionTag; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -@Mixin(value = AppEngClient.class, remap = false) -public class GuideMeAddonMixin { - @WrapOperation( - method = "createGuide", - at = @At( - value = "INVOKE", - target = "Lguideme/GuideBuilder;build()Lguideme/Guide;" - ), remap = false) - private Guide et$createGuide(GuideBuilder instance, Operation original) { - instance.extension(TagCompiler.EXTENSION_POINT, new ConditionTag()); - return original.call(instance); - } -} diff --git a/src/main/java/me/myogoo/extendedterminal/mixin/NetworkHandlerMixin.java b/src/main/java/me/myogoo/extendedterminal/mixin/NetworkHandlerMixin.java deleted file mode 100644 index 07833cb..0000000 --- a/src/main/java/me/myogoo/extendedterminal/mixin/NetworkHandlerMixin.java +++ /dev/null @@ -1,34 +0,0 @@ -package me.myogoo.extendedterminal.mixin; - -import appeng.core.sync.BasePacket; -import appeng.core.sync.BasePacketHandler; -import appeng.core.sync.network.NetworkHandler; -import com.mojang.logging.LogUtils; -import me.myogoo.extendedterminal.network.NetworkPacketType; -import net.minecraft.network.FriendlyByteBuf; -import org.slf4j.Logger; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(value = NetworkHandler.class) -public class NetworkHandlerMixin { - private static Logger LOGGER = LogUtils.getLogger(); - - @Inject(method = "deserializePacket", at = @At(value = "HEAD"), remap = false, cancellable = true) - private static void deserializePacket(FriendlyByteBuf payload, CallbackInfoReturnable cir) { - cir.cancel(); - var packetId = payload.readInt(); - if (packetId < BasePacketHandler.PacketTypes.values().length) { - cir.setReturnValue(BasePacketHandler.PacketTypes.getPacket(packetId).parsePacket(payload)); - } - if(packetId >= NetworkPacketType.ET_PACKET_START_ID) { - if(NetworkPacketType.get(packetId).isPresent()) { - cir.setReturnValue(NetworkPacketType.get(packetId).get().parsePacket(payload)); - } else { - LOGGER.error("Unknown packet id: " + packetId + " from " + NetworkHandler.class.getName()); - } - } - } -} \ No newline at end of file diff --git a/src/main/java/me/myogoo/extendedterminal/network/NetworkPacketType.java b/src/main/java/me/myogoo/extendedterminal/network/NetworkPacketType.java deleted file mode 100644 index a922fe8..0000000 --- a/src/main/java/me/myogoo/extendedterminal/network/NetworkPacketType.java +++ /dev/null @@ -1,43 +0,0 @@ -package me.myogoo.extendedterminal.network; - -import appeng.core.sync.BasePacket; -import me.myogoo.extendedterminal.network.serverbound.ETFillCraftingGridFromRecipePacket; -import net.minecraft.network.FriendlyByteBuf; - -import java.util.HashMap; -import java.util.Optional; -import java.util.function.Function; - -public class NetworkPacketType { - public static int ET_PACKET_START_ID = 10000; - - public enum PacketIDs { - TABLE_FILL_CRAFTING_GRID(10000); - - private final int value; - - PacketIDs(int value) { - this.value = value; - } - public int getValue() { - return value; - } - } - - private static final HashMap packetMap = new HashMap<>() { - { - put(PacketIDs.TABLE_FILL_CRAFTING_GRID.value,new Packet(ETFillCraftingGridFromRecipePacket.class, ETFillCraftingGridFromRecipePacket::new)); - } - }; - - public static Optional get(int packetId) { - Packet packet = packetMap.get(packetId); - return Optional.ofNullable(packet); - } - - public record Packet(Class clazz, Function factory) { - public BasePacket parsePacket(FriendlyByteBuf payload) { - return factory.apply(payload); - } - } -} diff --git a/src/main/java/me/myogoo/extendedterminal/network/serverbound/ETFillCraftingGridFromRecipePacket.java b/src/main/java/me/myogoo/extendedterminal/network/serverbound/ETFillCraftingGridFromRecipePacket.java index 4a90ba4..96312b6 100644 --- a/src/main/java/me/myogoo/extendedterminal/network/serverbound/ETFillCraftingGridFromRecipePacket.java +++ b/src/main/java/me/myogoo/extendedterminal/network/serverbound/ETFillCraftingGridFromRecipePacket.java @@ -7,17 +7,16 @@ import appeng.api.stacks.KeyCounter; import appeng.api.storage.MEStorage; import appeng.api.storage.StorageHelper; -import appeng.core.sync.BasePacket; import appeng.helpers.IMenuCraftingPacket; import appeng.items.storage.ViewCellItem; import appeng.util.prioritylist.IPartitionList; import com.google.common.base.Preconditions; import com.google.common.primitives.Ints; -import io.netty.buffer.Unpooled; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; import me.myogoo.extendedterminal.integration.ItemListTermCraftingHelper; -import me.myogoo.extendedterminal.network.NetworkPacketType; +import me.myogoo.myotus.api.network.IMyotusPacket; +import me.myogoo.myotus.api.network.MyoPacketContext; import me.myogoo.extendedterminal.util.extendedcrafting.TableCraftingHelper; import net.minecraft.core.NonNullList; import net.minecraft.network.FriendlyByteBuf; @@ -32,20 +31,22 @@ -public class ETFillCraftingGridFromRecipePacket extends FillRecipeBasePacket { +public class ETFillCraftingGridFromRecipePacket extends FillRecipeBasePacket implements IMyotusPacket { public static final int NOT_SET_RECIPE_SIZE = -1; - private @Nullable ResourceLocation recipeId = null; - private List ingredientTemplates; - private boolean craftMissing; - private int recipeWidth; - private int recipeHeight; + private final @Nullable ResourceLocation recipeId; + private final List ingredientTemplates; + private final boolean craftMissing; + private final int recipeWidth; + private final int recipeHeight; public ETFillCraftingGridFromRecipePacket(FriendlyByteBuf stream) { + ResourceLocation decodedRecipeId = null; if (stream.readBoolean()) { - recipeId = stream.readResourceLocation(); + decodedRecipeId = stream.readResourceLocation(); } + this.recipeId = decodedRecipeId; ingredientTemplates = NonNullList.withSize(stream.readInt(), ItemStack.EMPTY); for (int i = 0; i < ingredientTemplates.size(); i++) { ingredientTemplates.set(i, stream.readItem()); @@ -63,29 +64,41 @@ public ETFillCraftingGridFromRecipePacket( int recipeWidth, int recipeHeight ) { - var stream = new FriendlyByteBuf(Unpooled.buffer()); - // set packetID - stream.writeInt(NetworkPacketType.PacketIDs.TABLE_FILL_CRAFTING_GRID.getValue()); - if (recipeId != null) { + this.recipeId = recipeId; + this.ingredientTemplates = List.copyOf(ingredientTemplates); + this.craftMissing = craftMissing; + this.recipeWidth = recipeWidth; + this.recipeHeight = recipeHeight; + } + + @Override + public void write(FriendlyByteBuf stream) { + if (this.recipeId != null) { stream.writeBoolean(true); - stream.writeResourceLocation(recipeId); + stream.writeResourceLocation(this.recipeId); } else { stream.writeBoolean(false); } - stream.writeInt(ingredientTemplates.size()); - for (var ingredientTemplate : ingredientTemplates) { + stream.writeInt(this.ingredientTemplates.size()); + for (var ingredientTemplate : this.ingredientTemplates) { stream.writeItem(ingredientTemplate); } - stream.writeBoolean(craftMissing); - stream.writeInt(recipeWidth); - stream.writeInt(recipeHeight); + stream.writeBoolean(this.craftMissing); + stream.writeInt(this.recipeWidth); + stream.writeInt(this.recipeHeight); + } - configureWrite(stream); + public static void handle(ETFillCraftingGridFromRecipePacket packet, MyoPacketContext context) { + var player = context.sender(); + if (player == null) { + return; + } + + packet.handleOnServer(player); } - @Override - public void serverPacketData(ServerPlayer player) { + private void handleOnServer(ServerPlayer player) { // Setup and verification var menu = player.containerMenu; if (!(menu instanceof IMenuCraftingPacket cct)) { diff --git a/src/main/java/me/myogoo/extendedterminal/network/serverbound/ETFillSmithingGridFromRecipePacket.java b/src/main/java/me/myogoo/extendedterminal/network/serverbound/ETFillSmithingGridFromRecipePacket.java new file mode 100644 index 0000000..c8f18e7 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/network/serverbound/ETFillSmithingGridFromRecipePacket.java @@ -0,0 +1,207 @@ +package me.myogoo.extendedterminal.network.serverbound; + +import appeng.api.networking.crafting.ICraftingService; +import appeng.api.networking.storage.IStorageService; +import appeng.api.stacks.AEItemKey; +import appeng.api.stacks.KeyCounter; +import appeng.api.storage.MEStorage; +import appeng.api.storage.StorageHelper; +import appeng.helpers.IMenuCraftingPacket; +import appeng.items.storage.ViewCellItem; +import com.google.common.primitives.Ints; +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntList; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMode; +import me.myogoo.myotus.api.network.IMyotusPacket; +import me.myogoo.myotus.api.network.MyoPacketContext; +import net.minecraft.core.NonNullList; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.Recipe; +import net.minecraft.world.item.crafting.SmithingRecipe; +import org.jetbrains.annotations.Nullable; + +import java.util.LinkedHashMap; +import java.util.List; + +public class ETFillSmithingGridFromRecipePacket extends FillRecipeBasePacket implements IMyotusPacket { + private final @Nullable ResourceLocation recipeId; + private final NonNullList ingredientTemplates; + private final boolean craftMissing; + + public ETFillSmithingGridFromRecipePacket(FriendlyByteBuf stream) { + ResourceLocation decodedRecipeId = null; + if (stream.readBoolean()) { + decodedRecipeId = stream.readResourceLocation(); + } + this.recipeId = decodedRecipeId; + this.ingredientTemplates = NonNullList.withSize(stream.readInt(), ItemStack.EMPTY); + for (int i = 0; i < this.ingredientTemplates.size(); i++) { + this.ingredientTemplates.set(i, stream.readItem()); + } + this.craftMissing = stream.readBoolean(); + } + + public ETFillSmithingGridFromRecipePacket(@Nullable ResourceLocation recipeId, + NonNullList ingredientTemplates, boolean craftMissing) { + this.recipeId = recipeId; + this.ingredientTemplates = NonNullList.withSize(ingredientTemplates.size(), ItemStack.EMPTY); + for (int i = 0; i < ingredientTemplates.size(); i++) { + this.ingredientTemplates.set(i, ingredientTemplates.get(i)); + } + this.craftMissing = craftMissing; + } + + @Override + public void write(FriendlyByteBuf stream) { + if (this.recipeId != null) { + stream.writeBoolean(true); + stream.writeResourceLocation(this.recipeId); + } else { + stream.writeBoolean(false); + } + + stream.writeInt(this.ingredientTemplates.size()); + for (var ingredientTemplate : this.ingredientTemplates) { + stream.writeItem(ingredientTemplate); + } + stream.writeBoolean(this.craftMissing); + } + + public static void handle(ETFillSmithingGridFromRecipePacket packet, MyoPacketContext context) { + var player = context.sender(); + if (player == null) { + return; + } + + packet.handleOnServer(player); + } + + private void handleOnServer(ServerPlayer player) { + var menu = player.containerMenu; + if (!(menu instanceof ETTerminalMenu cct)) { + return; + } + + @Nullable + var node = cct.getNetworkNode(); + if (node == null) { + return; + } + + var energy = node.getGrid().getEnergyService(); + @Nullable ICraftingService craftingService = node.getGrid().getCraftingService(); + @Nullable IStorageService storageService = node.getGrid().getStorageService(); + if (storageService == null) { + return; + } + + MEStorage networkStorage = storageService.getInventory(); + KeyCounter cachedStorage = storageService.getCachedInventory(); + var craftMatrix = cct.getSmithingInventory(); + var filter = ViewCellItem.createItemFilter(cct.getViewCells()); + var ingredients = getDesiredIngredients(player); + + var toAutoCraft = new LinkedHashMap(); + boolean touchedGridStorage = false; + + for (int x = 0; x < craftMatrix.size(); x++) { + var currentItem = craftMatrix.getStackInSlot(x); + var ingredient = x < ingredients.size() ? ingredients.get(x) : Ingredient.EMPTY; + + if (!currentItem.isEmpty()) { + if (ingredient.test(currentItem)) { + continue; + } + + var in = AEItemKey.of(currentItem); + var inserted = StorageHelper.poweredInsert(energy, networkStorage, in, currentItem.getCount(), + cct.getActionSource()); + if (inserted > 0) { + touchedGridStorage = true; + } + if (inserted < currentItem.getCount()) { + currentItem = currentItem.copy(); + currentItem.shrink((int) inserted); + } else { + currentItem = ItemStack.EMPTY; + } + + player.getInventory().add(currentItem); + craftMatrix.setItemDirect(x, currentItem.isEmpty() ? ItemStack.EMPTY : currentItem); + } + + if (ingredient.isEmpty()) { + continue; + } + + if (currentItem.isEmpty()) { + var request = findBestMatchingItemStack(ingredient, filter, cachedStorage); + for (var what : request) { + var extracted = StorageHelper.poweredExtraction(energy, networkStorage, what, 1, + cct.getActionSource()); + if (extracted > 0) { + touchedGridStorage = true; + currentItem = what.toStack(Ints.saturatedCast(extracted)); + break; + } + } + } + + if (currentItem.isEmpty()) { + currentItem = takeIngredientFromPlayer(cct, player, ingredient); + } + + if (currentItem.isEmpty()) { + currentItem = takeIngredientFromOtherGrid(cct, ingredient); + } + + craftMatrix.setItemDirect(x, currentItem); + + if (currentItem.isEmpty() && this.craftMissing && craftingService != null) { + int slot = x; + findCraftableKey(ingredient, craftingService).ifPresent(key -> + toAutoCraft.computeIfAbsent(key, ignored -> new IntArrayList()).add(slot)); + } + } + + menu.slotsChanged(craftMatrix.toContainer()); + + if (!toAutoCraft.isEmpty()) { + if (touchedGridStorage) { + storageService.invalidateCache(); + } + + var stacks = toAutoCraft.entrySet().stream() + .map(entry -> new IMenuCraftingPacket.AutoCraftEntry(entry.getKey(), entry.getValue())) + .toList(); + cct.startAutoCrafting(stacks); + } + + cct.setMode(ETTerminalMode.SMITHING); + } + + @Override + protected NonNullList getDesiredIngredients(Player player) { + if (this.recipeId != null) { + var optionalRecipe = player.level().getRecipeManager().byKey(this.recipeId); + if (optionalRecipe.isPresent() && optionalRecipe.get() instanceof SmithingRecipe recipe) { + return recipe.getIngredients(); + } + } + + var ingredients = NonNullList.withSize(this.ingredientTemplates.size(), Ingredient.EMPTY); + for (int i = 0; i < this.ingredientTemplates.size(); i++) { + var template = this.ingredientTemplates.get(i); + if (!template.isEmpty()) { + ingredients.set(i, Ingredient.of(template)); + } + } + return ingredients; + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/network/serverbound/ETFillStonecutterGridFromRecipePacket.java b/src/main/java/me/myogoo/extendedterminal/network/serverbound/ETFillStonecutterGridFromRecipePacket.java new file mode 100644 index 0000000..45108c5 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/network/serverbound/ETFillStonecutterGridFromRecipePacket.java @@ -0,0 +1,200 @@ +package me.myogoo.extendedterminal.network.serverbound; + +import appeng.api.networking.crafting.ICraftingService; +import appeng.api.networking.storage.IStorageService; +import appeng.api.stacks.AEItemKey; +import appeng.api.stacks.KeyCounter; +import appeng.api.storage.MEStorage; +import appeng.api.storage.StorageHelper; +import appeng.helpers.IMenuCraftingPacket; +import appeng.items.storage.ViewCellItem; +import com.google.common.primitives.Ints; +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntList; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMode; +import me.myogoo.myotus.api.network.IMyotusPacket; +import me.myogoo.myotus.api.network.MyoPacketContext; +import net.minecraft.core.NonNullList; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.Recipe; +import net.minecraft.world.item.crafting.StonecutterRecipe; +import org.jetbrains.annotations.Nullable; + +import java.util.LinkedHashMap; + +public class ETFillStonecutterGridFromRecipePacket extends FillRecipeBasePacket implements IMyotusPacket { + private final @Nullable ResourceLocation recipeId; + private final ItemStack ingredientTemplate; + private final boolean craftMissing; + + public ETFillStonecutterGridFromRecipePacket(FriendlyByteBuf stream) { + ResourceLocation decodedRecipeId = null; + if (stream.readBoolean()) { + decodedRecipeId = stream.readResourceLocation(); + } + this.recipeId = decodedRecipeId; + this.ingredientTemplate = stream.readItem(); + this.craftMissing = stream.readBoolean(); + } + + public ETFillStonecutterGridFromRecipePacket(@Nullable ResourceLocation recipeId, ItemStack ingredientTemplate, + boolean craftMissing) { + this.recipeId = recipeId; + this.ingredientTemplate = ingredientTemplate.copy(); + this.craftMissing = craftMissing; + } + + @Override + public void write(FriendlyByteBuf stream) { + if (this.recipeId != null) { + stream.writeBoolean(true); + stream.writeResourceLocation(this.recipeId); + } else { + stream.writeBoolean(false); + } + stream.writeItem(this.ingredientTemplate); + stream.writeBoolean(this.craftMissing); + } + + public static void handle(ETFillStonecutterGridFromRecipePacket packet, MyoPacketContext context) { + var player = context.sender(); + if (player == null) { + return; + } + + packet.handleOnServer(player); + } + + private void handleOnServer(ServerPlayer player) { + var menu = player.containerMenu; + if (!(menu instanceof ETTerminalMenu cct)) { + return; + } + + @Nullable + var node = cct.getNetworkNode(); + if (node == null) { + return; + } + + var energy = node.getGrid().getEnergyService(); + @Nullable ICraftingService craftingService = node.getGrid().getCraftingService(); + @Nullable IStorageService storageService = node.getGrid().getStorageService(); + if (storageService == null) { + return; + } + + MEStorage networkStorage = storageService.getInventory(); + KeyCounter cachedStorage = storageService.getCachedInventory(); + var craftMatrix = cct.getStoneCutterInventory(); + var filter = ViewCellItem.createItemFilter(cct.getViewCells()); + var ingredients = getDesiredIngredients(player); + + var toAutoCraft = new LinkedHashMap(); + boolean touchedGridStorage = false; + + for (int x = 0; x < craftMatrix.size(); x++) { + var currentItem = craftMatrix.getStackInSlot(x); + var ingredient = ingredients.isEmpty() ? Ingredient.EMPTY : ingredients.get(0); + + if (!currentItem.isEmpty()) { + if (ingredient.test(currentItem)) { + if (this.recipeId != null && !this.recipeId.equals(cct.getStoneCutterRecipeId())) { + cct.setStoneCutterRecipeId(this.recipeId); + } + continue; + } + + var in = AEItemKey.of(currentItem); + var inserted = StorageHelper.poweredInsert(energy, networkStorage, in, currentItem.getCount(), + cct.getActionSource()); + if (inserted > 0) { + touchedGridStorage = true; + } + if (inserted < currentItem.getCount()) { + currentItem = currentItem.copy(); + currentItem.shrink((int) inserted); + } else { + currentItem = ItemStack.EMPTY; + } + + player.getInventory().add(currentItem); + craftMatrix.setItemDirect(x, currentItem.isEmpty() ? ItemStack.EMPTY : currentItem); + } + + if (ingredient.isEmpty()) { + continue; + } + + if (currentItem.isEmpty()) { + var request = findBestMatchingItemStack(ingredient, filter, cachedStorage); + for (var what : request) { + var extracted = StorageHelper.poweredExtraction(energy, networkStorage, what, 1, + cct.getActionSource()); + if (extracted > 0) { + touchedGridStorage = true; + currentItem = what.toStack(Ints.saturatedCast(extracted)); + break; + } + } + } + + if (currentItem.isEmpty()) { + currentItem = takeIngredientFromPlayer(cct, player, ingredient); + } + + if (currentItem.isEmpty()) { + currentItem = takeIngredientFromOtherGrid(cct, ingredient); + } + + craftMatrix.setItemDirect(x, currentItem); + + if (!currentItem.isEmpty()) { + cct.setStoneCutterRecipeId(this.recipeId); + } + + if (currentItem.isEmpty() && this.craftMissing && craftingService != null) { + int slot = x; + findCraftableKey(ingredient, craftingService).ifPresent(key -> + toAutoCraft.computeIfAbsent(key, ignored -> new IntArrayList()).add(slot)); + } + } + + menu.slotsChanged(craftMatrix.toContainer()); + + if (!toAutoCraft.isEmpty()) { + if (touchedGridStorage) { + storageService.invalidateCache(); + } + + var stacks = toAutoCraft.entrySet().stream() + .map(entry -> new IMenuCraftingPacket.AutoCraftEntry(entry.getKey(), entry.getValue())) + .toList(); + cct.startAutoCrafting(stacks); + } + + cct.setMode(ETTerminalMode.STONECUTTING); + } + + @Override + protected NonNullList getDesiredIngredients(Player player) { + if (this.recipeId != null) { + var optionalRecipe = player.level().getRecipeManager().byKey(this.recipeId); + if (optionalRecipe.isPresent() && optionalRecipe.get() instanceof StonecutterRecipe recipe) { + return recipe.getIngredients(); + } + } + + var ingredients = NonNullList.withSize(1, Ingredient.EMPTY); + if (!this.ingredientTemplate.isEmpty()) { + ingredients.set(0, Ingredient.of(this.ingredientTemplate)); + } + return ingredients; + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/network/serverbound/FillRecipeBasePacket.java b/src/main/java/me/myogoo/extendedterminal/network/serverbound/FillRecipeBasePacket.java index 4c088f3..1738940 100644 --- a/src/main/java/me/myogoo/extendedterminal/network/serverbound/FillRecipeBasePacket.java +++ b/src/main/java/me/myogoo/extendedterminal/network/serverbound/FillRecipeBasePacket.java @@ -4,7 +4,6 @@ import appeng.api.networking.crafting.ICraftingService; import appeng.api.stacks.AEItemKey; import appeng.api.stacks.KeyCounter; -import appeng.core.sync.BasePacket; import appeng.helpers.IMenuCraftingPacket; import appeng.util.prioritylist.IPartitionList; import net.minecraft.core.NonNullList; @@ -18,7 +17,7 @@ import java.util.Objects; import java.util.Optional; -public abstract class FillRecipeBasePacket extends BasePacket { +public abstract class FillRecipeBasePacket implements IETFillRecipeBasePacket { protected abstract NonNullList getDesiredIngredients(Player player); protected ItemStack takeIngredientFromPlayer(IMenuCraftingPacket cct, ServerPlayer player, Ingredient ingredient) { diff --git a/src/main/java/me/myogoo/extendedterminal/network/serverbound/IETFillRecipeBasePacket.java b/src/main/java/me/myogoo/extendedterminal/network/serverbound/IETFillRecipeBasePacket.java new file mode 100644 index 0000000..09d0e06 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/network/serverbound/IETFillRecipeBasePacket.java @@ -0,0 +1,35 @@ +package me.myogoo.extendedterminal.network.serverbound; + +import appeng.helpers.IMenuCraftingPacket; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMode; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.Ingredient; + +public interface IETFillRecipeBasePacket { + default ItemStack takeIngredientFromOtherGrid(IMenuCraftingPacket cct, Ingredient ingredient) { + if (!(cct instanceof ETTerminalMenu menu)) { + return ItemStack.EMPTY; + } + + var currentMode = menu.getMode(); + for (var mode : ETTerminalMode.loadableValues()) { + if (mode == currentMode) { + continue; + } + + var inventory = menu.getInventory(mode.getInventoryId()); + for (int i = 0; i < inventory.size(); i++) { + var item = inventory.getStackInSlot(i); + if (ingredient.test(item)) { + var result = item.split(1); + if (!result.isEmpty()) { + return result; + } + } + } + } + + return ItemStack.EMPTY; + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/part/extendedterminal/ETTerminalPart.java b/src/main/java/me/myogoo/extendedterminal/part/extendedterminal/ETTerminalPart.java new file mode 100644 index 0000000..5e06c16 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/part/extendedterminal/ETTerminalPart.java @@ -0,0 +1,174 @@ +package me.myogoo.extendedterminal.part.extendedterminal; + +import appeng.api.inventories.InternalInventory; +import appeng.api.parts.IPartItem; +import appeng.api.parts.IPartModel; +import appeng.items.parts.PartModels; +import appeng.parts.PartModel; +import appeng.util.inv.AppEngInternalInventory; +import me.myogoo.extendedterminal.ExtendedTerminal; +import me.myogoo.extendedterminal.api.host.IETTerminalHost; +import me.myogoo.extendedterminal.config.ExtendedTerminalConfig; +import me.myogoo.extendedterminal.menu.ETMenuType; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMode; +import me.myogoo.extendedterminal.part.ETTerminalBasePart; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.Tag; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.item.ItemStack; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class ETTerminalPart extends ETTerminalBasePart implements IETTerminalHost { + @PartModels + public static final ResourceLocation MODEL_OFF = ExtendedTerminal.makeId("part/extendedterminal/extended_terminal_off"); + @PartModels + public static final ResourceLocation MODEL_ON = ExtendedTerminal.makeId("part/extendedterminal/extended_terminal_on"); + + public static final IPartModel MODELS_OFF = new PartModel(MODEL_BASE, MODEL_OFF, MODEL_STATUS_OFF); + public static final IPartModel MODELS_ON = new PartModel(MODEL_BASE, MODEL_ON, MODEL_STATUS_ON); + public static final IPartModel MODELS_HAS_CHANNEL = new PartModel(MODEL_BASE, MODEL_ON, MODEL_STATUS_HAS_CHANNEL); + + public static final ResourceLocation SMITHING_INVENTORY = ExtendedTerminal.makeId("smithing_crafting_inventory"); + public static final ResourceLocation STONECUTTER_INVENTORY = ExtendedTerminal.makeId("stonecutter_crafting_inventory"); + public static final ResourceLocation ANVIL_INVENTORY = ExtendedTerminal.makeId("anvil_inventory"); + + private final AppEngInternalInventory smithingGrid = new AppEngInternalInventory(this, 3); + private final AppEngInternalInventory stoneCutterGrid = new AppEngInternalInventory(this, 1); + private final AppEngInternalInventory anvilInv = new AppEngInternalInventory(this, 2); + + private ETTerminalMode mode; + @Nullable + private ResourceLocation stonecuttingRecipeId; + private boolean isLoading; + + public ETTerminalPart(IPartItem partItem) { + super(partItem, ETMenuType.ET_TERMINAL, ExtendedTerminalConfig.INSTANCE.getExtendedTerminalConfig()); + this.mode = ETTerminalMode.loadableValues().get(0); + } + + @Override + public void clearContent() { + super.clearContent(); + this.smithingGrid.clear(); + this.stoneCutterGrid.clear(); + this.anvilInv.clear(); + } + + @Override + public MenuType getMenuType(Player p) { + return ETTerminalMenu.TYPE; + } + + @Override + public IPartModel getStaticModels() { + return this.selectModel(MODELS_ON, MODELS_OFF, MODELS_HAS_CHANNEL); + } + + @Override + public InternalInventory getSubInventory(ResourceLocation id) { + if (id.equals(SMITHING_INVENTORY)) { + return this.smithingGrid; + } else if (id.equals(STONECUTTER_INVENTORY)) { + return this.stoneCutterGrid; + } else if (id.equals(ANVIL_INVENTORY)) { + return this.anvilInv; + } + return super.getSubInventory(id); + } + + @Override + public void writeToNBT(CompoundTag data) { + super.writeToNBT(data); + data.putString("mode", this.mode.name()); + if (this.stonecuttingRecipeId != null) { + data.putString("stonecuttingRecipeId", this.stonecuttingRecipeId.toString()); + } + this.smithingGrid.writeToNBT(data, "smithingGrid"); + this.stoneCutterGrid.writeToNBT(data, "stoneCutterGrid"); + this.anvilInv.writeToNBT(data, "anvilInv"); + } + + @Override + public void readFromNBT(CompoundTag data) { + this.isLoading = true; + try { + super.readFromNBT(data); + try { + this.mode = ETTerminalMode.valueOf(data.getString("mode")); + } catch (IllegalArgumentException ignored) { + this.mode = ETTerminalMode.loadableValues().get(0); + } + + if (data.contains("stonecuttingRecipeId", Tag.TAG_STRING)) { + this.stonecuttingRecipeId = new ResourceLocation(data.getString("stonecuttingRecipeId")); + } else { + this.stonecuttingRecipeId = null; + } + + this.smithingGrid.readFromNBT(data, "smithingGrid"); + this.stoneCutterGrid.readFromNBT(data, "stoneCutterGrid"); + this.anvilInv.readFromNBT(data, "anvilInv"); + } finally { + this.isLoading = false; + } + } + + @Override + public void saveChanges() { + if (!this.isLoading) { + super.saveChanges(); + } + } + + @Override + public void addAdditionalDrops(List drops, boolean wrenched) { + super.addAdditionalDrops(drops, wrenched); + for (var is : this.smithingGrid) { + if (!is.isEmpty()) { + drops.add(is); + } + } + for (var is : this.stoneCutterGrid) { + if (!is.isEmpty()) { + drops.add(is); + } + } + for (var is : this.anvilInv) { + if (!is.isEmpty()) { + drops.add(is); + } + } + } + + @Override + public ETTerminalMode getMode() { + return this.mode; + } + + @Override + public void setMode(ETTerminalMode mode) { + this.mode = mode; + this.saveChanges(); + } + + @Override + public @Nullable ResourceLocation getStoneCutterRecipeId() { + return this.stonecuttingRecipeId; + } + + @Override + public void setStoneCutterRecipeId(@Nullable ResourceLocation stonecuttingRecipeId) { + this.stonecuttingRecipeId = stonecuttingRecipeId; + this.saveChanges(); + } + + @Override + protected IPartModel selectModel(IPartModel offModels, IPartModel onModels, IPartModel hasChannelModels) { + return super.selectModel(MODELS_OFF, MODELS_ON, MODELS_HAS_CHANNEL); + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/util/SafeClass.java b/src/main/java/me/myogoo/extendedterminal/util/SafeClass.java index 637680b..f1f823b 100644 --- a/src/main/java/me/myogoo/extendedterminal/util/SafeClass.java +++ b/src/main/java/me/myogoo/extendedterminal/util/SafeClass.java @@ -8,7 +8,7 @@ public class SafeClass { public static Class forName(String name) { try { return Class.forName(name); - } catch (ClassNotFoundException e) { + } catch (ClassNotFoundException | LinkageError e) { ExtendedTerminal.LOGGER.error("Can't find Class for : {}", String.valueOf(e)); return null; } diff --git a/src/main/java/me/myogoo/extendedterminal/util/mod/ModIntegrationManager.java b/src/main/java/me/myogoo/extendedterminal/util/mod/ModIntegrationManager.java deleted file mode 100644 index ab61aee..0000000 --- a/src/main/java/me/myogoo/extendedterminal/util/mod/ModIntegrationManager.java +++ /dev/null @@ -1,66 +0,0 @@ -package me.myogoo.extendedterminal.util.mod; - -import me.myogoo.extendedterminal.ExtendedTerminal; -import org.slf4j.Logger; - -import java.lang.annotation.Annotation; -import java.util.HashMap; -import java.util.Map; - -/** - * 다른 모드와의 호환성 및 연동을 관리하는 유틸리티 클래스. - * 어떤 모드가 로드되었는지 확인하고, 관련 어노테이션을 활성화합니다. - */ -public final class ModIntegrationManager { // final 클래스로 변경하여 상속 방지 - private static final Logger LOGGER = ExtendedTerminal.LOGGER; - - private static final Map> activeIntegrations = new HashMap<>(); - - public static void initialize() { - LOGGER.info("Checking for mod integrations..."); - activeIntegrations.clear(); - - for (SupportedMod mod : SupportedMod.values()) { - if (mod.isLoaded()) { - activeIntegrations.put(mod, mod.getAnnotationClass()); - LOGGER.info("Integration enabled for: {}", mod.name()); - } - } - } - - public static Class getClass(SupportedMod mod) { - return activeIntegrations.get(mod); - } - - public static Class getClass(String modId) { - for (var value : activeIntegrations.values()) { - if(value.getSimpleName().equals(modId)) { - return value; - } - } - return null; - } - - /** - * 특정 어노테이션 클래스에 해당하는 모드 연동이 활성화되었는지 확인합니다. - * - * @param annotationClass 확인할 어노테이션 클래스 - * @return 활성화 여부 - */ - public static boolean isLoaded(Class annotationClass) { - return activeIntegrations.containsValue(annotationClass); - } - - /** - * 특정 SupportedMod Enum에 해당하는 모드 연동이 활성화되었는지 확인합니다. - * - * @param mod 확인할 SupportedMod - * @return 활성화 여부 - */ - public static boolean isLoaded(SupportedMod mod) { - return activeIntegrations.containsKey(mod); - } - - // 유틸리티 클래스이므로 인스턴스화 방지 - private ModIntegrationManager() {} -} \ No newline at end of file diff --git a/src/main/java/me/myogoo/extendedterminal/util/mod/SupportedMod.java b/src/main/java/me/myogoo/extendedterminal/util/mod/SupportedMod.java deleted file mode 100644 index f946e92..0000000 --- a/src/main/java/me/myogoo/extendedterminal/util/mod/SupportedMod.java +++ /dev/null @@ -1,50 +0,0 @@ -package me.myogoo.extendedterminal.util.mod; - -import me.myogoo.extendedterminal.api.ModAccessor.*; -import net.minecraftforge.fml.ModList; -import net.minecraftforge.forgespi.language.IModInfo; - -import java.lang.annotation.Annotation; -import java.util.function.Predicate; - -public enum SupportedMod { - - //AE2WTLib("ae2wtlib", ModAccessor.AE2WTLib.class), - - ExtendedCrafting("extendedcrafting", ExtendedCrafting.class), - EpicExCrafting("extendedcrafting", EpicExCrafting.class, "Extended Crafting: Expanded"), - ReAvaritia("avaritia", ReAvaritia.class, "Re-Avaritia"), - AvaritiaNeo("avaritia", AvaritiaNeo.class, "Avaritia"); - - private final String modId; - private final Class annotationClass; - private final Predicate customLoadCondition; - - SupportedMod(String modId, Class annotationClass) { - this(modId, annotationClass, modInfo -> true); - } - - SupportedMod(String modId, Class annotationClass, String displayModName) { - this(modId, annotationClass, modInfo -> displayModName.equals(modInfo.getDisplayName())); - } - - SupportedMod(String modId, Class annotationClass, Predicate customLoadCondition) { - this.modId = modId; - this.annotationClass = annotationClass; - this.customLoadCondition = customLoadCondition; - } - - public String getModId() { - return modId; - } - - public Class getAnnotationClass() { - return annotationClass; - } - - public boolean isLoaded() { - return ModList.get().getModContainerById(modId) - .map(container -> customLoadCondition.test(container.getModInfo())) - .orElse(false); - } -} diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index 980353d..bb05f0a 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -62,6 +62,13 @@ versionRange = "${minecraft_version_range}" ordering = "NONE" side = "BOTH" +[[dependencies."${mod_id}"]] +modId = "myotus" +mandatory = true +versionRange = "${myotus_version_range}" +ordering = "AFTER" +side = "BOTH" + [[dependencies."${mod_id}"]] modId="ae2" mandatory = true diff --git a/src/main/resources/assets/ae2/screens/et_terminal.json b/src/main/resources/assets/ae2/screens/et_terminal.json new file mode 100644 index 0000000..d6d6816 --- /dev/null +++ b/src/main/resources/assets/ae2/screens/et_terminal.json @@ -0,0 +1,90 @@ +{ + "includes": [ + "terminals/terminal.json", + "panels/crafting.json", + "panels/stonecutter.json", + "panels/smithingtable.json", + "panels/anvil.json" + ], + "slots": { + "PLAYER_INVENTORY": { + "left": 8, + "bottom": 92, + "grid": "BREAK_AFTER_9COLS" + }, + "PLAYER_HOTBAR": { + "left": 8, + "bottom": 34, + "grid": "HORIZONTAL" + } + }, + "text": { + "crafting_grid_title": { + "text": { + "translate": "gui.extendedterminal.et_terminal" + }, + "position": { + "left": 8, + "bottom": 177 + } + }, + "player_inventory_title": { + "text": { + "translate": "container.inventory" + }, + "position": { + "left": 8, + "bottom": 103 + } + } + }, + "terminalStyle": { + "header": { + "texture": "guis/crafting.png", + "srcRect": [ + 0, + 0, + 195, + 17 + ] + }, + "firstRow": { + "texture": "guis/crafting.png", + "srcRect": [ + 0, + 17, + 195, + 18 + ] + }, + "row": { + "texture": "guis/crafting.png", + "srcRect": [ + 0, + 35, + 195, + 18 + ] + }, + "lastRow": { + "texture": "guis/crafting.png", + "srcRect": [ + 0, + 53, + 195, + 18 + ] + }, + "bottom": { + "texture": "guis/crafting.png", + "srcRect": [ + 0, + 71, + 195, + 180 + ] + } + }, + "widgets": { + } +} \ No newline at end of file diff --git a/src/main/resources/assets/ae2/screens/panels/anvil.json b/src/main/resources/assets/ae2/screens/panels/anvil.json new file mode 100644 index 0000000..6a770ce --- /dev/null +++ b/src/main/resources/assets/ae2/screens/panels/anvil.json @@ -0,0 +1,38 @@ +{ + "slots" : { + "ET_ANVIL_LEFT_INPUT": { + "left": 15, + "bottom": 140 + }, + "ET_ANVIL_RIGHT_INPUT": { + "left": 67, + "bottom": 140 + }, + "ANVIL_RESULT": { + "left": 134, + "bottom": 140 + } + }, + "widgets" : { + "ET_ANVIL_NAME_FIELD": { + "left": 70, + "bottom": 159, + "width": 89, + "height": 12 + }, + "modeTabButtonAnvilPanel": { + "left": 173, + "bottom": 112, + "width": 22, + "height": 22 + }, + "modePanelAnvilPanel": { + "left": 9, + "bottom": 166 + }, + "ET_ANVIL_COST_LABEL" : { + "left": 10, + "bottom": 110 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/ae2/screens/panels/crafting.json b/src/main/resources/assets/ae2/screens/panels/crafting.json new file mode 100644 index 0000000..c66daa0 --- /dev/null +++ b/src/main/resources/assets/ae2/screens/panels/crafting.json @@ -0,0 +1,33 @@ +{ + "slots": { + "CRAFTING_GRID": { + "left": 26, + "bottom": 158, + "grid": "BREAK_AFTER_3COLS" + }, + "CRAFTING_RESULT": { + "left": 134, + "bottom": 140 + } + }, + "widgets": { + "clearCraftingGrid": { + "left": 81, + "bottom": 159 + }, + "clearToPlayerInv": { + "left": 91, + "bottom": 159 + }, + "modeTabButtonCraftingPanel": { + "left": 173, + "bottom": 174, + "width": 22, + "height": 22 + }, + "modePanelCraftingPanel": { + "left": 9, + "bottom": 166 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/ae2/screens/panels/smithingtable.json b/src/main/resources/assets/ae2/screens/panels/smithingtable.json new file mode 100644 index 0000000..a3eafa9 --- /dev/null +++ b/src/main/resources/assets/ae2/screens/panels/smithingtable.json @@ -0,0 +1,40 @@ +{ + "slots": { + "ET_SMITHING_TABLE_TEMPLATE": { + "left": 26, + "bottom": 140 + }, + "ET_SMITHING_TABLE_BASE": { + "left": 44, + "bottom": 140 + }, + "ET_SMITHING_TABLE_ADDITION": { + "left": 62, + "bottom": 140 + }, + "SMITHING_TABLE_RESULT": { + "left": 134, + "bottom": 140 + } + }, + "widgets": { + "modeTabButtonSmithingTablePanel": { + "left": 173, + "bottom": 153, + "width": 22, + "height": 22 + }, + "modePanelSmithingTablePanel": { + "left": 9, + "bottom": 166 + }, + "clearSmithingGrid": { + "left" : 60, + "bottom" : 151 + }, + "clearSmithingGridToPlayerInv": { + "left" : 71, + "bottom" : 151 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/ae2/screens/panels/stonecutter.json b/src/main/resources/assets/ae2/screens/panels/stonecutter.json new file mode 100644 index 0000000..d3a076e --- /dev/null +++ b/src/main/resources/assets/ae2/screens/panels/stonecutter.json @@ -0,0 +1,29 @@ +{ + "slots": { + "ET_STONECUTTING_INPUT": { + "left": 15, + "bottom": 140 + }, + "STONECUTTING_RESULT": { + "left": 134, + "bottom": 140 + } + }, + "widgets": { + "stonecuttingPatternModeScrollbar": { + "left": 117, + "bottom": 156, + "height": 50 + }, + "modeTabButtonStoneCutterPanel": { + "left": 173, + "bottom": 132, + "width": 22, + "height": 22 + }, + "modePanelStoneCutterPanel": { + "left": 9, + "bottom": 166 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/ae2/screens/wireless_et_terminal.json b/src/main/resources/assets/ae2/screens/wireless_et_terminal.json new file mode 100644 index 0000000..ca2e7ce --- /dev/null +++ b/src/main/resources/assets/ae2/screens/wireless_et_terminal.json @@ -0,0 +1,6 @@ +{ + "includes": [ + "et_terminal.json", + "wtlib/universal_terminal_with_viewcells.json" + ] +} diff --git a/src/main/resources/assets/ae2/textures/guis/et_terminal_panel.png b/src/main/resources/assets/ae2/textures/guis/et_terminal_panel.png new file mode 100644 index 0000000000000000000000000000000000000000..1831a610e8bc18c1d26505063f4fd02fcc83cfbd GIT binary patch literal 2797 zcmeHJdo`rMCY7_hbvpgs_nhzVd%yR4zxUqn{oH$JesL!| zsi_cE003$(&JG>`$U#yLD4}qv%v)3g7bL>N$sTa(bqC-^K4`7$S^%yjs)_;>;9kRh zgO_7)=++!FI?b zL^^s$deQg$8fO|mjo=6he(M#W)WJ00|f;0G-yo|pK(%86|3czzH^nU%9Q2>vU6oEXHG+AM0 zg5T~%^fS*ug;g@8dcq?jTYaT^&QpK|UFJUzuF z8l{a@Xnl9tmbKW@~S66qhCjTGyrCHRigL~ByY209KL*D`L#E>T{lMDUYuyYj{liK5O| zgS?0RThlUEC-#L--C#efQZ>h!Y$R#j>g$YNL~AM&JJ|Xam@*5)%i9e2^$Vj}6+>w; zy+?>>`ZB0IT(D+zFRQCnNFJkNQUc|iEI-;KXa)!9Za}QH3-5n98KIQ6+se*AYWY(# zX)p7-ieyQjU)%9Ibi6?(O(E^CEf+d>=QS8Blq`N{1Ntvytu3nk=qP{MPrkni z+ww!FM09j>Y8}IXnMl_hmL_9)aZ?sBl47GIekUJG0zDHVS0%hW1o@dG9pUZ!ZC!_( zHr`*Myz>%xcz%2sC$KSIGd5{I4`=eXHFCXaVj^kOAD2Bm`}=5?&E46zGbo&)Q4zUu zFIbH+w6AA;NC;Z2-);A8z_UO6RzoYPNEU=wS^YRu<{Sd(%tCbA*cMkENPv% zt@x_{Z411*Bt%!F&K{1{(2rAYRK;+tCF1PDt{z2ZWflhj`6VF)aPNOvcjwuO?MIp< zhM3mX=+csjV>0w_Q8jWTQdp`}!e^Y}qqY?hoAW0PQSU}Grr75WgU=xgJ#nQuK_E-J zx6MtP8~-sUKS^aHhbs?OG=RBY-JL#)D1(hGuK_&*d=K}Xc^&j-o=s`B)s{-2L~bzw z@u}u`X3ustRNvy0tODua{z$`LPU`pxU7G z40x;^-Pf0474_HM3fLGA7%~^K#6rxH6>(v;E`cj-7?asuz-+K>#q8`l0OF*S5*mC* z9g<7)y=J+DgKgT8-P7zK5MaB`?N0AQb07Es<5MeBkYesMX4o&oi)z5Zde6)_z3)w* q=V6`e^Ag`qXLkB;(fFEZNEFt$xO$vY^CV#Z!(1H64jg;`_ Date: Sun, 12 Apr 2026 22:18:25 +0900 Subject: [PATCH 02/11] fix: ACTION_CLEAR_TO_PLAYER crash --- .../me/myogoo/extendedterminal/menu/ETTerminalBaseMenu.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/me/myogoo/extendedterminal/menu/ETTerminalBaseMenu.java b/src/main/java/me/myogoo/extendedterminal/menu/ETTerminalBaseMenu.java index 2d789b4..ce76d11 100644 --- a/src/main/java/me/myogoo/extendedterminal/menu/ETTerminalBaseMenu.java +++ b/src/main/java/me/myogoo/extendedterminal/menu/ETTerminalBaseMenu.java @@ -35,7 +35,7 @@ public ETTerminalBaseMenu(MenuType menuType, int id, Inventory ip, ITerminalH super(menuType, id, ip, host); this.menuType = etMenuType; this.config = config; - registerClientAction(ACTION_CLEAR_TO_PLAYER, this::clearToPlayerInventory); + registerClientAction(ACTION_CLEAR_TO_PLAYER, ResourceLocation.class, this::clearToPlayerInventory); } public R getCurrentRecipe() { From 35dfbe2ead53df80b1cd5edadf2eb738dc3ddaa1 Mon Sep 17 00:00:00 2001 From: njoyshadow Date: Sun, 12 Apr 2026 22:27:22 +0900 Subject: [PATCH 03/11] feat: add full charged wireless terminal in creativeTabs --- .../me/myogoo/extendedterminal/init/ETCreativeTab.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/me/myogoo/extendedterminal/init/ETCreativeTab.java b/src/main/java/me/myogoo/extendedterminal/init/ETCreativeTab.java index 07b51bf..0ab6bc2 100644 --- a/src/main/java/me/myogoo/extendedterminal/init/ETCreativeTab.java +++ b/src/main/java/me/myogoo/extendedterminal/init/ETCreativeTab.java @@ -1,7 +1,9 @@ package me.myogoo.extendedterminal.init; +import appeng.api.config.Actionable; import appeng.core.definitions.AEParts; import appeng.core.definitions.ItemDefinition; +import appeng.items.tools.powered.WirelessTerminalItem; import me.myogoo.extendedterminal.ExtendedTerminal; import me.myogoo.extendedterminal.init.wt.WTItems; import me.myogoo.myotus.api.annotation.wt.AE2WTLib; @@ -25,6 +27,11 @@ public class ETCreativeTab { if (ModIntegrationManager.isLoaded(AE2WTLib.class)) { for (ItemDefinition item : WTItems.WT_ITEMS) { output.accept(item.stack()); + var chargedStack = item.stack().copy(); + if(item.asItem() instanceof WirelessTerminalItem terminal) { + terminal.injectAEPower(chargedStack, terminal.getAEMaxPower(chargedStack), Actionable.MODULATE); + output.accept(chargedStack); + } } } }) From 8c812e6ed693adfe86e7cee3f87559b49d025670 Mon Sep 17 00:00:00 2001 From: njoyshadow Date: Mon, 13 Apr 2026 23:09:22 +0900 Subject: [PATCH 04/11] feat: update assets and add curios slot --- build.gradle | 56 ++++++++++++++++++ .../gui/panels/StoneCutterPanel.java | 6 +- .../extendedterminal/init/ETCreativeTab.java | 2 +- .../ae2/textures/guis/et_terminal_panel.png | Bin 2797 -> 3524 bytes .../models/item/et_terminal.json | 2 +- .../extended_terminal_off.json | 3 +- .../extended_terminal_on.json | 1 + .../textures/item/charged_ender_pearl.png | Bin 580 -> 1823 bytes .../item/charged_ender_pearl.png.mcmeta | 39 ++++++++++++ .../textures/item/wireless_et_terminal.png | Bin 497 -> 505 bytes .../advanced_terminal_front.png | Bin 449 -> 424 bytes .../advanced_terminal_side.png | Bin 569 -> 431 bytes .../extendedcrafting/basic_terminal_front.png | Bin 449 -> 424 bytes .../extendedcrafting/basic_terminal_side.png | Bin 569 -> 431 bytes .../extendedcrafting/elite_terminal_front.png | Bin 449 -> 424 bytes .../extendedcrafting/elite_terminal_side.png | Bin 569 -> 435 bytes .../extendedcrafting/epic_terminal_front.png | Bin 448 -> 424 bytes .../extendedcrafting/epic_terminal_side.png | Bin 573 -> 431 bytes .../ultimate_terminal_front.png | Bin 449 -> 424 bytes .../ultimate_terminal_side.png | Bin 569 -> 431 bytes .../part/extendedterminal/et_bright.png | Bin 407 -> 416 bytes .../part/extendedterminal/et_dark.png | Bin 409 -> 400 bytes .../part/extendedterminal/et_medium.png | Bin 0 -> 405 bytes .../data/curios/tags/item/curio.json | 6 ++ 24 files changed, 109 insertions(+), 6 deletions(-) create mode 100644 src/main/resources/assets/extendedterminal/textures/item/charged_ender_pearl.png.mcmeta create mode 100644 src/main/resources/assets/extendedterminal/textures/part/extendedterminal/et_medium.png create mode 100644 src/main/resources/data/curios/tags/item/curio.json diff --git a/build.gradle b/build.gradle index 7c57f64..cdc3179 100644 --- a/build.gradle +++ b/build.gradle @@ -1,3 +1,6 @@ +import org.gradle.api.publish.maven.tasks.AbstractPublishToMaven +import org.gradle.api.publish.tasks.GenerateModuleMetadata + buildscript { repositories { // These repositories are only for Gradle plugins, put any other repositories in the repository block further below @@ -12,6 +15,7 @@ buildscript { plugins { id 'eclipse' id 'idea' + id 'maven-publish' id 'net.minecraftforge.gradle' version '[6.0.16,6.2)' } @@ -305,3 +309,55 @@ tasks.named('jar', Jar).configure { tasks.withType(JavaCompile).configureEach { options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation } + +def mappedVersionSuffixPattern = java.util.regex.Pattern.compile( + "_mapped_${java.util.regex.Pattern.quote(mapping_channel)}_${java.util.regex.Pattern.quote(mapping_version)}(?:_at_[A-Za-z0-9]+)?\$" +) + +publishing { + publications { + register('mavenJava', MavenPublication) { + groupId = project.mod_group_id + artifactId = project.mod_id + version = project.mod_version + from components.java + } + } + + publications.withType(MavenPublication).configureEach { + pom.withXml { + def dependenciesNode = asNode().get('dependencies')?.getAt(0) + dependenciesNode?.get('dependency')?.each { dependencyNode -> + def versionNode = dependencyNode.get('version')?.getAt(0) + if (versionNode != null) { + versionNode.setValue(versionNode.text().replaceFirst(mappedVersionSuffixPattern, '')) + } + } + } + } +} + +tasks.withType(AbstractPublishToMaven).configureEach { + dependsOn tasks.named('reobfJar') +} + +tasks.withType(GenerateModuleMetadata).configureEach { + enabled = false +} + +def localMavenModulePath = providers.provider { + file("${System.getProperty('user.home')}/.m2/repository/${project.group.toString().replace('.', '/')}/${project.mod_id}/${project.version}/${project.mod_id}-${project.version}.module") +} + +tasks.register('removeLocalMavenModuleMetadata') { + group = 'publishing' + description = 'Removes Gradle module metadata from the local Maven publication so consumers fall back to the POM.' + + doLast { + delete(localMavenModulePath.get()) + } +} + +tasks.named('publishToMavenLocal').configure { + finalizedBy tasks.named('removeLocalMavenModuleMetadata') +} diff --git a/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/panels/StoneCutterPanel.java b/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/panels/StoneCutterPanel.java index d3caab6..93c0557 100644 --- a/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/panels/StoneCutterPanel.java +++ b/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/panels/StoneCutterPanel.java @@ -24,9 +24,9 @@ public class StoneCutterPanel extends ETTerminalModePanel { private static final Blitter BG = Blitter.texture("guis/et_terminal_panel.png", 512, 512).src(0, 134, 159, 65); private static final Blitter AE_BG = Blitter.texture("guis/pattern_modes.png").src(0, 140, 124, 66); - private static final Blitter BG_SLOT = AE_BG.copy().src(124, 140, 20, 22); - private static final Blitter BG_SLOT_SELECTED = AE_BG.copy().src(124, 162, 20, 22); - private static final Blitter BG_SLOT_HOVER = AE_BG.copy().src(124, 184, 20, 22); + private static final Blitter BG_SLOT = AE_BG.copy().src(126, 141, 16, 18); + private static final Blitter BG_SLOT_SELECTED = AE_BG.copy().src(126, 159, 16, 18); + private static final Blitter BG_SLOT_HOVER = AE_BG.copy().src(126, 177, 16, 18); private static final int COLS = 4; private static final int ROWS = 2; diff --git a/src/main/java/me/myogoo/extendedterminal/init/ETCreativeTab.java b/src/main/java/me/myogoo/extendedterminal/init/ETCreativeTab.java index 0ab6bc2..d8a88ce 100644 --- a/src/main/java/me/myogoo/extendedterminal/init/ETCreativeTab.java +++ b/src/main/java/me/myogoo/extendedterminal/init/ETCreativeTab.java @@ -19,7 +19,7 @@ public class ETCreativeTab { static { REGISTER.register("itemgroup.extendedcrafting",() -> CreativeModeTab.builder() .title(Component.translatable("itemGroup.extendedterminal")) - .icon(AEParts.CRAFTING_TERMINAL::stack) + .icon(ETParts.ET_TERMINAL_PART::stack) .displayItems((params, output) -> { for (ItemDefinition item : ETItems.ITEMS) { output.accept(item.stack()); diff --git a/src/main/resources/assets/ae2/textures/guis/et_terminal_panel.png b/src/main/resources/assets/ae2/textures/guis/et_terminal_panel.png index 1831a610e8bc18c1d26505063f4fd02fcc83cfbd..7f23dd1b9f282a6d53af8ec57701f0cd9ea29ced 100644 GIT binary patch literal 3524 zcmeGfX;70_@O^;@1VL-D3IwpVRRkKsWl)5m2*?=(IfVc!A{6D+1O*c)mWot7s;C_S zFSM1*A{8Zp6k3pifH304DT0X@667|7^yLFuDs5+++D?D?X5RPq?e4eN+uiql2VI

CmA=5{bm!-QCC2XQSQf&jKAG{pykOC2&!QadmcsRCEA03VneT8L`1T z8UW>T=|mQ4+cP0jHOAU2#w~n%3@tD!2)G1>?1~{cTW?xoLNFj07`~6##z3axATPV^ zc6K^I9&WHe4Z#8gLiTW~Pr=X?ppD3&c&SeY2nM_dS06Y-l4VhR7=)$cskST#3OP*7V;7ejfhCrq+F>^Y}TZ#lMt2;43vyPIbBzoLTKtO10qpM{hXnXk7{UY z2VkzT-TJkg=v01dpxaW?{G>o)mEVL!-#NFa=c1-U^EMZ!@7kXoFYHhGHp3zg*+QkJ zh~&uj0|Z++8^WCuyvE|2#)7DrfTxYDn!5={9i|AP?r!(i!SWX=8OLm-jBr1+tS!&? zu3ICQbNf=P8!$RU!V)jMIWSU*;okU~^73pDR9$&}UgS;BJno7`NmgpB?B#6o4EPm% zC%>ELFZ)^|I*XeuxR;+kte0@HVphBY_DX=GX#TL_Sdv!$d#8p!d=d10AKjYb z%_X}*F@MAr?^cpeHdYC^YQVR8P_wPIKPBV)h+eh%$|2eukFAfA3(~7^buBax>ZJE| zMVekb2R45dqE${^)_d4<@aqGjnPkVy?>n7iM!oCy!K1>*T@f3skRQ~V zERxuc%^LZ5+Vh`_#^ge0h&<8d%pN_+n}sW0DX~<-J_tn}@usoPU)H-Gd}FqfK8l4_ z^6So+W{Bwc*DX)Tm-R53Vcsa!(qx8X34%FN@|R?ObazTd6oLjZi~Pb!G^WMoP-Mm7 zlMZJJVHmm-|L7Qu@=y1VZjU>uoazf@7Psias2Hy%MuoJga8i4mklGz@4w#Dw{1du+ z?bZGw_hu#KA?6*PR`Kj4oy9nvz5f=0)JVgVtJTwbIk!!++3ur^TJ<))y)dq#J$QHxZ73#!ACj-Ba{S#MMM+<;B0q1~6yN5;%zc%kzc9c{BI2_jdrE$)kB=)> zz!kV>4i#Zq{Kv>txl&K&KAG}Pn26uizuJNvo-;1q%(;OR_IEBrMS3bmOvrWk`7;$C zIq@S+S+FdIy#4h#U0UsBL+PA>-%vUnF}7o(m_2umKeMVUf)1_$6O`URP# z={GW*loXo1c}sXMLbfU>bb z85@xmOVeh`+$pg_@H^Txa2=KdeJ()m3@sUB+Q2eX;UrA4)=?H&mbu0q%U3~j)_k-d z!xbfwSl)xM`N`lqIpq7Fgy{^EMuJr^3TiF!aSun$Rp%Q-I?>VH5UC zeX~2J2heWvc_x8lf*#o4*#GCQj!zutkH5^{pGASEe<}7K9rfEdxVMpa?7O`!JEt1$ z=KfusQ+ZC;v#MVHM3vqBi@7<@<;PIfMQznQvynj!g%J|G)$SP*^ajjET5ior5~;(R zFH|+~wD|d%e8It8tp=SFuy~4mY`nJnAQpAgFO(Y&;Dn~yE$y&Rc+|+(IO=g?U5m?L ziJvt{4oV8L@C0JdE&Ca;lvi(6uHoKq@D~smd(tL!P1w_1<6%e-s^6%mAXPHDprA41 zfo3vlfoilDRJaAHtNL9%712zq5KFJUqSS)g>zKGT%2U>t8y4b(Bax{3+>?=kr`vBn zYm%hwfL-Wnkgrz{t&ewLQtW^@eU(zBNp0M-3{B}Bwoey^(E5zfT-C7+E-= z-w%niK4$){>tN;w(+nLS1w^ZG@K~ZPQo9kn1K-8rf0qOjOmxYv>VhTj9gzM@*jYQT J&s!Ie_$y2~%1QtL literal 2797 zcmeHJdo`rMCY7_hbvpgs_nhzVd%yR4zxUqn{oH$JesL!| zsi_cE003$(&JG>`$U#yLD4}qv%v)3g7bL>N$sTa(bqC-^K4`7$S^%yjs)_;>;9kRh zgO_7)=++!FI?b zL^^s$deQg$8fO|mjo=6he(M#W)WJ00|f;0G-yo|pK(%86|3czzH^nU%9Q2>vU6oEXHG+AM0 zg5T~%^fS*ug;g@8dcq?jTYaT^&QpK|UFJUzuF z8l{a@Xnl9tmbKW@~S66qhCjTGyrCHRigL~ByY209KL*D`L#E>T{lMDUYuyYj{liK5O| zgS?0RThlUEC-#L--C#efQZ>h!Y$R#j>g$YNL~AM&JJ|Xam@*5)%i9e2^$Vj}6+>w; zy+?>>`ZB0IT(D+zFRQCnNFJkNQUc|iEI-;KXa)!9Za}QH3-5n98KIQ6+se*AYWY(# zX)p7-ieyQjU)%9Ibi6?(O(E^CEf+d>=QS8Blq`N{1Ntvytu3nk=qP{MPrkni z+ww!FM09j>Y8}IXnMl_hmL_9)aZ?sBl47GIekUJG0zDHVS0%hW1o@dG9pUZ!ZC!_( zHr`*Myz>%xcz%2sC$KSIGd5{I4`=eXHFCXaVj^kOAD2Bm`}=5?&E46zGbo&)Q4zUu zFIbH+w6AA;NC;Z2-);A8z_UO6RzoYPNEU=wS^YRu<{Sd(%tCbA*cMkENPv% zt@x_{Z411*Bt%!F&K{1{(2rAYRK;+tCF1PDt{z2ZWflhj`6VF)aPNOvcjwuO?MIp< zhM3mX=+csjV>0w_Q8jWTQdp`}!e^Y}qqY?hoAW0PQSU}Grr75WgU=xgJ#nQuK_E-J zx6MtP8~-sUKS^aHhbs?OG=RBY-JL#)D1(hGuK_&*d=K}Xc^&j-o=s`B)s{-2L~bzw z@u}u`X3ustRNvy0tODua{z$`LPU`pxU7G z40x;^-Pf0474_HM3fLGA7%~^K#6rxH6>(v;E`cj-7?asuz-+K>#q8`l0OF*S5*mC* z9g<7)y=J+DgKgT8-P7zK5MaB`?N0AQb07Es<5MeBkYesMX4o&oi)z5Zde6)_z3)w* q=V6`e^Ag`qXLkB;(fFEZNEFt$xO$vY^CV#Z!(1H64jg;`_VGd000@0yBi8IG7|wubN~PVxRKv3K?48)05Jgq01*HH09pV5 z0BMH=009610BisN000000Hc!t0O$h%0Hc!t0O$h%08n9RZgehAMN}X)E-@}KG60iI z0V4sHlW+kge+PGdp0>=|6aWAP%Sl8*RA@u(m|JWVRT#&AGrQd)q&wR}8%d0mtF%qI zY}wKR36~UvhFe337!nZ@MS0Ui@yYligcuFs!3RUYh&EAzf6ja*78w^qVM zN=tj7AWOUR`LOKL*_my3%gvDf-{$0;|C}@P&2PT%e}iW&Eq=hFqKSf*hTGKW37&AA z>o`bhp`eAyn>~kgEuDXFchOW|k1KSaaInF$#%?gZPy$QKgI#W+v9ZZNG^F7cjo~A+ zNY{1F{Qd{jor$f}EsF#B5?ERutUr6k|HeD-`d6%cox2^1uFejw-DsuxpDSdH&4s`# z;%wm2f9P@xo3?G`XjL71wto%notW*N+-q$obgPTBv~)=G#FjiXD9)F{`DHXVHu>w1 z9OdV)cEI&E= zA}uSE^z3ZN&Su5i>nSOoMw)4&Ke#)NaZof~hL0VMOLxCH69of$Do>;p(li@I!@M-vebECj2j6a55`QtBMT=0gwNR4g0TAN>;Fupg+)8o26qe8DWJ?Qb$6f%8Spm4w2ADA1 zhpIY`v1B%0Zw9x{w?JKk=Ewuzk_8wgMYeh&Ye^aEm&2*?AiiFh`}rrq*6;SGo*$^1 z6TJD`?&R}>>jw^7@&h1s9-ON@f57yQ-;42}_1m8?W=&3>2derMIja{xA`bvv7e^jE zC+hoLN$|k>F-28cD9p&0yan@6wI>)mb2^kx6_-EqKkO~L!Sq52EG`e`En6IHymkeE zYd6{$UE*i_+!+v+q&IWFC^+Gw$-0~Xb@GD2g&pg3|-TdDPoI*$I65FdclbYjs`qG*s=ByVeperl zxq(QuziLZ~bal4L%npILK&kSKo-dDd&Ti!Pbz-wLlKR#VVEvdZwmVWq!!fu^kf zqt*(fgiC__g8yRxhE271IDpce1s;*b3=Dh+L6~vJ#O${~L5ULAh>~FW{Irtt#G+J& zfW*wa5V?yMtp*${0UP=+@@>8L z|Njl?DBmmImsrysC7=A!{&}d`<*V$y~2pDJ_EetN|<{+DF}eivgli-SDm>FVdQ&MBb@0Q$?PwEzGB diff --git a/src/main/resources/assets/extendedterminal/textures/item/charged_ender_pearl.png.mcmeta b/src/main/resources/assets/extendedterminal/textures/item/charged_ender_pearl.png.mcmeta new file mode 100644 index 0000000..d7c7d6e --- /dev/null +++ b/src/main/resources/assets/extendedterminal/textures/item/charged_ender_pearl.png.mcmeta @@ -0,0 +1,39 @@ +{ + "animation": { + "interpolate": true, + "frames": [ + { + "index": 0, + "time": 50 + }, + { + "index": 1, + "time": 3 + }, + { + "index": 2, + "time": 3 + }, + { + "index": 3, + "time": 3 + }, + { + "index": 4, + "time": 3 + }, + { + "index": 5, + "time": 3 + }, + { + "index": 6, + "time": 3 + }, + { + "index": 7, + "time": 3 + } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/extendedterminal/textures/item/wireless_et_terminal.png b/src/main/resources/assets/extendedterminal/textures/item/wireless_et_terminal.png index e98964544bedf943e766979dd2a2c61c1ea3856b..26ac1cf8f30910cf8387ae3218f4cf5e90db3e7e 100644 GIT binary patch delta 284 zcmey!{F8Zto5uf!>wy6Qd3kxsNlAC_-aUHs=;FnT-CSMUqnBOZ{l>)Dn1O*oVw2Z` ziFwL=hZq?64l#;qcr^e8B`408<}x%AW^^wB@^(x-tmnuCWEe6sF$e*AN9$JwrW1BZkQajLMADCWkPp);8Dc%M@L>d>^PS z*3-o?L?bx&Tp$;NB8Th6D~4;g|NqN3&5ft{JYN{q;yOE6J}jNro5qIxyN>oDzP{<7K7G1(|MA4wvyT=(K7Hm&l>5B38;)e=b}%q7R9!vm zIx$a~?=S-c-(kk%`72U@f)W$wOLJQ0x-Z{kM|D+N-j3a@&AT2i-proD!v5i{3X?dQq*zLV{DS}g|Igr{weky)&spFR zS)t zak-hLAdnFS#F_0Z42(cJ2Z%x7W*H;H3uXk3ZU)0-5k_UkX_GA&Rejoa8-#7S!ngsb zO~=#4F+?LcIl+yYCxS&nV&;Md!6V6OX)YedO{_Bnn0%Nu8y*_)EMLsT!^lu+&vZ1w RpywjUK2KLamvv4FO#s2ANJ#(y delta 256 zcmZ3%e2{s9qZ5CCPl)UP|GxkK_k8;F>BWmz3=9mfH&$;2QmiFGe!>5NfZ_KxzF?pL zXMsm#F#`kNVGw3Kp1&dmC@3+pUYgTFI`h>EAZOdeC1&OVKt>c0XSTC2Faqf;AO?X1 zAO`VabUQq*zLV{DS}g|Igr{weky)&spFR zSYTq8qP!Mps$p2>lX2XpR`3#&_S2wWybWz!D?x59hMIq7r#{L8z>C4A= Zii`QoXDa-!Hu(_9T2EI$mvv4FO#l@oPqqL6 delta 390 zcmZ3_ypv^uW4&>JPl)UP|GxkK_k8;F>BWmzzP{;>_90GAPL7U_4h|0O{Y$T2yL0gH zg-44YPmDbqXZaM=4L+Y7^Fd!vZ666>B9}O_5uAP|#l;kY%h%9Dc;5!V$jK}j= zqyPmaN?apKg7ec#$`gxH87B7daau@czFGm4**0;BnYjRv5e3AV?JNw8KspPEK_CH$ zL3|h;keHcQqUYxtqF}0LsAn-*m{FN=%4Bm!)%w*9io(J3EHr?MdpunnLo|YI`?>iJ zEATiAZ-Icvoh3Gw4Y|6XgI-O0zD4Z7S{=s2g7zZnXJiVuUfZ=RmT@~* zMx7&b*Ho6|GltK(wKOM$b4<8>@%ND#JF4&Z#q6|HwG1eBnu389}3)!7y2bQJHbtWD7=BpSIlwVOy>+ZUAc2 z@pN$v(FjgXaAW3)V3ClRxu8MtNOD@5i-&O&>kI)VA7;&lhXy>$7c=oNGE~|#9ZfLk Qxd^h))78&qol`;+0IuRmP5=M^ delta 256 zcmZ3%e2{s9qZ5CCPl)T8GiUz)|NrUJrx!0?F)%PR#tBygDb|u8zhI#Fe}>=N_=14~ zoCO|{#S9F5he4R}c>anMprFLWdTCAz>C9IvfShd;mzbFg02xt0oY~I8zzC$XfEWZ4 zfEdJw(E*8>c_n&&t|1DhdWL!ylZ6?T8K+D(XH-pD-JmEOJkLS{sMy8R#W6%9xVO(z zh(Upa+49qWb7@iT&Q@!Y4NE!}eiV8pxbxU^){4Iz;aw}bQ^aHT3teIN%u(bN3_3Gs h?M<7_tL~dH@_a~VUg28EF9nu389}3)!7$l{QJHbt+ZUAaC z_H=O!(Fi_zej_h~f`HRS{x|zK8*X&SXW+cLx`E}Vi^^_u2d#!H3W?@7_9yU2Up~H5 ZT+C-aQ{jKL$%jDJdb;|#taD0e0ssjqQlJ0; delta 390 zcmZ3_ypv^uW4&>JPl)T8GiUz)|NrUJrx!0?`TC|i+J`tfIXOByIygAA_b5Ajy6FrI469^|?*J*mk|4iepk5Tfpt^Qu5>S$}z$3Dlfr0NZ2s0kf zUy%Y7lqhkHC<)F_D=AMbN@bYX!^deMo%w17P-ff2C1&OVKt>c0XSTC2Faqf;AO?X1 zAO`VabU-gaSYK2w(aNU zJFLLtEWBa%H2>3o{jJ;cymgk?ST^M9ehzvy?fDk518a2{4-49hsGpH3+JjPG2Pq>$U ziz$>l&u^paXr3%{$6o#M5=|M?bnc?%rt3`)Pk*)T8vCvb?249aJvIOx#^CAd=d#Wz Gp$PytJ(e&4 diff --git a/src/main/resources/assets/extendedterminal/textures/part/extendedcrafting/elite_terminal_front.png b/src/main/resources/assets/extendedterminal/textures/part/extendedcrafting/elite_terminal_front.png index c323c10d07e041932a5b5ef60cb6cbbc9446aaf9..267665378fce0b2cc7dfe6f3cb3fea68f6b16511 100644 GIT binary patch delta 254 zcmX@eyn=axV=_;GPlzkS|Nqnf|95h7VqjosU8L|4NU@Xz`33*~|DVA@YvmUppR>Rt zvY3H^?;r>>?wFYU7APoL;u=vBoS#-wo>-L15RjOeSEA?V8lqsTXQ*drB+Teu0#vkP z;&L-fK_DXvh%?(+7#M+c4iJOD%`!%Y7t9D6-3*4wB8eH= zn~tZ8V~9p@a)KK(PXvpE#LNW^f=80m(p)@@n^w;UocRB zv%n*=n1O-sFbFdq&tH)O6qJ})FU@Hoo%w17kh5*#5;JoFAR`KhGuv4h7=d&a5Q9Jh z5QF$IIv_DKuSCz!HAKNw&rr`|vM{4ERt zvY3H^?;r>>?wFYU7APoL;u=vBoS#-wo>-L15RjOeSEA?V8lqsTXQ*drB+Teu0#vkP z;&n4iK_DXvh%?(+7#M+c4iJOD%`!%Y7t9D6-3*4wE{w{I(eH= zo4KcpV~9rZ(SAcd1_d6bh2Q_%&o-NtB_p$ULxC{IlNk{cEL&N;L$==BFm+$&57l*v emU~zJs<38oEoRCLm5e9_S?%fS=d#Wzp$Py{dQ%Jl delta 390 zcmdnYypv^uW4&>JPlzkS|Nqnf|Nr#q(~B3ce0|d$?L(ZLoE#k;9UL6m`s{Qzn};s@AV=P!tZHXQ2U9+~euu7@`qu+t1B+ zSb@h`c*E>z{-^)?Tes(V>nyRcY{=F99Q111^DSZr*6J`G7PJ>pKOFVdQ&MBb@09-0I4*&oF delta 247 zcmZ3%e1Lg^qaA;MPl&67nL~hEz^6~2Uc7k4z`#(ekaZkLv6ck+1^)*EhTq%xf`I~@ z1s;*b3=DjSL74G){)&`|)e5YJT^wTPCN3~?UJPl&67nL~hEz^6~2Uc7ka>znRqAL8WXLk1v2zm_7&$Nlr41RG7zBZI6cA^&voJ6M=^P*i zfyI*<7+wGs!RUa*%)AmkKi3ciQ$0gHL&M2Jj9&FOo*Gn~{j#_KsJ_?J#W6%9*tS1V zh*^=td9hkH_oJf!m&-QXwfghpnJbUc#VYx9DWi#=uYBhEG+eK_P$QTzC*QcZc=Pv^ z!wPR1-O9c&WgqSO(WE$YZI#lQCCNM3!wYuHFII})7|Q1EddGRnKext?8@FSBNp8Jz zcdwG~^}h{z)vFk1O+R;j=}(~vnk(0-EWIq2+oN^g{px>)T^HCD*Lg-}fxP1B>gTe~ HDWM4fOsJim diff --git a/src/main/resources/assets/extendedterminal/textures/part/extendedcrafting/ultimate_terminal_front.png b/src/main/resources/assets/extendedterminal/textures/part/extendedcrafting/ultimate_terminal_front.png index 11916313a3840329257e5d86306fad715b36b270..543c8c744f39f51ba7ceabc7c62507ce3670f86e 100644 GIT binary patch delta 254 zcmX@eyn=axV=_;GPl&7k+uZ(F^PQZW7#J90QugHnDVCBTzu^D>|1&sft^5Mya~60+ z7BevL9Ry*<9TT(P0tF>YTq89 z)A4k14ABTqPHh($ diff --git a/src/main/resources/assets/extendedterminal/textures/part/extendedcrafting/ultimate_terminal_side.png b/src/main/resources/assets/extendedterminal/textures/part/extendedcrafting/ultimate_terminal_side.png index e086e6896b094abe1da89d5e2ceab21f5fbf45fd..3b4472b3d6f5e3aa56a434ecb1d302b261d996c7 100644 GIT binary patch delta 261 zcmdnVvYvT@V=_;GPl&7k+uZ(F^PQZW7#J90QugHnDVCBTzu^D>|1&sft^5Mya~60+ z7BevL9Ry*<9TT(P0tF>YTq824P#SFm3>9 zGxl_G4ABTadVV7>gMxt5MgBMYHydtr$YJPl&7k+uZ(F^FMw1^y0-UU*B{``w%B5Cr3v|2M34t{-sy1-8p#p z!lT8HC&r$Qa-UaGH=TijL5`y^7f1<~1o;L3M*|G1YiA|_B{>T`B8wRq_zr_GRC({W>jXJGTEF_wSIMjqHyp$3k{&+9#0p?5RG8ler~?Q z3Ovrj8)i@QKmFI=x;@WZXNiqvL$2=UpjXqLZxK7NR)_JhpuLFt8JWVZ*LLlSW!%n{ zQRm3qHI*g#jNx-`EzJqx920I|{C#A`j_Uh;F*_|)Edz>O`I`P%3$4gw{Pg;Sd+E2B zLb>z&HoA`H$uf8B)gLd>lrc@`E?RE7-t_SFSKF?!@4CRQXt~y71JGd%p00i_>zopr E0C-B1egFUf diff --git a/src/main/resources/assets/extendedterminal/textures/part/extendedterminal/et_bright.png b/src/main/resources/assets/extendedterminal/textures/part/extendedterminal/et_bright.png index e4218953f4c9a71cc592770698c836ca8fca2e54..ef0b2f28176e0494acc256d2158c1340457d079b 100644 GIT binary patch delta 228 zcmbQvynuOv8`uB;{}~t*~f|4b!5hcO-X(i=}MX3w{ ziJ5sNdVa1U3Z{C7dWJ^AjP4~sMLQ{7z v7TBzikT}ffCn~|jvNa*1`)neILj(guZUMvD%{_dxLH2pN`njxgN@xNAHo!f_ delta 219 zcmZ3$Je_%h8`q~#pBNYz9xuCdW@3P((P0J#zQc^i^H-z*1tm&cBT9nv(@M${i&7Z^ z5;OBk^!!{y6ioFD^(=GpZrK6VY@0Yo&z>2`Fl1z65CGCqK%Cjm!oUcmvw#=`7Efki zcmY%dqtT3-%+09GIAyXvqpDkMz)gw%xd%a-)jVAsLo|Yu6I_^iLWC0-m{k~67=+Uj m8jKS~np#6ynFO-AJ((Elq#0fx__Hk=WRIt-pUXO@geCx_@;Y$< diff --git a/src/main/resources/assets/extendedterminal/textures/part/extendedterminal/et_dark.png b/src/main/resources/assets/extendedterminal/textures/part/extendedterminal/et_dark.png index a6f95a025746b2ec3201562b6bd91157266a4744..5f546b01de7afd472171fb1f30092a242f53da71 100644 GIT binary patch delta 250 zcmbQqJb`(FBnKM<1B3kM|A`Y76|6Z6JR*x382Ao?FyoGi*>8c8k|nMYCBgY=CFO}l zsSE*$nRz98ey$-3rh0~YhDO4S?j=A)J0{N7b7TTC3>ldi1c7uE5NEctFfan?93TdP zn`Mj)FPITDx>*d9IT)20r%l#jRE=rdZ4kEQ3gZT#HXBbD#}EtuEalo5uBXh!pxJxW#GW*#1JXe&c&v|7|!Tg5t1;YF^$_u!I^=fh?U`b S=sC?&kVT%ZelF{r5}E+I)k1v$ diff --git a/src/main/resources/assets/extendedterminal/textures/part/extendedterminal/et_medium.png b/src/main/resources/assets/extendedterminal/textures/part/extendedterminal/et_medium.png new file mode 100644 index 0000000000000000000000000000000000000000..ce168216398fb8b756dce34f672172aa073f208b GIT binary patch literal 405 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBuf-vKbiP>*~f|4b!5hcO-X(i=}MX3w{iJ5sNdVa1U3Z{C7 zdWJ^AjP4~sMLSX>JkvZqwHP>n999M?Mpgz!Aj=DgrJ-z)b2J#4!QxCnwjm=EgCLNO z0^-be7O;2@kPQMi%NQA6Fe7MmTNxODk`ve&Sb%B`jEoH!7eLGf*~z*9V%9Vu8w8ku zCNqIm23cAFSx{Yu1_mJ6w%rC{Tdpu}05TmtT^vI!{F4(TSR)Sp2ZF;HDQ3H@*nmK- zgfWIolH)`m{{m}iX=%xXio^$udg;P%S>1r3#8BdZy7?qVh9@7~j|=_HnhG-5)78&q Iol`;+02vWd6#xJL literal 0 HcmV?d00001 diff --git a/src/main/resources/data/curios/tags/item/curio.json b/src/main/resources/data/curios/tags/item/curio.json new file mode 100644 index 0000000..153a4e4 --- /dev/null +++ b/src/main/resources/data/curios/tags/item/curio.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "extendedterminal:wireless_et_terminal" + ] +} From bac449d17d3a0891987883e5bc99a1b069f11ef5 Mon Sep 17 00:00:00 2001 From: njoyshadow Date: Tue, 14 Apr 2026 23:30:11 +0900 Subject: [PATCH 05/11] feat: add EMI/JEI integration for Extended Terminal --- CHANGELOG.md | 7 +- build.gradle | 56 -------- gradle.properties | 2 +- .../smithing/SmithingRecipeBaseAdapter.java | 6 + .../SmithingTransformRecipeAdapter.java | 24 ++++ .../smithing/SmithingTrimRecipeAdapter.java | 24 ++++ .../smithing/ISmithingRecipeAdapter.java | 23 ++++ .../api/integration/emi/ETEmiAddRecipe.java | 4 + .../api/integration/emi/ETEmiCategory.java | 4 + .../gui/panels/SmithingTablePanel.java | 3 +- .../gui/panels/StoneCutterPanel.java | 6 +- .../init/ETModIntegration.java | 1 - .../integration/emi/ETEmiPlugin.java | 12 +- .../integration/emi/EmiRegisterHelper.java | 26 ++++ .../emi/avaritiaRe/AVRecipeHandler.java | 11 +- .../emi/avaritiaRe/AVWorkstation.java | 12 +- .../emi/extendedcrafting/ECAddRecipe.java | 28 ++++ .../extendedcrafting/ECRecipeCategory.java | 38 ++++++ .../emi/extendedcrafting/ECRecipeHandler.java | 48 +++++++ .../emi/extendedcrafting/ECWorkstation.java | 32 +++++ .../handler/ECTableRecipeHandler.java | 47 +++++++ .../handler/ECTerminalRecipeHandler.java | 125 ++++++++++++++++++ .../recipe/ECTableRecipe.java | 125 ++++++++++++++++++ .../handler/AbstractETRecipeHandler.java | 90 +++++++------ .../handler/ETCraftingRecipeHandler.java | 6 + .../handler/ETSmithingRecipeHandler.java | 9 +- .../handler/ETStonecutterRecipeHandler.java | 8 ++ .../handler/ETCraftingRecipeTransfer.java | 37 ++++-- .../handler/ETSmithingRecipeTransfer.java | 35 +++-- .../handler/ETStonecutterRecipeTransfer.java | 36 +++-- .../handler/IJeiAbstractRecipeHandler.java | 90 +++++++++++++ .../ETSmithingRecipeTransferHelper.java | 3 +- .../menu/extendedterminal/ETTerminalMenu.java | 15 ++- .../SmithingTransformRecipeAccessor.java | 18 +++ .../mixin/SmithingTrimRecipeAccessor.java | 18 +++ .../ETFillSmithingGridFromRecipePacket.java | 3 +- .../ae2/textures/guis/et_terminal_panel.png | Bin 3524 -> 3523 bytes .../resources/extendedterminal.mixins.json | 4 +- 38 files changed, 881 insertions(+), 155 deletions(-) create mode 100644 src/main/java/me/myogoo/extendedterminal/adapter/recipe/smithing/SmithingRecipeBaseAdapter.java create mode 100644 src/main/java/me/myogoo/extendedterminal/adapter/recipe/smithing/SmithingTransformRecipeAdapter.java create mode 100644 src/main/java/me/myogoo/extendedterminal/adapter/recipe/smithing/SmithingTrimRecipeAdapter.java create mode 100644 src/main/java/me/myogoo/extendedterminal/api/adapter/recipe/smithing/ISmithingRecipeAdapter.java create mode 100644 src/main/java/me/myogoo/extendedterminal/api/integration/emi/ETEmiAddRecipe.java create mode 100644 src/main/java/me/myogoo/extendedterminal/api/integration/emi/ETEmiCategory.java create mode 100644 src/main/java/me/myogoo/extendedterminal/integration/emi/EmiRegisterHelper.java create mode 100644 src/main/java/me/myogoo/extendedterminal/integration/emi/extendedcrafting/ECAddRecipe.java create mode 100644 src/main/java/me/myogoo/extendedterminal/integration/emi/extendedcrafting/ECRecipeCategory.java create mode 100644 src/main/java/me/myogoo/extendedterminal/integration/emi/extendedcrafting/ECRecipeHandler.java create mode 100644 src/main/java/me/myogoo/extendedterminal/integration/emi/extendedcrafting/ECWorkstation.java create mode 100644 src/main/java/me/myogoo/extendedterminal/integration/emi/extendedcrafting/handler/ECTableRecipeHandler.java create mode 100644 src/main/java/me/myogoo/extendedterminal/integration/emi/extendedcrafting/handler/ECTerminalRecipeHandler.java create mode 100644 src/main/java/me/myogoo/extendedterminal/integration/emi/extendedcrafting/recipe/ECTableRecipe.java create mode 100644 src/main/java/me/myogoo/extendedterminal/integration/jei/handler/IJeiAbstractRecipeHandler.java create mode 100644 src/main/java/me/myogoo/extendedterminal/mixin/SmithingTransformRecipeAccessor.java create mode 100644 src/main/java/me/myogoo/extendedterminal/mixin/SmithingTrimRecipeAccessor.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c8cfd0..b1c7a33 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,2 +1,5 @@ -## Bug Fix -- Like the circuit in ae2, the insulator no longer consumes the press. [@CynSolveroftheAbsolute](https://github.com/CynSolveroftheAbsolute) ([#24](https://github.com/mc-myo-s-mod/ExtendedTerminal/issues/24#issue-3909100480)) \ No newline at end of file +# CHANGELOG + +## Feature +- Extended Terminal Arrived Now! +- Change to new Texture \ No newline at end of file diff --git a/build.gradle b/build.gradle index cdc3179..580f23f 100644 --- a/build.gradle +++ b/build.gradle @@ -33,62 +33,13 @@ java { } minecraft { - // The mappings can be changed at any time and must be in the following format. - // Channel: Version: - // official MCVersion Official field/method names from Mojang mapping files - // parchment YYYY.MM.DD-MCVersion Open community-sourced parameter names and javadocs layered on top of official - // - // You must be aware of the Mojang license when using the 'official' or 'parchment' mappings. - // See more information here: https://github.com/MinecraftForge/MCPConfig/blob/master/Mojang.md - // - // Parchment is an unofficial project maintained by ParchmentMC, separate from MinecraftForge - // Additional setup is needed to use their mappings: https://parchmentmc.org/docs/getting-started - // - // Use non-default mappings at your own risk. They may not always work. - // Simply re-run your setup task after changing the mappings to update your workspace. mappings channel: mapping_channel, version: mapping_version - - // When true, this property will have all Eclipse/IntelliJ IDEA run configurations run the "prepareX" task for the given run configuration before launching the game. - // In most cases, it is not necessary to enable. - // enableEclipsePrepareRuns = true - // enableIdeaPrepareRuns = true - - // This property allows configuring Gradle's ProcessResources task(s) to run on IDE output locations before launching the game. - // It is REQUIRED to be set to true for this template to function. - // See https://docs.gradle.org/current/dsl/org.gradle.language.jvm.tasks.ProcessResources.html copyIdeResources = true - - // When true, this property will add the folder name of all declared run configurations to generated IDE run configurations. - // The folder name can be set on a run configuration using the "folderName" property. - // By default, the folder name of a run configuration is the name of the Gradle project containing it. - // generateRunFolders = true - - // This property enables access transformers for use in development. - // They will be applied to the Minecraft artifact. - // The access transformer file can be anywhere in the project. - // However, it must be at "META-INF/accesstransformer.cfg" in the final mod jar to be loaded by Forge. - // This default location is a best practice to automatically put the file in the right place in the final jar. - // See https://docs.minecraftforge.net/en/latest/advanced/accesstransformers/ for more information. accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') - - // Default run configurations. - // These can be tweaked, removed, or duplicated as needed. runs { - // applies to all the run configs below configureEach { workingDirectory project.file('run') - - // Recommended logging data for a userdev environment - // The markers can be added/remove as needed separated by commas. - // "SCAN": For mods scan. - // "REGISTRIES": For firing of registry events. - // "REGISTRYDUMP": For getting the contents of all registries. property 'forge.logging.markers', 'REGISTRIES' - - - // Recommended logging level for the console - // You can set various levels here. - // Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels property 'forge.logging.console.level', 'debug' mods { @@ -99,27 +50,20 @@ minecraft { } client { - // Comma-separated list of namespaces to load gametests from. Empty = all namespaces. property 'mixin.env.remapRefMap', 'true' property 'mixin.env.refMapRemappingFile', "${projectDir}/build/createSrgToMcp/output.srg" property 'forge.enabledGameTestNamespaces', mod_id - } server { property 'forge.enabledGameTestNamespaces', mod_id args '--nogui' } - - // This run config launches GameTestServer and runs all registered gametests, then exits. - // By default, the server will crash when no gametests are provided. - // The gametest system is also enabled by default for other run configs under the /test command. gameTestServer { property 'forge.enabledGameTestNamespaces', mod_id } data { - // example of overriding the workingDirectory set in configureEach above workingDirectory project.file('run-data') // Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources. diff --git a/gradle.properties b/gradle.properties index 477ee76..81406d2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -37,7 +37,7 @@ Cucumber_version=7.0.14 ExtendedCrafting_version=6.0.9 guideME_version=20.1.11 -itemListMod=emi +itemListMod=jei enable_avaritia=re enable_excrafting=exex diff --git a/src/main/java/me/myogoo/extendedterminal/adapter/recipe/smithing/SmithingRecipeBaseAdapter.java b/src/main/java/me/myogoo/extendedterminal/adapter/recipe/smithing/SmithingRecipeBaseAdapter.java new file mode 100644 index 0000000..456415e --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/adapter/recipe/smithing/SmithingRecipeBaseAdapter.java @@ -0,0 +1,6 @@ +package me.myogoo.extendedterminal.adapter.recipe.smithing; + +import me.myogoo.extendedterminal.api.adapter.recipe.smithing.ISmithingRecipeAdapter; + +abstract class SmithingRecipeBaseAdapter implements ISmithingRecipeAdapter { +} diff --git a/src/main/java/me/myogoo/extendedterminal/adapter/recipe/smithing/SmithingTransformRecipeAdapter.java b/src/main/java/me/myogoo/extendedterminal/adapter/recipe/smithing/SmithingTransformRecipeAdapter.java new file mode 100644 index 0000000..d5eff60 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/adapter/recipe/smithing/SmithingTransformRecipeAdapter.java @@ -0,0 +1,24 @@ +package me.myogoo.extendedterminal.adapter.recipe.smithing; + +import me.myogoo.extendedterminal.mixin.SmithingTransformRecipeAccessor; +import net.minecraft.core.NonNullList; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.SmithingTransformRecipe; + +public class SmithingTransformRecipeAdapter extends SmithingRecipeBaseAdapter { + private final SmithingTransformRecipe recipe; + + public SmithingTransformRecipeAdapter(SmithingTransformRecipe recipe) { + this.recipe = recipe; + } + + @Override + public NonNullList getIngredients() { + var ingredients = NonNullList.withSize(3, Ingredient.EMPTY); + var accessor = (SmithingTransformRecipeAccessor) this.recipe; + ingredients.set(0, accessor.extendedterminal$getTemplate()); + ingredients.set(1, accessor.extendedterminal$getBase()); + ingredients.set(2, accessor.extendedterminal$getAddition()); + return ingredients; + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/adapter/recipe/smithing/SmithingTrimRecipeAdapter.java b/src/main/java/me/myogoo/extendedterminal/adapter/recipe/smithing/SmithingTrimRecipeAdapter.java new file mode 100644 index 0000000..dfa9974 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/adapter/recipe/smithing/SmithingTrimRecipeAdapter.java @@ -0,0 +1,24 @@ +package me.myogoo.extendedterminal.adapter.recipe.smithing; + +import me.myogoo.extendedterminal.mixin.SmithingTrimRecipeAccessor; +import net.minecraft.core.NonNullList; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.SmithingTrimRecipe; + +public class SmithingTrimRecipeAdapter extends SmithingRecipeBaseAdapter { + private final SmithingTrimRecipe recipe; + + public SmithingTrimRecipeAdapter(SmithingTrimRecipe recipe) { + this.recipe = recipe; + } + + @Override + public NonNullList getIngredients() { + var ingredients = NonNullList.withSize(3, Ingredient.EMPTY); + var accessor = (SmithingTrimRecipeAccessor) this.recipe; + ingredients.set(0, accessor.extendedterminal$getTemplate()); + ingredients.set(1, accessor.extendedterminal$getBase()); + ingredients.set(2, accessor.extendedterminal$getAddition()); + return ingredients; + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/api/adapter/recipe/smithing/ISmithingRecipeAdapter.java b/src/main/java/me/myogoo/extendedterminal/api/adapter/recipe/smithing/ISmithingRecipeAdapter.java new file mode 100644 index 0000000..476882c --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/api/adapter/recipe/smithing/ISmithingRecipeAdapter.java @@ -0,0 +1,23 @@ +package me.myogoo.extendedterminal.api.adapter.recipe.smithing; + +import me.myogoo.extendedterminal.adapter.recipe.smithing.SmithingTransformRecipeAdapter; +import me.myogoo.extendedterminal.adapter.recipe.smithing.SmithingTrimRecipeAdapter; +import net.minecraft.core.NonNullList; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.SmithingRecipe; +import net.minecraft.world.item.crafting.SmithingTransformRecipe; +import net.minecraft.world.item.crafting.SmithingTrimRecipe; + +public interface ISmithingRecipeAdapter { + NonNullList getIngredients(); + + static ISmithingRecipeAdapter of(SmithingRecipe recipe) { + if (recipe instanceof SmithingTransformRecipe transformRecipe) { + return new SmithingTransformRecipeAdapter(transformRecipe); + } else if (recipe instanceof SmithingTrimRecipe trimRecipe) { + return new SmithingTrimRecipeAdapter(trimRecipe); + } + + throw new IllegalArgumentException("Unsupported SmithingRecipe type: " + recipe.getClass().getName()); + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/api/integration/emi/ETEmiAddRecipe.java b/src/main/java/me/myogoo/extendedterminal/api/integration/emi/ETEmiAddRecipe.java new file mode 100644 index 0000000..d360731 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/api/integration/emi/ETEmiAddRecipe.java @@ -0,0 +1,4 @@ +package me.myogoo.extendedterminal.api.integration.emi; + +public @interface ETEmiAddRecipe { +} diff --git a/src/main/java/me/myogoo/extendedterminal/api/integration/emi/ETEmiCategory.java b/src/main/java/me/myogoo/extendedterminal/api/integration/emi/ETEmiCategory.java new file mode 100644 index 0000000..c70ae65 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/api/integration/emi/ETEmiCategory.java @@ -0,0 +1,4 @@ +package me.myogoo.extendedterminal.api.integration.emi; + +public @interface ETEmiCategory { +} diff --git a/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/panels/SmithingTablePanel.java b/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/panels/SmithingTablePanel.java index 75e07ee..9c4c984 100644 --- a/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/panels/SmithingTablePanel.java +++ b/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/panels/SmithingTablePanel.java @@ -5,6 +5,7 @@ import appeng.client.gui.WidgetContainer; import appeng.client.gui.style.Blitter; import appeng.client.gui.widgets.ActionButton; +import appeng.menu.SlotSemantics; import me.myogoo.extendedterminal.client.screen.extendedterminal.ETTerminalScreen; import me.myogoo.extendedterminal.client.screen.extendedterminal.gui.ETTerminalModePanel; import me.myogoo.extendedterminal.menu.ETSlotSemantics; @@ -47,7 +48,7 @@ public void setVisible(boolean visible) { screen.setSlotsHidden(ETSlotSemantics.SMITHING_TABLE_TEMPLATE, !visible); screen.setSlotsHidden(ETSlotSemantics.SMITHING_TABLE_BASE, !visible); screen.setSlotsHidden(ETSlotSemantics.SMITHING_TABLE_ADDITION, !visible); - screen.setSlotsHidden(ETSlotSemantics.SMITHING_TABLE_RESULT, !visible); + screen.setSlotsHidden(SlotSemantics.SMITHING_TABLE_RESULT, !visible); this.clearBtn.setVisibility(visible); this.clearToPlayerInvBtn.setVisibility(visible); } diff --git a/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/panels/StoneCutterPanel.java b/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/panels/StoneCutterPanel.java index 93c0557..d3caab6 100644 --- a/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/panels/StoneCutterPanel.java +++ b/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/panels/StoneCutterPanel.java @@ -24,9 +24,9 @@ public class StoneCutterPanel extends ETTerminalModePanel { private static final Blitter BG = Blitter.texture("guis/et_terminal_panel.png", 512, 512).src(0, 134, 159, 65); private static final Blitter AE_BG = Blitter.texture("guis/pattern_modes.png").src(0, 140, 124, 66); - private static final Blitter BG_SLOT = AE_BG.copy().src(126, 141, 16, 18); - private static final Blitter BG_SLOT_SELECTED = AE_BG.copy().src(126, 159, 16, 18); - private static final Blitter BG_SLOT_HOVER = AE_BG.copy().src(126, 177, 16, 18); + private static final Blitter BG_SLOT = AE_BG.copy().src(124, 140, 20, 22); + private static final Blitter BG_SLOT_SELECTED = AE_BG.copy().src(124, 162, 20, 22); + private static final Blitter BG_SLOT_HOVER = AE_BG.copy().src(124, 184, 20, 22); private static final int COLS = 4; private static final int ROWS = 2; diff --git a/src/main/java/me/myogoo/extendedterminal/init/ETModIntegration.java b/src/main/java/me/myogoo/extendedterminal/init/ETModIntegration.java index 072a1d9..57fec27 100644 --- a/src/main/java/me/myogoo/extendedterminal/init/ETModIntegration.java +++ b/src/main/java/me/myogoo/extendedterminal/init/ETModIntegration.java @@ -23,6 +23,5 @@ public static synchronized void initialize() { "Extended Crafting: Expanded", "*"); registrar.registerLoadableMod(ModAccessor.ReAvaritia.class, "avaritia", "Re-Avaritia", "*"); registrar.registerLoadableMod(ModAccessor.AvaritiaNeo.class, "avaritia", "Avaritia", "*"); - registrar.registerLoadableMod(AE2WTLib.class, "ae2wtlib", "*"); } } diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/ETEmiPlugin.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/ETEmiPlugin.java index 21b168e..035bfbd 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/emi/ETEmiPlugin.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/ETEmiPlugin.java @@ -3,18 +3,14 @@ import dev.emi.emi.api.EmiEntrypoint; import dev.emi.emi.api.EmiPlugin; import dev.emi.emi.api.EmiRegistry; -import me.myogoo.extendedterminal.api.integration.emi.ETEmiRecipeHandler; -import me.myogoo.extendedterminal.api.integration.emi.ETEmiWorkstation; -import me.myogoo.extendedterminal.integration.ItemListModLoadHelper; @EmiEntrypoint public class ETEmiPlugin implements EmiPlugin { - @Override public void register(EmiRegistry registry) { - ItemListModLoadHelper - .invokeItemListMod(ETEmiWorkstation.class, EmiRegistry.class, registry); - ItemListModLoadHelper - .invokeItemListMod(ETEmiRecipeHandler.class, EmiRegistry.class, registry); + EmiRegisterHelper.registerCategories(registry); + EmiRegisterHelper.registerWorkStations(registry); + EmiRegisterHelper.registerRecipeHandlers(registry); + EmiRegisterHelper.addRecipes(registry); } } diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/EmiRegisterHelper.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/EmiRegisterHelper.java new file mode 100644 index 0000000..8856c04 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/EmiRegisterHelper.java @@ -0,0 +1,26 @@ +package me.myogoo.extendedterminal.integration.emi; + +import dev.emi.emi.api.EmiRegistry; +import me.myogoo.extendedterminal.api.integration.emi.ETEmiAddRecipe; +import me.myogoo.extendedterminal.api.integration.emi.ETEmiCategory; +import me.myogoo.extendedterminal.api.integration.emi.ETEmiRecipeHandler; +import me.myogoo.extendedterminal.api.integration.emi.ETEmiWorkstation; +import me.myogoo.extendedterminal.integration.ItemListModLoadHelper; + +public class EmiRegisterHelper { + public static void registerCategories(EmiRegistry registry) { + ItemListModLoadHelper.invokeItemListMod(ETEmiCategory.class, EmiRegistry.class, registry); + } + + public static void registerWorkStations(EmiRegistry registry) { + ItemListModLoadHelper.invokeItemListMod(ETEmiWorkstation.class, EmiRegistry.class, registry); + } + + public static void registerRecipeHandlers(EmiRegistry registry) { + ItemListModLoadHelper.invokeItemListMod(ETEmiRecipeHandler.class, EmiRegistry.class, registry); + } + + public static void addRecipes(EmiRegistry registry) { + ItemListModLoadHelper.invokeItemListMod(ETEmiAddRecipe.class, EmiRegistry.class, registry); + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/avaritiaRe/AVRecipeHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/avaritiaRe/AVRecipeHandler.java index a12dbd1..498f0cd 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/emi/avaritiaRe/AVRecipeHandler.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/avaritiaRe/AVRecipeHandler.java @@ -14,18 +14,15 @@ import me.myogoo.extendedterminal.menu.avaritiaRe.ExtremeTerminalMenu; import me.myogoo.extendedterminal.menu.avaritiaRe.NetherTerminalMenu; import me.myogoo.extendedterminal.menu.avaritiaRe.SculkTerminalMenu; -import net.minecraftforge.fml.ModList; @ModAccessor.ReAvaritia @ETEmiRecipeHandler public class AVRecipeHandler { @MyotusSubscriber public static void init(EmiRegistry registry) { - if(!ModList.get().isLoaded("jei")) { - registry.addRecipeHandler(SculkTerminalMenu.TYPE, new AVTerminalRecipeHandler<>(SculkCraftingTableCategory.CATEGORY, SculkTerminalMenu.class, ETMenuType.SCULK_TERMINAL)); - registry.addRecipeHandler(NetherTerminalMenu.TYPE, new AVTerminalRecipeHandler<>(NetherCraftingTableCategory.CATEGORY, NetherTerminalMenu.class, ETMenuType.NETHER_TERMINAL)); - registry.addRecipeHandler(EndTerminalMenu.TYPE, new AVTerminalRecipeHandler<>(EndCraftingTableCategory.CATEGORY, EndTerminalMenu.class, ETMenuType.END_TERMINAL)); - registry.addRecipeHandler(ExtremeTerminalMenu.TYPE, new AVTerminalRecipeHandler<>(ExtremeCraftingTableCategory.CATEGORY, ExtremeTerminalMenu.class, ETMenuType.EXTREME_TERMINAL)); - } + registry.addRecipeHandler(SculkTerminalMenu.TYPE, new AVTerminalRecipeHandler<>(SculkCraftingTableCategory.CATEGORY, SculkTerminalMenu.class, ETMenuType.SCULK_TERMINAL)); + registry.addRecipeHandler(NetherTerminalMenu.TYPE, new AVTerminalRecipeHandler<>(NetherCraftingTableCategory.CATEGORY, NetherTerminalMenu.class, ETMenuType.NETHER_TERMINAL)); + registry.addRecipeHandler(EndTerminalMenu.TYPE, new AVTerminalRecipeHandler<>(EndCraftingTableCategory.CATEGORY, EndTerminalMenu.class, ETMenuType.END_TERMINAL)); + registry.addRecipeHandler(ExtremeTerminalMenu.TYPE, new AVTerminalRecipeHandler<>(ExtremeCraftingTableCategory.CATEGORY, ExtremeTerminalMenu.class, ETMenuType.EXTREME_TERMINAL)); } } diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/avaritiaRe/AVWorkstation.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/avaritiaRe/AVWorkstation.java index ed7e6af..42ddf8e 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/emi/avaritiaRe/AVWorkstation.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/avaritiaRe/AVWorkstation.java @@ -10,19 +10,15 @@ import me.myogoo.myotus.api.annotation.MyotusSubscriber; import me.myogoo.extendedterminal.api.integration.emi.ETEmiWorkstation; import me.myogoo.extendedterminal.init.ETParts; -import net.minecraftforge.fml.ModList; @ModAccessor.ReAvaritia @ETEmiWorkstation public class AVWorkstation { @MyotusSubscriber public static void init(EmiRegistry registry) { - if(!ModList.get().isLoaded("jei")) { - registry.addWorkstation(SculkCraftingTableCategory.CATEGORY, EmiStack.of(ETParts.SCULK_TERMINAL_PART)); - registry.addWorkstation(NetherCraftingTableCategory.CATEGORY, EmiStack.of(ETParts.NETHER_TERMINAL_PART)); - registry.addWorkstation(EndCraftingTableCategory.CATEGORY, EmiStack.of(ETParts.END_TERMINAL_PART)); - registry.addWorkstation(ExtremeCraftingTableCategory.CATEGORY, EmiStack.of(ETParts.EXTREME_TERMINAL_PART)); - } - + registry.addWorkstation(SculkCraftingTableCategory.CATEGORY, EmiStack.of(ETParts.SCULK_TERMINAL_PART)); + registry.addWorkstation(NetherCraftingTableCategory.CATEGORY, EmiStack.of(ETParts.NETHER_TERMINAL_PART)); + registry.addWorkstation(EndCraftingTableCategory.CATEGORY, EmiStack.of(ETParts.END_TERMINAL_PART)); + registry.addWorkstation(ExtremeCraftingTableCategory.CATEGORY, EmiStack.of(ETParts.EXTREME_TERMINAL_PART)); } } diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedcrafting/ECAddRecipe.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedcrafting/ECAddRecipe.java new file mode 100644 index 0000000..a8af62b --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedcrafting/ECAddRecipe.java @@ -0,0 +1,28 @@ +package me.myogoo.extendedterminal.integration.emi.extendedcrafting; + +import com.blakebr0.extendedcrafting.api.crafting.ITableRecipe; +import com.blakebr0.extendedcrafting.init.ModRecipeTypes; +import dev.emi.emi.api.EmiRegistry; +import me.myogoo.extendedterminal.api.ModAccessor; +import me.myogoo.extendedterminal.api.integration.emi.ETEmiAddRecipe; +import me.myogoo.extendedterminal.integration.emi.extendedcrafting.recipe.ECTableRecipe; +import me.myogoo.myotus.api.annotation.MyotusSubscriber; + +@ModAccessor.ExtendedCrafting +@ETEmiAddRecipe +public class ECAddRecipe { + @MyotusSubscriber + public static void register(EmiRegistry registry) { + registry.getRecipeManager().getAllRecipesFor(ModRecipeTypes.TABLE.get()) + .stream() + .map(recipe -> switch (recipe.getTier()) { + case 1 -> new ECTableRecipe(ECRecipeCategory.BASIC_TABLE_CRAFTING_CATEGORY, recipe); + case 2 -> new ECTableRecipe(ECRecipeCategory.ADVANCED_TABLE_CRAFTING_CATEGORY, recipe); + case 3 -> new ECTableRecipe(ECRecipeCategory.ELITE_TABLE_CRAFTING_CATEGORY, recipe); + case 4 -> new ECTableRecipe(ECRecipeCategory.ULTIMATE_TABLE_CRAFTING_CATEGORY, recipe); + default -> null; + }) + .filter(recipe -> recipe != null) + .forEach(registry::addRecipe); + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedcrafting/ECRecipeCategory.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedcrafting/ECRecipeCategory.java new file mode 100644 index 0000000..245be07 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedcrafting/ECRecipeCategory.java @@ -0,0 +1,38 @@ +package me.myogoo.extendedterminal.integration.emi.extendedcrafting; + +import com.blakebr0.extendedcrafting.init.ModBlocks; +import dev.emi.emi.api.EmiRegistry; +import dev.emi.emi.api.recipe.EmiRecipeCategory; +import dev.emi.emi.api.stack.EmiStack; +import me.myogoo.extendedterminal.ExtendedTerminal; +import me.myogoo.extendedterminal.api.ModAccessor; +import me.myogoo.extendedterminal.api.integration.emi.ETEmiCategory; +import me.myogoo.myotus.api.annotation.MyotusSubscriber; + +@ModAccessor.ExtendedCrafting +@ETEmiCategory +public class ECRecipeCategory { + public static final EmiRecipeCategory BASIC_TABLE_CRAFTING_CATEGORY = new EmiRecipeCategory( + ExtendedTerminal.makeId("basic_crafting_table"), + EmiStack.of(ModBlocks.BASIC_TABLE.get().asItem().getDefaultInstance())); + + public static final EmiRecipeCategory ADVANCED_TABLE_CRAFTING_CATEGORY = new EmiRecipeCategory( + ExtendedTerminal.makeId("advanced_crafting_table"), + EmiStack.of(ModBlocks.ADVANCED_TABLE.get().asItem().getDefaultInstance())); + + public static final EmiRecipeCategory ELITE_TABLE_CRAFTING_CATEGORY = new EmiRecipeCategory( + ExtendedTerminal.makeId("elite_crafting_table"), + EmiStack.of(ModBlocks.ELITE_TABLE.get().asItem().getDefaultInstance())); + + public static final EmiRecipeCategory ULTIMATE_TABLE_CRAFTING_CATEGORY = new EmiRecipeCategory( + ExtendedTerminal.makeId("ultimate_crafting_table"), + EmiStack.of(ModBlocks.ULTIMATE_TABLE.get().asItem().getDefaultInstance())); + + @MyotusSubscriber + public static void register(EmiRegistry registry) { + registry.addCategory(BASIC_TABLE_CRAFTING_CATEGORY); + registry.addCategory(ADVANCED_TABLE_CRAFTING_CATEGORY); + registry.addCategory(ELITE_TABLE_CRAFTING_CATEGORY); + registry.addCategory(ULTIMATE_TABLE_CRAFTING_CATEGORY); + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedcrafting/ECRecipeHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedcrafting/ECRecipeHandler.java new file mode 100644 index 0000000..2d26e5b --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedcrafting/ECRecipeHandler.java @@ -0,0 +1,48 @@ +package me.myogoo.extendedterminal.integration.emi.extendedcrafting; + +import com.blakebr0.extendedcrafting.init.ModContainerTypes; +import dev.emi.emi.api.EmiRegistry; +import me.myogoo.extendedterminal.api.ModAccessor; +import me.myogoo.extendedterminal.api.integration.emi.ETEmiRecipeHandler; +import me.myogoo.extendedterminal.integration.emi.extendedcrafting.handler.ECTableRecipeHandler; +import me.myogoo.extendedterminal.integration.emi.extendedcrafting.handler.ECTerminalRecipeHandler; +import me.myogoo.extendedterminal.menu.ETMenuType; +import me.myogoo.extendedterminal.menu.extendedcrafting.AdvancedTerminalMenu; +import me.myogoo.extendedterminal.menu.extendedcrafting.BasicTerminalMenu; +import me.myogoo.extendedterminal.menu.extendedcrafting.EliteTerminalMenu; +import me.myogoo.extendedterminal.menu.extendedcrafting.UltimateTerminalMenu; +import me.myogoo.myotus.api.annotation.MyotusSubscriber; + +@ModAccessor.ExtendedCrafting +@ETEmiRecipeHandler +public class ECRecipeHandler { + @MyotusSubscriber + public static void register(EmiRegistry registry) { + registry.addRecipeHandler(ModContainerTypes.BASIC_TABLE.get(), + new ECTableRecipeHandler<>(ECRecipeCategory.BASIC_TABLE_CRAFTING_CATEGORY, ETMenuType.BASIC_TERMINAL.getGridSize())); + registry.addRecipeHandler(ModContainerTypes.ADVANCED_TABLE.get(), + new ECTableRecipeHandler<>(ECRecipeCategory.ADVANCED_TABLE_CRAFTING_CATEGORY, ETMenuType.ADVANCED_TERMINAL.getGridSize())); + registry.addRecipeHandler(ModContainerTypes.ELITE_TABLE.get(), + new ECTableRecipeHandler<>(ECRecipeCategory.ELITE_TABLE_CRAFTING_CATEGORY, ETMenuType.ELITE_TERMINAL.getGridSize())); + registry.addRecipeHandler(ModContainerTypes.ULTIMATE_TABLE.get(), + new ECTableRecipeHandler<>(ECRecipeCategory.ULTIMATE_TABLE_CRAFTING_CATEGORY, ETMenuType.ULTIMATE_TERMINAL.getGridSize())); + + registry.addRecipeHandler(ModContainerTypes.BASIC_AUTO_TABLE.get(), + new ECTableRecipeHandler<>(ECRecipeCategory.BASIC_TABLE_CRAFTING_CATEGORY, ETMenuType.BASIC_TERMINAL.getGridSize())); + registry.addRecipeHandler(ModContainerTypes.ADVANCED_AUTO_TABLE.get(), + new ECTableRecipeHandler<>(ECRecipeCategory.ADVANCED_TABLE_CRAFTING_CATEGORY, ETMenuType.ADVANCED_TERMINAL.getGridSize())); + registry.addRecipeHandler(ModContainerTypes.ELITE_AUTO_TABLE.get(), + new ECTableRecipeHandler<>(ECRecipeCategory.ELITE_TABLE_CRAFTING_CATEGORY, ETMenuType.ELITE_TERMINAL.getGridSize())); + registry.addRecipeHandler(ModContainerTypes.ULTIMATE_AUTO_TABLE.get(), + new ECTableRecipeHandler<>(ECRecipeCategory.ULTIMATE_TABLE_CRAFTING_CATEGORY, ETMenuType.ULTIMATE_TERMINAL.getGridSize())); + + registry.addRecipeHandler(BasicTerminalMenu.TYPE, + new ECTerminalRecipeHandler<>(ECRecipeCategory.BASIC_TABLE_CRAFTING_CATEGORY, BasicTerminalMenu.class, ETMenuType.BASIC_TERMINAL)); + registry.addRecipeHandler(AdvancedTerminalMenu.TYPE, + new ECTerminalRecipeHandler<>(ECRecipeCategory.ADVANCED_TABLE_CRAFTING_CATEGORY, AdvancedTerminalMenu.class, ETMenuType.ADVANCED_TERMINAL)); + registry.addRecipeHandler(EliteTerminalMenu.TYPE, + new ECTerminalRecipeHandler<>(ECRecipeCategory.ELITE_TABLE_CRAFTING_CATEGORY, EliteTerminalMenu.class, ETMenuType.ELITE_TERMINAL)); + registry.addRecipeHandler(UltimateTerminalMenu.TYPE, + new ECTerminalRecipeHandler<>(ECRecipeCategory.ULTIMATE_TABLE_CRAFTING_CATEGORY, UltimateTerminalMenu.class, ETMenuType.ULTIMATE_TERMINAL)); + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedcrafting/ECWorkstation.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedcrafting/ECWorkstation.java new file mode 100644 index 0000000..119b61b --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedcrafting/ECWorkstation.java @@ -0,0 +1,32 @@ +package me.myogoo.extendedterminal.integration.emi.extendedcrafting; + +import com.blakebr0.extendedcrafting.init.ModBlocks; +import dev.emi.emi.api.EmiRegistry; +import dev.emi.emi.api.stack.EmiStack; +import me.myogoo.extendedterminal.api.ModAccessor; +import me.myogoo.extendedterminal.api.integration.emi.ETEmiWorkstation; +import me.myogoo.extendedterminal.init.ETParts; +import me.myogoo.myotus.api.annotation.MyotusSubscriber; + +@ModAccessor.ExtendedCrafting +@ETEmiWorkstation +public class ECWorkstation { + @MyotusSubscriber + public static void register(EmiRegistry registry) { + registry.addWorkstation(ECRecipeCategory.BASIC_TABLE_CRAFTING_CATEGORY, EmiStack.of(ModBlocks.BASIC_TABLE.get())); + registry.addWorkstation(ECRecipeCategory.BASIC_TABLE_CRAFTING_CATEGORY, EmiStack.of(ModBlocks.BASIC_AUTO_TABLE.get())); + registry.addWorkstation(ECRecipeCategory.BASIC_TABLE_CRAFTING_CATEGORY, EmiStack.of(ETParts.BASIC_TERMINAL_PART)); + + registry.addWorkstation(ECRecipeCategory.ADVANCED_TABLE_CRAFTING_CATEGORY, EmiStack.of(ModBlocks.ADVANCED_TABLE.get())); + registry.addWorkstation(ECRecipeCategory.ADVANCED_TABLE_CRAFTING_CATEGORY, EmiStack.of(ModBlocks.ADVANCED_AUTO_TABLE.get())); + registry.addWorkstation(ECRecipeCategory.ADVANCED_TABLE_CRAFTING_CATEGORY, EmiStack.of(ETParts.ADVANCED_TERMINAL_PART)); + + registry.addWorkstation(ECRecipeCategory.ELITE_TABLE_CRAFTING_CATEGORY, EmiStack.of(ModBlocks.ELITE_TABLE.get())); + registry.addWorkstation(ECRecipeCategory.ELITE_TABLE_CRAFTING_CATEGORY, EmiStack.of(ModBlocks.ELITE_AUTO_TABLE.get())); + registry.addWorkstation(ECRecipeCategory.ELITE_TABLE_CRAFTING_CATEGORY, EmiStack.of(ETParts.ELITE_TERMINAL_PART)); + + registry.addWorkstation(ECRecipeCategory.ULTIMATE_TABLE_CRAFTING_CATEGORY, EmiStack.of(ModBlocks.ULTIMATE_TABLE.get())); + registry.addWorkstation(ECRecipeCategory.ULTIMATE_TABLE_CRAFTING_CATEGORY, EmiStack.of(ModBlocks.ULTIMATE_AUTO_TABLE.get())); + registry.addWorkstation(ECRecipeCategory.ULTIMATE_TABLE_CRAFTING_CATEGORY, EmiStack.of(ETParts.ULTIMATE_TERMINAL_PART)); + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedcrafting/handler/ECTableRecipeHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedcrafting/handler/ECTableRecipeHandler.java new file mode 100644 index 0000000..dfc18c7 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedcrafting/handler/ECTableRecipeHandler.java @@ -0,0 +1,47 @@ +package me.myogoo.extendedterminal.integration.emi.extendedcrafting.handler; + +import com.blakebr0.cucumber.container.BaseContainerMenu; +import com.blakebr0.extendedcrafting.container.AdvancedTableContainer; +import com.blakebr0.extendedcrafting.container.BasicTableContainer; +import com.blakebr0.extendedcrafting.container.EliteTableContainer; +import com.blakebr0.extendedcrafting.container.UltimateTableContainer; +import dev.emi.emi.api.recipe.EmiRecipe; +import dev.emi.emi.api.recipe.EmiRecipeCategory; +import dev.emi.emi.api.recipe.handler.StandardRecipeHandler; +import me.myogoo.extendedterminal.integration.emi.extendedcrafting.ECRecipeCategory; +import me.myogoo.extendedterminal.menu.ETMenuType; +import net.minecraft.world.inventory.Slot; + +import java.util.ArrayList; +import java.util.List; + +public record ECTableRecipeHandler(EmiRecipeCategory category, + int gridSize) implements StandardRecipeHandler { + public static final ECTableRecipeHandler EMI_BASIC_TABLE_CRAFTING_HANDLER = + new ECTableRecipeHandler<>(ECRecipeCategory.BASIC_TABLE_CRAFTING_CATEGORY, ETMenuType.BASIC_TERMINAL.getGridSize()); + public static final ECTableRecipeHandler EMI_ADVANCED_TABLE_CRAFTING_HANDLER = + new ECTableRecipeHandler<>(ECRecipeCategory.ADVANCED_TABLE_CRAFTING_CATEGORY, ETMenuType.ADVANCED_TERMINAL.getGridSize()); + public static final ECTableRecipeHandler EMI_ELITE_TABLE_CRAFTING_HANDLER = + new ECTableRecipeHandler<>(ECRecipeCategory.ELITE_TABLE_CRAFTING_CATEGORY, ETMenuType.ELITE_TERMINAL.getGridSize()); + public static final ECTableRecipeHandler EMI_ULTIMATE_TABLE_CRAFTING_HANDLER = + new ECTableRecipeHandler<>(ECRecipeCategory.ULTIMATE_TABLE_CRAFTING_CATEGORY, ETMenuType.ULTIMATE_TERMINAL.getGridSize()); + + @Override + public List getInputSources(T menu) { + return menu.slots; + } + + @Override + public List getCraftingSlots(T menu) { + var slots = new ArrayList(); + for (int i = 1; i <= this.gridSize; i++) { + slots.add(menu.getSlot(i)); + } + return slots; + } + + @Override + public boolean supportsRecipe(EmiRecipe recipe) { + return recipe.getCategory().equals(this.category); + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedcrafting/handler/ECTerminalRecipeHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedcrafting/handler/ECTerminalRecipeHandler.java new file mode 100644 index 0000000..e43878f --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedcrafting/handler/ECTerminalRecipeHandler.java @@ -0,0 +1,125 @@ +package me.myogoo.extendedterminal.integration.emi.extendedcrafting.handler; + +import appeng.core.localization.ItemModText; +import com.blakebr0.extendedcrafting.api.crafting.ITableRecipe; +import dev.emi.emi.api.recipe.EmiRecipe; +import dev.emi.emi.api.recipe.EmiRecipeCategory; +import me.myogoo.extendedterminal.api.adapter.recipe.IShapedTableRecipeAdapter; +import me.myogoo.extendedterminal.api.adapter.recipe.ITableRecipeAdapter; +import me.myogoo.extendedterminal.integration.emi.extendedcrafting.ECRecipeCategory; +import me.myogoo.extendedterminal.integration.emi.handler.AbstractTableRecipeHandler; +import me.myogoo.extendedterminal.menu.ETMenuType; +import me.myogoo.extendedterminal.menu.extendedcrafting.ExtendedTerminalBaseMenu; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.Recipe; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static me.myogoo.extendedterminal.integration.ItemListTermCraftingHelper.ensureFittedCraftingGrid; + +public class ECTerminalRecipeHandler extends AbstractTableRecipeHandler { + private final ETMenuType menuType; + private final EmiRecipeCategory category; + + public ECTerminalRecipeHandler(EmiRecipeCategory category, Class containerClass, ETMenuType menuType) { + super(containerClass); + this.menuType = menuType; + this.category = category; + } + + @Override + public boolean supportsRecipe(EmiRecipe recipe) { + return recipe.getCategory().equals(this.category); + } + + @Override + protected Result transferRecipe(T menu, EmiRecipe emiRecipe, boolean doTransfer) { + var recipe = emiRecipe.getBackingRecipe(); + boolean craftingRecipe = isCraftingRecipe(recipe, emiRecipe); + if (!craftingRecipe) { + return Result.createNotApplicable(); + } + + if (!fitsInNxNGrid(recipe, emiRecipe, menuType.getGridSize())) { + return Result.createFailed(ItemModText.RECIPE_TOO_LARGE.text()); + } + + if (!(recipe instanceof ITableRecipe tableRecipe)) { + return Result.createFailed(ItemModText.INCOMPATIBLE_RECIPE.text()); + } + var adapterRecipe = ITableRecipeAdapter.of(tableRecipe); + var slotToIngredientMap = getGuiSlotToIngredientMap(menu, adapterRecipe); + var missingSlots = menu.findMissingIngredients(slotToIngredientMap); + + if (missingSlots.missingSlots().size() == slotToIngredientMap.size()) { + return Result.createFailed(ItemModText.NO_ITEMS.text(), missingSlots.missingSlots()); + } + + if (!doTransfer) { + if (missingSlots.anyMissingOrCraftable()) { + return new Result.PartiallyCraftable(missingSlots); + } + } else { + boolean craftMissing = AbstractContainerScreen.hasControlDown(); + performTransfer(menu, recipe.getId(), adapterRecipe, craftMissing); + } + + return Result.createSuccessful(); + } + + @Override + protected boolean isCraftingRecipe(Recipe recipe, EmiRecipe emiRecipe) { + if (recipe instanceof ITableRecipe tableRecipe) { + return emiRecipe.getCategory().equals(getCategory(tableRecipe.getTier())); + } + return false; + } + + @Override + protected Map getGuiSlotToIngredientMap(T menu, ITableRecipeAdapter recipe) { + int gridSideLength = menu.getCraftingGridWidth(); + var raw = recipe.recipe().getIngredients(); + List ingredients; + + int offsetX = 0; + int offsetY = 0; + int width = gridSideLength; + int height = gridSideLength; + if (recipe instanceof IShapedTableRecipeAdapter shapedRecipe) { + ingredients = ensureFittedCraftingGrid(shapedRecipe); + width = shapedRecipe.width(); + height = shapedRecipe.height(); + offsetX = Math.floorDiv(gridSideLength - shapedRecipe.width(), 2); + offsetY = Math.floorDiv(gridSideLength - shapedRecipe.height(), 2); + } else { + ingredients = raw; + } + + int max = gridSideLength * gridSideLength; + int count = Math.min(ingredients.size(), max); + var result = new HashMap(count); + for (int i = 0; i < count; i++) { + int x = i % width; + int y = i / width; + int guiSlot = (y + offsetY) * gridSideLength + (x + offsetX); + var ingredient = ingredients.get(i); + if (!ingredient.isEmpty()) { + result.put(guiSlot, ingredient); + } + } + return result; + } + + private EmiRecipeCategory getCategory(int tier) { + return switch (tier) { + case 1 -> ECRecipeCategory.BASIC_TABLE_CRAFTING_CATEGORY; + case 2 -> ECRecipeCategory.ADVANCED_TABLE_CRAFTING_CATEGORY; + case 3 -> ECRecipeCategory.ELITE_TABLE_CRAFTING_CATEGORY; + case 4 -> ECRecipeCategory.ULTIMATE_TABLE_CRAFTING_CATEGORY; + default -> throw new IllegalArgumentException("Invalid tier: " + tier); + }; + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedcrafting/recipe/ECTableRecipe.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedcrafting/recipe/ECTableRecipe.java new file mode 100644 index 0000000..4bbf95b --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedcrafting/recipe/ECTableRecipe.java @@ -0,0 +1,125 @@ +package me.myogoo.extendedterminal.integration.emi.extendedcrafting.recipe; + +import com.blakebr0.extendedcrafting.api.crafting.ITableRecipe; +import com.blakebr0.extendedcrafting.crafting.recipe.ShapelessTableRecipe; +import dev.emi.emi.api.recipe.BasicEmiRecipe; +import dev.emi.emi.api.recipe.EmiRecipeCategory; +import dev.emi.emi.api.render.EmiTexture; +import dev.emi.emi.api.stack.EmiIngredient; +import dev.emi.emi.api.stack.EmiStack; +import dev.emi.emi.api.widget.WidgetHolder; +import me.myogoo.extendedterminal.api.adapter.recipe.IShapedTableRecipeAdapter; +import me.myogoo.extendedterminal.api.adapter.recipe.ITableRecipeAdapter; +import me.myogoo.extendedterminal.integration.emi.extendedcrafting.ECRecipeCategory; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; +import net.minecraft.network.chat.Style; +import net.minecraft.util.FormattedCharSequence; +import net.minecraft.world.item.crafting.Ingredient; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class ECTableRecipe extends BasicEmiRecipe { + private static final int BASE_IN_X = 62; + private final ITableRecipe recipe; + private final ClientLevel level; + + public ECTableRecipe(EmiRecipeCategory category, ITableRecipe recipe) { + super(category, recipe.getId(), calcInvX(recipe.getTier()), calcInvY(recipe.getTier())); + this.recipe = recipe; + this.level = Minecraft.getInstance().level; + + addIngredients(recipe); + this.outputs.add(EmiStack.of(this.recipe.getResultItem(level.registryAccess()))); + } + + @Override + public void addWidgets(WidgetHolder widgets) { + for (int i = 0; i < this.getGridSize(); i++) { + EmiIngredient ingredient = i < this.inputs.size() + ? this.inputs.get(i) + : EmiIngredient.of(Ingredient.EMPTY); + + int nx = (i % this.getTierColNRow()) * 18; + int ny = (i / this.getTierColNRow()) * 18; + widgets.addTexture(EmiTexture.SLOT, nx, ny); + widgets.addSlot(ingredient, nx, ny).drawBack(false); + } + + int outputX = calcInvX(this.recipe.getTier()); + int outputY = (this.getTierColNRow() / 2) * 18; + + if (this.recipe instanceof ShapelessTableRecipe) { + widgets.addTexture(EmiTexture.SHAPELESS, outputX - 25, outputY - 18); + } + + widgets.addTexture(EmiTexture.EMPTY_ARROW, outputX - 58, outputY); + + String tooltipText = String.format("Require Tier %d Crafting Table", this.recipe.getTier()); + var tooltip = ClientTooltipComponent.create(FormattedCharSequence.forward(tooltipText, Style.EMPTY)); + + widgets.addTexture(EmiTexture.LARGE_SLOT, outputX - 30, outputY - 4).tooltip(List.of(tooltip)); + widgets.addSlot(EmiStack.of(recipe.getResultItem(level.registryAccess())), outputX - 30, outputY - 4) + .large(true) + .recipeContext(this) + .drawBack(false); + } + + private int getTierColNRow() { + return this.recipe.getTier() * 2 + 1; + } + + private int getGridSize() { + int side = this.getTierColNRow(); + return side * side; + } + + private void addIngredients(ITableRecipe recipe) { + var adapter = ITableRecipeAdapter.of(recipe); + + if (adapter instanceof IShapedTableRecipeAdapter shapedAdapter) { + int width = shapedAdapter.width(); + int height = shapedAdapter.height(); + int gridSize = 2 * recipe.getTier() + 1; + int offsetX = (gridSize - width) / 2; + int offsetY = (gridSize - height) / 2; + this.inputs = new ArrayList<>(Collections.nCopies(this.getGridSize(), EmiIngredient.of(Ingredient.EMPTY))); + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + int index = x + y * width; + Ingredient ingredient = recipe.getIngredients().get(index); + int guiSlot = (y + offsetY) * gridSize + (x + offsetX); + if (!ingredient.isEmpty()) { + this.inputs.set(guiSlot, EmiIngredient.of(ingredient)); + } + } + } + } else { + for (var ingredient : recipe.getIngredients()) { + this.inputs.add(EmiIngredient.of(ingredient)); + } + } + } + + private static int calcInvX(int tier) { + return BASE_IN_X + 18 * (2 * tier + 1); + } + + private static int calcInvY(int tier) { + return 18 * (2 * tier + 1); + } + + public static EmiRecipeCategory getCategory(int tier) { + return switch (tier) { + case 1 -> ECRecipeCategory.BASIC_TABLE_CRAFTING_CATEGORY; + case 2 -> ECRecipeCategory.ADVANCED_TABLE_CRAFTING_CATEGORY; + case 3 -> ECRecipeCategory.ELITE_TABLE_CRAFTING_CATEGORY; + case 4 -> ECRecipeCategory.ULTIMATE_TABLE_CRAFTING_CATEGORY; + default -> throw new IllegalArgumentException("Invalid tier: " + tier); + }; + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/AbstractETRecipeHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/AbstractETRecipeHandler.java index 8ec79b2..be92bcb 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/AbstractETRecipeHandler.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/AbstractETRecipeHandler.java @@ -1,24 +1,28 @@ package me.myogoo.extendedterminal.integration.emi.extendedterminal.handler; +import appeng.core.localization.ItemModText; import appeng.menu.SlotSemantics; -import dev.emi.emi.api.recipe.EmiPlayerInventory; import dev.emi.emi.api.recipe.EmiRecipe; -import dev.emi.emi.api.recipe.handler.EmiCraftContext; -import dev.emi.emi.api.recipe.handler.StandardRecipeHandler; -import dev.emi.emi.api.stack.EmiStack; +import me.myogoo.extendedterminal.integration.emi.handler.AbstractTableRecipeHandler; +import me.myogoo.extendedterminal.api.adapter.recipe.ITableRecipeAdapter; import me.myogoo.extendedterminal.menu.ETSlotSemantics; import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; -import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.item.crafting.Recipe; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; import java.util.Map; -public abstract class AbstractETRecipeHandler implements StandardRecipeHandler { +public abstract class AbstractETRecipeHandler extends AbstractTableRecipeHandler { + @SuppressWarnings("unchecked") + protected AbstractETRecipeHandler() { + super((Class) ETTerminalMenu.class); + } + @Override public List getInputSources(T menu) { var slots = new ArrayList(); @@ -33,51 +37,61 @@ public List getInputSources(T menu) { } @Override - public EmiPlayerInventory getInventory(AbstractContainerScreen screen) { - var list = new ArrayList(); - for (Slot slot : getInputSources(screen.getMenu())) { - list.add(EmiStack.of(slot.getItem())); - } - return new EmiPlayerInventory(list); - } - - @Override - public boolean canCraft(EmiRecipe recipe, EmiCraftContext context) { - return transferRecipe(recipe, context, false); - } - - @Override - public boolean craft(EmiRecipe recipe, EmiCraftContext context) { - return transferRecipe(recipe, context, true); - } - - private boolean transferRecipe(EmiRecipe emiRecipe, EmiCraftContext context, boolean doTransfer) { - var menu = context.getScreenHandler(); - if (menu == null) { - return false; - } - - var recipe = emiRecipe.getBackingRecipe(); + protected Result transferRecipe(T menu, EmiRecipe emiRecipe, boolean doTransfer) { + var recipe = resolveRecipe(menu, emiRecipe); if (!supportsRecipe(recipe, emiRecipe)) { - return false; + return Result.createNotApplicable(); } var slotToIngredientMap = getGuiSlotToIngredientMap(menu, recipe); - if (!slotToIngredientMap.isEmpty() - && menu.findMissingIngredients(slotToIngredientMap).missingSlots().size() == slotToIngredientMap.size()) { - return false; + var missingSlots = menu.findMissingIngredients(slotToIngredientMap); + if (!slotToIngredientMap.isEmpty() && missingSlots.missingSlots().size() == slotToIngredientMap.size()) { + return Result.createFailed(ItemModText.NO_ITEMS.text(), missingSlots.missingSlots()); } - if (doTransfer) { + if (!doTransfer) { + if (missingSlots.anyMissingOrCraftable()) { + return new Result.PartiallyCraftable(missingSlots); + } + } else { + prepareTransfer(menu, recipe); performTransfer(menu, recipe, AbstractContainerScreen.hasControlDown()); - Minecraft.getInstance().setScreen(context.getScreen()); } - return true; + + return Result.createSuccessful(); } protected abstract boolean supportsRecipe(Recipe recipe, EmiRecipe emiRecipe); protected abstract Map getGuiSlotToIngredientMap(T menu, Recipe recipe); + @Nullable + private Recipe resolveRecipe(T menu, EmiRecipe emiRecipe) { + var backingRecipe = emiRecipe.getBackingRecipe(); + if (backingRecipe != null) { + return backingRecipe; + } + + var recipeId = emiRecipe.getId(); + if (recipeId == null) { + return null; + } + + return menu.getPlayer().level().getRecipeManager().byKey(recipeId).orElse(null); + } + + @Override + protected boolean isCraftingRecipe(Recipe recipe, EmiRecipe emiRecipe) { + return supportsRecipe(recipe, emiRecipe); + } + + @Override + protected Map getGuiSlotToIngredientMap(T menu, ITableRecipeAdapter recipe) { + throw new UnsupportedOperationException("ET panel handlers use recipe-specific slot mapping"); + } + + protected void prepareTransfer(T menu, Recipe recipe) { + } + protected abstract void performTransfer(T menu, Recipe recipe, boolean craftMissing); } diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETCraftingRecipeHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETCraftingRecipeHandler.java index 0a7ca5d..77e37a3 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETCraftingRecipeHandler.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETCraftingRecipeHandler.java @@ -4,6 +4,7 @@ import dev.emi.emi.api.recipe.VanillaEmiRecipeCategories; import me.myogoo.extendedterminal.integration.module.extendedterminal.ETCraftingRecipeTransferHelper; import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMode; import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.crafting.CraftingRecipe; import net.minecraft.world.item.crafting.Ingredient; @@ -38,6 +39,11 @@ protected Map getGuiSlotToIngredientMap(T menu, Recipe r return ETCraftingRecipeTransferHelper.getGuiSlotToIngredientMap(menu, (CraftingRecipe) recipe); } + @Override + protected void prepareTransfer(T menu, Recipe recipe) { + menu.setMode(ETTerminalMode.CRAFTING); + } + @Override protected void performTransfer(T menu, Recipe recipe, boolean craftMissing) { ETCraftingRecipeTransferHelper.performTransfer(menu, (CraftingRecipe) recipe, null, craftMissing); diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETSmithingRecipeHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETSmithingRecipeHandler.java index f2c07f1..b866b27 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETSmithingRecipeHandler.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETSmithingRecipeHandler.java @@ -1,10 +1,12 @@ package me.myogoo.extendedterminal.integration.emi.extendedterminal.handler; +import appeng.menu.SlotSemantics; import dev.emi.emi.api.recipe.EmiRecipe; import dev.emi.emi.api.recipe.VanillaEmiRecipeCategories; import me.myogoo.extendedterminal.integration.module.extendedterminal.ETSmithingRecipeTransferHelper; import me.myogoo.extendedterminal.menu.ETSlotSemantics; import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMode; import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.item.crafting.Recipe; @@ -31,7 +33,7 @@ public List getCraftingSlots(T menu) { @Override public Slot getOutputSlot(T menu) { - return menu.getSlots(ETSlotSemantics.SMITHING_TABLE_RESULT).get(0); + return menu.getSlots(SlotSemantics.SMITHING_TABLE_RESULT).get(0); } @Override @@ -44,6 +46,11 @@ protected Map getGuiSlotToIngredientMap(T menu, Recipe r return ETSmithingRecipeTransferHelper.getGuiSlotToIngredientMap((SmithingRecipe) recipe); } + @Override + protected void prepareTransfer(T menu, Recipe recipe) { + menu.setMode(ETTerminalMode.SMITHING); + } + @Override protected void performTransfer(T menu, Recipe recipe, boolean craftMissing) { ETSmithingRecipeTransferHelper.performTransfer(menu, (SmithingRecipe) recipe, craftMissing); diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETStonecutterRecipeHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETStonecutterRecipeHandler.java index c260236..0d4bfcf 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETStonecutterRecipeHandler.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETStonecutterRecipeHandler.java @@ -5,6 +5,7 @@ import me.myogoo.extendedterminal.integration.module.extendedterminal.ETStoneCutterRecipeTransferHelper; import me.myogoo.extendedterminal.menu.ETSlotSemantics; import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMode; import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.item.crafting.Recipe; @@ -40,6 +41,13 @@ protected Map getGuiSlotToIngredientMap(T menu, Recipe r return ETStoneCutterRecipeTransferHelper.getGuiSlotToIngredientMap((StonecutterRecipe) recipe); } + @Override + protected void prepareTransfer(T menu, Recipe recipe) { + var stonecutterRecipe = (StonecutterRecipe) recipe; + menu.setMode(ETTerminalMode.STONECUTTING); + menu.setStoneCutterRecipeId(stonecutterRecipe.getId()); + } + @Override protected void performTransfer(T menu, Recipe recipe, boolean craftMissing) { ETStoneCutterRecipeTransferHelper.performTransfer(menu, (StonecutterRecipe) recipe, craftMissing); diff --git a/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/handler/ETCraftingRecipeTransfer.java b/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/handler/ETCraftingRecipeTransfer.java index 8143be5..7295026 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/handler/ETCraftingRecipeTransfer.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/handler/ETCraftingRecipeTransfer.java @@ -1,10 +1,14 @@ package me.myogoo.extendedterminal.integration.jei.extendedterminal.handler; import appeng.core.localization.ItemModText; +import me.myogoo.extendedterminal.integration.jei.handler.IJeiAbstractRecipeHandler; import me.myogoo.extendedterminal.integration.module.extendedterminal.ETCraftingRecipeTransferHelper; import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMode; import mezz.jei.api.constants.RecipeTypes; +import mezz.jei.api.gui.ingredient.IRecipeSlotView; import mezz.jei.api.gui.ingredient.IRecipeSlotsView; +import mezz.jei.api.recipe.RecipeIngredientRole; import mezz.jei.api.recipe.RecipeType; import mezz.jei.api.recipe.transfer.IRecipeTransferError; import mezz.jei.api.recipe.transfer.IRecipeTransferHandler; @@ -15,9 +19,12 @@ import net.minecraft.world.item.crafting.CraftingRecipe; import org.jetbrains.annotations.Nullable; +import java.util.List; +import java.util.Objects; import java.util.Optional; -public class ETCraftingRecipeTransfer implements IRecipeTransferHandler { +public class ETCraftingRecipeTransfer + implements IRecipeTransferHandler, IJeiAbstractRecipeHandler { private final MenuType menuType; private final Class containerClass; private final IRecipeTransferHandlerHelper helper; @@ -48,21 +55,33 @@ public RecipeType getRecipeType() { public @Nullable IRecipeTransferError transferRecipe(T menu, CraftingRecipe recipe, IRecipeSlotsView recipeSlots, Player player, boolean maxTransfer, boolean doTransfer) { if (recipe.getIngredients().isEmpty()) { - return helper.createUserErrorWithTooltip(ItemModText.INCOMPATIBLE_RECIPE.text()); + return Result.createInCompatibleError(helper); } if (!recipe.canCraftInDimensions(menu.getCraftingGridWidth(), menu.getCraftingGridHeight())) { - return helper.createUserErrorWithTooltip(ItemModText.RECIPE_TOO_LARGE.text()); + return Result.createRecipeToLargeError(helper); } + boolean craftMissing = AbstractContainerScreen.hasControlDown(); + List inputSlots = recipeSlots.getSlotViews(RecipeIngredientRole.INPUT); var slotToIngredientMap = ETCraftingRecipeTransferHelper.getGuiSlotToIngredientMap(menu, recipe); - if (!slotToIngredientMap.isEmpty() - && menu.findMissingIngredients(slotToIngredientMap).missingSlots().size() == slotToIngredientMap.size()) { - return helper.createUserErrorWithTooltip(ItemModText.NO_ITEMS.text()); + var missingSlots = menu.findMissingIngredients(slotToIngredientMap); + if (!slotToIngredientMap.isEmpty() && missingSlots.missingSlots().size() == slotToIngredientMap.size()) { + var missingSlotViews = missingSlots.missingSlots().stream() + .map(idx -> idx < inputSlots.size() ? inputSlots.get(idx) : null) + .filter(Objects::nonNull) + .toList(); + return helper.createUserErrorForMissingSlots(ItemModText.NO_ITEMS.text(), missingSlotViews); } - if (doTransfer) { - ETCraftingRecipeTransferHelper.performTransfer(menu, recipe, null, AbstractContainerScreen.hasControlDown()); + if (!doTransfer) { + if (missingSlots.totalSize() != 0) { + int color = missingSlots.anyMissing() ? RED_SLOT_HIGHLIGHT_COLOR : BLUE_SLOT_HIGHLIGHT_COLOR; + return new Result.PartiallyCraftable(missingSlots, color, craftMissing); + } + } else { + menu.setMode(ETTerminalMode.CRAFTING); + ETCraftingRecipeTransferHelper.performTransfer(menu, recipe, null, craftMissing); } - return null; + return Result.createSuccessful(); } } diff --git a/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/handler/ETSmithingRecipeTransfer.java b/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/handler/ETSmithingRecipeTransfer.java index 63d7951..2ee3f30 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/handler/ETSmithingRecipeTransfer.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/handler/ETSmithingRecipeTransfer.java @@ -1,10 +1,14 @@ package me.myogoo.extendedterminal.integration.jei.extendedterminal.handler; import appeng.core.localization.ItemModText; +import me.myogoo.extendedterminal.integration.jei.handler.IJeiAbstractRecipeHandler; import me.myogoo.extendedterminal.integration.module.extendedterminal.ETSmithingRecipeTransferHelper; import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMode; import mezz.jei.api.constants.RecipeTypes; +import mezz.jei.api.gui.ingredient.IRecipeSlotView; import mezz.jei.api.gui.ingredient.IRecipeSlotsView; +import mezz.jei.api.recipe.RecipeIngredientRole; import mezz.jei.api.recipe.RecipeType; import mezz.jei.api.recipe.transfer.IRecipeTransferError; import mezz.jei.api.recipe.transfer.IRecipeTransferHandler; @@ -15,9 +19,12 @@ import net.minecraft.world.item.crafting.SmithingRecipe; import org.jetbrains.annotations.Nullable; +import java.util.List; +import java.util.Objects; import java.util.Optional; -public class ETSmithingRecipeTransfer implements IRecipeTransferHandler { +public class ETSmithingRecipeTransfer + implements IRecipeTransferHandler, IJeiAbstractRecipeHandler { private final MenuType menuType; private final Class containerClass; private final IRecipeTransferHandlerHelper helper; @@ -48,18 +55,30 @@ public RecipeType getRecipeType() { public @Nullable IRecipeTransferError transferRecipe(T menu, SmithingRecipe recipe, IRecipeSlotsView recipeSlots, Player player, boolean maxTransfer, boolean doTransfer) { if (!recipe.canCraftInDimensions(3, 1)) { - return helper.createUserErrorWithTooltip(ItemModText.RECIPE_TOO_LARGE.text()); + return Result.createRecipeToLargeError(helper); } + boolean craftMissing = AbstractContainerScreen.hasControlDown(); + List inputSlots = recipeSlots.getSlotViews(RecipeIngredientRole.INPUT); var slotToIngredientMap = ETSmithingRecipeTransferHelper.getGuiSlotToIngredientMap(recipe); - if (!slotToIngredientMap.isEmpty() - && menu.findMissingIngredients(slotToIngredientMap).missingSlots().size() == slotToIngredientMap.size()) { - return helper.createUserErrorWithTooltip(ItemModText.NO_ITEMS.text()); + var missingSlots = menu.findMissingIngredients(slotToIngredientMap); + if (!slotToIngredientMap.isEmpty() && missingSlots.missingSlots().size() == slotToIngredientMap.size()) { + var missingSlotViews = missingSlots.missingSlots().stream() + .map(idx -> idx < inputSlots.size() ? inputSlots.get(idx) : null) + .filter(Objects::nonNull) + .toList(); + return helper.createUserErrorForMissingSlots(ItemModText.NO_ITEMS.text(), missingSlotViews); } - if (doTransfer) { - ETSmithingRecipeTransferHelper.performTransfer(menu, recipe, AbstractContainerScreen.hasControlDown()); + if (!doTransfer) { + if (missingSlots.totalSize() != 0) { + int color = missingSlots.anyMissing() ? RED_SLOT_HIGHLIGHT_COLOR : BLUE_SLOT_HIGHLIGHT_COLOR; + return new Result.PartiallyCraftable(missingSlots, color, craftMissing); + } + } else { + menu.setMode(ETTerminalMode.SMITHING); + ETSmithingRecipeTransferHelper.performTransfer(menu, recipe, craftMissing); } - return null; + return Result.createSuccessful(); } } diff --git a/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/handler/ETStonecutterRecipeTransfer.java b/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/handler/ETStonecutterRecipeTransfer.java index fec437e..27d8400 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/handler/ETStonecutterRecipeTransfer.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/handler/ETStonecutterRecipeTransfer.java @@ -1,10 +1,14 @@ package me.myogoo.extendedterminal.integration.jei.extendedterminal.handler; import appeng.core.localization.ItemModText; +import me.myogoo.extendedterminal.integration.jei.handler.IJeiAbstractRecipeHandler; import me.myogoo.extendedterminal.integration.module.extendedterminal.ETStoneCutterRecipeTransferHelper; import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMode; import mezz.jei.api.constants.RecipeTypes; +import mezz.jei.api.gui.ingredient.IRecipeSlotView; import mezz.jei.api.gui.ingredient.IRecipeSlotsView; +import mezz.jei.api.recipe.RecipeIngredientRole; import mezz.jei.api.recipe.RecipeType; import mezz.jei.api.recipe.transfer.IRecipeTransferError; import mezz.jei.api.recipe.transfer.IRecipeTransferHandler; @@ -15,9 +19,12 @@ import net.minecraft.world.item.crafting.StonecutterRecipe; import org.jetbrains.annotations.Nullable; +import java.util.List; +import java.util.Objects; import java.util.Optional; -public class ETStonecutterRecipeTransfer implements IRecipeTransferHandler { +public class ETStonecutterRecipeTransfer + implements IRecipeTransferHandler, IJeiAbstractRecipeHandler { private final MenuType menuType; private final Class containerClass; private final IRecipeTransferHandlerHelper helper; @@ -48,18 +55,31 @@ public RecipeType getRecipeType() { public @Nullable IRecipeTransferError transferRecipe(T menu, StonecutterRecipe recipe, IRecipeSlotsView recipeSlots, Player player, boolean maxTransfer, boolean doTransfer) { if (!recipe.canCraftInDimensions(1, 1)) { - return helper.createUserErrorWithTooltip(ItemModText.RECIPE_TOO_LARGE.text()); + return Result.createRecipeToLargeError(helper); } + boolean craftMissing = AbstractContainerScreen.hasControlDown(); + List inputSlots = recipeSlots.getSlotViews(RecipeIngredientRole.INPUT); var slotToIngredientMap = ETStoneCutterRecipeTransferHelper.getGuiSlotToIngredientMap(recipe); - if (!slotToIngredientMap.isEmpty() - && menu.findMissingIngredients(slotToIngredientMap).missingSlots().size() == slotToIngredientMap.size()) { - return helper.createUserErrorWithTooltip(ItemModText.NO_ITEMS.text()); + var missingSlots = menu.findMissingIngredients(slotToIngredientMap); + if (!slotToIngredientMap.isEmpty() && missingSlots.missingSlots().size() == slotToIngredientMap.size()) { + var missingSlotViews = missingSlots.missingSlots().stream() + .map(idx -> idx < inputSlots.size() ? inputSlots.get(idx) : null) + .filter(Objects::nonNull) + .toList(); + return helper.createUserErrorForMissingSlots(ItemModText.NO_ITEMS.text(), missingSlotViews); } - if (doTransfer) { - ETStoneCutterRecipeTransferHelper.performTransfer(menu, recipe, AbstractContainerScreen.hasControlDown()); + if (!doTransfer) { + if (missingSlots.totalSize() != 0) { + int color = missingSlots.anyMissing() ? RED_SLOT_HIGHLIGHT_COLOR : BLUE_SLOT_HIGHLIGHT_COLOR; + return new Result.PartiallyCraftable(missingSlots, color, craftMissing); + } + } else { + menu.setMode(ETTerminalMode.STONECUTTING); + menu.setStoneCutterRecipeId(recipe.getId()); + ETStoneCutterRecipeTransferHelper.performTransfer(menu, recipe, craftMissing); } - return null; + return Result.createSuccessful(); } } diff --git a/src/main/java/me/myogoo/extendedterminal/integration/jei/handler/IJeiAbstractRecipeHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/jei/handler/IJeiAbstractRecipeHandler.java new file mode 100644 index 0000000..cf2f26a --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/integration/jei/handler/IJeiAbstractRecipeHandler.java @@ -0,0 +1,90 @@ +package me.myogoo.extendedterminal.integration.jei.handler; + +import appeng.core.localization.ItemModText; +import appeng.integration.modules.jeirei.TransferHelper; +import appeng.menu.me.items.CraftingTermMenu; +import mezz.jei.api.gui.builder.ITooltipBuilder; +import mezz.jei.api.gui.ingredient.IRecipeSlotsView; +import mezz.jei.api.recipe.RecipeIngredientRole; +import mezz.jei.api.recipe.transfer.IRecipeTransferError; +import mezz.jei.api.recipe.transfer.IRecipeTransferHandlerHelper; +import net.minecraft.client.gui.GuiGraphics; +import org.jetbrains.annotations.Nullable; + +public interface IJeiAbstractRecipeHandler { + int BLUE_SLOT_HIGHLIGHT_COLOR = TransferHelper.BLUE_SLOT_HIGHLIGHT_COLOR; + int RED_SLOT_HIGHLIGHT_COLOR = TransferHelper.RED_SLOT_HIGHLIGHT_COLOR; + + abstract class Result implements IRecipeTransferError { + @Override + public Type getType() { + return Type.COSMETIC; + } + + @Nullable + public static IRecipeTransferError createSuccessful() { + return null; + } + + public static IRecipeTransferError createNotApplicable(IRecipeTransferHandlerHelper helper) { + return helper.createInternalError(); + } + + public static IRecipeTransferError createInCompatibleError(IRecipeTransferHandlerHelper helper) { + return helper.createUserErrorWithTooltip(ItemModText.INCOMPATIBLE_RECIPE.text()); + } + + public static IRecipeTransferError createRecipeToLargeError(IRecipeTransferHandlerHelper helper) { + return helper.createUserErrorWithTooltip(ItemModText.RECIPE_TOO_LARGE.text()); + } + + public static final class PartiallyCraftable extends Result { + private final CraftingTermMenu.MissingIngredientSlots missingSlots; + private final boolean craftMissing; + private final int color; + + public PartiallyCraftable(CraftingTermMenu.MissingIngredientSlots missingSlots, int color, + boolean craftMissing) { + this.missingSlots = missingSlots; + this.color = color; + this.craftMissing = craftMissing; + } + + @Override + public int getButtonHighlightColor() { + return this.color; + } + + @Override + public void showError(GuiGraphics guiGraphics, int mouseX, int mouseY, IRecipeSlotsView slots, int recipeX, + int recipeY) { + var poseStack = guiGraphics.pose(); + poseStack.pushPose(); + poseStack.translate(recipeX, recipeY, 0); + + var slotViews = slots.getSlotViews(RecipeIngredientRole.INPUT); + for (int i = 0; i < slotViews.size(); i++) { + var slotView = slotViews.get(i); + boolean missing = missingSlots.missingSlots().contains(i); + boolean craftable = missingSlots.craftableSlots().contains(i); + if (missing || craftable) { + slotView.drawHighlight(guiGraphics, + missing ? RED_SLOT_HIGHLIGHT_COLOR : BLUE_SLOT_HIGHLIGHT_COLOR); + } + } + + poseStack.popPose(); + } + + @Override + public int getMissingCountHint() { + return missingSlots.missingSlots().size(); + } + + @Override + public void getTooltip(ITooltipBuilder tooltip) { + tooltip.addAll(TransferHelper.createCraftingTooltip(missingSlots, craftMissing)); + } + } + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/integration/module/extendedterminal/ETSmithingRecipeTransferHelper.java b/src/main/java/me/myogoo/extendedterminal/integration/module/extendedterminal/ETSmithingRecipeTransferHelper.java index 00c4f9b..da655ef 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/module/extendedterminal/ETSmithingRecipeTransferHelper.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/module/extendedterminal/ETSmithingRecipeTransferHelper.java @@ -3,6 +3,7 @@ import appeng.api.stacks.AEItemKey; import appeng.integration.modules.jeirei.EncodingHelper; import appeng.menu.me.common.GridInventoryEntry; +import me.myogoo.extendedterminal.api.adapter.recipe.smithing.ISmithingRecipeAdapter; import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; import me.myogoo.extendedterminal.network.serverbound.ETFillSmithingGridFromRecipePacket; import me.myogoo.myotus.api.MyotusAPI; @@ -23,7 +24,7 @@ private ETSmithingRecipeTransferHelper() { } public static Map getGuiSlotToIngredientMap(SmithingRecipe recipe) { - var ingredients = recipe.getIngredients(); + var ingredients = ISmithingRecipeAdapter.of(recipe).getIngredients(); var result = new HashMap(ingredients.size()); for (int i = 0; i < ingredients.size(); i++) { var ingredient = ingredients.get(i); diff --git a/src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/ETTerminalMenu.java b/src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/ETTerminalMenu.java index d7ed64f..77239e1 100644 --- a/src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/ETTerminalMenu.java +++ b/src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/ETTerminalMenu.java @@ -6,6 +6,7 @@ import appeng.core.sync.network.NetworkHandler; import appeng.core.sync.packets.InventoryActionPacket; import appeng.helpers.InventoryAction; +import appeng.menu.SlotSemantics; import appeng.menu.implementations.MenuTypeBuilder; import appeng.menu.slot.AppEngSlot; import appeng.menu.slot.CraftingMatrixSlot; @@ -25,6 +26,7 @@ import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.inventory.CraftingContainer; +import net.minecraft.world.inventory.DataSlot; import net.minecraft.world.inventory.MenuType; import net.minecraft.world.inventory.Slot; import net.minecraft.world.inventory.TransientCraftingContainer; @@ -114,7 +116,7 @@ public ETTerminalMenu(MenuType menuType, int id, Inventory ip, IETTerminalHos ETSlotSemantics.SMITHING_TABLE_ADDITION); this.addSlot(this.smithingOutputSlot = new ETSmithingSlot(this.getPlayerInventory().player, this.getActionSource(), this.powerSource, host.getInventory(), smithingInv, smithingInv, this), - ETSlotSemantics.SMITHING_TABLE_RESULT); + SlotSemantics.SMITHING_TABLE_RESULT); var stonecuttingInv = this.craftingInventoryHost.getSubInventory(STONECUTTER_INVENTORY); this.addSlot(this.stonecuttingSlot = new CraftingMatrixSlot(this, stonecuttingInv, 0), @@ -129,6 +131,17 @@ public ETTerminalMenu(MenuType menuType, int id, Inventory ip, IETTerminalHos this.addSlot(this.anvilRightSlot = new CraftingMatrixSlot(this, anvilInv, 1), ETSlotSemantics.ANVIL_RIGHT_INPUT); this.addSlot(this.anvilOutputSlot = new ETAnvilSlot(this.getPlayerInventory().player, anvilInv, this.anvilDelegate, this), ETSlotSemantics.ANVIL_RESULT); + this.addDataSlot(new DataSlot() { + @Override + public int get() { + return ETTerminalMenu.this.anvilCost; + } + + @Override + public void set(int value) { + ETTerminalMenu.this.anvilCost = value; + } + }); this.stoneCutterRecipeId = host.getStoneCutterRecipeId(); registerClientAction(ACTION_SET_STONECUTTING_RECIPE_ID, ResourceLocation.class, this::setStoneCutterRecipeId); diff --git a/src/main/java/me/myogoo/extendedterminal/mixin/SmithingTransformRecipeAccessor.java b/src/main/java/me/myogoo/extendedterminal/mixin/SmithingTransformRecipeAccessor.java new file mode 100644 index 0000000..b1f53cc --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/mixin/SmithingTransformRecipeAccessor.java @@ -0,0 +1,18 @@ +package me.myogoo.extendedterminal.mixin; + +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.SmithingTransformRecipe; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(SmithingTransformRecipe.class) +public interface SmithingTransformRecipeAccessor { + @Accessor("template") + Ingredient extendedterminal$getTemplate(); + + @Accessor("base") + Ingredient extendedterminal$getBase(); + + @Accessor("addition") + Ingredient extendedterminal$getAddition(); +} diff --git a/src/main/java/me/myogoo/extendedterminal/mixin/SmithingTrimRecipeAccessor.java b/src/main/java/me/myogoo/extendedterminal/mixin/SmithingTrimRecipeAccessor.java new file mode 100644 index 0000000..27e02d9 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/mixin/SmithingTrimRecipeAccessor.java @@ -0,0 +1,18 @@ +package me.myogoo.extendedterminal.mixin; + +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.SmithingTrimRecipe; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(SmithingTrimRecipe.class) +public interface SmithingTrimRecipeAccessor { + @Accessor("template") + Ingredient extendedterminal$getTemplate(); + + @Accessor("base") + Ingredient extendedterminal$getBase(); + + @Accessor("addition") + Ingredient extendedterminal$getAddition(); +} diff --git a/src/main/java/me/myogoo/extendedterminal/network/serverbound/ETFillSmithingGridFromRecipePacket.java b/src/main/java/me/myogoo/extendedterminal/network/serverbound/ETFillSmithingGridFromRecipePacket.java index c8f18e7..a37435f 100644 --- a/src/main/java/me/myogoo/extendedterminal/network/serverbound/ETFillSmithingGridFromRecipePacket.java +++ b/src/main/java/me/myogoo/extendedterminal/network/serverbound/ETFillSmithingGridFromRecipePacket.java @@ -11,6 +11,7 @@ import com.google.common.primitives.Ints; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; +import me.myogoo.extendedterminal.api.adapter.recipe.smithing.ISmithingRecipeAdapter; import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMode; import me.myogoo.myotus.api.network.IMyotusPacket; @@ -191,7 +192,7 @@ protected NonNullList getDesiredIngredients(Player player) { if (this.recipeId != null) { var optionalRecipe = player.level().getRecipeManager().byKey(this.recipeId); if (optionalRecipe.isPresent() && optionalRecipe.get() instanceof SmithingRecipe recipe) { - return recipe.getIngredients(); + return ISmithingRecipeAdapter.of(recipe).getIngredients(); } } diff --git a/src/main/resources/assets/ae2/textures/guis/et_terminal_panel.png b/src/main/resources/assets/ae2/textures/guis/et_terminal_panel.png index 7f23dd1b9f282a6d53af8ec57701f0cd9ea29ced..541824cb561ca27ddda42950e8b11eb2357e629e 100644 GIT binary patch literal 3523 zcmeHKX;f2J5WerlS0EHAg-TTrt*xe7XaFfoWi1e+Hf&K+Ko)JVScQ~C2ofQ<6e%L= zIfAuRsfgHWacNmJKq4wymMXSxXdoUGu?QFw5`tNJ-;1cnR!$buX9k%Qc|j~*L`otrJt371LKBjbc}|QV=2SN)XD4SDYlOyw zO0{ejJ&{hI1x(=v1CtO8Ads35-^q_?7z&^uB!Z8}qdyc!txWp#F*(SogMYV%t~f&i21gJd8(_3z{t->|oo!e!S<$uWE11p1Gz4 zySbfFc`;|(rwq|?9W#=lEHbC~Vcd>_ta-6IorCvChR7`QqeJiS z?sc48^9^!y`xeyBtwOq?{+-MAA!EzqYXU0dOmKWOR) z^jGs7*_m&Kt^AMU4nYfnG0{p~3S_j!Mto7oq4pbXI3lH3#C&0l@i zx}IGo7Kz6f^K4`XJo{(dV;>!Wk*&PZrRCc{8{H>^Ya9Ncd4FckrPe3b)*r^0u1}(} zXqd!mgUK*dpWk6!e;Xx-o-9c#%f7aJNS&<|imjAlV+wp^(3RWko{b-qE9SY27nlTB zLf@R!&3T>MgH3{+{^55g&=MI}UY|OODJL3kO=JggFlR88fK>|twxc1Mmts*H3$i#LJ3_{7^hQl~wpDfYrB1!TzOtXdRa+G*SSil9^8G4lm!AKaTaGU5 z%NEy*nIKCbmq)Mok7oxEg$rJsN*xhkv9k%g4uu6xc{9xFR3t4uMK(##A zKgP2?+Nl&zutN}@Ri7_VCKaY%JNIJSps`&{eGz<~i>omdj0HqVx|5;V_tM3RDhFyg z-k80I@%oA{eJM!;&H-wPpGtcAs>T$TC00lu%%@ zOD#k_F4P%ShX>H!JvP4Q_Sg`Z_137+UbWfaaAG@bKp_<2`a3Sa7NGpAj@>h{`$wW* z!l*~bAgZ4R^=sHu?~W`d5{1b;MI=TlvBUG=@NVfvNRbhon8}cZuF&)8$yV&a=M^&cE|) zipH;QZ(&SEVjwaLeyPUv)RAV_Wwb^GKGSM8o4072UGaIQf%B{?I+)c{dtyMmColPw z+hbN@6yh^rc0L_ez0{@AMM1t_N159N%RQ~dv}NHtlJ5QY1+awIoVF{nD$+zDN{755 z-287=Tvk)<=W>CE{@z3#ZG~o3OJ0w$d~pL)oO9XQn-#*Z^-X#&!X(bwz@9NdCO7W! zD_Up6cEE3d?VulC@a1A59IB)4CN4(wYwdRr!cHS%$FO=LcWad5H}DyrJkhpDvtxNM zp*pllqd!$LLosP_!-LjML<_LN4#YDaQt*+c3X?}X9#rf8e2%;z_s^L;|MbKg@mw2; n9Y&=gtzqDQ^8Y;i=RjZpEZgLtL|3&G{I3K(h!I#B5Wnts3*XMT literal 3524 zcmeGfX;70_@O^;@1VL-D3IwpVRRkKsWl)5m2*?=(IfVc!A{6D+1O*c)mWot7s;C_S zFSM1*A{8Zp6k3pifH304DT0X@667|7^yLFuDs5+++D?D?X5RPq?e4eN+uiql2VI

CmA=5{bm!-QCC2XQSQf&jKAG{pykOC2&!QadmcsRCEA03VneT8L`1T z8UW>T=|mQ4+cP0jHOAU2#w~n%3@tD!2)G1>?1~{cTW?xoLNFj07`~6##z3axATPV^ zc6K^I9&WHe4Z#8gLiTW~Pr=X?ppD3&c&SeY2nM_dS06Y-l4VhR7=)$cskST#3OP*7V;7ejfhCrq+F>^Y}TZ#lMt2;43vyPIbBzoLTKtO10qpM{hXnXk7{UY z2VkzT-TJkg=v01dpxaW?{G>o)mEVL!-#NFa=c1-U^EMZ!@7kXoFYHhGHp3zg*+QkJ zh~&uj0|Z++8^WCuyvE|2#)7DrfTxYDn!5={9i|AP?r!(i!SWX=8OLm-jBr1+tS!&? zu3ICQbNf=P8!$RU!V)jMIWSU*;okU~^73pDR9$&}UgS;BJno7`NmgpB?B#6o4EPm% zC%>ELFZ)^|I*XeuxR;+kte0@HVphBY_DX=GX#TL_Sdv!$d#8p!d=d10AKjYb z%_X}*F@MAr?^cpeHdYC^YQVR8P_wPIKPBV)h+eh%$|2eukFAfA3(~7^buBax>ZJE| zMVekb2R45dqE${^)_d4<@aqGjnPkVy?>n7iM!oCy!K1>*T@f3skRQ~V zERxuc%^LZ5+Vh`_#^ge0h&<8d%pN_+n}sW0DX~<-J_tn}@usoPU)H-Gd}FqfK8l4_ z^6So+W{Bwc*DX)Tm-R53Vcsa!(qx8X34%FN@|R?ObazTd6oLjZi~Pb!G^WMoP-Mm7 zlMZJJVHmm-|L7Qu@=y1VZjU>uoazf@7Psias2Hy%MuoJga8i4mklGz@4w#Dw{1du+ z?bZGw_hu#KA?6*PR`Kj4oy9nvz5f=0)JVgVtJTwbIk!!++3ur^TJ<))y)dq#J$QHxZ73#!ACj-Ba{S#MMM+<;B0q1~6yN5;%zc%kzc9c{BI2_jdrE$)kB=)> zz!kV>4i#Zq{Kv>txl&K&KAG}Pn26uizuJNvo-;1q%(;OR_IEBrMS3bmOvrWk`7;$C zIq@S+S+FdIy#4h#U0UsBL+PA>-%vUnF}7o(m_2umKeMVUf)1_$6O`URP# z={GW*loXo1c}sXMLbfU>bb z85@xmOVeh`+$pg_@H^Txa2=KdeJ()m3@sUB+Q2eX;UrA4)=?H&mbu0q%U3~j)_k-d z!xbfwSl)xM`N`lqIpq7Fgy{^EMuJr^3TiF!aSun$Rp%Q-I?>VH5UC zeX~2J2heWvc_x8lf*#o4*#GCQj!zutkH5^{pGASEe<}7K9rfEdxVMpa?7O`!JEt1$ z=KfusQ+ZC;v#MVHM3vqBi@7<@<;PIfMQznQvynj!g%J|G)$SP*^ajjET5ior5~;(R zFH|+~wD|d%e8It8tp=SFuy~4mY`nJnAQpAgFO(Y&;Dn~yE$y&Rc+|+(IO=g?U5m?L ziJvt{4oV8L@C0JdE&Ca;lvi(6uHoKq@D~smd(tL!P1w_1<6%e-s^6%mAXPHDprA41 zfo3vlfoilDRJaAHtNL9%712zq5KFJUqSS)g>zKGT%2U>t8y4b(Bax{3+>?=kr`vBn zYm%hwfL-Wnkgrz{t&ewLQtW^@eU(zBNp0M-3{B}Bwoey^(E5zfT-C7+E-= z-w%niK4$){>tN;w(+nLS1w^ZG@K~ZPQo9kn1K-8rf0qOjOmxYv>VhTj9gzM@*jYQT J&s!Ie_$y2~%1QtL diff --git a/src/main/resources/extendedterminal.mixins.json b/src/main/resources/extendedterminal.mixins.json index d365c55..7f00073 100644 --- a/src/main/resources/extendedterminal.mixins.json +++ b/src/main/resources/extendedterminal.mixins.json @@ -5,7 +5,9 @@ "compatibilityLevel": "JAVA_17", "refmap": "extendedterminal.refmap.json", "mixins": [ - "AEBaseMenuMixin" + "AEBaseMenuMixin", + "SmithingTransformRecipeAccessor", + "SmithingTrimRecipeAccessor" ], "injectors": { "defaultRequire": 1 From 392083ef9fde9104abadb72ea68965e9e7210535 Mon Sep 17 00:00:00 2001 From: njoyshadow Date: Tue, 14 Apr 2026 23:30:27 +0900 Subject: [PATCH 06/11] feat: update terminal conditions and add Extended Terminal guideme --- .../assets/extendedterminal/ae2guide/index.md | 1 + .../ae2guide/terminals/avaritianeo.md | 2 +- .../ae2guide/terminals/extendedcrafting.md | 12 +++++- .../ae2guide/terminals/extendedterminal.md | 37 +++++++++++++++++++ .../ae2guide/terminals/re_avaritia.md | 2 +- 5 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 src/main/resources/assets/extendedterminal/ae2guide/terminals/extendedterminal.md diff --git a/src/main/resources/assets/extendedterminal/ae2guide/index.md b/src/main/resources/assets/extendedterminal/ae2guide/index.md index d9b6cf0..bc244b0 100644 --- a/src/main/resources/assets/extendedterminal/ae2guide/index.md +++ b/src/main/resources/assets/extendedterminal/ae2guide/index.md @@ -10,6 +10,7 @@ navigation: - [Compat Processor](compat_processor.md) ## Terminals +- [Extended Terminal](terminals/extendedterminal.md) - [Extended Crafting Terminal](terminals/extendedcrafting.md) - [Re:Avaritia Crafting Terminal](terminals/re_avaritia.md) - [AvaritiaNeo Crafting Terminal](terminals/avaritianeo.md) diff --git a/src/main/resources/assets/extendedterminal/ae2guide/terminals/avaritianeo.md b/src/main/resources/assets/extendedterminal/ae2guide/terminals/avaritianeo.md index 8512aba..57120e2 100644 --- a/src/main/resources/assets/extendedterminal/ae2guide/terminals/avaritianeo.md +++ b/src/main/resources/assets/extendedterminal/ae2guide/terminals/avaritianeo.md @@ -12,7 +12,7 @@ item_ids: # AvaritiaNeo Crafting Terminal - + diff --git a/src/main/resources/assets/extendedterminal/ae2guide/terminals/extendedcrafting.md b/src/main/resources/assets/extendedterminal/ae2guide/terminals/extendedcrafting.md index 19c8d62..a08aa47 100644 --- a/src/main/resources/assets/extendedterminal/ae2guide/terminals/extendedcrafting.md +++ b/src/main/resources/assets/extendedterminal/ae2guide/terminals/extendedcrafting.md @@ -61,4 +61,14 @@ item_ids: - + +# Extended Crafting Terminal: Expanded + ## Epic Extended Crafting Terminal + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/assets/extendedterminal/ae2guide/terminals/extendedterminal.md b/src/main/resources/assets/extendedterminal/ae2guide/terminals/extendedterminal.md new file mode 100644 index 0000000..182197a --- /dev/null +++ b/src/main/resources/assets/extendedterminal/ae2guide/terminals/extendedterminal.md @@ -0,0 +1,37 @@ +--- +navigation: + title: Extended Terminal + icon: et_terminal + parent: index.md + position: 1 +categories: + - extendedterminal +item_ids: + - et_terminal + - wireless_et_terminal +--- + +# Extended Terminal + + + + is all in one terminal that include Crafting, Smithing, Stonecutter and Anvil. + +## Recipe + + + +# Wireless Terminal + is a wireless version of the . It requires a to function. +## Recipe + + +### Universal Wireless Terminal + can be combined with as well + + + + + + + \ No newline at end of file diff --git a/src/main/resources/assets/extendedterminal/ae2guide/terminals/re_avaritia.md b/src/main/resources/assets/extendedterminal/ae2guide/terminals/re_avaritia.md index 3dbd98d..cb06dd5 100644 --- a/src/main/resources/assets/extendedterminal/ae2guide/terminals/re_avaritia.md +++ b/src/main/resources/assets/extendedterminal/ae2guide/terminals/re_avaritia.md @@ -15,7 +15,7 @@ item_ids: # Re:Avaritia Crafting Terminal - + From 94cd3429005267cc231d2fb80612479ca05a0bea Mon Sep 17 00:00:00 2001 From: njoyshadow Date: Wed, 15 Apr 2026 19:13:48 +0900 Subject: [PATCH 07/11] feat: update stone cutter guis & update avaritia recipe condition --- TODO.md | 1 + gradle.properties | 8 ++++---- .../gui/panels/StoneCutterPanel.java | 16 ++++++++-------- .../ae2/textures/guis/et_terminal_panel.png | Bin 3523 -> 3619 bytes .../recipes/avaritianeo/extreme_terminal.json | 2 +- .../recipes/reavaritia/end_terminal.json | 2 +- .../recipes/reavaritia/extreme_terminal.json | 2 +- .../recipes/reavaritia/nether_terminal.json | 2 +- .../recipes/reavaritia/sculk_terminal.json | 2 +- 9 files changed, 18 insertions(+), 17 deletions(-) create mode 100644 TODO.md diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..3b0ba46 --- /dev/null +++ b/TODO.md @@ -0,0 +1 @@ +1. et terminal에서 stonecutter 조합법 button 이미지 조정 필요 \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 81406d2..9dbfb37 100644 --- a/gradle.properties +++ b/gradle.properties @@ -37,8 +37,8 @@ Cucumber_version=7.0.14 ExtendedCrafting_version=6.0.9 guideME_version=20.1.11 -itemListMod=jei +itemListMod=emi -enable_avaritia=re -enable_excrafting=exex -enable_wtlib=true \ No newline at end of file +enable_avaritia=neo +enable_excrafting=ex +enable_wtlib=false \ No newline at end of file diff --git a/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/panels/StoneCutterPanel.java b/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/panels/StoneCutterPanel.java index d3caab6..fffd390 100644 --- a/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/panels/StoneCutterPanel.java +++ b/src/main/java/me/myogoo/extendedterminal/client/screen/extendedterminal/gui/panels/StoneCutterPanel.java @@ -22,11 +22,11 @@ import java.util.Objects; public class StoneCutterPanel extends ETTerminalModePanel { - private static final Blitter BG = Blitter.texture("guis/et_terminal_panel.png", 512, 512).src(0, 134, 159, 65); - private static final Blitter AE_BG = Blitter.texture("guis/pattern_modes.png").src(0, 140, 124, 66); - private static final Blitter BG_SLOT = AE_BG.copy().src(124, 140, 20, 22); - private static final Blitter BG_SLOT_SELECTED = AE_BG.copy().src(124, 162, 20, 22); - private static final Blitter BG_SLOT_HOVER = AE_BG.copy().src(124, 184, 20, 22); + private static final Blitter TEXTURE = Blitter.texture("guis/et_terminal_panel.png", 512, 512); + private static final Blitter BG = TEXTURE.copy().src(0, 134, 159, 65); + private static final Blitter BG_SLOT = TEXTURE.copy().src(160, 0, 20, 22); + private static final Blitter BG_SLOT_SELECTED = TEXTURE.copy().src(160, 23, 20, 22); + private static final Blitter BG_SLOT_HOVER = TEXTURE.copy().src(160, 45, 20, 22); private static final int COLS = 4; private static final int ROWS = 2; @@ -117,13 +117,13 @@ private void drawRecipes(GuiGraphics guiGraphics, Rect2i bounds, Point mouse) { } int renderX = bounds.getX() + slotBounds.getX(); - int renderY = bounds.getY() + slotBounds.getY(); + int renderY = bounds.getY() + slotBounds.getY() + 1; blitter.dest(renderX, renderY).blit(guiGraphics); var resultItem = recipe.getResultItem(getRegistryAccess()); if (selected || mouse.isIn(slotBounds)) { - guiGraphics.renderItem(resultItem, renderX + 2, renderY + 3); - guiGraphics.renderItemDecorations(Minecraft.getInstance().font, resultItem, renderX + 2, renderY + 3); + guiGraphics.renderItem(resultItem, renderX + 2, renderY + 2); + guiGraphics.renderItemDecorations(Minecraft.getInstance().font, resultItem, renderX + 2, renderY + 2); } else { guiGraphics.renderItem(resultItem, renderX + 2, renderY + 2); guiGraphics.renderItemDecorations(Minecraft.getInstance().font, resultItem, renderX + 2, renderY + 2); diff --git a/src/main/resources/assets/ae2/textures/guis/et_terminal_panel.png b/src/main/resources/assets/ae2/textures/guis/et_terminal_panel.png index 541824cb561ca27ddda42950e8b11eb2357e629e..1d9ab003c025d8b5125179e4196a9959cf5e3bc0 100644 GIT binary patch literal 3619 zcmeHKdr(tX8b3E721BK?1bIc2rQ_-ffq+hefQkqaL4t&rMFS}Vlr16~0s(nNprsWB zow2-hfr3J{EzpIwAOupSK+B^%+KPln5Tq!E;PMCrlI*!bDXssw)19_|^v>Lz?{V(; zI=}BbllMG5=$i;e1OUJ$*CU6$0Kh;J12nO4xm)&H8(ffRFZv-+(M5U$8I3Tj<>rVl}gRb%v7mVrd#!oyY737?JlpAe*SJnh&$WI z$LDpw*HI&t$#l4E=6ZQB;m-9B5SyJcgu0DUM@~copxuPN2o1-44GImp&i-8HnNTi| z%?SaX?C?k~*~8g;`(84IOtIEQ=v=s|HpJgG)YbLxKoc@JV1(cR0;!|$HGW3JG{H^; ztCpkrQVx zTRD(M9}KjNQSbD!r9tZ1R}?ENRNFvoh?~DxFa*FWJlDgH-f=9+ki^%RzB!$}Vv29w z*r=-SG`yJ3yTxlG%y&JCew>uN%UIIwoqLXN#$ugczQ_z8ez>A6X?(oQ|J$1=`5&Le zJ{iL3ZfO4i{Mh@m-#}L5N13et`jYbNY8~VQo3qXQ=C14^icc0$aaN`AOknfB5j+7V zQBgLRB-Gs_eH+)kZP!Q}BPS+k+^8?|0Vn%p4^vw+gUh+1ec@#AK?oEg$1; zRW>x4F)nCQmFmxpEtul9W^&Jd592oIi@d{%-7jw4efAq<^b(mU_F4IEP5#5y%E?{2 zqHN;mr7Vp3-m;-|!IO{eSUt=g%J+%1Di{VtZrQK8(1OoQKkC!78bJVAG?Bw+2-Di&) zZ8fOdBRz{-3{arocQEa2Jhv*JMf|7Hry>y@-*GfVpltl7Q1 z1+P&RMH=_%Bt%kf3DCO`PL-R+OYb>N;uN(>n(F$)vyXSU1hHtl{W<2QSW1B?Pz{L0 z2e~ez-tY`XZlVO4bow^cZ+N%@p2B;Kl>yo{h@JTB;LK^oCrGQ-%#3AL^G%4^ySUm& zm3(`|>01s8h-A?!l7n$^BgwO60atJDS1hbaop1&}sAA(2J_Okcc^qoc)|WpOrj&h) z6##inos3$OrfwsW`N6k@MU@y6bKz&mX#Z+&kt~Fg1EA8xLbz-^;HYkcEPb&u`^>A! zI&JsB+c4n_LX<)yDrxY*CVOwbXe=sXwOg|E#2kh7j3SdyCq$)?vLxz;>5Q=yAlsDY z;?v8Y@bQG1pQ3NfU1p?C;0(~_UNJ8&Sl0?)GO!;R!ck(GMq8U40wP-6gk1#BFX1UX zojpR`?}m4&ph!}=LE~`b^_;uxHcO`CUC5pFBsF?DzmejvLD6!2#jo>8ozr)6kbG9O z)Nh&Bi)J#ss4RFAmU1GmmF0O9O)4P`L+fs!?&M=%n(QL;lgk%f8krxfp(~!lOircq z8vN(rY{U}8;>K5EJ^&`6?Te0xeMgQX;{N~n8GNI0#giz!o43Hn&A@@9d*`X2Hsg|%u!nVC-0%GMB7K(9Vaq6=5mBj7CrC*Th!ZP9Y8PIahk0bAJ z5M`w=+reuu!VsUcl%IfJgU@(&zUccHRSJW9pQJl2g&kNOk{(i~CstgGN`Y-!U}0u% zQwd~gcNFM7_4$RWj%LiD2SLVzcTqqG+mM}~t#?rMet%O_DR3KlL%Y4df}M~Qy;Pbo z7kG0>?ZjfD>O!=r8i zS&Lfi%+blo_vOPYQHhS502lvIUqorIt@eN4THAcqMwYl3sIwXzwtc0;Awaz~CUZ&N zer>~;(L&-xp~dP9fc2qBZtOgW3m$O$ieWmmXb#)HrAABLKflW)SRF%|{LbSbnkXdU mtmsI`pX8r)_@jY9fj2gE{mY~@_!jzi#MRm3aK)jZ)c*ps$_h*X literal 3523 zcmeHKX;f2J5WerlS0EHAg-TTrt*xe7XaFfoWi1e+Hf&K+Ko)JVScQ~C2ofQ<6e%L= zIfAuRsfgHWacNmJKq4wymMXSxXdoUGu?QFw5`tNJ-;1cnR!$buX9k%Qc|j~*L`otrJt371LKBjbc}|QV=2SN)XD4SDYlOyw zO0{ejJ&{hI1x(=v1CtO8Ads35-^q_?7z&^uB!Z8}qdyc!txWp#F*(SogMYV%t~f&i21gJd8(_3z{t->|oo!e!S<$uWE11p1Gz4 zySbfFc`;|(rwq|?9W#=lEHbC~Vcd>_ta-6IorCvChR7`QqeJiS z?sc48^9^!y`xeyBtwOq?{+-MAA!EzqYXU0dOmKWOR) z^jGs7*_m&Kt^AMU4nYfnG0{p~3S_j!Mto7oq4pbXI3lH3#C&0l@i zx}IGo7Kz6f^K4`XJo{(dV;>!Wk*&PZrRCc{8{H>^Ya9Ncd4FckrPe3b)*r^0u1}(} zXqd!mgUK*dpWk6!e;Xx-o-9c#%f7aJNS&<|imjAlV+wp^(3RWko{b-qE9SY27nlTB zLf@R!&3T>MgH3{+{^55g&=MI}UY|OODJL3kO=JggFlR88fK>|twxc1Mmts*H3$i#LJ3_{7^hQl~wpDfYrB1!TzOtXdRa+G*SSil9^8G4lm!AKaTaGU5 z%NEy*nIKCbmq)Mok7oxEg$rJsN*xhkv9k%g4uu6xc{9xFR3t4uMK(##A zKgP2?+Nl&zutN}@Ri7_VCKaY%JNIJSps`&{eGz<~i>omdj0HqVx|5;V_tM3RDhFyg z-k80I@%oA{eJM!;&H-wPpGtcAs>T$TC00lu%%@ zOD#k_F4P%ShX>H!JvP4Q_Sg`Z_137+UbWfaaAG@bKp_<2`a3Sa7NGpAj@>h{`$wW* z!l*~bAgZ4R^=sHu?~W`d5{1b;MI=TlvBUG=@NVfvNRbhon8}cZuF&)8$yV&a=M^&cE|) zipH;QZ(&SEVjwaLeyPUv)RAV_Wwb^GKGSM8o4072UGaIQf%B{?I+)c{dtyMmColPw z+hbN@6yh^rc0L_ez0{@AMM1t_N159N%RQ~dv}NHtlJ5QY1+awIoVF{nD$+zDN{755 z-287=Tvk)<=W>CE{@z3#ZG~o3OJ0w$d~pL)oO9XQn-#*Z^-X#&!X(bwz@9NdCO7W! zD_Up6cEE3d?VulC@a1A59IB)4CN4(wYwdRr!cHS%$FO=LcWad5H}DyrJkhpDvtxNM zp*pllqd!$LLosP_!-LjML<_LN4#YDaQt*+c3X?}X9#rf8e2%;z_s^L;|MbKg@mw2; n9Y&=gtzqDQ^8Y;i=RjZpEZgLtL|3&G{I3K(h!I#B5Wnts3*XMT diff --git a/src/main/resources/data/extendedterminal/recipes/avaritianeo/extreme_terminal.json b/src/main/resources/data/extendedterminal/recipes/avaritianeo/extreme_terminal.json index be974e4..9ade750 100644 --- a/src/main/resources/data/extendedterminal/recipes/avaritianeo/extreme_terminal.json +++ b/src/main/resources/data/extendedterminal/recipes/avaritianeo/extreme_terminal.json @@ -5,7 +5,7 @@ "conditions": [ { "type": "myotus:mod_condition", - "active_mod": "avaritia" + "active_mod": "Avaritia" } ], "recipe": { diff --git a/src/main/resources/data/extendedterminal/recipes/reavaritia/end_terminal.json b/src/main/resources/data/extendedterminal/recipes/reavaritia/end_terminal.json index bc7307b..83b04ba 100644 --- a/src/main/resources/data/extendedterminal/recipes/reavaritia/end_terminal.json +++ b/src/main/resources/data/extendedterminal/recipes/reavaritia/end_terminal.json @@ -5,7 +5,7 @@ "conditions": [ { "type": "myotus:mod_condition", - "active_mod": "avaritia" + "active_mod": "Re-Avaritia" } ], "recipe": { diff --git a/src/main/resources/data/extendedterminal/recipes/reavaritia/extreme_terminal.json b/src/main/resources/data/extendedterminal/recipes/reavaritia/extreme_terminal.json index 41c1271..e70ea91 100644 --- a/src/main/resources/data/extendedterminal/recipes/reavaritia/extreme_terminal.json +++ b/src/main/resources/data/extendedterminal/recipes/reavaritia/extreme_terminal.json @@ -5,7 +5,7 @@ "conditions": [ { "type": "myotus:mod_condition", - "active_mod": "avaritia" + "active_mod": "Re-Avaritia" } ], "recipe": { diff --git a/src/main/resources/data/extendedterminal/recipes/reavaritia/nether_terminal.json b/src/main/resources/data/extendedterminal/recipes/reavaritia/nether_terminal.json index 64662dc..5f7ba97 100644 --- a/src/main/resources/data/extendedterminal/recipes/reavaritia/nether_terminal.json +++ b/src/main/resources/data/extendedterminal/recipes/reavaritia/nether_terminal.json @@ -5,7 +5,7 @@ "conditions": [ { "type": "myotus:mod_condition", - "active_mod": "avaritia" + "active_mod": "Re-Avaritia" } ], "recipe": { diff --git a/src/main/resources/data/extendedterminal/recipes/reavaritia/sculk_terminal.json b/src/main/resources/data/extendedterminal/recipes/reavaritia/sculk_terminal.json index 2936502..5d8d26e 100644 --- a/src/main/resources/data/extendedterminal/recipes/reavaritia/sculk_terminal.json +++ b/src/main/resources/data/extendedterminal/recipes/reavaritia/sculk_terminal.json @@ -5,7 +5,7 @@ "conditions": [ { "type": "myotus:mod_condition", - "active_mod": "avaritia" + "active_mod": "Re-Avaritia" } ], "recipe": { From 127585191c42fbad716fb4e1096f70a405d569c0 Mon Sep 17 00:00:00 2001 From: njoyshadow Date: Wed, 15 Apr 2026 23:01:37 +0900 Subject: [PATCH 08/11] fix: wireless terminal register --- gradle.properties | 2 +- .../extendedterminal/ExtendedTerminal.java | 7 ++- .../extendedterminal/client/ETClient.java | 4 +- .../extendedterminal/init/ETCreativeTab.java | 5 +- .../extendedterminal/init/wt/WTInit.java | 59 ------------------- .../extendedterminal/init/wt/WTInits.java | 21 +++++++ .../extendedterminal/init/wt/WTItems.java | 10 +--- src/main/resources/META-INF/mods.toml | 7 +++ 8 files changed, 40 insertions(+), 75 deletions(-) delete mode 100644 src/main/java/me/myogoo/extendedterminal/init/wt/WTInit.java create mode 100644 src/main/java/me/myogoo/extendedterminal/init/wt/WTInits.java diff --git a/gradle.properties b/gradle.properties index 9dbfb37..e9d6945 100644 --- a/gradle.properties +++ b/gradle.properties @@ -41,4 +41,4 @@ itemListMod=emi enable_avaritia=neo enable_excrafting=ex -enable_wtlib=false \ No newline at end of file +enable_wtlib=true \ No newline at end of file diff --git a/src/main/java/me/myogoo/extendedterminal/ExtendedTerminal.java b/src/main/java/me/myogoo/extendedterminal/ExtendedTerminal.java index 61beb82..edc0ee2 100644 --- a/src/main/java/me/myogoo/extendedterminal/ExtendedTerminal.java +++ b/src/main/java/me/myogoo/extendedterminal/ExtendedTerminal.java @@ -3,12 +3,14 @@ import com.mojang.logging.LogUtils; import me.myogoo.extendedterminal.init.*; +import me.myogoo.extendedterminal.init.wt.WTInits; import me.myogoo.extendedterminal.init.wt.WTItems; import me.myogoo.extendedterminal.init.wt.WTMenus; +import me.myogoo.myotus.api.MyotusAPI; import me.myogoo.myotus.api.annotation.wt.AE2WTLib; -import me.myogoo.myotus.util.mod.ModIntegrationManager; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.eventbus.api.EventPriority; import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; @@ -31,9 +33,10 @@ public ExtendedTerminal() { ETParts.REGISTER.register(modEventBus); ETMenus.REGISTER.register(modEventBus); ETCreativeTab.REGISTER.register(modEventBus); - if (ModIntegrationManager.isLoaded(AE2WTLib.class)) { + if (MyotusAPI.get().modIntegrationManager().isLoaded(AE2WTLib.class)) { WTItems.register(); WTMenus.register(); + modEventBus.addListener(EventPriority.LOWEST,WTInits::init); } MinecraftForge.EVENT_BUS.register(this); diff --git a/src/main/java/me/myogoo/extendedterminal/client/ETClient.java b/src/main/java/me/myogoo/extendedterminal/client/ETClient.java index 300d37e..33c8eb8 100644 --- a/src/main/java/me/myogoo/extendedterminal/client/ETClient.java +++ b/src/main/java/me/myogoo/extendedterminal/client/ETClient.java @@ -20,8 +20,8 @@ import me.myogoo.extendedterminal.menu.extendedcrafting.*; import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; import me.myogoo.extendedterminal.menu.extendedterminal.wt.ETWTMenu; +import me.myogoo.myotus.api.MyotusAPI; import me.myogoo.myotus.api.annotation.wt.AE2WTLib; -import me.myogoo.myotus.util.mod.ModIntegrationManager; import net.minecraft.world.level.ItemLike; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.client.event.RegisterColorHandlersEvent; @@ -44,7 +44,7 @@ public static void clientSetup(FMLClientSetupEvent event) { event.enqueueWork(ETClient::initScreens); event.enqueueWork(() -> { - if (ModIntegrationManager.isLoaded(AE2WTLib.class)) { + if (MyotusAPI.get().modIntegrationManager().isLoaded(AE2WTLib.class)) { initWTScreen(); } }); diff --git a/src/main/java/me/myogoo/extendedterminal/init/ETCreativeTab.java b/src/main/java/me/myogoo/extendedterminal/init/ETCreativeTab.java index d8a88ce..d5de295 100644 --- a/src/main/java/me/myogoo/extendedterminal/init/ETCreativeTab.java +++ b/src/main/java/me/myogoo/extendedterminal/init/ETCreativeTab.java @@ -1,13 +1,12 @@ package me.myogoo.extendedterminal.init; import appeng.api.config.Actionable; -import appeng.core.definitions.AEParts; import appeng.core.definitions.ItemDefinition; import appeng.items.tools.powered.WirelessTerminalItem; import me.myogoo.extendedterminal.ExtendedTerminal; import me.myogoo.extendedterminal.init.wt.WTItems; +import me.myogoo.myotus.api.MyotusAPI; import me.myogoo.myotus.api.annotation.wt.AE2WTLib; -import me.myogoo.myotus.util.mod.ModIntegrationManager; import net.minecraft.core.registries.Registries; import net.minecraft.network.chat.Component; import net.minecraft.world.item.CreativeModeTab; @@ -24,7 +23,7 @@ public class ETCreativeTab { for (ItemDefinition item : ETItems.ITEMS) { output.accept(item.stack()); } - if (ModIntegrationManager.isLoaded(AE2WTLib.class)) { + if (MyotusAPI.get().modIntegrationManager().isLoaded(AE2WTLib.class)) { for (ItemDefinition item : WTItems.WT_ITEMS) { output.accept(item.stack()); var chargedStack = item.stack().copy(); diff --git a/src/main/java/me/myogoo/extendedterminal/init/wt/WTInit.java b/src/main/java/me/myogoo/extendedterminal/init/wt/WTInit.java deleted file mode 100644 index 9c3cc75..0000000 --- a/src/main/java/me/myogoo/extendedterminal/init/wt/WTInit.java +++ /dev/null @@ -1,59 +0,0 @@ -package me.myogoo.extendedterminal.init.wt; - -import appeng.api.features.GridLinkables; -import appeng.items.tools.powered.WirelessTerminalItem; -import de.mari_023.ae2wtlib.terminal.ItemWT; -import de.mari_023.ae2wtlib.wut.WUTHandler; -import me.myogoo.extendedterminal.ExtendedTerminal; -import me.myogoo.extendedterminal.me.host.ETWTHost; -import me.myogoo.extendedterminal.menu.ETMenuType; -import me.myogoo.extendedterminal.menu.extendedterminal.wt.ETWTMenu; -import me.myogoo.myotus.api.annotation.wt.AE2WTLib; -import me.myogoo.myotus.util.mod.ModIntegrationManager; -import net.minecraft.core.registries.Registries; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.common.capabilities.RegisterCapabilitiesEvent; -import net.minecraftforge.registries.RegisterEvent; - -@Mod.EventBusSubscriber(modid = ExtendedTerminal.MODID, bus = Mod.EventBusSubscriber.Bus.MOD) -public final class WTInit { - private WTInit() { - } - - @SubscribeEvent - public static void init(RegisterEvent event) { - WTItems.register(); - WTMenus.register(); - - if (!event.getRegistryKey().equals(Registries.ITEM)) { - return; - } - - if (!ModIntegrationManager.isLoaded(AE2WTLib.class)) { - ExtendedTerminal.LOGGER.warn("[ET] AE2WTLib not loaded, skipping wireless terminal registration"); - return; - } - - if (WTItems.WIRELESS_ET_TERMINAL == null) { - ExtendedTerminal.LOGGER.warn("[ET] WIRELESS_ET_TERMINAL is null, skipping wireless terminal registration"); - return; - } - - var terminal = (ItemWT) WTItems.WIRELESS_ET_TERMINAL.asItem(); - WUTHandler.addTerminal( - ETMenuType.ET_TERMINAL.getWTIdAsString(), - terminal::tryOpen, - ETWTHost::new, - ETWTMenu.TYPE, - terminal, - ETMenuType.ET_TERMINAL.getWTIdAsString(), - "item.extendedterminal.wireless_et_terminal"); - GridLinkables.register(terminal, WirelessTerminalItem.LINKABLE_HANDLER); - } - - @SubscribeEvent - public static void initCapabilities(RegisterCapabilitiesEvent event) { - // WT-specific capability wiring is handled by AE2WTLib when present. - } -} diff --git a/src/main/java/me/myogoo/extendedterminal/init/wt/WTInits.java b/src/main/java/me/myogoo/extendedterminal/init/wt/WTInits.java new file mode 100644 index 0000000..0eecc0e --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/init/wt/WTInits.java @@ -0,0 +1,21 @@ +package me.myogoo.extendedterminal.init.wt; + +import de.mari_023.ae2wtlib.wut.WUTHandler; +import me.myogoo.extendedterminal.me.host.ETWTHost; +import me.myogoo.extendedterminal.menu.extendedterminal.wt.ETWTMenu; +import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; +import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.RegisterEvent; + +public class WTInits { + public static void init(RegisterEvent event) { + if (event.getRegistryKey().equals(ForgeRegistries.Keys.ITEMS)) { + WUTHandler + .addTerminal("wireless_et_terminal", + WTItems.WIRELESS_ET_TERMINAL.asItem()::tryOpen, + ETWTHost::new, + ETWTMenu.TYPE, + WTItems.WIRELESS_ET_TERMINAL.asItem()); + } + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/init/wt/WTItems.java b/src/main/java/me/myogoo/extendedterminal/init/wt/WTItems.java index c31ab46..b5226ab 100644 --- a/src/main/java/me/myogoo/extendedterminal/init/wt/WTItems.java +++ b/src/main/java/me/myogoo/extendedterminal/init/wt/WTItems.java @@ -1,6 +1,7 @@ package me.myogoo.extendedterminal.init.wt; import appeng.core.definitions.ItemDefinition; +import de.mari_023.ae2wtlib.terminal.ItemWT; import me.myogoo.extendedterminal.ExtendedTerminal; import me.myogoo.extendedterminal.init.ETItems; import me.myogoo.extendedterminal.item.wtitem.ETWTItem; @@ -16,21 +17,14 @@ public final class WTItems { public static final List> WT_ITEMS = new ArrayList<>(); - public static final ItemDefinition WIRELESS_ET_TERMINAL = createWTItem( + public static final ItemDefinition WIRELESS_ET_TERMINAL = createWTItem( "Extended Wireless Terminal", ExtendedTerminal.makeId("wireless_et_terminal"), ETWTItem::new ); - private WTItems() { - } - private static ItemDefinition createWTItem(String name, ResourceLocation id, Function itemFactory) { - if (!ModIntegrationManager.isLoaded(AE2WTLib.class)) { - return null; - } - var definition = ETItems.createItem(name, id, itemFactory); WT_ITEMS.add(definition); return definition; diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index bb05f0a..b54615d 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -75,6 +75,13 @@ mandatory = true side="BOTH" versionRange = "[15.4.0,)" +[[dependencies."${mod_id}"]] +modId="ae2wtlib" +mandatory=false +versionRange="[15,)" +ordering="AFTER" +side="BOTH" + [[dependencies."${mod_id}"]] modId = "extendedcrafting" mandatory = false From 66e20c6ffa30f12086cb8a2663a0f954d8629cd6 Mon Sep 17 00:00:00 2001 From: myogoo Date: Thu, 16 Apr 2026 23:15:17 +0900 Subject: [PATCH 09/11] fix release publishing --- .github/workflows/publish.yml | 226 +++++++++++++++++----------------- .gitignore | 3 +- gradle.properties | 6 +- 3 files changed, 119 insertions(+), 116 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 7a268bf..741ab3a 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,123 +1,125 @@ - - -name: 'Publish to Modrinth & CurseForge' - -on: - pull_request: - types: [closed] - branches: - - '1.20.1' - paths: - - 'CHANGELOG.md' -jobs: - build: - if: github.event.pull_request.merged == true - runs-on: ubuntu-latest - outputs: - artifact_name: ${{ steps.vars.outputs.artifact_name }} - artifact_path: ${{ steps.vars.outputs.artifact_path }} - mc_version: ${{ steps.vars.outputs.mc_version }} - mod_version: ${{ steps.vars.outputs.mod_version }} - mod_loader: ${{ steps.vars.outputs.mod_loader }} - version_type: ${{ steps.vars.outputs.version_type }} - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Read Variables from gradle.properties - id: vars - run: | - java_version=$(grep '^java_version=' gradle.properties | cut -d'=' -f2 | tr -d ' \r') - echo "java_version=$java_version" >> $GITHUB_OUTPUT - mc_version=$(grep '^minecraft_version=' gradle.properties | cut -d'=' -f2 | tr -d ' \r') - echo "mc_version=$mc_version" >> $GITHUB_OUTPUT - mod_version=$(grep '^mod_version=' gradle.properties | cut -d'=' -f2 | tr -d ' \r') - echo "mod_version=$mod_version" >> $GITHUB_OUTPUT - mod_loader=$(grep '^mod_loader=' gradle.properties | cut -d'=' -f2 | tr -d ' \r') - echo "mod_loader=$mod_loader" >> $GITHUB_OUTPUT - version_type=$(grep '^mod_version_type=' gradle.properties | cut -d'=' -f2 | tr -d ' \r') - echo "version_type=$version_type" >> $GITHUB_OUTPUT - echo artifact_path=build/libs/ExtendedTerminal-$mc_version-$mod_version.jar >> $GITHUB_OUTPUT - echo artifact_name=ExtendedTerminal-$mc_version-$mod_version >> $GITHUB_OUTPUT - - name: Setup Java - uses: actions/setup-java@v4 - with: - distribution: 'microsoft' - java-version: ${{ steps.vars.outputs.java_version }} - - - name: Setup Gradle - uses: gradle/actions/setup-gradle@v4 - - - name: Make gradlew executable - run: chmod +x ./gradlew - - - name: Build with Gradle - run: ./gradlew build - - - name: Upload build artifacts - uses: actions/upload-artifact@v4 - with: - name: ${{ steps.vars.outputs.artifact_name }} - path: | - ${{ steps.vars.outputs.artifact_path }} - CHANGELOG.md - publish-to-curseforge: - if: github.event.pull_request.merged == true - runs-on: ubuntu-latest - needs: build - steps: - - name: Download build-artifact - uses: actions/download-artifact@v4 - with: - name: ${{ needs.build.outputs.artifact_name }} - - name: Publish to Modrinth & CurseForge - uses: Kir-Antipov/mc-publish@v3.3 - with: - curseforge-id: 1302078 - curseforge-token: ${{ secrets.CURSEFORGE_TOKEN }} - - changelog-file: 'CHANGELOG.md' - game-versions: ${{ needs.build.outputs.mc_version }} - loaders: ${{ needs.build.outputs.mod_loader }} - version-type: ${{ needs.build.outputs.version_type }} - - files: 'build/libs/*.jar' - name: ${{ needs.build.outputs.artifact_name }} - version: ${{ needs.build.outputs.mc_version }}-${{ needs.build.outputs.mod_version }} - + + +name: 'Publish to Modrinth & CurseForge' + +on: + pull_request: + types: [closed] + branches: + - '1.20.1' + paths: + - 'CHANGELOG.md' +jobs: + build: + if: github.event.pull_request.merged == true + runs-on: ubuntu-latest + outputs: + artifact_name: ${{ steps.vars.outputs.artifact_name }} + artifact_path: ${{ steps.vars.outputs.artifact_path }} + mc_version: ${{ steps.vars.outputs.mc_version }} + mod_version: ${{ steps.vars.outputs.mod_version }} + mod_loader: ${{ steps.vars.outputs.mod_loader }} + version_type: ${{ steps.vars.outputs.version_type }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Read Variables from gradle.properties + id: vars + run: | + java_version=$(grep '^java_version=' gradle.properties | cut -d'=' -f2 | tr -d ' \r') + echo "java_version=$java_version" >> $GITHUB_OUTPUT + mc_version=$(grep '^minecraft_version=' gradle.properties | cut -d'=' -f2 | tr -d ' \r') + echo "mc_version=$mc_version" >> $GITHUB_OUTPUT + mod_version=$(grep '^mod_version=' gradle.properties | cut -d'=' -f2 | tr -d ' \r') + echo "mod_version=$mod_version" >> $GITHUB_OUTPUT + mod_loader=$(grep '^mod_loader=' gradle.properties | cut -d'=' -f2 | tr -d ' \r') + echo "mod_loader=$mod_loader" >> $GITHUB_OUTPUT + version_type=$(grep '^mod_version_type=' gradle.properties | cut -d'=' -f2 | tr -d ' \r') + echo "version_type=$version_type" >> $GITHUB_OUTPUT + echo artifact_path=build/libs/ExtendedTerminal-$mc_version-$mod_version.jar >> $GITHUB_OUTPUT + echo artifact_name=ExtendedTerminal-$mc_version-$mod_version >> $GITHUB_OUTPUT + - name: Setup Java + uses: actions/setup-java@v4 + with: + distribution: 'microsoft' + java-version: ${{ steps.vars.outputs.java_version }} + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v4 + + - name: Make gradlew executable + run: chmod +x ./gradlew + + - name: Build with Gradle + run: ./gradlew build + + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: ${{ steps.vars.outputs.artifact_name }} + path: | + ${{ steps.vars.outputs.artifact_path }} + CHANGELOG.md + publish-to-curseforge: + if: github.event.pull_request.merged == true + runs-on: ubuntu-latest + needs: build + steps: + - name: Download build-artifact + uses: actions/download-artifact@v4 + with: + name: ${{ needs.build.outputs.artifact_name }} + - name: Publish to Modrinth & CurseForge + uses: Kir-Antipov/mc-publish@v3.3 + with: + curseforge-id: 1302078 + curseforge-token: ${{ secrets.CURSEFORGE_TOKEN }} + + changelog-file: 'CHANGELOG.md' + game-versions: ${{ needs.build.outputs.mc_version }} + loaders: ${{ needs.build.outputs.mod_loader }} + version-type: ${{ needs.build.outputs.version_type }} + + files: ${{ needs.build.outputs.artifact_path }} + name: ${{ needs.build.outputs.artifact_name }} + version: ${{ needs.build.outputs.mc_version }}-${{ needs.build.outputs.mod_version }} + dependencies: | ae2(required){modrinth:XxWD5pD3}{curseforge:223794} + myotus(required){modrinth:32YA23Pp}{curseforge:1496024} ae2wtlib(optional){modrinth:pNabrMMw}{curseforge:459929} extendedcrafting(optional){modrinth:5JMG1gql}{curseforge:1083158} avaritianeo(optional){modrinth:j5gjLUvf}{curseforge:268387} re-avaritia(optional){modrinth:QeB3NRC5}{curseforge:623969} - - publish-to-modrinth: - if: github.event.pull_request.merged == true - runs-on: ubuntu-latest - needs: build - steps: - - name: Download build-artifact - uses: actions/download-artifact@v4 - with: - name: ${{ needs.build.outputs.artifact_name }} - - name: Publish to Modrinth & CurseForge - uses: Kir-Antipov/mc-publish@v3.3 - with: - modrinth-id: SwdQUhgJ - modrinth-token: ${{ secrets.MODRINTH_TOKEN }} - - changelog-file: 'CHANGELOG.md' - game-versions: ${{ needs.build.outputs.mc_version }} - loaders: ${{ needs.build.outputs.mod_loader }} - version-type: ${{ needs.build.outputs.version_type }} - - files: 'build/libs/*.jar' - name: ${{ needs.build.outputs.artifact_name }} - version: ${{ needs.build.outputs.mc_version }}-${{ needs.build.outputs.mod_version }} - + + publish-to-modrinth: + if: github.event.pull_request.merged == true + runs-on: ubuntu-latest + needs: build + steps: + - name: Download build-artifact + uses: actions/download-artifact@v4 + with: + name: ${{ needs.build.outputs.artifact_name }} + - name: Publish to Modrinth & CurseForge + uses: Kir-Antipov/mc-publish@v3.3 + with: + modrinth-id: SwdQUhgJ + modrinth-token: ${{ secrets.MODRINTH_TOKEN }} + + changelog-file: 'CHANGELOG.md' + game-versions: ${{ needs.build.outputs.mc_version }} + loaders: ${{ needs.build.outputs.mod_loader }} + version-type: ${{ needs.build.outputs.version_type }} + + files: ${{ needs.build.outputs.artifact_path }} + name: ${{ needs.build.outputs.artifact_name }} + version: ${{ needs.build.outputs.mc_version }}-${{ needs.build.outputs.mod_version }} + dependencies: | ae2(required){modrinth:XxWD5pD3}{curseforge:223794} + myotus(required){modrinth:32YA23Pp}{curseforge:1496024} ae2wtlib(optional){modrinth:pNabrMMw}{curseforge:459929} extendedcrafting(optional){modrinth:5JMG1gql}{curseforge:1083158} avaritianeo(optional){modrinth:j5gjLUvf}{curseforge:268387} diff --git a/.gitignore b/.gitignore index 2049d2c..2d35248 100644 --- a/.gitignore +++ b/.gitignore @@ -86,6 +86,7 @@ ehthumbs_vista.db # Folder config file [Dd]esktop.ini +NUL # Recycle Bin used on file shares $RECYCLE.BIN/ @@ -121,4 +122,4 @@ run-data/ *.pdn .codex -.idea \ No newline at end of file +.idea diff --git a/gradle.properties b/gradle.properties index e9d6945..cb8056e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,7 +20,7 @@ mod_authors=NJoyShadow mod_description=Add some terminal like extended crafting Myotus_version=15.0.3 -myotus_version_range=[0.3-SNAPSHOT,) +myotus_version_range=[15.0.3,) AE2_version=15.4.10 AE2WTLib_version=15.3.3-forge @@ -39,6 +39,6 @@ guideME_version=20.1.11 itemListMod=emi -enable_avaritia=neo +enable_avaritia=re enable_excrafting=ex -enable_wtlib=true \ No newline at end of file +enable_wtlib=true From ff83104772401933edb73cb4c0351414e5e8961c Mon Sep 17 00:00:00 2001 From: njoyshadow Date: Thu, 16 Apr 2026 23:16:06 +0900 Subject: [PATCH 10/11] feat: rename recipe handler classes and update references for EMI integration --- TODO.md | 1 - build.gradle | 3 +- .../recipe/ShapedTableRecipeAdapter.java | 5 + .../recipe/ShapelessTableRecipeAdapter.java | 8 ++ .../adapter/recipe/ITableRecipeAdapter.java | 11 +++ .../extendedterminal/datagen/ETDataGen.java | 2 +- .../extendedterminal/init/wt/WTInits.java | 2 + .../extendedterminal/init/wt/WTItems.java | 5 + .../handler/AVNeoEmiRecipeHandler.java | 4 +- .../handler/AVTerminalRecipeHandler.java | 9 +- .../handler/ECTerminalRecipeHandler.java | 4 +- .../emi/extendedterminal/ETRecipeHandler.java | 12 +-- .../handler/AbstractETRecipeHandler.java | 97 ------------------- .../handler/ETCraftingRecipeHandler.java | 51 ---------- .../handler/ETSmithingRecipeHandler.java | 58 ----------- .../handler/ETStonecutterRecipeHandler.java | 55 ----------- .../handler/ETTerminalBaseRecipeHandler.java | 25 +++++ .../panel/ETCraftingRecipeHandler.java | 89 +++++++++++++++++ .../panel/ETSmithingRecipeHandler.java | 70 +++++++++++++ .../panel/ETStonecutterRecipeHandler.java | 70 +++++++++++++ .../wt/ETWTRecipeHandler.java | 12 +-- ...ava => AbstractEmiTableRecipeHandler.java} | 4 +- .../handler/ETCraftingRecipeTransfer.java | 2 +- .../ETCraftingRecipeTransferHelper.java | 4 +- .../ETStoneCutterRecipeTransferHelper.java | 1 - .../menu/extendedterminal/ETTerminalMenu.java | 8 +- .../menu/extendedterminal/wt/ETWTMenu.java | 11 ++- .../ETFillCraftingGridFromRecipePacket.java | 1 - .../assets/extendedterminal/lang/en_us.json | 1 + .../curios/tags/{item => items}/curio.json | 0 30 files changed, 324 insertions(+), 301 deletions(-) delete mode 100644 TODO.md delete mode 100644 src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/AbstractETRecipeHandler.java delete mode 100644 src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETCraftingRecipeHandler.java delete mode 100644 src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETSmithingRecipeHandler.java delete mode 100644 src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETStonecutterRecipeHandler.java create mode 100644 src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETTerminalBaseRecipeHandler.java create mode 100644 src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/panel/ETCraftingRecipeHandler.java create mode 100644 src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/panel/ETSmithingRecipeHandler.java create mode 100644 src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/panel/ETStonecutterRecipeHandler.java rename src/main/java/me/myogoo/extendedterminal/integration/emi/handler/{AbstractTableRecipeHandler.java => AbstractEmiTableRecipeHandler.java} (98%) rename src/main/resources/data/curios/tags/{item => items}/curio.json (100%) diff --git a/TODO.md b/TODO.md deleted file mode 100644 index 3b0ba46..0000000 --- a/TODO.md +++ /dev/null @@ -1 +0,0 @@ -1. et terminal에서 stonecutter 조합법 button 이미지 조정 필요 \ No newline at end of file diff --git a/build.gradle b/build.gradle index 580f23f..d56850e 100644 --- a/build.gradle +++ b/build.gradle @@ -150,6 +150,7 @@ dependencies { compileOnly fg.deobf("curse.maven:extended-crafting-expanded-1017786:5613251") compileOnly fg.deobf("maven.modrinth:applied-energistics-2-wireless-terminals:${AE2WTLib_version}") + runtimeOnly fg.deobf("top.theillusivec4.curios:curios-forge:${curios_version}") runtimeOnly fg.deobf("dev.architectury:architectury-forge:${architectury_version}") runtimeOnly fg.deobf("me.shedaniel.cloth:cloth-config-forge:${cloth_config_version}") runtimeOnly fg.deobf("top.theillusivec4.curios:curios-forge:${curios_version}") @@ -168,7 +169,7 @@ dependencies { compileOnly fg.deobf("me.shedaniel:RoughlyEnoughItems-forge:${REI_version}") compileOnly fg.deobf("dev.emi:emi-forge:${EMI_version}:api") - if(project.enable_wtlib == "true") { + if(project.enable_wtlib.toString().trim() == "true") { runtimeOnly fg.deobf("maven.modrinth:applied-energistics-2-wireless-terminals:${AE2WTLib_version}") } diff --git a/src/main/java/me/myogoo/extendedterminal/adapter/recipe/ShapedTableRecipeAdapter.java b/src/main/java/me/myogoo/extendedterminal/adapter/recipe/ShapedTableRecipeAdapter.java index e77c829..b7877a4 100644 --- a/src/main/java/me/myogoo/extendedterminal/adapter/recipe/ShapedTableRecipeAdapter.java +++ b/src/main/java/me/myogoo/extendedterminal/adapter/recipe/ShapedTableRecipeAdapter.java @@ -6,6 +6,7 @@ import net.byAqua3.avaritia.recipe.RecipeExtremeShaped; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.crafting.Recipe; +import net.minecraft.world.item.crafting.ShapedRecipe; import java.util.Optional; @@ -23,6 +24,10 @@ public ShapedTableRecipeAdapter(Recipe recipe, int tier, int width, int heigh this.recipeHeight = height; } + public ShapedTableRecipeAdapter(ShapedRecipe recipe) { + this(recipe, 1, recipe.getWidth(), recipe.getHeight()); + } + public ShapedTableRecipeAdapter(ShapedTableRecipe recipe) { this(recipe, recipe.getTier(), recipe.getWidth(), recipe.getHeight()); } diff --git a/src/main/java/me/myogoo/extendedterminal/adapter/recipe/ShapelessTableRecipeAdapter.java b/src/main/java/me/myogoo/extendedterminal/adapter/recipe/ShapelessTableRecipeAdapter.java index 2fc7f5c..a6a1763 100644 --- a/src/main/java/me/myogoo/extendedterminal/adapter/recipe/ShapelessTableRecipeAdapter.java +++ b/src/main/java/me/myogoo/extendedterminal/adapter/recipe/ShapelessTableRecipeAdapter.java @@ -7,7 +7,9 @@ import me.myogoo.extendedterminal.api.adapter.recipe.IShapelessTableRecipeAdapter; import net.byAqua3.avaritia.recipe.RecipeExtremeShapeless; import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.crafting.CraftingRecipe; import net.minecraft.world.item.crafting.Recipe; +import net.minecraft.world.item.crafting.ShapelessRecipe; import java.util.Optional; @@ -19,6 +21,12 @@ public ShapelessTableRecipeAdapter(Recipe recipe, int tier) { this.recipe = recipe; this.recipeTier = tier; } + public ShapelessTableRecipeAdapter(ShapelessRecipe recipe) { + this(recipe, 1); + } + public ShapelessTableRecipeAdapter(CraftingRecipe recipe) { + this(recipe, 1); + } //Extended Crafting public ShapelessTableRecipeAdapter(ShapelessTableRecipe recipe) { this(recipe, recipe.getTier()); } diff --git a/src/main/java/me/myogoo/extendedterminal/api/adapter/recipe/ITableRecipeAdapter.java b/src/main/java/me/myogoo/extendedterminal/api/adapter/recipe/ITableRecipeAdapter.java index 118b58d..f4ce32f 100644 --- a/src/main/java/me/myogoo/extendedterminal/api/adapter/recipe/ITableRecipeAdapter.java +++ b/src/main/java/me/myogoo/extendedterminal/api/adapter/recipe/ITableRecipeAdapter.java @@ -12,6 +12,7 @@ import net.byAqua3.avaritia.recipe.RecipeExtremeShaped; import net.byAqua3.avaritia.recipe.RecipeExtremeShapeless; import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.crafting.CraftingRecipe; import net.minecraft.world.item.crafting.Recipe; import net.minecraft.world.item.crafting.ShapedRecipe; import net.minecraft.world.item.crafting.ShapelessRecipe; @@ -24,6 +25,16 @@ public interface ITableRecipeAdapter { ResourceLocation recipeId(); int tier(); + static ITableRecipeAdapter of(CraftingRecipe recipe) { + if (recipe instanceof ShapedRecipe shaped) { + return new ShapedTableRecipeAdapter(shaped); + } else if (recipe instanceof ShapelessRecipe shapeless) { + return new ShapelessTableRecipeAdapter(shapeless); + } else { + return new ShapelessTableRecipeAdapter(recipe); + } + } + @ExtendedCrafting static ITableRecipeAdapter of(ITableRecipe recipe) { if (recipe instanceof ShapedTableRecipe shaped) { diff --git a/src/main/java/me/myogoo/extendedterminal/datagen/ETDataGen.java b/src/main/java/me/myogoo/extendedterminal/datagen/ETDataGen.java index 24d0081..d589138 100644 --- a/src/main/java/me/myogoo/extendedterminal/datagen/ETDataGen.java +++ b/src/main/java/me/myogoo/extendedterminal/datagen/ETDataGen.java @@ -21,6 +21,6 @@ public static void onGatherData(GatherDataEvent event) { var generator = event.getGenerator(); var pack = generator.getVanillaPack(true); - pack.addProvider(InscriberRecipeProvider::new); + //pack.addProvider(InscriberRecipeProvider::new); } } diff --git a/src/main/java/me/myogoo/extendedterminal/init/wt/WTInits.java b/src/main/java/me/myogoo/extendedterminal/init/wt/WTInits.java index 0eecc0e..60daa3a 100644 --- a/src/main/java/me/myogoo/extendedterminal/init/wt/WTInits.java +++ b/src/main/java/me/myogoo/extendedterminal/init/wt/WTInits.java @@ -1,5 +1,7 @@ package me.myogoo.extendedterminal.init.wt; +import appeng.api.features.GridLinkables; +import appeng.items.tools.powered.WirelessTerminalItem; import de.mari_023.ae2wtlib.wut.WUTHandler; import me.myogoo.extendedterminal.me.host.ETWTHost; import me.myogoo.extendedterminal.menu.extendedterminal.wt.ETWTMenu; diff --git a/src/main/java/me/myogoo/extendedterminal/init/wt/WTItems.java b/src/main/java/me/myogoo/extendedterminal/init/wt/WTItems.java index b5226ab..7d40482 100644 --- a/src/main/java/me/myogoo/extendedterminal/init/wt/WTItems.java +++ b/src/main/java/me/myogoo/extendedterminal/init/wt/WTItems.java @@ -1,6 +1,8 @@ package me.myogoo.extendedterminal.init.wt; +import appeng.api.features.GridLinkables; import appeng.core.definitions.ItemDefinition; +import appeng.items.tools.powered.WirelessTerminalItem; import de.mari_023.ae2wtlib.terminal.ItemWT; import me.myogoo.extendedterminal.ExtendedTerminal; import me.myogoo.extendedterminal.init.ETItems; @@ -26,8 +28,11 @@ public final class WTItems { private static ItemDefinition createWTItem(String name, ResourceLocation id, Function itemFactory) { var definition = ETItems.createItem(name, id, itemFactory); + GridLinkables.register(definition.asItem(), WirelessTerminalItem.LINKABLE_HANDLER); WT_ITEMS.add(definition); return definition; + + } public static void register() { diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/avaritiaNeo/handler/AVNeoEmiRecipeHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/avaritiaNeo/handler/AVNeoEmiRecipeHandler.java index e166dac..11d23a9 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/emi/avaritiaNeo/handler/AVNeoEmiRecipeHandler.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/avaritiaNeo/handler/AVNeoEmiRecipeHandler.java @@ -5,7 +5,7 @@ import dev.emi.emi.api.recipe.EmiRecipeCategory; import me.myogoo.extendedterminal.api.adapter.recipe.IShapedTableRecipeAdapter; import me.myogoo.extendedterminal.api.adapter.recipe.ITableRecipeAdapter; -import me.myogoo.extendedterminal.integration.emi.handler.AbstractTableRecipeHandler; +import me.myogoo.extendedterminal.integration.emi.handler.AbstractEmiTableRecipeHandler; import me.myogoo.extendedterminal.menu.ETMenuType; import me.myogoo.extendedterminal.menu.avaritiaNeo.NeoExtremeTerminalMenu; import net.byAqua3.avaritia.recipe.RecipeExtremeCrafting; @@ -19,7 +19,7 @@ import static me.myogoo.extendedterminal.integration.ItemListTermCraftingHelper.ensureFittedCraftingGrid; -public class AVNeoEmiRecipeHandler extends AbstractTableRecipeHandler { +public class AVNeoEmiRecipeHandler extends AbstractEmiTableRecipeHandler { private final ETMenuType menuType; private final EmiRecipeCategory category; diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/avaritiaRe/handler/AVTerminalRecipeHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/avaritiaRe/handler/AVTerminalRecipeHandler.java index 178afe9..ef013fa 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/emi/avaritiaRe/handler/AVTerminalRecipeHandler.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/avaritiaRe/handler/AVTerminalRecipeHandler.java @@ -2,33 +2,28 @@ import appeng.core.localization.ItemModText; import committee.nova.mods.avaritia.common.crafting.recipe.ITierCraftingRecipe; -import committee.nova.mods.avaritia.common.crafting.recipe.ShapedTableCraftingRecipe; import committee.nova.mods.avaritia.init.compat.emi.category.tables.EndCraftingTableCategory; import committee.nova.mods.avaritia.init.compat.emi.category.tables.ExtremeCraftingTableCategory; import committee.nova.mods.avaritia.init.compat.emi.category.tables.NetherCraftingTableCategory; import committee.nova.mods.avaritia.init.compat.emi.category.tables.SculkCraftingTableCategory; import dev.emi.emi.api.recipe.EmiRecipe; import dev.emi.emi.api.recipe.EmiRecipeCategory; -import dev.emi.emi.api.stack.EmiStack; import me.myogoo.extendedterminal.api.adapter.recipe.IShapedTableRecipeAdapter; import me.myogoo.extendedterminal.api.adapter.recipe.ITableRecipeAdapter; -import me.myogoo.extendedterminal.integration.emi.handler.AbstractTableRecipeHandler; +import me.myogoo.extendedterminal.integration.emi.handler.AbstractEmiTableRecipeHandler; import me.myogoo.extendedterminal.menu.ETMenuType; import me.myogoo.extendedterminal.menu.avaritiaRe.AvaritiaTerminalBaseMenu; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; -import net.minecraft.core.NonNullList; -import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.item.crafting.Recipe; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Optional; import static me.myogoo.extendedterminal.integration.ItemListTermCraftingHelper.ensureFittedCraftingGrid; -public class AVTerminalRecipeHandler extends AbstractTableRecipeHandler { +public class AVTerminalRecipeHandler extends AbstractEmiTableRecipeHandler { private final ETMenuType menuType; private final EmiRecipeCategory category; public AVTerminalRecipeHandler(EmiRecipeCategory category, Class containerClass, ETMenuType menuType) { diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedcrafting/handler/ECTerminalRecipeHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedcrafting/handler/ECTerminalRecipeHandler.java index e43878f..670048f 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedcrafting/handler/ECTerminalRecipeHandler.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedcrafting/handler/ECTerminalRecipeHandler.java @@ -7,7 +7,7 @@ import me.myogoo.extendedterminal.api.adapter.recipe.IShapedTableRecipeAdapter; import me.myogoo.extendedterminal.api.adapter.recipe.ITableRecipeAdapter; import me.myogoo.extendedterminal.integration.emi.extendedcrafting.ECRecipeCategory; -import me.myogoo.extendedterminal.integration.emi.handler.AbstractTableRecipeHandler; +import me.myogoo.extendedterminal.integration.emi.handler.AbstractEmiTableRecipeHandler; import me.myogoo.extendedterminal.menu.ETMenuType; import me.myogoo.extendedterminal.menu.extendedcrafting.ExtendedTerminalBaseMenu; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; @@ -20,7 +20,7 @@ import static me.myogoo.extendedterminal.integration.ItemListTermCraftingHelper.ensureFittedCraftingGrid; -public class ECTerminalRecipeHandler extends AbstractTableRecipeHandler { +public class ECTerminalRecipeHandler extends AbstractEmiTableRecipeHandler { private final ETMenuType menuType; private final EmiRecipeCategory category; diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/ETRecipeHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/ETRecipeHandler.java index 6d88276..b24590e 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/ETRecipeHandler.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/ETRecipeHandler.java @@ -3,9 +3,9 @@ import dev.emi.emi.api.EmiRegistry; import me.myogoo.extendedterminal.api.integration.emi.ETEmiRecipeHandler; import me.myogoo.extendedterminal.config.ExtendedTerminalConfig; -import me.myogoo.extendedterminal.integration.emi.extendedterminal.handler.ETCraftingRecipeHandler; -import me.myogoo.extendedterminal.integration.emi.extendedterminal.handler.ETSmithingRecipeHandler; -import me.myogoo.extendedterminal.integration.emi.extendedterminal.handler.ETStonecutterRecipeHandler; +import me.myogoo.extendedterminal.integration.emi.extendedterminal.handler.panel.ETCraftingRecipeHandler; +import me.myogoo.extendedterminal.integration.emi.extendedterminal.handler.panel.ETSmithingRecipeHandler; +import me.myogoo.extendedterminal.integration.emi.extendedterminal.handler.panel.ETStonecutterRecipeHandler; import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; import me.myogoo.myotus.api.annotation.MyotusSubscriber; @@ -19,13 +19,13 @@ public static void init(EmiRegistry registry) { } if (config.enableCraftingPanel()) { - registry.addRecipeHandler(ETTerminalMenu.TYPE, new ETCraftingRecipeHandler()); + registry.addRecipeHandler(ETTerminalMenu.TYPE, new ETCraftingRecipeHandler<>(ETTerminalMenu.class)); } if (config.enableSmithingPanel()) { - registry.addRecipeHandler(ETTerminalMenu.TYPE, new ETSmithingRecipeHandler()); + registry.addRecipeHandler(ETTerminalMenu.TYPE, new ETSmithingRecipeHandler<>(ETTerminalMenu.class)); } if (config.enableStonecutterPanel()) { - registry.addRecipeHandler(ETTerminalMenu.TYPE, new ETStonecutterRecipeHandler()); + registry.addRecipeHandler(ETTerminalMenu.TYPE, new ETStonecutterRecipeHandler<>(ETTerminalMenu.class)); } } } diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/AbstractETRecipeHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/AbstractETRecipeHandler.java deleted file mode 100644 index be92bcb..0000000 --- a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/AbstractETRecipeHandler.java +++ /dev/null @@ -1,97 +0,0 @@ -package me.myogoo.extendedterminal.integration.emi.extendedterminal.handler; - -import appeng.core.localization.ItemModText; -import appeng.menu.SlotSemantics; -import dev.emi.emi.api.recipe.EmiRecipe; -import me.myogoo.extendedterminal.integration.emi.handler.AbstractTableRecipeHandler; -import me.myogoo.extendedterminal.api.adapter.recipe.ITableRecipeAdapter; -import me.myogoo.extendedterminal.menu.ETSlotSemantics; -import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; -import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; -import net.minecraft.world.inventory.Slot; -import net.minecraft.world.item.crafting.Ingredient; -import net.minecraft.world.item.crafting.Recipe; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -public abstract class AbstractETRecipeHandler extends AbstractTableRecipeHandler { - @SuppressWarnings("unchecked") - protected AbstractETRecipeHandler() { - super((Class) ETTerminalMenu.class); - } - - @Override - public List getInputSources(T menu) { - var slots = new ArrayList(); - slots.addAll(menu.getSlots(SlotSemantics.PLAYER_HOTBAR)); - slots.addAll(menu.getSlots(SlotSemantics.PLAYER_INVENTORY)); - slots.addAll(menu.getSlots(menu.getCraftingGridSlotSemantic())); - slots.addAll(menu.getSlots(ETSlotSemantics.SMITHING_TABLE_TEMPLATE)); - slots.addAll(menu.getSlots(ETSlotSemantics.SMITHING_TABLE_BASE)); - slots.addAll(menu.getSlots(ETSlotSemantics.SMITHING_TABLE_ADDITION)); - slots.addAll(menu.getSlots(ETSlotSemantics.STONECUTTING_INPUT)); - return slots; - } - - @Override - protected Result transferRecipe(T menu, EmiRecipe emiRecipe, boolean doTransfer) { - var recipe = resolveRecipe(menu, emiRecipe); - if (!supportsRecipe(recipe, emiRecipe)) { - return Result.createNotApplicable(); - } - - var slotToIngredientMap = getGuiSlotToIngredientMap(menu, recipe); - var missingSlots = menu.findMissingIngredients(slotToIngredientMap); - if (!slotToIngredientMap.isEmpty() && missingSlots.missingSlots().size() == slotToIngredientMap.size()) { - return Result.createFailed(ItemModText.NO_ITEMS.text(), missingSlots.missingSlots()); - } - - if (!doTransfer) { - if (missingSlots.anyMissingOrCraftable()) { - return new Result.PartiallyCraftable(missingSlots); - } - } else { - prepareTransfer(menu, recipe); - performTransfer(menu, recipe, AbstractContainerScreen.hasControlDown()); - } - - return Result.createSuccessful(); - } - - protected abstract boolean supportsRecipe(Recipe recipe, EmiRecipe emiRecipe); - - protected abstract Map getGuiSlotToIngredientMap(T menu, Recipe recipe); - - @Nullable - private Recipe resolveRecipe(T menu, EmiRecipe emiRecipe) { - var backingRecipe = emiRecipe.getBackingRecipe(); - if (backingRecipe != null) { - return backingRecipe; - } - - var recipeId = emiRecipe.getId(); - if (recipeId == null) { - return null; - } - - return menu.getPlayer().level().getRecipeManager().byKey(recipeId).orElse(null); - } - - @Override - protected boolean isCraftingRecipe(Recipe recipe, EmiRecipe emiRecipe) { - return supportsRecipe(recipe, emiRecipe); - } - - @Override - protected Map getGuiSlotToIngredientMap(T menu, ITableRecipeAdapter recipe) { - throw new UnsupportedOperationException("ET panel handlers use recipe-specific slot mapping"); - } - - protected void prepareTransfer(T menu, Recipe recipe) { - } - - protected abstract void performTransfer(T menu, Recipe recipe, boolean craftMissing); -} diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETCraftingRecipeHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETCraftingRecipeHandler.java deleted file mode 100644 index 77e37a3..0000000 --- a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETCraftingRecipeHandler.java +++ /dev/null @@ -1,51 +0,0 @@ -package me.myogoo.extendedterminal.integration.emi.extendedterminal.handler; - -import dev.emi.emi.api.recipe.EmiRecipe; -import dev.emi.emi.api.recipe.VanillaEmiRecipeCategories; -import me.myogoo.extendedterminal.integration.module.extendedterminal.ETCraftingRecipeTransferHelper; -import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; -import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMode; -import net.minecraft.world.inventory.Slot; -import net.minecraft.world.item.crafting.CraftingRecipe; -import net.minecraft.world.item.crafting.Ingredient; -import net.minecraft.world.item.crafting.Recipe; - -import java.util.List; -import java.util.Map; - -public class ETCraftingRecipeHandler extends AbstractETRecipeHandler { - @Override - public boolean supportsRecipe(EmiRecipe recipe) { - return recipe.getCategory().equals(VanillaEmiRecipeCategories.CRAFTING); - } - - @Override - public List getCraftingSlots(T menu) { - return menu.getSlots(menu.getCraftingGridSlotSemantic()); - } - - @Override - public Slot getOutputSlot(T menu) { - return menu.getSlots(menu.getOutputSlotSemantic()).get(0); - } - - @Override - protected boolean supportsRecipe(Recipe recipe, EmiRecipe emiRecipe) { - return recipe instanceof CraftingRecipe && emiRecipe.getCategory().equals(VanillaEmiRecipeCategories.CRAFTING); - } - - @Override - protected Map getGuiSlotToIngredientMap(T menu, Recipe recipe) { - return ETCraftingRecipeTransferHelper.getGuiSlotToIngredientMap(menu, (CraftingRecipe) recipe); - } - - @Override - protected void prepareTransfer(T menu, Recipe recipe) { - menu.setMode(ETTerminalMode.CRAFTING); - } - - @Override - protected void performTransfer(T menu, Recipe recipe, boolean craftMissing) { - ETCraftingRecipeTransferHelper.performTransfer(menu, (CraftingRecipe) recipe, null, craftMissing); - } -} diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETSmithingRecipeHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETSmithingRecipeHandler.java deleted file mode 100644 index b866b27..0000000 --- a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETSmithingRecipeHandler.java +++ /dev/null @@ -1,58 +0,0 @@ -package me.myogoo.extendedterminal.integration.emi.extendedterminal.handler; - -import appeng.menu.SlotSemantics; -import dev.emi.emi.api.recipe.EmiRecipe; -import dev.emi.emi.api.recipe.VanillaEmiRecipeCategories; -import me.myogoo.extendedterminal.integration.module.extendedterminal.ETSmithingRecipeTransferHelper; -import me.myogoo.extendedterminal.menu.ETSlotSemantics; -import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; -import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMode; -import net.minecraft.world.inventory.Slot; -import net.minecraft.world.item.crafting.Ingredient; -import net.minecraft.world.item.crafting.Recipe; -import net.minecraft.world.item.crafting.SmithingRecipe; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -public class ETSmithingRecipeHandler extends AbstractETRecipeHandler { - @Override - public boolean supportsRecipe(EmiRecipe recipe) { - return recipe.getCategory().equals(VanillaEmiRecipeCategories.SMITHING); - } - - @Override - public List getCraftingSlots(T menu) { - var slots = new ArrayList(); - slots.addAll(menu.getSlots(ETSlotSemantics.SMITHING_TABLE_TEMPLATE)); - slots.addAll(menu.getSlots(ETSlotSemantics.SMITHING_TABLE_BASE)); - slots.addAll(menu.getSlots(ETSlotSemantics.SMITHING_TABLE_ADDITION)); - return slots; - } - - @Override - public Slot getOutputSlot(T menu) { - return menu.getSlots(SlotSemantics.SMITHING_TABLE_RESULT).get(0); - } - - @Override - protected boolean supportsRecipe(Recipe recipe, EmiRecipe emiRecipe) { - return recipe instanceof SmithingRecipe && emiRecipe.getCategory().equals(VanillaEmiRecipeCategories.SMITHING); - } - - @Override - protected Map getGuiSlotToIngredientMap(T menu, Recipe recipe) { - return ETSmithingRecipeTransferHelper.getGuiSlotToIngredientMap((SmithingRecipe) recipe); - } - - @Override - protected void prepareTransfer(T menu, Recipe recipe) { - menu.setMode(ETTerminalMode.SMITHING); - } - - @Override - protected void performTransfer(T menu, Recipe recipe, boolean craftMissing) { - ETSmithingRecipeTransferHelper.performTransfer(menu, (SmithingRecipe) recipe, craftMissing); - } -} diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETStonecutterRecipeHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETStonecutterRecipeHandler.java deleted file mode 100644 index 0d4bfcf..0000000 --- a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETStonecutterRecipeHandler.java +++ /dev/null @@ -1,55 +0,0 @@ -package me.myogoo.extendedterminal.integration.emi.extendedterminal.handler; - -import dev.emi.emi.api.recipe.EmiRecipe; -import dev.emi.emi.api.recipe.VanillaEmiRecipeCategories; -import me.myogoo.extendedterminal.integration.module.extendedterminal.ETStoneCutterRecipeTransferHelper; -import me.myogoo.extendedterminal.menu.ETSlotSemantics; -import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; -import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMode; -import net.minecraft.world.inventory.Slot; -import net.minecraft.world.item.crafting.Ingredient; -import net.minecraft.world.item.crafting.Recipe; -import net.minecraft.world.item.crafting.StonecutterRecipe; - -import java.util.List; -import java.util.Map; - -public class ETStonecutterRecipeHandler extends AbstractETRecipeHandler { - @Override - public boolean supportsRecipe(EmiRecipe recipe) { - return recipe.getCategory().equals(VanillaEmiRecipeCategories.STONECUTTING); - } - - @Override - public List getCraftingSlots(T menu) { - return menu.getSlots(ETSlotSemantics.STONECUTTING_INPUT); - } - - @Override - public Slot getOutputSlot(T menu) { - return menu.getSlots(ETSlotSemantics.STONECUTTING_RESULT).get(0); - } - - @Override - protected boolean supportsRecipe(Recipe recipe, EmiRecipe emiRecipe) { - return recipe instanceof StonecutterRecipe - && emiRecipe.getCategory().equals(VanillaEmiRecipeCategories.STONECUTTING); - } - - @Override - protected Map getGuiSlotToIngredientMap(T menu, Recipe recipe) { - return ETStoneCutterRecipeTransferHelper.getGuiSlotToIngredientMap((StonecutterRecipe) recipe); - } - - @Override - protected void prepareTransfer(T menu, Recipe recipe) { - var stonecutterRecipe = (StonecutterRecipe) recipe; - menu.setMode(ETTerminalMode.STONECUTTING); - menu.setStoneCutterRecipeId(stonecutterRecipe.getId()); - } - - @Override - protected void performTransfer(T menu, Recipe recipe, boolean craftMissing) { - ETStoneCutterRecipeTransferHelper.performTransfer(menu, (StonecutterRecipe) recipe, craftMissing); - } -} diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETTerminalBaseRecipeHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETTerminalBaseRecipeHandler.java new file mode 100644 index 0000000..c5c5950 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/ETTerminalBaseRecipeHandler.java @@ -0,0 +1,25 @@ +package me.myogoo.extendedterminal.integration.emi.extendedterminal.handler; + +import me.myogoo.extendedterminal.integration.emi.handler.AbstractEmiTableRecipeHandler; +import me.myogoo.extendedterminal.menu.ETSlotSemantics; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; +import net.minecraft.world.inventory.Slot; + +import java.util.List; + +public abstract class ETTerminalBaseRecipeHandler extends AbstractEmiTableRecipeHandler { + public ETTerminalBaseRecipeHandler(Class containerClass) { + super(containerClass); + } + + @Override + public List getInputSources(T menu) { + var slots = super.getInputSources(menu); + slots.addAll(menu.getSlots(ETSlotSemantics.STONECUTTING_INPUT)); + slots.addAll(menu.getSlots(ETSlotSemantics.SMITHING_TABLE_BASE)); + slots.addAll(menu.getSlots(ETSlotSemantics.SMITHING_TABLE_TEMPLATE)); + slots.addAll(menu.getSlots(ETSlotSemantics.SMITHING_TABLE_ADDITION)); + return slots; + } + +} \ No newline at end of file diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/panel/ETCraftingRecipeHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/panel/ETCraftingRecipeHandler.java new file mode 100644 index 0000000..ffbb613 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/panel/ETCraftingRecipeHandler.java @@ -0,0 +1,89 @@ +package me.myogoo.extendedterminal.integration.emi.extendedterminal.handler.panel; + +import appeng.core.localization.ItemModText; +import dev.emi.emi.api.recipe.EmiRecipe; +import dev.emi.emi.api.recipe.VanillaEmiRecipeCategories; +import dev.emi.emi.api.stack.EmiStack; +import me.myogoo.extendedterminal.api.adapter.recipe.ITableRecipeAdapter; +import me.myogoo.extendedterminal.integration.emi.extendedterminal.handler.ETTerminalBaseRecipeHandler; +import me.myogoo.extendedterminal.integration.module.extendedterminal.ETCraftingRecipeTransferHelper; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.core.NonNullList; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.*; + +import java.util.Map; + +public class ETCraftingRecipeHandler extends ETTerminalBaseRecipeHandler { + public ETCraftingRecipeHandler(Class containerClass) { + super(containerClass); + } + + @Override + protected Result transferRecipe(T menu, EmiRecipe emiRecipe, boolean doTransfer) { + var recipeId = emiRecipe.getId(); + var recipe = emiRecipe.getBackingRecipe(); + boolean craftingRecipe = isCraftingRecipe(recipe, emiRecipe); + if (!craftingRecipe) { + return Result.createNotApplicable(); + } + if (recipe != null && !recipe.canCraftInDimensions(3, 3)) { + return Result.createFailed(ItemModText.RECIPE_TOO_LARGE.text()); + } + if (recipe == null) { + recipe = createFakeRecipe(emiRecipe); + } + if (!(recipe instanceof CraftingRecipe cRecipe)) { + return Result.createFailed(ItemModText.INCOMPATIBLE_RECIPE.text()); + } + + var slotToIngredientMap = getGuiSlotToIngredientMap(menu, ITableRecipeAdapter.of(cRecipe)); + var missingSlots = menu.findMissingIngredients(slotToIngredientMap); + + if (missingSlots.missingSlots().size() == slotToIngredientMap.size()) { + return Result.createFailed(ItemModText.NO_ITEMS.text(), missingSlots.missingSlots()); + } + + if (!doTransfer) { + if (missingSlots.anyMissingOrCraftable()) { + return new Result.PartiallyCraftable(missingSlots); + } + } else { + boolean craftingMissing = AbstractContainerScreen.hasControlDown(); + ETCraftingRecipeTransferHelper.performTransfer(menu, cRecipe, craftingMissing); + } + return Result.createSuccessful(); + } + + @Override + protected boolean isCraftingRecipe(Recipe recipe, EmiRecipe emiRecipe) { + return emiRecipe.getCategory().equals(VanillaEmiRecipeCategories.CRAFTING); + } + + @Override + public boolean supportsRecipe(EmiRecipe recipe) { + return recipe.getCategory().equals(VanillaEmiRecipeCategories.CRAFTING); + } + + @Override + protected Map getGuiSlotToIngredientMap(T menu, ITableRecipeAdapter recipe) { + return ETCraftingRecipeTransferHelper.getGuiSlotToIngredientMap(menu, recipe.recipe()); + } + + private Recipe createFakeRecipe(EmiRecipe recipe) { + var ingredients = NonNullList.withSize(3 * 3, + Ingredient.EMPTY); + + for (int i = 0; i < Math.min(recipe.getInputs().size(), ingredients.size()); i++) { + var ingredient = Ingredient.of(recipe.getInputs().get(i).getEmiStacks().stream() + .map(EmiStack::getItemStack) + .filter(is -> !is.isEmpty())); + ingredients.set(i, ingredient); + } + + return new ShapedRecipe(new ResourceLocation(""), "", CraftingBookCategory.MISC, 3, + 3, ingredients, ItemStack.EMPTY); + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/panel/ETSmithingRecipeHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/panel/ETSmithingRecipeHandler.java new file mode 100644 index 0000000..099b9b5 --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/panel/ETSmithingRecipeHandler.java @@ -0,0 +1,70 @@ +package me.myogoo.extendedterminal.integration.emi.extendedterminal.handler.panel; + +import appeng.core.localization.ItemModText; +import dev.emi.emi.api.recipe.EmiRecipe; +import dev.emi.emi.api.recipe.VanillaEmiRecipeCategories; +import me.myogoo.extendedterminal.api.adapter.recipe.ITableRecipeAdapter; +import me.myogoo.extendedterminal.integration.emi.extendedterminal.handler.ETTerminalBaseRecipeHandler; +import me.myogoo.extendedterminal.integration.module.extendedterminal.ETSmithingRecipeTransferHelper; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.Recipe; +import net.minecraft.world.item.crafting.SmithingRecipe; + +import java.util.Map; + +public class ETSmithingRecipeHandler extends ETTerminalBaseRecipeHandler { + public ETSmithingRecipeHandler(Class containerClass) { + super(containerClass); + } + + @Override + protected Result transferRecipe(T menu, EmiRecipe emiRecipe, boolean doTransfer) { + var recipeId = emiRecipe.getId(); + var recipe = emiRecipe.getBackingRecipe(); + boolean craftingRecipe = isCraftingRecipe(recipe, emiRecipe); + if(!craftingRecipe || recipe == null) { + return Result.createNotApplicable(); + } + if(!recipe.canCraftInDimensions(3,1)) { + return Result.createFailed(ItemModText.RECIPE_TOO_LARGE.text()); + } + if(!(recipe instanceof SmithingRecipe smithingRecipe)) { + return Result.createFailed(ItemModText.INCOMPATIBLE_RECIPE.text()); + } + + var slotToIngredientMap = ETSmithingRecipeTransferHelper.getGuiSlotToIngredientMap(smithingRecipe); + var missingSlots = menu.findMissingIngredients(slotToIngredientMap); + + if (missingSlots.missingSlots().size() == slotToIngredientMap.size()) { + return Result.createFailed(ItemModText.NO_ITEMS.text(), missingSlots.missingSlots()); + } + + if (!doTransfer) { + if (missingSlots.anyMissingOrCraftable()) { + return new Result.PartiallyCraftable(missingSlots); + } + } else { + boolean craftingMissing = AbstractContainerScreen.hasControlDown(); + ETSmithingRecipeTransferHelper.performTransfer(menu, smithingRecipe, craftingMissing); + } + + return Result.createSuccessful(); + } + + @Override + public boolean supportsRecipe(EmiRecipe recipe) { + return recipe.getCategory().equals(VanillaEmiRecipeCategories.SMITHING); + } + + @Override + protected boolean isCraftingRecipe(Recipe recipe, EmiRecipe emiRecipe) { + return emiRecipe.getCategory().equals(VanillaEmiRecipeCategories.SMITHING); + } + + @Override + protected Map getGuiSlotToIngredientMap(T menu, ITableRecipeAdapter recipe) { + return Map.of(); + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/panel/ETStonecutterRecipeHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/panel/ETStonecutterRecipeHandler.java new file mode 100644 index 0000000..e798dcd --- /dev/null +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/handler/panel/ETStonecutterRecipeHandler.java @@ -0,0 +1,70 @@ +package me.myogoo.extendedterminal.integration.emi.extendedterminal.handler.panel; + +import appeng.core.localization.ItemModText; +import dev.emi.emi.api.recipe.EmiRecipe; +import dev.emi.emi.api.recipe.VanillaEmiRecipeCategories; +import me.myogoo.extendedterminal.api.adapter.recipe.ITableRecipeAdapter; +import me.myogoo.extendedterminal.integration.emi.extendedterminal.handler.ETTerminalBaseRecipeHandler; +import me.myogoo.extendedterminal.integration.module.extendedterminal.ETStoneCutterRecipeTransferHelper; +import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.Recipe; +import net.minecraft.world.item.crafting.StonecutterRecipe; + +import java.util.Map; + +public class ETStonecutterRecipeHandler extends ETTerminalBaseRecipeHandler { + public ETStonecutterRecipeHandler(Class containerClass) { + super(containerClass); + } + + @Override + protected Result transferRecipe(T menu, EmiRecipe emiRecipe, boolean doTransfer) { + var recipeId = emiRecipe.getId(); + var recipe = emiRecipe.getBackingRecipe(); + boolean craftingRecipe = isCraftingRecipe(recipe, emiRecipe); + if (!craftingRecipe || recipe == null) { + return Result.createNotApplicable(); + } + if (!recipe.canCraftInDimensions(1, 1)) { + return Result.createFailed(ItemModText.RECIPE_TOO_LARGE.text()); + } + if (!(recipe instanceof StonecutterRecipe singleItemRecipe)) { + return Result.createFailed(ItemModText.INCOMPATIBLE_RECIPE.text()); + } + + var slotToIngredientMap = ETStoneCutterRecipeTransferHelper.getGuiSlotToIngredientMap(singleItemRecipe); + var missingSlots = menu.findMissingIngredients(slotToIngredientMap); + + if (missingSlots.missingSlots().size() == slotToIngredientMap.size()) { + return Result.createFailed(ItemModText.NO_ITEMS.text(), missingSlots.missingSlots()); + } + + if (!doTransfer) { + if (missingSlots.anyMissingOrCraftable()) { + return new Result.PartiallyCraftable(missingSlots); + } + } else { + boolean craftingMissing = AbstractContainerScreen.hasControlDown(); + ETStoneCutterRecipeTransferHelper.performTransfer(menu, singleItemRecipe, craftingMissing); + } + + return Result.createSuccessful(); + } + + @Override + protected boolean isCraftingRecipe(Recipe recipe, EmiRecipe emiRecipe) { + return emiRecipe.getCategory().equals(VanillaEmiRecipeCategories.STONECUTTING); + } + + @Override + public boolean supportsRecipe(EmiRecipe recipe) { + return recipe.getCategory().equals(VanillaEmiRecipeCategories.STONECUTTING); + } + + @Override + protected Map getGuiSlotToIngredientMap(T menu, ITableRecipeAdapter recipe) { + return Map.of(); + } +} diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/wt/ETWTRecipeHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/wt/ETWTRecipeHandler.java index cf0ac2e..1668502 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/wt/ETWTRecipeHandler.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/extendedterminal/wt/ETWTRecipeHandler.java @@ -2,9 +2,9 @@ import dev.emi.emi.api.EmiRegistry; import me.myogoo.extendedterminal.api.integration.emi.ETEmiRecipeHandler; -import me.myogoo.extendedterminal.integration.emi.extendedterminal.handler.ETCraftingRecipeHandler; -import me.myogoo.extendedterminal.integration.emi.extendedterminal.handler.ETSmithingRecipeHandler; -import me.myogoo.extendedterminal.integration.emi.extendedterminal.handler.ETStonecutterRecipeHandler; +import me.myogoo.extendedterminal.integration.emi.extendedterminal.handler.panel.ETCraftingRecipeHandler; +import me.myogoo.extendedterminal.integration.emi.extendedterminal.handler.panel.ETSmithingRecipeHandler; +import me.myogoo.extendedterminal.integration.emi.extendedterminal.handler.panel.ETStonecutterRecipeHandler; import me.myogoo.extendedterminal.menu.extendedterminal.wt.ETWTMenu; import me.myogoo.myotus.api.annotation.MyotusSubscriber; import me.myogoo.myotus.api.annotation.wt.AE2WTLib; @@ -14,8 +14,8 @@ public class ETWTRecipeHandler { @MyotusSubscriber public static void init(EmiRegistry registry) { - registry.addRecipeHandler(ETWTMenu.TYPE, new ETCraftingRecipeHandler<>()); - registry.addRecipeHandler(ETWTMenu.TYPE, new ETSmithingRecipeHandler<>()); - registry.addRecipeHandler(ETWTMenu.TYPE, new ETStonecutterRecipeHandler<>()); + registry.addRecipeHandler(ETWTMenu.TYPE, new ETCraftingRecipeHandler<>(ETWTMenu.class)); + registry.addRecipeHandler(ETWTMenu.TYPE, new ETSmithingRecipeHandler<>(ETWTMenu.class)); + registry.addRecipeHandler(ETWTMenu.TYPE, new ETStonecutterRecipeHandler<>(ETWTMenu.class)); } } diff --git a/src/main/java/me/myogoo/extendedterminal/integration/emi/handler/AbstractTableRecipeHandler.java b/src/main/java/me/myogoo/extendedterminal/integration/emi/handler/AbstractEmiTableRecipeHandler.java similarity index 98% rename from src/main/java/me/myogoo/extendedterminal/integration/emi/handler/AbstractTableRecipeHandler.java rename to src/main/java/me/myogoo/extendedterminal/integration/emi/handler/AbstractEmiTableRecipeHandler.java index 23edb49..8f4d92f 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/emi/handler/AbstractTableRecipeHandler.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/emi/handler/AbstractEmiTableRecipeHandler.java @@ -41,10 +41,10 @@ import static me.myogoo.extendedterminal.network.serverbound.ETFillCraftingGridFromRecipePacket.NOT_SET_RECIPE_SIZE; //mess up so dirty -public abstract class AbstractTableRecipeHandler> implements StandardRecipeHandler { +public abstract class AbstractEmiTableRecipeHandler> implements StandardRecipeHandler { private final Class containerClass; - public AbstractTableRecipeHandler(Class containerClass) { + public AbstractEmiTableRecipeHandler(Class containerClass) { this.containerClass = containerClass; } diff --git a/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/handler/ETCraftingRecipeTransfer.java b/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/handler/ETCraftingRecipeTransfer.java index 7295026..bf3afcb 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/handler/ETCraftingRecipeTransfer.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/jei/extendedterminal/handler/ETCraftingRecipeTransfer.java @@ -80,7 +80,7 @@ public RecipeType getRecipeType() { } } else { menu.setMode(ETTerminalMode.CRAFTING); - ETCraftingRecipeTransferHelper.performTransfer(menu, recipe, null, craftMissing); + ETCraftingRecipeTransferHelper.performTransfer(menu, recipe, craftMissing); } return Result.createSuccessful(); } diff --git a/src/main/java/me/myogoo/extendedterminal/integration/module/extendedterminal/ETCraftingRecipeTransferHelper.java b/src/main/java/me/myogoo/extendedterminal/integration/module/extendedterminal/ETCraftingRecipeTransferHelper.java index ea711c5..7f0a120 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/module/extendedterminal/ETCraftingRecipeTransferHelper.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/module/extendedterminal/ETCraftingRecipeTransferHelper.java @@ -41,7 +41,7 @@ public static Map getGuiSlotToIngredientMap(ETTerminalMenu return result; } - public static void performTransfer(ETTerminalMenu menu, CraftingRecipe recipe, @Nullable ResourceLocation recipeId, + public static void performTransfer(ETTerminalMenu menu, CraftingRecipe recipe, boolean craftMissing) { var ingredientPriorities = EncodingHelper.getIngredientPriorities(menu, ENTRY_COMPARATOR); var templateItems = NonNullList.withSize(menu.getCraftingGridSize(), ItemStack.EMPTY); @@ -55,6 +55,6 @@ public static void performTransfer(ETTerminalMenu menu, CraftingRecipe recipe, @ templateItems.set(entry.getKey(), stack); } - NetworkHandler.instance().sendToServer(new FillCraftingGridFromRecipePacket(recipeId, templateItems, craftMissing)); + NetworkHandler.instance().sendToServer(new FillCraftingGridFromRecipePacket(recipe.getId(), templateItems, craftMissing)); } } diff --git a/src/main/java/me/myogoo/extendedterminal/integration/module/extendedterminal/ETStoneCutterRecipeTransferHelper.java b/src/main/java/me/myogoo/extendedterminal/integration/module/extendedterminal/ETStoneCutterRecipeTransferHelper.java index d85e490..fe90f29 100644 --- a/src/main/java/me/myogoo/extendedterminal/integration/module/extendedterminal/ETStoneCutterRecipeTransferHelper.java +++ b/src/main/java/me/myogoo/extendedterminal/integration/module/extendedterminal/ETStoneCutterRecipeTransferHelper.java @@ -6,7 +6,6 @@ import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; import me.myogoo.extendedterminal.network.serverbound.ETFillStonecutterGridFromRecipePacket; import me.myogoo.myotus.api.MyotusAPI; -import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.item.crafting.StonecutterRecipe; diff --git a/src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/ETTerminalMenu.java b/src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/ETTerminalMenu.java index 77239e1..e8a2d54 100644 --- a/src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/ETTerminalMenu.java +++ b/src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/ETTerminalMenu.java @@ -2,11 +2,11 @@ import appeng.api.inventories.ISegmentedInventory; import appeng.api.inventories.InternalInventory; -import appeng.api.storage.ITerminalHost; import appeng.core.sync.network.NetworkHandler; import appeng.core.sync.packets.InventoryActionPacket; import appeng.helpers.InventoryAction; import appeng.menu.SlotSemantics; +import appeng.menu.guisync.GuiSync; import appeng.menu.implementations.MenuTypeBuilder; import appeng.menu.slot.AppEngSlot; import appeng.menu.slot.CraftingMatrixSlot; @@ -61,6 +61,7 @@ public class ETTerminalMenu extends ETTerminalBaseMenu { private final ISegmentedInventory craftingInventoryHost; private final IETTerminalHost host; + @GuiSync(0) private ETTerminalMode currentMode; private final CraftingMatrixSlot[] craftingSlots; @@ -77,13 +78,14 @@ public class ETTerminalMenu extends ETTerminalBaseMenu { private final CraftingMatrixSlot stonecuttingSlot; private final ETStoneCutterSlot stoneCutterOutputSlot; private final List stoneCutterRecipes = new ArrayList<>(); - @Nullable - private ResourceLocation stoneCutterRecipeId; + @GuiSync(1) + private ResourceLocation stoneCutterRecipeId = null; private final CraftingMatrixSlot anvilLeftSlot; private final CraftingMatrixSlot anvilRightSlot; private final ETAnvilSlot anvilOutputSlot; private final FakeAnvilMenu anvilDelegate; + @GuiSync(2) private int anvilCost; private boolean handlingAnvilTake; diff --git a/src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/wt/ETWTMenu.java b/src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/wt/ETWTMenu.java index 24ec9c7..0350580 100644 --- a/src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/wt/ETWTMenu.java +++ b/src/main/java/me/myogoo/extendedterminal/menu/extendedterminal/wt/ETWTMenu.java @@ -1,5 +1,6 @@ package me.myogoo.extendedterminal.menu.extendedterminal.wt; +import appeng.api.networking.IGridNode; import appeng.menu.slot.RestrictedInputSlot; import de.mari_023.ae2wtlib.AE2wtlibSlotSemantics; import de.mari_023.ae2wtlib.terminal.WTMenuHost; @@ -10,14 +11,16 @@ import me.myogoo.extendedterminal.menu.extendedterminal.ETTerminalMenu; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.inventory.MenuType; +import org.jetbrains.annotations.Nullable; public class ETWTMenu extends ETTerminalMenu { public static final MenuType TYPE = MenuTypeBuilder .create(ETWTMenu::new, ETWTHost.class) .build(ETMenuType.ET_TERMINAL.getWTIdAsString()); - + private final ETWTHost host; public ETWTMenu(int id, Inventory ip, ETWTHost host) { super(TYPE, id, ip, host); + this.host =host; addSlot(new RestrictedInputSlot( RestrictedInputSlot.PlacableItemType.QE_SINGULARITY, host.getSubInventory(WTMenuHost.INV_SINGULARITY), @@ -25,11 +28,11 @@ public ETWTMenu(int id, Inventory ip, ETWTHost host) { } @Override - public ETWTHost getHost() { - return (ETWTHost) super.getHost(); + public @Nullable IGridNode getNetworkNode() { + return this.host.getActionableNode(); } public boolean isWUT() { - return ((WTMenuHost) getHost()).getItemStack().getItem() instanceof ItemWUT; + return this.host.getItemStack().getItem() instanceof ItemWUT; } } diff --git a/src/main/java/me/myogoo/extendedterminal/network/serverbound/ETFillCraftingGridFromRecipePacket.java b/src/main/java/me/myogoo/extendedterminal/network/serverbound/ETFillCraftingGridFromRecipePacket.java index 96312b6..bd42701 100644 --- a/src/main/java/me/myogoo/extendedterminal/network/serverbound/ETFillCraftingGridFromRecipePacket.java +++ b/src/main/java/me/myogoo/extendedterminal/network/serverbound/ETFillCraftingGridFromRecipePacket.java @@ -115,7 +115,6 @@ private void handleOnServer(ServerPlayer player) { @Nullable var node = cct.getNetworkNode(); - if (node == null) { return; } diff --git a/src/main/resources/assets/extendedterminal/lang/en_us.json b/src/main/resources/assets/extendedterminal/lang/en_us.json index e9ee31a..8a5c90d 100644 --- a/src/main/resources/assets/extendedterminal/lang/en_us.json +++ b/src/main/resources/assets/extendedterminal/lang/en_us.json @@ -3,6 +3,7 @@ "item.extendedterminal.et_terminal": "Extended Terminal", "item.extendedterminal.wireless_et_terminal": "Wireless Extended Terminal", + "key.ae2.wireless_wireless_et_terminal_terminal": "Wireless Extended Terminal", "item.extendedterminal.basic_terminal": "Basic Extended Crafting Terminal", "item.extendedterminal.advanced_terminal": "Advanced Extended Crafting Terminal", diff --git a/src/main/resources/data/curios/tags/item/curio.json b/src/main/resources/data/curios/tags/items/curio.json similarity index 100% rename from src/main/resources/data/curios/tags/item/curio.json rename to src/main/resources/data/curios/tags/items/curio.json From c3b6c0bb23a7ddbf16f9657f0d61669792d39b86 Mon Sep 17 00:00:00 2001 From: njoyshadow Date: Thu, 16 Apr 2026 23:25:18 +0900 Subject: [PATCH 11/11] feat: update changelog and .gitignore for Extended Terminal enhancements --- .gitignore | 1 + CHANGELOG.md | 8 ++++++-- .../me/myogoo/extendedterminal/init/ETModIntegration.java | 4 ++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 2d35248..4701906 100644 --- a/.gitignore +++ b/.gitignore @@ -123,3 +123,4 @@ run-data/ .codex .idea +TODO.md \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index b1c7a33..6649c3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG ## Feature -- Extended Terminal Arrived Now! -- Change to new Texture \ No newline at end of file +- Implemented Myotus +- Update Terminal's textures +## Extended Terminal +> Now 1.20.1 arrived +Extended Terminal can crafting, smithing, stonecutting, anvil in one terminal +Support wireless terminal diff --git a/src/main/java/me/myogoo/extendedterminal/init/ETModIntegration.java b/src/main/java/me/myogoo/extendedterminal/init/ETModIntegration.java index 57fec27..7ee7aff 100644 --- a/src/main/java/me/myogoo/extendedterminal/init/ETModIntegration.java +++ b/src/main/java/me/myogoo/extendedterminal/init/ETModIntegration.java @@ -21,7 +21,7 @@ public static synchronized void initialize() { registrar.registerLoadableMod(ModAccessor.ExtendedCrafting.class, "extendedcrafting", "*"); registrar.registerLoadableMod(ModAccessor.EpicExCrafting.class, "extendedcrafting", "Extended Crafting: Expanded", "*"); - registrar.registerLoadableMod(ModAccessor.ReAvaritia.class, "avaritia", "Re-Avaritia", "*"); - registrar.registerLoadableMod(ModAccessor.AvaritiaNeo.class, "avaritia", "Avaritia", "*"); + registrar.registerLoadableMod(ModAccessor.ReAvaritia.class, "avaritia", "Re-Avaritia", "[1.3.9.8,)"); + registrar.registerLoadableMod(ModAccessor.AvaritiaNeo.class, "avaritia", "Avaritia", "[1.1.3,)"); } }