├── .github └── workflows │ ├── build_master.yml │ ├── build_pr.yml │ └── modrinth.yml ├── .gitignore ├── LICENSE ├── README.md ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src └── main ├── java └── tfar │ └── ae2wt │ ├── AE2WirelessTerminals.java │ ├── ArmorSlot.java │ ├── Events.java │ ├── WTConfig.java │ ├── ae2copies │ ├── FluidRepo.java │ └── FluidSorters.java │ ├── client │ └── ae2wtlibclient.java │ ├── cpu │ ├── CraftingCPUCycler.java │ └── CraftingCPURecord.java │ ├── init │ ├── Menus.java │ └── ModItems.java │ ├── jei │ ├── CraftingRecipeTransferHandler.java │ ├── JeiPlug.java │ ├── PatternRecipeTransferHandler.java │ └── RecipeTransferHandler.java │ ├── mixin │ ├── AEBaseContainerAccess.java │ ├── AESubScreenMixin.java │ ├── ContainerAccess.java │ ├── ContainerTypeBuilderMixin.java │ ├── CraftConfirmContainerMixin.java │ ├── InvActionPacketMixin.java │ ├── MeMonitorableScreenWireless.java │ └── PlayerInventoryMixin.java │ ├── net │ ├── C2SCycleTerminalPacket.java │ ├── C2SHotkeyPacket.java │ ├── C2SPatternSlotPacket.java │ ├── C2SSwitchGuiPacket.java │ ├── PacketHandler.java │ ├── client │ │ └── S2CInterfaceTerminalPacket.java │ └── server │ │ ├── C2SClearPatternPacket.java │ │ ├── C2SDeleteTrashPacket.java │ │ ├── C2SEncodePatternPacket.java │ │ ├── C2SSetMagnetModePacket.java │ │ ├── C2STogglePatternCraftingModePacket.java │ │ └── C2STogglePatternSubsitutionPacket.java │ ├── terminal │ ├── AbstractWirelessTerminalItem.java │ ├── FixedViewCellInventory.java │ ├── IInfinityBoosterCardHolder.java │ ├── InternalInventory.java │ ├── ItemInfinityBooster.java │ ├── SlotType.java │ ├── WTGuiObject.java │ └── WTInventoryHandler.java │ ├── util │ ├── ContainerHelper.java │ ├── FixedEmptyInventory.java │ ├── ItemButton.java │ └── ae2wtlibSubScreen.java │ ├── wirelesscraftingterminal │ ├── CraftingTerminalHandler.java │ ├── PlayerWidget.java │ ├── TermFactory.java │ ├── WCTGuiObject.java │ ├── WCTItem.java │ ├── WirelessCraftingTermSlot.java │ ├── WirelessCraftingTerminalContainer.java │ ├── WirelessCraftingTerminalScreen.java │ └── magnet_card │ │ ├── ItemMagnetCard.java │ │ ├── MagnetHandler.java │ │ ├── MagnetMode.java │ │ └── MagnetSettings.java │ ├── wirelessfluidterminal │ ├── TermFactory.java │ ├── WFluidTGuiObject.java │ ├── WirelessFluidTerminalContainer.java │ ├── WirelessFluidTerminalItem.java │ └── WirelessFluidTerminalScreen.java │ ├── wirelessinterfaceterminal │ ├── TermFactory.java │ ├── WITGuiObject.java │ ├── WITItem.java │ ├── WITScreen.java │ └── WirelessInterfaceTerminalContainer.java │ ├── wpt │ ├── TermFactory.java │ ├── WPTGuiObject.java │ ├── WPTItem.java │ ├── WirelessPatternTermSlot.java │ ├── WirelessPatternTerminalContainer.java │ └── WirelessPatternTerminalScreen.java │ └── wut │ ├── CycleTerminalButton.java │ ├── IUniversalTerminalCapable.java │ ├── WUTHandler.java │ ├── WUTItem.java │ └── recipe │ ├── Combine.java │ ├── CombineJsonFormat.java │ ├── CombineSerializer.java │ ├── Common.java │ ├── InputHelper.java │ ├── Serializer.java │ ├── Upgrade.java │ ├── UpgradeJsonFormat.java │ └── UpgradeSerializer.java └── resources ├── META-INF └── mods.toml ├── ae2wtlib.mixins.json ├── assets ├── ae2wtlib │ ├── icon.png │ ├── lang │ │ ├── de_de.json │ │ ├── en_us.json │ │ ├── ru_ru.json │ │ └── zh_cn.json │ ├── models │ │ └── item │ │ │ ├── infinity_booster_card.json │ │ │ ├── magnet_card.json │ │ │ ├── wireless_crafting_terminal.json │ │ │ ├── wireless_interface_terminal.json │ │ │ ├── wireless_pattern_terminal.json │ │ │ └── wireless_universal_terminal.json │ └── textures │ │ ├── infinity_booster_card.png │ │ ├── magnet_card.png │ │ ├── wireless_crafting_terminal.png │ │ ├── wireless_fluid_terminal.png │ │ ├── wireless_interface_terminal.png │ │ ├── wireless_pattern_terminal.png │ │ └── wireless_universal_terminal.png └── appliedenergistics2 │ ├── screens │ └── wtlib │ │ ├── schema.json │ │ ├── wireless_crafting_terminal.json │ │ ├── wireless_interface_terminal.json │ │ └── wireless_pattern_terminal.json │ └── textures │ └── wtlib │ ├── gui │ ├── crafting.png │ ├── interface.png │ └── pattern.png │ └── guis │ ├── crafting.png │ ├── interface.png │ └── pattern.png ├── data └── ae2wtlib │ ├── advancements │ └── recipes │ │ ├── infinity_booster_card.json │ │ ├── magnet_card.json │ │ ├── wireless_crafting_terminal.json │ │ ├── wireless_interface_terminal.json │ │ ├── wireless_pattern_terminal.json │ │ └── wireless_universal_terminal │ │ ├── ci.json │ │ ├── cp.json │ │ ├── ip.json │ │ ├── upgrade_crafting.json │ │ ├── upgrade_interface.json │ │ └── upgrade_pattern.json │ └── recipes │ ├── infinity_booster_card.json │ ├── magnet_card.json │ ├── wireless_crafting_terminal.json │ ├── wireless_interface_terminal.json │ ├── wireless_pattern_terminal.json │ └── wireless_universal_terminal │ ├── ci.json │ ├── cp.json │ ├── ip.json │ ├── upgrade_crafting.json │ ├── upgrade_interface.json │ └── upgrade_pattern.json ├── pack.mcmeta └── rei ├── CraftingRecipeTransferHandler.java ├── PatternRecipeTransferHandler.java ├── Plugin.java ├── REIRecipePacket.java └── RecipeTransferHandler.java /.github/workflows/build_master.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Gradle 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle 3 | 4 | name: build master 5 | on: 6 | push: 7 | branches: [ master ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | - name: Set up JDK 1.8 17 | uses: actions/setup-java@v1 18 | with: 19 | java-version: 1.8 20 | - name: Grant execute permission for gradlew 21 | run: chmod +x gradlew 22 | - name: Use gradle cache for faster builds 23 | uses: actions/cache@v1 24 | with: 25 | path: ~/.gradle/caches 26 | key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} 27 | - name: Clean gradle 28 | run: ./gradlew clean --no-daemon --max-workers 1 29 | env: 30 | CURSEFORGE_TOKEN: ${{ secrets.CURSEFORGE_TOKEN }} 31 | - name: Validate no assets 32 | run: test ! -d ./src/generated 33 | - name: Build with Gradle 34 | run: ./gradlew remapJar 35 | env: 36 | CURSEFORGE_TOKEN: ${{ secrets.CURSEFORGE_TOKEN }} 37 | HASH: $(git rev-parse --short "$GITHUB_SHA") 38 | - name: Upload a Build Artifact 39 | uses: actions/upload-artifact@v2.2.2 40 | with: 41 | path: build/libs/AE2WTLib-**.jar -------------------------------------------------------------------------------- /.github/workflows/build_pr.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Gradle 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle 3 | 4 | name: build pr 5 | on: 6 | pull_request: 7 | branches: 8 | - '*' 9 | 10 | jobs: 11 | build: 12 | 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v2 17 | - name: Set up JDK 1.8 18 | uses: actions/setup-java@v1 19 | with: 20 | java-version: 1.8 21 | - name: Grant execute permission for gradlew 22 | run: chmod +x gradlew 23 | - name: Use gradle cache for faster builds 24 | uses: actions/cache@v1 25 | with: 26 | path: ~/.gradle/caches 27 | key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} 28 | - name: Clean gradle 29 | run: ./gradlew clean --no-daemon --max-workers 1 30 | env: 31 | CURSEFORGE_TOKEN: ${{ secrets.CURSEFORGE_TOKEN }} 32 | - name: Validate no assets 33 | run: test ! -d ./src/generated 34 | - name: Build with Gradle 35 | run: ./gradlew remapJar 36 | env: 37 | CURSEFORGE_TOKEN: ${{ secrets.CURSEFORGE_TOKEN }} 38 | PR_NUMBER: ${{ github.event.pull_request.number }} 39 | - name: Upload a Build Artifact 40 | uses: actions/upload-artifact@v2.2.2 41 | with: 42 | path: build/libs/AE2WTLib-**.jar -------------------------------------------------------------------------------- /.github/workflows/modrinth.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Gradle 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle 3 | 4 | name: publish to modrinth and curseforge 5 | 6 | on: 7 | release: 8 | types: [published] 9 | 10 | jobs: 11 | build: 12 | 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v2 17 | - name: Set up JDK 1.8 18 | uses: actions/setup-java@v1 19 | with: 20 | java-version: 1.8 21 | - name: Grant execute permission for gradlew 22 | run: chmod +x gradlew 23 | - name: Use gradle cache for faster builds 24 | uses: actions/cache@v1 25 | with: 26 | path: ~/.gradle/caches 27 | key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} 28 | - name: Clean gradle 29 | run: ./gradlew clean --no-daemon --max-workers 1 30 | env: 31 | CURSEFORGE_TOKEN: ${{ secrets.CURSEFORGE_TOKEN }} 32 | - name: Validate no assets 33 | run: test ! -d ./src/generated 34 | - name: Build with Gradle 35 | run: ./gradlew remapJar 36 | env: 37 | CURSEFORGE_TOKEN: ${{ secrets.CURSEFORGE_TOKEN }} 38 | TAG: ${{ github.event.release.tag_name }} 39 | - name: Upload a Build Artifact for debug purposes only 40 | uses: actions/upload-artifact@v2.2.2 41 | with: 42 | path: build/libs/AE2WTLib-**.jar 43 | - name: modrinth task 44 | run: ./gradlew publishModrinth 45 | env: 46 | CURSEFORGE_TOKEN: ${{ secrets.CURSEFORGE_TOKEN }} 47 | MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }} 48 | TAG: ${{ github.event.release.tag_name }} 49 | CHANGELOG: ${{ github.event.release.body }} 50 | - name: curseForge Task 51 | run: ./gradlew curseforge 52 | env: 53 | CURSEFORGE_TOKEN: ${{ secrets.CURSEFORGE_TOKEN }} 54 | TAG: ${{ github.event.release.tag_name }} 55 | CHANGELOG: ${{ github.event.release.body }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # User-specific stuff 2 | .idea/ 3 | 4 | *.iml 5 | *.ipr 6 | *.iws 7 | 8 | # IntelliJ 9 | out/ 10 | # mpeltonen/sbt-idea plugin 11 | .idea_modules/ 12 | 13 | # JIRA plugin 14 | atlassian-ide-plugin.xml 15 | 16 | # Compiled class file 17 | *.class 18 | 19 | # Log file 20 | *.log 21 | 22 | # BlueJ files 23 | *.ctxt 24 | 25 | # Package Files # 26 | *.jar 27 | *.war 28 | *.nar 29 | *.ear 30 | *.zip 31 | *.tar.gz 32 | *.rar 33 | 34 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 35 | hs_err_pid* 36 | 37 | *~ 38 | 39 | # temporary files which can be created if a process still has a handle open of a deleted file 40 | .fuse_hidden* 41 | 42 | # KDE directory preferences 43 | .directory 44 | 45 | # Linux trash folder which might appear on any partition or disk 46 | .Trash-* 47 | 48 | # .nfs files are created when an open file is removed but is still being accessed 49 | .nfs* 50 | 51 | # General 52 | .DS_Store 53 | .AppleDouble 54 | .LSOverride 55 | 56 | # Icon must end with two \r 57 | Icon 58 | 59 | # Thumbnails 60 | ._* 61 | 62 | # Files that might appear in the root of a volume 63 | .DocumentRevisions-V100 64 | .fseventsd 65 | .Spotlight-V100 66 | .TemporaryItems 67 | .Trashes 68 | .VolumeIcon.icns 69 | .com.apple.timemachine.donotpresent 70 | 71 | # Directories potentially created on remote AFP share 72 | .AppleDB 73 | .AppleDesktop 74 | Network Trash Folder 75 | Temporary Items 76 | .apdisk 77 | 78 | # Windows thumbnail cache files 79 | Thumbs.db 80 | Thumbs.db:encryptable 81 | ehthumbs.db 82 | ehthumbs_vista.db 83 | 84 | # Dump file 85 | *.stackdump 86 | 87 | # Folder config file 88 | [Dd]esktop.ini 89 | 90 | # Recycle Bin used on file shares 91 | $RECYCLE.BIN/ 92 | 93 | # Windows Installer files 94 | *.cab 95 | *.msi 96 | *.msix 97 | *.msm 98 | *.msp 99 | 100 | # Windows shortcuts 101 | *.lnk 102 | 103 | .gradle 104 | build/ 105 | 106 | # Ignore Gradle GUI config 107 | gradle-app.setting 108 | 109 | # Cache of project 110 | .gradletasknamecache 111 | 112 | **/build/ 113 | 114 | # Common working directory 115 | run/ 116 | 117 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) 118 | !gradle-wrapper.jar 119 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2021 mari_023 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![build master](https://github.com/Tfarcenim/AE2WirelessTerminalLibrary/actions/workflows/build_master.yml/badge.svg)](https://github.com/Tfarcenim/AE2WirelessTerminalLibrary/actions/workflows/build_master.yml) 2 | [![Curseforge downloads](http://cf.way2muchnoise.eu/full_483310_downloads.svg)](https://www.curseforge.com/minecraft/mc-mods/applied-energistics-2-wireless-terminals-forge) 3 | [![Curseforge Versions](http://cf.way2muchnoise.eu/versions/483310.svg)](https://www.curseforge.com/minecraft/mc-mods/applied-energistics-2-wireless-terminals/files) 4 | 5 | Applied Energistics 2 Wireless Terminals 6 | ======================================== 7 | This is a Forge Port of the Fabric port 8 | of [Wireless Crafting Terminal](https://www.curseforge.com/minecraft/mc-mods/wireless-crafting-terminal) 9 | , [Wireless Pattern Terminal](https://www.curseforge.com/minecraft/mc-mods/wireless-pattern-terminal) 10 | , [Wireless Interface Terminal](https://www.curseforge.com/minecraft/mc-mods/wireless-interface-terminal), [~~Wireless 11 | Fluid Terminal~~](https://www.curseforge.com/minecraft/mc-mods/wireless-fluid-terminal) (not yet implemented) 12 | and [Wireless Terminal Library](https://www.curseforge.com/minecraft/mc-mods/ae2wtlib) 13 | 14 | It features several wireless versions of Applied Energistics 2 terminals with support for an Infinity Booster Card, 15 | which allows terminals to work from everywhere and even across dimensions. 16 | 17 | It also adds a wireless universal terminal which has all wireless terminals in one item 18 | 19 | ## Missing Features / Known Issues 20 | 21 | - Wireless Fluid Terminal 22 | - Magnet Card can't filter items 23 | - Curios support 24 | - support for viewcells 25 | 26 | ## License 27 | 28 | * Applied Energistics 2 Wireless Terminals 29 | - (c) 2021 Tfarecnim 30 | - [![License](https://img.shields.io/badge/License-MIT-red.svg?style=flat-square)](http://opensource.org/licenses/MIT) 31 | 32 | * Textures 33 | - (c) 2021, [Ridanisaurus Rid](https://github.com/Ridanisaurus/) 34 | - [![License](https://img.shields.io/badge/License-CC%20BY--NC--SA%203.0-yellow.svg?style=flat-square)](https://creativecommons.org/licenses/by-nc-sa/3.0/) 35 | - based on [Applied Energistics 2](https://github.com/AppliedEnergistics/Applied-Energistics-2) Textures 36 | - (c) 2020, [Ridanisaurus Rid](https://github.com/Ridanisaurus/), (c) 2013 - 2020 AlgorithmX2 et al 37 | - [![License](https://img.shields.io/badge/License-CC%20BY--NC--SA%203.0-yellow.svg?style=flat-square)](https://creativecommons.org/licenses/by-nc-sa/3.0/) 38 | 39 | * Text and Translations 40 | - [![License](https://img.shields.io/badge/License-No%20Restriction-green.svg?style=flat-square)](https://creativecommons.org/publicdomain/zero/1.0/) 41 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Sets default memory used for gradle commands. Can be overridden by user or command line properties. 2 | # This is required to provide enough memory for the Minecraft decompilation process. 3 | org.gradle.jvmargs=-Xmx8G 4 | org.gradle.daemon=false 5 | mod_version=0.3.3 6 | modid=ae2wtlib 7 | mc_version=1.16.5 8 | forge_version=36.1.10 9 | mapping=20210309 10 | mcp_version=1.16.5 11 | ae2_version=8.4.2 12 | jei_version=7.7.1.126 13 | 14 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tfarcenim/AE2WirelessTerminalLibrary/9ef7893c8aaed44babeb3590e37524ab096c81f5/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip 6 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | jcenter() 4 | maven { 5 | name = 'Fabric' 6 | url = 'https://maven.fabricmc.net/' 7 | } 8 | gradlePluginPortal() 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/AE2WirelessTerminals.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt; 2 | 3 | import appeng.api.features.IRegistryContainer; 4 | import appeng.api.features.IWirelessTermRegistry; 5 | import appeng.core.Api; 6 | import tfar.ae2wt.init.Menus; 7 | import net.minecraft.inventory.container.ContainerType; 8 | import net.minecraft.item.Item; 9 | import net.minecraft.item.ItemGroup; 10 | import net.minecraft.item.ItemStack; 11 | import net.minecraft.util.ResourceLocation; 12 | import net.minecraftforge.common.MinecraftForge; 13 | import net.minecraftforge.event.RegistryEvent; 14 | import net.minecraftforge.eventbus.api.IEventBus; 15 | import net.minecraftforge.fml.common.Mod; 16 | import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; 17 | import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; 18 | import net.minecraftforge.fml.loading.FMLEnvironment; 19 | import net.minecraftforge.registries.IForgeRegistry; 20 | import net.minecraftforge.registries.IForgeRegistryEntry; 21 | import tfar.ae2wt.client.ae2wtlibclient; 22 | import tfar.ae2wt.init.ModItems; 23 | import tfar.ae2wt.net.PacketHandler; 24 | 25 | @Mod(value = AE2WirelessTerminals.MODID) 26 | public class AE2WirelessTerminals { 27 | public static final String MODID = "ae2wtlib"; 28 | 29 | public static final ItemGroup ITEM_GROUP = new ItemGroup(MODID) { 30 | @Override 31 | public ItemStack createIcon() { 32 | return new ItemStack(ModItems.CRAFTING_TERMINAL); 33 | } 34 | }; 35 | 36 | public AE2WirelessTerminals() { 37 | IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus(); 38 | bus.addGenericListener(Item.class,this::items); 39 | bus.addGenericListener(ContainerType.class, Menus::menus); 40 | MinecraftForge.EVENT_BUS.addListener(Events::serverTick); 41 | bus.addListener(this::common); 42 | if (FMLEnvironment.dist.isClient()) { 43 | // MinecraftForge.EVENT_BUS.addListener(ae2wtlibclient::clientTick); 44 | bus.addListener(ae2wtlibclient::setup); 45 | } 46 | } 47 | 48 | private void common(FMLCommonSetupEvent e) { 49 | PacketHandler.registerPackets(); 50 | IRegistryContainer iRegistryContainer = Api.instance().registries(); 51 | 52 | IWirelessTermRegistry iWirelessTermRegistry = iRegistryContainer.wireless(); 53 | 54 | iWirelessTermRegistry.registerWirelessHandler(ModItems.CRAFTING_TERMINAL); 55 | iWirelessTermRegistry.registerWirelessHandler(ModItems.PATTERN_TERMINAL); 56 | iWirelessTermRegistry.registerWirelessHandler(ModItems.INTERFACE_TERMINAL); 57 | iWirelessTermRegistry.registerWirelessHandler(ModItems.UNIVERSAL_TERMINAL); 58 | iWirelessTermRegistry.registerWirelessHandler(ModItems.WIRELESS_FLUID_TERMINAL); 59 | 60 | } 61 | 62 | 63 | public void items(RegistryEvent.Register e) { 64 | register("infinity_booster_card", ModItems.INFINITY_BOOSTER_CARD, e.getRegistry()); 65 | register("magnet_card", ModItems.MAGNET_CARD, e.getRegistry()); 66 | register("wireless_crafting_terminal", ModItems.CRAFTING_TERMINAL, e.getRegistry()); 67 | register("wireless_pattern_terminal", ModItems.PATTERN_TERMINAL, e.getRegistry()); 68 | register("wireless_interface_terminal", ModItems.INTERFACE_TERMINAL, e.getRegistry()); 69 | register("wireless_universal_terminal", ModItems.UNIVERSAL_TERMINAL, e.getRegistry()); 70 | register("wireless_fluid_terminal",ModItems.WIRELESS_FLUID_TERMINAL,e.getRegistry()); 71 | } 72 | 73 | public static > T register(String name,T obj,IForgeRegistry registry) { 74 | registry.register(obj.setRegistryName(new ResourceLocation(MODID,name))); 75 | return obj; 76 | } 77 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/ArmorSlot.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt; 2 | 3 | import appeng.container.slot.AppEngSlot; 4 | import net.minecraftforge.items.IItemHandler; 5 | 6 | public class ArmorSlot extends AppEngSlot { 7 | public ArmorSlot(IItemHandler inv, int invSlot) { 8 | super(inv, invSlot); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/Events.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt; 2 | 3 | import net.minecraftforge.event.TickEvent; 4 | import net.minecraftforge.fml.server.ServerLifecycleHooks; 5 | import tfar.ae2wt.wirelesscraftingterminal.magnet_card.MagnetHandler; 6 | 7 | public class Events { 8 | 9 | public static void serverTick(TickEvent.PlayerTickEvent e) { 10 | if (e.phase == TickEvent.Phase.START && !e.player.world.isRemote) { 11 | MagnetHandler.doMagnet(e.player); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/WTConfig.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt; 2 | 3 | import appeng.core.AEConfig; 4 | 5 | public class WTConfig { 6 | 7 | public static double getPowerMultiplier(double range, boolean isOutOfRange) { 8 | if(!isOutOfRange) return AEConfig.instance().wireless_getDrainRate(range); 9 | return AEConfig.instance().wireless_getDrainRate(528 * getOutOfRangePowerMultiplier());//the drain rate while in range is dependent on the distance, and calculated by ae2. since 528 blocks is the max distance a terminal can normally work, out of range has to calculate the power with max range, or otherwise it uses less energy when out of range than at the edge of range 10 | } 11 | 12 | public static double getChargeRate() { 13 | return 32000;//8000 is ae2's default charge rate, so I chose to use it too 14 | } 15 | 16 | public static double WUTChargeRateMultiplier() { 17 | return 1; 18 | } 19 | 20 | private static int getOutOfRangePowerMultiplier() { 21 | return 2;//has to be > 1 for terminals to use more energy outside of range than in range 22 | } 23 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/ae2copies/FluidRepo.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.ae2copies; 2 | 3 | import appeng.api.config.SortDir; 4 | import appeng.api.config.SortOrder; 5 | import appeng.api.storage.data.IAEFluidStack; 6 | import appeng.client.gui.me.common.Repo; 7 | import appeng.client.gui.widgets.IScrollSource; 8 | import appeng.client.gui.widgets.ISortSource; 9 | import appeng.util.Platform; 10 | 11 | import java.util.Comparator; 12 | import java.util.regex.Pattern; 13 | 14 | public class FluidRepo extends Repo { 15 | public FluidRepo(IScrollSource src, ISortSource sortSrc) { 16 | super(src, sortSrc); 17 | } 18 | 19 | protected boolean matchesSearch(SearchMode searchMode, Pattern searchPattern, IAEFluidStack stack) { 20 | String displayName; 21 | if (searchMode == SearchMode.MOD) { 22 | displayName = Platform.getModId(stack); 23 | return searchPattern.matcher(displayName).find(); 24 | } else { 25 | displayName = Platform.getFluidDisplayName(stack).getString(); 26 | return searchPattern.matcher(displayName).find(); 27 | } 28 | } 29 | 30 | protected Comparator getComparator(SortOrder sortBy, SortDir sortDir) { 31 | return FluidSorters.getComparator(sortBy, sortDir); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/ae2copies/FluidSorters.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.ae2copies; 2 | 3 | import appeng.api.config.SortDir; 4 | import appeng.api.config.SortOrder; 5 | import appeng.api.storage.data.IAEFluidStack; 6 | import appeng.api.storage.data.IAEStack; 7 | import appeng.util.Platform; 8 | 9 | import java.util.Comparator; 10 | import java.util.function.Function; 11 | 12 | public class FluidSorters { 13 | public static final Comparator NAME_ASC = Comparator.comparing((fs) -> Platform.getFluidDisplayName(fs).getString(), String::compareToIgnoreCase); 14 | public static final Comparator NAME_DESC = NAME_ASC.reversed(); 15 | public static final Comparator MOD_ASC = Comparator.comparing((Function) Platform::getModId, String::compareToIgnoreCase).thenComparing(NAME_ASC); 16 | public static final Comparator MOD_DESC = MOD_ASC.reversed(); 17 | public static final Comparator SIZE_ASC = Comparator.comparingLong(IAEStack::getStackSize); 18 | public static final Comparator SIZE_DESC = SIZE_ASC.reversed(); 19 | 20 | private FluidSorters() { 21 | } 22 | 23 | public static Comparator getComparator(SortOrder order, SortDir dir) { 24 | switch (order) { 25 | case NAME: 26 | default: 27 | return dir == SortDir.ASCENDING ? NAME_ASC : NAME_DESC; 28 | case AMOUNT: 29 | return dir == SortDir.ASCENDING ? SIZE_ASC : SIZE_DESC; 30 | case MOD: 31 | return dir == SortDir.ASCENDING ? MOD_ASC : MOD_DESC; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/client/ae2wtlibclient.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.client; 2 | 3 | import appeng.client.gui.AEBaseScreen; 4 | import appeng.client.gui.ScreenRegistration; 5 | import appeng.client.gui.style.ScreenStyle; 6 | import appeng.client.gui.style.StyleManager; 7 | import appeng.container.AEBaseContainer; 8 | import net.minecraft.inventory.container.ContainerType; 9 | import tfar.ae2wt.init.Menus; 10 | import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; 11 | import tfar.ae2wt.wirelesscraftingterminal.WirelessCraftingTerminalScreen; 12 | import tfar.ae2wt.wirelessfluidterminal.WirelessFluidTerminalScreen; 13 | import tfar.ae2wt.wirelessinterfaceterminal.WITScreen; 14 | import tfar.ae2wt.wpt.WirelessPatternTerminalScreen; 15 | import net.minecraft.client.gui.ScreenManager; 16 | 17 | import java.io.FileNotFoundException; 18 | 19 | public class ae2wtlibclient { 20 | 21 | public static void setup(FMLClientSetupEvent e) { 22 | register(Menus.WCT, WirelessCraftingTerminalScreen::new,"/screens/wtlib/wireless_crafting_terminal.json"); 23 | register(Menus.PATTERN, WirelessPatternTerminalScreen::new,"/screens/wtlib/wireless_pattern_terminal.json"); 24 | register(Menus.WIT, WITScreen::new,"/screens/wtlib/wireless_interface_terminal.json"); 25 | register(Menus.WIRELESS_FLUID_TERMINAL, WirelessFluidTerminalScreen::new,"/screens/terminals/fluid_terminal.json"); 26 | 27 | /* ClientPlayNetworking.registerGlobalReceiver(new Identifier("ae2wtlib", "interface_terminal"), (client, handler, buf, responseSender) -> { 28 | buf.retain(); 29 | client.execute(() -> { 30 | if (client.player == null) return; 31 | 32 | final Screen screen = MinecraftClient.getInstance().currentScreen; 33 | if (screen instanceof WITScreen) { 34 | WITScreen s = (WITScreen) screen; 35 | CompoundNBT tag = buf.readCompoundTag(); 36 | if (tag != null) s.postUpdate(tag); 37 | } 38 | buf.release(); 39 | }); 40 | });*/ 41 | //registerKeybindings(); 42 | } 43 | 44 | /* static KeyBinding wct = new KeyBinding("key.ae2wtlib.wct", GLFW.GLFW_KEY_UNKNOWN, "key.category.ae2wtlib"); 45 | static KeyBinding wpt = new KeyBinding("key.ae2wtlib.wpt", GLFW.GLFW_KEY_UNKNOWN, "key.category.ae2wtlib"); 46 | static KeyBinding wit = new KeyBinding("key.ae2wtlib.wit", GLFW.GLFW_KEY_UNKNOWN, "key.category.ae2wtlib"); 47 | 48 | public static void registerKeybindings() { 49 | ClientRegistry.registerKeyBinding(wct); 50 | ClientRegistry.registerKeyBinding(wpt); 51 | ClientRegistry.registerKeyBinding(wit); 52 | } 53 | 54 | public static void clientTick(TickEvent.ClientTickEvent e) { 55 | if (e.phase == TickEvent.Phase.END) { 56 | while (wct.isPressed()) { 57 | // PacketHandler.INSTANCE.sendToServer(new C2SHotkeyPacket("crafting")); 58 | } 59 | while (wpt.isPressed()) { 60 | // PacketHandler.INSTANCE.sendToServer(new C2SHotkeyPacket("pattern")); 61 | 62 | } 63 | while (wit.isPressed()) { 64 | // PacketHandler.INSTANCE.sendToServer(new C2SHotkeyPacket("interface")); 65 | } 66 | } 67 | }*/ 68 | 69 | 70 | /** 71 | * Registers a screen for a given container and ensures the given style is applied after opening the screen. 72 | */ 73 | private static > void register(ContainerType type, 74 | ScreenRegistration.StyledScreenFactory factory, 75 | String stylePath) { 76 | // CONTAINER_STYLES.put(type, stylePath); 77 | ScreenManager.registerFactory(type, (container, playerInv, title) -> { 78 | ScreenStyle style; 79 | try { 80 | style = StyleManager.loadStyleDoc(stylePath); 81 | } catch (FileNotFoundException e) { 82 | throw new RuntimeException("Failed to read Screen JSON file: " + stylePath + ": " + e.getMessage()); 83 | } catch (Exception e) { 84 | throw new RuntimeException("Failed to read Screen JSON file: " + stylePath, e); 85 | } 86 | 87 | return factory.create(container, playerInv, title, style); 88 | }); 89 | } 90 | 91 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/cpu/CraftingCPUCycler.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.cpu; 2 | 3 | import appeng.api.networking.IGrid; 4 | import appeng.api.networking.crafting.ICraftingCPU; 5 | import appeng.api.networking.crafting.ICraftingGrid; 6 | import com.google.common.collect.ImmutableSet; 7 | import com.google.common.collect.UnmodifiableIterator; 8 | import java.util.ArrayList; 9 | import java.util.Collections; 10 | import java.util.List; 11 | import java.util.function.Predicate; 12 | import net.minecraft.util.text.StringTextComponent; 13 | 14 | public class CraftingCPUCycler { 15 | private final Predicate cpuFilter; 16 | private final CraftingCPUCycler.ChangeListener changeListener; 17 | private final List cpus = new ArrayList<>(); 18 | private int selectedCpu = -1; 19 | private boolean initialDataSent = false; 20 | private boolean allowNoSelection; 21 | 22 | public CraftingCPUCycler(Predicate cpuFilter,CraftingCPUCycler.ChangeListener changeListener) { 23 | this.cpuFilter = cpuFilter; 24 | this.changeListener = changeListener; 25 | } 26 | 27 | public void detectAndSendChanges(IGrid network) { 28 | ICraftingGrid cc = network.getCache(ICraftingGrid.class); 29 | ImmutableSet cpuSet = cc.getCpus(); 30 | int matches = 0; 31 | boolean changed = !this.initialDataSent; 32 | this.initialDataSent = true; 33 | UnmodifiableIterator var6 = cpuSet.iterator(); 34 | 35 | ICraftingCPU c; 36 | while(var6.hasNext()) { 37 | c = var6.next(); 38 | boolean found = false; 39 | 40 | for (CraftingCPURecord ccr : this.cpus) { 41 | if (ccr.getCpu() == c) { 42 | found = true; 43 | break; 44 | } 45 | } 46 | 47 | boolean matched = this.cpuFilter.test(c); 48 | if (matched) { 49 | ++matches; 50 | } 51 | 52 | if (found == !matched) { 53 | changed = true; 54 | } 55 | } 56 | 57 | if (changed || this.cpus.size() != matches) { 58 | this.cpus.clear(); 59 | var6 = cpuSet.iterator(); 60 | 61 | while(var6.hasNext()) { 62 | c = var6.next(); 63 | if (this.cpuFilter.test(c)) { 64 | this.cpus.add(new CraftingCPURecord(c.getAvailableStorage(), c.getCoProcessors(), c)); 65 | } 66 | } 67 | 68 | Collections.sort(this.cpus); 69 | 70 | for(int i = 0; i < this.cpus.size(); ++i) { 71 | CraftingCPURecord cpu = this.cpus.get(i); 72 | if (cpu.getName() == null) { 73 | cpu.setName(new StringTextComponent("#" + (i + 1))); 74 | } 75 | } 76 | 77 | this.notifyListener(); 78 | } 79 | 80 | } 81 | 82 | public void cycleCpu(boolean next) { 83 | if (next) { 84 | ++this.selectedCpu; 85 | } else { 86 | --this.selectedCpu; 87 | } 88 | 89 | int lowerLimit = this.allowNoSelection ? -1 : 0; 90 | if (this.selectedCpu < lowerLimit) { 91 | this.selectedCpu = this.cpus.size() - 1; 92 | } else if (this.selectedCpu >= this.cpus.size()) { 93 | this.selectedCpu = lowerLimit; 94 | } 95 | 96 | this.notifyListener(); 97 | } 98 | 99 | public boolean isAllowNoSelection() { 100 | return this.allowNoSelection; 101 | } 102 | 103 | public void setAllowNoSelection(boolean allowNoSelection) { 104 | this.allowNoSelection = allowNoSelection; 105 | } 106 | 107 | private void notifyListener() { 108 | if (this.selectedCpu >= this.cpus.size()) { 109 | this.selectedCpu = -1; 110 | } 111 | 112 | if (!this.allowNoSelection && this.selectedCpu == -1 && !this.cpus.isEmpty()) { 113 | this.selectedCpu = 0; 114 | } 115 | 116 | if (this.selectedCpu != -1) { 117 | this.changeListener.onChange(this.cpus.get(this.selectedCpu), true); 118 | } else { 119 | this.changeListener.onChange(null, !this.cpus.isEmpty()); 120 | } 121 | 122 | } 123 | 124 | @FunctionalInterface 125 | public interface ChangeListener { 126 | void onChange(CraftingCPURecord var1, boolean var2); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/cpu/CraftingCPURecord.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.cpu; 2 | 3 | import appeng.api.networking.crafting.ICraftingCPU; 4 | import net.minecraft.util.text.ITextComponent; 5 | 6 | import javax.annotation.Nonnull; 7 | 8 | public class CraftingCPURecord implements Comparable { 9 | private final ICraftingCPU cpu; 10 | private final long size; 11 | private final int processors; 12 | private ITextComponent name; 13 | 14 | public CraftingCPURecord(long size, int coProcessors, ICraftingCPU server) { 15 | this.size = size; 16 | this.processors = coProcessors; 17 | this.cpu = server; 18 | this.name = server.getName(); 19 | } 20 | 21 | public int compareTo(@Nonnull CraftingCPURecord o) { 22 | int a = Long.compare(o.getProcessors(), this.getProcessors()); 23 | return a != 0 ? a : Long.compare(o.getSize(), this.getSize()); 24 | } 25 | 26 | public ICraftingCPU getCpu() { 27 | return this.cpu; 28 | } 29 | 30 | public int getProcessors() { 31 | return this.processors; 32 | } 33 | 34 | public long getSize() { 35 | return this.size; 36 | } 37 | 38 | public ITextComponent getName() { 39 | return this.name; 40 | } 41 | 42 | public void setName(ITextComponent name) { 43 | this.name = name; 44 | } 45 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/init/Menus.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.init; 2 | 3 | import appeng.container.ContainerLocator; 4 | import appeng.container.ContainerOpener; 5 | import appeng.core.Api; 6 | import net.minecraft.entity.player.PlayerEntity; 7 | import net.minecraft.entity.player.PlayerInventory; 8 | import net.minecraft.entity.player.ServerPlayerEntity; 9 | import net.minecraft.inventory.container.ContainerType; 10 | import net.minecraft.network.PacketBuffer; 11 | import net.minecraftforge.common.extensions.IForgeContainerType; 12 | import net.minecraftforge.event.RegistryEvent; 13 | import tfar.ae2wt.AE2WirelessTerminals; 14 | import tfar.ae2wt.WTConfig; 15 | import tfar.ae2wt.wirelesscraftingterminal.WirelessCraftingTerminalContainer; 16 | import tfar.ae2wt.wirelessfluidterminal.WirelessFluidTerminalContainer; 17 | import tfar.ae2wt.wirelessinterfaceterminal.WirelessInterfaceTerminalContainer; 18 | import tfar.ae2wt.wpt.WirelessPatternTerminalContainer; 19 | import tfar.ae2wt.wut.WUTHandler; 20 | 21 | public class Menus { 22 | public static ContainerType WIT = IForgeContainerType.create((int windowId1, PlayerInventory inv1, PacketBuffer inv12) -> WirelessInterfaceTerminalContainer.openClient(windowId1, inv1)); 23 | public static ContainerType WCT = new ContainerType<>(WirelessCraftingTerminalContainer::openClient); 24 | public static ContainerType PATTERN = IForgeContainerType.create((windowId1, inv1, buf1) -> WirelessPatternTerminalContainer.openClient(windowId1, inv1)); 25 | public static ContainerType WIRELESS_FLUID_TERMINAL = new ContainerType<>(WirelessFluidTerminalContainer::openClient); 26 | 27 | public static void menus(RegistryEvent.Register> e) { 28 | AE2WirelessTerminals.register("wireless_crafting_terminal",WCT,e.getRegistry()); 29 | AE2WirelessTerminals.register( "wireless_pattern_terminal",PATTERN ,e.getRegistry()); 30 | AE2WirelessTerminals.register( "wireless_interface_terminal",WIT,e.getRegistry()); 31 | AE2WirelessTerminals.register( "wireless_fluid_terminal", WIRELESS_FLUID_TERMINAL,e.getRegistry()); 32 | 33 | WUTHandler.addTerminal("crafting", ModItems.CRAFTING_TERMINAL::open); 34 | WUTHandler.addTerminal("pattern", ModItems.PATTERN_TERMINAL::open); 35 | WUTHandler.addTerminal("interface", ModItems.INTERFACE_TERMINAL::open); 36 | 37 | ContainerOpener.addOpener(WCT, (new CheckedOpener(WirelessCraftingTerminalContainer::openServer))::open); 38 | ContainerOpener.addOpener(PATTERN, (new CheckedOpener(WirelessPatternTerminalContainer::openServer))::open); 39 | ContainerOpener.addOpener(WIT, (new CheckedOpener(WirelessInterfaceTerminalContainer::openServer))::open); 40 | ContainerOpener.addOpener(WIRELESS_FLUID_TERMINAL, (new CheckedOpener(WirelessFluidTerminalContainer::openServer))::open); 41 | 42 | Api.instance().registries().charger().addChargeRate(ModItems.CRAFTING_TERMINAL, WTConfig.getChargeRate()); 43 | Api.instance().registries().charger().addChargeRate(ModItems.PATTERN_TERMINAL, WTConfig.getChargeRate()); 44 | Api.instance().registries().charger().addChargeRate(ModItems.INTERFACE_TERMINAL, WTConfig.getChargeRate()); 45 | Api.instance().registries().charger().addChargeRate(ModItems.UNIVERSAL_TERMINAL, WTConfig.getChargeRate() * WTConfig.WUTChargeRateMultiplier()); 46 | Api.instance().registries().charger().addChargeRate(ModItems.WIRELESS_FLUID_TERMINAL, WTConfig.getChargeRate()); 47 | } 48 | 49 | private static class CheckedOpener { 50 | private final UncheckedOpener opener; 51 | public CheckedOpener(UncheckedOpener opener) { 52 | this.opener = opener; 53 | } 54 | 55 | public boolean open(PlayerEntity player, ContainerLocator locator) { 56 | if (!(player instanceof ServerPlayerEntity)) { 57 | // Cannot open containers on the client or for non-players 58 | return false; 59 | } 60 | 61 | if (!locator.hasItemIndex()) { 62 | return false; 63 | } 64 | 65 | opener.open(player, locator); 66 | return true; 67 | } 68 | } 69 | 70 | @FunctionalInterface 71 | public interface UncheckedOpener { 72 | void open(PlayerEntity player, ContainerLocator locator); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/init/ModItems.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.init; 2 | 3 | import appeng.core.AEConfig; 4 | import net.minecraft.item.Item; 5 | import tfar.ae2wt.AE2WirelessTerminals; 6 | import tfar.ae2wt.terminal.ItemInfinityBooster; 7 | import tfar.ae2wt.wirelesscraftingterminal.WCTItem; 8 | import tfar.ae2wt.wirelesscraftingterminal.magnet_card.ItemMagnetCard; 9 | import tfar.ae2wt.wirelessfluidterminal.WirelessFluidTerminalItem; 10 | import tfar.ae2wt.wirelessinterfaceterminal.WITItem; 11 | import tfar.ae2wt.wpt.WPTItem; 12 | import tfar.ae2wt.wut.WUTItem; 13 | 14 | public class ModItems { 15 | public static final WCTItem CRAFTING_TERMINAL = new WCTItem(); 16 | public static final WPTItem PATTERN_TERMINAL = new WPTItem(); 17 | public static final WITItem INTERFACE_TERMINAL = new WITItem(); 18 | public static final WUTItem UNIVERSAL_TERMINAL = new WUTItem(); 19 | public static final WirelessFluidTerminalItem WIRELESS_FLUID_TERMINAL = new WirelessFluidTerminalItem(AEConfig.instance().getWirelessTerminalBattery(), 20 | new Item.Properties().group(AE2WirelessTerminals.ITEM_GROUP).maxStackSize(1)); 21 | public static final ItemInfinityBooster INFINITY_BOOSTER_CARD = new ItemInfinityBooster(); 22 | public static final ItemMagnetCard MAGNET_CARD = new ItemMagnetCard(new Item.Properties().group(AE2WirelessTerminals.ITEM_GROUP).maxStackSize(1)); 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/jei/CraftingRecipeTransferHandler.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.jei; 2 | 3 | import appeng.api.storage.data.IAEItemStack; 4 | import appeng.util.item.AEItemStack; 5 | import com.mojang.blaze3d.matrix.MatrixStack; 6 | import mezz.jei.api.gui.IRecipeLayout; 7 | import mezz.jei.api.gui.ingredient.IGuiIngredient; 8 | import mezz.jei.api.recipe.transfer.IRecipeTransferError; 9 | import mezz.jei.api.recipe.transfer.IRecipeTransferHandlerHelper; 10 | import net.minecraft.entity.player.PlayerEntity; 11 | import net.minecraft.item.ItemStack; 12 | import net.minecraft.item.crafting.IRecipe; 13 | import net.minecraft.util.text.ITextComponent; 14 | import net.minecraft.util.text.TranslationTextComponent; 15 | import tfar.ae2wt.wirelesscraftingterminal.WirelessCraftingTerminalContainer; 16 | 17 | import java.util.ArrayList; 18 | import java.util.HashMap; 19 | import java.util.List; 20 | import java.util.Map; 21 | 22 | public class CraftingRecipeTransferHandler extends RecipeTransferHandler { 23 | CraftingRecipeTransferHandler(Class containerClass, IRecipeTransferHandlerHelper helper) { 24 | super(containerClass, helper); 25 | } 26 | 27 | @Override 28 | protected IRecipeTransferError doTransferRecipe(WirelessCraftingTerminalContainer container, IRecipe recipe, IRecipeLayout recipeLayout, PlayerEntity player, boolean maxTransfer) { 29 | // Try to figure out if any slots have missing ingredients 30 | // Find every "slot" (in JEI parlance) that has no equivalent item in the item repo or player inventory 31 | List missingSlots = new ArrayList<>(); 32 | 33 | // We need to track how many of a given item stack we've already used for other slots in the recipe. 34 | // Otherwise recipes that need 4x will not correctly show missing items if at least 1 of is in 35 | // the grid. 36 | Map reservedGridAmounts = new HashMap<>(); 37 | 38 | for (Map.Entry> entry : recipeLayout.getItemStacks() 39 | .getGuiIngredients().entrySet()) { 40 | IGuiIngredient ingredient = entry.getValue(); 41 | List ingredients = ingredient.getAllIngredients(); 42 | if (!ingredient.isInput() || ingredients.isEmpty()) { 43 | continue; 44 | } 45 | boolean found = false; 46 | // Player inventory is cheaper to check 47 | for (ItemStack itemStack : ingredients) { 48 | if (itemStack != null && player.inventory.getSlotFor(itemStack) != -1) { 49 | found = true; 50 | break; 51 | } 52 | } 53 | // Then check the terminal screen's repository of network items 54 | if (!found) { 55 | for (ItemStack itemStack : ingredients) { 56 | if (itemStack != null) { 57 | // We use AE stacks to get an easily comparable item type key that ignores stack size 58 | IAEItemStack aeStack = AEItemStack.fromItemStack(itemStack); 59 | int reservedAmount = reservedGridAmounts.getOrDefault(aeStack, 0) + 1; 60 | if (container.hasItemType(itemStack, reservedAmount)) { 61 | reservedGridAmounts.put(aeStack, reservedAmount); 62 | found = true; 63 | break; 64 | } 65 | } 66 | } 67 | } 68 | 69 | if (!found) { 70 | missingSlots.add(entry.getKey()); 71 | } 72 | } 73 | 74 | if (!missingSlots.isEmpty()) { 75 | ITextComponent message = new TranslationTextComponent("jei.appliedenergistics2.missing_items"); 76 | return new TransferWarning(helper.createUserErrorForSlots(message, missingSlots)); 77 | } 78 | 79 | return null; 80 | } 81 | 82 | protected boolean isCrafting() { 83 | return true; 84 | } 85 | 86 | private static class TransferWarning implements IRecipeTransferError { 87 | 88 | private final IRecipeTransferError parent; 89 | 90 | public TransferWarning(IRecipeTransferError parent) { 91 | this.parent = parent; 92 | } 93 | 94 | @Override 95 | public Type getType() { 96 | return Type.COSMETIC; 97 | } 98 | 99 | @Override 100 | public void showError(MatrixStack matrixStack, int mouseX, int mouseY, IRecipeLayout recipeLayout, int recipeX, 101 | int recipeY) { 102 | this.parent.showError(matrixStack, mouseX, mouseY, recipeLayout, recipeX, recipeY); 103 | } 104 | 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/jei/JeiPlug.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.jei; 2 | 3 | import mezz.jei.api.IModPlugin; 4 | import mezz.jei.api.JeiPlugin; 5 | import mezz.jei.api.recipe.transfer.IRecipeTransferHandler; 6 | import mezz.jei.api.registration.IRecipeTransferRegistration; 7 | import net.minecraft.util.ResourceLocation; 8 | import tfar.ae2wt.AE2WirelessTerminals; 9 | import tfar.ae2wt.wirelesscraftingterminal.WirelessCraftingTerminalContainer; 10 | import tfar.ae2wt.wpt.WirelessPatternTerminalContainer; 11 | 12 | @JeiPlugin 13 | public class JeiPlug implements IModPlugin { 14 | 15 | public static final ResourceLocation UNIVERSAL_RECIPE_TRANSFER_UID = new ResourceLocation("jei", "universal_recipe_transfer_handler"); 16 | public static final ResourceLocation CRAFTING = new ResourceLocation("minecraft", "crafting"); 17 | 18 | 19 | @Override 20 | public ResourceLocation getPluginUid() { 21 | return new ResourceLocation(AE2WirelessTerminals.MODID, AE2WirelessTerminals.MODID); 22 | } 23 | 24 | @Override 25 | public void registerRecipeTransferHandlers(IRecipeTransferRegistration registration) { 26 | registration.addRecipeTransferHandler(new CraftingRecipeTransferHandler(WirelessCraftingTerminalContainer.class, registration.getTransferHelper()), this.CRAFTING); 27 | registration.addUniversalRecipeTransferHandler(new PatternRecipeTransferHandler(WirelessPatternTerminalContainer.class, registration.getTransferHelper())); 28 | } 29 | 30 | public static class RecipeTransferHandler implements IRecipeTransferHandler { 31 | @Override 32 | public Class getContainerClass() { 33 | return WirelessCraftingTerminalContainer.class; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/jei/PatternRecipeTransferHandler.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.jei; 2 | 3 | import mezz.jei.api.constants.VanillaRecipeCategoryUid; 4 | import mezz.jei.api.gui.IRecipeLayout; 5 | import mezz.jei.api.recipe.transfer.IRecipeTransferError; 6 | import mezz.jei.api.recipe.transfer.IRecipeTransferHandlerHelper; 7 | import net.minecraft.client.resources.I18n; 8 | import net.minecraft.entity.player.PlayerEntity; 9 | import net.minecraft.item.crafting.IRecipe; 10 | import tfar.ae2wt.wpt.WirelessPatternTerminalContainer; 11 | 12 | public class PatternRecipeTransferHandler extends RecipeTransferHandler { 13 | PatternRecipeTransferHandler(Class containerClass, IRecipeTransferHandlerHelper helper) { 14 | super(containerClass, helper); 15 | } 16 | 17 | @Override 18 | protected IRecipeTransferError doTransferRecipe(WirelessPatternTerminalContainer container, IRecipe recipe, IRecipeLayout recipeLayout, PlayerEntity player, boolean maxTransfer) { 19 | if (container.isCraftingMode() && recipeLayout.getRecipeCategory().getUid() != VanillaRecipeCategoryUid.CRAFTING) { 20 | return this.helper.createUserErrorWithTooltip(I18n.format("jei.appliedenergistics2.requires_processing_mode")); 21 | } else { 22 | return recipe.getRecipeOutput().isEmpty() ? this.helper.createUserErrorWithTooltip(I18n.format("jei.appliedenergistics2.no_output")) : null; 23 | } 24 | } 25 | 26 | protected boolean isCrafting() { 27 | return false; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/mixin/AEBaseContainerAccess.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.mixin; 2 | 3 | import appeng.api.networking.security.IActionHost; 4 | import appeng.container.AEBaseContainer; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.gen.Invoker; 7 | 8 | @Mixin(value = AEBaseContainer.class,remap = false) 9 | public interface AEBaseContainerAccess { 10 | @Invoker("getActionHost") 11 | IActionHost invokeGetActionHost(); 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/mixin/AESubScreenMixin.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.mixin; 2 | 3 | import appeng.client.gui.implementations.AESubScreen; 4 | import net.minecraft.inventory.container.ContainerType; 5 | import net.minecraft.item.ItemStack; 6 | import org.spongepowered.asm.mixin.Final; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.Mutable; 9 | import org.spongepowered.asm.mixin.Shadow; 10 | import org.spongepowered.asm.mixin.injection.At; 11 | import org.spongepowered.asm.mixin.injection.Inject; 12 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 13 | import tfar.ae2wt.terminal.WTGuiObject; 14 | 15 | @Mixin(value = AESubScreen.class, remap = false) 16 | public class AESubScreenMixin { 17 | 18 | @Mutable 19 | @Shadow 20 | @Final 21 | private ContainerType previousContainerType; 22 | 23 | @Mutable 24 | @Shadow 25 | @Final 26 | private ItemStack previousContainerIcon; 27 | 28 | @Inject(method = "(Ljava/lang/Object;)V", at = @At(value = "TAIL")) 29 | public void serverPacketData(Object containerHost, CallbackInfo ci) { 30 | if (containerHost instanceof WTGuiObject) { 31 | previousContainerType = ((WTGuiObject) containerHost).getType(); 32 | previousContainerIcon = ((WTGuiObject) containerHost).getItemStack(); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/mixin/ContainerAccess.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.mixin; 2 | 3 | import net.minecraft.inventory.container.Container; 4 | import net.minecraft.inventory.container.IContainerListener; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.gen.Accessor; 7 | 8 | import java.util.List; 9 | 10 | @Mixin(Container.class) 11 | public interface ContainerAccess { 12 | @Accessor 13 | List getListeners(); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/mixin/ContainerTypeBuilderMixin.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.mixin; 2 | 3 | import appeng.container.ContainerLocator; 4 | import appeng.container.implementations.ContainerTypeBuilder; 5 | import net.minecraft.entity.player.PlayerEntity; 6 | import net.minecraft.item.ItemStack; 7 | import org.spongepowered.asm.mixin.Final; 8 | import org.spongepowered.asm.mixin.Mixin; 9 | import org.spongepowered.asm.mixin.Shadow; 10 | import org.spongepowered.asm.mixin.injection.At; 11 | import org.spongepowered.asm.mixin.injection.Inject; 12 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 13 | import tfar.ae2wt.terminal.AbstractWirelessTerminalItem; 14 | import tfar.ae2wt.wirelesscraftingterminal.WCTGuiObject; 15 | import tfar.ae2wt.wirelesscraftingterminal.WCTItem; 16 | import tfar.ae2wt.wirelessinterfaceterminal.WITGuiObject; 17 | import tfar.ae2wt.wirelessinterfaceterminal.WITItem; 18 | import tfar.ae2wt.wpt.WPTGuiObject; 19 | import tfar.ae2wt.wpt.WPTItem; 20 | 21 | @Mixin(value = ContainerTypeBuilder.class, remap = false) 22 | public class ContainerTypeBuilderMixin { 23 | @Shadow 24 | @Final 25 | private Class hostInterface; 26 | 27 | @Inject(method = "getHostFromPlayerInventory", at = @At(value = "HEAD"), cancellable = true) 28 | private void getWirelessHostFromPlayerInventory(PlayerEntity player, ContainerLocator locator, CallbackInfoReturnable cir) { 29 | ItemStack it = player.inventory.getStackInSlot(locator.getItemIndex()); 30 | 31 | if (it.isEmpty()) { 32 | return; 33 | } 34 | 35 | // FIXME: this shouldn't be hardcoded 36 | if (it.getItem() instanceof AbstractWirelessTerminalItem) { 37 | AbstractWirelessTerminalItem awti = (AbstractWirelessTerminalItem)it.getItem(); 38 | if (awti instanceof WCTItem) { 39 | cir.setReturnValue(hostInterface.cast(new WCTGuiObject(awti, it, player, locator.getItemIndex()))); 40 | } else if (awti instanceof WPTItem) { 41 | cir.setReturnValue(hostInterface.cast(new WPTGuiObject(awti, it, player, locator.getItemIndex()))); 42 | } else if (awti instanceof WITItem) { 43 | cir.setReturnValue(hostInterface.cast(new WITGuiObject(awti, it, player, locator.getItemIndex()))); 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/mixin/CraftConfirmContainerMixin.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.mixin; 2 | 3 | import appeng.api.networking.IGrid; 4 | import appeng.api.networking.crafting.ICraftingCPU; 5 | import appeng.api.networking.crafting.ICraftingGrid; 6 | import appeng.api.networking.crafting.ICraftingJob; 7 | import appeng.api.networking.crafting.ICraftingLink; 8 | import appeng.api.networking.security.IActionHost; 9 | import appeng.api.networking.security.IActionSource; 10 | import appeng.container.AEBaseContainer; 11 | import appeng.container.ContainerOpener; 12 | import appeng.container.me.crafting.CraftConfirmContainer; 13 | import net.minecraft.inventory.container.ContainerType; 14 | import org.spongepowered.asm.mixin.Mixin; 15 | import org.spongepowered.asm.mixin.Shadow; 16 | import org.spongepowered.asm.mixin.injection.At; 17 | import org.spongepowered.asm.mixin.injection.Inject; 18 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 19 | import tfar.ae2wt.init.Menus; 20 | import tfar.ae2wt.wirelesscraftingterminal.WCTGuiObject; 21 | 22 | @Mixin(value = CraftConfirmContainer.class,remap = false) 23 | abstract class CraftConfirmContainerMixin { 24 | 25 | @Shadow 26 | private ICraftingCPU selectedCpu; 27 | @Shadow 28 | private ICraftingJob result; 29 | 30 | @Shadow 31 | protected abstract IGrid getGrid(); 32 | 33 | @Shadow 34 | protected abstract IActionSource getActionSrc(); 35 | 36 | @Shadow 37 | public abstract void setAutoStart(boolean autoStart); 38 | 39 | @Inject(method = "startJob", at = @At(value = "HEAD"), cancellable = true) 40 | public void serverPacketData(CallbackInfo ci) { 41 | IActionHost ah = ((AEBaseContainerAccess) this).invokeGetActionHost(); 42 | if(ah instanceof WCTGuiObject) { 43 | ContainerType originalGui = Menus.WCT; 44 | if(result == null || result.isSimulation()) return; 45 | ICraftingLink g = ((ICraftingGrid) getGrid().getCache(ICraftingGrid.class)).submitJob(result, null, selectedCpu, true, getActionSrc()); 46 | setAutoStart(false); 47 | if(g != null && originalGui != null && ((AEBaseContainer) (Object) this).getLocator() != null) 48 | ContainerOpener.openContainer(originalGui, ((AEBaseContainer) (Object) this).getPlayerInventory().player, ((AEBaseContainer) (Object) this).getLocator()); 49 | ci.cancel(); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/mixin/InvActionPacketMixin.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.mixin; 2 | 3 | import appeng.core.sync.network.INetworkInfo; 4 | import appeng.core.sync.packets.InventoryActionPacket; 5 | import appeng.helpers.InventoryAction; 6 | import net.minecraft.entity.player.PlayerEntity; 7 | import org.spongepowered.asm.mixin.Final; 8 | import org.spongepowered.asm.mixin.Mixin; 9 | import org.spongepowered.asm.mixin.Shadow; 10 | import org.spongepowered.asm.mixin.injection.At; 11 | import org.spongepowered.asm.mixin.injection.Inject; 12 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 13 | 14 | @Mixin(value = InventoryActionPacket.class,remap = false) 15 | public class InvActionPacketMixin { 16 | 17 | @Shadow 18 | @Final 19 | private InventoryAction action; 20 | 21 | @Inject(method = "serverPacketData", at = @At(value = "TAIL"), require = 1, allow = 1, remap = false) 22 | public void serverPacketData(INetworkInfo manager, PlayerEntity player, CallbackInfo ci) { 23 | if(action == InventoryAction.AUTO_CRAFT) { 24 | /* final ServerPlayerEntity sender = (ServerPlayerEntity) player; 25 | if(sender.openContainer instanceof WirelessCraftingTerminalContainer || sender.openContainer instanceof WirelessPatternTerminalContainer) { 26 | final AEBaseContainer baseContainer = (AEBaseContainer) sender.openContainer; 27 | final ContainerLocator locator = baseContainer.getLocator(); 28 | if(locator != null) { 29 | WirelessCraftAmountContainer.openServer(player, locator); 30 | 31 | if(sender.openContainer instanceof WirelessCraftAmountContainer) { 32 | final WirelessCraftAmountContainer cca = (WirelessCraftAmountContainer) sender.openContainer; 33 | 34 | if(baseContainer.getTargetStack() != null) { 35 | cca.getCraftingItem().putStack(baseContainer.getTargetStack().asItemStackRepresentation()); 36 | // This is the *actual* item that matters, not the display item above 37 | cca.setItemToCraft(baseContainer.getTargetStack()); 38 | } 39 | cca.detectAndSendChanges(); 40 | } 41 | } 42 | }*/ 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/mixin/MeMonitorableScreenWireless.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.mixin; 2 | 3 | import appeng.client.gui.me.common.MEMonitorableScreen; 4 | import tfar.ae2wt.init.Menus; 5 | import net.minecraft.util.registry.Registry; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | import org.spongepowered.asm.mixin.injection.Inject; 9 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 10 | import tfar.ae2wt.net.C2SSwitchGuiPacket; 11 | import tfar.ae2wt.net.PacketHandler; 12 | import tfar.ae2wt.wirelesscraftingterminal.WirelessCraftingTerminalScreen; 13 | import tfar.ae2wt.wpt.WirelessPatternTerminalScreen; 14 | 15 | @Mixin(MEMonitorableScreen.class) 16 | public class MeMonitorableScreenWireless { 17 | 18 | @Inject(method = "showCraftingStatus", at = @At(value = "HEAD"), remap = false, cancellable = true) 19 | private void showWirelessCraftingStatus(CallbackInfo ci) { 20 | if(!((Object) this instanceof WirelessCraftingTerminalScreen) && !((Object) this instanceof WirelessPatternTerminalScreen)) return; 21 | PacketHandler.INSTANCE.sendToServer(new C2SSwitchGuiPacket(Registry.MENU.getKey(Menus.WIRELESS_FLUID_TERMINAL).getPath())); 22 | ci.cancel(); 23 | } 24 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/mixin/PlayerInventoryMixin.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.mixin; 2 | 3 | import appeng.api.config.Actionable; 4 | import appeng.api.features.ILocatable; 5 | import appeng.api.networking.IGrid; 6 | import appeng.api.networking.security.IActionHost; 7 | import appeng.api.networking.storage.IStorageGrid; 8 | import appeng.api.storage.IMEMonitor; 9 | import appeng.api.storage.channels.IItemStorageChannel; 10 | import appeng.api.storage.data.IAEItemStack; 11 | import appeng.core.Api; 12 | import appeng.me.helpers.PlayerSource; 13 | import appeng.util.item.AEItemStack; 14 | import tfar.ae2wt.wirelesscraftingterminal.CraftingTerminalHandler; 15 | import tfar.ae2wt.wirelesscraftingterminal.magnet_card.ItemMagnetCard; 16 | import net.minecraft.entity.player.PlayerEntity; 17 | import net.minecraft.entity.player.PlayerInventory; 18 | import net.minecraft.item.ItemStack; 19 | import org.spongepowered.asm.mixin.Final; 20 | import org.spongepowered.asm.mixin.Mixin; 21 | import org.spongepowered.asm.mixin.Shadow; 22 | import org.spongepowered.asm.mixin.injection.At; 23 | import org.spongepowered.asm.mixin.injection.Inject; 24 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 25 | 26 | @Mixin(PlayerInventory.class) 27 | public class PlayerInventoryMixin { 28 | 29 | @Shadow 30 | @Final 31 | public PlayerEntity player; 32 | 33 | @Inject(method = "addItemStackToInventory(Lnet/minecraft/item/ItemStack;)Z", at = @At(value = "INVOKE"), require = 1, allow = 1) 34 | public void insertStackInME(ItemStack stack, CallbackInfoReturnable cir) { 35 | if(stack.isEmpty()) return; 36 | CraftingTerminalHandler CTHandler = CraftingTerminalHandler.getCraftingTerminalHandler(player); 37 | ItemStack terminal = CTHandler.getCraftingTerminal(); 38 | if(ItemMagnetCard.isPickupME(terminal) && CTHandler.inRange()) { 39 | final ILocatable securityStation = CTHandler.getSecurityStation(); 40 | if(securityStation == null) return; 41 | IGrid targetGrid = CTHandler.getTargetGrid(); 42 | IStorageGrid sg = targetGrid.getCache(IStorageGrid.class); 43 | IMEMonitor itemStorage = sg.getInventory(Api.instance().storage().getStorageChannel(IItemStorageChannel.class)); 44 | IAEItemStack leftover = itemStorage.injectItems(AEItemStack.fromItemStack(stack), Actionable.MODULATE, new PlayerSource(player, (IActionHost) securityStation)); 45 | 46 | if(leftover == null || leftover.createItemStack().isEmpty()) stack.setCount(0); 47 | else stack.setCount(leftover.createItemStack().getCount()); 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/net/C2SCycleTerminalPacket.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.net; 2 | 3 | import appeng.container.AEBaseContainer; 4 | import appeng.container.ContainerLocator; 5 | import net.minecraft.entity.player.PlayerEntity; 6 | import net.minecraft.inventory.container.Container; 7 | import net.minecraft.item.ItemStack; 8 | import net.minecraft.network.PacketBuffer; 9 | import net.minecraftforge.fml.network.NetworkEvent; 10 | import tfar.ae2wt.wut.WUTItem; 11 | import tfar.ae2wt.wut.WUTHandler; 12 | 13 | import java.util.function.Supplier; 14 | 15 | public class C2SCycleTerminalPacket { 16 | 17 | public void encode(PacketBuffer buf) { 18 | 19 | } 20 | 21 | public void handle(Supplier ctx) { 22 | PlayerEntity player = ctx.get().getSender(); 23 | 24 | if (player == null) return; 25 | 26 | ctx.get().enqueueWork( ()-> { 27 | final Container screenHandler = player.openContainer; 28 | 29 | if(!(screenHandler instanceof AEBaseContainer)) return; 30 | 31 | final AEBaseContainer container = (AEBaseContainer) screenHandler; 32 | final ContainerLocator locator = container.getLocator(); 33 | ItemStack item = player.inventory.getStackInSlot(locator.getItemIndex()); 34 | 35 | if(!(item.getItem() instanceof WUTItem)) return; 36 | WUTHandler.cycle(item); 37 | 38 | WUTHandler.open(player, locator); 39 | }); 40 | ctx.get().setPacketHandled(true); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/net/C2SHotkeyPacket.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.net; 2 | 3 | import appeng.container.ContainerLocator; 4 | import net.minecraft.entity.player.PlayerEntity; 5 | import net.minecraft.entity.player.PlayerInventory; 6 | import net.minecraft.item.ItemStack; 7 | import net.minecraft.network.PacketBuffer; 8 | import net.minecraft.server.MinecraftServer; 9 | import net.minecraftforge.fml.network.NetworkEvent; 10 | import tfar.ae2wt.init.ModItems; 11 | import tfar.ae2wt.util.ContainerHelper; 12 | import tfar.ae2wt.wirelesscraftingterminal.WCTItem; 13 | import tfar.ae2wt.wirelessinterfaceterminal.WITItem; 14 | import tfar.ae2wt.wpt.WPTItem; 15 | import tfar.ae2wt.wut.WUTItem; 16 | import tfar.ae2wt.wut.WUTHandler; 17 | 18 | import java.util.function.Supplier; 19 | 20 | public class C2SHotkeyPacket { 21 | 22 | private String terminalName; 23 | 24 | public C2SHotkeyPacket(String terminalName) { 25 | this.terminalName = terminalName; 26 | } 27 | 28 | public C2SHotkeyPacket(PacketBuffer buf) { 29 | terminalName = buf.readString(32767); 30 | } 31 | 32 | public void encode(PacketBuffer buf) { 33 | buf.writeString(terminalName); 34 | } 35 | 36 | public void handle(Supplier ctx) { 37 | PlayerEntity player = ctx.get().getSender(); 38 | 39 | if (player == null) return; 40 | 41 | ctx.get().enqueueWork( ()-> { 42 | MinecraftServer server = player.getServer(); 43 | server.execute(() -> { 44 | if (terminalName.equalsIgnoreCase("crafting")) { 45 | PlayerInventory inv = player.inventory; 46 | int slot = -1; 47 | for (int i = 0; i < inv.getSizeInventory(); i++) { 48 | ItemStack terminal = inv.getStackInSlot(i); 49 | if (terminal.getItem() instanceof WCTItem || (terminal.getItem() instanceof WUTItem && WUTHandler.hasTerminal(terminal, "crafting"))) { 50 | slot = i; 51 | break; 52 | } 53 | } 54 | if (slot == -1) return; 55 | ContainerLocator locator = ContainerHelper.getContainerLocatorForSlot(slot); 56 | ModItems.CRAFTING_TERMINAL.open(player, locator); 57 | } else if (terminalName.equalsIgnoreCase("pattern")) { 58 | PlayerInventory inv = player.inventory; 59 | int slot = -1; 60 | for (int i = 0; i < inv.getSizeInventory(); i++) { 61 | ItemStack terminal = inv.getStackInSlot(i); 62 | if (terminal.getItem() instanceof WPTItem || (terminal.getItem() instanceof WUTItem && WUTHandler.hasTerminal(terminal, "pattern"))) { 63 | slot = i; 64 | break; 65 | } 66 | } 67 | if (slot == -1) return; 68 | ContainerLocator locator = ContainerHelper.getContainerLocatorForSlot(slot); 69 | ModItems.PATTERN_TERMINAL.open(player, locator); 70 | } else if (terminalName.equalsIgnoreCase("interface")) { 71 | PlayerInventory inv = player.inventory; 72 | int slot = -1; 73 | for (int i = 0; i < inv.getSizeInventory(); i++) { 74 | ItemStack terminal = inv.getStackInSlot(i); 75 | if (terminal.getItem() instanceof WITItem || (terminal.getItem() instanceof WUTItem && WUTHandler.hasTerminal(terminal, "interface"))) { 76 | slot = i; 77 | break; 78 | } 79 | } 80 | if (slot == -1) return; 81 | ContainerLocator locator = ContainerHelper.getContainerLocatorForSlot(slot); 82 | ModItems.INTERFACE_TERMINAL.open(player, locator); 83 | } 84 | }); 85 | }); 86 | ctx.get().setPacketHandled(true); 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/net/C2SPatternSlotPacket.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.net; 2 | 3 | import appeng.api.storage.data.IAEItemStack; 4 | import appeng.util.item.AEItemStack; 5 | import net.minecraft.entity.player.PlayerEntity; 6 | import net.minecraft.network.PacketBuffer; 7 | import net.minecraft.server.MinecraftServer; 8 | import net.minecraftforge.fml.network.NetworkEvent; 9 | import tfar.ae2wt.wpt.WirelessPatternTerminalContainer; 10 | 11 | import java.util.function.Supplier; 12 | 13 | public class C2SPatternSlotPacket { 14 | 15 | IAEItemStack slotItem; 16 | boolean shift; 17 | IAEItemStack[] pattern = new IAEItemStack[9]; 18 | 19 | public C2SPatternSlotPacket(IAEItemStack slotItem, boolean shift, IAEItemStack[] pattern) { 20 | this.slotItem = slotItem; 21 | this.shift = shift; 22 | this.pattern = pattern; 23 | } 24 | 25 | public C2SPatternSlotPacket(PacketBuffer buf) { 26 | slotItem = AEItemStack.fromPacket(buf); 27 | shift = buf.readBoolean(); 28 | for (int i = 0; i < 9;i++) { 29 | pattern[i] = AEItemStack.fromPacket(buf); 30 | } 31 | } 32 | 33 | public void encode(PacketBuffer buf) { 34 | slotItem.writeToPacket(buf); 35 | buf.writeBoolean(shift); 36 | for (int i = 0;i < 9;i++) { 37 | pattern[i].writeToPacket(buf); 38 | } 39 | } 40 | 41 | public void handle(Supplier ctx) { 42 | PlayerEntity player = ctx.get().getSender(); 43 | 44 | if (player == null) return; 45 | 46 | ctx.get().enqueueWork( ()-> { 47 | MinecraftServer server = player.getServer(); 48 | server.execute(() -> { 49 | if(player.openContainer instanceof WirelessPatternTerminalContainer) { 50 | final WirelessPatternTerminalContainer patternTerminal = (WirelessPatternTerminalContainer) player.openContainer; 51 | patternTerminal.craftOrGetItem(slotItem,shift,pattern); 52 | } 53 | }); 54 | }); 55 | ctx.get().setPacketHandled(true); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/net/C2SSwitchGuiPacket.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.net; 2 | 3 | import appeng.container.AEBaseContainer; 4 | import appeng.container.ContainerLocator; 5 | import net.minecraft.entity.player.PlayerEntity; 6 | import net.minecraft.inventory.container.Container; 7 | import net.minecraft.network.PacketBuffer; 8 | import net.minecraft.server.MinecraftServer; 9 | import net.minecraftforge.fml.network.NetworkEvent; 10 | import tfar.ae2wt.wirelesscraftingterminal.WirelessCraftingTerminalContainer; 11 | import tfar.ae2wt.wirelessinterfaceterminal.WirelessInterfaceTerminalContainer; 12 | import tfar.ae2wt.wpt.WirelessPatternTerminalContainer; 13 | 14 | import java.util.function.Supplier; 15 | 16 | public class C2SSwitchGuiPacket { 17 | 18 | private String id; 19 | 20 | public C2SSwitchGuiPacket(String id) { 21 | this.id = id; 22 | } 23 | 24 | public C2SSwitchGuiPacket(PacketBuffer buf) { 25 | id = buf.readString(32767); 26 | } 27 | 28 | public void encode(PacketBuffer buf) { 29 | buf.writeString(id); 30 | } 31 | 32 | public void handle(Supplier ctx) { 33 | PlayerEntity player = ctx.get().getSender(); 34 | 35 | if (player == null) return; 36 | 37 | ctx.get().enqueueWork( ()-> { 38 | MinecraftServer server = player.getServer(); 39 | server.execute(() -> { 40 | final Container c = player.openContainer; 41 | if(!(c instanceof AEBaseContainer)) { 42 | return; 43 | } 44 | AEBaseContainer container = (AEBaseContainer) c; 45 | final ContainerLocator locator = container.getLocator(); 46 | if(locator == null) { 47 | return; 48 | } 49 | switch(id) { 50 | case "wireless_crafting_terminal": 51 | WirelessCraftingTerminalContainer.openServer(player, locator); 52 | break; 53 | case "wireless_pattern_terminal": 54 | WirelessPatternTerminalContainer.openServer(player, locator); 55 | break; 56 | case "wireless_interface_terminal": 57 | WirelessInterfaceTerminalContainer.openServer(player, locator); 58 | break; 59 | } 60 | }); 61 | }); 62 | ctx.get().setPacketHandled(true); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/net/PacketHandler.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.net; 2 | 3 | import tfar.ae2wt.AE2WirelessTerminals; 4 | import net.minecraft.util.ResourceLocation; 5 | import net.minecraftforge.fml.network.NetworkRegistry; 6 | import net.minecraftforge.fml.network.simple.SimpleChannel; 7 | import tfar.ae2wt.net.client.S2CInterfaceTerminalPacket; 8 | import tfar.ae2wt.net.server.*; 9 | 10 | public class PacketHandler { 11 | 12 | public static SimpleChannel INSTANCE; 13 | static int i = 0; 14 | 15 | public static void registerPackets() { 16 | INSTANCE = NetworkRegistry.newSimpleChannel(new ResourceLocation(AE2WirelessTerminals.MODID, AE2WirelessTerminals.MODID), () -> "1.0", s -> true, s -> true); 17 | 18 | INSTANCE.registerMessage(i++, C2SCycleTerminalPacket.class, 19 | (message, buffer) -> {}, 20 | buffer -> new C2SCycleTerminalPacket(), 21 | C2SCycleTerminalPacket::handle); 22 | 23 | INSTANCE.registerMessage(i++, C2SDeleteTrashPacket.class, 24 | C2SDeleteTrashPacket::encode, 25 | C2SDeleteTrashPacket::new, 26 | C2SDeleteTrashPacket::handle); 27 | 28 | INSTANCE.registerMessage(i++, C2SEncodePatternPacket.class, 29 | C2SEncodePatternPacket::encode, 30 | C2SEncodePatternPacket::new, 31 | C2SEncodePatternPacket::handle); 32 | 33 | INSTANCE.registerMessage(i++, C2SClearPatternPacket.class, 34 | C2SClearPatternPacket::encode, 35 | C2SClearPatternPacket::new, 36 | C2SClearPatternPacket::handle); 37 | 38 | INSTANCE.registerMessage(i++, C2STogglePatternSubsitutionPacket.class, 39 | C2STogglePatternSubsitutionPacket::encode, 40 | C2STogglePatternSubsitutionPacket::new, 41 | C2STogglePatternSubsitutionPacket::handle); 42 | 43 | INSTANCE.registerMessage(i++, C2STogglePatternCraftingModePacket.class, 44 | C2STogglePatternCraftingModePacket::encode, 45 | C2STogglePatternCraftingModePacket::new, 46 | C2STogglePatternCraftingModePacket::handle); 47 | 48 | INSTANCE.registerMessage(i++, C2SSwitchGuiPacket.class, 49 | C2SSwitchGuiPacket::encode, 50 | C2SSwitchGuiPacket::new, 51 | C2SSwitchGuiPacket::handle); 52 | 53 | INSTANCE.registerMessage(i++, C2SSetMagnetModePacket.class, 54 | C2SSetMagnetModePacket::encode, 55 | C2SSetMagnetModePacket::new, 56 | C2SSetMagnetModePacket::handle); 57 | 58 | INSTANCE.registerMessage(i++, S2CInterfaceTerminalPacket.class, 59 | S2CInterfaceTerminalPacket::encode, 60 | S2CInterfaceTerminalPacket::new, 61 | S2CInterfaceTerminalPacket::handle); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/net/client/S2CInterfaceTerminalPacket.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.net.client; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import net.minecraft.client.gui.screen.Screen; 5 | import net.minecraft.nbt.CompoundNBT; 6 | import net.minecraft.network.PacketBuffer; 7 | import net.minecraftforge.fml.network.NetworkEvent; 8 | import tfar.ae2wt.wirelessinterfaceterminal.WITScreen; 9 | 10 | import java.util.function.Supplier; 11 | 12 | public class S2CInterfaceTerminalPacket { 13 | 14 | private CompoundNBT nbt; 15 | 16 | public S2CInterfaceTerminalPacket(CompoundNBT nbt) { 17 | this.nbt = nbt; 18 | } 19 | 20 | public S2CInterfaceTerminalPacket(PacketBuffer buf) { 21 | nbt = buf.readCompoundTag(); 22 | } 23 | 24 | public void encode(PacketBuffer buf) { 25 | buf.writeCompoundTag(nbt); 26 | } 27 | 28 | public void handle(Supplier ctx) { 29 | ctx.get().enqueueWork(() -> { 30 | if (Minecraft.getInstance().player == null) return; 31 | 32 | final Screen screen = Minecraft.getInstance().currentScreen; 33 | if (screen instanceof WITScreen) { 34 | WITScreen s = (WITScreen) screen; 35 | if (nbt != null) s.postUpdate(true,nbt); 36 | } 37 | }); 38 | ctx.get().setPacketHandled(true); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/net/server/C2SClearPatternPacket.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.net.server; 2 | 3 | import net.minecraft.entity.player.PlayerEntity; 4 | import net.minecraft.inventory.container.Container; 5 | import net.minecraft.network.PacketBuffer; 6 | import net.minecraft.server.MinecraftServer; 7 | import net.minecraftforge.fml.network.NetworkEvent; 8 | import tfar.ae2wt.wpt.WirelessPatternTerminalContainer; 9 | 10 | import java.util.function.Supplier; 11 | 12 | public class C2SClearPatternPacket { 13 | 14 | public C2SClearPatternPacket() { 15 | } 16 | 17 | public C2SClearPatternPacket(PacketBuffer buf) { 18 | } 19 | 20 | public void encode(PacketBuffer buf) { 21 | } 22 | 23 | public void handle(Supplier ctx) { 24 | PlayerEntity player = ctx.get().getSender(); 25 | if (player == null) return; 26 | ctx.get().enqueueWork(() -> run(player)); 27 | ctx.get().setPacketHandled(true); 28 | } 29 | 30 | public void run(PlayerEntity player) { 31 | MinecraftServer server = player.getServer(); 32 | server.execute(() -> { 33 | final Container c = player.openContainer; 34 | if (c instanceof WirelessPatternTerminalContainer) { 35 | final WirelessPatternTerminalContainer container = (WirelessPatternTerminalContainer) c; 36 | container.clearPattern(); 37 | } 38 | }); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/net/server/C2SDeleteTrashPacket.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.net.server; 2 | 3 | import net.minecraft.entity.player.PlayerEntity; 4 | import net.minecraft.inventory.container.Container; 5 | import net.minecraft.network.PacketBuffer; 6 | import net.minecraft.server.MinecraftServer; 7 | import net.minecraftforge.fml.network.NetworkEvent; 8 | import tfar.ae2wt.wirelesscraftingterminal.WirelessCraftingTerminalContainer; 9 | 10 | import java.util.function.Supplier; 11 | 12 | public class C2SDeleteTrashPacket { 13 | 14 | public C2SDeleteTrashPacket() { 15 | } 16 | 17 | public C2SDeleteTrashPacket(PacketBuffer buf) { 18 | } 19 | 20 | public void encode(PacketBuffer buf) { 21 | } 22 | 23 | public void handle(Supplier ctx) { 24 | PlayerEntity player = ctx.get().getSender(); 25 | if (player == null) return; 26 | ctx.get().enqueueWork(() -> run(player)); 27 | ctx.get().setPacketHandled(true); 28 | } 29 | 30 | public void run(PlayerEntity player) { 31 | MinecraftServer server = player.getServer(); 32 | server.execute(() -> { 33 | final Container c = player.openContainer; 34 | if (c instanceof WirelessCraftingTerminalContainer) { 35 | final WirelessCraftingTerminalContainer container = (WirelessCraftingTerminalContainer) c; 36 | container.deleteTrashSlot(); 37 | } 38 | }); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/net/server/C2SEncodePatternPacket.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.net.server; 2 | 3 | import net.minecraft.entity.player.PlayerEntity; 4 | import net.minecraft.inventory.container.Container; 5 | import net.minecraft.network.PacketBuffer; 6 | import net.minecraft.server.MinecraftServer; 7 | import net.minecraftforge.fml.network.NetworkEvent; 8 | import tfar.ae2wt.wpt.WirelessPatternTerminalContainer; 9 | 10 | import java.util.function.Supplier; 11 | 12 | public class C2SEncodePatternPacket { 13 | 14 | public C2SEncodePatternPacket() { 15 | } 16 | 17 | public C2SEncodePatternPacket(PacketBuffer buf) { 18 | } 19 | 20 | public void encode(PacketBuffer buf) { 21 | } 22 | 23 | public void handle(Supplier ctx) { 24 | PlayerEntity player = ctx.get().getSender(); 25 | if (player == null) return; 26 | ctx.get().enqueueWork(() -> run(player)); 27 | ctx.get().setPacketHandled(true); 28 | } 29 | 30 | public void run(PlayerEntity player) { 31 | MinecraftServer server = player.getServer(); 32 | server.execute(() -> { 33 | final Container c = player.openContainer; 34 | if (c instanceof WirelessPatternTerminalContainer) { 35 | final WirelessPatternTerminalContainer container = (WirelessPatternTerminalContainer) c; 36 | container.encode(); 37 | } 38 | }); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/net/server/C2SSetMagnetModePacket.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.net.server; 2 | 3 | import net.minecraft.entity.player.PlayerEntity; 4 | import net.minecraft.inventory.container.Container; 5 | import net.minecraft.network.PacketBuffer; 6 | import net.minecraft.server.MinecraftServer; 7 | import net.minecraftforge.fml.network.NetworkEvent; 8 | import tfar.ae2wt.wirelesscraftingterminal.WirelessCraftingTerminalContainer; 9 | import tfar.ae2wt.wirelesscraftingterminal.magnet_card.MagnetMode; 10 | 11 | import java.util.function.Supplier; 12 | 13 | public class C2SSetMagnetModePacket { 14 | 15 | MagnetMode mode; 16 | 17 | public C2SSetMagnetModePacket(MagnetMode mode) { 18 | this.mode = mode; 19 | } 20 | 21 | public C2SSetMagnetModePacket(PacketBuffer buf) { 22 | mode = MagnetMode.modes[buf.readInt()]; 23 | } 24 | 25 | public void encode(PacketBuffer buf) { 26 | buf.writeInt(mode.ordinal()); 27 | } 28 | 29 | public void handle(Supplier ctx) { 30 | PlayerEntity player = ctx.get().getSender(); 31 | if (player == null) return; 32 | ctx.get().enqueueWork(() -> run(player)); 33 | ctx.get().setPacketHandled(true); 34 | } 35 | 36 | public void run(PlayerEntity player) { 37 | MinecraftServer server = player.getServer(); 38 | server.execute(() -> { 39 | final Container c = player.openContainer; 40 | if (c instanceof WirelessCraftingTerminalContainer) { 41 | final WirelessCraftingTerminalContainer container = (WirelessCraftingTerminalContainer) c; 42 | container.getMagnetSettings().magnetMode = mode; 43 | container.saveMagnetSettings(); 44 | } 45 | }); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/net/server/C2STogglePatternCraftingModePacket.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.net.server; 2 | 3 | import net.minecraft.entity.player.PlayerEntity; 4 | import net.minecraft.inventory.container.Container; 5 | import net.minecraft.network.PacketBuffer; 6 | import net.minecraft.server.MinecraftServer; 7 | import net.minecraftforge.fml.network.NetworkEvent; 8 | import tfar.ae2wt.wpt.WirelessPatternTerminalContainer; 9 | 10 | import java.util.function.Supplier; 11 | 12 | public class C2STogglePatternCraftingModePacket { 13 | 14 | boolean mode; 15 | 16 | public C2STogglePatternCraftingModePacket(boolean mode) { 17 | this.mode = mode; 18 | } 19 | 20 | public C2STogglePatternCraftingModePacket(PacketBuffer buf) { 21 | mode = buf.readBoolean(); 22 | } 23 | 24 | public void encode(PacketBuffer buf) { 25 | buf.writeBoolean(mode); 26 | } 27 | 28 | public void handle(Supplier ctx) { 29 | PlayerEntity player = ctx.get().getSender(); 30 | if (player == null) return; 31 | ctx.get().enqueueWork(() -> run(player)); 32 | ctx.get().setPacketHandled(true); 33 | } 34 | 35 | public void run(PlayerEntity player) { 36 | MinecraftServer server = player.getServer(); 37 | server.execute(() -> { 38 | final Container c = player.openContainer; 39 | if (c instanceof WirelessPatternTerminalContainer) { 40 | final WirelessPatternTerminalContainer container = (WirelessPatternTerminalContainer) c; 41 | container.getPatternTerminal().setCraftingMode(mode); 42 | } 43 | }); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/net/server/C2STogglePatternSubsitutionPacket.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.net.server; 2 | 3 | import net.minecraft.entity.player.PlayerEntity; 4 | import net.minecraft.inventory.container.Container; 5 | import net.minecraft.network.PacketBuffer; 6 | import net.minecraft.server.MinecraftServer; 7 | import net.minecraftforge.fml.network.NetworkEvent; 8 | import tfar.ae2wt.wpt.WirelessPatternTerminalContainer; 9 | 10 | import java.util.function.Supplier; 11 | 12 | public class C2STogglePatternSubsitutionPacket { 13 | 14 | boolean sub; 15 | 16 | public C2STogglePatternSubsitutionPacket(boolean sub) { 17 | this.sub = sub; 18 | } 19 | 20 | public C2STogglePatternSubsitutionPacket(PacketBuffer buf) { 21 | sub = buf.readBoolean(); 22 | } 23 | 24 | public void encode(PacketBuffer buf) { 25 | buf.writeBoolean(sub); 26 | } 27 | 28 | public void handle(Supplier ctx) { 29 | PlayerEntity player = ctx.get().getSender(); 30 | if (player == null) return; 31 | ctx.get().enqueueWork(() -> run(player)); 32 | ctx.get().setPacketHandled(true); 33 | } 34 | 35 | public void run(PlayerEntity player) { 36 | MinecraftServer server = player.getServer(); 37 | server.execute(() -> { 38 | final Container c = player.openContainer; 39 | if (c instanceof WirelessPatternTerminalContainer) { 40 | final WirelessPatternTerminalContainer container = (WirelessPatternTerminalContainer) c; 41 | container.getPatternTerminal().setSubstitution(sub); 42 | } 43 | }); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/terminal/FixedViewCellInventory.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.terminal; 2 | 3 | import appeng.items.storage.ViewCellItem; 4 | import net.minecraft.item.ItemStack; 5 | import net.minecraftforge.items.IItemHandlerModifiable; 6 | 7 | import javax.annotation.Nonnull; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | //todo 12 | public class FixedViewCellInventory implements IItemHandlerModifiable { 13 | 14 | private static final int viewCellCount = 5; 15 | private final ItemStack hostStack; 16 | 17 | public FixedViewCellInventory(ItemStack host) { 18 | hostStack = host; 19 | } 20 | 21 | @Override 22 | public int getSlots() { 23 | return 5; 24 | } 25 | 26 | @Override 27 | public ItemStack getStackInSlot(int i) { 28 | if (i < viewCellCount) return AbstractWirelessTerminalItem.getSavedSlot(hostStack, SlotType.viewCell, i); 29 | return ItemStack.EMPTY; 30 | } 31 | 32 | @Nonnull 33 | @Override 34 | public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate) { 35 | return ItemStack.EMPTY; 36 | } 37 | 38 | @Override 39 | public boolean isItemValid(int i, ItemStack itemStack) { 40 | return i < viewCellCount && (itemStack.getItem() instanceof ViewCellItem || itemStack.isEmpty()); 41 | } 42 | 43 | @Override 44 | public void setStackInSlot(int i, ItemStack itemStack) { 45 | if (isItemValid(i, itemStack)) { 46 | AbstractWirelessTerminalItem.setSavedSlot(hostStack, itemStack, SlotType.viewCell, i); 47 | } 48 | } 49 | 50 | public List getViewCells() { 51 | List viewCells = new ArrayList<>(); 52 | for (int i = 0; i < viewCellCount; i++) { 53 | viewCells.add(getStackInSlot(i)); 54 | } 55 | return viewCells; 56 | } 57 | 58 | @Override 59 | public ItemStack extractItem(int slot, int maxCount, boolean simulate) { 60 | if (slot > viewCellCount) return ItemStack.EMPTY; 61 | ItemStack is = getStackInSlot(slot); 62 | if (!simulate) setStackInSlot(slot, ItemStack.EMPTY); 63 | return is; 64 | } 65 | 66 | @Override 67 | public int getSlotLimit(int slot) { 68 | return 64; 69 | } 70 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/terminal/IInfinityBoosterCardHolder.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.terminal; 2 | 3 | import net.minecraft.item.ItemStack; 4 | 5 | public interface IInfinityBoosterCardHolder { 6 | 7 | boolean hasBoosterCard(ItemStack hostItem); 8 | 9 | void setBoosterCard(ItemStack hostItem, ItemStack boosterCard); 10 | 11 | ItemStack getBoosterCard(ItemStack hostItem); 12 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/terminal/InternalInventory.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.terminal; 2 | 3 | import appeng.tile.inventory.AppEngInternalInventory; 4 | import appeng.util.inv.IAEAppEngInventory; 5 | import net.minecraft.item.ItemStack; 6 | 7 | public class InternalInventory extends AppEngInternalInventory { 8 | 9 | private final ItemStack terminal; 10 | private final SlotType identifier; 11 | 12 | public InternalInventory(IAEAppEngInventory inventory, int size, SlotType identifier, ItemStack terminal) { 13 | super(inventory, size); 14 | this.terminal = terminal; 15 | this.identifier = identifier; 16 | for(int slot = 0; slot < size; slot++) super.setStackInSlot(slot, AbstractWirelessTerminalItem.getSavedSlot(terminal, identifier , slot)); 17 | } 18 | 19 | @Override 20 | public void setStackInSlot(int slot, ItemStack to) { 21 | super.setStackInSlot(slot, to); 22 | AbstractWirelessTerminalItem.setSavedSlot(terminal, to, identifier , slot); 23 | } 24 | 25 | @Override 26 | protected void onContentsChanged(int slot) { 27 | super.onContentsChanged(slot); 28 | //todo is this correct? 29 | AbstractWirelessTerminalItem.setSavedSlot(terminal, getStackInSlot(slot), identifier , slot); 30 | } 31 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/terminal/ItemInfinityBooster.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.terminal; 2 | 3 | import net.minecraft.client.util.ITooltipFlag; 4 | import net.minecraft.item.Item; 5 | import net.minecraft.item.ItemStack; 6 | import net.minecraft.util.text.ITextComponent; 7 | import net.minecraft.util.text.TranslationTextComponent; 8 | import net.minecraft.world.World; 9 | import net.minecraftforge.api.distmarker.Dist; 10 | import net.minecraftforge.api.distmarker.OnlyIn; 11 | import tfar.ae2wt.AE2WirelessTerminals; 12 | 13 | import java.util.List; 14 | 15 | public class ItemInfinityBooster extends Item { 16 | public ItemInfinityBooster() { 17 | super(new Properties().group(AE2WirelessTerminals.ITEM_GROUP).maxStackSize(1)); 18 | } 19 | 20 | @Override 21 | @OnlyIn(Dist.CLIENT) 22 | public void addInformation(final ItemStack stack, final World world, final List lines, final ITooltipFlag advancedTooltips) { 23 | super.addInformation(stack, world, lines, advancedTooltips); 24 | lines.add(new TranslationTextComponent("item.ae2wtlib.infinity_booster_card.desc")); 25 | } 26 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/terminal/SlotType.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.terminal; 2 | 3 | public enum SlotType { 4 | boosterCard,crafting, magnetCard,output,pattern,pattern_crafting,trash,viewCell; 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/util/ContainerHelper.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.util; 2 | 3 | import appeng.api.util.AEPartLocation; 4 | import appeng.container.AEBaseContainer; 5 | import appeng.container.ContainerLocator; 6 | import net.minecraft.entity.player.PlayerInventory; 7 | import net.minecraft.util.ResourceLocation; 8 | import net.minecraft.util.math.BlockPos; 9 | 10 | import java.lang.reflect.Constructor; 11 | 12 | public final class ContainerHelper { 13 | 14 | /** 15 | * creates a @link ContainerLocator} for any Inventory Slot since it's constructor is private and there is no static method which directly allows this 16 | * @param slot the slot the container is in 17 | * @return The new {@link ContainerLocator} 18 | */ 19 | public static ContainerLocator getContainerLocatorForSlot(int slot) { 20 | try { 21 | Object containerLocatorTypePLAYER_INVENTORY = null; 22 | Class containerLocatorTypeClass = Class.forName("appeng.container.ContainerLocator$Type"); 23 | for (Object obj : containerLocatorTypeClass.getEnumConstants()) { 24 | if(obj.toString().equals("PLAYER_INVENTORY")) { 25 | containerLocatorTypePLAYER_INVENTORY = obj; 26 | break; 27 | } 28 | } 29 | 30 | Constructor constructor = ContainerLocator.class.getDeclaredConstructor(containerLocatorTypeClass, int.class, ResourceLocation.class, BlockPos.class, AEPartLocation.class); 31 | constructor.setAccessible(true); 32 | ContainerLocator containerLocator = constructor.newInstance(containerLocatorTypePLAYER_INVENTORY, slot, null, null, null); 33 | constructor.setAccessible(false); 34 | return containerLocator; 35 | } catch(Exception ignored) {} 36 | return null; 37 | } 38 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/util/FixedEmptyInventory.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.util; 2 | 3 | import net.minecraft.item.ItemStack; 4 | import net.minecraftforge.items.IItemHandler; 5 | 6 | import javax.annotation.Nonnull; 7 | 8 | public class FixedEmptyInventory implements IItemHandler { 9 | 10 | private final int size; 11 | 12 | public FixedEmptyInventory(int size) { 13 | this.size = size; 14 | } 15 | 16 | @Override 17 | public int getSlots() { 18 | return size; 19 | } 20 | 21 | @Override 22 | public ItemStack getStackInSlot(int slot) { 23 | return ItemStack.EMPTY; 24 | } 25 | 26 | @Override 27 | public boolean isItemValid(int slot, ItemStack stack) { 28 | return false; 29 | } 30 | 31 | @Override 32 | public ItemStack insertItem(int slot, ItemStack to, boolean simulation) { 33 | return to; 34 | } 35 | 36 | @Nonnull 37 | @Override 38 | public ItemStack extractItem(int slot, int amount, boolean simulate) { 39 | return ItemStack.EMPTY; 40 | } 41 | 42 | @Override 43 | public int getSlotLimit(int slot) { 44 | return 0; 45 | } 46 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/util/ItemButton.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.util; 2 | 3 | import appeng.client.gui.widgets.ITooltip; 4 | import com.mojang.blaze3d.matrix.MatrixStack; 5 | import com.mojang.blaze3d.systems.RenderSystem; 6 | import net.minecraft.client.Minecraft; 7 | import net.minecraft.client.audio.SoundHandler; 8 | import net.minecraft.client.gui.widget.button.Button; 9 | import net.minecraft.client.renderer.texture.TextureManager; 10 | import net.minecraft.util.ResourceLocation; 11 | import net.minecraft.util.text.ITextComponent; 12 | import net.minecraft.util.text.StringTextComponent; 13 | 14 | import java.util.List; 15 | 16 | public class ItemButton extends Button implements ITooltip { 17 | 18 | private final ResourceLocation texture; 19 | public static final ResourceLocation TEXTURE_STATES = new ResourceLocation("appliedenergistics2", "textures/guis/states.png"); 20 | private boolean halfSize = false; 21 | 22 | public ItemButton(ResourceLocation texture, Button.IPressable onPress) { 23 | super(0, 0, 16, 16, StringTextComponent.EMPTY, onPress); 24 | this.texture = texture; 25 | } 26 | 27 | public void setVisibility(final boolean vis) { 28 | visible = vis; 29 | active = vis; 30 | } 31 | 32 | @Override 33 | public void playDownSound(SoundHandler soundManager) { 34 | super.playDownSound(soundManager); 35 | } 36 | 37 | @Override 38 | public void render(MatrixStack matrices, final int mouseX, final int mouseY, float partial) { 39 | 40 | Minecraft minecraft = Minecraft.getInstance(); 41 | 42 | if(visible) { 43 | TextureManager textureManager = minecraft.getTextureManager(); 44 | textureManager.bindTexture(TEXTURE_STATES); 45 | RenderSystem.disableDepthTest(); 46 | RenderSystem.enableBlend(); 47 | if(halfSize) { 48 | width = 8; 49 | height = 8; 50 | 51 | RenderSystem.pushMatrix(); 52 | RenderSystem.translatef(x, y, 0.0F); 53 | 54 | RenderSystem.scalef(0.5f, 0.5f, 0.5f); 55 | } else { 56 | RenderSystem.pushMatrix(); 57 | RenderSystem.translatef(x, y, 0.0F); 58 | } 59 | blit(matrices, 0, 0, 256 - 16, 256 - 16, 16, 16); 60 | RenderSystem.scalef(1f / 16f, 1f / 16f, 1f / 16f); 61 | if(active) { 62 | RenderSystem.color4f(1.0f, 1.0f, 1.0f, 1.0f); 63 | } else { 64 | RenderSystem.color4f(0.5f, 0.5f, 0.5f, 1.0f); 65 | } 66 | textureManager.bindTexture(texture); 67 | blit(matrices, 0, 0, 0, 0, 256, 256); 68 | RenderSystem.popMatrix(); 69 | RenderSystem.enableDepthTest(); 70 | RenderSystem.color4f(1.0f, 1.0f, 1.0f, 1.0f); 71 | 72 | if(isHovered()) { 73 | renderToolTip(matrices, mouseX, mouseY); 74 | } 75 | } 76 | } 77 | 78 | @Override 79 | public int getTooltipAreaX() { 80 | return x; 81 | } 82 | 83 | @Override 84 | public int getTooltipAreaY() { 85 | return y; 86 | } 87 | 88 | @Override 89 | public int getTooltipAreaWidth() { 90 | return halfSize ? 8 : 16; 91 | } 92 | 93 | @Override 94 | public int getTooltipAreaHeight() { 95 | return halfSize ? 8 : 16; 96 | } 97 | 98 | @Override 99 | public boolean isTooltipAreaVisible() { 100 | return visible; 101 | } 102 | 103 | public void setHalfSize(final boolean halfSize) { 104 | this.halfSize = halfSize; 105 | } 106 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/util/ae2wtlibSubScreen.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.util; 2 | 3 | import appeng.client.gui.AEBaseScreen; 4 | import appeng.client.gui.Icon; 5 | import appeng.client.gui.WidgetContainer; 6 | import appeng.client.gui.widgets.TabButton; 7 | import appeng.core.localization.GuiText; 8 | import net.minecraft.client.Minecraft; 9 | import net.minecraft.client.renderer.ItemRenderer; 10 | import net.minecraft.inventory.container.ContainerType; 11 | import net.minecraft.item.ItemStack; 12 | import net.minecraft.util.registry.Registry; 13 | import net.minecraft.util.text.ITextComponent; 14 | import tfar.ae2wt.init.Menus; 15 | import tfar.ae2wt.init.ModItems; 16 | import tfar.ae2wt.net.C2SSwitchGuiPacket; 17 | import tfar.ae2wt.net.PacketHandler; 18 | import tfar.ae2wt.wirelesscraftingterminal.WCTGuiObject; 19 | import tfar.ae2wt.wpt.WPTGuiObject; 20 | 21 | import javax.annotation.Nullable; 22 | import java.util.function.Consumer; 23 | 24 | public final class ae2wtlibSubScreen { 25 | 26 | private final AEBaseScreen gui; 27 | private final ContainerType previousContainerType; 28 | private final ItemStack previousContainerIcon; 29 | 30 | /** 31 | * Based on the container we're opening for, try to determine what it's "primary" GUI would be so that we can go 32 | * back to it. 33 | */ 34 | public ae2wtlibSubScreen(AEBaseScreen gui, Object containerTarget) { 35 | this.gui = gui; 36 | if(containerTarget instanceof WCTGuiObject) {//TODO don't hardcode 37 | previousContainerIcon = new ItemStack(ModItems.CRAFTING_TERMINAL); 38 | previousContainerType = Menus.WCT; 39 | } else if(containerTarget instanceof WPTGuiObject) { 40 | previousContainerIcon = new ItemStack(ModItems.PATTERN_TERMINAL); 41 | previousContainerType = Menus.PATTERN; 42 | } else { 43 | previousContainerIcon = null; 44 | previousContainerType = null; 45 | } 46 | } 47 | 48 | public TabButton addBackButton(String id, WidgetContainer widgets) { 49 | return this.addBackButton(id, widgets, null); 50 | } 51 | 52 | public TabButton addBackButton(String id, WidgetContainer widgets, @Nullable ITextComponent label) { 53 | if (this.previousContainerType != null && !this.previousContainerIcon.isEmpty()) { 54 | if (label == null) { 55 | label = this.previousContainerIcon.getDisplayName(); 56 | } 57 | 58 | ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer(); 59 | TabButton button = new TabButton(this.previousContainerIcon, label, itemRenderer, (btn) -> { 60 | this.goBack(); 61 | }); 62 | widgets.add(id, button); 63 | return button; 64 | } else { 65 | return null; 66 | } 67 | } 68 | 69 | public final void goBack() { 70 | PacketHandler.INSTANCE.sendToServer(new C2SSwitchGuiPacket(Registry.MENU.getKey(previousContainerType).getPath())); 71 | } 72 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wirelesscraftingterminal/CraftingTerminalHandler.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wirelesscraftingterminal; 2 | 3 | import appeng.api.features.ILocatable; 4 | import appeng.api.implementations.tiles.IWirelessAccessPoint; 5 | import appeng.api.networking.IGrid; 6 | import appeng.api.networking.IGridNode; 7 | import appeng.api.networking.IMachineSet; 8 | import appeng.api.networking.security.IActionHost; 9 | import appeng.api.util.DimensionalCoord; 10 | import appeng.core.Api; 11 | import appeng.tile.networking.WirelessTileEntity; 12 | import tfar.ae2wt.terminal.IInfinityBoosterCardHolder; 13 | import tfar.ae2wt.terminal.AbstractWirelessTerminalItem; 14 | import tfar.ae2wt.wut.WUTItem; 15 | import tfar.ae2wt.wut.WUTHandler; 16 | import net.minecraft.entity.player.PlayerEntity; 17 | import net.minecraft.entity.player.PlayerInventory; 18 | import net.minecraft.item.ItemStack; 19 | 20 | import java.util.HashMap; 21 | import java.util.UUID; 22 | 23 | public class CraftingTerminalHandler { 24 | 25 | private static final HashMap players = new HashMap<>(); 26 | private final PlayerEntity player; 27 | private ItemStack craftingTerminal = ItemStack.EMPTY; 28 | private ILocatable securityStation; 29 | private IGrid targetGrid; 30 | 31 | private CraftingTerminalHandler(PlayerEntity player) { 32 | this.player = player; 33 | } 34 | 35 | public static CraftingTerminalHandler getCraftingTerminalHandler(PlayerEntity player) { 36 | if(players.containsKey(player.getUniqueID())) return players.get(player.getUniqueID()); 37 | CraftingTerminalHandler handler = new CraftingTerminalHandler(player); 38 | players.put(player.getUniqueID(), handler); 39 | return handler; 40 | } 41 | 42 | public ItemStack getCraftingTerminal() {//TODO trinkets/curios 43 | PlayerInventory inv = player.inventory; 44 | if((!craftingTerminal.isEmpty()) && inv.hasItemStack(craftingTerminal)) return craftingTerminal; 45 | 46 | for(int i = 0; i < inv.getSizeInventory(); i++) { 47 | ItemStack terminal = inv.getStackInSlot(i); 48 | if(terminal.getItem() instanceof WCTItem || (terminal.getItem() instanceof WUTItem && WUTHandler.hasTerminal(terminal, "crafting"))) { 49 | return craftingTerminal = terminal; 50 | } 51 | } 52 | return ItemStack.EMPTY; 53 | } 54 | 55 | public ILocatable getSecurityStation() { 56 | if(securityStation != null) return securityStation; 57 | final String unParsedKey = ((AbstractWirelessTerminalItem) craftingTerminal.getItem()).getEncryptionKey(craftingTerminal); 58 | if(unParsedKey.isEmpty()) return null; 59 | final long parsedKey = Long.parseLong(unParsedKey); 60 | return securityStation = Api.instance().registries().locatable().getLocatableBy(parsedKey); 61 | } 62 | 63 | public IGrid getTargetGrid() { 64 | if(getSecurityStation() == null) return targetGrid = null; 65 | final IGridNode n = ((IActionHost) securityStation).getActionableNode(); 66 | 67 | if(n != null) { 68 | return targetGrid = n.getGrid(); 69 | } 70 | return targetGrid = null; 71 | } 72 | 73 | private IWirelessAccessPoint myWap; 74 | private double sqRange = Double.MAX_VALUE; 75 | 76 | public boolean inRange() { 77 | if(((IInfinityBoosterCardHolder) craftingTerminal.getItem()).hasBoosterCard(craftingTerminal)) return true; 78 | sqRange = Double.MAX_VALUE; 79 | 80 | if(getTargetGrid() == null) return false; 81 | if(targetGrid != null) { 82 | if(myWap != null) { 83 | if(myWap.getGrid() == targetGrid) { 84 | if(testWap(myWap)) return true; 85 | } 86 | } 87 | 88 | final IMachineSet tw = targetGrid.getMachines(WirelessTileEntity.class); 89 | 90 | myWap = null; 91 | 92 | for(final IGridNode n : tw) { 93 | final IWirelessAccessPoint wap = (IWirelessAccessPoint) n.getMachine(); 94 | if(testWap(wap)) { 95 | myWap = wap; 96 | } 97 | } 98 | 99 | return myWap != null; 100 | } 101 | return false; 102 | } 103 | 104 | private boolean testWap(final IWirelessAccessPoint wap) { 105 | double rangeLimit = wap.getRange(); 106 | rangeLimit *= rangeLimit; 107 | 108 | final DimensionalCoord dc = wap.getLocation(); 109 | 110 | if(dc.getWorld() == player.world) { 111 | final double offX = dc.x - player.getPosX(); 112 | final double offY = dc.y - player.getPosY(); 113 | final double offZ = dc.z - player.getPosZ(); 114 | 115 | final double r = offX * offX + offY * offY + offZ * offZ; 116 | if(r < rangeLimit && sqRange > r) { 117 | if(wap.isActive()) { 118 | sqRange = r; 119 | return true; 120 | } 121 | } 122 | } 123 | return false; 124 | } 125 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wirelesscraftingterminal/PlayerWidget.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wirelesscraftingterminal; 2 | 3 | import com.mojang.blaze3d.matrix.MatrixStack; 4 | import net.minecraft.client.Minecraft; 5 | import net.minecraft.client.gui.screen.inventory.InventoryScreen; 6 | import net.minecraft.client.gui.widget.Widget; 7 | import net.minecraft.util.text.StringTextComponent; 8 | 9 | public class PlayerWidget extends Widget { 10 | public PlayerWidget() { 11 | super(0, 0, 0, 0, new StringTextComponent("")); 12 | } 13 | 14 | 15 | //why doesn't the fabric port use the helper method? 16 | @Override 17 | protected void renderBg(MatrixStack matrixStack, Minecraft minecraft, int mouseX, int mouseY) { 18 | 19 | InventoryScreen.drawEntityOnScreen(x, y, 30, x - mouseX, y - mouseY - 50, minecraft.player); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wirelesscraftingterminal/TermFactory.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wirelesscraftingterminal; 2 | 3 | import appeng.container.ContainerLocator; 4 | import appeng.core.localization.GuiText; 5 | import net.minecraft.entity.player.PlayerEntity; 6 | import net.minecraft.entity.player.PlayerInventory; 7 | import net.minecraft.inventory.container.Container; 8 | import net.minecraft.inventory.container.INamedContainerProvider; 9 | import net.minecraft.util.text.ITextComponent; 10 | 11 | import javax.annotation.Nullable; 12 | 13 | public class TermFactory implements INamedContainerProvider { 14 | 15 | private final WCTGuiObject obj; 16 | private final ContainerLocator locator; 17 | 18 | public TermFactory(WCTGuiObject obj, ContainerLocator locator) { 19 | 20 | this.obj = obj; 21 | this.locator = locator; 22 | } 23 | 24 | @Override 25 | public ITextComponent getDisplayName() { 26 | return GuiText.Terminal.text(); 27 | } 28 | 29 | @Nullable 30 | @Override 31 | public Container createMenu(int p_createMenu_1_, PlayerInventory p_createMenu_2_, PlayerEntity p_createMenu_3_) { 32 | 33 | WirelessCraftingTerminalContainer c = new WirelessCraftingTerminalContainer(p_createMenu_1_, p_createMenu_2_, obj); 34 | // Set the original locator on the opened server-side container for it to more 35 | // easily remember how to re-open after being closed. 36 | c.setLocator(locator); 37 | return c; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wirelesscraftingterminal/WCTGuiObject.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wirelesscraftingterminal; 2 | 3 | import appeng.api.features.IWirelessTermHandler; 4 | import appeng.api.implementations.guiobjects.IPortableCell; 5 | import appeng.api.implementations.tiles.IViewCellStorage; 6 | import net.minecraft.entity.player.PlayerEntity; 7 | import net.minecraft.inventory.container.ContainerType; 8 | import net.minecraft.item.ItemStack; 9 | import tfar.ae2wt.init.Menus; 10 | import tfar.ae2wt.terminal.WTGuiObject; 11 | 12 | public class WCTGuiObject extends WTGuiObject implements IPortableCell , IViewCellStorage { 13 | 14 | public WCTGuiObject(final IWirelessTermHandler wh, final ItemStack is, final PlayerEntity ep, int inventorySlot) { 15 | super(wh, is, ep, inventorySlot); 16 | } 17 | 18 | @Override 19 | public ContainerType getType() { 20 | return Menus.WCT; 21 | } 22 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wirelesscraftingterminal/WCTItem.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wirelesscraftingterminal; 2 | 3 | import appeng.container.ContainerLocator; 4 | import appeng.core.AEConfig; 5 | import net.minecraft.item.Item; 6 | import tfar.ae2wt.AE2WirelessTerminals; 7 | import tfar.ae2wt.terminal.IInfinityBoosterCardHolder; 8 | import tfar.ae2wt.terminal.AbstractWirelessTerminalItem; 9 | import net.minecraft.entity.player.PlayerEntity; 10 | import net.minecraft.item.ItemStack; 11 | 12 | public class WCTItem extends AbstractWirelessTerminalItem implements IInfinityBoosterCardHolder { 13 | 14 | public WCTItem() { 15 | super(AEConfig.instance().getWirelessTerminalBattery(), new Item.Properties().group(AE2WirelessTerminals.ITEM_GROUP).maxStackSize(1)); 16 | } 17 | 18 | @Override 19 | public void open(final PlayerEntity player, final ContainerLocator locator) { 20 | WirelessCraftingTerminalContainer.openServer(player, locator); 21 | } 22 | 23 | @Override 24 | public boolean canHandle(ItemStack is) { 25 | return is.getItem() instanceof WCTItem; 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wirelesscraftingterminal/WirelessCraftingTermSlot.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wirelesscraftingterminal; 2 | 3 | import appeng.api.networking.energy.IEnergySource; 4 | import appeng.api.networking.security.IActionSource; 5 | import appeng.api.storage.IStorageMonitorable; 6 | import appeng.container.slot.CraftingTermSlot; 7 | import appeng.helpers.IContainerCraftingPacket; 8 | import net.minecraft.entity.player.PlayerEntity; 9 | import net.minecraft.inventory.CraftingInventory; 10 | import net.minecraft.item.ItemStack; 11 | import net.minecraft.item.crafting.IRecipe; 12 | import net.minecraft.item.crafting.IRecipeType; 13 | import net.minecraft.util.NonNullList; 14 | import net.minecraft.world.World; 15 | import net.minecraftforge.items.IItemHandler; 16 | 17 | public class WirelessCraftingTermSlot extends CraftingTermSlot { 18 | private final IContainerCraftingPacket container; 19 | 20 | public WirelessCraftingTermSlot(PlayerEntity player, IActionSource mySrc, IEnergySource energySrc, IStorageMonitorable storage, IItemHandler cMatrix, IItemHandler secondMatrix, IContainerCraftingPacket container) { 21 | super(player, mySrc, energySrc, storage, cMatrix, secondMatrix, container); 22 | this.container = container; 23 | } 24 | 25 | // TODO: This is really hacky and NEEDS to be solved with a full container/gui 26 | // refactoring. 27 | @Override 28 | protected IRecipe findRecipe(CraftingInventory ic, World world) { 29 | if (this.container instanceof WirelessCraftingTerminalContainer) { 30 | final WirelessCraftingTerminalContainer containerTerminal = (WirelessCraftingTerminalContainer) this.container; 31 | final IRecipe recipe = containerTerminal.getCurrentRecipe(); 32 | 33 | if (recipe != null && recipe.matches(ic, world)) { 34 | return containerTerminal.getCurrentRecipe(); 35 | } 36 | } 37 | 38 | return world.getRecipeManager().getRecipe(IRecipeType.CRAFTING, ic, world).orElse(null); 39 | } 40 | 41 | // TODO: This is really hacky and NEEDS to be solved with a full container/gui 42 | // refactoring. 43 | @Override 44 | protected NonNullList getRemainingItems(CraftingInventory ic, World world) { 45 | if (this.container instanceof WirelessCraftingTerminalContainer) { 46 | final WirelessCraftingTerminalContainer containerTerminal = (WirelessCraftingTerminalContainer) this.container; 47 | final IRecipe recipe = containerTerminal.getCurrentRecipe(); 48 | 49 | if (recipe != null && recipe.matches(ic, world)) { 50 | return containerTerminal.getCurrentRecipe().getRemainingItems(ic); 51 | } 52 | } 53 | 54 | return super.getRemainingItems(ic, world); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wirelesscraftingterminal/WirelessCraftingTerminalScreen.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wirelesscraftingterminal; 2 | 3 | import appeng.api.config.ActionItems; 4 | import appeng.client.gui.Icon; 5 | import appeng.client.gui.me.items.ItemTerminalScreen; 6 | import appeng.client.gui.style.ScreenStyle; 7 | import appeng.client.gui.widgets.ActionButton; 8 | import appeng.client.gui.widgets.IconButton; 9 | import com.mojang.blaze3d.matrix.MatrixStack; 10 | import net.minecraft.client.Minecraft; 11 | import net.minecraft.client.gui.screen.inventory.InventoryScreen; 12 | import net.minecraft.entity.player.PlayerInventory; 13 | import net.minecraft.util.ResourceLocation; 14 | import net.minecraft.util.text.ITextComponent; 15 | import net.minecraft.util.text.TranslationTextComponent; 16 | import tfar.ae2wt.net.PacketHandler; 17 | import tfar.ae2wt.net.server.C2SDeleteTrashPacket; 18 | import tfar.ae2wt.net.server.C2SSetMagnetModePacket; 19 | import tfar.ae2wt.util.ItemButton; 20 | import tfar.ae2wt.wirelesscraftingterminal.magnet_card.MagnetMode; 21 | import tfar.ae2wt.wirelesscraftingterminal.magnet_card.MagnetSettings; 22 | import tfar.ae2wt.wut.CycleTerminalButton; 23 | import tfar.ae2wt.wut.IUniversalTerminalCapable; 24 | 25 | public class WirelessCraftingTerminalScreen extends ItemTerminalScreen implements IUniversalTerminalCapable { 26 | 27 | ItemButton magnetCardToggleButton; 28 | 29 | public WirelessCraftingTerminalScreen(WirelessCraftingTerminalContainer container, PlayerInventory playerInventory, ITextComponent title, ScreenStyle style) { 30 | super(container, playerInventory, title,style); 31 | ActionButton clearBtn = new ActionButton(ActionItems.STASH, (btn) -> container.clearCraftingGrid()); 32 | clearBtn.setHalfSize(true); 33 | widgets.add("clearCraftingGrid", clearBtn); 34 | IconButton deleteButton = new IconButton(btn -> delete()) { 35 | @Override 36 | protected Icon getIcon() { 37 | return Icon.CONDENSER_OUTPUT_TRASH; 38 | } 39 | }; 40 | deleteButton.setHalfSize(true); 41 | deleteButton.setMessage(new TranslationTextComponent("gui.ae2wtlib.emptytrash").appendString("\n") 42 | .appendSibling(new TranslationTextComponent("gui.ae2wtlib.emptytrash.desc"))); 43 | widgets.add("emptyTrash", deleteButton); 44 | 45 | magnetCardToggleButton = new ItemButton(new ResourceLocation("ae2wtlib", "textures/magnet_card.png"),btn -> setMagnetMode()); 46 | magnetCardToggleButton.setHalfSize(true); 47 | widgets.add("magnetCardToggleButton", magnetCardToggleButton); 48 | resetMagnetSettings(); 49 | if(getContainer().isWUT()) widgets.add("cycleTerminal", new CycleTerminalButton(btn -> cycleTerminal())); 50 | 51 | widgets.add("player", new PlayerWidget()); 52 | } 53 | 54 | @Override 55 | public void drawBG(MatrixStack matrices, final int offsetX, final int offsetY, final int mouseX, final int mouseY, float partialTicks) { 56 | super.drawBG(matrices, offsetX, offsetY, mouseX, mouseY, partialTicks); 57 | } 58 | 59 | @Override 60 | public void drawFG(MatrixStack matrices, final int offsetX, final int offsetY, final int mouseX, final int mouseY) { 61 | super.drawFG(matrices, offsetX, offsetY, mouseX, mouseY); 62 | } 63 | 64 | private void delete() { 65 | PacketHandler.INSTANCE.sendToServer(new C2SDeleteTrashPacket()); 66 | } 67 | 68 | private MagnetSettings magnetSettings = null; 69 | 70 | public void resetMagnetSettings() { 71 | magnetSettings = container.getMagnetSettings(); 72 | setMagnetModeText(); 73 | } 74 | 75 | private void setMagnetMode() { 76 | switch(magnetSettings.magnetMode) { 77 | case NO_CARD: 78 | return; 79 | case OFF: 80 | magnetSettings.magnetMode = MagnetMode.PICKUP_INVENTORY; 81 | break; 82 | case PICKUP_INVENTORY: 83 | magnetSettings.magnetMode = MagnetMode.PICKUP_ME; 84 | break; 85 | case PICKUP_ME: 86 | magnetSettings.magnetMode = MagnetMode.OFF; 87 | break; 88 | } 89 | setMagnetModeText(); 90 | PacketHandler.INSTANCE.sendToServer(new C2SSetMagnetModePacket(magnetSettings.magnetMode)); 91 | } 92 | 93 | private void setMagnetModeText() { 94 | switch(magnetSettings.magnetMode) { 95 | case NO_CARD: 96 | magnetCardToggleButton.setVisibility(false); 97 | return; 98 | case OFF: 99 | magnetCardToggleButton.setMessage(new TranslationTextComponent("gui.ae2wtlib.magnetcard").appendString("\n").appendSibling(new TranslationTextComponent("gui.ae2wtlib.magnetcard.desc.off"))); 100 | break; 101 | case PICKUP_INVENTORY: 102 | magnetCardToggleButton.setMessage(new TranslationTextComponent("gui.ae2wtlib.magnetcard").appendString("\n").appendSibling(new TranslationTextComponent("gui.ae2wtlib.magnetcard.desc.inv"))); 103 | break; 104 | case PICKUP_ME: 105 | magnetCardToggleButton.setMessage(new TranslationTextComponent("gui.ae2wtlib.magnetcard").appendString("\n").appendSibling(new TranslationTextComponent("gui.ae2wtlib.magnetcard.desc.me"))); 106 | break; 107 | } 108 | magnetCardToggleButton.setVisibility(true); 109 | } 110 | 111 | //todo jei 112 | /* @Override 113 | public List getExclusionZones() { 114 | List zones = super.getExclusionZones(); 115 | zones.add(new Rectangle(guiTop + 195, y, 24,ySize - 110)); 116 | return zones; 117 | }*/ 118 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wirelesscraftingterminal/magnet_card/ItemMagnetCard.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wirelesscraftingterminal.magnet_card; 2 | 3 | import net.minecraft.client.util.ITooltipFlag; 4 | import net.minecraft.item.Item; 5 | import net.minecraft.item.ItemStack; 6 | import net.minecraft.util.text.ITextComponent; 7 | import net.minecraft.util.text.TranslationTextComponent; 8 | import net.minecraft.world.World; 9 | import net.minecraftforge.api.distmarker.Dist; 10 | import net.minecraftforge.api.distmarker.OnlyIn; 11 | import tfar.ae2wt.terminal.SlotType; 12 | import tfar.ae2wt.terminal.AbstractWirelessTerminalItem; 13 | 14 | import java.util.List; 15 | 16 | public class ItemMagnetCard extends Item { 17 | 18 | public ItemMagnetCard(Properties properties) { 19 | super(properties); 20 | } 21 | 22 | @Override 23 | @OnlyIn(Dist.CLIENT) 24 | public void addInformation(final ItemStack stack, final World world, final List lines, final ITooltipFlag advancedTooltips) { 25 | super.addInformation(stack, world, lines, advancedTooltips); 26 | lines.add(new TranslationTextComponent("item.ae2wtlib.magnet_card.desc")); 27 | } 28 | 29 | public static void saveMagnetSettings(ItemStack magnetCardHolder, MagnetSettings magnetSettings) { 30 | ItemStack magnetCard = AbstractWirelessTerminalItem.getSavedSlot(magnetCardHolder, SlotType.magnetCard); 31 | magnetSettings.saveTo(magnetCard); 32 | AbstractWirelessTerminalItem.setSavedSlot(magnetCardHolder, magnetCard, SlotType.magnetCard); 33 | } 34 | 35 | public static MagnetSettings loadMagnetSettings(ItemStack magnetCardHolder) { 36 | ItemStack magnetCard = AbstractWirelessTerminalItem.getSavedSlot(magnetCardHolder, SlotType.magnetCard); 37 | return MagnetSettings.from(magnetCard); 38 | } 39 | 40 | public static boolean isActiveMagnet(ItemStack magnetCardHolder) { 41 | if(magnetCardHolder.isEmpty()) return false; 42 | MagnetSettings settings = loadMagnetSettings(magnetCardHolder); 43 | return settings.magnetMode.isActive(); 44 | } 45 | 46 | public static boolean isPickupME(ItemStack magnetCardHolder) { 47 | if(magnetCardHolder.isEmpty()) return false; 48 | MagnetSettings settings = loadMagnetSettings(magnetCardHolder); 49 | return settings.magnetMode == MagnetMode.PICKUP_ME; 50 | } 51 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wirelesscraftingterminal/magnet_card/MagnetHandler.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wirelesscraftingterminal.magnet_card; 2 | 3 | import net.minecraft.entity.item.ItemEntity; 4 | import net.minecraft.entity.player.PlayerEntity; 5 | import net.minecraft.entity.player.ServerPlayerEntity; 6 | import net.minecraft.item.ItemStack; 7 | import net.minecraft.server.MinecraftServer; 8 | import net.minecraft.util.EntityPredicates; 9 | import tfar.ae2wt.wirelesscraftingterminal.CraftingTerminalHandler; 10 | 11 | import java.util.List; 12 | 13 | public class MagnetHandler { 14 | public static void doMagnet(PlayerEntity player) { 15 | ItemStack magnetCardHolder = CraftingTerminalHandler.getCraftingTerminalHandler(player).getCraftingTerminal(); 16 | if (ItemMagnetCard.isActiveMagnet(magnetCardHolder)) { 17 | List entityItems = player.world.getEntitiesWithinAABB(ItemEntity.class, player.getBoundingBox().grow(16.0D)); 18 | for (ItemEntity entityItemNearby : entityItems) { 19 | if (!player.isSneaking()) { 20 | entityItemNearby.onCollideWithPlayer(player); 21 | } 22 | } 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wirelesscraftingterminal/magnet_card/MagnetMode.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wirelesscraftingterminal.magnet_card; 2 | 3 | public enum MagnetMode { 4 | NO_CARD,OFF,PICKUP_INVENTORY,PICKUP_ME; 5 | public static final MagnetMode DEFAULT = OFF; 6 | public static final MagnetMode[] modes = values(); 7 | 8 | public boolean isActive() { 9 | return this == PICKUP_INVENTORY || this == PICKUP_ME; 10 | } 11 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wirelesscraftingterminal/magnet_card/MagnetSettings.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wirelesscraftingterminal.magnet_card; 2 | 3 | import net.minecraft.item.ItemStack; 4 | import net.minecraft.nbt.CompoundNBT; 5 | 6 | public class MagnetSettings { 7 | 8 | public MagnetMode magnetMode; 9 | 10 | private MagnetSettings(MagnetMode mode) { 11 | this.magnetMode = mode; 12 | } 13 | 14 | public static MagnetSettings from(ItemStack magnetCard) { 15 | if (magnetCard.isEmpty()) { 16 | return new MagnetSettings(MagnetMode.NO_CARD); 17 | } else { 18 | CompoundNBT nbt = magnetCard.getTag() != null ? magnetCard.getTag().getCompound("magnet_settings") : null; 19 | if (nbt != null) { 20 | int ordinal = nbt.getInt("magnetMode"); 21 | MagnetMode mode = MagnetMode.modes[ordinal]; 22 | return new MagnetSettings(mode); 23 | } else { 24 | return new MagnetSettings(MagnetMode.NO_CARD); 25 | } 26 | } 27 | } 28 | 29 | public void saveTo(ItemStack magnetCard) { 30 | magnetCard.getOrCreateTag().put("magnet_settings", toTag()); 31 | } 32 | 33 | public CompoundNBT toTag() { 34 | CompoundNBT tag = new CompoundNBT(); 35 | tag.putInt("magnetMode", magnetMode.ordinal()); 36 | return tag; 37 | } 38 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wirelessfluidterminal/TermFactory.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wirelessfluidterminal; 2 | 3 | import appeng.container.ContainerLocator; 4 | import appeng.core.localization.GuiText; 5 | import net.minecraft.entity.player.PlayerEntity; 6 | import net.minecraft.entity.player.PlayerInventory; 7 | import net.minecraft.inventory.container.Container; 8 | import net.minecraft.inventory.container.INamedContainerProvider; 9 | import net.minecraft.util.text.ITextComponent; 10 | 11 | import javax.annotation.Nullable; 12 | 13 | public class TermFactory implements INamedContainerProvider { 14 | 15 | private final WFluidTGuiObject obj; 16 | private final ContainerLocator locator; 17 | 18 | public TermFactory(WFluidTGuiObject obj, ContainerLocator locator) { 19 | 20 | this.obj = obj; 21 | this.locator = locator; 22 | } 23 | 24 | @Override 25 | public ITextComponent getDisplayName() { 26 | return GuiText.Terminal.text(); 27 | } 28 | 29 | @Nullable 30 | @Override 31 | public Container createMenu(int p_createMenu_1_, PlayerInventory p_createMenu_2_, PlayerEntity p_createMenu_3_) { 32 | 33 | WirelessFluidTerminalContainer c = new WirelessFluidTerminalContainer(p_createMenu_1_, p_createMenu_2_, obj); 34 | // Set the original locator on the opened server-side container for it to more 35 | // easily remember how to re-open after being closed. 36 | c.setLocator(locator); 37 | return c; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wirelessfluidterminal/WFluidTGuiObject.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wirelessfluidterminal; 2 | 3 | import appeng.api.features.IWirelessTermHandler; 4 | import appeng.api.implementations.guiobjects.IPortableCell; 5 | import appeng.api.implementations.tiles.IViewCellStorage; 6 | import net.minecraft.entity.player.PlayerEntity; 7 | import net.minecraft.inventory.container.ContainerType; 8 | import net.minecraft.item.ItemStack; 9 | import tfar.ae2wt.init.Menus; 10 | import tfar.ae2wt.terminal.WTGuiObject; 11 | 12 | public class WFluidTGuiObject extends WTGuiObject implements IPortableCell , IViewCellStorage { 13 | 14 | public WFluidTGuiObject(final IWirelessTermHandler wh, final ItemStack is, final PlayerEntity ep, int inventorySlot) { 15 | super(wh, is, ep, inventorySlot); 16 | } 17 | 18 | @Override 19 | public ContainerType getType() { 20 | return Menus.WIRELESS_FLUID_TERMINAL; 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wirelessfluidterminal/WirelessFluidTerminalItem.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wirelessfluidterminal; 2 | 3 | import appeng.container.ContainerLocator; 4 | import net.minecraft.entity.player.PlayerEntity; 5 | import tfar.ae2wt.terminal.AbstractWirelessTerminalItem; 6 | 7 | import java.util.function.DoubleSupplier; 8 | 9 | public class WirelessFluidTerminalItem extends AbstractWirelessTerminalItem { 10 | public WirelessFluidTerminalItem(DoubleSupplier powerCapacity, Properties props) { 11 | super(powerCapacity, props); 12 | } 13 | 14 | @Override 15 | public void open(PlayerEntity player, ContainerLocator locator) { 16 | WirelessFluidTerminalContainer.openServer(player, locator); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wirelessfluidterminal/WirelessFluidTerminalScreen.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wirelessfluidterminal; 2 | 3 | import appeng.api.storage.data.IAEFluidStack; 4 | import appeng.client.gui.me.common.MEMonitorableScreen; 5 | import appeng.client.gui.me.common.Repo; 6 | import appeng.client.gui.style.ScreenStyle; 7 | import appeng.client.gui.widgets.IScrollSource; 8 | import appeng.container.me.common.GridInventoryEntry; 9 | import appeng.container.me.fluids.FluidTerminalContainer; 10 | import appeng.core.AELog; 11 | import appeng.fluids.client.gui.FluidBlitter; 12 | import appeng.helpers.InventoryAction; 13 | import appeng.util.Platform; 14 | import appeng.util.prioritylist.IPartitionList; 15 | import com.mojang.blaze3d.matrix.MatrixStack; 16 | import net.minecraft.entity.player.PlayerInventory; 17 | import net.minecraft.inventory.container.ClickType; 18 | import net.minecraft.item.ItemStack; 19 | import net.minecraft.util.text.ITextComponent; 20 | import net.minecraft.util.text.StringTextComponent; 21 | import tfar.ae2wt.ae2copies.FluidRepo; 22 | 23 | import javax.annotation.Nullable; 24 | import java.text.NumberFormat; 25 | import java.util.ArrayList; 26 | import java.util.List; 27 | import java.util.Locale; 28 | 29 | public class WirelessFluidTerminalScreen extends MEMonitorableScreen { 30 | public WirelessFluidTerminalScreen(WirelessFluidTerminalContainer container, PlayerInventory playerInventory, ITextComponent title, ScreenStyle style) { 31 | super(container, playerInventory, title, style); 32 | } 33 | 34 | protected Repo createRepo(IScrollSource scrollSource) { 35 | return new FluidRepo(scrollSource, this); 36 | } 37 | 38 | protected IPartitionList createPartitionList(List viewCells) { 39 | return null; 40 | } 41 | 42 | protected void renderGridInventoryEntry(MatrixStack matrices, int x, int y, GridInventoryEntry entry) { 43 | IAEFluidStack fs = entry.getStack(); 44 | FluidBlitter.create(fs.getFluidStack()).dest(x, y, 16, 16).blit(matrices, this.getBlitOffset()); 45 | } 46 | 47 | protected void renderGridInventoryEntryTooltip(MatrixStack matrices, GridInventoryEntry entry, int x, int y) { 48 | IAEFluidStack fluidStack = entry.getStack(); 49 | String formattedAmount = NumberFormat.getNumberInstance(Locale.US).format((double)entry.getStoredAmount() / 1000.0D) + " B"; 50 | String modName = Platform.getModName(Platform.getModId(fluidStack)); 51 | List list = new ArrayList<>(); 52 | list.add(fluidStack.getFluidStack().getDisplayName()); 53 | list.add(new StringTextComponent(formattedAmount)); 54 | list.add(new StringTextComponent(modName)); 55 | this.renderWrappedToolTip(matrices, list, x, y, this.font); 56 | } 57 | 58 | protected void handleGridInventoryEntryMouseClick(@Nullable GridInventoryEntry entry, int mouseButton, ClickType clickType) { 59 | if (clickType == ClickType.PICKUP) { 60 | if (mouseButton == 0 && entry != null) { 61 | AELog.debug("mouse0 GUI STACK SIZE %s", entry.getStoredAmount()); 62 | this.container.handleInteraction(entry.getSerial(), InventoryAction.FILL_ITEM); 63 | } else { 64 | if (entry != null) { 65 | AELog.debug("mouse1 GUI STACK SIZE %s", entry.getStoredAmount()); 66 | } 67 | 68 | this.container.handleInteraction(-1L, InventoryAction.EMPTY_ITEM); 69 | } 70 | } 71 | 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wirelessinterfaceterminal/TermFactory.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wirelessinterfaceterminal; 2 | 3 | import appeng.container.ContainerLocator; 4 | import appeng.core.localization.GuiText; 5 | import net.minecraft.entity.player.PlayerEntity; 6 | import net.minecraft.entity.player.PlayerInventory; 7 | import net.minecraft.inventory.container.Container; 8 | import net.minecraft.inventory.container.INamedContainerProvider; 9 | import net.minecraft.util.text.ITextComponent; 10 | import tfar.ae2wt.terminal.WTGuiObject; 11 | 12 | import javax.annotation.Nullable; 13 | 14 | public class TermFactory implements INamedContainerProvider { 15 | 16 | private final WTGuiObject obj; 17 | private final ContainerLocator locator; 18 | 19 | TermFactory(WTGuiObject obj, ContainerLocator locator) { 20 | 21 | this.obj = obj; 22 | this.locator = locator; 23 | } 24 | 25 | @Override 26 | public ITextComponent getDisplayName() { 27 | return GuiText.Terminal.text(); 28 | } 29 | 30 | @Nullable 31 | @Override 32 | public Container createMenu(int p_createMenu_1_, PlayerInventory p_createMenu_2_, PlayerEntity p_createMenu_3_) { 33 | 34 | WirelessInterfaceTerminalContainer c = new WirelessInterfaceTerminalContainer(p_createMenu_1_, p_createMenu_2_, obj); 35 | // Set the original locator on the opened server-side container for it to more 36 | // easily remember how to re-open after being closed. 37 | c.setLocator(locator); 38 | return c; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wirelessinterfaceterminal/WITGuiObject.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wirelessinterfaceterminal; 2 | 3 | import appeng.api.features.IWirelessTermHandler; 4 | import net.minecraft.entity.player.PlayerEntity; 5 | import net.minecraft.inventory.container.ContainerType; 6 | import net.minecraft.item.ItemStack; 7 | import tfar.ae2wt.init.Menus; 8 | import tfar.ae2wt.terminal.WTGuiObject; 9 | 10 | public class WITGuiObject extends WTGuiObject { 11 | public WITGuiObject(IWirelessTermHandler wh, ItemStack is, PlayerEntity ep, int inventorySlot) { 12 | super(wh, is, ep, inventorySlot); 13 | } 14 | 15 | @Override 16 | public ContainerType getType() { 17 | return Menus.WIT; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wirelessinterfaceterminal/WITItem.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wirelessinterfaceterminal; 2 | 3 | import appeng.container.ContainerLocator; 4 | import appeng.core.AEConfig; 5 | import tfar.ae2wt.AE2WirelessTerminals; 6 | import tfar.ae2wt.terminal.IInfinityBoosterCardHolder; 7 | import tfar.ae2wt.terminal.AbstractWirelessTerminalItem; 8 | import net.minecraft.entity.player.PlayerEntity; 9 | import tfar.ae2wt.wirelessfluidterminal.WirelessFluidTerminalContainer; 10 | 11 | public class WITItem extends AbstractWirelessTerminalItem implements IInfinityBoosterCardHolder { 12 | 13 | public WITItem() { 14 | super(AEConfig.instance().getWirelessTerminalBattery(), new Properties().group(AE2WirelessTerminals.ITEM_GROUP).maxStackSize(1)); 15 | } 16 | 17 | @Override 18 | public void open(final PlayerEntity player, final ContainerLocator locator) { 19 | WirelessInterfaceTerminalContainer.openServer(player, locator); 20 | } 21 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wpt/TermFactory.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wpt; 2 | 3 | import appeng.container.ContainerLocator; 4 | import appeng.core.localization.GuiText; 5 | import net.minecraft.entity.player.PlayerEntity; 6 | import net.minecraft.entity.player.PlayerInventory; 7 | import net.minecraft.inventory.container.Container; 8 | import net.minecraft.inventory.container.INamedContainerProvider; 9 | import net.minecraft.util.text.ITextComponent; 10 | 11 | import javax.annotation.Nullable; 12 | 13 | public class TermFactory implements INamedContainerProvider { 14 | 15 | private final WPTGuiObject obj; 16 | private final ContainerLocator locator; 17 | 18 | TermFactory(WPTGuiObject obj, ContainerLocator locator) { 19 | 20 | this.obj = obj; 21 | this.locator = locator; 22 | } 23 | 24 | @Override 25 | public ITextComponent getDisplayName() { 26 | return GuiText.Terminal.text(); 27 | } 28 | 29 | @Nullable 30 | @Override 31 | public Container createMenu(int p_createMenu_1_, PlayerInventory p_createMenu_2_, PlayerEntity p_createMenu_3_) { 32 | 33 | WirelessPatternTerminalContainer c = new WirelessPatternTerminalContainer(p_createMenu_1_, p_createMenu_2_, obj); 34 | // Set the original locator on the opened server-side container for it to more 35 | // easily remember how to re-open after being closed. 36 | c.setLocator(locator); 37 | return c; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wpt/WPTGuiObject.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wpt; 2 | 3 | import appeng.api.features.IWirelessTermHandler; 4 | import appeng.api.implementations.guiobjects.IPortableCell; 5 | import appeng.api.implementations.tiles.IViewCellStorage; 6 | import appeng.api.networking.crafting.ICraftingPatternDetails; 7 | import appeng.api.storage.data.IAEItemStack; 8 | import appeng.core.Api; 9 | import appeng.tile.inventory.AppEngInternalInventory; 10 | import appeng.util.inv.IAEAppEngInventory; 11 | import appeng.util.inv.InvOperation; 12 | import net.minecraft.inventory.container.ContainerType; 13 | import net.minecraftforge.items.IItemHandler; 14 | import tfar.ae2wt.init.Menus; 15 | import tfar.ae2wt.init.ModItems; 16 | import tfar.ae2wt.terminal.SlotType; 17 | import tfar.ae2wt.terminal.WTGuiObject; 18 | import tfar.ae2wt.terminal.InternalInventory; 19 | import net.minecraft.entity.player.PlayerEntity; 20 | import net.minecraft.item.ItemStack; 21 | 22 | public class WPTGuiObject extends WTGuiObject implements IPortableCell, IAEAppEngInventory, IViewCellStorage { 23 | 24 | private boolean craftingMode = true; 25 | private boolean substitute = false; 26 | private final AppEngInternalInventory crafting; 27 | private final AppEngInternalInventory output; 28 | private final AppEngInternalInventory pattern; 29 | 30 | public WPTGuiObject(final IWirelessTermHandler wh, final ItemStack is, final PlayerEntity ep, int inventorySlot) { 31 | super(wh, is, ep, inventorySlot); 32 | crafting = new InternalInventory(this, 9, SlotType.pattern_crafting, is); 33 | output = new InternalInventory(this, 3, SlotType.output, is); 34 | pattern = new InternalInventory(this, 2, SlotType.pattern, is); 35 | } 36 | 37 | public boolean isCraftingRecipe() { 38 | return craftingMode; 39 | } 40 | 41 | public AppEngInternalInventory getInventoryByName(final String name) { 42 | if(name.equals("crafting")) return crafting; 43 | 44 | if(name.equals("output")) return output; 45 | 46 | if(name.equals("pattern")) return pattern; 47 | return null; 48 | } 49 | 50 | @Override 51 | public void saveChanges() {} 52 | 53 | @Override 54 | public void onChangeInventory(IItemHandler inv, int slot, InvOperation mc, ItemStack removedStack, ItemStack newStack) { 55 | if(inv == pattern && slot == 1) { 56 | final ItemStack is = pattern.getStackInSlot(1); 57 | final ICraftingPatternDetails details = Api.instance().crafting().decodePattern(is, getPlayer().world, false); 58 | if(details != null) { 59 | setCraftingMode(details.isCraftable()); 60 | setSubstitution(details.canSubstitute()); 61 | 62 | for(int x = 0; x < crafting.getSlots() && x < details.getSparseInputs().length; x++) { 63 | final IAEItemStack item = details.getSparseInputs()[x]; 64 | crafting.setStackInSlot(x, item == null ? ItemStack.EMPTY : item.createItemStack()); 65 | } 66 | 67 | for(int x = 0; x < output.getSlots() && x < details.getSparseOutputs().length; x++) { 68 | final IAEItemStack item = details.getSparseOutputs()[x]; 69 | output.setStackInSlot(x, item == null ? ItemStack.EMPTY : item.createItemStack()); 70 | } 71 | } 72 | } else if(inv == crafting) fixCraftingRecipes(); 73 | } 74 | 75 | @Override 76 | public boolean isRemote() { 77 | return getPlayer().world.isRemote; 78 | } 79 | 80 | public void setCraftingMode(final boolean craftingMode) { 81 | this.craftingMode = craftingMode; 82 | fixCraftingRecipes(); 83 | } 84 | 85 | public boolean isSubstitution() { 86 | return this.substitute; 87 | } 88 | 89 | public void setSubstitution(final boolean canSubstitute) { 90 | this.substitute = canSubstitute; 91 | } 92 | 93 | private void fixCraftingRecipes() { 94 | if(craftingMode) for(int x = 0; x < crafting.getSlots(); x++) { 95 | final ItemStack is = crafting.getStackInSlot(x); 96 | if(!is.isEmpty()) is.setCount(1); 97 | } 98 | } 99 | 100 | @Override 101 | public ContainerType getType() { 102 | return Menus.PATTERN; 103 | } 104 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wpt/WPTItem.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wpt; 2 | 3 | import appeng.container.ContainerLocator; 4 | import appeng.core.AEConfig; 5 | import tfar.ae2wt.AE2WirelessTerminals; 6 | import tfar.ae2wt.terminal.IInfinityBoosterCardHolder; 7 | import tfar.ae2wt.terminal.AbstractWirelessTerminalItem; 8 | import net.minecraft.entity.player.PlayerEntity; 9 | 10 | public class WPTItem extends AbstractWirelessTerminalItem implements IInfinityBoosterCardHolder { 11 | 12 | public WPTItem() { 13 | super(AEConfig.instance().getWirelessTerminalBattery(), new Properties().group(AE2WirelessTerminals.ITEM_GROUP).maxStackSize(1)); 14 | } 15 | 16 | @Override 17 | public void open(final PlayerEntity player, final ContainerLocator locator) { 18 | WirelessPatternTerminalContainer.openServer(player, locator); 19 | } 20 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wpt/WirelessPatternTermSlot.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wpt; 2 | 3 | import appeng.api.networking.energy.IEnergySource; 4 | import appeng.api.networking.security.IActionSource; 5 | import appeng.api.storage.IStorageMonitorable; 6 | import appeng.api.storage.channels.IItemStorageChannel; 7 | import appeng.api.storage.data.IAEItemStack; 8 | import appeng.container.slot.IOptionalSlotHost; 9 | import appeng.container.slot.PatternTermSlot; 10 | import appeng.core.Api; 11 | import appeng.core.sync.BasePacket; 12 | import appeng.core.sync.packets.PatternSlotPacket; 13 | import appeng.helpers.IContainerCraftingPacket; 14 | import tfar.ae2wt.net.C2SPatternSlotPacket; 15 | import tfar.ae2wt.net.PacketHandler; 16 | import tfar.ae2wt.util.FixedEmptyInventory; 17 | import net.minecraft.entity.player.PlayerEntity; 18 | import net.minecraft.network.PacketBuffer; 19 | import net.minecraftforge.items.IItemHandler; 20 | 21 | import java.lang.reflect.Field; 22 | 23 | public class WirelessPatternTermSlot extends PatternTermSlot { 24 | 25 | 26 | public WirelessPatternTermSlot(PlayerEntity player, IActionSource mySrc, IEnergySource energySrc, IStorageMonitorable storage, IItemHandler cMatrix, IItemHandler secondMatrix, IOptionalSlotHost h, int groupNumber, IContainerCraftingPacket c) { 27 | super(player, mySrc, energySrc, storage, cMatrix, secondMatrix, h, groupNumber, c); 28 | } 29 | 30 | @Override 31 | public BasePacket getRequest(final boolean shift) { 32 | IItemHandler pattern = null; 33 | try { 34 | Field f = getClass().getSuperclass().getSuperclass().getDeclaredField("pattern"); 35 | f.setAccessible(true); 36 | pattern = (IItemHandler) f.get(this); 37 | f.setAccessible(false); 38 | } catch(IllegalAccessException | NoSuchFieldException ignored) {} 39 | 40 | if(pattern == null) 41 | return new PatternSlotPacket(new FixedEmptyInventory(9), Api.instance().storage().getStorageChannel(IItemStorageChannel.class).createStack(getStack()), shift); 42 | 43 | //todo this seems like an awful idea 44 | IAEItemStack[] stacks = new IAEItemStack[9]; 45 | for (int i = 0; i < 9; i++) { 46 | stacks[i] = Api.instance().storage().getStorageChannel(IItemStorageChannel.class).createStack(pattern.getStackInSlot(i)); 47 | } 48 | PacketHandler.INSTANCE.sendToServer(new C2SPatternSlotPacket(Api.instance().storage().getStorageChannel(IItemStorageChannel.class).createStack(getStack()),shift,stacks)); 49 | 50 | //This is just a stub. we don't actually use it, but this is the easiest (tho dirty) way to hack our own solution in 51 | return new PatternSlotPacket(pattern, Api.instance().storage().getStorageChannel(IItemStorageChannel.class).createStack(getStack()), shift); 52 | } 53 | 54 | private void writeItem(final IAEItemStack slotItem, final PacketBuffer data) { 55 | if(slotItem == null) data.writeBoolean(false); 56 | else { 57 | data.writeBoolean(true); 58 | slotItem.writeToPacket(data); 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wpt/WirelessPatternTerminalScreen.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wpt; 2 | 3 | import appeng.api.config.ActionItems; 4 | import appeng.client.gui.me.items.ItemTerminalScreen; 5 | import appeng.client.gui.style.Blitter; 6 | import appeng.client.gui.style.ScreenStyle; 7 | import appeng.client.gui.widgets.ActionButton; 8 | import appeng.client.gui.widgets.TabButton; 9 | import appeng.container.SlotSemantic; 10 | import appeng.core.localization.GuiText; 11 | import com.mojang.blaze3d.matrix.MatrixStack; 12 | import net.minecraft.block.Blocks; 13 | import net.minecraft.entity.player.PlayerInventory; 14 | import net.minecraft.item.ItemStack; 15 | import net.minecraft.util.text.ITextComponent; 16 | import tfar.ae2wt.net.PacketHandler; 17 | import tfar.ae2wt.net.server.C2SClearPatternPacket; 18 | import tfar.ae2wt.net.server.C2SEncodePatternPacket; 19 | import tfar.ae2wt.net.server.C2STogglePatternCraftingModePacket; 20 | import tfar.ae2wt.net.server.C2STogglePatternSubsitutionPacket; 21 | import tfar.ae2wt.wut.CycleTerminalButton; 22 | import tfar.ae2wt.wut.IUniversalTerminalCapable; 23 | 24 | public class WirelessPatternTerminalScreen extends ItemTerminalScreen implements IUniversalTerminalCapable { 25 | 26 | 27 | private static final boolean SUBSITUTION_DISABLE = false; 28 | private static final boolean SUBSITUTION_ENABLE = true; 29 | 30 | private static final boolean CRAFTMODE_CRAFTING = true; 31 | private static final boolean CRAFTMODE_PROCESSING = false; 32 | 33 | private final TabButton tabCraftButton; 34 | private final TabButton tabProcessButton; 35 | private final ActionButton substitutionsEnabledBtn; 36 | private final ActionButton substitutionsDisabledBtn; 37 | 38 | public WirelessPatternTerminalScreen(WirelessPatternTerminalContainer container, PlayerInventory playerInventory, ITextComponent title, ScreenStyle style) { 39 | super(container, playerInventory, title,style); 40 | 41 | tabCraftButton = new TabButton(new ItemStack(Blocks.CRAFTING_TABLE), GuiText.CraftingPattern.text(), itemRenderer, btn -> toggleCraftMode(CRAFTMODE_PROCESSING)); 42 | widgets.add("craftingPatternMode", tabCraftButton); 43 | 44 | tabProcessButton = new TabButton(new ItemStack(Blocks.FURNACE), GuiText.ProcessingPattern.text(), itemRenderer, btn -> toggleCraftMode(CRAFTMODE_CRAFTING)); 45 | widgets.add("processingPatternMode", tabProcessButton); 46 | 47 | substitutionsEnabledBtn = new ActionButton(ActionItems.ENABLE_SUBSTITUTION, act -> toggleSubstitutions(SUBSITUTION_DISABLE)); 48 | substitutionsEnabledBtn.setHalfSize(true); 49 | widgets.add("substitutionsEnabled", substitutionsEnabledBtn); 50 | 51 | substitutionsDisabledBtn = new ActionButton(ActionItems.DISABLE_SUBSTITUTION, act -> toggleSubstitutions(SUBSITUTION_ENABLE)); 52 | substitutionsDisabledBtn.setHalfSize(true); 53 | widgets.add("substitutionsDisabled", substitutionsDisabledBtn); 54 | 55 | ActionButton clearBtn = addButton(new ActionButton(ActionItems.CLOSE, btn -> clear())); 56 | clearBtn.setHalfSize(true); 57 | widgets.add("clearPattern", clearBtn); 58 | widgets.add("encodePattern", new ActionButton(ActionItems.ENCODE, act -> encode())); 59 | 60 | if(container.isWUT()) widgets.add("cycleTerminal", new CycleTerminalButton(btn -> cycleTerminal())); 61 | } 62 | 63 | private void toggleCraftMode(boolean mode) { 64 | PacketHandler.INSTANCE.sendToServer(new C2STogglePatternCraftingModePacket(mode)); 65 | } 66 | 67 | private void toggleSubstitutions(boolean mode) { 68 | PacketHandler.INSTANCE.sendToServer(new C2STogglePatternSubsitutionPacket(mode)); 69 | } 70 | 71 | private void encode() { 72 | PacketHandler.INSTANCE.sendToServer(new C2SEncodePatternPacket()); 73 | } 74 | 75 | private void clear() { 76 | PacketHandler.INSTANCE.sendToServer(new C2SClearPatternPacket()); 77 | } 78 | 79 | @Override 80 | protected void updateBeforeRender() { 81 | super.updateBeforeRender(); 82 | if(container.isCraftingMode()) { 83 | tabCraftButton.visible = true; 84 | tabProcessButton.visible = false; 85 | if(container.substitute) { 86 | substitutionsEnabledBtn.visible = true; 87 | substitutionsDisabledBtn.visible = false; 88 | } else { 89 | substitutionsEnabledBtn.visible = false; 90 | substitutionsDisabledBtn.visible = true; 91 | } 92 | } else { 93 | tabCraftButton.visible = false; 94 | tabProcessButton.visible = true; 95 | substitutionsEnabledBtn.visible = false; 96 | substitutionsDisabledBtn.visible = false; 97 | } 98 | 99 | setSlotsHidden(SlotSemantic.CRAFTING_RESULT, !container.isCraftingMode()); 100 | setSlotsHidden(SlotSemantic.PROCESSING_RESULT, container.isCraftingMode()); 101 | } 102 | 103 | @Override 104 | public void drawBG(MatrixStack matrixStack, int offsetX, int offsetY, int mouseX, int mouseY, float partialTicks) { 105 | super.drawBG(matrixStack, offsetX, offsetY, mouseX, mouseY, partialTicks); 106 | if(container.isCraftingMode()) return; 107 | Blitter.texture("guis/pattern_modes.png").src(100, 77, 18, 54).dest(guiLeft + 109, guiTop + ySize - 159).blit(matrixStack, getBlitOffset()); 108 | } 109 | 110 | /*@Override 111 | public List getExclusionZones() { 112 | List zones = super.getExclusionZones(); 113 | zones.add(new Rectangle(guiLeft + 195, y, 24, backgroundHeight-110)); 114 | return zones; 115 | }*/ 116 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wut/CycleTerminalButton.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wut; 2 | 3 | import appeng.client.gui.widgets.ITooltip; 4 | import com.mojang.blaze3d.matrix.MatrixStack; 5 | import com.mojang.blaze3d.systems.RenderSystem; 6 | import net.minecraft.client.Minecraft; 7 | import net.minecraft.client.gui.widget.button.Button; 8 | import net.minecraft.client.renderer.texture.TextureManager; 9 | import net.minecraft.util.ResourceLocation; 10 | import net.minecraft.util.text.ITextComponent; 11 | import net.minecraft.util.text.TranslationTextComponent; 12 | 13 | public class CycleTerminalButton extends Button implements ITooltip { 14 | 15 | public CycleTerminalButton(IPressable onPress) { 16 | super(0, 0, 16, 16, new TranslationTextComponent("gui.ae2wtlib.cycle_terminal"), onPress); 17 | visible = true; 18 | active = true; 19 | } 20 | 21 | // @Override 22 | // public ITextComponent getTooltipMessage() { 23 | // return new TranslationTextComponent("gui.ae2wtlib.cycle_terminal.desc"); 24 | // } 25 | 26 | @Override 27 | public int getTooltipAreaX() { 28 | return x; 29 | } 30 | 31 | @Override 32 | public int getTooltipAreaY() { 33 | return y; 34 | } 35 | 36 | @Override 37 | public int getTooltipAreaWidth() { 38 | return 16; 39 | } 40 | 41 | @Override 42 | public int getTooltipAreaHeight() { 43 | return 16; 44 | } 45 | 46 | @Override 47 | public boolean isTooltipAreaVisible() { 48 | return true;//TODO 49 | } 50 | 51 | public static final ResourceLocation TEXTURE_STATES = new ResourceLocation("appliedenergistics2", "textures/guis/states.png"); 52 | 53 | @Override 54 | public void render(MatrixStack matrices, final int mouseX, final int mouseY, float partial) { 55 | Minecraft minecraft = Minecraft.getInstance(); 56 | if(this.visible) { 57 | final int iconIndex = 6; 58 | 59 | TextureManager textureManager = minecraft.getTextureManager(); 60 | textureManager.bindTexture(TEXTURE_STATES); 61 | RenderSystem.disableDepthTest(); 62 | RenderSystem.enableBlend(); 63 | 64 | if(this.active) RenderSystem.color4f(1.0f, 1.0f, 1.0f, 1.0f); 65 | else RenderSystem.color4f(0.5f, 0.5f, 0.5f, 1.0f); 66 | 67 | final int uv_y = iconIndex / 16; 68 | 69 | blit(matrices, this.x, this.y, 256 - 16, 256 - 16, 16, 16); 70 | blit(matrices, this.x, this.y, iconIndex * 16, uv_y * 16, 16, 16); 71 | 72 | RenderSystem.enableDepthTest(); 73 | RenderSystem.color4f(1.0f, 1.0f, 1.0f, 1.0f); 74 | 75 | if(isHovered()) renderToolTip(matrices, mouseX, mouseY); 76 | } 77 | } 78 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wut/IUniversalTerminalCapable.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wut; 2 | 3 | import tfar.ae2wt.net.C2SCycleTerminalPacket; 4 | import tfar.ae2wt.net.PacketHandler; 5 | 6 | public interface IUniversalTerminalCapable { 7 | default void cycleTerminal() { 8 | PacketHandler.INSTANCE.sendToServer(new C2SCycleTerminalPacket()); 9 | } 10 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wut/WUTHandler.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wut; 2 | 3 | import appeng.container.ContainerLocator; 4 | import net.minecraft.entity.player.PlayerEntity; 5 | import net.minecraft.item.ItemStack; 6 | import net.minecraft.util.text.StringTextComponent; 7 | 8 | import java.util.ArrayList; 9 | import java.util.HashMap; 10 | import java.util.List; 11 | 12 | public class WUTHandler { 13 | public static boolean hasTerminal(ItemStack itemStack, String terminal) { 14 | if(!terminalNames.contains(terminal)) return false; 15 | if(itemStack.getTag() == null) return false; 16 | return itemStack.getTag().getBoolean(terminal); 17 | } 18 | 19 | public static String getCurrentTerminal(ItemStack wirelessUniversalTerminal) { 20 | if(!(wirelessUniversalTerminal.getItem() instanceof WUTItem) || wirelessUniversalTerminal.getTag() == null) 21 | return "noTerminal"; 22 | String currentTerminal = wirelessUniversalTerminal.getTag().getString("currentTerminal"); 23 | 24 | if(!wirelessTerminals.containsKey(currentTerminal)) for(String terminal : terminalNames) 25 | if(wirelessUniversalTerminal.getTag().getBoolean(terminal)) { 26 | currentTerminal = terminal; 27 | wirelessUniversalTerminal.getTag().putString("currentTerminal", currentTerminal); 28 | break; 29 | } 30 | return currentTerminal; 31 | } 32 | 33 | public static void cycle(ItemStack itemStack) { 34 | if(itemStack.getTag() == null) return; 35 | String nextTerminal = itemStack.getTag().getString("currentTerminal"); 36 | do { 37 | int i = terminalNames.indexOf(nextTerminal) + 1; 38 | if(i == terminalNames.size()) i = 0; 39 | nextTerminal = terminalNames.get(i); 40 | } while(!itemStack.getTag().getBoolean(nextTerminal)); 41 | itemStack.getTag().putString("currentTerminal", nextTerminal); 42 | } 43 | 44 | public static void open(final PlayerEntity player, final ContainerLocator locator) { 45 | ItemStack is = player.inventory.getStackInSlot(locator.getItemIndex()); 46 | if(is.getTag() == null) return; 47 | String currentTerminal = is.getTag().getString("currentTerminal"); 48 | 49 | if(!wirelessTerminals.containsKey(currentTerminal)) for(String terminal : terminalNames) 50 | if(is.getTag().getBoolean(terminal)) { 51 | currentTerminal = terminal; 52 | is.getTag().putString("currentTerminal", currentTerminal); 53 | break; 54 | } 55 | if(!wirelessTerminals.containsKey(currentTerminal)) { 56 | player.sendStatusMessage(new StringTextComponent("This terminal does not contain any other Terminals"), false); 57 | return; 58 | } 59 | wirelessTerminals.get(currentTerminal).open(player, locator); 60 | } 61 | 62 | private static final HashMap wirelessTerminals = new HashMap<>(); 63 | public static final List terminalNames = new ArrayList<>(); 64 | 65 | public static void addTerminal(String Name, containerOpener open) { 66 | if(terminalNames.contains(Name)) return; 67 | wirelessTerminals.put(Name, open); 68 | terminalNames.add(Name); 69 | } 70 | 71 | @FunctionalInterface 72 | public interface containerOpener { 73 | void open(final PlayerEntity player, final ContainerLocator locator); 74 | } 75 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wut/WUTItem.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wut; 2 | 3 | import appeng.container.ContainerLocator; 4 | import appeng.core.AEConfig; 5 | import net.minecraft.util.text.Style; 6 | import net.minecraft.util.text.TextFormatting; 7 | import tfar.ae2wt.AE2WirelessTerminals; 8 | import tfar.ae2wt.terminal.IInfinityBoosterCardHolder; 9 | import tfar.ae2wt.terminal.AbstractWirelessTerminalItem; 10 | import net.minecraft.client.util.ITooltipFlag; 11 | import net.minecraft.entity.player.PlayerEntity; 12 | import net.minecraft.item.Item; 13 | import net.minecraft.item.ItemStack; 14 | import net.minecraft.util.text.ITextComponent; 15 | import net.minecraft.util.text.TranslationTextComponent; 16 | import net.minecraft.world.World; 17 | import net.minecraftforge.api.distmarker.Dist; 18 | import net.minecraftforge.api.distmarker.OnlyIn; 19 | 20 | import java.util.List; 21 | 22 | public class WUTItem extends AbstractWirelessTerminalItem implements IInfinityBoosterCardHolder { 23 | 24 | public WUTItem() { 25 | super(AEConfig.instance().getWirelessTerminalBattery(), new Item.Properties().group(AE2WirelessTerminals.ITEM_GROUP).maxStackSize(1)); 26 | } 27 | 28 | @Override 29 | public void open(final PlayerEntity player, final ContainerLocator locator) { 30 | WUTHandler.open(player, locator); 31 | } 32 | 33 | @Override 34 | @OnlyIn(Dist.CLIENT) 35 | public void addInformation(final ItemStack stack, final World world, final List lines, final ITooltipFlag advancedTooltips) { 36 | lines.add(new TranslationTextComponent("item.ae2wtlib.wireless_universal_terminal.desc").setStyle(Style.EMPTY.applyFormatting(TextFormatting.GRAY))); 37 | if(WUTHandler.hasTerminal(stack, "crafting")) lines.add(new TranslationTextComponent("item.ae2wtlib.wireless_crafting_terminal").setStyle(Style.EMPTY.applyFormatting(TextFormatting.GRAY))); 38 | if(WUTHandler.hasTerminal(stack, "interface")) lines.add(new TranslationTextComponent("item.ae2wtlib.wireless_interface_terminal").setStyle(Style.EMPTY.applyFormatting(TextFormatting.GRAY))); 39 | if(WUTHandler.hasTerminal(stack, "pattern")) lines.add(new TranslationTextComponent("item.ae2wtlib.wireless_pattern_terminal").setStyle(Style.EMPTY.applyFormatting(TextFormatting.GRAY))); 40 | super.addInformation(stack, world, lines, advancedTooltips); 41 | } 42 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wut/recipe/Combine.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wut.recipe; 2 | 3 | import net.minecraft.inventory.CraftingInventory; 4 | import net.minecraft.item.ItemStack; 5 | import net.minecraft.item.crafting.Ingredient; 6 | import net.minecraft.nbt.CompoundNBT; 7 | import net.minecraft.util.NonNullList; 8 | import net.minecraft.util.ResourceLocation; 9 | import net.minecraft.world.World; 10 | 11 | public class Combine extends Common { 12 | private final Ingredient TerminalA; 13 | private final Ingredient TerminalB; 14 | private final String TerminalAName; 15 | private final String TerminalBName; 16 | 17 | public Combine(Ingredient TerminalA, Ingredient TerminalB, String TerminalAName, String TerminalBName, ResourceLocation id) { 18 | super(id); 19 | this.TerminalA = TerminalA; 20 | this.TerminalB = TerminalB; 21 | this.TerminalAName = TerminalAName; 22 | this.TerminalBName = TerminalBName; 23 | if(!outputStack.hasTag()) outputStack.setTag(new CompoundNBT()); 24 | outputStack.getTag().putBoolean(TerminalAName, true); 25 | outputStack.getTag().putBoolean(TerminalBName, true); 26 | } 27 | 28 | public Ingredient getTerminalA() { 29 | return TerminalA; 30 | } 31 | 32 | public Ingredient getTerminalB() { 33 | return TerminalB; 34 | } 35 | 36 | public String getTerminalAName() { 37 | return TerminalAName; 38 | } 39 | 40 | public String getTerminalBName() { 41 | return TerminalBName; 42 | } 43 | 44 | @Override 45 | public boolean matches(CraftingInventory inv, World world) { 46 | return !InputHelper.getInputStack(inv, TerminalA).isEmpty() && !InputHelper.getInputStack(inv, TerminalB).isEmpty() && InputHelper.getInputCount(inv) == 2; 47 | } 48 | 49 | @Override 50 | public ItemStack getCraftingResult(CraftingInventory inv) { 51 | CompoundNBT terminalA = InputHelper.getInputStack(inv, TerminalA).getTag(); 52 | if(terminalA == null) terminalA = new CompoundNBT(); 53 | else terminalA = terminalA.copy(); 54 | 55 | CompoundNBT terminalB = InputHelper.getInputStack(inv, TerminalB).getTag(); 56 | if(terminalB == null) terminalB = new CompoundNBT(); 57 | else terminalB = terminalB.copy(); 58 | 59 | ItemStack wut = outputStack.copy(); 60 | wut.getTag().merge(terminalB).merge(terminalA); 61 | return wut; 62 | } 63 | 64 | @Override 65 | public Serializer getSerializer() { 66 | return CombineSerializer.INSTANCE; 67 | } 68 | 69 | public NonNullList getIngredients() { 70 | NonNullList inputs = NonNullList.create(); 71 | inputs.add(TerminalA); 72 | inputs.add(TerminalB); 73 | return inputs; 74 | } 75 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wut/recipe/CombineJsonFormat.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wut.recipe; 2 | 3 | import com.google.gson.JsonObject; 4 | 5 | public class CombineJsonFormat { 6 | JsonObject TerminalA; 7 | JsonObject TerminalB; 8 | String TerminalAName; 9 | String TerminalBName; 10 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wut/recipe/CombineSerializer.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wut.recipe; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.JsonObject; 5 | import com.google.gson.JsonSyntaxException; 6 | import net.minecraft.item.crafting.IRecipeSerializer; 7 | import net.minecraft.item.crafting.Ingredient; 8 | import net.minecraft.network.PacketBuffer; 9 | import net.minecraft.util.ResourceLocation; 10 | 11 | import javax.annotation.Nullable; 12 | 13 | public class CombineSerializer extends Serializer { 14 | public static final CombineSerializer INSTANCE = new CombineSerializer(); 15 | 16 | public static final ResourceLocation ID = new ResourceLocation("ae2wtlib", "combine"); 17 | 18 | @Override 19 | public Combine read(ResourceLocation id, JsonObject json) { 20 | CombineJsonFormat recipeJson = new Gson().fromJson(json, CombineJsonFormat.class); 21 | if(recipeJson.TerminalA == null || recipeJson.TerminalB == null || validateOutput(recipeJson.TerminalAName) || validateOutput(recipeJson.TerminalBName)) 22 | throw new JsonSyntaxException("A required attribute is missing or invalid!"); 23 | 24 | Ingredient TerminalA = Ingredient.deserialize(recipeJson.TerminalA); 25 | Ingredient TerminalB = Ingredient.deserialize(recipeJson.TerminalB); 26 | 27 | return new Combine(TerminalA, TerminalB, recipeJson.TerminalAName, recipeJson.TerminalBName, id); 28 | } 29 | 30 | @Override 31 | public void write(PacketBuffer packetData, Combine recipe) { 32 | recipe.getTerminalA().write(packetData); 33 | recipe.getTerminalB().write(packetData); 34 | packetData.writeString(recipe.getTerminalAName()); 35 | packetData.writeString(recipe.getTerminalBName()); 36 | } 37 | 38 | @Override 39 | public Combine read(ResourceLocation id, PacketBuffer packetData) { 40 | Ingredient TerminalA = Ingredient.read(packetData); 41 | Ingredient TerminalB = Ingredient.read(packetData); 42 | String TerminalAName = packetData.readString(32767); 43 | String TerminalBName = packetData.readString(32767); 44 | return new Combine(TerminalA, TerminalB, TerminalAName, TerminalBName, id); 45 | } 46 | 47 | @Override 48 | public IRecipeSerializer setRegistryName(ResourceLocation name) { 49 | return this; 50 | } 51 | 52 | @Nullable 53 | @Override 54 | public ResourceLocation getRegistryName() { 55 | return ID; 56 | } 57 | 58 | @Override 59 | public Class> getRegistryType() { 60 | return null; 61 | } 62 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wut/recipe/Common.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wut.recipe; 2 | 3 | import net.minecraft.item.ItemStack; 4 | import net.minecraft.item.crafting.ICraftingRecipe; 5 | import net.minecraft.util.ResourceLocation; 6 | import tfar.ae2wt.init.ModItems; 7 | 8 | public abstract class Common implements ICraftingRecipe { 9 | 10 | protected final ItemStack outputStack = new ItemStack(ModItems.UNIVERSAL_TERMINAL); 11 | protected final ResourceLocation id; 12 | 13 | protected Common(ResourceLocation id) { 14 | this.id = id; 15 | } 16 | 17 | 18 | @Override 19 | public boolean canFit(int width, int height) { 20 | return width > 1 || height > 1; 21 | } 22 | 23 | @Override 24 | public ItemStack getRecipeOutput() { 25 | return outputStack; 26 | } 27 | 28 | @Override 29 | public ResourceLocation getId() { 30 | return id; 31 | } 32 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wut/recipe/InputHelper.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wut.recipe; 2 | 3 | import net.minecraft.inventory.CraftingInventory; 4 | import net.minecraft.item.ItemStack; 5 | import net.minecraft.item.crafting.Ingredient; 6 | import tfar.ae2wt.init.ModItems; 7 | 8 | public class InputHelper { 9 | 10 | public static ItemStack getInputStack(CraftingInventory inventory, Ingredient ingredient) { 11 | for(int i = 0; i < inventory.getSizeInventory(); i++) 12 | if(ingredient.test(inventory.getStackInSlot(i))) return inventory.getStackInSlot(i); 13 | return ItemStack.EMPTY; 14 | } 15 | 16 | public static int getInputCount(CraftingInventory inventory) { 17 | int count = 0; 18 | for(int i = 0; i < inventory.getSizeInventory(); i++) if(!inventory.getStackInSlot(i).isEmpty()) count++; 19 | return count; 20 | } 21 | 22 | public static Ingredient wut = Ingredient.fromItems(ModItems.UNIVERSAL_TERMINAL); 23 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wut/recipe/Serializer.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wut.recipe; 2 | 3 | import net.minecraft.item.crafting.IRecipeSerializer; 4 | import tfar.ae2wt.wut.WUTHandler; 5 | 6 | public abstract class Serializer implements IRecipeSerializer { 7 | protected boolean validateOutput(String s) { 8 | if(s == null) return true; 9 | return !WUTHandler.terminalNames.contains(s); 10 | } 11 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wut/recipe/Upgrade.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wut.recipe; 2 | 3 | import net.minecraft.inventory.CraftingInventory; 4 | import net.minecraft.item.ItemStack; 5 | import net.minecraft.item.crafting.Ingredient; 6 | import net.minecraft.nbt.CompoundNBT; 7 | import net.minecraft.util.NonNullList; 8 | import net.minecraft.util.ResourceLocation; 9 | import net.minecraft.world.World; 10 | import tfar.ae2wt.wut.WUTHandler; 11 | 12 | public class Upgrade extends Common { 13 | private final Ingredient Terminal; 14 | private final String TerminalName; 15 | 16 | public Upgrade(Ingredient Terminal, String TerminalName, ResourceLocation id) { 17 | super(id); 18 | this.Terminal = Terminal; 19 | this.TerminalName = TerminalName; 20 | if(!outputStack.hasTag()) outputStack.setTag(new CompoundNBT()); 21 | outputStack.getTag().putBoolean(TerminalName, true); 22 | } 23 | 24 | public Ingredient getTerminal() { 25 | return Terminal; 26 | } 27 | 28 | public String getTerminalName() { 29 | return TerminalName; 30 | } 31 | 32 | @Override 33 | public boolean matches(CraftingInventory inv, World world) { 34 | ItemStack wut = InputHelper.getInputStack(inv, InputHelper.wut); 35 | return !InputHelper.getInputStack(inv, Terminal).isEmpty() && !wut.isEmpty() 36 | && InputHelper.getInputCount(inv) == 2 && !WUTHandler.hasTerminal(wut, TerminalName); 37 | } 38 | 39 | @Override 40 | public ItemStack getCraftingResult(CraftingInventory inv) { 41 | ItemStack wut = InputHelper.getInputStack(inv, InputHelper.wut).copy(); 42 | CompoundNBT terminal = InputHelper.getInputStack(inv, Terminal).getTag().copy(); 43 | wut.getTag().putBoolean(TerminalName, true); 44 | terminal.merge(wut.getTag()); 45 | wut.setTag(terminal); 46 | 47 | return wut; 48 | } 49 | 50 | @Override 51 | public Serializer getSerializer() { 52 | return UpgradeSerializer.INSTANCE; 53 | } 54 | 55 | public NonNullList getIngredients() { 56 | NonNullList inputs = NonNullList.create(); 57 | inputs.add(Terminal); 58 | inputs.add(InputHelper.wut); 59 | return inputs; 60 | } 61 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wut/recipe/UpgradeJsonFormat.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wut.recipe; 2 | 3 | import com.google.gson.JsonObject; 4 | 5 | public class UpgradeJsonFormat { 6 | JsonObject Terminal; 7 | String TerminalName; 8 | } -------------------------------------------------------------------------------- /src/main/java/tfar/ae2wt/wut/recipe/UpgradeSerializer.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.wut.recipe; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.JsonObject; 5 | import com.google.gson.JsonSyntaxException; 6 | import net.minecraft.item.crafting.IRecipeSerializer; 7 | import net.minecraft.item.crafting.Ingredient; 8 | import net.minecraft.network.PacketBuffer; 9 | import net.minecraft.util.ResourceLocation; 10 | 11 | import javax.annotation.Nullable; 12 | 13 | public class UpgradeSerializer extends Serializer { 14 | public static final UpgradeSerializer INSTANCE = new UpgradeSerializer(); 15 | 16 | public static final ResourceLocation ID = new ResourceLocation("ae2wtlib", "upgrade"); 17 | 18 | @Override 19 | public Upgrade read(ResourceLocation id, JsonObject json) { 20 | UpgradeJsonFormat recipeJson = new Gson().fromJson(json, UpgradeJsonFormat.class); 21 | if(recipeJson.Terminal == null || validateOutput(recipeJson.TerminalName)) 22 | throw new JsonSyntaxException("A required attribute is missing or invalid!"); 23 | 24 | Ingredient Terminal = Ingredient.deserialize(recipeJson.Terminal); 25 | 26 | return new Upgrade(Terminal, recipeJson.TerminalName, id); 27 | } 28 | 29 | @Override 30 | public void write(PacketBuffer packetData, Upgrade recipe) { 31 | recipe.getTerminal().write(packetData); 32 | packetData.writeString(recipe.getTerminalName()); 33 | } 34 | 35 | @Override 36 | public Upgrade read(ResourceLocation id, PacketBuffer packetData) { 37 | Ingredient TerminalA = Ingredient.read(packetData); 38 | String TerminalAName = packetData.readString(32767); 39 | return new Upgrade(TerminalA, TerminalAName, id); 40 | } 41 | 42 | @Override 43 | public IRecipeSerializer setRegistryName(ResourceLocation name) { 44 | return this; 45 | } 46 | 47 | @Nullable 48 | @Override 49 | public ResourceLocation getRegistryName() { 50 | return ID; 51 | } 52 | 53 | @Override 54 | public Class> getRegistryType() { 55 | return null; 56 | } 57 | } -------------------------------------------------------------------------------- /src/main/resources/META-INF/mods.toml: -------------------------------------------------------------------------------- 1 | # This is an example mods.toml file. It contains the data relating to the loading mods. 2 | # There are several mandatory fields (#mandatory), and many more that are optional (#optional). 3 | # The overall format is standard TOML format, v0.5.0. 4 | # Note that there are a couple of TOML lists in this file. 5 | # Find more information on toml format here: https://github.com/toml-lang/toml 6 | # The name of the mod loader type to load - for regular FML @Mod mods it should be javafml 7 | modLoader="javafml" #mandatory 8 | # A version range to match for said mod loader - for regular FML @Mod it will be the forge version 9 | loaderVersion="[34,)" #mandatory (32 is current forge version) 10 | # A URL to refer people to when problems occur with this mod 11 | issueTrackerURL="https://github.com/Tfarcenim/AE2WirelessTerminalLibrary/issues/" #optional 12 | # A list of mods - how many allowed here is determined by the individual mod loader 13 | license="Unlicense" 14 | [[mods]] #mandatory 15 | # The modid of the mod 16 | modId="ae2wtlib" #mandatory 17 | # The version number of the mod - there's a few well known ${} variables useable here or just hardcode it 18 | version="${file.jarVersion}" #mandatory 19 | # A display name for the mod 20 | displayName="AE2 Wireless Terminals" #mandatory 21 | # A URL to query for updates for this mod. See the JSON update specification 22 | #updateJSONURL="http://myurl.me/" #optional 23 | # A URL for the "homepage" for this mod, displayed in the mod UI 24 | #displayURL="http://example.com/" #optional 25 | # A file name (in the root of the mod JAR) containing a logo for display 26 | #logoFile="cursedearth.png" #optional 27 | # A text field displayed in the mod UI 28 | #credits="Thanks for this example mod goes to Java" #optional 29 | # A text field displayed in the mod UI 30 | authors="mari_023,Tfarecnim" #optional 31 | # The description text for the mod (multi line!) (#mandatory) 32 | description=''' 33 | 34 | A Library which provides basic functions to create AE2 Wireless Terminals with infinite range capabilities 35 | ''' 36 | [[dependencies.ae2twlib]] #optional 37 | # the modid of the dependency 38 | modId="appliedenergistics2" #mandatory 39 | # Does this dependency have to exist - if not, ordering below must be specified 40 | mandatory=true #mandatory 41 | # The version range of the dependency 42 | versionRange="[8.4.0,)" #mandatory 43 | # An ordering relationship for the dependency - BEFORE or AFTER required if the relationship is not mandatory 44 | ordering="NONE" 45 | # Side this dependency is applied on - BOTH, CLIENT or SERVER 46 | side="BOTH" 47 | 48 | -------------------------------------------------------------------------------- /src/main/resources/ae2wtlib.mixins.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "minVersion": "0.8", 4 | "package": "tfar.ae2wt.mixin", 5 | "compatibilityLevel": "JAVA_8", 6 | "refmap": "ae2wtlib.refmap.json", 7 | "mixins": [ 8 | "AEBaseContainerAccess", 9 | "ContainerAccess", 10 | "ContainerTypeBuilderMixin", 11 | "CraftConfirmContainerMixin", 12 | "InvActionPacketMixin", 13 | "PlayerInventoryMixin" 14 | ], 15 | "client": [ 16 | "AESubScreenMixin", 17 | "MeMonitorableScreenWireless" 18 | ], 19 | "injectors": { 20 | "defaultRequire": 1 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/resources/assets/ae2wtlib/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tfarcenim/AE2WirelessTerminalLibrary/9ef7893c8aaed44babeb3590e37524ab096c81f5/src/main/resources/assets/ae2wtlib/icon.png -------------------------------------------------------------------------------- /src/main/resources/assets/ae2wtlib/lang/de_de.json: -------------------------------------------------------------------------------- 1 | { 2 | "itemGroup.ae2wtlib.general": "AE2 Drahtlose Zugangskonsolen (AE2WTLib)", 3 | "key.category.ae2wtlib": "AE2 Drahtlose Zugangskonsolen (AE2WTLib)", 4 | 5 | "gui.ae2wtlib.emptytrash": "Müll löschen", 6 | "gui.ae2wtlib.emptytrash.desc": "Löscht den Inhalt des Müll slots", 7 | 8 | "item.ae2wtlib.infinity_booster_card": "Unendlicher Drahtlosverstärker", 9 | "item.ae2wtlib.infinity_booster_card.desc": "Erweitert die Reichweite von Drahtloskonsolen ins unendliche", 10 | "item.ae2wtlib.magnet_card": "Magnet Karte", 11 | "item.ae2wtlib.magnet_card.desc": "Magnet Upgrade für die Drahtlose Fertigungskonsole", 12 | "gui.ae2wtlib.magnet_card": "Magnet Karte", 13 | "gui.ae2wtlib.magnetcard.desc.off": "Aus", 14 | "gui.ae2wtlib.magnetcard.desc.inv": "Items werden in das Inventar eingesammelt", 15 | "gui.ae2wtlib.magnetcard.desc.me": "Items werden in das Inventar eingesammelt", 16 | "gui.ae2wtlib.cycle_terminal.desc": "nächste Konsole Öffnen", 17 | 18 | "item.ae2wtlib.wireless_crafting_terminal": "Drahtlose Fertigungskonsole", 19 | "item.ae2wtlib.wireless_pattern_terminal": "Drahtlose Schablonenkonsole", 20 | "item.ae2wtlib.wireless_interface_terminal": "Drahtlose Schnittstellenkonsole", 21 | "item.ae2wtlib.wireless_universal_terminal": "Drahtlose Universalkonsole", 22 | "item.ae2wtlib.wireless_universal_terminal.desc": "Installierte Konsolen:", 23 | 24 | "key.ae2wtlib.wct": "Drahtlose Fertigungskonsole Öffnen", 25 | "key.ae2wtlib.wpt": "Drahtlose Schablonenkonsole Öffnen", 26 | "key.ae2wtlib.wit": "Drahtlose Schnittstellenkonsole Öffnen" 27 | } -------------------------------------------------------------------------------- /src/main/resources/assets/ae2wtlib/lang/en_us.json: -------------------------------------------------------------------------------- 1 | { 2 | "itemGroup.ae2wtlib.general": "AE2 Wireless Terminals (AE2WTLib)", 3 | "key.category.ae2wtlib": "AE2 Wireless Terminals (AE2WTLib)", 4 | 5 | "gui.ae2wtlib.emptytrash": "Empty Trash", 6 | "gui.ae2wtlib.emptytrash.desc": "Delete contents of the Trash slot", 7 | 8 | "item.ae2wtlib.infinity_booster_card": "Infinity Booster Card", 9 | "item.ae2wtlib.infinity_booster_card.desc": "Expands Wireless Terminals to infinity", 10 | "item.ae2wtlib.magnet_card": "Magnet Card", 11 | "item.ae2wtlib.magnet_card.desc": "Magnet upgrade for the Wireless Crafting Terminal", 12 | "gui.ae2wtlib.magnet_card": "Magnet Card", 13 | "gui.ae2wtlib.magnetcard.desc.off": "Off", 14 | "gui.ae2wtlib.magnetcard.desc.inv": "Pickup to Inventory", 15 | "gui.ae2wtlib.magnetcard.desc.me": "Pickup to ME", 16 | "gui.ae2wtlib.cycle_terminal.desc": "Open next Terminal", 17 | 18 | "item.ae2wtlib.wireless_crafting_terminal": "Wireless Crafting Terminal", 19 | "item.ae2wtlib.wireless_pattern_terminal": "Wireless Pattern Terminal", 20 | "item.ae2wtlib.wireless_interface_terminal": "Wireless Interface Terminal", 21 | "item.ae2wtlib.wireless_universal_terminal": "Wireless Universal Terminal", 22 | "item.ae2wtlib.wireless_universal_terminal.desc": "Installed Terminals:", 23 | 24 | "key.ae2wtlib.wct": "Open Wireless Crafting Terminal", 25 | "key.ae2wtlib.wpt": "Open Wireless Pattern Terminal", 26 | "key.ae2wtlib.wit": "Open Wireless Interface Terminal" 27 | } -------------------------------------------------------------------------------- /src/main/resources/assets/ae2wtlib/lang/ru_ru.json: -------------------------------------------------------------------------------- 1 | { 2 | "itemGroup.ae2wtlib.general": "AE2 Wireless Terminals (AE2WTLib)", 3 | "key.category.ae2wtlib": "AE2 Wireless Terminals (AE2WTLib)", 4 | 5 | "gui.ae2wtlib.emptytrash": "Пустая мусорная корзина", 6 | "gui.ae2wtlib.emptytrash.desc": "Удаляет содержимое слота Мусорной корзины.", 7 | 8 | "item.ae2wtlib.infinity_booster_card": "Бесконечная карта-ускоритель", 9 | "item.ae2wtlib.infinity_booster_card.desc": "Расширяет Беспроводные терминалы до бесконечности.", 10 | "item.ae2wtlib.magnet_card": "Магнитная карта", 11 | "item.ae2wtlib.magnet_card.desc": "Магнитное улучшения для Беспроводного терминала изготовления.", 12 | "gui.ae2wtlib.magnet_card": "Магнитная карта", 13 | "gui.ae2wtlib.magnetcard.desc.off": "Выключена", 14 | "gui.ae2wtlib.magnetcard.desc.inv": "Подбирать в Инвентарь", 15 | "gui.ae2wtlib.magnetcard.desc.me": "Подбирать в МЕ", 16 | "gui.ae2wtlib.cycle_terminal.desc": "Открыть следующий Терминал", 17 | 18 | "item.ae2wtlib.wireless_crafting_terminal": "Беспроводной терминал изготовления", 19 | "item.ae2wtlib.wireless_pattern_terminal": "Беспроводной шаблон терминала", 20 | "item.ae2wtlib.wireless_interface_terminal": "Беспроводной интерфейс терминала", 21 | "item.ae2wtlib.wireless_universal_terminal": "Беспроводной универсальный терминал", 22 | "item.ae2wtlib.wireless_universal_terminal.desc": "Терминалов установлено:", 23 | 24 | "key.ae2wtlib.wct": "Открыть Беспроводной терминал изготовления", 25 | "key.ae2wtlib.wpt": "Открыть Беспроводной шаблон терминала", 26 | "key.ae2wtlib.wit": "Открыть Беспроводной интерфейс терминал" 27 | } 28 | -------------------------------------------------------------------------------- /src/main/resources/assets/ae2wtlib/lang/zh_cn.json: -------------------------------------------------------------------------------- 1 | { 2 | "itemGroup.ae2wtlib.general": "AE2无线终端(AE2WTLib)", 3 | "key.category.ae2wtlib": "AE2无线终端(AE2WTLib)", 4 | 5 | "gui.ae2wtlib.emptytrash": "清空垃圾桶", 6 | "gui.ae2wtlib.emptytrash.desc": "删除垃圾桶内的物品", 7 | 8 | "item.ae2wtlib.infinity_booster_card": "无限增幅卡", 9 | "item.ae2wtlib.magnet_card": "磁卡", 10 | "outdated.item.ae2wtlib.magnet_card.desc": "尚未实现", 11 | 12 | "item.ae2wtlib.wireless_crafting_terminal": "无线合成终端", 13 | "item.ae2wtlib.wireless_pattern_terminal": "无线样板终端", 14 | "item.ae2wtlib.wireless_interface_terminal": "无线接口终端" 15 | } -------------------------------------------------------------------------------- /src/main/resources/assets/ae2wtlib/models/item/infinity_booster_card.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "ae2wtlib:infinity_booster_card" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/ae2wtlib/models/item/magnet_card.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "ae2wtlib:magnet_card" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/ae2wtlib/models/item/wireless_crafting_terminal.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "ae2wtlib:wireless_crafting_terminal" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/ae2wtlib/models/item/wireless_interface_terminal.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "ae2wtlib:wireless_interface_terminal" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/ae2wtlib/models/item/wireless_pattern_terminal.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "ae2wtlib:wireless_pattern_terminal" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/ae2wtlib/models/item/wireless_universal_terminal.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "ae2wtlib:wireless_universal_terminal" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/ae2wtlib/textures/infinity_booster_card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tfarcenim/AE2WirelessTerminalLibrary/9ef7893c8aaed44babeb3590e37524ab096c81f5/src/main/resources/assets/ae2wtlib/textures/infinity_booster_card.png -------------------------------------------------------------------------------- /src/main/resources/assets/ae2wtlib/textures/magnet_card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tfarcenim/AE2WirelessTerminalLibrary/9ef7893c8aaed44babeb3590e37524ab096c81f5/src/main/resources/assets/ae2wtlib/textures/magnet_card.png -------------------------------------------------------------------------------- /src/main/resources/assets/ae2wtlib/textures/wireless_crafting_terminal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tfarcenim/AE2WirelessTerminalLibrary/9ef7893c8aaed44babeb3590e37524ab096c81f5/src/main/resources/assets/ae2wtlib/textures/wireless_crafting_terminal.png -------------------------------------------------------------------------------- /src/main/resources/assets/ae2wtlib/textures/wireless_fluid_terminal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tfarcenim/AE2WirelessTerminalLibrary/9ef7893c8aaed44babeb3590e37524ab096c81f5/src/main/resources/assets/ae2wtlib/textures/wireless_fluid_terminal.png -------------------------------------------------------------------------------- /src/main/resources/assets/ae2wtlib/textures/wireless_interface_terminal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tfarcenim/AE2WirelessTerminalLibrary/9ef7893c8aaed44babeb3590e37524ab096c81f5/src/main/resources/assets/ae2wtlib/textures/wireless_interface_terminal.png -------------------------------------------------------------------------------- /src/main/resources/assets/ae2wtlib/textures/wireless_pattern_terminal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tfarcenim/AE2WirelessTerminalLibrary/9ef7893c8aaed44babeb3590e37524ab096c81f5/src/main/resources/assets/ae2wtlib/textures/wireless_pattern_terminal.png -------------------------------------------------------------------------------- /src/main/resources/assets/ae2wtlib/textures/wireless_universal_terminal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tfarcenim/AE2WirelessTerminalLibrary/9ef7893c8aaed44babeb3590e37524ab096c81f5/src/main/resources/assets/ae2wtlib/textures/wireless_universal_terminal.png -------------------------------------------------------------------------------- /src/main/resources/assets/appliedenergistics2/screens/wtlib/wireless_crafting_terminal.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "schema.json", 3 | "includes": ["../terminals/item_terminal.json"], 4 | "slots": { 5 | "CRAFTING_GRID": { 6 | "left": 80, 7 | "bottom": 160, 8 | "grid": "BREAK_AFTER_3COLS" 9 | }, 10 | "CRAFTING_RESULT": { 11 | "left": 174, 12 | "bottom": 142 13 | }, 14 | "PLAYER_INVENTORY": { 15 | "left": 8, 16 | "bottom": 84, 17 | "grid": "BREAK_AFTER_9COLS" 18 | }, 19 | "PLAYER_HOTBAR": { 20 | "left": 8, 21 | "bottom": 26, 22 | "grid": "HORIZONTAL" 23 | }, 24 | "INSCRIBER_PLATE_BOTTOM": { 25 | "$comment": "TRASH", 26 | "left": 98, 27 | "bottom": 106 28 | }, 29 | "INSCRIBER_PLATE_TOP": { 30 | "$comment": "MAGNET_CARD", 31 | "left": 134, 32 | "bottom": 104 33 | }, 34 | "BIOMETRIC_CARD": { 35 | "$comment": "INFINITY_BOOSTER_CARD", 36 | "left": 152, 37 | "bottom": 104 38 | }, 39 | "MACHINE_INPUT": { 40 | "$comment": "HELMET", 41 | "left": 8, 42 | "bottom": 160 43 | }, 44 | "MACHINE_PROCESSING": { 45 | "$comment": "CHESTPLATE", 46 | "left": 8, 47 | "bottom": 142 48 | }, 49 | "MACHINE_OUTPUT": { 50 | "$comment": "LEGGINGS", 51 | "left": 8, 52 | "bottom": 124 53 | }, 54 | "MACHINE_CRAFTING_GRID": { 55 | "$comment": "BOOT", 56 | "left": 8, 57 | "bottom": 106 58 | }, 59 | "PROCESSING_RESULT": { 60 | "$comment": "OFFHAND", 61 | "left": 80, 62 | "bottom": 106 63 | } 64 | }, 65 | "text": { 66 | "dialog_title": { 67 | "text": { 68 | "translate": "gui.appliedenergistics2.Terminal" 69 | }, 70 | "position": { 71 | "left": 8, 72 | "top": 6 73 | } 74 | }, 75 | "crafting_grid_title": { 76 | "text": { 77 | "translate": "gui.appliedenergistics2.CraftingTerminal" 78 | }, 79 | "position": { 80 | "left": 8, 81 | "bottom": 170 82 | } 83 | } 84 | }, 85 | "terminalStyle": { 86 | "header": { 87 | "texture": "wtlib/guis/crafting.png", 88 | "srcRect": [0, 0, 195, 17] 89 | }, 90 | "firstRow": { 91 | "texture": "wtlib/guis/crafting.png", 92 | "srcRect": [0, 17, 195, 18] 93 | }, 94 | "row": { 95 | "texture": "wtlib/guis/crafting.png", 96 | "srcRect": [0, 35, 195, 18] 97 | }, 98 | "lastRow": { 99 | "texture": "wtlib/guis/crafting.png", 100 | "srcRect": [0, 53, 195, 18] 101 | }, 102 | "bottom": { 103 | "texture": "wtlib/guis/crafting.png", 104 | "srcRect": [0, 71, 200, 172] 105 | } 106 | }, 107 | "widgets": { 108 | "clearCraftingGrid": { 109 | "left": 135, 110 | "bottom": 162 111 | }, 112 | "emptyTrash": { 113 | "left": 116, 114 | "bottom": 106 115 | }, 116 | "magnetCardToggleButton": { 117 | "left": 142, 118 | "bottom": 114 119 | }, 120 | "cycleTerminal": { 121 | "left": -20, 122 | "top": 108 123 | }, 124 | "player": { 125 | "left": 52, 126 | "bottom": 94 127 | } 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /src/main/resources/assets/appliedenergistics2/screens/wtlib/wireless_interface_terminal.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "schema.json", 3 | "includes": ["../common/common.json", "../common/player_inventory.json"], 4 | "slots": { 5 | "BIOMETRIC_CARD": { 6 | "$comment": "INFINITY_BOOSTER_CARD", 7 | "left": 173, 8 | "bottom": 93 9 | } 10 | }, 11 | "text": { 12 | "dialog_title": { 13 | "text": { 14 | "translate": "gui.appliedenergistics2.InterfaceTerminal" 15 | }, 16 | "position": { 17 | "left": 8, 18 | "top": 6 19 | } 20 | } 21 | }, 22 | "widgets": { 23 | "scrollbar": { 24 | "left": 175, 25 | "top": 18 26 | }, 27 | "cycleTerminal": { 28 | "left": -20, 29 | "top": 28 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/resources/assets/appliedenergistics2/screens/wtlib/wireless_pattern_terminal.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "schema.json", 3 | "includes": ["../terminals/item_terminal.json"], 4 | "slots": { 5 | "PLAYER_INVENTORY": { 6 | "left": 8, 7 | "bottom": 82, 8 | "grid": "BREAK_AFTER_9COLS" 9 | }, 10 | "PLAYER_HOTBAR": { 11 | "left": 8, 12 | "bottom": 24, 13 | "grid": "HORIZONTAL" 14 | }, 15 | "BIOMETRIC_CARD": { 16 | "$comment": "INFINITY_BOOSTER_CARD", 17 | "left": 80, 18 | "bottom": 102 19 | }, 20 | "BLANK_PATTERN": { 21 | "left": 147, 22 | "bottom": 163 23 | }, 24 | "ENCODED_PATTERN": { 25 | "left": 147, 26 | "bottom": 120 27 | }, 28 | "CRAFTING_GRID": { 29 | "left": 18, 30 | "bottom": 158, 31 | "grid": "BREAK_AFTER_3COLS" 32 | }, 33 | "CRAFTING_RESULT": { 34 | "left": 110, 35 | "bottom": 140 36 | }, 37 | "PROCESSING_RESULT": { 38 | "left": 110, 39 | "bottom": 158, 40 | "grid": "VERTICAL" 41 | } 42 | }, 43 | "text": { 44 | "dialog_title": { 45 | "text": { 46 | "translate": "gui.appliedenergistics2.Terminal" 47 | }, 48 | "position": { 49 | "left": 8, 50 | "top": 6 51 | } 52 | }, 53 | "crafting_grid_title": { 54 | "text": { 55 | "translate": "gui.appliedenergistics2.PatternTerminal" 56 | }, 57 | "position": { 58 | "left": 8, 59 | "bottom": 174 60 | } 61 | } 62 | }, 63 | "terminalStyle": { 64 | "header": { 65 | "texture": "wtlib/guis/pattern.png", 66 | "srcRect": [0, 0, 195, 17] 67 | }, 68 | "firstRow": { 69 | "texture": "wtlib/guis/pattern.png", 70 | "srcRect": [0, 17, 195, 18] 71 | }, 72 | "row": { 73 | "texture": "wtlib/guis/pattern.png", 74 | "srcRect": [0, 35, 195, 18] 75 | }, 76 | "lastRow": { 77 | "texture": "wtlib/guis/pattern.png", 78 | "srcRect": [0, 53, 195, 18] 79 | }, 80 | "bottom": { 81 | "texture": "wtlib/guis/pattern.png", 82 | "srcRect": [0, 71, 195, 178] 83 | } 84 | }, 85 | "widgets": { 86 | "craftingPatternMode": { 87 | "left": 173, 88 | "bottom": 177 89 | }, 90 | "processingPatternMode": { 91 | "left": 173, 92 | "bottom": 177 93 | }, 94 | "substitutionsEnabled": { 95 | "left": 84, 96 | "bottom": 163 97 | }, 98 | "substitutionsDisabled": { 99 | "left": 84, 100 | "bottom": 163 101 | }, 102 | "clearPattern": { 103 | "left": 74, 104 | "bottom": 163 105 | }, 106 | "encodePattern": { 107 | "left": 147, 108 | "bottom": 142 109 | }, 110 | "cycleTerminal": { 111 | "left": -20, 112 | "top": 108 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/main/resources/assets/appliedenergistics2/textures/wtlib/gui/crafting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tfarcenim/AE2WirelessTerminalLibrary/9ef7893c8aaed44babeb3590e37524ab096c81f5/src/main/resources/assets/appliedenergistics2/textures/wtlib/gui/crafting.png -------------------------------------------------------------------------------- /src/main/resources/assets/appliedenergistics2/textures/wtlib/gui/interface.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tfarcenim/AE2WirelessTerminalLibrary/9ef7893c8aaed44babeb3590e37524ab096c81f5/src/main/resources/assets/appliedenergistics2/textures/wtlib/gui/interface.png -------------------------------------------------------------------------------- /src/main/resources/assets/appliedenergistics2/textures/wtlib/gui/pattern.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tfarcenim/AE2WirelessTerminalLibrary/9ef7893c8aaed44babeb3590e37524ab096c81f5/src/main/resources/assets/appliedenergistics2/textures/wtlib/gui/pattern.png -------------------------------------------------------------------------------- /src/main/resources/assets/appliedenergistics2/textures/wtlib/guis/crafting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tfarcenim/AE2WirelessTerminalLibrary/9ef7893c8aaed44babeb3590e37524ab096c81f5/src/main/resources/assets/appliedenergistics2/textures/wtlib/guis/crafting.png -------------------------------------------------------------------------------- /src/main/resources/assets/appliedenergistics2/textures/wtlib/guis/interface.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tfarcenim/AE2WirelessTerminalLibrary/9ef7893c8aaed44babeb3590e37524ab096c81f5/src/main/resources/assets/appliedenergistics2/textures/wtlib/guis/interface.png -------------------------------------------------------------------------------- /src/main/resources/assets/appliedenergistics2/textures/wtlib/guis/pattern.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tfarcenim/AE2WirelessTerminalLibrary/9ef7893c8aaed44babeb3590e37524ab096c81f5/src/main/resources/assets/appliedenergistics2/textures/wtlib/guis/pattern.png -------------------------------------------------------------------------------- /src/main/resources/data/ae2wtlib/advancements/recipes/infinity_booster_card.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "minecraft:recipes/root", 3 | "rewards": { 4 | "recipes": [ 5 | "ae2wtlib:infinity_booster_card" 6 | ] 7 | }, 8 | "criteria": { 9 | "has_wct": { 10 | "trigger": "minecraft:inventory_changed", 11 | "conditions": { 12 | "items": [ 13 | { 14 | "item": "ae2wtlib:wireless_crafting_terminal" 15 | } 16 | ] 17 | } 18 | }, 19 | "has_wpt": { 20 | "trigger": "minecraft:inventory_changed", 21 | "conditions": { 22 | "items": [ 23 | { 24 | "item": "ae2wtlib:wireless_pattern_terminal" 25 | } 26 | ] 27 | } 28 | }, 29 | "has_wit": { 30 | "trigger": "minecraft:inventory_changed", 31 | "conditions": { 32 | "items": [ 33 | { 34 | "item": "ae2wtlib:wireless_interface_terminal" 35 | } 36 | ] 37 | } 38 | }, 39 | "has_the_recipe": { 40 | "trigger": "minecraft:recipe_unlocked", 41 | "conditions": { 42 | "recipe": "ae2wtlib:infinity_booster_card" 43 | } 44 | } 45 | }, 46 | "requirements": [ 47 | [ 48 | "has_wct", 49 | "has_wpt", 50 | "has_wit", 51 | "has_the_recipe" 52 | ] 53 | ] 54 | } -------------------------------------------------------------------------------- /src/main/resources/data/ae2wtlib/advancements/recipes/magnet_card.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "minecraft:recipes/root", 3 | "rewards": { 4 | "recipes": [ 5 | "ae2wtlib:magnet_card" 6 | ] 7 | }, 8 | "criteria": { 9 | "has_wct": { 10 | "trigger": "minecraft:inventory_changed", 11 | "conditions": { 12 | "items": [ 13 | { 14 | "item": "ae2wtlib:wireless_crafting_terminal" 15 | } 16 | ] 17 | } 18 | }, 19 | "has_the_recipe": { 20 | "trigger": "minecraft:recipe_unlocked", 21 | "conditions": { 22 | "recipe": "ae2wtlib:magnet_card" 23 | } 24 | } 25 | }, 26 | "requirements": [ 27 | [ 28 | "has_wct", 29 | "has_the_recipe" 30 | ] 31 | ] 32 | } -------------------------------------------------------------------------------- /src/main/resources/data/ae2wtlib/advancements/recipes/wireless_crafting_terminal.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "minecraft:recipes/root", 3 | "rewards": { 4 | "recipes": [ 5 | "ae2wtlib:wireless_crafting_terminal" 6 | ] 7 | }, 8 | "criteria": { 9 | "has_wt": { 10 | "trigger": "minecraft:inventory_changed", 11 | "conditions": { 12 | "items": [ 13 | { 14 | "item": "appliedenergistics2:wireless_terminal" 15 | } 16 | ] 17 | } 18 | }, 19 | "has_the_recipe": { 20 | "trigger": "minecraft:recipe_unlocked", 21 | "conditions": { 22 | "recipe": "ae2wtlib:wireless_crafting_terminal" 23 | } 24 | } 25 | }, 26 | "requirements": [ 27 | [ 28 | "has_wt", 29 | "has_the_recipe" 30 | ] 31 | ] 32 | } -------------------------------------------------------------------------------- /src/main/resources/data/ae2wtlib/advancements/recipes/wireless_interface_terminal.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "minecraft:recipes/root", 3 | "rewards": { 4 | "recipes": [ 5 | "ae2wtlib:wireless_interface_terminal" 6 | ] 7 | }, 8 | "criteria": { 9 | "has_wt": { 10 | "trigger": "minecraft:inventory_changed", 11 | "conditions": { 12 | "items": [ 13 | { 14 | "item": "appliedenergistics2:wireless_terminal" 15 | } 16 | ] 17 | } 18 | }, 19 | "has_the_recipe": { 20 | "trigger": "minecraft:recipe_unlocked", 21 | "conditions": { 22 | "recipe": "ae2wtlib:wireless_interface_terminal" 23 | } 24 | } 25 | }, 26 | "requirements": [ 27 | [ 28 | "has_wt", 29 | "has_the_recipe" 30 | ] 31 | ] 32 | } -------------------------------------------------------------------------------- /src/main/resources/data/ae2wtlib/advancements/recipes/wireless_pattern_terminal.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "minecraft:recipes/root", 3 | "rewards": { 4 | "recipes": [ 5 | "ae2wtlib:wireless_pattern_terminal" 6 | ] 7 | }, 8 | "criteria": { 9 | "has_wt": { 10 | "trigger": "minecraft:inventory_changed", 11 | "conditions": { 12 | "items": [ 13 | { 14 | "item": "appliedenergistics2:wireless_terminal" 15 | } 16 | ] 17 | } 18 | }, 19 | "has_the_recipe": { 20 | "trigger": "minecraft:recipe_unlocked", 21 | "conditions": { 22 | "recipe": "ae2wtlib:wireless_pattern_terminal" 23 | } 24 | } 25 | }, 26 | "requirements": [ 27 | [ 28 | "has_wt", 29 | "has_the_recipe" 30 | ] 31 | ] 32 | } -------------------------------------------------------------------------------- /src/main/resources/data/ae2wtlib/advancements/recipes/wireless_universal_terminal/ci.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "minecraft:recipes/root", 3 | "rewards": { 4 | "recipes": [ 5 | "ae2wtlib:wireless_universal_terminal/ci" 6 | ] 7 | }, 8 | "criteria": { 9 | "has_wct": { 10 | "trigger": "minecraft:inventory_changed", 11 | "conditions": { 12 | "items": [ 13 | { 14 | "item": "ae2wtlib:wireless_crafting_terminal" 15 | } 16 | ] 17 | } 18 | }, 19 | "has_wit": { 20 | "trigger": "minecraft:inventory_changed", 21 | "conditions": { 22 | "items": [ 23 | { 24 | "item": "ae2wtlib:wireless_interface_terminal" 25 | } 26 | ] 27 | } 28 | }, 29 | "has_the_recipe": { 30 | "trigger": "minecraft:recipe_unlocked", 31 | "conditions": { 32 | "recipe": "ae2wtlib:wireless_universal_terminal/ci" 33 | } 34 | } 35 | }, 36 | "requirements": [ 37 | [ 38 | "has_wct", 39 | "has_wit", 40 | "has_the_recipe" 41 | ] 42 | ] 43 | } -------------------------------------------------------------------------------- /src/main/resources/data/ae2wtlib/advancements/recipes/wireless_universal_terminal/cp.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "minecraft:recipes/root", 3 | "rewards": { 4 | "recipes": [ 5 | "ae2wtlib:wireless_universal_terminal/cp" 6 | ] 7 | }, 8 | "criteria": { 9 | "has_wct": { 10 | "trigger": "minecraft:inventory_changed", 11 | "conditions": { 12 | "items": [ 13 | { 14 | "item": "ae2wtlib:wireless_crafting_terminal" 15 | } 16 | ] 17 | } 18 | }, 19 | "has_wpt": { 20 | "trigger": "minecraft:inventory_changed", 21 | "conditions": { 22 | "items": [ 23 | { 24 | "item": "ae2wtlib:wireless_pattern_terminal" 25 | } 26 | ] 27 | } 28 | }, 29 | "has_the_recipe": { 30 | "trigger": "minecraft:recipe_unlocked", 31 | "conditions": { 32 | "recipe": "ae2wtlib:wireless_universal_terminal/cp" 33 | } 34 | } 35 | }, 36 | "requirements": [ 37 | [ 38 | "has_wct", 39 | "has_wpt", 40 | "has_the_recipe" 41 | ] 42 | ] 43 | } -------------------------------------------------------------------------------- /src/main/resources/data/ae2wtlib/advancements/recipes/wireless_universal_terminal/ip.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "minecraft:recipes/root", 3 | "rewards": { 4 | "recipes": [ 5 | "ae2wtlib:wireless_universal_terminal/ip" 6 | ] 7 | }, 8 | "criteria": { 9 | "has_wpt": { 10 | "trigger": "minecraft:inventory_changed", 11 | "conditions": { 12 | "items": [ 13 | { 14 | "item": "ae2wtlib:wireless_pattern_terminal" 15 | } 16 | ] 17 | } 18 | }, 19 | "has_wit": { 20 | "trigger": "minecraft:inventory_changed", 21 | "conditions": { 22 | "items": [ 23 | { 24 | "item": "ae2wtlib:wireless_interface_terminal" 25 | } 26 | ] 27 | } 28 | }, 29 | "has_the_recipe": { 30 | "trigger": "minecraft:recipe_unlocked", 31 | "conditions": { 32 | "recipe": "ae2wtlib:wireless_universal_terminal/ip" 33 | } 34 | } 35 | }, 36 | "requirements": [ 37 | [ 38 | "has_wit", 39 | "has_wpt", 40 | "has_the_recipe" 41 | ] 42 | ] 43 | } -------------------------------------------------------------------------------- /src/main/resources/data/ae2wtlib/advancements/recipes/wireless_universal_terminal/upgrade_crafting.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "minecraft:recipes/root", 3 | "rewards": { 4 | "recipes": [ 5 | "ae2wtlib:wireless_universal_terminal/upgrade_crafting" 6 | ] 7 | }, 8 | "criteria": { 9 | "has_wct": { 10 | "trigger": "minecraft:inventory_changed", 11 | "conditions": { 12 | "items": [ 13 | { 14 | "item": "ae2wtlib:wireless_crafting_terminal" 15 | } 16 | ] 17 | } 18 | }, 19 | "has_the_recipe": { 20 | "trigger": "minecraft:recipe_unlocked", 21 | "conditions": { 22 | "recipe": "ae2wtlib:wireless_universal_terminal/upgrade_crafting" 23 | } 24 | } 25 | }, 26 | "requirements": [ 27 | [ 28 | "has_wct", 29 | "has_the_recipe" 30 | ] 31 | ] 32 | } -------------------------------------------------------------------------------- /src/main/resources/data/ae2wtlib/advancements/recipes/wireless_universal_terminal/upgrade_interface.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "minecraft:recipes/root", 3 | "rewards": { 4 | "recipes": [ 5 | "ae2wtlib:wireless_universal_terminal/upgrade_interface" 6 | ] 7 | }, 8 | "criteria": { 9 | "has_wit": { 10 | "trigger": "minecraft:inventory_changed", 11 | "conditions": { 12 | "items": [ 13 | { 14 | "item": "ae2wtlib:wireless_interface_terminal" 15 | } 16 | ] 17 | } 18 | }, 19 | "has_the_recipe": { 20 | "trigger": "minecraft:recipe_unlocked", 21 | "conditions": { 22 | "recipe": "ae2wtlib:wireless_universal_terminal/upgrade_interface" 23 | } 24 | } 25 | }, 26 | "requirements": [ 27 | [ 28 | "has_wit", 29 | "has_the_recipe" 30 | ] 31 | ] 32 | } -------------------------------------------------------------------------------- /src/main/resources/data/ae2wtlib/advancements/recipes/wireless_universal_terminal/upgrade_pattern.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "minecraft:recipes/root", 3 | "rewards": { 4 | "recipes": [ 5 | "ae2wtlib:wireless_universal_terminal/upgrade_pattern" 6 | ] 7 | }, 8 | "criteria": { 9 | "has_wpt": { 10 | "trigger": "minecraft:inventory_changed", 11 | "conditions": { 12 | "items": [ 13 | { 14 | "item": "ae2wtlib:wireless_pattern_terminal" 15 | } 16 | ] 17 | } 18 | }, 19 | "has_the_recipe": { 20 | "trigger": "minecraft:recipe_unlocked", 21 | "conditions": { 22 | "recipe": "ae2wtlib:wireless_universal_terminal/upgrade_pattern" 23 | } 24 | } 25 | }, 26 | "requirements": [ 27 | [ 28 | "has_wpt", 29 | "has_the_recipe" 30 | ] 31 | ] 32 | } -------------------------------------------------------------------------------- /src/main/resources/data/ae2wtlib/recipes/infinity_booster_card.json: -------------------------------------------------------------------------------- 1 | { 2 | "result": { 3 | "item": "ae2wtlib:infinity_booster_card" 4 | }, 5 | "type": "minecraft:crafting_shaped", 6 | "pattern": ["a a", " b "], 7 | "key": { 8 | "a": { 9 | "item": "appliedenergistics2:fluix_pearl" 10 | }, 11 | "b": { 12 | "item": "appliedenergistics2:wireless_receiver" 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/resources/data/ae2wtlib/recipes/magnet_card.json: -------------------------------------------------------------------------------- 1 | { 2 | "result": { 3 | "item": "ae2wtlib:magnet_card" 4 | }, 5 | "type": "minecraft:crafting_shaped", 6 | "pattern": ["abc", "ded", "ddd"], 7 | "key": { 8 | "a": { 9 | "item": "minecraft:redstone_block" 10 | }, 11 | "b": { 12 | "item": "appliedenergistics2:annihilation_plane" 13 | }, 14 | "c": { 15 | "item": "minecraft:lapis_block" 16 | }, 17 | "d": { 18 | "item": "minecraft:iron_block" 19 | }, 20 | "e": { 21 | "item": "appliedenergistics2:advanced_card" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/resources/data/ae2wtlib/recipes/wireless_crafting_terminal.json: -------------------------------------------------------------------------------- 1 | { 2 | "result": { 3 | "item": "ae2wtlib:wireless_crafting_terminal" 4 | }, 5 | "type": "minecraft:crafting_shapeless", 6 | "ingredients": [ 7 | { 8 | "item": "appliedenergistics2:wireless_terminal" 9 | }, 10 | { 11 | "item": "appliedenergistics2:fluix_pearl" 12 | }, 13 | { 14 | "item": "appliedenergistics2:crafting_terminal" 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /src/main/resources/data/ae2wtlib/recipes/wireless_interface_terminal.json: -------------------------------------------------------------------------------- 1 | { 2 | "result": { 3 | "item": "ae2wtlib:wireless_interface_terminal" 4 | }, 5 | "type": "minecraft:crafting_shapeless", 6 | "ingredients": [ 7 | { 8 | "item": "appliedenergistics2:wireless_terminal" 9 | }, 10 | { 11 | "item": "appliedenergistics2:fluix_pearl" 12 | }, 13 | { 14 | "item": "appliedenergistics2:interface_terminal" 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /src/main/resources/data/ae2wtlib/recipes/wireless_pattern_terminal.json: -------------------------------------------------------------------------------- 1 | { 2 | "result": { 3 | "item": "ae2wtlib:wireless_pattern_terminal" 4 | }, 5 | "type": "minecraft:crafting_shapeless", 6 | "ingredients": [ 7 | { 8 | "item": "appliedenergistics2:wireless_terminal" 9 | }, 10 | { 11 | "item": "appliedenergistics2:fluix_pearl" 12 | }, 13 | { 14 | "item": "appliedenergistics2:pattern_terminal" 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /src/main/resources/data/ae2wtlib/recipes/wireless_universal_terminal/ci.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "ae2wtlib:combine", 3 | "TerminalA": { 4 | "item": "ae2wtlib:wireless_crafting_terminal" 5 | }, 6 | "TerminalB": { 7 | "item": "ae2wtlib:wireless_interface_terminal" 8 | }, 9 | "TerminalAName": "crafting", 10 | "TerminalBName": "interface" 11 | } -------------------------------------------------------------------------------- /src/main/resources/data/ae2wtlib/recipes/wireless_universal_terminal/cp.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "ae2wtlib:combine", 3 | "TerminalA": { 4 | "item": "ae2wtlib:wireless_crafting_terminal" 5 | }, 6 | "TerminalB": { 7 | "item": "ae2wtlib:wireless_pattern_terminal" 8 | }, 9 | "TerminalAName": "crafting", 10 | "TerminalBName": "pattern" 11 | } -------------------------------------------------------------------------------- /src/main/resources/data/ae2wtlib/recipes/wireless_universal_terminal/ip.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "ae2wtlib:combine", 3 | "TerminalA": { 4 | "item": "ae2wtlib:wireless_interface_terminal" 5 | }, 6 | "TerminalB": { 7 | "item": "ae2wtlib:wireless_pattern_terminal" 8 | }, 9 | "TerminalAName": "interface", 10 | "TerminalBName": "pattern" 11 | } -------------------------------------------------------------------------------- /src/main/resources/data/ae2wtlib/recipes/wireless_universal_terminal/upgrade_crafting.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "ae2wtlib:upgrade", 3 | "Terminal": { 4 | "item": "ae2wtlib:wireless_crafting_terminal" 5 | }, 6 | "TerminalName": "crafting" 7 | } -------------------------------------------------------------------------------- /src/main/resources/data/ae2wtlib/recipes/wireless_universal_terminal/upgrade_interface.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "ae2wtlib:upgrade", 3 | "Terminal": { 4 | "item": "ae2wtlib:wireless_interface_terminal" 5 | }, 6 | "TerminalName": "interface" 7 | } -------------------------------------------------------------------------------- /src/main/resources/data/ae2wtlib/recipes/wireless_universal_terminal/upgrade_pattern.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "ae2wtlib:upgrade", 3 | "Terminal": { 4 | "item": "ae2wtlib:wireless_pattern_terminal" 5 | }, 6 | "TerminalName": "pattern" 7 | } -------------------------------------------------------------------------------- /src/main/resources/pack.mcmeta: -------------------------------------------------------------------------------- 1 | { 2 | "pack": { 3 | "description": "ae2wtlib resources", 4 | "pack_format": 6 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/rei/CraftingRecipeTransferHandler.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.rei; 2 | 3 | import tfar.ae2wt.wirelesscraftingterminal.WirelessCraftingTerminalContainer; 4 | import me.shedaniel.rei.api.AutoTransferHandler; 5 | import me.shedaniel.rei.api.RecipeDisplay; 6 | 7 | public class CraftingRecipeTransferHandler extends RecipeTransferHandler { 8 | 9 | public CraftingRecipeTransferHandler(Class containerClass) { 10 | super(containerClass); 11 | } 12 | 13 | @Override 14 | protected AutoTransferHandler.Result doTransferRecipe(WirelessCraftingTerminalContainer container, RecipeDisplay recipe, AutoTransferHandler.Context context) { 15 | return null; 16 | } 17 | 18 | @Override 19 | protected boolean isCrafting() { 20 | return true; 21 | } 22 | } -------------------------------------------------------------------------------- /src/main/resources/rei/PatternRecipeTransferHandler.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.rei; 2 | 3 | import tfar.ae2wt.wpt.WirelessPatternTerminalContainer; 4 | import me.shedaniel.rei.api.AutoTransferHandler; 5 | import me.shedaniel.rei.api.RecipeDisplay; 6 | import me.shedaniel.rei.plugin.DefaultPlugin; 7 | 8 | public class PatternRecipeTransferHandler extends RecipeTransferHandler { 9 | 10 | PatternRecipeTransferHandler(Class containerClass) { 11 | super(containerClass); 12 | } 13 | 14 | protected AutoTransferHandler.Result doTransferRecipe(WirelessPatternTerminalContainer container, RecipeDisplay recipe, AutoTransferHandler.Context context) { 15 | if(container.isCraftingMode() && recipe.getRecipeCategory() != DefaultPlugin.CRAFTING) { 16 | return AutoTransferHandler.Result.createFailed("jei.appliedenergistics2.requires_processing_mode"); 17 | } 18 | 19 | if(recipe.getResultingEntries().isEmpty()) { 20 | return AutoTransferHandler.Result.createFailed("jei.appliedenergistics2.no_output"); 21 | } 22 | return null; 23 | } 24 | 25 | @Override 26 | protected boolean isCrafting() { 27 | return false; 28 | } 29 | } -------------------------------------------------------------------------------- /src/main/resources/rei/Plugin.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.rei; 2 | 3 | import tfar.ae2wt.init.ModItems; 4 | import tfar.ae2wt.wirelesscraftingterminal.WirelessCraftingTerminalContainer; 5 | import tfar.ae2wt.wpt.WirelessPatternTerminalContainer; 6 | import me.shedaniel.rei.api.EntryStack; 7 | import me.shedaniel.rei.api.RecipeHelper; 8 | import me.shedaniel.rei.api.plugins.REIPluginV0; 9 | import me.shedaniel.rei.plugin.DefaultPlugin; 10 | import net.minecraft.util.Identifier; 11 | 12 | public class Plugin implements REIPluginV0 { 13 | 14 | @Override 15 | public Identifier getPluginIdentifier() { 16 | return new Identifier("ae2wtlib", "rei"); 17 | } 18 | 19 | @Override 20 | public void registerOthers(RecipeHelper recipeHelper) { 21 | recipeHelper.registerAutoCraftingHandler(new CraftingRecipeTransferHandler(WirelessCraftingTerminalContainer.class)); 22 | recipeHelper.registerAutoCraftingHandler(new PatternRecipeTransferHandler(WirelessPatternTerminalContainer.class)); 23 | 24 | recipeHelper.registerWorkingStations(DefaultPlugin.CRAFTING, EntryStack.create(ModItems.CRAFTING_TERMINAL)); 25 | } 26 | } -------------------------------------------------------------------------------- /src/main/resources/rei/RecipeTransferHandler.java: -------------------------------------------------------------------------------- 1 | package tfar.ae2wt.rei; 2 | 3 | import appeng.helpers.IContainerCraftingPacket; 4 | import me.shedaniel.rei.api.AutoTransferHandler; 5 | import me.shedaniel.rei.api.EntryStack; 6 | import me.shedaniel.rei.api.RecipeDisplay; 7 | import me.shedaniel.rei.api.TransferRecipeDisplay; 8 | import net.minecraft.item.ItemStack; 9 | import net.minecraft.recipe.Ingredient; 10 | import net.minecraft.recipe.ShapedRecipe; 11 | import net.minecraft.screen.ScreenHandler; 12 | import net.minecraft.util.Identifier; 13 | import net.minecraft.util.collection.DefaultedList; 14 | 15 | import java.util.List; 16 | import java.util.stream.Stream; 17 | 18 | abstract class RecipeTransferHandler implements AutoTransferHandler { 19 | 20 | private final Class containerClass; 21 | 22 | RecipeTransferHandler(Class containerClass) { 23 | this.containerClass = containerClass; 24 | } 25 | 26 | @Override 27 | public AutoTransferHandler.Result handle(AutoTransferHandler.Context context) { 28 | RecipeDisplay recipe = context.getRecipe(); 29 | 30 | if(!containerClass.isInstance(context.getContainerScreen().getScreenHandler())) { 31 | return AutoTransferHandler.Result.createNotApplicable(); 32 | } 33 | 34 | T container = containerClass.cast(context.getContainerScreen().getScreenHandler()); 35 | 36 | final Identifier recipeId = recipe.getRecipeLocation().orElse(null); 37 | 38 | // Check that the recipe can actually be looked up via the manager, i.e. our 39 | // facade recipes 40 | // have an ID, but are never registered with the recipe manager. 41 | boolean canSendReference = true; 42 | if(recipeId == null || !context.getMinecraft().world.getRecipeManager().get(recipeId).isPresent()) { 43 | canSendReference = false; 44 | } 45 | 46 | if(recipe instanceof TransferRecipeDisplay) { 47 | TransferRecipeDisplay trd = (TransferRecipeDisplay) recipe; 48 | if(trd.getWidth() > 3 || trd.getHeight() > 3) { 49 | return AutoTransferHandler.Result.createFailed("jei.appliedenergistics2.recipe_too_large"); 50 | } 51 | } else if(recipe.getInputEntries().size() > 9) { 52 | return AutoTransferHandler.Result.createFailed("jei.appliedenergistics2.recipe_too_large"); 53 | } 54 | 55 | final AutoTransferHandler.Result error = doTransferRecipe(container, recipe, context); 56 | 57 | if(error != null) { 58 | return error; 59 | } 60 | 61 | if(context.isActuallyCrafting()) { 62 | if(canSendReference) { 63 | new REIRecipePacket(recipeId, isCrafting()).send(); 64 | } else { 65 | // To avoid earlier problems of too large packets being sent that crashed the 66 | // client, 67 | // as a fallback when the recipe ID could not be resolved, we'll just send the 68 | // displayed 69 | // items. 70 | DefaultedList flatIngredients = DefaultedList.ofSize(9, Ingredient.EMPTY); 71 | ItemStack output = null; 72 | for(EntryStack entryStack : recipe.getResultingEntries().get(0)) { 73 | if(entryStack.getType() == EntryStack.Type.ITEM) { 74 | output = entryStack.getItemStack(); 75 | } 76 | } 77 | if(output == null || output.isEmpty()) { 78 | return AutoTransferHandler.Result.createFailed("jei.appliedenergistics2.no_output"); 79 | } 80 | 81 | // Now map the actual ingredients into the output/input 82 | for(int i = 0; i < recipe.getInputEntries().size(); i++) { 83 | List inputEntry = recipe.getInputEntries().get(i); 84 | if(inputEntry.isEmpty()) { 85 | continue; 86 | } 87 | EntryStack first = inputEntry.get(0); 88 | if(i < flatIngredients.size()) { 89 | ItemStack displayedIngredient = first.getItemStack(); 90 | if(displayedIngredient != null) { 91 | flatIngredients.set(i, Ingredient.ofStacks(Stream.of(displayedIngredient))); 92 | } 93 | } 94 | } 95 | 96 | ShapedRecipe fallbackRecipe = new ShapedRecipe(recipeId, "", 3, 3, flatIngredients, output); 97 | new REIRecipePacket(fallbackRecipe, isCrafting()).send(); 98 | } 99 | } 100 | 101 | return Result.createSuccessful().blocksFurtherHandling(); 102 | } 103 | 104 | protected abstract AutoTransferHandler.Result doTransferRecipe(T container, RecipeDisplay recipe, AutoTransferHandler.Context context); 105 | 106 | protected abstract boolean isCrafting(); 107 | } --------------------------------------------------------------------------------