├── .editorconfig ├── .gitattributes ├── .github └── workflows │ ├── build-and-test.yml │ └── release-tags.yml ├── .gitignore ├── CODEOWNERS ├── LICENSE ├── README.md ├── addon.gradle ├── build.gradle ├── dependencies.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── gtnhShared └── spotless.gradle ├── jitpack.yml ├── misc ├── eclipse-formatter-settings.xml └── spotless.importorder ├── repositories.gradle ├── settings.gradle └── src ├── main ├── java │ └── com │ │ └── recursive_pineapple │ │ └── matter_manipulator │ │ ├── ClientProxy.java │ │ ├── CommonProxy.java │ │ ├── GlobalMMConfig.java │ │ ├── MMMod.java │ │ ├── MMModCore.java │ │ ├── asm │ │ ├── ASMUtils.java │ │ ├── DeMemberator.java │ │ └── Optional.java │ │ ├── client │ │ ├── gui │ │ │ ├── DirectionDrawable.java │ │ │ ├── RadialMenu.java │ │ │ └── RadialMenuBuilder.java │ │ ├── nei │ │ │ ├── NEIMMConfig.java │ │ │ └── UpdateRecipeNEIHandler.java │ │ └── rendering │ │ │ ├── BoxRenderer.java │ │ │ └── QuadViewComparator.java │ │ ├── common │ │ ├── building │ │ │ ├── AEAnalysisResult.java │ │ │ ├── AECellItemProvider.java │ │ │ ├── AEPartData.java │ │ │ ├── AbstractBuildable.java │ │ │ ├── ArchitectureCraftAnalysisResult.java │ │ │ ├── BlockAnalyzer.java │ │ │ ├── BlockSpec.java │ │ │ ├── CopyableProperty.java │ │ │ ├── CoverData.java │ │ │ ├── GTAnalysisResult.java │ │ │ ├── IBuildable.java │ │ │ ├── IItemProvider.java │ │ │ ├── IPseudoInventory.java │ │ │ ├── ITileAnalysisIntegration.java │ │ │ ├── ImmutableBlockSpec.java │ │ │ ├── InteropConstants.java │ │ │ ├── InventoryAnalysis.java │ │ │ ├── MMInventory.java │ │ │ ├── MultipartAnalysisResult.java │ │ │ ├── MultipartPart.java │ │ │ ├── PatternItemProvider.java │ │ │ ├── PendingBlock.java │ │ │ ├── PendingBuild.java │ │ │ ├── PendingMove.java │ │ │ ├── PortableItemStack.java │ │ │ ├── ProxiedWorld.java │ │ │ └── providers │ │ │ │ └── BatteryItemProvider.java │ │ ├── compat │ │ │ ├── BlockProperty.java │ │ │ ├── BlockPropertyRegistry.java │ │ │ ├── BooleanProperty.java │ │ │ ├── DirectionBlockProperty.java │ │ │ ├── ExtendedFacingBlockProperty.java │ │ │ ├── FloatProperty.java │ │ │ ├── IntegerProperty.java │ │ │ ├── IntrinsicProperty.java │ │ │ ├── MetaBlockProperty.java │ │ │ ├── Orientation.java │ │ │ └── OrientationBlockProperty.java │ │ ├── data │ │ │ └── WeightedSpecList.java │ │ ├── entities │ │ │ ├── EntityID.java │ │ │ └── EntityItemLarge.java │ │ ├── items │ │ │ ├── IDMetaItem.java │ │ │ ├── MMItemList.java │ │ │ ├── MMItems.java │ │ │ ├── MMUpgrades.java │ │ │ ├── MetaItem.java │ │ │ ├── RecipeInstallUpgrade.java │ │ │ └── manipulator │ │ │ │ ├── ItemMatterManipulator.java │ │ │ │ ├── Location.java │ │ │ │ ├── MMConfig.java │ │ │ │ ├── MMKeyInputs.java │ │ │ │ ├── MMRenderer.java │ │ │ │ ├── MMState.java │ │ │ │ ├── RenderHints.java │ │ │ │ └── Transform.java │ │ ├── networking │ │ │ ├── MMPacket.java │ │ │ ├── Messages.java │ │ │ ├── Network.java │ │ │ └── SoundResource.java │ │ ├── persist │ │ │ ├── NBTJsonAdapter.java │ │ │ ├── StaticEnumJsonAdapter.java │ │ │ ├── UIDJsonAdapter.java │ │ │ └── WeightedListJsonAdapter.java │ │ ├── structure │ │ │ ├── CasingGTFrames.java │ │ │ └── MMCasings.java │ │ ├── uplink │ │ │ ├── IUplinkMulti.java │ │ │ ├── MTEMMUplink.java │ │ │ ├── MTEMMUplinkMEHatch.java │ │ │ ├── Structures.java │ │ │ ├── UplinkState.java │ │ │ └── UplinkStatus.java │ │ └── utils │ │ │ ├── BigFluidStack.java │ │ │ ├── BigItemStack.java │ │ │ ├── BlockMeta.java │ │ │ ├── FluidId.java │ │ │ ├── ImmutableBlockMeta.java │ │ │ ├── ImmutableItemMeta.java │ │ │ ├── InventoryAdapter.java │ │ │ ├── ItemId.java │ │ │ ├── ItemMeta.java │ │ │ ├── Lazy.java │ │ │ ├── LazyBlock.java │ │ │ ├── LazyItem.java │ │ │ ├── MMUtils.java │ │ │ ├── MMValues.java │ │ │ └── Mods.java │ │ ├── mixin │ │ ├── BlockCaptureDrops.java │ │ ├── LateMixinPlugin.java │ │ ├── Mixin.java │ │ └── TargetedMod.java │ │ └── server │ │ └── BlockStateCommand.java └── resources │ ├── LICENSE │ ├── META-INF │ └── mm_at.cfg │ ├── assets │ └── matter-manipulator │ │ ├── lang │ │ └── en_US.lang │ │ ├── shaders │ │ ├── fancybox.frag.glsl │ │ └── fancybox.vert.glsl │ │ └── textures │ │ ├── blocks │ │ └── machines │ │ │ └── uplink │ │ │ ├── OVERLAY_FRONT_ACTIVE_GLOW.png │ │ │ ├── OVERLAY_FRONT_ACTIVE_GLOW.png.mcmeta │ │ │ ├── OVERLAY_FRONT_IDLE_GLOW.png │ │ │ ├── OVERLAY_FRONT_IDLE_GLOW.png.mcmeta │ │ │ └── OVERLAY_FRONT_OFF.png │ │ └── items │ │ ├── itemMatterManipulator0.png │ │ ├── itemMatterManipulator1.png │ │ ├── itemMatterManipulator2.png │ │ ├── itemMatterManipulator3.png │ │ └── metaitem │ │ ├── 0.png │ │ ├── 1.png │ │ ├── 1.png.mcmeta │ │ ├── 10.png │ │ ├── 11.png │ │ ├── 11.png.mcmeta │ │ ├── 12.png │ │ ├── 13.png │ │ ├── 14.png │ │ ├── 15.png │ │ ├── 16.png │ │ ├── 16.png.mcmeta │ │ ├── 17.png │ │ ├── 18.png │ │ ├── 19.png │ │ ├── 2.png │ │ ├── 20.png │ │ ├── 21.png │ │ ├── 22.png │ │ ├── 23.png │ │ ├── 24.png │ │ ├── 25.png │ │ ├── 26.png │ │ ├── 27.png │ │ ├── 3.png │ │ ├── 4.png │ │ ├── 5.png │ │ ├── 6.png │ │ ├── 6.png.mcmeta │ │ ├── 7.png │ │ ├── 8.png │ │ └── 9.png │ ├── mcmod.info │ ├── mixins.matter-manipulator.early.json │ ├── mixins.matter-manipulator.json │ ├── mixins.matter-manipulator.late.json │ └── pack.mcmeta ├── mixin └── java │ └── com │ └── recursive_pineapple │ └── matter_manipulator │ └── mixin │ └── mixins │ ├── early │ ├── MixinBlockDropCapturing.java │ └── MixinKeyBinding.java │ └── late │ └── MixinBlockExtremeAutoCrafter.java └── test └── java └── com └── recursive_pineapple └── matter_manipulator └── common └── UtilsTests.java /.editorconfig: -------------------------------------------------------------------------------- 1 | # This is the universal Text Editor Configuration 2 | # for all GTNewHorizons projects 3 | # See: https://editorconfig.org/ 4 | 5 | root = true 6 | 7 | [*] 8 | charset = utf-8 9 | end_of_line = lf 10 | indent_size = 4 11 | indent_style = space 12 | insert_final_newline = true 13 | trim_trailing_whitespace = true 14 | 15 | [*.{bat,ini}] 16 | end_of_line = crlf 17 | 18 | [*.{dtd,json,info,mcmeta,md,sh,svg,xml,xsd,xsl,yaml,yml}] 19 | indent_size = 2 20 | 21 | [*.lang] 22 | trim_trailing_whitespace = false 23 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text eol=lf 2 | 3 | *.[jJ][aA][rR] binary 4 | 5 | *.[pP][nN][gG] binary 6 | *.[jJ][pP][gG] binary 7 | *.[jJ][pP][eE][gG] binary 8 | *.[gG][iI][fF] binary 9 | *.[tT][iI][fF] binary 10 | *.[tT][iI][fF][fF] binary 11 | *.[iI][cC][oO] binary 12 | *.[sS][vV][gG] text 13 | *.[eE][pP][sS] binary 14 | *.[xX][cC][fF] binary 15 | 16 | *.[kK][aA][rR] binary 17 | *.[mM]4[aA] binary 18 | *.[mM][iI][dD] binary 19 | *.[mM][iI][dD][iI] binary 20 | *.[mM][pP]3 binary 21 | *.[oO][gG][gG] binary 22 | *.[rR][aA] binary 23 | 24 | *.7[zZ] binary 25 | *.[gG][zZ] binary 26 | *.[tT][aA][rR] binary 27 | *.[tT][gG][zZ] binary 28 | *.[zZ][iI][pP] binary 29 | 30 | *.[tT][cC][nN] binary 31 | *.[sS][oO] binary 32 | *.[dD][lL][lL] binary 33 | *.[dD][yY][lL][iI][bB] binary 34 | *.[pP][sS][dD] binary 35 | *.[tT][tT][fF] binary 36 | *.[oO][tT][fF] binary 37 | 38 | *.[pP][aA][tT][cC][hH] -text 39 | 40 | *.[bB][aA][tT] text eol=crlf 41 | *.[cC][mM][dD] text eol=crlf 42 | *.[pP][sS]1 text eol=crlf 43 | 44 | *[aA][uU][tT][oO][gG][eE][nN][eE][rR][aA][tT][eE][dD]* binary 45 | -------------------------------------------------------------------------------- /.github/workflows/build-and-test.yml: -------------------------------------------------------------------------------- 1 | 2 | name: Build and test 3 | 4 | on: 5 | pull_request: 6 | branches: [ master, main ] 7 | push: 8 | branches: [ master, main ] 9 | 10 | jobs: 11 | build-and-test: 12 | uses: GTNewHorizons/GTNH-Actions-Workflows/.github/workflows/build-and-test.yml@master 13 | secrets: inherit 14 | -------------------------------------------------------------------------------- /.github/workflows/release-tags.yml: -------------------------------------------------------------------------------- 1 | 2 | name: Release tagged build 3 | 4 | on: 5 | push: 6 | tags: [ '*' ] 7 | 8 | permissions: 9 | contents: write 10 | 11 | jobs: 12 | release-tags: 13 | uses: GTNewHorizons/GTNH-Actions-Workflows/.github/workflows/release-tags.yml@master 14 | secrets: inherit 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | .settings 3 | /.idea/ 4 | /.vscode/ 5 | /run/ 6 | /build/ 7 | /eclipse/ 8 | .classpath 9 | .project 10 | /bin/ 11 | /config/ 12 | /crash-reports/ 13 | /logs/ 14 | options.txt 15 | /saves/ 16 | usernamecache.json 17 | banned-ips.json 18 | banned-players.json 19 | eula.txt 20 | ops.json 21 | server.properties 22 | servers.dat 23 | usercache.json 24 | whitelist.json 25 | /out/ 26 | *.iml 27 | *.ipr 28 | *.iws 29 | src/main/resources/mixins.*([!.]).json 30 | *.bat 31 | *.DS_Store 32 | !gradlew.bat 33 | .factorypath 34 | addon.local.gradle 35 | addon.local.gradle.kts 36 | addon.late.local.gradle 37 | addon.late.local.gradle.kts 38 | layout.json 39 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Any Github changes require admin approval 2 | /.github/** @GTNewHorizons/admin 3 | 4 | -------------------------------------------------------------------------------- /addon.gradle: -------------------------------------------------------------------------------- 1 | 2 | test { 3 | useJUnitPlatform() 4 | testLogging { 5 | events "passed", "skipped", "failed" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | 2 | plugins { 3 | id 'com.gtnewhorizons.gtnhconvention' 4 | } 5 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | @rem SPDX-License-Identifier: Apache-2.0 17 | @rem 18 | 19 | @if "%DEBUG%"=="" @echo off 20 | @rem ########################################################################## 21 | @rem 22 | @rem Gradle startup script for Windows 23 | @rem 24 | @rem ########################################################################## 25 | 26 | @rem Set local scope for the variables with windows NT shell 27 | if "%OS%"=="Windows_NT" setlocal 28 | 29 | set DIRNAME=%~dp0 30 | if "%DIRNAME%"=="" set DIRNAME=. 31 | @rem This is normally unused 32 | set APP_BASE_NAME=%~n0 33 | set APP_HOME=%DIRNAME% 34 | 35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 37 | 38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 39 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 40 | 41 | @rem Find java.exe 42 | if defined JAVA_HOME goto findJavaFromJavaHome 43 | 44 | set JAVA_EXE=java.exe 45 | %JAVA_EXE% -version >NUL 2>&1 46 | if %ERRORLEVEL% equ 0 goto execute 47 | 48 | echo. 1>&2 49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 50 | echo. 1>&2 51 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 52 | echo location of your Java installation. 1>&2 53 | 54 | goto fail 55 | 56 | :findJavaFromJavaHome 57 | set JAVA_HOME=%JAVA_HOME:"=% 58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 59 | 60 | if exist "%JAVA_EXE%" goto execute 61 | 62 | echo. 1>&2 63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 64 | echo. 1>&2 65 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 66 | echo location of your Java installation. 1>&2 67 | 68 | goto fail 69 | 70 | :execute 71 | @rem Setup the command line 72 | 73 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 74 | 75 | 76 | @rem Execute Gradle 77 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 78 | 79 | :end 80 | @rem End local scope for the variables with windows NT shell 81 | if %ERRORLEVEL% equ 0 goto mainEnd 82 | 83 | :fail 84 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 85 | rem the _cmd.exe /c_ return code! 86 | set EXIT_CODE=%ERRORLEVEL% 87 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 88 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 89 | exit /b %EXIT_CODE% 90 | 91 | :mainEnd 92 | if "%OS%"=="Windows_NT" endlocal 93 | 94 | :omega 95 | -------------------------------------------------------------------------------- /gtnhShared/spotless.gradle: -------------------------------------------------------------------------------- 1 | 2 | spotless { 3 | encoding 'UTF-8' 4 | 5 | java { 6 | target 'src/main/java/**/*.java' 7 | removeUnusedImports() 8 | importOrderFile('misc/spotless.importorder') 9 | trimTrailingWhitespace() 10 | endWithNewline() 11 | eclipse().configFile('misc/eclipse-formatter-settings.xml') 12 | } 13 | } 14 | 15 | tasks.getByName('spotlessJava') 16 | .dependsOn('createMcLauncherFiles') 17 | .dependsOn('decompressDecompiledSources') 18 | .dependsOn('injectTags') 19 | -------------------------------------------------------------------------------- /jitpack.yml: -------------------------------------------------------------------------------- 1 | before_install: 2 | - ./gradlew setupCIWorkspace -------------------------------------------------------------------------------- /misc/spotless.importorder: -------------------------------------------------------------------------------- 1 | #Organize Import Order 2 | #Wed Jan 08 23:07:36 EST 2025 3 | 0=java 4 | 1=javax 5 | 2=net.minecraft 6 | 3=net.minecraftforge 7 | 4=cpw.mods.fml 8 | 5=gregtech 9 | 6=appeng 10 | 7=com 11 | 8=net 12 | 9=org 13 | -------------------------------------------------------------------------------- /repositories.gradle: -------------------------------------------------------------------------------- 1 | // Add any additional repositories for your dependencies here. 2 | 3 | repositories { 4 | mavenLocal() 5 | } 6 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | 2 | pluginManagement { 3 | repositories { 4 | maven { 5 | // RetroFuturaGradle 6 | name "GTNH Maven" 7 | url "https://nexus.gtnewhorizons.com/repository/public/" 8 | mavenContent { 9 | includeGroup("com.gtnewhorizons") 10 | includeGroupByRegex("com\\.gtnewhorizons\\..+") 11 | } 12 | } 13 | gradlePluginPortal() 14 | mavenCentral() 15 | mavenLocal() 16 | } 17 | } 18 | 19 | plugins { 20 | id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.38' 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/ClientProxy.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator; 2 | 3 | import net.minecraft.entity.player.EntityPlayer; 4 | 5 | import cpw.mods.fml.client.FMLClientHandler; 6 | import cpw.mods.fml.common.event.FMLInitializationEvent; 7 | 8 | import com.recursive_pineapple.matter_manipulator.common.entities.EntityItemLarge; 9 | import com.recursive_pineapple.matter_manipulator.common.items.manipulator.MMKeyInputs; 10 | import com.recursive_pineapple.matter_manipulator.common.items.manipulator.MMRenderer; 11 | 12 | public class ClientProxy extends CommonProxy { 13 | 14 | @Override 15 | public void init(FMLInitializationEvent event) { 16 | super.init(event); 17 | 18 | EntityItemLarge.registerClient(); 19 | MMRenderer.init(); 20 | MMKeyInputs.init(); 21 | } 22 | 23 | @Override 24 | public EntityPlayer getThePlayer() { 25 | return FMLClientHandler.instance().getClientPlayerEntity(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/CommonProxy.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator; 2 | 3 | import net.minecraft.entity.player.EntityPlayer; 4 | 5 | import cpw.mods.fml.common.event.FMLInitializationEvent; 6 | import cpw.mods.fml.common.event.FMLPostInitializationEvent; 7 | import cpw.mods.fml.common.event.FMLPreInitializationEvent; 8 | import cpw.mods.fml.common.event.FMLServerStartingEvent; 9 | 10 | import com.recursive_pineapple.matter_manipulator.common.compat.BlockPropertyRegistry; 11 | import com.recursive_pineapple.matter_manipulator.common.entities.EntityItemLarge; 12 | import com.recursive_pineapple.matter_manipulator.common.items.MMItems; 13 | import com.recursive_pineapple.matter_manipulator.common.items.RecipeInstallUpgrade; 14 | import com.recursive_pineapple.matter_manipulator.common.networking.Messages; 15 | import com.recursive_pineapple.matter_manipulator.common.utils.Mods; 16 | import com.recursive_pineapple.matter_manipulator.server.BlockStateCommand; 17 | 18 | public class CommonProxy { 19 | 20 | public void preInit(FMLPreInitializationEvent event) { 21 | MMMod.LOG.info("Loading Matter Manipulator version " + Tags.VERSION); 22 | 23 | GlobalMMConfig.init(); 24 | MMItems.registerItems(); 25 | Messages.init(); 26 | } 27 | 28 | public void init(FMLInitializationEvent event) { 29 | EntityItemLarge.registerCommon(); 30 | 31 | if (Mods.AppliedEnergistics2.isModLoaded() && Mods.GregTech.isModLoaded()) { 32 | MMItems.registerMultis(); 33 | } 34 | 35 | RecipeInstallUpgrade.register(); 36 | } 37 | 38 | public void postInit(FMLPostInitializationEvent event) { 39 | BlockPropertyRegistry.init(); 40 | } 41 | 42 | public void serverStarting(FMLServerStartingEvent event) { 43 | event.registerServerCommand(new BlockStateCommand()); 44 | } 45 | 46 | public EntityPlayer getThePlayer() { 47 | return null; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/GlobalMMConfig.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator; 2 | 3 | import com.gtnewhorizon.gtnhlib.config.Config; 4 | import com.gtnewhorizon.gtnhlib.config.ConfigException; 5 | import com.gtnewhorizon.gtnhlib.config.ConfigurationManager; 6 | import com.recursive_pineapple.matter_manipulator.common.utils.Mods.Names; 7 | 8 | public class GlobalMMConfig { 9 | 10 | @Config(modid = Names.MATTER_MANIPULATOR, category = "interaction") 11 | public static class InteractionConfig { 12 | 13 | @Config.Comment("Clear the paste region when the copy or cut regions are marked") 14 | @Config.DefaultBoolean(true) 15 | @Config.Name("Auto Clear Paste") 16 | public static boolean pasteAutoClear; 17 | 18 | @Config.Comment("Clear the transform and the stacking amount when the coordinates are cleared") 19 | @Config.DefaultBoolean(true) 20 | @Config.Name("Clear Transform") 21 | public static boolean resetTransform; 22 | } 23 | 24 | @Config(modid = Names.MATTER_MANIPULATOR, category = "rendering") 25 | public static class RenderingConfig { 26 | 27 | @Config.Comment("Controls how many blocks are shown in the preview. Client only.") 28 | @Config.DefaultInt(1_000_000) 29 | @Config.Name("Max Hints Shown") 30 | public static int maxHints; 31 | 32 | @Config.Comment("Controls the duration of the build status warning/error hints (seconds). Client only. Set to 0 to never clear hints.") 33 | @Config.DefaultInt(60) 34 | @Config.Name("Build Status Timeout") 35 | public static int statusExpiration; 36 | 37 | @Config.Comment("When true, hints will always be drawn on top of the terrain. Client only.") 38 | @Config.DefaultBoolean(true) 39 | @Config.Name("Draw Hints On Top") 40 | public static boolean hintsOnTop; 41 | } 42 | 43 | @Config(modid = Names.MATTER_MANIPULATOR, category = "debug") 44 | public static class DebugConfig { 45 | 46 | @Config.DefaultBoolean(false) 47 | @Config.Name("Enable Debug Logging") 48 | public static boolean debug; 49 | } 50 | 51 | @Config(modid = Names.MATTER_MANIPULATOR, category = "building") 52 | public static class BuildingConfig { 53 | 54 | @Config.Comment("Empty ME Output Hatches/Busses when they're removed. Server only.") 55 | @Config.DefaultBoolean(true) 56 | @Config.Name("Empty ME Outputs") 57 | public static boolean meEmptying; 58 | 59 | @Config.Comment("High values may cause world desync and lag. Server only. Requires restart.") 60 | @Config.DefaultInt(256) 61 | @Config.RangeInt(min = 1) 62 | @Config.Name("MK3 Block Place Speed") 63 | @Config.RequiresMcRestart 64 | public static int mk3BlocksPerPlace; 65 | } 66 | 67 | public static boolean DEVENV = false; 68 | 69 | public static void init() { 70 | try { 71 | ConfigurationManager.registerConfig(InteractionConfig.class); 72 | ConfigurationManager.registerConfig(RenderingConfig.class); 73 | ConfigurationManager.registerConfig(DebugConfig.class); 74 | ConfigurationManager.registerConfig(BuildingConfig.class); 75 | } catch (ConfigException e) { 76 | throw new RuntimeException(e); 77 | } 78 | 79 | try { 80 | Class.forName("net.minecraft.server.MinecraftServer"); 81 | DEVENV = true; 82 | } catch (ClassNotFoundException e) { 83 | // ignored 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/MMMod.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator; 2 | 3 | import cpw.mods.fml.common.Mod; 4 | import cpw.mods.fml.common.Mod.EventHandler; 5 | import cpw.mods.fml.common.SidedProxy; 6 | import cpw.mods.fml.common.event.FMLInitializationEvent; 7 | import cpw.mods.fml.common.event.FMLMissingMappingsEvent; 8 | import cpw.mods.fml.common.event.FMLMissingMappingsEvent.MissingMapping; 9 | import cpw.mods.fml.common.event.FMLPostInitializationEvent; 10 | import cpw.mods.fml.common.event.FMLPreInitializationEvent; 11 | import cpw.mods.fml.common.event.FMLServerStartingEvent; 12 | import cpw.mods.fml.common.registry.GameRegistry.Type; 13 | 14 | import org.apache.logging.log4j.LogManager; 15 | import org.apache.logging.log4j.Logger; 16 | 17 | @Mod(modid = MMMod.MODID, version = Tags.VERSION, name = "Matter Manipulator", acceptedMinecraftVersions = "[1.7.10]") 18 | public class MMMod { 19 | 20 | public static final String MODID = "matter-manipulator"; 21 | public static final Logger LOG = LogManager.getLogger(MODID); 22 | 23 | @SidedProxy( 24 | clientSide = "com.recursive_pineapple.matter_manipulator.ClientProxy", 25 | serverSide = "com.recursive_pineapple.matter_manipulator.CommonProxy" 26 | ) 27 | public static CommonProxy proxy; 28 | 29 | @Mod.EventHandler 30 | public void preInit(FMLPreInitializationEvent event) { 31 | proxy.preInit(event); 32 | } 33 | 34 | @Mod.EventHandler 35 | public void init(FMLInitializationEvent event) { 36 | proxy.init(event); 37 | } 38 | 39 | @Mod.EventHandler 40 | public void postInit(FMLPostInitializationEvent event) { 41 | proxy.postInit(event); 42 | } 43 | 44 | @Mod.EventHandler 45 | public void serverStarting(FMLServerStartingEvent event) { 46 | proxy.serverStarting(event); 47 | } 48 | 49 | @EventHandler 50 | public void missingMapping(FMLMissingMappingsEvent event) { 51 | for (MissingMapping mapping : event.getAll()) { 52 | if (mapping.type != Type.ITEM) continue; 53 | if (mapping.name.equals("gregtech:gt.metaitem.04")) mapping.ignore(); 54 | if (mapping.name.equals("gregtech:itemMatterManipulator0")) mapping.ignore(); 55 | if (mapping.name.equals("gregtech:itemMatterManipulator1")) mapping.ignore(); 56 | if (mapping.name.equals("gregtech:itemMatterManipulator2")) mapping.ignore(); 57 | if (mapping.name.equals("gregtech:itemMatterManipulator3")) mapping.ignore(); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/MMModCore.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | import java.util.Set; 6 | 7 | import cpw.mods.fml.relauncher.IFMLLoadingPlugin; 8 | 9 | import com.gtnewhorizon.gtnhmixins.IEarlyMixinLoader; 10 | import com.recursive_pineapple.matter_manipulator.mixin.Mixin; 11 | 12 | @IFMLLoadingPlugin.MCVersion("1.7.10") 13 | public class MMModCore implements IFMLLoadingPlugin, IEarlyMixinLoader { 14 | 15 | @Override 16 | public String[] getASMTransformerClass() { 17 | return new String[] { 18 | "com.recursive_pineapple.matter_manipulator.asm.DeMemberator" 19 | }; 20 | } 21 | 22 | @Override 23 | public String getModContainerClass() { 24 | return null; 25 | } 26 | 27 | @Override 28 | public String getSetupClass() { 29 | return null; 30 | } 31 | 32 | @Override 33 | public void injectData(Map data) { 34 | 35 | } 36 | 37 | @Override 38 | public String getAccessTransformerClass() { 39 | return null; 40 | } 41 | 42 | @Override 43 | public String getMixinConfig() { 44 | return "mixins.matter-manipulator.early.json"; 45 | } 46 | 47 | @Override 48 | public List getMixins(Set loadedCoreMods) { 49 | return Mixin.getEarlyMixins(loadedCoreMods); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/asm/DeMemberator.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.asm; 2 | 3 | import java.lang.reflect.InvocationTargetException; 4 | import java.lang.reflect.Method; 5 | import java.util.Iterator; 6 | import java.util.List; 7 | 8 | import net.minecraft.launchwrapper.IClassTransformer; 9 | 10 | import com.gtnewhorizon.gtnhlib.asm.ClassConstantPoolParser; 11 | 12 | import org.objectweb.asm.ClassReader; 13 | import org.objectweb.asm.ClassWriter; 14 | import org.objectweb.asm.Opcodes; 15 | import org.objectweb.asm.tree.AnnotationNode; 16 | import org.objectweb.asm.tree.ClassNode; 17 | import org.objectweb.asm.tree.FieldNode; 18 | import org.objectweb.asm.tree.MethodNode; 19 | 20 | /** 21 | * Removes members 22 | */ 23 | public class DeMemberator implements IClassTransformer { 24 | 25 | private final ClassConstantPoolParser parser = new ClassConstantPoolParser("Lcom/recursive_pineapple/matter_manipulator/asm/Optional;"); 26 | 27 | @Override 28 | public byte[] transform(String name, String transformedName, byte[] basicClass) { 29 | 30 | if (parser.find(basicClass)) { 31 | ClassReader reader = new ClassReader(basicClass); 32 | ClassNode node = new ClassNode(Opcodes.ASM5); 33 | reader.accept(node, 0); 34 | 35 | Iterator fields = node.fields.iterator(); 36 | 37 | while (fields.hasNext()) { 38 | FieldNode field = fields.next(); 39 | if (field.invisibleAnnotations != null) { 40 | for (AnnotationNode an : field.invisibleAnnotations) { 41 | if (shouldBeRemoved(an)) { 42 | fields.remove(); 43 | break; 44 | } 45 | } 46 | } 47 | } 48 | 49 | Iterator methods = node.methods.iterator(); 50 | 51 | while (methods.hasNext()) { 52 | MethodNode method = methods.next(); 53 | 54 | if (method.invisibleAnnotations != null) { 55 | for (AnnotationNode an : method.invisibleAnnotations) { 56 | if (shouldBeRemoved(an)) { 57 | methods.remove(); 58 | break; 59 | } 60 | } 61 | } 62 | } 63 | 64 | final ClassWriter writer = new ClassWriter(0); 65 | node.accept(writer); 66 | return writer.toByteArray(); 67 | } else { 68 | return basicClass; 69 | } 70 | } 71 | 72 | private boolean shouldBeRemoved(AnnotationNode an) { 73 | if ("Lcom/recursive_pineapple/matter_manipulator/asm/Optional;".equals(an.desc)) { 74 | if (an.values != null && an.values.size() == 2) { 75 | @SuppressWarnings("unchecked") 76 | List mods = (List) an.values.get(1); 77 | 78 | for (String mod : mods) { 79 | try { 80 | Method method = Class.forName("cpw.mods.fml.common.Loader").getMethod("isModLoaded", String.class); 81 | 82 | if (!(boolean) method.invoke(null, mod)) { return true; } 83 | } catch (NoSuchMethodException | SecurityException | ClassNotFoundException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { 84 | throw new RuntimeException(e); 85 | } 86 | } 87 | } 88 | } 89 | 90 | return false; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/asm/Optional.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.asm; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Retention(RetentionPolicy.CLASS) 9 | @Target({ 10 | ElementType.FIELD, ElementType.METHOD 11 | }) 12 | public @interface Optional { 13 | 14 | public String[] value(); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/client/gui/DirectionDrawable.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.client.gui; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import net.minecraft.client.renderer.Tessellator; 5 | import net.minecraft.entity.Entity; 6 | 7 | import com.gtnewhorizons.modularui.api.drawable.IDrawable; 8 | 9 | import org.lwjgl.opengl.GL11; 10 | 11 | /** 12 | * "borrowed" from angelica and adapted to MUI 13 | * https://github.com/GTNewHorizons/Angelica/blob/99a81369f03d649bc4a48f23b026a1dea09c9e26/src/main/java/com/gtnewhorizons/angelica/debug/F3Direction.java 14 | */ 15 | public class DirectionDrawable implements IDrawable { 16 | 17 | private final Minecraft mc = Minecraft.getMinecraft(); 18 | 19 | @Override 20 | public void draw(float x, float y, float width, float height, float partialTicks) { 21 | if (mc.gameSettings.thirdPersonView == 0) { 22 | GL11.glPushMatrix(); 23 | 24 | GL11.glTranslatef(x + width / 2, y + height / 2, -90); 25 | 26 | Entity entity = mc.renderViewEntity; 27 | GL11.glRotatef(entity.prevRotationPitch + (entity.rotationPitch - entity.prevRotationPitch) * partialTicks, 1.0F, 0.0F, 0.0F); 28 | GL11.glRotatef(entity.prevRotationYaw + (entity.rotationYaw - entity.prevRotationYaw) * partialTicks, 0.0F, -1.0F, 0.0F); 29 | 30 | GL11.glScalef(-1.0F, -1.0F, 1.0F); 31 | 32 | renderWorldDirections(Math.min(width / 2, height / 2)); 33 | 34 | GL11.glPopMatrix(); 35 | } 36 | } 37 | 38 | public void renderWorldDirections(double length) { 39 | GL11.glDisable(GL11.GL_TEXTURE_2D); 40 | GL11.glDisable(GL11.GL_LIGHTING); 41 | GL11.glDepthMask(false); 42 | Tessellator tessellator = Tessellator.instance; 43 | 44 | GL11.glLineWidth(2.0F); 45 | tessellator.startDrawing(GL11.GL_LINES); 46 | 47 | // X 48 | tessellator.setColorRGBA(255, 0, 0, 255); 49 | tessellator.addVertex(0.0D, 0.0D, 0.0D); 50 | tessellator.addVertex(length, 0.0D, 0.0D); 51 | 52 | // Z 53 | tessellator.setColorRGBA(75, 75, 255, 255); 54 | tessellator.addVertex(0.0D, 0.0D, 0.0D); 55 | tessellator.addVertex(0.0D, 0.0D, length); 56 | 57 | // Y 58 | tessellator.setColorRGBA(0, 255, 0, 255); 59 | tessellator.addVertex(0.0D, 0.0D, 0.0D); 60 | tessellator.addVertex(0.0D, length, 0.0D); 61 | 62 | tessellator.draw(); 63 | 64 | GL11.glLineWidth(1.0F); 65 | GL11.glDepthMask(true); 66 | GL11.glEnable(GL11.GL_LIGHTING); 67 | GL11.glEnable(GL11.GL_TEXTURE_2D); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/client/nei/NEIMMConfig.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.client.nei; 2 | 3 | import cpw.mods.fml.common.eventhandler.SubscribeEvent; 4 | import cpw.mods.fml.relauncher.Side; 5 | 6 | import com.gtnewhorizon.gtnhlib.eventbus.EventBusSubscriber; 7 | import com.recursive_pineapple.matter_manipulator.MMMod; 8 | import com.recursive_pineapple.matter_manipulator.Tags; 9 | import com.recursive_pineapple.matter_manipulator.common.items.MMItemList; 10 | 11 | import codechicken.nei.api.IConfigureNEI; 12 | import codechicken.nei.event.NEIRegisterHandlerInfosEvent; 13 | import codechicken.nei.recipe.GuiCraftingRecipe; 14 | import codechicken.nei.recipe.GuiUsageRecipe; 15 | import codechicken.nei.recipe.HandlerInfo; 16 | 17 | @SuppressWarnings("unused") 18 | @EventBusSubscriber(side = Side.CLIENT) 19 | public class NEIMMConfig implements IConfigureNEI { 20 | 21 | private static final UpdateRecipeNEIHandler UPDATE_RECIPE_NEI_HANDLER = new UpdateRecipeNEIHandler(); 22 | 23 | @Override 24 | public void loadConfig() { 25 | GuiCraftingRecipe.craftinghandlers.add(UPDATE_RECIPE_NEI_HANDLER); 26 | GuiUsageRecipe.usagehandlers.add(UPDATE_RECIPE_NEI_HANDLER); 27 | } 28 | 29 | @Override 30 | public String getName() { 31 | return "Matter Manipulator"; 32 | } 33 | 34 | @Override 35 | public String getVersion() { 36 | return Tags.VERSION; 37 | } 38 | 39 | @SubscribeEvent 40 | public static void registerHandlerInfo(NEIRegisterHandlerInfosEvent event) { 41 | event.registerHandlerInfo( 42 | new HandlerInfo.Builder( 43 | UPDATE_RECIPE_NEI_HANDLER.getOverlayIdentifier(), 44 | "Matter Manipulator", 45 | MMMod.MODID 46 | ) 47 | .setMaxRecipesPerPage(100) 48 | .setDisplayStack(MMItemList.UpgradeBlank.get(1)) 49 | .build() 50 | ); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/client/nei/UpdateRecipeNEIHandler.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.client.nei; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Comparator; 5 | import java.util.List; 6 | 7 | import net.minecraft.item.ItemStack; 8 | import net.minecraft.util.StatCollector; 9 | 10 | import com.recursive_pineapple.matter_manipulator.common.items.MMItemList; 11 | import com.recursive_pineapple.matter_manipulator.common.items.MMItems; 12 | import com.recursive_pineapple.matter_manipulator.common.items.MMUpgrades; 13 | import com.recursive_pineapple.matter_manipulator.common.items.manipulator.ItemMatterManipulator; 14 | import com.recursive_pineapple.matter_manipulator.common.items.manipulator.MMState; 15 | 16 | import codechicken.nei.recipe.ShapelessRecipeHandler; 17 | 18 | public class UpdateRecipeNEIHandler extends ShapelessRecipeHandler { 19 | 20 | @Override 21 | public String getOverlayIdentifier() { 22 | return "mm.recipe.upgrades"; 23 | } 24 | 25 | @Override 26 | public String getRecipeTabName() { 27 | return getRecipeName(); 28 | } 29 | 30 | @Override 31 | public String getRecipeName() { 32 | return StatCollector.translateToLocal(getOverlayIdentifier()); 33 | } 34 | 35 | @Override 36 | public void loadCraftingRecipes(String outputId, Object... results) { 37 | if (outputId.equals("crafting") || outputId.equals(getOverlayIdentifier())) { 38 | loadRecipe(MMItemList.MK0.get(1)); 39 | loadRecipe(MMItemList.MK1.get(1)); 40 | loadRecipe(MMItemList.MK2.get(1)); 41 | loadRecipe(MMItemList.MK3.get(1)); 42 | } 43 | } 44 | 45 | @Override 46 | public void loadCraftingRecipes(ItemStack result) { 47 | if (result != null && result.getItem() instanceof ItemMatterManipulator) { 48 | loadRecipe(result); 49 | } 50 | } 51 | 52 | @Override 53 | public void loadUsageRecipes(ItemStack ingredient) { 54 | if (ingredient != null && ingredient.getItem() instanceof ItemMatterManipulator) { 55 | loadRecipe(ingredient); 56 | } 57 | 58 | if (ingredient != null && ingredient.getItem() == MMItems.META_ITEM) { 59 | MMUpgrades upgrade = MMUpgrades.UPGRADES_BY_META.get(ingredient.itemDamage); 60 | 61 | if (upgrade != null) { 62 | for (var tier : ItemMatterManipulator.ManipulatorTier.values()) { 63 | if (!tier.allowedUpgrades.contains(upgrade)) continue; 64 | 65 | arecipes.add( 66 | new CachedShapelessRecipe( 67 | new Object[] { 68 | tier.container.get(1), 69 | ingredient.copy(), 70 | }, 71 | modifyMM(tier.container.get(1), upgrade) 72 | ) 73 | ); 74 | } 75 | } 76 | } 77 | } 78 | 79 | private void loadRecipe(ItemStack mm) { 80 | MMState state = ItemMatterManipulator.getState(mm); 81 | 82 | List upgrades = new ArrayList<>(state.manipulator.tier.allowedUpgrades); 83 | upgrades.sort(Comparator.comparingInt(Enum::ordinal)); 84 | 85 | upgrades.removeIf(upgrade -> !state.couldAcceptUpgrade(state.manipulator.tier, upgrade)); 86 | 87 | for (MMUpgrades upgrade : upgrades) { 88 | arecipes.add( 89 | new CachedShapelessRecipe( 90 | new Object[] { 91 | mm.copy(), 92 | upgrade.getStack(), 93 | }, 94 | modifyMM(mm, upgrade) 95 | ) 96 | ); 97 | } 98 | } 99 | 100 | private ItemStack modifyMM(ItemStack mm, MMUpgrades toInstall) { 101 | mm = mm.copy(); 102 | 103 | MMState state = ItemMatterManipulator.getState(mm); 104 | 105 | state.installUpgrade(toInstall); 106 | 107 | ItemMatterManipulator.setState(mm, state); 108 | 109 | return mm; 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/client/rendering/QuadViewComparator.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.client.rendering; 2 | 3 | import java.util.Comparator; 4 | 5 | import com.gtnewhorizon.gtnhlib.client.renderer.quad.QuadView; 6 | 7 | import org.joml.Vector3f; 8 | 9 | /** 10 | * Sorts QuadViews according to their distance from the player. 11 | * It's mostly copied from the vanilla comparator. 12 | * This can certainly be improved, but it works well enough so I haven't. 13 | */ 14 | public class QuadViewComparator implements Comparator { 15 | 16 | private float pX, pY, pZ; 17 | 18 | public void setOrigin(float x, float y, float z) { 19 | pX = x; 20 | pY = y; 21 | pZ = z; 22 | } 23 | 24 | @Override 25 | public int compare(QuadView q1, QuadView q2) { 26 | Vector3f avg1 = new Vector3f(); 27 | Vector3f avg2 = new Vector3f(); 28 | 29 | for (int i = 0; i < 4; i++) { 30 | avg1.x += q1.getX(i) - pX; 31 | avg1.y += q1.getY(i) - pY; 32 | avg1.z += q1.getZ(i) - pZ; 33 | avg2.x += q2.getX(i) - pX; 34 | avg2.y += q2.getY(i) - pY; 35 | avg2.z += q2.getZ(i) - pZ; 36 | } 37 | 38 | avg1.mul(0.25f); 39 | avg2.mul(0.25f); 40 | 41 | return Float.compare(avg2.lengthSquared(), avg1.lengthSquared()); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/building/CopyableProperty.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.building; 2 | 3 | import com.google.common.collect.ImmutableList; 4 | 5 | public enum CopyableProperty { 6 | 7 | FACING, 8 | FORWARD, 9 | UP, 10 | LEFT, 11 | TOP, 12 | ROTATION, 13 | MODE, 14 | TEXT, 15 | ORIENTATION, 16 | DELAY, 17 | INVERTED, 18 | COLOR, 19 | ROTATION_STATE, 20 | ; 21 | 22 | public static final ImmutableList VALUES = ImmutableList.copyOf(values()); 23 | 24 | @Override 25 | public String toString() { 26 | return name().toLowerCase(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/building/CoverData.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.building; 2 | 3 | import net.minecraft.item.ItemStack; 4 | import net.minecraft.nbt.NBTTagCompound; 5 | 6 | import net.minecraftforge.common.util.ForgeDirection; 7 | 8 | import gregtech.api.interfaces.tileentity.ICoverable; 9 | import gregtech.common.covers.Cover; 10 | 11 | /** 12 | * Contains all GT cover analysis data. 13 | */ 14 | public class CoverData { 15 | 16 | public PortableItemStack cover; 17 | public int coverID; 18 | public NBTTagCompound coverData; 19 | 20 | public CoverData() {} 21 | 22 | public CoverData(PortableItemStack cover, int coverID, NBTTagCompound coverData) { 23 | this.cover = cover; 24 | this.coverID = coverID; 25 | this.coverData = coverData; 26 | } 27 | 28 | public ItemStack getCoverStack() { 29 | return cover.toStack(); 30 | } 31 | 32 | @Override 33 | public CoverData clone() { 34 | CoverData dup = new CoverData(); 35 | 36 | dup.cover = cover.clone(); 37 | dup.coverID = coverID; 38 | dup.coverData = (NBTTagCompound) coverData.copy(); 39 | 40 | return dup; 41 | } 42 | 43 | /** 44 | * Converts a CoverInfo into a CoverData. 45 | * 46 | * @return The CoverData, or null if there's no cover. 47 | */ 48 | public static CoverData fromMachine(ICoverable coverable, ForgeDirection dir) { 49 | if (!coverable.hasCoverAtSide(dir)) return null; 50 | 51 | Cover cover = coverable.getCoverAtSide(dir); 52 | 53 | return new CoverData( 54 | PortableItemStack.withNBT(coverable.getCoverItemAtSide(dir)), 55 | cover.getCoverID(), 56 | cover.writeToNBT(new NBTTagCompound()) 57 | ); 58 | } 59 | 60 | @Override 61 | public int hashCode() { 62 | final int prime = 31; 63 | int result = 1; 64 | result = prime * result + ((cover == null) ? 0 : cover.hashCode()); 65 | result = prime * result + coverID; 66 | result = prime * result + ((coverData == null) ? 0 : coverData.hashCode()); 67 | return result; 68 | } 69 | 70 | @Override 71 | public boolean equals(Object obj) { 72 | if (this == obj) return true; 73 | if (obj == null) return false; 74 | if (getClass() != obj.getClass()) return false; 75 | CoverData other = (CoverData) obj; 76 | if (cover == null) { 77 | if (other.cover != null) return false; 78 | } else if (!cover.equals(other.cover)) return false; 79 | if (other.coverID != coverID) return false; 80 | if (coverData == null) { 81 | if (other.coverData != null) return false; 82 | } else if (!coverData.equals(other.coverData)) return false; 83 | return true; 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/building/IBuildable.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.building; 2 | 3 | import net.minecraft.entity.player.EntityPlayer; 4 | import net.minecraft.item.ItemStack; 5 | 6 | /** 7 | * Something that can be built. 8 | */ 9 | public interface IBuildable { 10 | 11 | public void tryPlaceBlocks(ItemStack stack, EntityPlayer player); 12 | 13 | public void onStopped(); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/building/IItemProvider.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.building; 2 | 3 | import net.minecraft.item.ItemStack; 4 | 5 | import org.jetbrains.annotations.Contract; 6 | import org.jetbrains.annotations.Nullable; 7 | 8 | /** 9 | * Something that can provide items. 10 | */ 11 | public interface IItemProvider { 12 | 13 | /** 14 | * Gets a stack of the item provided by this provider. 15 | * The extraction must be atomic - if it fails, this method must not delete items. 16 | * 17 | * @param inv 18 | * @param consume When false, no items will be extracted and the item will be provided as normal. 19 | * @return The item, or null if the pseudo inventory didn't have the required items. 20 | */ 21 | @Contract("_,false->!null") 22 | @Nullable 23 | ItemStack getStack(IPseudoInventory inv, boolean consume); 24 | 25 | default String describe() { 26 | return getStack(null, false).getDisplayName(); 27 | } 28 | 29 | IItemProvider clone(); 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/building/IPseudoInventory.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.building; 2 | 3 | import java.util.List; 4 | 5 | import net.minecraft.item.ItemStack; 6 | 7 | import net.minecraftforge.fluids.FluidStack; 8 | 9 | import com.recursive_pineapple.matter_manipulator.common.utils.BigFluidStack; 10 | import com.recursive_pineapple.matter_manipulator.common.utils.BigItemStack; 11 | import com.recursive_pineapple.matter_manipulator.common.utils.MMUtils; 12 | 13 | import it.unimi.dsi.fastutil.booleans.BooleanObjectImmutablePair; 14 | 15 | /** 16 | * Something that can accept and provide items/fluids. 17 | */ 18 | public interface IPseudoInventory { 19 | 20 | /** Items will not actually be consumed. */ 21 | public static final int CONSUME_SIMULATED = 0b1; 22 | /** Items will be fuzzily-matched. Ignores NBT and ignores damage for items without subitems */ 23 | public static final int CONSUME_FUZZY = 0b10; 24 | /** Not all items must be extracted. */ 25 | public static final int CONSUME_PARTIAL = 0b100; 26 | /** Creative mode infinite supply will be ignored, but not 111 stacks. */ 27 | public static final int CONSUME_IGNORE_CREATIVE = 0b1000; 28 | /** Only consume real items (extractions while planning will always fail). */ 29 | public static final int CONSUME_REAL_ONLY = 0b10000; 30 | 31 | /** 32 | * Atomically extracts items from this pseudo inventory. 33 | * The returned list is guaranteed to at minimum be equal to the items param. 34 | * If the extraction succeeded and partial mode wasn't enabled, extraneous items will not be extracted and the 35 | * returned list will contain the same items as the request. 36 | * If fuzzy mode is enabled there may be several stacks with different tags (and damages where relevant), but every 37 | * stackable item will be merged into the same BigItemStack. 38 | * 39 | * @param items The list of items to extract. 40 | * @param flags The flags (see {@link IPseudoInventory#CONSUME_SIMULATED}, {@link IPseudoInventory#CONSUME_FUZZY}, 41 | * etc). 42 | * @return Key = whether the extract was successful. Value = the list of items extracted (only relevant for fuzzy 43 | * mode). 44 | */ 45 | public BooleanObjectImmutablePair> tryConsumeItems(List items, int flags); 46 | 47 | /** 48 | * Consumes a set of items. 49 | * 50 | * @return True when the items were successfully consumed. 51 | */ 52 | public default boolean tryConsumeItems(ItemStack... items) { 53 | return tryConsumeItems(MMUtils.mapToList(items, BigItemStack::create), 0).leftBoolean(); 54 | } 55 | 56 | public void givePlayerItems(List items); 57 | 58 | public default void givePlayerItems(ItemStack... items) { 59 | givePlayerItems(MMUtils.mapToList(items, BigItemStack::create)); 60 | } 61 | 62 | public void givePlayerFluids(List fluids); 63 | 64 | public default void givePlayerFluids(FluidStack... fluids) { 65 | givePlayerFluids(MMUtils.mapToList(fluids, BigFluidStack::create)); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/building/ITileAnalysisIntegration.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.building; 2 | 3 | import java.util.List; 4 | 5 | import net.minecraft.nbt.NBTTagCompound; 6 | 7 | import com.recursive_pineapple.matter_manipulator.common.building.BlockAnalyzer.IBlockApplyContext; 8 | import com.recursive_pineapple.matter_manipulator.common.items.manipulator.Transform; 9 | 10 | public interface ITileAnalysisIntegration { 11 | 12 | boolean apply(IBlockApplyContext ctx); 13 | 14 | boolean getRequiredItemsForExistingBlock(IBlockApplyContext context); 15 | 16 | boolean getRequiredItemsForNewBlock(IBlockApplyContext context); 17 | 18 | void getItemTag(NBTTagCompound tag); 19 | 20 | void getItemDetails(List details); 21 | 22 | void transform(Transform transform); 23 | 24 | ITileAnalysisIntegration clone(); 25 | 26 | void migrate(); 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/building/ImmutableBlockSpec.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.building; 2 | 3 | import java.util.Comparator; 4 | import java.util.List; 5 | import java.util.Map; 6 | 7 | import net.minecraft.block.Block; 8 | import net.minecraft.item.Item; 9 | import net.minecraft.item.ItemStack; 10 | import net.minecraft.world.World; 11 | 12 | import cpw.mods.fml.common.registry.GameRegistry.UniqueIdentifier; 13 | 14 | import com.recursive_pineapple.matter_manipulator.common.utils.ImmutableItemMeta; 15 | import com.recursive_pineapple.matter_manipulator.common.utils.ItemId; 16 | 17 | public interface ImmutableBlockSpec extends ImmutableItemMeta { 18 | 19 | UniqueIdentifier getObjectId(); 20 | 21 | Block getBlock(); 22 | 23 | Item getItem(); 24 | 25 | ItemId getItemId(); 26 | 27 | int getMeta(); 28 | 29 | int getBlockMeta(); 30 | 31 | ItemStack getStack(); 32 | 33 | PendingBlock instantiate(int worldId, int x, int y, int z); 34 | 35 | default PendingBlock instantiate(World world, int x, int y, int z) { 36 | return instantiate(world.provider.dimensionId, x, y, z); 37 | } 38 | 39 | String getProperty(CopyableProperty property); 40 | 41 | ImmutableBlockSpec withProperties(Map properties); 42 | 43 | default boolean isEquivalent(ImmutableBlockSpec other) { 44 | return ItemStack.areItemStacksEqual(getStack(), other.getStack()); 45 | } 46 | 47 | /** Returns true when this contains air. BlockSpecs may be air if an invalid block was analyzed. */ 48 | default boolean isAir() { 49 | return getObjectId() == null || getBlock() == null || InteropConstants.isAir(getBlock(), getBlockMeta()); 50 | } 51 | 52 | default boolean skipWhenCopying() { 53 | return InteropConstants.skipWhenCopying(getBlock(), getBlockMeta()); 54 | } 55 | 56 | default boolean shouldDropItem() { 57 | return InteropConstants.shouldDropItem(getBlock(), getBlockMeta()); 58 | } 59 | 60 | default boolean isFree() { 61 | return InteropConstants.isFree(getBlock(), getBlockMeta()); 62 | } 63 | 64 | void getItemDetails(List details); 65 | 66 | static Comparator getComparator() { 67 | Comparator blockId = Comparator.nullsFirst( 68 | Comparator.comparing((UniqueIdentifier id) -> id.modId) 69 | .thenComparing(id -> id.name) 70 | ); 71 | 72 | return Comparator.nullsFirst(Comparator.comparing(ImmutableBlockSpec::getObjectId, blockId)).thenComparingInt(ImmutableBlockSpec::getMeta); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/building/InteropConstants.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.building; 2 | 3 | import net.minecraft.block.Block; 4 | import net.minecraft.block.material.MaterialLiquid; 5 | import net.minecraft.block.material.MaterialTransparent; 6 | import net.minecraft.init.Blocks; 7 | 8 | import net.minecraftforge.oredict.OreDictionary; 9 | 10 | import gregtech.api.GregTechAPI; 11 | 12 | import com.recursive_pineapple.matter_manipulator.asm.Optional; 13 | import com.recursive_pineapple.matter_manipulator.common.utils.LazyBlock; 14 | import com.recursive_pineapple.matter_manipulator.common.utils.Mods; 15 | import com.recursive_pineapple.matter_manipulator.common.utils.Mods.Names; 16 | 17 | import bartworks.common.loaders.FluidLoader; 18 | import goodgenerator.loader.Loaders; 19 | import tectech.thing.casing.TTCasingsContainer; 20 | 21 | /** 22 | * Various constants or static methods used for interop. 23 | */ 24 | public class InteropConstants { 25 | 26 | private InteropConstants() {} 27 | 28 | public static final LazyBlock BRIGHT_AIR = new LazyBlock(Mods.GalacticraftCore, "tile.brightAir", OreDictionary.WILDCARD_VALUE); 29 | public static final LazyBlock ARCANE_LAMP_LIGHT = new LazyBlock(Mods.Thaumcraft, "blockAiry", 2); 30 | public static final LazyBlock WIRELESS_CONNECTOR = new LazyBlock(Mods.AE2Stuff, "Wireless"); 31 | public static final LazyBlock AE_BLOCK_CABLE = new LazyBlock(Mods.AppliedEnergistics2, "tile.BlockCableBus"); 32 | public static final LazyBlock FMP_BLOCK = new LazyBlock(Mods.ForgeMultipart, "block"); 33 | 34 | public static boolean isAir(Block block, int meta) { 35 | if (block.getMaterial() instanceof MaterialTransparent) return true; 36 | 37 | return false; 38 | } 39 | 40 | public static boolean skipWhenCopying(Block block, int meta) { 41 | if (block.getMaterial() instanceof MaterialLiquid) return true; 42 | 43 | if (Mods.GregTech.isModLoaded() && isGTRenderer(block)) return true; 44 | if (FMP_BLOCK.matches(block, meta)) return true; 45 | if (BRIGHT_AIR.matches(block, meta)) return true; 46 | if (ARCANE_LAMP_LIGHT.matches(block, meta)) return true; 47 | 48 | return false; 49 | } 50 | 51 | public static boolean shouldDropItem(Block block, int meta) { 52 | if (Mods.GregTech.isModLoaded() && isGTRenderer(block)) return false; 53 | 54 | // Don't check for MaterialTransparent because it could include things like nitor 55 | if (BRIGHT_AIR.matches(block, meta)) return false; 56 | if (ARCANE_LAMP_LIGHT.matches(block, meta)) return false; 57 | 58 | return true; 59 | } 60 | 61 | @Optional(Names.GREG_TECH) 62 | private static boolean isGTRenderer(Block block) { 63 | if (block == GregTechAPI.sDroneRender) return true; 64 | if (block == GregTechAPI.sWormholeRender) return true; 65 | if (block == GregTechAPI.sBlackholeRender) return true; 66 | if (block == TTCasingsContainer.eyeOfHarmonyRenderBlock) return true; 67 | if (block == TTCasingsContainer.forgeOfGodsRenderBlock) return true; 68 | if (block == FluidLoader.bioFluidBlock) return true; 69 | if (block == Loaders.antimatterRenderBlock) return true; 70 | 71 | return false; 72 | } 73 | 74 | public static boolean isFree(Block block, int metadata) { 75 | if (block == Blocks.air) return true; 76 | 77 | if (FMP_BLOCK.matches(block, metadata)) return true; 78 | if (AE_BLOCK_CABLE.matches(block, metadata)) return true; 79 | 80 | return false; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/building/InventoryAnalysis.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.building; 2 | 3 | import java.util.Objects; 4 | 5 | import javax.annotation.Nullable; 6 | 7 | import net.minecraft.inventory.IInventory; 8 | import net.minecraft.item.ItemStack; 9 | 10 | import com.recursive_pineapple.matter_manipulator.common.building.BlockAnalyzer.IBlockApplyContext; 11 | import com.recursive_pineapple.matter_manipulator.common.building.providers.BatteryItemProvider; 12 | import com.recursive_pineapple.matter_manipulator.common.utils.InventoryAdapter; 13 | import com.recursive_pineapple.matter_manipulator.common.utils.MMUtils; 14 | import com.recursive_pineapple.matter_manipulator.common.utils.Mods; 15 | 16 | /** 17 | * An analysis for an inventory. 18 | */ 19 | public class InventoryAnalysis { 20 | 21 | public boolean mFuzzy; 22 | public IItemProvider[] mItems; 23 | 24 | public InventoryAnalysis() {} 25 | 26 | /** 27 | * Gets an analysis for an inventory. 28 | * 29 | * @param fuzzy When true, NBT will be ignored and items will be fuzzily-retrieved. 30 | */ 31 | public static @Nullable InventoryAnalysis fromInventory(IInventory inv, boolean fuzzy) { 32 | InventoryAnalysis analysis = new InventoryAnalysis(); 33 | analysis.mFuzzy = fuzzy; 34 | 35 | analysis.mItems = new IItemProvider[inv.getSizeInventory()]; 36 | 37 | InventoryAdapter adapter = InventoryAdapter.findAdapter(inv); 38 | 39 | if (adapter == null) return null; 40 | 41 | for (int slot = 0; slot < analysis.mItems.length; slot++) { 42 | if (!adapter.isValidSlot(inv, slot)) continue; 43 | 44 | analysis.mItems[slot] = getProviderFor(inv.getStackInSlot(slot), fuzzy); 45 | } 46 | 47 | return analysis; 48 | } 49 | 50 | private static IItemProvider getProviderFor(ItemStack stack, boolean fuzzy) { 51 | if (stack == null || stack.getItem() == null) return null; 52 | 53 | if (Mods.AppliedEnergistics2.isModLoaded()) { 54 | if (!fuzzy) { 55 | IItemProvider cell = AECellItemProvider.fromWorkbenchItem(stack); 56 | 57 | if (cell != null) return cell; 58 | } 59 | 60 | IItemProvider pattern = PatternItemProvider.fromPattern(stack); 61 | 62 | if (pattern != null) return pattern; 63 | } 64 | 65 | IItemProvider battery = BatteryItemProvider.fromStack(stack); 66 | 67 | if (battery != null) return battery; 68 | 69 | return fuzzy ? new PortableItemStack(stack) : PortableItemStack.withNBT(stack); 70 | } 71 | 72 | /** 73 | * Applies the analysis 74 | * 75 | * @param consume When true, items will be consumed 76 | * @param simulate When true, the inventory will not be modified in any way 77 | * @return True when the inventory was successfully updated 78 | */ 79 | public boolean apply(IBlockApplyContext context, IInventory inv, boolean consume, boolean simulate) { 80 | return apply(context, inv, InventoryAdapter.findAdapter(inv), consume, simulate); 81 | } 82 | 83 | private boolean apply(IBlockApplyContext context, IInventory inv, InventoryAdapter adapter, boolean consume, boolean simulate) { 84 | if (!adapter.validate(context, inv)) return false; 85 | 86 | if (inv.getSizeInventory() != mItems.length) { 87 | context.warn("Inventory was the wrong size (expected " + mItems.length + ", was " + inv.getSizeInventory() + ")"); 88 | return false; 89 | } 90 | 91 | boolean didSomething = false; 92 | boolean success = true; 93 | 94 | for (int slot = 0; slot < mItems.length; slot++) { 95 | if (!adapter.isValidSlot(inv, slot)) continue; 96 | 97 | IItemProvider target = mItems[slot]; 98 | IItemProvider actual = getProviderFor(inv.getStackInSlot(slot), mFuzzy); 99 | 100 | if (!Objects.equals(target, actual)) { 101 | ItemStack stack = inv.getStackInSlot(slot); 102 | if (stack != null) { 103 | if (!adapter.canExtract(inv, slot)) { 104 | context.warn("Could not extract item in slot " + slot + ": " + MMUtils.stripFormat(stack.getDisplayName())); 105 | continue; 106 | } 107 | 108 | if (!simulate) { 109 | stack = adapter.extract(inv, slot); 110 | if (stack != null) didSomething = true; 111 | } 112 | 113 | if (stack != null && consume) context.givePlayerItems(stack); 114 | } 115 | 116 | if (target != null) { 117 | if (!adapter.canInsert(inv, slot, target.getStack(null, false))) { 118 | context.warn("Invalid item for slot " + slot + ": " + MMUtils.stripFormat(target.describe())); 119 | continue; 120 | } 121 | 122 | ItemStack toInsert = target.getStack(context, consume); 123 | 124 | if (toInsert == null) { 125 | context.warn("Could not gather item for inventory: " + MMUtils.stripFormat(target.describe())); 126 | success = false; 127 | } else { 128 | if (!simulate) { 129 | if (adapter.insert(inv, slot, toInsert)) { 130 | didSomething = true; 131 | } else { 132 | context.givePlayerItems(toInsert); 133 | } 134 | } 135 | } 136 | } 137 | } 138 | } 139 | 140 | if (didSomething) inv.markDirty(); 141 | 142 | return success; 143 | } 144 | 145 | @Override 146 | protected InventoryAnalysis clone() { 147 | InventoryAnalysis dup = new InventoryAnalysis(); 148 | 149 | dup.mFuzzy = mFuzzy; 150 | dup.mItems = MMUtils.mapToArray(mItems, IItemProvider[]::new, x -> x == null ? null : x.clone()); 151 | 152 | return dup; 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/building/MultipartAnalysisResult.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.building; 2 | 3 | import java.util.List; 4 | 5 | import net.minecraft.nbt.NBTTagCompound; 6 | import net.minecraft.tileentity.TileEntity; 7 | import net.minecraft.world.World; 8 | 9 | import com.recursive_pineapple.matter_manipulator.common.building.BlockAnalyzer.IBlockApplyContext; 10 | import com.recursive_pineapple.matter_manipulator.common.items.manipulator.Transform; 11 | 12 | import codechicken.lib.vec.BlockCoord; 13 | import codechicken.microblock.Microblock; 14 | import codechicken.multipart.TileMultipart; 15 | 16 | public class MultipartAnalysisResult implements ITileAnalysisIntegration { 17 | 18 | public static MultipartAnalysisResult analyze(TileEntity tile) { 19 | if (!(tile instanceof TileMultipart multipart)) return null; 20 | 21 | var partList = multipart.jPartList(); 22 | 23 | Microblock m = (Microblock) partList.get(0); 24 | 25 | return null; 26 | } 27 | 28 | @Override 29 | public boolean apply(IBlockApplyContext ctx) { 30 | World world = ctx.getWorld(); 31 | int x = ctx.getX(); 32 | int y = ctx.getY(); 33 | int z = ctx.getZ(); 34 | 35 | if (!InteropConstants.FMP_BLOCK.matches(world.getBlock(x, y, z), 0)) return false; 36 | 37 | BlockCoord coord = new BlockCoord(x, y, z); 38 | 39 | TileMultipart tile = TileMultipart.getOrConvertTile(ctx.getWorld(), coord); 40 | 41 | var partList = tile.jPartList(); 42 | 43 | return true; 44 | } 45 | 46 | @Override 47 | public boolean getRequiredItemsForExistingBlock(IBlockApplyContext context) { 48 | return true; 49 | } 50 | 51 | @Override 52 | public boolean getRequiredItemsForNewBlock(IBlockApplyContext context) { 53 | return true; 54 | } 55 | 56 | @Override 57 | public void getItemTag(NBTTagCompound tag) { 58 | 59 | } 60 | 61 | @Override 62 | public void getItemDetails(List details) { 63 | 64 | } 65 | 66 | @Override 67 | public void transform(Transform transform) { 68 | 69 | } 70 | 71 | @Override 72 | public void migrate() { 73 | 74 | } 75 | 76 | @Override 77 | public MultipartAnalysisResult clone() { 78 | MultipartAnalysisResult dup = new MultipartAnalysisResult(); 79 | 80 | return dup; 81 | } 82 | 83 | @Override 84 | public int hashCode() { 85 | return 0; 86 | } 87 | 88 | @Override 89 | public boolean equals(Object obj) { 90 | return obj instanceof MultipartAnalysisResult; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/building/MultipartPart.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.building; 2 | 3 | public class MultipartPart { 4 | 5 | public PortableItemStack item; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/building/PatternItemProvider.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.building; 2 | 3 | import java.util.Arrays; 4 | 5 | import net.minecraft.item.ItemStack; 6 | import net.minecraft.nbt.NBTTagCompound; 7 | 8 | import appeng.api.AEApi; 9 | import appeng.api.definitions.IItemDefinition; 10 | 11 | import com.recursive_pineapple.matter_manipulator.common.utils.BigItemStack; 12 | 13 | import org.jetbrains.annotations.Nullable; 14 | 15 | /** 16 | * An item provider that creates encoded AE patterns from blank patterns. 17 | */ 18 | public class PatternItemProvider implements IItemProvider { 19 | 20 | private Integer amount; 21 | private NBTTagCompound pattern; 22 | 23 | private static final IItemDefinition BLANK_PATTERN = AEApi.instance() 24 | .definitions() 25 | .materials() 26 | .blankPattern(); 27 | private static final IItemDefinition PATTERN = AEApi.instance() 28 | .definitions() 29 | .items() 30 | .encodedPattern(); 31 | 32 | public PatternItemProvider() {} 33 | 34 | public static PatternItemProvider fromPattern(ItemStack stack) { 35 | if (!PATTERN.isSameAs(stack)) { return null; } 36 | 37 | PatternItemProvider pattern = new PatternItemProvider(); 38 | 39 | pattern.amount = stack.stackSize != 1 ? stack.stackSize : null; 40 | pattern.pattern = stack.getTagCompound(); 41 | 42 | return pattern; 43 | } 44 | 45 | @Override 46 | public @Nullable ItemStack getStack(IPseudoInventory inv, boolean consume) { 47 | ItemStack stack = PATTERN.maybeStack(1).get(); 48 | 49 | stack.stackSize = amount == null ? 1 : amount; 50 | stack.setTagCompound(pattern != null ? (NBTTagCompound) pattern.copy() : null); 51 | 52 | if (consume) { 53 | if (!inv.tryConsumeItems(Arrays.asList(BigItemStack.create(stack)), IPseudoInventory.CONSUME_REAL_ONLY).firstBoolean()) { 54 | ItemStack toConsume = BLANK_PATTERN.maybeStack(amount == null ? 1 : amount).get(); 55 | if (!inv.tryConsumeItems(toConsume)) return null; 56 | } 57 | } 58 | 59 | return stack; 60 | } 61 | 62 | @Override 63 | public String describe() { 64 | return BLANK_PATTERN.maybeStack(1).get().getDisplayName(); 65 | } 66 | 67 | @Override 68 | public PatternItemProvider clone() { 69 | PatternItemProvider dup = new PatternItemProvider(); 70 | 71 | dup.amount = amount; 72 | dup.pattern = (NBTTagCompound) pattern.copy(); 73 | 74 | return dup; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/building/PortableItemStack.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.building; 2 | 3 | import net.minecraft.block.Block; 4 | import net.minecraft.init.Items; 5 | import net.minecraft.item.Item; 6 | import net.minecraft.item.ItemStack; 7 | import net.minecraft.nbt.NBTTagCompound; 8 | 9 | import cpw.mods.fml.common.registry.GameRegistry; 10 | import cpw.mods.fml.common.registry.GameRegistry.UniqueIdentifier; 11 | 12 | import com.google.gson.annotations.SerializedName; 13 | 14 | /** 15 | * An item stack that can be moved between worlds without id shifting. 16 | */ 17 | public class PortableItemStack implements IItemProvider { 18 | 19 | @SerializedName("id") 20 | public UniqueIdentifier item; 21 | @SerializedName("m") 22 | public Integer metadata; 23 | @SerializedName("a") 24 | public Integer amount; 25 | @SerializedName("nbt") 26 | public NBTTagCompound nbt; 27 | 28 | public transient Item itemRef; 29 | public transient Block blockRef; 30 | public transient ItemStack itemStack; 31 | 32 | public PortableItemStack() {} 33 | 34 | public PortableItemStack(Item item, int metadata) { 35 | this.item = GameRegistry.findUniqueIdentifierFor(item); 36 | this.metadata = metadata == 0 ? null : metadata; 37 | this.amount = null; 38 | } 39 | 40 | public PortableItemStack(Item item, int metadata, NBTTagCompound nbt) { 41 | this.item = GameRegistry.findUniqueIdentifierFor(item); 42 | this.metadata = metadata == 0 ? null : metadata; 43 | this.amount = null; 44 | this.nbt = nbt; 45 | } 46 | 47 | public PortableItemStack(ItemStack stack) { 48 | item = GameRegistry.findUniqueIdentifierFor(stack.getItem()); 49 | metadata = Items.feather.getDamage(stack); 50 | if (metadata == 0) metadata = null; 51 | amount = stack.stackSize == 1 ? null : stack.stackSize; 52 | } 53 | 54 | public static PortableItemStack withoutStackSize(ItemStack stack) { 55 | stack = stack.copy(); 56 | stack.stackSize = 1; 57 | return new PortableItemStack(stack); 58 | } 59 | 60 | public static PortableItemStack withNBT(ItemStack stack) { 61 | PortableItemStack portable = new PortableItemStack(stack); 62 | portable.nbt = stack.getTagCompound() == null ? null : (NBTTagCompound) stack.getTagCompound().copy(); 63 | return portable; 64 | } 65 | 66 | public int getMeta() { 67 | return metadata == null ? 0 : metadata.intValue(); 68 | } 69 | 70 | public Item getItem() { 71 | if (blockRef == null) { 72 | itemRef = GameRegistry.findItem(item.modId, item.name); 73 | } 74 | 75 | return itemRef; 76 | } 77 | 78 | public ItemStack toStack() { 79 | if (itemStack == null) { 80 | Item item = getItem(); 81 | 82 | if (item == null) return null; 83 | 84 | itemStack = new ItemStack( 85 | item, 86 | amount == null ? 1 : amount, 87 | metadata == null ? 0 : metadata 88 | ); 89 | 90 | if (nbt != null) { 91 | itemStack.setTagCompound((NBTTagCompound) nbt.copy()); 92 | } 93 | } 94 | 95 | return itemStack.copy(); 96 | } 97 | 98 | public Block getBlock() { 99 | if (blockRef == null) { 100 | blockRef = GameRegistry.findBlock(item.modId, item.name); 101 | } 102 | 103 | return blockRef; 104 | } 105 | 106 | @Override 107 | public ItemStack getStack(IPseudoInventory inv, boolean consume) { 108 | ItemStack stack = toStack(); 109 | 110 | if (!consume) { return stack; } 111 | 112 | if (!inv.tryConsumeItems(stack)) { return null; } 113 | 114 | return stack; 115 | } 116 | 117 | @Override 118 | public String toString() { 119 | return toStack().getDisplayName() + (amount == null || amount == 1 ? "" : " x " + amount); 120 | } 121 | 122 | @Override 123 | public PortableItemStack clone() { 124 | PortableItemStack dup = new PortableItemStack(); 125 | 126 | dup.item = item; 127 | dup.metadata = metadata; 128 | dup.amount = amount; 129 | dup.nbt = nbt == null ? null : (NBTTagCompound) nbt.copy(); 130 | dup.itemRef = itemRef; 131 | dup.blockRef = blockRef; 132 | dup.itemStack = itemStack; 133 | 134 | return dup; 135 | } 136 | 137 | @Override 138 | public int hashCode() { 139 | final int prime = 31; 140 | int result = 1; 141 | result = prime * result + ((item == null) ? 0 : item.hashCode()); 142 | result = prime * result + ((metadata == null) ? 0 : metadata.hashCode()); 143 | result = prime * result + ((amount == null) ? 0 : amount.hashCode()); 144 | result = prime * result + ((nbt == null) ? 0 : nbt.hashCode()); 145 | result = prime * result + ((itemStack == null) ? 0 : itemStack.hashCode()); 146 | return result; 147 | } 148 | 149 | @Override 150 | public boolean equals(Object obj) { 151 | if (this == obj) return true; 152 | if (obj == null) return false; 153 | if (getClass() != obj.getClass()) return false; 154 | PortableItemStack other = (PortableItemStack) obj; 155 | if (item == null) { 156 | if (other.item != null) return false; 157 | } else if (!item.equals(other.item)) return false; 158 | if (metadata == null) { 159 | if (other.metadata != null) return false; 160 | } else if (!metadata.equals(other.metadata)) return false; 161 | if (amount == null) { 162 | if (other.amount != null) return false; 163 | } else if (!amount.equals(other.amount)) return false; 164 | if (nbt == null) { 165 | if (other.nbt != null) return false; 166 | } else if (!nbt.equals(other.nbt)) return false; 167 | if (itemStack == null) { 168 | if (other.itemStack != null) return false; 169 | } else if (!itemStack.equals(other.itemStack)) return false; 170 | return true; 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/building/ProxiedWorld.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.building; 2 | 3 | import java.io.File; 4 | 5 | import net.minecraft.block.Block; 6 | import net.minecraft.entity.Entity; 7 | import net.minecraft.init.Blocks; 8 | import net.minecraft.nbt.NBTTagCompound; 9 | import net.minecraft.profiler.Profiler; 10 | import net.minecraft.tileentity.TileEntity; 11 | import net.minecraft.world.World; 12 | import net.minecraft.world.WorldProvider; 13 | import net.minecraft.world.WorldSettings; 14 | import net.minecraft.world.biome.BiomeGenBase; 15 | import net.minecraft.world.chunk.IChunkProvider; 16 | import net.minecraft.world.chunk.storage.IChunkLoader; 17 | import net.minecraft.world.storage.IPlayerFileData; 18 | import net.minecraft.world.storage.ISaveHandler; 19 | import net.minecraft.world.storage.WorldInfo; 20 | 21 | import com.gtnewhorizon.structurelib.util.XSTR; 22 | 23 | public class ProxiedWorld extends World { 24 | 25 | private final World world; 26 | 27 | public int airX, airY, airZ; 28 | 29 | public ProxiedWorld(World world) { 30 | super(new ISaveHandler() { 31 | 32 | @Override 33 | public void saveWorldInfoWithPlayer(WorldInfo worldInfo, NBTTagCompound nbtTagCompound) {} 34 | 35 | @Override 36 | public void saveWorldInfo(WorldInfo worldInfo) {} 37 | 38 | @Override 39 | public WorldInfo loadWorldInfo() { 40 | return null; 41 | } 42 | 43 | @Override 44 | public IPlayerFileData getSaveHandler() { 45 | return null; 46 | } 47 | 48 | @Override 49 | public File getMapFileFromName(String mapName) { 50 | return null; 51 | } 52 | 53 | @Override 54 | public IChunkLoader getChunkLoader(WorldProvider worldProvider) { 55 | return null; 56 | } 57 | 58 | @Override 59 | public void flush() {} 60 | 61 | @Override 62 | public void checkSessionLock() {} 63 | 64 | @Override 65 | public String getWorldDirectoryName() { 66 | return null; 67 | } 68 | 69 | @Override 70 | public File getWorldDirectory() { 71 | return null; 72 | } 73 | }, "DUMMY_DIMENSION", null, new WorldSettings(new WorldInfo(new NBTTagCompound())), new Profiler()); 74 | 75 | this.rand = new XSTR(); 76 | this.world = world; 77 | this.chunkProvider = world.getChunkProvider(); 78 | } 79 | 80 | @Override 81 | protected IChunkProvider createChunkProvider() { 82 | return null; 83 | } 84 | 85 | @Override 86 | public Entity getEntityByID(int aEntityID) { 87 | return null; 88 | } 89 | 90 | @Override 91 | public boolean setBlock(int aX, int aY, int aZ, Block aBlock, int aMeta, int aFlags) { 92 | return true; 93 | } 94 | 95 | @Override 96 | public float getSunBrightnessFactor(float p_72967_1_) { 97 | return world.getSunBrightnessFactor(p_72967_1_); 98 | } 99 | 100 | @Override 101 | public BiomeGenBase getBiomeGenForCoords(int aX, int aZ) { 102 | return world.getBiomeGenForCoords(aX, aZ); 103 | } 104 | 105 | @Override 106 | public int getFullBlockLightValue(int aX, int aY, int aZ) { 107 | return world.getFullBlockLightValue(aX, aY, aZ); 108 | } 109 | 110 | @Override 111 | public Block getBlock(int aX, int aY, int aZ) { 112 | if (aX == airX && aY == airY && aZ == airZ) return Blocks.air; 113 | 114 | return world.getBlock(aX, aY, aZ); 115 | } 116 | 117 | @Override 118 | public int getBlockMetadata(int aX, int aY, int aZ) { 119 | if (aX == airX && aY == airY && aZ == airZ) return 0; 120 | 121 | return world.getBlockMetadata(aX, aY, aZ); 122 | } 123 | 124 | @Override 125 | public TileEntity getTileEntity(int aX, int aY, int aZ) { 126 | if (aX == airX && aY == airY && aZ == airZ) return null; 127 | 128 | return world.getTileEntity(aX, aY, aZ); 129 | } 130 | 131 | @Override 132 | public boolean canBlockSeeTheSky(int aX, int aY, int aZ) { 133 | return world.canBlockSeeTheSky(aX, aY, aZ); 134 | } 135 | 136 | @Override 137 | protected int func_152379_p() { 138 | return 0; 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/building/providers/BatteryItemProvider.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.building.providers; 2 | 3 | import java.util.Arrays; 4 | 5 | import net.minecraft.init.Items; 6 | import net.minecraft.item.ItemStack; 7 | 8 | import net.minecraftforge.oredict.OreDictionary; 9 | 10 | import com.recursive_pineapple.matter_manipulator.common.building.IItemProvider; 11 | import com.recursive_pineapple.matter_manipulator.common.building.IPseudoInventory; 12 | import com.recursive_pineapple.matter_manipulator.common.utils.BigItemStack; 13 | import com.recursive_pineapple.matter_manipulator.common.utils.ImmutableItemMeta; 14 | import com.recursive_pineapple.matter_manipulator.common.utils.ItemMeta; 15 | 16 | import org.jetbrains.annotations.Nullable; 17 | 18 | public class BatteryItemProvider implements IItemProvider { 19 | 20 | public ImmutableItemMeta battery; 21 | 22 | public BatteryItemProvider() {} 23 | 24 | public static BatteryItemProvider fromStack(ItemStack stack) { 25 | if (stack == null) return null; 26 | 27 | boolean isBattery = false; 28 | 29 | for (int oreId : OreDictionary.getOreIDs(stack)) { 30 | if (OreDictionary.getOreName(oreId).startsWith("battery")) { 31 | isBattery = true; 32 | break; 33 | } 34 | } 35 | 36 | if (!isBattery) return null; 37 | 38 | BatteryItemProvider provider = new BatteryItemProvider(); 39 | 40 | provider.battery = new ItemMeta(stack.getItem(), Items.feather.getDamage(stack)); 41 | 42 | return provider; 43 | } 44 | 45 | @Override 46 | public @Nullable ItemStack getStack(IPseudoInventory inv, boolean consume) { 47 | ItemStack stack = new ItemStack(battery.getItem(), 1, battery.getMeta()); 48 | 49 | if (!consume) return stack; 50 | 51 | var result = inv.tryConsumeItems(Arrays.asList(BigItemStack.create(stack)), IPseudoInventory.CONSUME_FUZZY); 52 | 53 | if (!result.leftBoolean()) return null; 54 | 55 | return result.right().get(0).getItemStack(); 56 | } 57 | 58 | @Override 59 | public IItemProvider clone() { 60 | BatteryItemProvider provider = new BatteryItemProvider(); 61 | 62 | provider.battery = new ItemMeta(battery.getItem(), battery.getMeta()); 63 | 64 | return provider; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/compat/BlockProperty.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.compat; 2 | 3 | import java.util.Objects; 4 | 5 | import net.minecraft.world.World; 6 | 7 | public interface BlockProperty { 8 | 9 | default boolean appliesTo(Object obj) { 10 | return true; 11 | } 12 | 13 | String getName(); 14 | 15 | TValue getValue(World world, int x, int y, int z); 16 | 17 | void setValue(World world, int x, int y, int z, TValue value); 18 | 19 | default void setValueFromText(World world, int x, int y, int z, String text) throws Exception { 20 | setValue(world, x, y, z, parse(text)); 21 | } 22 | 23 | TValue parse(String text) throws Exception; 24 | 25 | default String getValueAsString(World world, int x, int y, int z) { 26 | return stringify(getValue(world, x, y, z)); 27 | } 28 | 29 | default String stringify(TValue value) { 30 | return Objects.toString(value); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/compat/BooleanProperty.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.compat; 2 | 3 | import net.minecraft.block.Block; 4 | import net.minecraft.world.World; 5 | 6 | public interface BooleanProperty extends BlockProperty { 7 | 8 | public default Boolean getValue(World world, int x, int y, int z) { 9 | return getBoolean(world, x, y, z); 10 | } 11 | 12 | public default void setValue(World world, int x, int y, int z, Boolean value) { 13 | setBoolean(world, x, y, z, value.booleanValue()); 14 | } 15 | 16 | @Override 17 | default Boolean parse(String text) throws Exception { 18 | return Boolean.parseBoolean(text); 19 | } 20 | 21 | public boolean getBoolean(World world, int x, int y, int z); 22 | 23 | public void setBoolean(World world, int x, int y, int z, boolean value); 24 | 25 | public static BooleanProperty range(String name, int offset, int size) { 26 | return new BooleanProperty() { 27 | 28 | @Override 29 | public String getName() { 30 | return name; 31 | } 32 | 33 | @Override 34 | public boolean getBoolean(World world, int x, int y, int z) { 35 | int meta = world.getBlockMetadata(x, y, z); 36 | return meta >= offset && meta < offset + size; 37 | } 38 | 39 | @Override 40 | public void setBoolean(World world, int x, int y, int z, boolean value) { 41 | int meta = world.getBlockMetadata(x, y, z); 42 | 43 | if (meta >= offset && meta < offset + size) meta -= offset; 44 | 45 | if (value) meta += offset; 46 | 47 | world.setBlockMetadataWithNotify(x, y, z, meta, 2); 48 | } 49 | }; 50 | } 51 | 52 | public static FlagBooleanProperty flag(String name, int flag) { 53 | return new FlagBooleanProperty(name, flag); 54 | } 55 | 56 | public static class FlagBooleanProperty implements BooleanProperty { 57 | 58 | public final String name; 59 | public final int flag; 60 | 61 | public FlagBooleanProperty(String name, int flag) { 62 | this.name = name; 63 | this.flag = flag; 64 | } 65 | 66 | @Override 67 | public String getName() { 68 | return name; 69 | } 70 | 71 | @Override 72 | public boolean getBoolean(World world, int x, int y, int z) { 73 | int meta = world.getBlockMetadata(x, y, z); 74 | return (meta & flag) == flag; 75 | } 76 | 77 | @Override 78 | public void setBoolean(World world, int x, int y, int z, boolean value) { 79 | int meta = world.getBlockMetadata(x, y, z); 80 | 81 | meta &= ~flag; 82 | if (value) meta |= flag; 83 | 84 | world.setBlockMetadataWithNotify(x, y, z, meta, 2); 85 | } 86 | } 87 | 88 | public static BooleanProperty blocks(String name, Block inactive, Block active) { 89 | return new BooleanProperty() { 90 | 91 | @Override 92 | public String getName() { 93 | return name; 94 | } 95 | 96 | @Override 97 | public boolean getBoolean(World world, int x, int y, int z) { 98 | return world.getBlock(x, y, z) == active; 99 | } 100 | 101 | @Override 102 | public void setBoolean(World world, int x, int y, int z, boolean value) { 103 | world.setBlock(x, y, z, value ? active : inactive, world.getBlockMetadata(x, y, z), 2); 104 | } 105 | }; 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/compat/DirectionBlockProperty.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.compat; 2 | 3 | import static net.minecraftforge.common.util.ForgeDirection.*; 4 | 5 | import net.minecraft.world.World; 6 | 7 | import net.minecraftforge.common.util.ForgeDirection; 8 | 9 | import com.recursive_pineapple.matter_manipulator.common.utils.MMUtils; 10 | 11 | public interface DirectionBlockProperty extends BlockProperty { 12 | 13 | default DirectionBlockProperty setName(String name) { 14 | return this; 15 | } 16 | 17 | @Override 18 | default ForgeDirection parse(String text) throws Exception { 19 | return ForgeDirection.valueOf(text.toUpperCase()); 20 | } 21 | 22 | @Override 23 | default String stringify(ForgeDirection value) { 24 | return value.name().toLowerCase(); 25 | } 26 | 27 | abstract class AbstractDirectionBlockProperty implements DirectionBlockProperty { 28 | 29 | private String name; 30 | 31 | public AbstractDirectionBlockProperty(String name) { 32 | this.name = name; 33 | } 34 | 35 | @Override 36 | public DirectionBlockProperty setName(String name) { 37 | this.name = name; 38 | return this; 39 | } 40 | 41 | @Override 42 | public String getName() { 43 | return name; 44 | } 45 | } 46 | 47 | static DirectionBlockProperty facing() { 48 | return new AbstractDirectionBlockProperty("facing") { 49 | 50 | @Override 51 | public ForgeDirection getValue(World world, int x, int y, int z) { 52 | ForgeDirection dir = MMUtils.getIndexSafe(ForgeDirection.VALID_DIRECTIONS, world.getBlockMetadata(x, y, z)); 53 | 54 | return dir == null ? UNKNOWN : dir; 55 | } 56 | 57 | @Override 58 | public void setValue(World world, int x, int y, int z, ForgeDirection value) { 59 | if (value == UNKNOWN) return; 60 | 61 | world.setBlockMetadataWithNotify(x, y, z, value.ordinal(), 2); 62 | } 63 | }; 64 | } 65 | 66 | public static DirectionBlockProperty facingVanilla(int mask) { 67 | return facing( 68 | mask, 69 | dir -> switch (dir) { 70 | case NORTH -> 3; 71 | case SOUTH -> 4; 72 | case WEST -> 1; 73 | case EAST -> 2; 74 | case UP -> 0; 75 | case DOWN -> 5; 76 | default -> 3; 77 | }, 78 | meta -> switch (meta) { 79 | case 3 -> NORTH; 80 | case 4 -> SOUTH; 81 | case 1 -> WEST; 82 | case 2 -> EAST; 83 | case 0 -> UP; 84 | case 5 -> DOWN; 85 | default -> NORTH; 86 | } 87 | ); 88 | } 89 | 90 | public static interface D2M { 91 | 92 | int getMeta(ForgeDirection dir); 93 | } 94 | 95 | public static interface M2D { 96 | 97 | ForgeDirection getDir(int meta); 98 | } 99 | 100 | public static DirectionBlockProperty facing(int mask, D2M toMeta, M2D toDir) { 101 | return new AbstractDirectionBlockProperty("facing") { 102 | 103 | @Override 104 | public ForgeDirection getValue(World world, int x, int y, int z) { 105 | return toDir.getDir(world.getBlockMetadata(x, y, z) & mask); 106 | } 107 | 108 | @Override 109 | public void setValue(World world, int x, int y, int z, ForgeDirection value) { 110 | int meta = 0; 111 | if (mask != -1) { 112 | meta = world.getBlockMetadata(x, y, z) & ~mask; 113 | } 114 | 115 | world.setBlockMetadataWithNotify(x, y, z, toMeta.getMeta(value) | meta, 2); 116 | } 117 | }; 118 | } 119 | 120 | public static interface D2M2 { 121 | 122 | int getMeta(ForgeDirection dir, int existing); 123 | } 124 | 125 | public static DirectionBlockProperty facing(D2M2 toMeta, M2D toDir) { 126 | return new AbstractDirectionBlockProperty("facing") { 127 | 128 | @Override 129 | public ForgeDirection getValue(World world, int x, int y, int z) { 130 | return toDir.getDir(world.getBlockMetadata(x, y, z)); 131 | } 132 | 133 | @Override 134 | public void setValue(World world, int x, int y, int z, ForgeDirection value) { 135 | int meta = world.getBlockMetadata(x, y, z); 136 | 137 | world.setBlockMetadataWithNotify(x, y, z, toMeta.getMeta(value, meta), 2); 138 | } 139 | }; 140 | } 141 | 142 | public static DirectionBlockProperty facing(int mask, int north, int south, int west, int east, int up, int down) { 143 | return facing( 144 | mask, 145 | dir -> switch (dir) { 146 | case NORTH -> north == -1 ? 0 : north; 147 | case SOUTH -> south == -1 ? 0 : south; 148 | case WEST -> west == -1 ? 0 : west; 149 | case EAST -> east == -1 ? 0 : east; 150 | case UP -> up == -1 ? 0 : up; 151 | case DOWN -> down == -1 ? 0 : down; 152 | case UNKNOWN -> 0; 153 | }, 154 | meta -> { 155 | if (meta == north) return NORTH; 156 | if (meta == south) return SOUTH; 157 | if (meta == west) return WEST; 158 | if (meta == east) return EAST; 159 | if (meta == up) return UP; 160 | if (meta == down) return DOWN; 161 | 162 | return UNKNOWN; 163 | } 164 | ); 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/compat/ExtendedFacingBlockProperty.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.compat; 2 | 3 | import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; 4 | 5 | public interface ExtendedFacingBlockProperty extends BlockProperty { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/compat/FloatProperty.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.compat; 2 | 3 | import net.minecraft.world.World; 4 | 5 | public interface FloatProperty extends BlockProperty { 6 | 7 | default Float getValue(World world, int x, int y, int z) { 8 | return getFloat(world, x, y, z); 9 | } 10 | 11 | default void setValue(World world, int x, int y, int z, Float value) { 12 | setFloat(world, x, y, z, value); 13 | } 14 | 15 | @Override 16 | default Float parse(String text) throws Exception { 17 | return Float.parseFloat(text); 18 | } 19 | 20 | float getFloat(World world, int x, int y, int z); 21 | 22 | void setFloat(World world, int x, int y, int z, float value); 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/compat/IntegerProperty.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.compat; 2 | 3 | import java.util.List; 4 | 5 | import net.minecraft.world.World; 6 | 7 | import com.recursive_pineapple.matter_manipulator.common.utils.MMUtils; 8 | 9 | public interface IntegerProperty extends BlockProperty { 10 | 11 | default Integer getValue(World world, int x, int y, int z) { 12 | return getInt(world, x, y, z); 13 | } 14 | 15 | default void setValue(World world, int x, int y, int z, Integer value) { 16 | setInt(world, x, y, z, value); 17 | } 18 | 19 | @Override 20 | default Integer parse(String text) { 21 | return Integer.parseInt(text); 22 | } 23 | 24 | int getInt(World world, int x, int y, int z); 25 | 26 | void setInt(World world, int x, int y, int z, int value); 27 | 28 | default BlockProperty map(List values) { 29 | return new BlockProperty<>() { 30 | 31 | @Override 32 | public String getName() { 33 | return IntegerProperty.this.getName(); 34 | } 35 | 36 | @Override 37 | public String getValue(World world, int x, int y, int z) { 38 | return MMUtils.getIndexSafe(values, IntegerProperty.this.getInt(world, x, y, z)); 39 | } 40 | 41 | @Override 42 | public void setValue(World world, int x, int y, int z, String value) { 43 | setInt(world, x, y, z, values.indexOf(value)); 44 | } 45 | 46 | @Override 47 | public String parse(String text) { 48 | return text; 49 | } 50 | }; 51 | } 52 | 53 | static IntegerProperty meta(String name, int mask, int shift) { 54 | return new IntegerProperty() { 55 | 56 | @Override 57 | public String getName() { 58 | return name; 59 | } 60 | 61 | @Override 62 | public int getInt(World world, int x, int y, int z) { 63 | return (world.getBlockMetadata(x, y, z) & mask) >> shift; 64 | } 65 | 66 | @Override 67 | public void setInt(World world, int x, int y, int z, int value) { 68 | int meta = world.getBlockMetadata(x, y, z) & ~mask; 69 | 70 | meta |= (value << shift) & mask; 71 | 72 | world.setBlockMetadataWithNotify(x, y, z, meta, 2); 73 | } 74 | }; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/compat/IntrinsicProperty.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.compat; 2 | 3 | import java.util.List; 4 | 5 | import net.minecraft.item.ItemStack; 6 | import net.minecraft.world.IBlockAccess; 7 | 8 | import com.google.gson.JsonElement; 9 | 10 | /** A property which is kept when a block is destroyed. */ 11 | public interface IntrinsicProperty { 12 | 13 | String getName(); 14 | 15 | boolean hasValue(ItemStack stack); 16 | 17 | boolean hasValue(IBlockAccess world, int x, int y, int z); 18 | 19 | JsonElement getValue(ItemStack stack); 20 | 21 | JsonElement getValue(IBlockAccess world, int x, int y, int z); 22 | 23 | void setValue(ItemStack stack, JsonElement value); 24 | 25 | void setValue(IBlockAccess world, int x, int y, int z, JsonElement value); 26 | 27 | default void getItemDetails(List details, JsonElement value) {} 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/compat/MetaBlockProperty.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.compat; 2 | 3 | import net.minecraft.world.World; 4 | 5 | public interface MetaBlockProperty extends BlockProperty { 6 | 7 | default boolean needsExisting() { 8 | return true; 9 | } 10 | 11 | int getMeta(T value, int existing); 12 | 13 | T getValue(int meta); 14 | 15 | default T getValue(World world, int x, int y, int z) { 16 | return getValue(world.getBlockMetadata(x, y, z)); 17 | } 18 | 19 | default void setValue(World world, int x, int y, int z, T value) { 20 | boolean needsExisting = needsExisting(); 21 | 22 | int existing = needsExisting ? world.getBlockMetadata(x, y, z) : 0; 23 | 24 | int meta = getMeta(value, existing); 25 | 26 | if (!needsExisting || existing != meta) { 27 | world.setBlockMetadataWithNotify(x, y, z, meta, 2); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/compat/Orientation.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.compat; 2 | 3 | import static net.minecraftforge.common.util.ForgeDirection.*; 4 | 5 | import java.util.EnumMap; 6 | 7 | import net.minecraftforge.common.util.ForgeDirection; 8 | 9 | public enum Orientation { 10 | 11 | NONE(UNKNOWN, UNKNOWN), 12 | DOWN_DOWN(DOWN, DOWN), 13 | UP_DOWN(UP, DOWN), 14 | NORTH_DOWN(NORTH, DOWN), 15 | SOUTH_DOWN(SOUTH, DOWN), 16 | WEST_DOWN(WEST, DOWN), 17 | EAST_DOWN(EAST, DOWN), 18 | DOWN_UP(DOWN, UP), 19 | UP_UP(UP, UP), 20 | NORTH_UP(NORTH, UP), 21 | SOUTH_UP(SOUTH, UP), 22 | WEST_UP(WEST, UP), 23 | EAST_UP(EAST, UP), 24 | DOWN_NORTH(DOWN, NORTH), 25 | UP_NORTH(UP, NORTH), 26 | NORTH_NORTH(NORTH, NORTH), 27 | SOUTH_NORTH(SOUTH, NORTH), 28 | WEST_NORTH(WEST, NORTH), 29 | EAST_NORTH(EAST, NORTH), 30 | DOWN_SOUTH(DOWN, SOUTH), 31 | UP_SOUTH(UP, SOUTH), 32 | NORTH_SOUTH(NORTH, SOUTH), 33 | SOUTH_SOUTH(SOUTH, SOUTH), 34 | WEST_SOUTH(WEST, SOUTH), 35 | EAST_SOUTH(EAST, SOUTH), 36 | DOWN_WEST(DOWN, WEST), 37 | UP_WEST(UP, WEST), 38 | NORTH_WEST(NORTH, WEST), 39 | SOUTH_WEST(SOUTH, WEST), 40 | WEST_WEST(WEST, WEST), 41 | EAST_WEST(EAST, WEST), 42 | DOWN_EAST(DOWN, EAST), 43 | UP_EAST(UP, EAST), 44 | NORTH_EAST(NORTH, EAST), 45 | SOUTH_EAST(SOUTH, EAST), 46 | WEST_EAST(WEST, EAST), 47 | EAST_EAST(EAST, EAST); 48 | 49 | public final ForgeDirection a, b; 50 | 51 | private Orientation(ForgeDirection a, ForgeDirection b) { 52 | this.a = a; 53 | this.b = b; 54 | } 55 | 56 | private static final EnumMap> ORIENTATIONS = new EnumMap<>(ForgeDirection.class); 57 | 58 | static { 59 | for (Orientation o : values()) { 60 | ORIENTATIONS.computeIfAbsent(o.a, x -> new EnumMap<>(ForgeDirection.class)).put(o.b, o); 61 | } 62 | } 63 | 64 | public static Orientation getOrientation(ForgeDirection a, ForgeDirection b) { 65 | if (a == null) a = ForgeDirection.UNKNOWN; 66 | if (b == null) b = ForgeDirection.UNKNOWN; 67 | 68 | return ORIENTATIONS.get(a).get(b); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/compat/OrientationBlockProperty.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.compat; 2 | 3 | import net.minecraft.world.World; 4 | 5 | public interface OrientationBlockProperty extends BlockProperty { 6 | 7 | @Override 8 | default Orientation parse(String text) throws Exception { 9 | for (Orientation o : Orientation.values()) { 10 | if (o.name().equalsIgnoreCase(text)) { return o; } 11 | } 12 | 13 | throw new Exception("illegal orientation: '" + text + "'"); 14 | } 15 | 16 | @Override 17 | default String stringify(Orientation value) { 18 | return value.name().toLowerCase(); 19 | } 20 | 21 | public static interface O2M { 22 | 23 | int getMeta(Orientation dir); 24 | } 25 | 26 | public static interface M2O { 27 | 28 | Orientation getDir(int meta); 29 | } 30 | 31 | public static OrientationBlockProperty orientation(int mask, O2M o2m, M2O m2o) { 32 | return new OrientationBlockProperty() { 33 | 34 | @Override 35 | public String getName() { 36 | return "orientation"; 37 | } 38 | 39 | @Override 40 | public Orientation getValue(World world, int x, int y, int z) { 41 | return m2o.getDir(world.getBlockMetadata(x, y, z) & mask); 42 | } 43 | 44 | @Override 45 | public void setValue(World world, int x, int y, int z, Orientation value) { 46 | int meta = 0; 47 | if (mask != -1) { 48 | meta = world.getBlockMetadata(x, y, z) & ~mask; 49 | } 50 | 51 | world.setBlockMetadataWithNotify(x, y, z, o2m.getMeta(value) | meta, 2); 52 | } 53 | }; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/data/WeightedSpecList.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.data; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Objects; 5 | import java.util.Random; 6 | 7 | import com.recursive_pineapple.matter_manipulator.common.building.BlockSpec; 8 | import com.recursive_pineapple.matter_manipulator.common.building.ImmutableBlockSpec; 9 | 10 | import it.unimi.dsi.fastutil.objects.ObjectIntMutablePair; 11 | 12 | public class WeightedSpecList { 13 | 14 | public ArrayList> specs = new ArrayList<>(); 15 | 16 | public WeightedSpecList(BlockSpec... values) { 17 | for (BlockSpec spec : values) { 18 | add(spec); 19 | } 20 | } 21 | 22 | public void add(BlockSpec spec) { 23 | for (var p : specs) { 24 | if (Objects.equals(p.first(), spec)) { 25 | p.right(p.rightInt() + 1); 26 | return; 27 | } 28 | } 29 | 30 | specs.add(ObjectIntMutablePair.of(spec, 1)); 31 | } 32 | 33 | public ImmutableBlockSpec get(Random rng) { 34 | if (specs.isEmpty()) return BlockSpec.AIR; 35 | 36 | int sum = 0; 37 | 38 | for (var p : specs) 39 | sum += p.rightInt(); 40 | 41 | if (sum == 0) return BlockSpec.AIR; 42 | 43 | int selector = rng.nextInt(sum); 44 | 45 | for (var p : specs) { 46 | if (selector < p.rightInt()) return p.left(); 47 | 48 | selector -= p.rightInt(); 49 | } 50 | 51 | return BlockSpec.AIR; 52 | } 53 | 54 | public boolean contains(BlockSpec spec) { 55 | for (var p : specs) { 56 | if (Objects.equals(p.first(), spec)) { return true; } 57 | } 58 | 59 | return false; 60 | } 61 | 62 | @Override 63 | public String toString() { 64 | StringBuilder sb = new StringBuilder(); 65 | 66 | for (var p : specs) { 67 | if (sb.length() > 0) sb.append(", "); 68 | 69 | sb.append(p.left().getDisplayName()); 70 | 71 | if (p.rightInt() > 1) sb.append(" x ").append(p.rightInt()); 72 | } 73 | 74 | return sb.toString(); 75 | } 76 | 77 | @Override 78 | public int hashCode() { 79 | final int prime = 31; 80 | int result = 1; 81 | result = prime * result + ((specs == null) ? 0 : specs.hashCode()); 82 | return result; 83 | } 84 | 85 | @Override 86 | public boolean equals(Object obj) { 87 | if (this == obj) return true; 88 | if (obj == null) return false; 89 | if (getClass() != obj.getClass()) return false; 90 | WeightedSpecList other = (WeightedSpecList) obj; 91 | if (specs == null) { 92 | if (other.specs != null) return false; 93 | } else if (!specs.equals(other.specs)) return false; 94 | return true; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/entities/EntityID.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.entities; 2 | 3 | public enum EntityID { 4 | 5 | LargeItem(0); 6 | 7 | public final int ID; 8 | 9 | private EntityID(int id) { 10 | if (id < 0 || id > 255) throw new IllegalArgumentException("id"); 11 | ID = id; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/items/IDMetaItem.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.items; 2 | 3 | public enum IDMetaItem { 4 | 5 | // Please pretty please, add your entries while conserving the order 6 | Hologram(0, MMItemList.Hologram), 7 | PowerCore0(1, MMItemList.PowerCore0), 8 | ComputerCore0(2, MMItemList.ComputerCore0), 9 | TeleporterCore0(3, MMItemList.TeleporterCore0), 10 | Frame0(4, MMItemList.Frame0), 11 | Lens0(5, MMItemList.Lens0), 12 | PowerCore1(6, MMItemList.PowerCore1), 13 | ComputerCore1(7, MMItemList.ComputerCore1), 14 | TeleporterCore1(8, MMItemList.TeleporterCore1), 15 | Frame1(9, MMItemList.Frame1), 16 | Lens1(10, MMItemList.Lens1), 17 | PowerCore2(11, MMItemList.PowerCore2), 18 | ComputerCore2(12, MMItemList.ComputerCore2), 19 | TeleporterCore2(13, MMItemList.TeleporterCore2), 20 | Frame2(14, MMItemList.Frame2), 21 | Lens2(15, MMItemList.Lens2), 22 | PowerCore3(16, MMItemList.PowerCore3), 23 | ComputerCore3(17, MMItemList.ComputerCore3), 24 | TeleporterCore3(18, MMItemList.TeleporterCore3), 25 | Frame3(19, MMItemList.Frame3), 26 | Lens3(20, MMItemList.Lens3), 27 | AEDownlink(21, MMItemList.AEDownlink), 28 | QuantumDownlink(22, MMItemList.QuantumDownlink), 29 | UpgradeBlank(23, MMItemList.UpgradeBlank), 30 | UpgradePowerP2P(24, MMItemList.UpgradePowerP2P), 31 | UpgradePrototypeMining(25, MMItemList.UpgradePrototypeMining), 32 | UpgradeSpeed(26, MMItemList.UpgradeSpeed), 33 | UpgradePowerEff(27, MMItemList.UpgradePowerEff), 34 | // 35 | ; 36 | 37 | public final int ID; 38 | public final MMItemList container; 39 | 40 | IDMetaItem(int ID, MMItemList container) { 41 | this.ID = ID; 42 | this.container = container; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/items/MMItemList.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.items; 2 | 3 | import net.minecraft.item.Item; 4 | import net.minecraft.item.ItemStack; 5 | 6 | public enum MMItemList { 7 | 8 | MK0, 9 | MK1, 10 | MK2, 11 | MK3, 12 | 13 | Hologram, 14 | PowerCore0, 15 | ComputerCore0, 16 | TeleporterCore0, 17 | Frame0, 18 | Lens0, 19 | 20 | PowerCore1, 21 | ComputerCore1, 22 | TeleporterCore1, 23 | Frame1, 24 | Lens1, 25 | 26 | PowerCore2, 27 | ComputerCore2, 28 | TeleporterCore2, 29 | Frame2, 30 | Lens2, 31 | 32 | PowerCore3, 33 | ComputerCore3, 34 | TeleporterCore3, 35 | Frame3, 36 | Lens3, 37 | 38 | AEDownlink, 39 | QuantumDownlink, 40 | 41 | UplinkController, 42 | UplinkHatch, 43 | 44 | UpgradeBlank, 45 | UpgradePowerP2P, 46 | UpgradePrototypeMining, 47 | UpgradeSpeed, 48 | UpgradePowerEff, 49 | 50 | ; 51 | 52 | public ItemStack stack; 53 | 54 | public void set(ItemStack stack) { 55 | this.stack = stack; 56 | } 57 | 58 | public void set(Item item) { 59 | stack = new ItemStack(item, 1); 60 | } 61 | 62 | public void set(Item item, int meta) { 63 | stack = new ItemStack(item, 1, meta); 64 | } 65 | 66 | public ItemStack get() { 67 | return stack.copy(); 68 | } 69 | 70 | public ItemStack get(int amount) { 71 | ItemStack copy = stack.copy(); 72 | copy.stackSize = amount; 73 | return copy; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/items/MMItems.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.items; 2 | 3 | import gregtech.api.enums.MetaTileEntityIDs; 4 | 5 | import com.recursive_pineapple.matter_manipulator.asm.Optional; 6 | import com.recursive_pineapple.matter_manipulator.common.items.manipulator.ItemMatterManipulator; 7 | import com.recursive_pineapple.matter_manipulator.common.items.manipulator.ItemMatterManipulator.ManipulatorTier; 8 | import com.recursive_pineapple.matter_manipulator.common.uplink.MTEMMUplink; 9 | import com.recursive_pineapple.matter_manipulator.common.uplink.MTEMMUplinkMEHatch; 10 | import com.recursive_pineapple.matter_manipulator.common.utils.Mods.Names; 11 | 12 | public class MMItems { 13 | 14 | private MMItems() {} 15 | 16 | public static MetaItem META_ITEM; 17 | 18 | public static void registerItems() { 19 | MMItemList.MK0.set(new ItemMatterManipulator(ManipulatorTier.Tier0)); 20 | MMItemList.MK1.set(new ItemMatterManipulator(ManipulatorTier.Tier1)); 21 | MMItemList.MK2.set(new ItemMatterManipulator(ManipulatorTier.Tier2)); 22 | MMItemList.MK3.set(new ItemMatterManipulator(ManipulatorTier.Tier3)); 23 | 24 | META_ITEM = new MetaItem("metaitem"); 25 | } 26 | 27 | @Optional({ 28 | Names.GREG_TECH, Names.APPLIED_ENERGISTICS2 29 | }) 30 | public static void registerMultis() { 31 | MMItemList.UplinkController.set( 32 | new MTEMMUplink( 33 | MetaTileEntityIDs.MATTER_MANIPULATOR_UPLINK.ID, 34 | "multimachine.mmuplink", 35 | "Matter Manipulator Quantum Uplink" 36 | ).getStackForm(1) 37 | ); 38 | MMItemList.UplinkHatch.set( 39 | new MTEMMUplinkMEHatch( 40 | MetaTileEntityIDs.HATCH_MATTER_MANIPULATOR_UPLINK_ME.ID, 41 | "hatch.mmuplink.me", 42 | "Quantum Uplink ME Connector Hatch" 43 | ).getStackForm(1) 44 | ); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/items/MMUpgrades.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.items; 2 | 3 | import net.minecraft.item.ItemStack; 4 | 5 | import com.recursive_pineapple.matter_manipulator.common.items.manipulator.ItemMatterManipulator; 6 | 7 | import it.unimi.dsi.fastutil.ints.Int2ObjectMap; 8 | import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; 9 | 10 | public enum MMUpgrades { 11 | 12 | PowerP2P(IDMetaItem.UpgradePowerP2P, 0, 0), 13 | Mining(IDMetaItem.UpgradePrototypeMining, 1, ItemMatterManipulator.ALLOW_REMOVING), 14 | Speed(IDMetaItem.UpgradeSpeed, 2, 0), 15 | PowerEff(IDMetaItem.UpgradePowerEff, 3, 0), 16 | // 17 | ; 18 | 19 | public static final Int2ObjectMap UPGRADES_BY_META = new Int2ObjectOpenHashMap<>(); 20 | public static final Int2ObjectMap UPGRADES_BY_BIT = new Int2ObjectOpenHashMap<>(); 21 | 22 | static { 23 | for (MMUpgrades upgrade : MMUpgrades.values()) { 24 | UPGRADES_BY_META.put(upgrade.id, upgrade); 25 | UPGRADES_BY_BIT.put(upgrade.bit, upgrade); 26 | } 27 | } 28 | 29 | public final int id; 30 | public final int bit; 31 | public final int providesCaps; 32 | 33 | MMUpgrades(IDMetaItem id, int bit, int providesCaps) { 34 | this.id = id.ID; 35 | this.bit = bit; 36 | this.providesCaps = providesCaps; 37 | } 38 | 39 | public ItemStack getStack() { 40 | return new ItemStack(MMItems.META_ITEM, 1, id); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/items/RecipeInstallUpgrade.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.items; 2 | 3 | import net.minecraft.inventory.InventoryCrafting; 4 | import net.minecraft.item.ItemStack; 5 | import net.minecraft.item.crafting.CraftingManager; 6 | import net.minecraft.item.crafting.IRecipe; 7 | import net.minecraft.world.World; 8 | 9 | import com.github.bsideup.jabel.Desugar; 10 | import com.recursive_pineapple.matter_manipulator.common.items.manipulator.ItemMatterManipulator; 11 | import com.recursive_pineapple.matter_manipulator.common.items.manipulator.MMState; 12 | 13 | public class RecipeInstallUpgrade implements IRecipe { 14 | 15 | public static final RecipeInstallUpgrade INSTANCE = new RecipeInstallUpgrade(); 16 | 17 | public static void register() { 18 | CraftingManager.getInstance().getRecipeList().add(INSTANCE); 19 | } 20 | 21 | @Override 22 | public boolean matches(InventoryCrafting inv, World world) { 23 | if (getItemCount(inv) > 2) return false; 24 | 25 | var manipulator = findManipulator(inv); 26 | 27 | if (manipulator == null) return false; 28 | 29 | var upgrade = findUpgrade(inv, manipulator); 30 | 31 | return upgrade != null; 32 | } 33 | 34 | @Override 35 | public ItemStack getCraftingResult(InventoryCrafting inv) { 36 | if (getItemCount(inv) > 2) return null; 37 | 38 | var manipulator = findManipulator(inv); 39 | 40 | if (manipulator == null) return null; 41 | 42 | var upgrade = findUpgrade(inv, manipulator); 43 | 44 | if (upgrade == null) return null; 45 | 46 | ItemStack stack = manipulator.stack.copy(); 47 | 48 | manipulator.state.installUpgrade(upgrade.upgrade); 49 | ItemMatterManipulator.setState(stack, manipulator.state); 50 | 51 | return stack; 52 | } 53 | 54 | @Override 55 | public int getRecipeSize() { 56 | return 2; 57 | } 58 | 59 | @Override 60 | public ItemStack getRecipeOutput() { 61 | return null; 62 | } 63 | 64 | private static int getItemCount(InventoryCrafting inv) { 65 | int size = inv.getSizeInventory(); 66 | int count = 0; 67 | 68 | for (int i = 0; i < size; i++) { 69 | ItemStack stack = inv.getStackInSlot(i); 70 | 71 | if (stack == null || stack.getItem() == null) continue; 72 | 73 | count++; 74 | } 75 | 76 | return count; 77 | } 78 | 79 | @Desugar 80 | private record ManipulatorInfo(ItemStack stack, int slot, MMState state, ItemMatterManipulator.ManipulatorTier tier) {} 81 | 82 | private static ManipulatorInfo findManipulator(InventoryCrafting inv) { 83 | int size = inv.getSizeInventory(); 84 | 85 | for (int i = 0; i < size; i++) { 86 | ItemStack stack = inv.getStackInSlot(i); 87 | 88 | if (stack == null || stack.getItem() == null) continue; 89 | 90 | if (!(stack.getItem() instanceof ItemMatterManipulator manipulator)) continue; 91 | 92 | return new ManipulatorInfo(stack, i, ItemMatterManipulator.getState(stack), manipulator.tier); 93 | } 94 | 95 | return null; 96 | } 97 | 98 | @Desugar 99 | private record UpgradeInfo(ItemStack stack, int slot, MMUpgrades upgrade) {} 100 | 101 | private static UpgradeInfo findUpgrade(InventoryCrafting inv, ManipulatorInfo manipulator) { 102 | int size = inv.getSizeInventory(); 103 | 104 | for (int i = 0; i < size; i++) { 105 | ItemStack stack = inv.getStackInSlot(i); 106 | 107 | if (stack == null || stack.getItem() == null) continue; 108 | 109 | if (!(stack.getItem() instanceof MetaItem)) continue; 110 | 111 | MMUpgrades upgrade = MMUpgrades.UPGRADES_BY_META.get(stack.getItemDamage()); 112 | 113 | if (upgrade == null) continue; 114 | if (!manipulator.state.couldAcceptUpgrade(manipulator.tier, upgrade)) continue; 115 | 116 | return new UpgradeInfo(stack, i, upgrade); 117 | } 118 | 119 | return null; 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/items/manipulator/Location.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.items.manipulator; 2 | 3 | import javax.annotation.Nonnull; 4 | 5 | import net.minecraft.client.Minecraft; 6 | import net.minecraft.world.World; 7 | 8 | import net.minecraftforge.common.DimensionManager; 9 | import net.minecraftforge.common.util.ForgeDirection; 10 | 11 | import cpw.mods.fml.common.FMLCommonHandler; 12 | import cpw.mods.fml.relauncher.Side; 13 | import cpw.mods.fml.relauncher.SideOnly; 14 | 15 | import org.joml.Vector3i; 16 | 17 | /** 18 | * Represents a location in a world. 19 | * Can probably be improved, but it's not a big problem yet since these aren't meant to be kept around for very 20 | * long. 21 | */ 22 | public class Location { 23 | 24 | public int worldId; 25 | public int x, y, z; 26 | 27 | public Location() { 28 | 29 | } 30 | 31 | public Location(int worldId, int x, int y, int z) { 32 | this.worldId = worldId; 33 | this.x = x; 34 | this.y = y; 35 | this.z = z; 36 | } 37 | 38 | public Location(@Nonnull World world, int x, int y, int z) { 39 | this(world.provider.dimensionId, x, y, z); 40 | } 41 | 42 | public Location(@Nonnull World world, Vector3i v) { 43 | this(world, v.x, v.y, v.z); 44 | } 45 | 46 | @Override 47 | public String toString() { 48 | return String.format("X=%,d Y=%,d Z=%,d", x, y, z); 49 | } 50 | 51 | public Vector3i toVec() { 52 | return new Vector3i(x, y, z); 53 | } 54 | 55 | public boolean isInWorld(@Nonnull World world) { 56 | return world.provider.dimensionId == worldId; 57 | } 58 | 59 | public int distanceTo2(Location other) { 60 | int dx = x - other.x; 61 | int dy = y - other.y; 62 | int dz = z - other.z; 63 | return dx * dx + dy * dy + dz * dz; 64 | } 65 | 66 | public double distanceTo(Location other) { 67 | return Math.sqrt(distanceTo2(other)); 68 | } 69 | 70 | public World getWorld() { 71 | if (FMLCommonHandler.instance().getEffectiveSide().isClient()) { 72 | return getWorldClient(); 73 | } else { 74 | return DimensionManager.getWorld(this.worldId); 75 | } 76 | } 77 | 78 | @SideOnly(Side.CLIENT) 79 | private World getWorldClient() { 80 | World world = Minecraft.getMinecraft().theWorld; 81 | 82 | return world.provider.dimensionId == this.worldId ? world : null; 83 | } 84 | 85 | public Location offset(ForgeDirection dir) { 86 | this.x += dir.offsetX; 87 | this.y += dir.offsetY; 88 | this.z += dir.offsetZ; 89 | return this; 90 | } 91 | 92 | public Location offset(int dx, int dy, int dz) { 93 | this.x += dx; 94 | this.y += dy; 95 | this.z += dz; 96 | return this; 97 | } 98 | 99 | public Location clone() { 100 | return new Location(worldId, x, y, z); 101 | } 102 | 103 | /** 104 | * Checks if two locations are compatible (in the same world). 105 | */ 106 | public static boolean areCompatible(Location a, Location b) { 107 | if (a == null || b == null) return false; 108 | 109 | if (a.worldId != b.worldId) return false; 110 | 111 | return true; 112 | } 113 | 114 | /** 115 | * Checks if three locations are compatible (in the same world). 116 | */ 117 | public static boolean areCompatible(Location a, Location b, Location c) { 118 | if (a == null || b == null || c == null) return false; 119 | 120 | if (a.worldId != b.worldId) return false; 121 | if (a.worldId != c.worldId) return false; 122 | 123 | return true; 124 | } 125 | 126 | @Override 127 | public int hashCode() { 128 | final int prime = 31; 129 | int result = 1; 130 | result = prime * result + worldId; 131 | result = prime * result + x; 132 | result = prime * result + y; 133 | result = prime * result + z; 134 | return result; 135 | } 136 | 137 | @Override 138 | public boolean equals(Object obj) { 139 | if (this == obj) return true; 140 | if (obj == null) return false; 141 | if (getClass() != obj.getClass()) return false; 142 | Location other = (Location) obj; 143 | if (worldId != other.worldId) return false; 144 | if (x != other.x) return false; 145 | if (y != other.y) return false; 146 | if (z != other.z) return false; 147 | return true; 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/items/manipulator/MMKeyInputs.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.items.manipulator; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import net.minecraft.client.settings.KeyBinding; 5 | import net.minecraft.entity.player.EntityPlayer; 6 | import net.minecraft.item.ItemStack; 7 | 8 | import net.minecraftforge.client.event.MouseEvent; 9 | 10 | import cpw.mods.fml.client.registry.ClientRegistry; 11 | import cpw.mods.fml.common.eventhandler.SubscribeEvent; 12 | import cpw.mods.fml.common.gameevent.InputEvent.KeyInputEvent; 13 | 14 | import com.gtnewhorizon.gtnhlib.eventbus.EventBusSubscriber; 15 | import com.recursive_pineapple.matter_manipulator.GlobalMMConfig.InteractionConfig; 16 | import com.recursive_pineapple.matter_manipulator.common.items.manipulator.MMState.PlaceMode; 17 | import com.recursive_pineapple.matter_manipulator.common.networking.Messages; 18 | 19 | import org.lwjgl.input.Keyboard; 20 | 21 | @EventBusSubscriber 22 | public class MMKeyInputs { 23 | 24 | public static final KeyBinding CONTROL = new KeyBinding("key.mm-ctrl", Keyboard.KEY_LCONTROL, "key.mm"); 25 | public static final KeyBinding CUT = new KeyBinding("key.mm-cut", Keyboard.KEY_X, "key.mm"); 26 | public static final KeyBinding COPY = new KeyBinding("key.mm-copy", Keyboard.KEY_C, "key.mm"); 27 | public static final KeyBinding PASTE = new KeyBinding("key.mm-paste", Keyboard.KEY_V, "key.mm"); 28 | public static final KeyBinding RESET = new KeyBinding("key.mm-reset", Keyboard.KEY_Z, "key.mm"); 29 | 30 | public static void init() { 31 | ClientRegistry.registerKeyBinding(CONTROL); 32 | ClientRegistry.registerKeyBinding(CUT); 33 | ClientRegistry.registerKeyBinding(COPY); 34 | ClientRegistry.registerKeyBinding(PASTE); 35 | ClientRegistry.registerKeyBinding(RESET); 36 | } 37 | 38 | @SubscribeEvent 39 | public static void onKeyPressed(KeyInputEvent event) { 40 | EntityPlayer player = Minecraft.getMinecraft().thePlayer; 41 | ItemStack held = player.getHeldItem(); 42 | 43 | if (held == null || !(held.getItem() instanceof ItemMatterManipulator)) return; 44 | 45 | MMState state = ItemMatterManipulator.getState(held); 46 | 47 | if (CONTROL.getKeyCode() != 0 && !CONTROL.getIsKeyPressed()) return; 48 | 49 | if (CUT.isPressed()) { 50 | if (state.config.placeMode != PlaceMode.MOVING) { 51 | Messages.SetPlaceMode.sendToServer(PlaceMode.MOVING); 52 | } 53 | 54 | if (InteractionConfig.pasteAutoClear) { 55 | Messages.ClearCoords.sendToServer(); 56 | 57 | if (InteractionConfig.resetTransform) { 58 | Messages.ClearTransform.sendToServer(); 59 | Messages.ResetArray.sendToServer(); 60 | } 61 | } 62 | 63 | Messages.MarkCut.sendToServer(); 64 | 65 | return; 66 | } 67 | 68 | if (COPY.isPressed()) { 69 | if (state.config.placeMode != PlaceMode.COPYING) { 70 | Messages.SetPlaceMode.sendToServer(PlaceMode.COPYING); 71 | } 72 | 73 | if (InteractionConfig.pasteAutoClear) { 74 | Messages.ClearCoords.sendToServer(); 75 | 76 | if (InteractionConfig.resetTransform) { 77 | Messages.ClearTransform.sendToServer(); 78 | Messages.ResetArray.sendToServer(); 79 | } 80 | } 81 | 82 | Messages.MarkCopy.sendToServer(); 83 | 84 | return; 85 | } 86 | 87 | if (PASTE.isPressed()) { 88 | // set the mode to copying if we aren't in a mode supports pasting (moving/copying) 89 | if (state.config.placeMode != PlaceMode.COPYING && state.config.placeMode != PlaceMode.MOVING) { 90 | Messages.SetPlaceMode.sendToServer(PlaceMode.COPYING); 91 | } 92 | 93 | Messages.MarkPaste.sendToServer(); 94 | 95 | return; 96 | } 97 | 98 | if (RESET.isPressed()) { 99 | Messages.ClearCoords.sendToServer(); 100 | 101 | if (InteractionConfig.resetTransform) { 102 | Messages.ClearTransform.sendToServer(); 103 | Messages.ResetArray.sendToServer(); 104 | } 105 | 106 | return; 107 | } 108 | } 109 | 110 | /** 111 | * For some reason, the key bindings will be phantom pressed if you change your hotbar while they're pressed. 112 | * If you do the following, it will act up. 113 | *
    114 | *
  1. Bind hotbar 1 to C
  2. 115 | *
  3. Press C
  4. 116 | *
  5. Scroll back to the manipulator
  6. 117 | *
  7. Press control
  8. 118 | *
  9. Magically presses C somehow
  10. 119 | *
120 | */ 121 | @SubscribeEvent 122 | public static void onMouseScroll(MouseEvent event) { 123 | if (event.dwheel == 0) return; 124 | 125 | CUT.unpressKey(); 126 | COPY.unpressKey(); 127 | PASTE.unpressKey(); 128 | RESET.unpressKey(); 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/networking/MMPacket.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.networking; 2 | 3 | import net.minecraft.network.INetHandler; 4 | import net.minecraft.world.IBlockAccess; 5 | 6 | import com.google.common.io.ByteArrayDataInput; 7 | 8 | import io.netty.buffer.ByteBuf; 9 | 10 | public abstract class MMPacket { 11 | 12 | public MMPacket() {} 13 | 14 | /** 15 | * Unique ID of this packet. 16 | */ 17 | public abstract byte getPacketID(); 18 | 19 | /** 20 | * Encode the data into given byte buffer. 21 | */ 22 | public abstract void encode(ByteBuf buffer); 23 | 24 | /** 25 | * Decode byte buffer into packet object. 26 | */ 27 | public abstract MMPacket decode(ByteArrayDataInput buffer); 28 | 29 | /** 30 | * Process the received packet. 31 | * 32 | * @param world null if message is received on server side, the client world if message is received on client side 33 | */ 34 | public abstract void process(IBlockAccess world); 35 | 36 | /** 37 | * This will be called just before {@link #process(IBlockAccess)} to inform the handler about the source and type of 38 | * connection. 39 | */ 40 | public void setINetHandler(INetHandler handler) {} 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/networking/Network.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.networking; 2 | 3 | import java.util.EnumMap; 4 | import java.util.List; 5 | 6 | import net.minecraft.entity.player.EntityPlayer; 7 | import net.minecraft.entity.player.EntityPlayerMP; 8 | import net.minecraft.world.World; 9 | import net.minecraft.world.chunk.Chunk; 10 | 11 | import cpw.mods.fml.common.network.FMLEmbeddedChannel; 12 | import cpw.mods.fml.common.network.FMLOutboundHandler; 13 | import cpw.mods.fml.common.network.NetworkRegistry; 14 | import cpw.mods.fml.common.network.internal.FMLProxyPacket; 15 | import cpw.mods.fml.relauncher.Side; 16 | 17 | import com.google.common.io.ByteArrayDataInput; 18 | import com.google.common.io.ByteStreams; 19 | import com.recursive_pineapple.matter_manipulator.MMMod; 20 | 21 | import io.netty.buffer.ByteBuf; 22 | import io.netty.buffer.Unpooled; 23 | import io.netty.channel.ChannelHandler; 24 | import io.netty.channel.ChannelHandlerContext; 25 | import io.netty.channel.SimpleChannelInboundHandler; 26 | import io.netty.handler.codec.MessageToMessageCodec; 27 | 28 | @ChannelHandler.Sharable 29 | public class Network extends MessageToMessageCodec { 30 | 31 | private final EnumMap mChannel; 32 | private final MMPacket[] mSubChannels; 33 | 34 | public Network(String channelName, MMPacket... packetTypes) { 35 | this.mChannel = NetworkRegistry.INSTANCE.newChannel(channelName, this, new HandlerShared()); 36 | final int lastPId = packetTypes[packetTypes.length - 1].getPacketID(); 37 | this.mSubChannels = new MMPacket[lastPId + 1]; 38 | for (MMPacket packetType : packetTypes) { 39 | final int pId = packetType.getPacketID(); 40 | if (this.mSubChannels[pId] == null) 41 | this.mSubChannels[pId] = packetType; 42 | else 43 | throw new IllegalArgumentException("Duplicate Packet ID! " + pId); 44 | } 45 | } 46 | 47 | @Override 48 | protected void encode(ChannelHandlerContext aContext, MMPacket aPacket, List aOutput) { 49 | final ByteBuf tBuf = Unpooled.buffer() 50 | .writeByte(aPacket.getPacketID()); 51 | aPacket.encode(tBuf); 52 | aOutput.add( 53 | new FMLProxyPacket( 54 | tBuf, 55 | aContext.channel() 56 | .attr(NetworkRegistry.FML_CHANNEL) 57 | .get() 58 | ) 59 | ); 60 | } 61 | 62 | @Override 63 | protected void decode(ChannelHandlerContext aContext, FMLProxyPacket aPacket, List aOutput) { 64 | final ByteArrayDataInput aData = ByteStreams.newDataInput( 65 | aPacket.payload() 66 | .array() 67 | ); 68 | final MMPacket tPacket = this.mSubChannels[aData.readByte()].decode(aData); 69 | tPacket.setINetHandler(aPacket.handler()); 70 | aOutput.add(tPacket); 71 | } 72 | 73 | public void sendToPlayer(MMPacket aPacket, EntityPlayerMP aPlayer) { 74 | if (aPacket == null) { 75 | MMMod.LOG.info("packet null"); 76 | return; 77 | } 78 | if (aPlayer == null) { 79 | MMMod.LOG.info("player null"); 80 | return; 81 | } 82 | this.mChannel.get(Side.SERVER) 83 | .attr(FMLOutboundHandler.FML_MESSAGETARGET) 84 | .set(FMLOutboundHandler.OutboundTarget.PLAYER); 85 | this.mChannel.get(Side.SERVER) 86 | .attr(FMLOutboundHandler.FML_MESSAGETARGETARGS) 87 | .set(aPlayer); 88 | this.mChannel.get(Side.SERVER) 89 | .writeAndFlush(aPacket); 90 | } 91 | 92 | public void sendToAllAround(MMPacket aPacket, NetworkRegistry.TargetPoint aPosition) { 93 | this.mChannel.get(Side.SERVER) 94 | .attr(FMLOutboundHandler.FML_MESSAGETARGET) 95 | .set(FMLOutboundHandler.OutboundTarget.ALLAROUNDPOINT); 96 | this.mChannel.get(Side.SERVER) 97 | .attr(FMLOutboundHandler.FML_MESSAGETARGETARGS) 98 | .set(aPosition); 99 | this.mChannel.get(Side.SERVER) 100 | .writeAndFlush(aPacket); 101 | } 102 | 103 | public void sendToAll(MMPacket aPacket) { 104 | this.mChannel.get(Side.SERVER) 105 | .attr(FMLOutboundHandler.FML_MESSAGETARGET) 106 | .set(FMLOutboundHandler.OutboundTarget.ALL); 107 | this.mChannel.get(Side.SERVER) 108 | .writeAndFlush(aPacket); 109 | } 110 | 111 | public void sendToServer(MMPacket aPacket) { 112 | this.mChannel.get(Side.CLIENT) 113 | .attr(FMLOutboundHandler.FML_MESSAGETARGET) 114 | .set(FMLOutboundHandler.OutboundTarget.TOSERVER); 115 | this.mChannel.get(Side.CLIENT) 116 | .writeAndFlush(aPacket); 117 | } 118 | 119 | public void sendPacketToAllPlayersInRange(World aWorld, MMPacket aPacket, int aX, int aZ) { 120 | if (!aWorld.isRemote) { 121 | for (Object tObject : aWorld.playerEntities) { 122 | if (!(tObject instanceof EntityPlayerMP tPlayer)) { 123 | break; 124 | } 125 | Chunk tChunk = aWorld.getChunkFromBlockCoords(aX, aZ); 126 | if (tPlayer.getServerForPlayer().getPlayerManager().isPlayerWatchingChunk(tPlayer, tChunk.xPosition, tChunk.zPosition)) { 127 | sendToPlayer(aPacket, tPlayer); 128 | } 129 | } 130 | } 131 | } 132 | 133 | @ChannelHandler.Sharable 134 | static final class HandlerShared extends SimpleChannelInboundHandler { 135 | 136 | @Override 137 | protected void channelRead0(ChannelHandlerContext ctx, MMPacket aPacket) { 138 | final EntityPlayer aPlayer = MMMod.proxy.getThePlayer(); 139 | aPacket.process(aPlayer == null ? null : aPlayer.worldObj); 140 | } 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/persist/NBTJsonAdapter.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.persist; 2 | 3 | import java.lang.reflect.Type; 4 | 5 | import net.minecraft.nbt.NBTTagCompound; 6 | 7 | import com.google.gson.JsonDeserializationContext; 8 | import com.google.gson.JsonDeserializer; 9 | import com.google.gson.JsonElement; 10 | import com.google.gson.JsonObject; 11 | import com.google.gson.JsonParseException; 12 | import com.google.gson.JsonSerializationContext; 13 | import com.google.gson.JsonSerializer; 14 | import com.recursive_pineapple.matter_manipulator.common.utils.MMUtils; 15 | 16 | public class NBTJsonAdapter implements JsonSerializer, JsonDeserializer { 17 | 18 | @Override 19 | public NBTTagCompound deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { 20 | if (!(json instanceof JsonObject)) throw new JsonParseException("expected object"); 21 | 22 | return (NBTTagCompound) MMUtils.toNbtExact(json); 23 | } 24 | 25 | @Override 26 | public JsonElement serialize(NBTTagCompound src, Type typeOfSrc, JsonSerializationContext context) { 27 | return MMUtils.toJsonObjectExact(src); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/persist/StaticEnumJsonAdapter.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.persist; 2 | 3 | import java.lang.reflect.Type; 4 | 5 | import com.google.gson.JsonDeserializationContext; 6 | import com.google.gson.JsonDeserializer; 7 | import com.google.gson.JsonElement; 8 | import com.google.gson.JsonParseException; 9 | import com.google.gson.JsonPrimitive; 10 | import com.google.gson.JsonSerializationContext; 11 | import com.google.gson.JsonSerializer; 12 | 13 | public class StaticEnumJsonAdapter> implements JsonSerializer, JsonDeserializer { 14 | 15 | private final Class clazz; 16 | private final T[] values; 17 | 18 | public StaticEnumJsonAdapter(Class clazz) { 19 | this.clazz = clazz; 20 | values = clazz.getEnumConstants(); 21 | } 22 | 23 | @Override 24 | public T deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { 25 | if (!(json instanceof JsonPrimitive primitive)) throw new JsonParseException("expected number: " + json); 26 | 27 | if (primitive.isNumber()) { 28 | int index = primitive.getAsInt(); 29 | 30 | if (index < 0 || index >= values.length) throw new JsonParseException("illegal enum index: " + index); 31 | 32 | return values[index]; 33 | } else { 34 | try { 35 | return Enum.valueOf(clazz, primitive.getAsString()); 36 | } catch (IllegalArgumentException e) { 37 | throw new JsonParseException("illegal enum variant: '" + primitive.getAsString() + "'", e); 38 | } 39 | } 40 | } 41 | 42 | @Override 43 | public JsonElement serialize(T src, Type typeOfSrc, JsonSerializationContext context) { 44 | return new JsonPrimitive(src.ordinal()); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/persist/UIDJsonAdapter.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.persist; 2 | 3 | import java.lang.reflect.Type; 4 | 5 | import cpw.mods.fml.common.registry.GameRegistry.UniqueIdentifier; 6 | 7 | import com.google.gson.JsonDeserializationContext; 8 | import com.google.gson.JsonDeserializer; 9 | import com.google.gson.JsonElement; 10 | import com.google.gson.JsonParseException; 11 | import com.google.gson.JsonPrimitive; 12 | import com.google.gson.JsonSerializationContext; 13 | import com.google.gson.JsonSerializer; 14 | import com.recursive_pineapple.matter_manipulator.MMMod; 15 | import com.recursive_pineapple.matter_manipulator.common.utils.MMUtils; 16 | import com.recursive_pineapple.matter_manipulator.common.utils.Mods; 17 | 18 | public class UIDJsonAdapter implements JsonSerializer, JsonDeserializer { 19 | 20 | @Override 21 | public JsonElement serialize(UniqueIdentifier src, Type typeOfSrc, JsonSerializationContext context) { 22 | CommonName common = null; 23 | 24 | for (CommonName name : CommonName.values()) { 25 | if (name.mod.ID.equals(src.modId) && name.name.equals(src.name)) { 26 | common = name; 27 | break; 28 | } 29 | } 30 | 31 | if (common != null) { 32 | return new JsonPrimitive(common.ordinal()); 33 | } else { 34 | if ("minecraft".equals(src.modId)) { 35 | return new JsonPrimitive(src.name); 36 | } else { 37 | return new JsonPrimitive(src.toString()); 38 | } 39 | } 40 | } 41 | 42 | @Override 43 | public UniqueIdentifier deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { 44 | if (!(json instanceof JsonPrimitive primitive)) { 45 | MMMod.LOG.error("cannot parse UniqueIdentifier: expected number or string, but got " + json); 46 | return new UniqueIdentifier("minecraft:air"); 47 | } 48 | 49 | if (primitive.isNumber()) { 50 | int ordinal = primitive.getAsInt(); 51 | 52 | CommonName name = MMUtils.getIndexSafe(CommonName.values(), ordinal); 53 | 54 | if (name == null) { 55 | MMMod.LOG.error("cannot parse UniqueIdentifier: illegal common name index: " + ordinal); 56 | return new UniqueIdentifier("minecraft:air"); 57 | } 58 | 59 | return new UniqueIdentifier(name.mod.ID + ":" + name.name); 60 | } else if (primitive.isString()) { 61 | String id = primitive.getAsString(); 62 | 63 | return new UniqueIdentifier(id.contains(":") ? id : "minecraft:" + id); 64 | } else { 65 | MMMod.LOG.error("cannot parse UniqueIdentifier: expected number or string, but got " + json); 66 | return new UniqueIdentifier("minecraft:air"); 67 | } 68 | } 69 | 70 | public static enum CommonName { 71 | 72 | AIR(Mods.Minecraft, "air"), 73 | GT_BLOCKMACHINES(Mods.GregTech, "gt.blockmachines"), 74 | AE_ITEMPART(Mods.AppliedEnergistics2, "item.ItemMultiPart"), 75 | ARCH_SHAPE(Mods.ArchitectureCraft, "shape"), 76 | ARCH_SHAPE_GLOW(Mods.ArchitectureCraft, "shapeSE"), 77 | ; 78 | 79 | public final Mods mod; 80 | public final String name; 81 | 82 | private CommonName(Mods mod, String name) { 83 | this.mod = mod; 84 | this.name = name; 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/persist/WeightedListJsonAdapter.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.persist; 2 | 3 | import java.lang.reflect.Type; 4 | 5 | import com.google.common.reflect.TypeToken; 6 | import com.google.gson.JsonArray; 7 | import com.google.gson.JsonDeserializationContext; 8 | import com.google.gson.JsonDeserializer; 9 | import com.google.gson.JsonElement; 10 | import com.google.gson.JsonNull; 11 | import com.google.gson.JsonObject; 12 | import com.google.gson.JsonParseException; 13 | import com.google.gson.JsonPrimitive; 14 | import com.google.gson.JsonSerializationContext; 15 | import com.google.gson.JsonSerializer; 16 | import com.recursive_pineapple.matter_manipulator.common.building.BlockSpec; 17 | import com.recursive_pineapple.matter_manipulator.common.data.WeightedSpecList; 18 | 19 | import it.unimi.dsi.fastutil.objects.ObjectIntMutablePair; 20 | 21 | public class WeightedListJsonAdapter implements JsonSerializer, JsonDeserializer { 22 | 23 | private static final Type BLOCK_SPEC = new TypeToken() {}.getType(); 24 | 25 | @Override 26 | public WeightedSpecList deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { 27 | if (!(json instanceof JsonArray array)) return new WeightedSpecList(); 28 | 29 | WeightedSpecList list = new WeightedSpecList(); 30 | 31 | for (var x : array) { 32 | if (!(x instanceof JsonObject obj)) continue; 33 | if (!(obj.get("s") instanceof JsonObject spec)) continue; 34 | if (!(obj.get("w") instanceof JsonPrimitive weight) || !weight.isNumber()) continue; 35 | 36 | list.specs.add(ObjectIntMutablePair.of(context.deserialize(spec, BLOCK_SPEC), weight.getAsInt())); 37 | } 38 | 39 | return list; 40 | } 41 | 42 | @Override 43 | public JsonElement serialize(WeightedSpecList src, Type typeOfSrc, JsonSerializationContext context) { 44 | if (src.specs.size() == 1) { 45 | BlockSpec spec = src.specs.get(0).left(); 46 | 47 | if (spec == null || spec.isAir()) return JsonNull.INSTANCE; 48 | } 49 | 50 | JsonArray array = new JsonArray(); 51 | 52 | for (var p : src.specs) { 53 | JsonObject pair = new JsonObject(); 54 | 55 | pair.add("s", context.serialize(p.left())); 56 | pair.addProperty("w", p.rightInt()); 57 | 58 | array.add(pair); 59 | } 60 | 61 | return array; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/structure/CasingGTFrames.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.structure; 2 | 3 | import static gregtech.api.util.GTStructureUtility.ofFrame; 4 | 5 | import java.util.Map; 6 | import java.util.concurrent.ConcurrentHashMap; 7 | 8 | import net.minecraft.block.Block; 9 | 10 | import gregtech.api.GregTechAPI; 11 | import gregtech.api.casing.ICasing; 12 | import gregtech.api.enums.Materials; 13 | 14 | import com.gtnewhorizon.structurelib.structure.IStructureElement; 15 | 16 | import org.jetbrains.annotations.NotNull; 17 | 18 | public class CasingGTFrames implements ICasing { 19 | 20 | public final Materials material; 21 | 22 | private static final Map FRAMES = new ConcurrentHashMap<>(); 23 | 24 | private CasingGTFrames(Materials material) { 25 | this.material = material; 26 | } 27 | 28 | @Override 29 | public @NotNull Block getBlock() { 30 | return GregTechAPI.sBlockFrames; 31 | } 32 | 33 | @Override 34 | public int getBlockMeta() { 35 | return material.mMetaItemSubID; 36 | } 37 | 38 | @Override 39 | public IStructureElement asElement(CasingElementContext context) { 40 | return ofFrame(material); 41 | } 42 | 43 | @Override 44 | public boolean isTiered() { 45 | return false; 46 | } 47 | 48 | @Override 49 | public int getTextureId() { 50 | throw new UnsupportedOperationException("CasingGTFrames does not support getTextureId()"); 51 | } 52 | 53 | public static CasingGTFrames forMaterial(Materials material) { 54 | return FRAMES.computeIfAbsent(material, CasingGTFrames::new); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/structure/MMCasings.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.structure; 2 | 3 | import java.util.function.Supplier; 4 | 5 | import net.minecraft.block.Block; 6 | 7 | import gregtech.api.GregTechAPI; 8 | import gregtech.api.casing.ICasing; 9 | 10 | import org.jetbrains.annotations.NotNull; 11 | 12 | import gtPlusPlus.core.block.ModBlocks; 13 | import tectech.thing.casing.BlockGTCasingsTT; 14 | import tectech.thing.casing.TTCasingsContainer; 15 | 16 | public enum MMCasings implements ICasing { 17 | 18 | ChemicallyInertMachineCasing(() -> GregTechAPI.sBlockCasings8, 0, 176), 19 | PTFEPipeCasing(() -> GregTechAPI.sBlockCasings8, 1, 176), 20 | MiningNeutroniumCasing(() -> GregTechAPI.sBlockCasings8, 2, 176), 21 | MiningBlackPlutoniumCasing(() -> GregTechAPI.sBlockCasings8, 3, 176), 22 | ExtremeEngineIntakeCasing(() -> GregTechAPI.sBlockCasings8, 4, 176), 23 | EuropiumReinforcedRadiationProofMachineCasing(() -> GregTechAPI.sBlockCasings8, 5, 176), 24 | AdvancedRhodiumPlatedPalladiumMachineCasing(() -> GregTechAPI.sBlockCasings8, 6, 176), 25 | AdvancedIridiumPlatedMachineCasing(() -> GregTechAPI.sBlockCasings8, 7, 176), 26 | MagicalMachineCasing(() -> GregTechAPI.sBlockCasings8, 8, 176), 27 | HSSSTurbineCasing(() -> GregTechAPI.sBlockCasings8, 9, 176), 28 | RadiantNaquadahAlloyCasing(() -> GregTechAPI.sBlockCasings8, 10, 176), 29 | BasicPhotolithographicFrameworkCasing(() -> GregTechAPI.sBlockCasings8, 11, 176), 30 | ReinforcedPhotolithographicFrameworkCasing(() -> GregTechAPI.sBlockCasings8, 12, 176), 31 | RadiationProofPhotolithographicFrameworkCasing(() -> GregTechAPI.sBlockCasings8, 13, 176), 32 | InfinityCooledCasing(() -> GregTechAPI.sBlockCasings8, 14, 176), 33 | 34 | CentrifugeCasing(() -> ModBlocks.blockCasingsMisc, 0, 64), 35 | StructuralCokeOvenCasing(() -> ModBlocks.blockCasingsMisc, 1, 64), 36 | HeatResistantCokeOvenCasing(() -> ModBlocks.blockCasingsMisc, 2, 64), 37 | HeatProofCokeOvenCasing(() -> ModBlocks.blockCasingsMisc, 3, 64), 38 | MaterialPressMachineCasing(() -> ModBlocks.blockCasingsMisc, 4, 64), 39 | ElectrolyzerCasing(() -> ModBlocks.blockCasingsMisc, 5, 64), 40 | WireFactoryCasing(() -> ModBlocks.blockCasingsMisc, 6, 64), 41 | MacerationStackCasing(() -> ModBlocks.blockCasingsMisc, 7, 64), 42 | MatterGenerationCoil(() -> ModBlocks.blockCasingsMisc, 8, 64), 43 | MatterFabricatorCasing(() -> ModBlocks.blockCasingsMisc, 9, 64), 44 | IronPlatedBricks(() -> ModBlocks.blockCasingsMisc, 10, 64), 45 | MultitankExteriorCasing(() -> ModBlocks.blockCasingsMisc, 11, 64), 46 | HastelloyNReactorCasing(() -> ModBlocks.blockCasingsMisc, 12, 64), 47 | Zeron100ReactorShielding(() -> ModBlocks.blockCasingsMisc, 13, 64), 48 | BlastSmelterHeatContainmentCoil(() -> ModBlocks.blockCasingsMisc, 14, 64), 49 | BlastSmelterCasingBlock(() -> ModBlocks.blockCasingsMisc, 15, 64), 50 | 51 | FusionMachineCasingMKIV(() -> ModBlocks.blockCasings6Misc, 0, 116), 52 | AdvancedFusionCoilII(() -> ModBlocks.blockCasings6Misc, 1, 116), 53 | 54 | HighPowerCasing(() -> TTCasingsContainer.sBlockCasingsTT, 0, BlockGTCasingsTT.texturePage), 55 | ComputerCasing(() -> TTCasingsContainer.sBlockCasingsTT, 1, BlockGTCasingsTT.texturePage), 56 | ComputerHeatVent(() -> TTCasingsContainer.sBlockCasingsTT, 2, BlockGTCasingsTT.texturePage), 57 | AdvancedComputerCasing(() -> TTCasingsContainer.sBlockCasingsTT, 3, BlockGTCasingsTT.texturePage), 58 | MolecularCasing(() -> TTCasingsContainer.sBlockCasingsTT, 4, BlockGTCasingsTT.texturePage), 59 | AdvancedMolecularCasing(() -> TTCasingsContainer.sBlockCasingsTT, 5, BlockGTCasingsTT.texturePage), 60 | ContainmentFieldGenerator(() -> TTCasingsContainer.sBlockCasingsTT, 6, BlockGTCasingsTT.texturePage), 61 | MolecularCoil(() -> TTCasingsContainer.sBlockCasingsTT, 7, BlockGTCasingsTT.texturePage), 62 | HollowCasing(() -> TTCasingsContainer.sBlockCasingsTT, 8, BlockGTCasingsTT.texturePage), 63 | SpacetimeAlteringCasing(() -> TTCasingsContainer.sBlockCasingsTT, 9, BlockGTCasingsTT.texturePage), 64 | TeleportationCasing(() -> TTCasingsContainer.sBlockCasingsTT, 10, BlockGTCasingsTT.texturePage), 65 | DimensionalBridgeGenerator(() -> TTCasingsContainer.sBlockCasingsTT, 11, BlockGTCasingsTT.texturePage), 66 | UltimateMolecularCasing(() -> TTCasingsContainer.sBlockCasingsTT, 12, BlockGTCasingsTT.texturePage), 67 | UltimateAdvancedMolecularCasing(() -> TTCasingsContainer.sBlockCasingsTT, 13, BlockGTCasingsTT.texturePage), 68 | UltimateContainmentFieldGenerator(() -> TTCasingsContainer.sBlockCasingsTT, 14, BlockGTCasingsTT.texturePage), 69 | ; 70 | 71 | public final Supplier blockGetter; 72 | public final int meta; 73 | public final int textureOffset; 74 | 75 | MMCasings(Supplier blockGetter, int meta, int textureOffset) { 76 | this.blockGetter = blockGetter; 77 | this.meta = meta; 78 | this.textureOffset = textureOffset; 79 | } 80 | 81 | @Override 82 | public @NotNull Block getBlock() { 83 | return blockGetter.get(); 84 | } 85 | 86 | @Override 87 | public int getBlockMeta() { 88 | return meta; 89 | } 90 | 91 | @Override 92 | public boolean isTiered() { 93 | return false; 94 | } 95 | 96 | @Override 97 | public int getTextureId() { 98 | if (textureOffset == -1) { 99 | throw new UnsupportedOperationException("Casing " + name() + " does not have a casing texture; The result of getTextureId() is undefined."); 100 | } 101 | 102 | return textureOffset + meta; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/uplink/IUplinkMulti.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.uplink; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import net.minecraft.entity.player.EntityPlayer; 7 | import net.minecraft.item.ItemStack; 8 | 9 | import net.minecraftforge.fluids.FluidStack; 10 | 11 | import cpw.mods.fml.relauncher.Side; 12 | import cpw.mods.fml.relauncher.SideOnly; 13 | 14 | import appeng.api.networking.storage.IStorageGrid; 15 | 16 | import com.google.common.collect.MapMaker; 17 | import com.recursive_pineapple.matter_manipulator.asm.Optional; 18 | import com.recursive_pineapple.matter_manipulator.common.building.IPseudoInventory; 19 | import com.recursive_pineapple.matter_manipulator.common.items.manipulator.Location; 20 | import com.recursive_pineapple.matter_manipulator.common.utils.BigFluidStack; 21 | import com.recursive_pineapple.matter_manipulator.common.utils.BigItemStack; 22 | import com.recursive_pineapple.matter_manipulator.common.utils.Mods.Names; 23 | 24 | import it.unimi.dsi.fastutil.Pair; 25 | 26 | public interface IUplinkMulti { 27 | 28 | boolean isActive(); 29 | 30 | Location getLocation(); 31 | 32 | UplinkState getState(); 33 | 34 | @SideOnly(Side.CLIENT) 35 | void setState(UplinkState state); 36 | 37 | /** 38 | * See {@link IPseudoInventory#tryConsumeItems(List, int)} 39 | */ 40 | Pair> tryConsumeItems(List requestedItems, boolean simulate, boolean fuzzy); 41 | 42 | /** 43 | * See {@link IPseudoInventory#givePlayerItems(ItemStack...)} 44 | */ 45 | UplinkStatus tryGivePlayerItems(List items); 46 | 47 | /** 48 | * See {@link IPseudoInventory#givePlayerFluids(FluidStack...)} 49 | */ 50 | UplinkStatus tryGivePlayerFluids(List fluids); 51 | 52 | @Optional(Names.APPLIED_ENERGISTICS2) 53 | IStorageGrid getStorageGrid(); 54 | 55 | /** 56 | * Submits a new plan to the ME hatch. 57 | * 58 | * @param details Some extra details for the plan 59 | * @param autocraft When true, the plan will be automatically crafted 60 | */ 61 | void submitPlan(EntityPlayer submitter, String details, List requiredItems, boolean autocraft); 62 | 63 | /** 64 | * Clears any manual plans 65 | */ 66 | void clearManualPlans(EntityPlayer player); 67 | 68 | /** 69 | * Clears and auto plans and cancels their jobs 70 | */ 71 | void cancelAutoPlans(EntityPlayer player); 72 | 73 | /** 74 | * Drains power from the uplink 75 | * 76 | * @param requested The wanted amount of power 77 | * @return The amount of power actually drained 78 | */ 79 | double drainPower(double requested); 80 | 81 | /** 82 | * A weak-valued map containing all active uplinks 83 | */ 84 | Map UPLINKS = new MapMaker().weakValues() 85 | .makeMap(); 86 | 87 | static IUplinkMulti getUplink(long address) { 88 | return UPLINKS.get(address); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/uplink/Structures.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.uplink; 2 | 3 | public class Structures { 4 | 5 | public static final String[][] UPLINK = { 6 | { 7 | " ", 8 | " ", 9 | " ", 10 | " ", 11 | " AA~AA ", 12 | " ", 13 | " ", 14 | " ", 15 | " " 16 | }, { 17 | " ", 18 | " ", 19 | " A A ", 20 | " AA AA ", 21 | " AA AA ", 22 | " AA AA ", 23 | " A A ", 24 | " ", 25 | " " 26 | }, { 27 | " ", 28 | " A A ", 29 | " ACCCCCA ", 30 | " AD DA ", 31 | "A D D A", 32 | " AD DA ", 33 | " ACCCCCA ", 34 | " A A ", 35 | " " 36 | }, { 37 | " ", 38 | " AA AA ", 39 | " AD DA ", 40 | "A A", 41 | "A A", 42 | "A A", 43 | " AD DA ", 44 | " AA AA ", 45 | " " 46 | }, { 47 | " A A ", 48 | " AA AA ", 49 | "A D D A", 50 | "A A", 51 | "ABBE EBBA", 52 | "A A", 53 | "A D D A", 54 | " AA AA ", 55 | " A A " 56 | }, { 57 | " ", 58 | " AA AA ", 59 | " AD DA ", 60 | "A A", 61 | "A A", 62 | "A A", 63 | " AD DA ", 64 | " AA AA ", 65 | " " 66 | }, { 67 | " ", 68 | " A A ", 69 | " ACCCCCA ", 70 | " AD DA ", 71 | "A D D A", 72 | " AD DA ", 73 | " ACCCCCA ", 74 | " A A ", 75 | " " 76 | }, { 77 | " ", 78 | " ", 79 | " A A ", 80 | " AA AA ", 81 | " AA AA ", 82 | " AA AA ", 83 | " A A ", 84 | " ", 85 | " " 86 | }, { 87 | " ", 88 | " ", 89 | " ", 90 | " ", 91 | " A A ", 92 | " ", 93 | " ", 94 | " ", 95 | " " 96 | } 97 | }; 98 | } 99 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/uplink/UplinkState.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.uplink; 2 | 3 | public enum UplinkState { 4 | OFF, 5 | IDLE, 6 | ACTIVE, 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/uplink/UplinkStatus.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.uplink; 2 | 3 | public enum UplinkStatus { 4 | 5 | OK, 6 | NO_PLASMA, 7 | AE_OFFLINE, 8 | NO_HATCH; 9 | 10 | @Override 11 | public String toString() { 12 | return switch (this) { 13 | case OK -> "Ok"; 14 | case NO_PLASMA -> "Insufficient plasma"; 15 | case AE_OFFLINE -> "Could not connect to the ME system"; 16 | case NO_HATCH -> "Missing ME hatch"; 17 | }; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/utils/BigFluidStack.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.utils; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Objects; 6 | 7 | import net.minecraft.nbt.NBTTagCompound; 8 | 9 | import net.minecraftforge.fluids.Fluid; 10 | import net.minecraftforge.fluids.FluidStack; 11 | 12 | import cpw.mods.fml.common.Optional.Method; 13 | 14 | import appeng.api.storage.data.IAEFluidStack; 15 | import appeng.util.item.AEFluidStack; 16 | 17 | import com.recursive_pineapple.matter_manipulator.common.utils.Mods.Names; 18 | 19 | public class BigFluidStack { 20 | 21 | public Fluid fluid; 22 | public long amount; 23 | public int meta; 24 | public NBTTagCompound tag; 25 | 26 | public transient FluidId id; 27 | 28 | public BigFluidStack() {} 29 | 30 | private BigFluidStack(FluidStack stack) { 31 | this.fluid = stack.getFluid(); 32 | this.amount = stack.amount; 33 | this.tag = MMUtils.copy(stack.tag); 34 | } 35 | 36 | private BigFluidStack(FluidId id, long amount) { 37 | this(id.getFluidStack()); 38 | setStackSize(amount); 39 | } 40 | 41 | public FluidId getId() { 42 | if (id == null) { 43 | id = FluidId.createWithCopy(fluid, null, tag); 44 | } 45 | 46 | return id; 47 | } 48 | 49 | public FluidStack getFluidStack() { 50 | FluidStack stack = new FluidStack(fluid, amount > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) amount); 51 | stack.tag = MMUtils.copy(tag); 52 | return stack; 53 | } 54 | 55 | @Method(modid = Names.APPLIED_ENERGISTICS2) 56 | public IAEFluidStack getAEFluidStack() { 57 | return Objects.requireNonNull(AEFluidStack.create(getFluidStack())).setStackSize(amount); 58 | } 59 | 60 | public static BigFluidStack create(FluidStack stack) { 61 | if (stack == null) return null; 62 | 63 | return new BigFluidStack(stack); 64 | } 65 | 66 | public static BigFluidStack create(FluidId id, long amount) { 67 | if (id == null) return null; 68 | 69 | return new BigFluidStack(id, amount); 70 | } 71 | 72 | @Method(modid = Names.APPLIED_ENERGISTICS2) 73 | public static BigFluidStack create(IAEFluidStack stack) { 74 | if (stack == null) return null; 75 | 76 | return create(stack.getFluidStack()).setStackSize(stack.getStackSize()); 77 | } 78 | 79 | public FluidStack remove(int amount) { 80 | if (this.amount < amount) { 81 | FluidStack stack = new FluidStack(fluid, (int) this.amount); 82 | stack.tag = MMUtils.copy(tag); 83 | this.amount = 0; 84 | return stack; 85 | } else { 86 | FluidStack stack = new FluidStack(fluid, amount); 87 | stack.tag = MMUtils.copy(tag); 88 | this.amount -= amount; 89 | return stack; 90 | } 91 | } 92 | 93 | public BigFluidStack removeBig(long amount) { 94 | long toRemove = Math.min(this.amount, amount); 95 | 96 | BigFluidStack stack = copy().setStackSize(toRemove); 97 | this.amount -= toRemove; 98 | 99 | return stack; 100 | } 101 | 102 | public BigFluidStack incStackSize(long amount) { 103 | this.amount += amount; 104 | return this; 105 | } 106 | 107 | public BigFluidStack decStackSize(long amount) { 108 | this.amount -= amount; 109 | return this; 110 | } 111 | 112 | public List toStacks() { 113 | List stack = new ArrayList<>(); 114 | 115 | while (this.amount > 0) { 116 | stack.add(remove(Integer.MAX_VALUE)); 117 | } 118 | 119 | return stack; 120 | } 121 | 122 | public BigFluidStack copy() { 123 | BigFluidStack out = new BigFluidStack(); 124 | 125 | out.fluid = fluid; 126 | out.amount = amount; 127 | out.meta = meta; 128 | out.tag = tag == null ? null : (NBTTagCompound) tag.copy(); 129 | 130 | return out; 131 | } 132 | 133 | public BigFluidStack setStackSize(long amount) { 134 | this.amount = amount; 135 | return this; 136 | } 137 | 138 | public long getStackSize() { 139 | return amount; 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/utils/BigItemStack.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.utils; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Objects; 6 | 7 | import net.minecraft.init.Items; 8 | import net.minecraft.item.Item; 9 | import net.minecraft.item.ItemStack; 10 | import net.minecraft.nbt.NBTTagCompound; 11 | 12 | import cpw.mods.fml.common.Optional.Method; 13 | 14 | import appeng.api.storage.data.IAEItemStack; 15 | import appeng.util.item.AEItemStack; 16 | 17 | import com.recursive_pineapple.matter_manipulator.common.utils.Mods.Names; 18 | 19 | public class BigItemStack { 20 | 21 | public Item item; 22 | public long stackSize; 23 | public int meta; 24 | public NBTTagCompound tag; 25 | 26 | public transient ItemId id; 27 | 28 | public BigItemStack() {} 29 | 30 | private BigItemStack(ItemStack stack) { 31 | this.item = stack.getItem(); 32 | this.stackSize = stack.stackSize; 33 | this.meta = Items.feather.getDamage(stack); 34 | this.tag = stack.getTagCompound(); 35 | } 36 | 37 | private BigItemStack(ItemId id, long amount) { 38 | this(id.getItemStack()); 39 | setStackSize(amount); 40 | } 41 | 42 | public ItemId getId() { 43 | if (id == null) { 44 | id = ItemId.create(item, meta, tag); 45 | } 46 | 47 | return id; 48 | } 49 | 50 | public ItemStack getItemStack() { 51 | ItemStack stack = new ItemStack(item, stackSize > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) stackSize, this.meta); 52 | stack.setTagCompound(tag == null ? null : (NBTTagCompound) tag.copy()); 53 | return stack; 54 | } 55 | 56 | @Method(modid = Names.APPLIED_ENERGISTICS2) 57 | public IAEItemStack getAEItemStack() { 58 | return Objects.requireNonNull(AEItemStack.create(getItemStack())).setStackSize(stackSize); 59 | } 60 | 61 | public static BigItemStack create(ItemStack stack) { 62 | if (stack == null) return null; 63 | 64 | return new BigItemStack(stack); 65 | } 66 | 67 | public static BigItemStack create(ItemId id, long amount) { 68 | if (id == null) return null; 69 | 70 | return new BigItemStack(id, amount); 71 | } 72 | 73 | @Method(modid = Names.APPLIED_ENERGISTICS2) 74 | public static BigItemStack create(IAEItemStack stack) { 75 | if (stack == null) return null; 76 | 77 | return create(stack.getItemStack()).setStackSize(stack.getStackSize()); 78 | } 79 | 80 | public ItemStack remove(int stackSize) { 81 | if (this.stackSize < stackSize) { 82 | ItemStack stack = new ItemStack(item, (int) this.stackSize, this.meta); 83 | stack.setTagCompound(tag == null ? null : (NBTTagCompound) tag.copy()); 84 | this.stackSize = 0; 85 | return stack; 86 | } else { 87 | ItemStack stack = new ItemStack(item, stackSize, this.meta); 88 | stack.setTagCompound(tag == null ? null : (NBTTagCompound) tag.copy()); 89 | this.stackSize -= stackSize; 90 | return stack; 91 | } 92 | } 93 | 94 | public BigItemStack removeBig(int stackSize) { 95 | long toRemove = Math.min(this.stackSize, stackSize); 96 | 97 | BigItemStack stack = copy().setStackSize(toRemove); 98 | this.stackSize -= toRemove; 99 | 100 | return stack; 101 | } 102 | 103 | public BigItemStack incStackSize(long stackSize) { 104 | this.stackSize += stackSize; 105 | return this; 106 | } 107 | 108 | public BigItemStack decStackSize(long stackSize) { 109 | this.stackSize -= stackSize; 110 | return this; 111 | } 112 | 113 | public List toStacks() { 114 | List stack = new ArrayList<>(); 115 | 116 | while (this.stackSize > 0) { 117 | stack.add(remove(Integer.MAX_VALUE)); 118 | } 119 | 120 | return stack; 121 | } 122 | 123 | public List toStacks(int stackSize) { 124 | List stack = new ArrayList<>(); 125 | 126 | while (this.stackSize > 0) { 127 | stack.add(remove(stackSize)); 128 | } 129 | 130 | return stack; 131 | } 132 | 133 | public BigItemStack copy() { 134 | BigItemStack out = new BigItemStack(); 135 | 136 | out.item = item; 137 | out.stackSize = stackSize; 138 | out.meta = meta; 139 | out.tag = tag == null ? null : (NBTTagCompound) tag.copy(); 140 | 141 | return out; 142 | } 143 | 144 | public BigItemStack setStackSize(long stackSize) { 145 | this.stackSize = stackSize; 146 | return this; 147 | } 148 | 149 | public long getStackSize() { 150 | return stackSize; 151 | } 152 | 153 | public Item getItem() { 154 | return item; 155 | } 156 | 157 | public int getItemDamage() { 158 | return meta; 159 | } 160 | 161 | public boolean hasSubtypes() { 162 | return item.getHasSubtypes(); 163 | } 164 | 165 | public boolean isSameType(ItemStack other) { 166 | if (other == null) return false; 167 | 168 | return item == other.getItem() && meta == Items.feather.getDamage(other) && Objects.equals(tag, other.getTagCompound()); 169 | } 170 | 171 | public boolean isSameType(BigItemStack other) { 172 | if (other == null) return false; 173 | 174 | return item == other.getItem() && meta == other.meta && Objects.equals(tag, other.tag); 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/utils/BlockMeta.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.utils; 2 | 3 | import net.minecraft.block.Block; 4 | 5 | public class BlockMeta implements ImmutableBlockMeta { 6 | 7 | public Block block; 8 | public int meta; 9 | 10 | public BlockMeta() {} 11 | 12 | public BlockMeta(Block block, int meta) { 13 | this.block = block; 14 | this.meta = meta; 15 | } 16 | 17 | @Override 18 | public Block getBlock() { 19 | return block; 20 | } 21 | 22 | @Override 23 | public int getMeta() { 24 | return meta; 25 | } 26 | 27 | public void setBlock(Block block) { 28 | this.block = block; 29 | } 30 | 31 | public void setMeta(int meta) { 32 | this.meta = meta; 33 | } 34 | 35 | @Override 36 | public int hashCode() { 37 | final int prime = 31; 38 | int result = 1; 39 | result = prime * result + ((block == null) ? 0 : block.hashCode()); 40 | result = prime * result + meta; 41 | return result; 42 | } 43 | 44 | @Override 45 | public boolean equals(Object obj) { 46 | if (this == obj) return true; 47 | if (obj == null) return false; 48 | if (getClass() != obj.getClass()) return false; 49 | BlockMeta other = (BlockMeta) obj; 50 | if (block == null) { 51 | if (other.block != null) return false; 52 | } else if (!block.equals(other.block)) return false; 53 | if (meta != other.meta) return false; 54 | return true; 55 | } 56 | 57 | @Override 58 | public String toString() { 59 | return "BlockMeta [block=" + block + ", meta=" + meta + "]"; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/utils/FluidId.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.utils; 2 | 3 | import static net.minecraftforge.common.util.Constants.NBT.TAG_COMPOUND; 4 | import static net.minecraftforge.common.util.Constants.NBT.TAG_INT; 5 | 6 | import javax.annotation.Nonnull; 7 | import javax.annotation.Nullable; 8 | 9 | import net.minecraft.nbt.NBTTagCompound; 10 | 11 | import net.minecraftforge.fluids.Fluid; 12 | import net.minecraftforge.fluids.FluidRegistry; 13 | import net.minecraftforge.fluids.FluidStack; 14 | 15 | import com.google.auto.value.AutoValue; 16 | 17 | @AutoValue 18 | public abstract class FluidId { 19 | 20 | public static FluidId create(NBTTagCompound tag) { 21 | return new AutoValue_FluidId( 22 | FluidRegistry.getFluid(tag.getString("FluidName")), 23 | tag.hasKey("Tag", TAG_COMPOUND) ? tag.getCompoundTag("Tag") : null, 24 | tag.hasKey("Amount", TAG_INT) ? tag.getInteger("Amount") : null 25 | ); 26 | } 27 | 28 | public NBTTagCompound writeToNBT() { 29 | NBTTagCompound tag = new NBTTagCompound(); 30 | tag.setString("FluidName", fluid().getName()); 31 | if (nbt() != null) tag.setTag("Tag", nbt()); 32 | Integer amount = amount(); 33 | if (amount != null) tag.setInteger("Amount", amount); 34 | return tag; 35 | } 36 | 37 | public static FluidId create(FluidStack fluidStack) { 38 | return createWithCopy(fluidStack.getFluid(), null, fluidStack.tag); 39 | } 40 | 41 | public static FluidId createWithAmount(FluidStack fluidStack) { 42 | return createWithCopy(fluidStack.getFluid(), (Integer) fluidStack.amount, fluidStack.tag); 43 | } 44 | 45 | public static FluidId create(Fluid fluid) { 46 | return createNoCopy(fluid, null, null); 47 | } 48 | 49 | public static FluidId createWithCopy(Fluid fluid, Integer amount, @Nullable NBTTagCompound nbt) { 50 | if (nbt != null) { 51 | nbt = (NBTTagCompound) nbt.copy(); 52 | } 53 | return new AutoValue_FluidId(fluid, nbt, amount); 54 | } 55 | 56 | /** 57 | * This method does not copy the NBT tag. 58 | */ 59 | public static FluidId createNoCopy(Fluid fluid, Integer amount, @Nullable NBTTagCompound nbt) { 60 | return new AutoValue_FluidId(fluid, nbt, amount); 61 | } 62 | 63 | protected abstract Fluid fluid(); 64 | 65 | @Nullable 66 | protected abstract NBTTagCompound nbt(); 67 | 68 | @Nullable 69 | protected abstract Integer amount(); 70 | 71 | @Nonnull 72 | public FluidStack getFluidStack() { 73 | NBTTagCompound nbt = nbt(); 74 | return new FluidStack(fluid(), 1, nbt != null ? (NBTTagCompound) nbt.copy() : null); 75 | } 76 | 77 | @Nonnull 78 | public FluidStack getFluidStack(int amount) { 79 | NBTTagCompound nbt = nbt(); 80 | return new FluidStack(fluid(), amount, nbt != null ? (NBTTagCompound) nbt.copy() : null); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/utils/ImmutableBlockMeta.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.utils; 2 | 3 | import static com.recursive_pineapple.matter_manipulator.common.utils.MMValues.W; 4 | 5 | import net.minecraft.block.Block; 6 | import net.minecraft.item.Item; 7 | 8 | import com.recursive_pineapple.matter_manipulator.common.building.BlockSpec; 9 | 10 | public interface ImmutableBlockMeta { 11 | 12 | Block getBlock(); 13 | 14 | int getMeta(); 15 | 16 | default BlockSpec asSpec() { 17 | return new BlockSpec().setObject(getBlock(), getMeta()); 18 | } 19 | 20 | default Item getItem() { 21 | return Item.getItemFromBlock(getBlock()); 22 | } 23 | 24 | default boolean matches(Block block, int meta) { 25 | return getBlock() == block && (getMeta() == meta || getMeta() == W || meta == W); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/utils/ImmutableItemMeta.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.utils; 2 | 3 | import static com.recursive_pineapple.matter_manipulator.common.utils.MMValues.W; 4 | 5 | import net.minecraft.block.Block; 6 | import net.minecraft.init.Items; 7 | import net.minecraft.item.Item; 8 | import net.minecraft.item.ItemStack; 9 | 10 | public interface ImmutableItemMeta { 11 | 12 | public Item getItem(); 13 | 14 | public int getMeta(); 15 | 16 | public default Block getBlock() { 17 | return Block.getBlockFromItem(getItem()); 18 | } 19 | 20 | public default boolean matches(ItemStack stack) { 21 | if (stack == null) return false; 22 | 23 | int meta = Items.feather.getDamage(stack); 24 | return getItem() == stack.getItem() && (getMeta() == meta || getMeta() == W || meta == W); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/utils/ItemMeta.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.utils; 2 | 3 | import net.minecraft.item.Item; 4 | 5 | public class ItemMeta implements ImmutableItemMeta { 6 | 7 | public Item item; 8 | public int meta; 9 | 10 | public ItemMeta() {} 11 | 12 | public ItemMeta(Item item, int meta) { 13 | this.item = item; 14 | this.meta = meta; 15 | } 16 | 17 | @Override 18 | public Item getItem() { 19 | return item; 20 | } 21 | 22 | @Override 23 | public int getMeta() { 24 | return meta; 25 | } 26 | 27 | public void setItem(Item item) { 28 | this.item = item; 29 | } 30 | 31 | public void setMeta(int meta) { 32 | this.meta = meta; 33 | } 34 | 35 | @Override 36 | public int hashCode() { 37 | final int prime = 31; 38 | int result = 1; 39 | result = prime * result + ((item == null) ? 0 : item.hashCode()); 40 | result = prime * result + meta; 41 | return result; 42 | } 43 | 44 | @Override 45 | public boolean equals(Object obj) { 46 | if (this == obj) return true; 47 | if (obj == null) return false; 48 | if (getClass() != obj.getClass()) return false; 49 | ItemMeta other = (ItemMeta) obj; 50 | if (item == null) { 51 | if (other.item != null) return false; 52 | } else if (!item.equals(other.item)) return false; 53 | if (meta != other.meta) return false; 54 | return true; 55 | } 56 | 57 | @Override 58 | public String toString() { 59 | return "ItemMeta [item=" + item + ", meta=" + meta + "]"; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/utils/Lazy.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.utils; 2 | 3 | import java.util.function.Supplier; 4 | 5 | public class Lazy implements Supplier { 6 | 7 | private boolean hasValue = false; 8 | private T value; 9 | 10 | private Supplier getter; 11 | 12 | public Lazy(Supplier getter) { 13 | this.getter = getter; 14 | } 15 | 16 | @Override 17 | public synchronized T get() { 18 | if (!hasValue) { 19 | value = getter.get(); 20 | getter = null; 21 | hasValue = true; 22 | } 23 | 24 | return value; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/utils/LazyBlock.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.utils; 2 | 3 | import java.util.Objects; 4 | 5 | import net.minecraft.block.Block; 6 | 7 | import cpw.mods.fml.common.registry.GameRegistry; 8 | 9 | import com.recursive_pineapple.matter_manipulator.common.building.ImmutableBlockSpec; 10 | 11 | public class LazyBlock extends Lazy { 12 | 13 | public final Mods mod; 14 | public final String blockName; 15 | 16 | public LazyBlock(Mods mod, String blockName, int meta) { 17 | super(() -> { 18 | if (!mod.isModLoaded()) return null; 19 | 20 | Block block = GameRegistry.findBlock(mod.ID, blockName); 21 | 22 | Objects.requireNonNull(block, "could not find block: " + mod.ID + ":" + blockName); 23 | 24 | return new BlockMeta(block, meta); 25 | }); 26 | 27 | this.mod = mod; 28 | this.blockName = blockName; 29 | } 30 | 31 | public LazyBlock(Mods mod, String blockName) { 32 | this(mod, blockName, 0); 33 | } 34 | 35 | public boolean isLoaded() { 36 | return mod.isModLoaded(); 37 | } 38 | 39 | public boolean matches(Block other, int metaOther) { 40 | if (!isLoaded()) return false; 41 | 42 | ImmutableBlockMeta bm = get(); 43 | 44 | return bm == null ? false : bm.matches(other, metaOther); 45 | } 46 | 47 | public boolean matches(ImmutableBlockSpec spec) { 48 | return matches(spec.getBlock(), spec.getBlockMeta()); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/utils/LazyItem.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.utils; 2 | 3 | import static com.recursive_pineapple.matter_manipulator.common.utils.MMValues.W; 4 | 5 | import java.util.Objects; 6 | 7 | import net.minecraft.init.Items; 8 | import net.minecraft.item.Item; 9 | import net.minecraft.item.ItemStack; 10 | 11 | import cpw.mods.fml.common.registry.GameRegistry; 12 | 13 | public class LazyItem extends Lazy { 14 | 15 | public final Mods mod; 16 | public final String itemName; 17 | 18 | public LazyItem(Mods mod, String itemName, int meta) { 19 | super(() -> { 20 | if (!mod.isModLoaded()) return null; 21 | 22 | Item item = GameRegistry.findItem(mod.ID, itemName); 23 | 24 | Objects.requireNonNull(item, "could not find item: " + mod.ID + ":" + itemName); 25 | 26 | return new ItemMeta(item, meta); 27 | }); 28 | 29 | this.mod = mod; 30 | this.itemName = itemName; 31 | } 32 | 33 | public LazyItem(Mods mod, String itemName) { 34 | this(mod, itemName, 0); 35 | } 36 | 37 | public boolean isLoaded() { 38 | return mod.isModLoaded(); 39 | } 40 | 41 | public boolean matches(Item other, int metaOther) { 42 | if (!isLoaded()) return false; 43 | 44 | ImmutableItemMeta bm = get(); 45 | 46 | if (bm == null) return false; 47 | 48 | return bm.getItem() == other && (bm.getMeta() == metaOther || bm.getMeta() == W || metaOther == W); 49 | } 50 | 51 | public boolean matches(ItemStack stack) { 52 | if (stack == null) return false; 53 | 54 | return matches(stack.getItem(), Items.feather.getDamage(stack)); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/utils/MMValues.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.utils; 2 | 3 | import net.minecraftforge.oredict.OreDictionary; 4 | 5 | public class MMValues { 6 | 7 | private MMValues() {} 8 | 9 | /** 10 | * Renamed from "MATERIAL_UNIT" to just "M" 11 | *

12 | * This is worth exactly one normal Item. This Constant can be divided by many commonly used Numbers such as 1, 2, 13 | * 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 24, ... 64 or 81 without losing precision and is for that 14 | * reason used as Unit of Amount. But it is also small enough to be multiplied with larger Numbers. 15 | *

16 | * This is used to determine the amount of Material contained inside a prefixed Ore. For example Nugget = M / 9 as 17 | * it contains out of 1/9 of an Ingot. 18 | */ 19 | public static final long M = 3628800; 20 | 21 | /** 22 | * Renamed from "FLUID_MATERIAL_UNIT" to just "L" 23 | *

24 | * Fluid per Material Unit (Prime Factors: 3 * 3 * 2 * 2 * 2 * 2) 25 | */ 26 | public static final long L = 144; 27 | 28 | /** 29 | * The Item WildCard Tag. Even shorter than the "-1" of the past 30 | */ 31 | public static final short W = OreDictionary.WILDCARD_VALUE; 32 | 33 | /** 34 | * The Voltage Tiers. Use this Array instead of the old named Voltage Variables 35 | */ 36 | public static final long[] V = new long[] { 37 | 8L, 38 | 32L, 39 | 128L, 40 | 512L, 41 | 2048L, 42 | 8192L, 43 | 32_768L, 44 | 131_072L, 45 | 524_288L, 46 | 2_097_152L, 47 | 8_388_608L, 48 | 33_554_432L, 49 | 134_217_728L, 50 | 536_870_912L, 51 | Integer.MAX_VALUE - 7, 52 | // Error tier to prevent out of bounds errors. Not really a real tier (for now). 53 | 8_589_934_592L 54 | }; 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/common/utils/Mods.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common.utils; 2 | 3 | import java.util.Locale; 4 | 5 | import net.minecraft.util.ResourceLocation; 6 | 7 | import cpw.mods.fml.common.Loader; 8 | 9 | public enum Mods { 10 | 11 | AE2Stuff(Names.AE2STUFF), 12 | Angelica(Names.ANGELICA), 13 | AppliedEnergistics2(Names.APPLIED_ENERGISTICS2), 14 | ArchitectureCraft(Names.ARCHITECTURE_CRAFT), 15 | BloodMagic(Names.BLOOD_MAGIC), 16 | CarpentersBlocks(Names.CARPENTERS_BLOCKS), 17 | EnderIO(Names.ENDER_I_O), 18 | /** Creates the actual block parts from blocks. */ 19 | ForgeMicroblocks(Names.FORGE_MICROBLOCKS), 20 | /** The forge multipart library. */ 21 | ForgeMultipart(Names.FORGE_MULTIPART), 22 | FloodLights(Names.FLOOD_LIGHTS), 23 | GalacticraftCore(Names.GALACTICRAFT_CORE), 24 | GalaxySpace(Names.GALAXY_SPACE), 25 | GregTech(Names.GREG_TECH), 26 | GTPlusPlus(Names.G_T_PLUS_PLUS), 27 | GTNHIntergalactic(Names.GTNH_INTERGALACTIC), 28 | GraviSuite(Names.GRAVI_SUITE), 29 | Hodgepodge(Names.HODGEPODGE), 30 | IndustrialCraft2(Names.INDUSTRIAL_CRAFT2), 31 | LogisticsPipes(Names.LOGISTICS_PIPES), 32 | MatterManipulator(Names.MATTER_MANIPULATOR), 33 | Minecraft(Names.MINECRAFT) { 34 | 35 | @Override 36 | public boolean isModLoaded() { 37 | return true; 38 | } 39 | }, 40 | NewHorizonsCoreMod(Names.NEW_HORIZONS_CORE_MOD), 41 | NotEnoughItems(Names.NOT_ENOUGH_ITEMS), 42 | StorageDrawers(Names.STORAGE_DRAWERS), 43 | Thaumcraft(Names.THAUMCRAFT), 44 | 45 | ; 46 | 47 | public static class Names { 48 | 49 | public static final String AE2STUFF = "ae2stuff"; 50 | public static final String ANGELICA = "angelica"; 51 | public static final String APPLIED_ENERGISTICS2 = "appliedenergistics2"; 52 | public static final String ARCHITECTURE_CRAFT = "ArchitectureCraft"; 53 | public static final String BLOOD_MAGIC = "AWWayofTime"; 54 | public static final String CARPENTERS_BLOCKS = "CarpentersBlocks"; 55 | public static final String ENDER_I_O = "EnderIO"; 56 | public static final String FORGE_MICROBLOCKS = "ForgeMicroblock"; 57 | public static final String FORGE_MULTIPART = "ForgeMultipart"; 58 | public static final String FLOOD_LIGHTS = "FloodLights"; 59 | public static final String GALACTICRAFT_CORE = "GalacticraftCore"; 60 | public static final String GALAXY_SPACE = "GalaxySpace"; 61 | public static final String GREG_TECH = "gregtech"; 62 | public static final String GRAVI_SUITE = "GraviSuite"; 63 | public static final String G_T_PLUS_PLUS = "miscutils"; 64 | public static final String GTNH_INTERGALACTIC = "gtnhintergalactic"; 65 | public static final String HODGEPODGE = "hodgepodge"; 66 | public static final String INDUSTRIAL_CRAFT2 = "IC2"; 67 | public static final String LOGISTICS_PIPES = "LogisticsPipes"; 68 | public static final String MATTER_MANIPULATOR = "matter-manipulator"; 69 | public static final String MINECRAFT = "minecraft"; 70 | public static final String NEW_HORIZONS_CORE_MOD = "dreamcraft"; 71 | public static final String NOT_ENOUGH_ITEMS = "NotEnoughItems"; 72 | public static final String STORAGE_DRAWERS = "StorageDrawers"; 73 | public static final String THAUMCRAFT = "Thaumcraft"; 74 | } 75 | 76 | public final String ID; 77 | public final String resourceDomain; 78 | private boolean checkedMod, modLoaded; 79 | 80 | Mods(String ID) { 81 | this.ID = ID; 82 | this.resourceDomain = ID.toLowerCase(Locale.ENGLISH); 83 | } 84 | 85 | public boolean isModLoaded() { 86 | if (!checkedMod) { 87 | this.modLoaded = Loader.isModLoaded(ID); 88 | checkedMod = true; 89 | } 90 | return this.modLoaded; 91 | } 92 | 93 | public String getResourcePath(String... path) { 94 | return this.getResourceLocation(path) 95 | .toString(); 96 | } 97 | 98 | public ResourceLocation getResourceLocation(String... path) { 99 | return new ResourceLocation(this.resourceDomain, String.join("/", path)); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/mixin/BlockCaptureDrops.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.mixin; 2 | 3 | import java.util.Collections; 4 | import java.util.List; 5 | 6 | import net.minecraft.block.Block; 7 | import net.minecraft.item.ItemStack; 8 | 9 | public interface BlockCaptureDrops { 10 | 11 | public void captureDrops(); 12 | 13 | public List stopCapturingDrops(); 14 | 15 | public static void captureDrops(Block block) { 16 | if (block instanceof BlockCaptureDrops drops) drops.captureDrops(); 17 | } 18 | 19 | public static List stopCapturingDrops(Block block) { 20 | if (block instanceof BlockCaptureDrops drops) { 21 | return drops.stopCapturingDrops(); 22 | } else { 23 | return Collections.emptyList(); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/mixin/LateMixinPlugin.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.mixin; 2 | 3 | import java.util.List; 4 | import java.util.Set; 5 | 6 | import com.gtnewhorizon.gtnhmixins.ILateMixinLoader; 7 | import com.gtnewhorizon.gtnhmixins.LateMixin; 8 | 9 | @LateMixin 10 | public class LateMixinPlugin implements ILateMixinLoader { 11 | 12 | @Override 13 | public String getMixinConfig() { 14 | return "mixins.matter-manipulator.late.json"; 15 | } 16 | 17 | @Override 18 | public List getMixins(Set loadedMods) { 19 | return Mixin.getLateMixins(loadedMods); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/mixin/TargetedMod.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.mixin; 2 | 3 | import cpw.mods.fml.common.Mod; 4 | 5 | public enum TargetedMod { 6 | 7 | // NOTE: This doesn't work - late mods need a modid, not a coremod class 8 | ADVANCED_SOLAR_PANELS("Advanced Solar Panels", null, "AdvancedSolarPanel"), 9 | ANGELICA("Angelica", "com.gtnewhorizons.angelica.loading.AngelicaTweaker", "angelica"), 10 | ARCHAICFIX("ArchaicFix", "org.embeddedt.archaicfix.ArchaicCore", "archaicfix"), 11 | AUTOMAGY("Automagy", null, "Automagy"), 12 | AVARITIA_ADDONS("Avaritia Addons", null, "avaritiaddons"), 13 | BAUBLES("Baubles", null, "Baubles"), 14 | BETTERHUD("Better HUD", null, "hud"), 15 | BIBLIOCRAFT("Bibliocraft", null, "BiblioCraft"), 16 | BOP("BiomesOPlenty", null, "BiomesOPlenty"), 17 | BUGTORCH("BugTorch", "jss.bugtorch.mixinplugin.BugTorchEarlyMixins", "bugtorch"), 18 | BUKKIT("Bukkit/Thermos", "Bukkit", null), 19 | COFH_CORE("CoFHCore", "cofh.asm.LoadingPlugin", "CoFHCore"), 20 | DAMAGE_INDICATORS("Damage Indicators", null, "DamageIndicatorsMod"), 21 | EXTRATIC("ExtraTiC", null, "ExtraTiC"), 22 | EXTRA_UTILITIES("ExtraUtilities", null, "ExtraUtilities"), 23 | FASTCRAFT("FastCraft", "fastcraft.Tweaker"), 24 | GALACTICRAFT_CORE("GalacticraftCore", "micdoodle8.mods.galacticraft.core.asm.GCLoadingPlugin", "GalacticraftCore"), 25 | GT5U("GregTech5u", null, "gregtech"), // Also matches GT6. 26 | GT6("GregTech6", "gregtech.asm.GT_ASM", "gregapi"), // Can be used to exclude GT6 from the GT5U target. 27 | GTNHLIB("GTNHLib", "com.gtnewhorizon.gtnhlib.core.GTNHLibCore", "gtnhlib"), 28 | HARVESTCRAFT("harvestcraft", null, "harvestcraft"), 29 | HARVESTTHENETHER("harvestthenether", null, "harvestthenether"), 30 | HUNGER_OVERHAUL("HungerOverhaul", null, "HungerOverhaul"), 31 | IC2("IC2", "ic2.core.coremod.IC2core", "IC2"), 32 | IMMERSIVE_ENGINENEERING("Immersive Engineering", null, "ImmersiveEngineering"), 33 | JOURNEYMAP("JourneyMap", null, "journeymap"), 34 | LOTR("The Lord of the rings mod", "lotr.common.coremod.LOTRLoadingPlugin", "lotr"), 35 | LWJGL3IFY("lwjgl3ify", "me.eigenraven.lwjgl3ify.core.Lwjgl3ifyCoremod", "lwjgl3ify"), 36 | MINECHEM("Minechem", null, "minechem"), 37 | MINEFACTORY_RELOADED("MineFactory Reloaded", null, "MineFactoryReloaded"), 38 | MRTJPCORE("MrTJPCore", null, "MrTJPCoreMod"), 39 | NOTENOUGHITEMS("NotEnoughItems", "codechicken.nei.asm.NEICorePlugin", "NotEnoughItems"), 40 | OPTIFINE("Optifine", "optifine.OptiFineForgeTweaker", "Optifine"), 41 | PORTAL_GUN("PortalGun", null, "PortalGun"), 42 | PROJECT_E("ProjectE", null, "ProjectE"), 43 | RAILCRAFT("Railcraft", null, "Railcraft"), 44 | THAUMCRAFT("Thaumcraft", null, "Thaumcraft"), // "thaumcraft.codechicken.core.launch.DepLoader" 45 | THERMALDYNAMICS("Thermal Dynamics", null, "ThermalDynamics"), 46 | THERMALEXPANSION("Thermal Expansion", null, "ThermalExpansion"), 47 | TINKERSCONSTRUCT("TConstruct", null, "TConstruct"), 48 | TRAVELLERSGEAR("TravellersGear", null, "TravellersGear"), 49 | VANILLA("Minecraft", null), 50 | VOXELMAP("VoxelMap", "com.thevoxelbox.voxelmap.litemod.VoxelMapTransformer", "voxelmap"), 51 | WITCHERY("Witchery", null, "witchery"), 52 | XAEROWORLDMAP("Xaero's World Map", null, "XaeroWorldMap"), 53 | ZTONES("ZTones", null, "Ztones"); 54 | 55 | /** The "name" in the {@link Mod @Mod} annotation */ 56 | public final String modName; 57 | /** Class that implements the IFMLLoadingPlugin interface */ 58 | public final String coreModClass; 59 | /** The "modid" in the {@link Mod @Mod} annotation */ 60 | public final String modId; 61 | 62 | TargetedMod(String modName, String coreModClass) { 63 | this(modName, coreModClass, null); 64 | } 65 | 66 | TargetedMod(String modName, String coreModClass, String modId) { 67 | this.modName = modName; 68 | this.coreModClass = coreModClass; 69 | this.modId = modId; 70 | } 71 | 72 | @Override 73 | public String toString() { 74 | return "TargetedMod{modName='" + modName + "', coreModClass='" + coreModClass + "', modId='" + modId + "'}"; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/com/recursive_pineapple/matter_manipulator/server/BlockStateCommand.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.server; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Map; 6 | 7 | import net.minecraft.command.CommandBase; 8 | import net.minecraft.command.ICommandSender; 9 | import net.minecraft.entity.player.EntityPlayer; 10 | import net.minecraft.util.MovingObjectPosition.MovingObjectType; 11 | 12 | import com.recursive_pineapple.matter_manipulator.common.compat.BlockProperty; 13 | import com.recursive_pineapple.matter_manipulator.common.compat.BlockPropertyRegistry; 14 | import com.recursive_pineapple.matter_manipulator.common.utils.MMUtils; 15 | 16 | import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; 17 | 18 | public class BlockStateCommand extends CommandBase { 19 | 20 | @Override 21 | public String getCommandName() { 22 | return "state"; 23 | } 24 | 25 | @Override 26 | public String getCommandUsage(ICommandSender sender) { 27 | return "/state [property name] [property value]"; 28 | } 29 | 30 | @Override 31 | public List getCommandAliases() { 32 | return new ArrayList<>(); 33 | } 34 | 35 | @Override 36 | public void processCommand(ICommandSender sender, String[] args) { 37 | if (!(sender instanceof EntityPlayer player)) return; 38 | 39 | String action = MMUtils.getIndexSafe(args, 0); 40 | String name = MMUtils.getIndexSafe(args, 1); 41 | String value = MMUtils.getIndexSafe(args, 2); 42 | 43 | if (action == null || "set".equals(action) && name != null && value == null) { 44 | MMUtils.sendErrorToPlayer(player, getCommandUsage(sender)); 45 | return; 46 | } 47 | 48 | var hit = MMUtils.getHitResult(player, true); 49 | 50 | if (hit == null || hit.typeOfHit != MovingObjectType.BLOCK) { 51 | MMUtils.sendErrorToPlayer(player, "You must be looking at a block to use this command."); 52 | return; 53 | } 54 | 55 | Map> properties = new Object2ObjectOpenHashMap<>(); 56 | BlockPropertyRegistry.getProperties(player.worldObj, hit.blockX, hit.blockY, hit.blockZ, properties); 57 | 58 | if ("get".equals(action)) { 59 | if (name != null) { 60 | var prop = properties.get(name); 61 | 62 | if (prop == null) { 63 | MMUtils.sendErrorToPlayer(player, "Property not found."); 64 | return; 65 | } 66 | 67 | MMUtils.sendChatToPlayer(player, prop.getName() + ": " + prop.getValueAsString(player.worldObj, hit.blockX, hit.blockY, hit.blockZ)); 68 | return; 69 | } else { 70 | MMUtils.sendChatToPlayer(player, "Properties:"); 71 | 72 | if (properties.isEmpty()) { 73 | MMUtils.sendChatToPlayer(player, "None"); 74 | } else { 75 | for (var e : properties.entrySet()) { 76 | MMUtils.sendChatToPlayer( 77 | player, 78 | e.getValue().getName() + ": " + e.getValue().getValueAsString(player.worldObj, hit.blockX, hit.blockY, hit.blockZ) 79 | ); 80 | } 81 | } 82 | 83 | return; 84 | } 85 | } else { 86 | var prop = properties.get(name); 87 | 88 | if (prop == null) { 89 | MMUtils.sendErrorToPlayer(player, "Property not found."); 90 | return; 91 | } 92 | 93 | try { 94 | prop.setValueFromText(player.worldObj, hit.blockX, hit.blockY, hit.blockZ, value); 95 | } catch (Exception e) { 96 | MMUtils.sendErrorToPlayer(player, "Error setting property: " + e.getMessage()); 97 | } 98 | 99 | return; 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/mm_at.cfg: -------------------------------------------------------------------------------- 1 | public net.minecraft.nbt.NBTTagList field_74747_a # tagList 2 | public net.minecraft.nbt.NBTTagCompound field_74784_a # tagMap 3 | 4 | public net.minecraft.item.ItemReed field_150935_a # the block this fancy item places 5 | public net.minecraft.block.BlockSlab field_150004_a # whether the slab is a full block 6 | 7 | public net.minecraft.client.particle.EffectRenderer field_78876_b # fxLayers 8 | 9 | public net.minecraft.tileentity.TileEntitySkull field_145910_i # rotation 10 | 11 | public net.minecraft.item.ItemStack field_77991_e # metadata 12 | 13 | public net.minecraft.block.Block func_149642_a(Lnet/minecraft/world/World;IIILnet/minecraft/item/ItemStack;)V # dropBlockAsItem 14 | 15 | public net.minecraft.client.settings.KeyBinding func_74505_d()V # unpressKey 16 | 17 | public net.minecraft.block.Block func_149644_j(I)Lnet/minecraft/item/ItemStack; # createStackedBlock 18 | 19 | # required because of the transformer for createStackedBlock 20 | public net.minecraft.block.BlockPane func_149644_j(I)Lnet/minecraft/item/ItemStack; # createStackedBlock 21 | public net.minecraft.block.BlockQuartz func_149644_j(I)Lnet/minecraft/item/ItemStack; # createStackedBlock 22 | public net.minecraft.block.BlockLeaves func_149644_j(I)Lnet/minecraft/item/ItemStack; # createStackedBlock 23 | public net.minecraft.block.BlockRotatedPillar func_149644_j(I)Lnet/minecraft/item/ItemStack; # createStackedBlock 24 | public net.minecraft.block.BlockWoodSlab func_149644_j(I)Lnet/minecraft/item/ItemStack; # createStackedBlock 25 | public net.minecraft.block.BlockStoneSlab func_149644_j(I)Lnet/minecraft/item/ItemStack; # createStackedBlock 26 | public net.minecraft.block.BlockRedstoneOre func_149644_j(I)Lnet/minecraft/item/ItemStack; # createStackedBlock 27 | public net.minecraft.block.BlockRedstoneLight func_149644_j(I)Lnet/minecraft/item/ItemStack; # createStackedBlock 28 | public net.minecraft.block.BlockDirt func_149644_j(I)Lnet/minecraft/item/ItemStack; # createStackedBlock 29 | public net.minecraft.block.BlockSilverfish func_149644_j(I)Lnet/minecraft/item/ItemStack; # createStackedBlock 30 | -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/lang/en_US.lang: -------------------------------------------------------------------------------- 1 | 2 | tile.air.name=Air 3 | 4 | item.itemMatterManipulator0.name=Prototype Matter Manipulator 5 | item.itemMatterManipulator1.name=Matter Manipulator MKI 6 | item.itemMatterManipulator2.name=Matter Manipulator MKII 7 | item.itemMatterManipulator3.name=Matter Manipulator MKIII 8 | 9 | item.metaitem.0.name=Matter Manipulator Plan 10 | item.metaitem.1.name=Prototype Matter Manipulator Power Core 11 | item.metaitem.2.name=Prototype Matter Manipulator 'Computer' Core 12 | item.metaitem.3.name=Prototype Matter Manipulator Teleporter Core 13 | item.metaitem.4.name=Prototype Matter Manipulator Frame 14 | item.metaitem.5.name=Prototype Matter Manipulator Lens Assembly 15 | item.metaitem.6.name=Matter Manipulator Power Core MKI 16 | item.metaitem.7.name=Matter Manipulator Computer Core MKI 17 | item.metaitem.8.name=Matter Manipulator Teleporter Core MKI 18 | item.metaitem.9.name=Matter Manipulator Frame MKI 19 | item.metaitem.10.name=Matter Manipulator Lens Assembly MKI 20 | item.metaitem.11.name=Matter Manipulator Power Core MKII 21 | item.metaitem.12.name=Matter Manipulator Computer Core MKII 22 | item.metaitem.13.name=Matter Manipulator Teleporter Core MKII 23 | item.metaitem.14.name=Matter Manipulator Frame MKII 24 | item.metaitem.15.name=Matter Manipulator Lens Assembly MKII 25 | item.metaitem.16.name=Matter Manipulator Power Core MKIII 26 | item.metaitem.17.name=Matter Manipulator Computer Core MKIII 27 | item.metaitem.18.name=Matter Manipulator Teleporter Core MKIII 28 | item.metaitem.19.name=Matter Manipulator Frame MKIII 29 | item.metaitem.20.name=Matter Manipulator Lens Assembly MKIII 30 | item.metaitem.21.name=Matter Manipulator ME Downlink 31 | item.metaitem.22.name=Matter Manipulator Quantum Downlink 32 | item.metaitem.23.name=Blank Manipulator Upgrade 33 | item.metaitem.24.name=Energy Tunnel Manipulator Upgrade 34 | item.metaitem.24.desc=Allows a Matter Manipulator MKIII draw power from Laser Target Hatches or Multiamp Hatches on Quantum Uplinks 35 | item.metaitem.25.name=Excavation Manipulator Upgrade 36 | item.metaitem.25.desc=Allows a Prototype Matter Manipulator remove blocks 37 | item.metaitem.26.name=Auxiliary Teleporter Manipulator Upgrade 38 | item.metaitem.26.desc=Doubles manipulator place rate 39 | item.metaitem.27.name=Adaptive Wiring Harness Manipulator Upgrade 40 | item.metaitem.27.desc=Reduces manipulator power usage by 50% 41 | 42 | mm.upgrade.hint=Craft together with one of the following manipulators to install this upgrade 43 | 44 | mm.tooltip.voltage=%s / %s EU - Voltage: %s 45 | mm.tooltip.installed_upgrades=Installed Upgrades: 46 | 47 | mm.structure.hatch-info=Any %s Casing 48 | mm.structure.hatch-dots= (dots %s) 49 | 50 | # Keybindings 51 | key.mm=Matter Manipulator 52 | key.mm-ctrl=Control 53 | key.mm-cut=Mark Cut 54 | key.mm-copy=Mark Copy 55 | key.mm-paste=Mark Paste 56 | key.mm-reset=Reset Coords 57 | 58 | # Config 59 | interaction=Interaction 60 | rendering=Rendering 61 | debug=Debug 62 | building=Building 63 | 64 | # NEI 65 | mm.recipe.upgrades=Manipulator Upgrades 66 | -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/shaders/fancybox.frag.glsl: -------------------------------------------------------------------------------- 1 | #version 120 2 | 3 | uniform float time; 4 | 5 | varying vec4 v_Colour; 6 | 7 | void main() { 8 | float t = time / 2.5 * 2 * 3.14159; 9 | 10 | float theta = ((gl_TexCoord[0].x + gl_TexCoord[0].y) * 5.0); 11 | float k = (sin(theta + t) + 1) * 0.5 + 0.25; 12 | 13 | gl_FragColor = mix(v_Colour * 0.25, v_Colour, k); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/shaders/fancybox.vert.glsl: -------------------------------------------------------------------------------- 1 | #version 120 2 | 3 | varying vec4 v_Colour; 4 | 5 | void main() { 6 | gl_TexCoord[0] = gl_MultiTexCoord0; 7 | v_Colour = gl_Color; 8 | 9 | gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 10 | } 11 | -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/blocks/machines/uplink/OVERLAY_FRONT_ACTIVE_GLOW.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/src/main/resources/assets/matter-manipulator/textures/blocks/machines/uplink/OVERLAY_FRONT_ACTIVE_GLOW.png -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/blocks/machines/uplink/OVERLAY_FRONT_ACTIVE_GLOW.png.mcmeta: -------------------------------------------------------------------------------- 1 | { 2 | "animation": { 3 | "frametime": 1 4 | } 5 | } 6 | 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/blocks/machines/uplink/OVERLAY_FRONT_IDLE_GLOW.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/src/main/resources/assets/matter-manipulator/textures/blocks/machines/uplink/OVERLAY_FRONT_IDLE_GLOW.png -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/blocks/machines/uplink/OVERLAY_FRONT_IDLE_GLOW.png.mcmeta: -------------------------------------------------------------------------------- 1 | { 2 | "animation": { 3 | "frametime": 30 4 | } 5 | } 6 | 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/blocks/machines/uplink/OVERLAY_FRONT_OFF.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/src/main/resources/assets/matter-manipulator/textures/blocks/machines/uplink/OVERLAY_FRONT_OFF.png -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/itemMatterManipulator0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/src/main/resources/assets/matter-manipulator/textures/items/itemMatterManipulator0.png -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/itemMatterManipulator1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/src/main/resources/assets/matter-manipulator/textures/items/itemMatterManipulator1.png -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/itemMatterManipulator2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/src/main/resources/assets/matter-manipulator/textures/items/itemMatterManipulator2.png -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/itemMatterManipulator3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/src/main/resources/assets/matter-manipulator/textures/items/itemMatterManipulator3.png -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/metaitem/0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/src/main/resources/assets/matter-manipulator/textures/items/metaitem/0.png -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/metaitem/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/src/main/resources/assets/matter-manipulator/textures/items/metaitem/1.png -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/metaitem/1.png.mcmeta: -------------------------------------------------------------------------------- 1 | { 2 | "animation": { 3 | "frametime": 30 4 | } 5 | } 6 | 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/metaitem/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/src/main/resources/assets/matter-manipulator/textures/items/metaitem/10.png -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/metaitem/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/src/main/resources/assets/matter-manipulator/textures/items/metaitem/11.png -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/metaitem/11.png.mcmeta: -------------------------------------------------------------------------------- 1 | { 2 | "animation": { 3 | "frametime": 30 4 | } 5 | } 6 | 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/metaitem/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/src/main/resources/assets/matter-manipulator/textures/items/metaitem/12.png -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/metaitem/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/src/main/resources/assets/matter-manipulator/textures/items/metaitem/13.png -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/metaitem/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/src/main/resources/assets/matter-manipulator/textures/items/metaitem/14.png -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/metaitem/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/src/main/resources/assets/matter-manipulator/textures/items/metaitem/15.png -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/metaitem/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/src/main/resources/assets/matter-manipulator/textures/items/metaitem/16.png -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/metaitem/16.png.mcmeta: -------------------------------------------------------------------------------- 1 | { 2 | "animation": { 3 | "frametime": 30 4 | } 5 | } 6 | 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/metaitem/17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/src/main/resources/assets/matter-manipulator/textures/items/metaitem/17.png -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/metaitem/18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/src/main/resources/assets/matter-manipulator/textures/items/metaitem/18.png -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/metaitem/19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/src/main/resources/assets/matter-manipulator/textures/items/metaitem/19.png -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/metaitem/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/src/main/resources/assets/matter-manipulator/textures/items/metaitem/2.png -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/metaitem/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/src/main/resources/assets/matter-manipulator/textures/items/metaitem/20.png -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/metaitem/21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/src/main/resources/assets/matter-manipulator/textures/items/metaitem/21.png -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/metaitem/22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/src/main/resources/assets/matter-manipulator/textures/items/metaitem/22.png -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/metaitem/23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/src/main/resources/assets/matter-manipulator/textures/items/metaitem/23.png -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/metaitem/24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/src/main/resources/assets/matter-manipulator/textures/items/metaitem/24.png -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/metaitem/25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/src/main/resources/assets/matter-manipulator/textures/items/metaitem/25.png -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/metaitem/26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/src/main/resources/assets/matter-manipulator/textures/items/metaitem/26.png -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/metaitem/27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/src/main/resources/assets/matter-manipulator/textures/items/metaitem/27.png -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/metaitem/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/src/main/resources/assets/matter-manipulator/textures/items/metaitem/3.png -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/metaitem/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/src/main/resources/assets/matter-manipulator/textures/items/metaitem/4.png -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/metaitem/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/src/main/resources/assets/matter-manipulator/textures/items/metaitem/5.png -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/metaitem/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/src/main/resources/assets/matter-manipulator/textures/items/metaitem/6.png -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/metaitem/6.png.mcmeta: -------------------------------------------------------------------------------- 1 | { 2 | "animation": { 3 | "frametime": 30 4 | } 5 | } 6 | 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/metaitem/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/src/main/resources/assets/matter-manipulator/textures/items/metaitem/7.png -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/metaitem/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/src/main/resources/assets/matter-manipulator/textures/items/metaitem/8.png -------------------------------------------------------------------------------- /src/main/resources/assets/matter-manipulator/textures/items/metaitem/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RecursivePineapple/MatterManipulator/2cf39c459f0248beb983feb5725a3598167efe47/src/main/resources/assets/matter-manipulator/textures/items/metaitem/9.png -------------------------------------------------------------------------------- /src/main/resources/mcmod.info: -------------------------------------------------------------------------------- 1 | { 2 | "modListVersion": 2, 3 | "modList": [{ 4 | "modid": "${modId}", 5 | "name": "${modName}", 6 | "description": "A mod that helps reduce world-edit use in survival.", 7 | "version": "${modVersion}", 8 | "mcversion": "${minecraftVersion}", 9 | "url": "https://github.com/RecursivePineapple/MatterManipulator", 10 | "updateUrl": "", 11 | "authorList": ["Recursive Pineapple"], 12 | "credits": "", 13 | "logoFile": "", 14 | "screenshots": [], 15 | "parent": "", 16 | "requiredMods": [], 17 | "dependencies": [], 18 | "dependants": [], 19 | "useDependencyInformation": false 20 | }] 21 | } 22 | -------------------------------------------------------------------------------- /src/main/resources/mixins.matter-manipulator.early.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "minVersion": "0.8.5-GTNH", 4 | "package": "com.recursive_pineapple.matter_manipulator.mixin.mixins.early", 5 | "refmap": "mixins.matter-manipulator.refmap.json", 6 | "target": "@env(DEFAULT)", 7 | "compatibilityLevel": "JAVA_8", 8 | "mixins": [], 9 | "client": [], 10 | "server": [] 11 | } 12 | -------------------------------------------------------------------------------- /src/main/resources/mixins.matter-manipulator.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "minVersion": "0.8.5-GTNH", 4 | "refmap": "mixins.matter-manipulator.refmap.json", 5 | "target": "@env(DEFAULT)", 6 | "compatibilityLevel": "JAVA_8", 7 | "mixins": [], 8 | "client": [], 9 | "server": [] 10 | } 11 | -------------------------------------------------------------------------------- /src/main/resources/mixins.matter-manipulator.late.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "minVersion": "0.8.5-GTNH", 4 | "package": "com.recursive_pineapple.matter_manipulator.mixin.mixins.late", 5 | "refmap": "mixins.matter-manipulator.refmap.json", 6 | "target": "@env(DEFAULT)", 7 | "compatibilityLevel": "JAVA_8", 8 | "mixins": [], 9 | "client": [], 10 | "server": [] 11 | } 12 | -------------------------------------------------------------------------------- /src/main/resources/pack.mcmeta: -------------------------------------------------------------------------------- 1 | { 2 | "pack": { 3 | "pack_format": 1, 4 | "description": "Resources used for the Matter Manipulator mod" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/mixin/java/com/recursive_pineapple/matter_manipulator/mixin/mixins/early/MixinBlockDropCapturing.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.mixin.mixins.early; 2 | 3 | import java.util.List; 4 | 5 | import net.minecraft.block.Block; 6 | import net.minecraft.item.ItemStack; 7 | 8 | import com.recursive_pineapple.matter_manipulator.mixin.BlockCaptureDrops; 9 | 10 | import org.spongepowered.asm.mixin.Mixin; 11 | import org.spongepowered.asm.mixin.Shadow; 12 | 13 | @Mixin(Block.class) 14 | public abstract class MixinBlockDropCapturing implements BlockCaptureDrops { 15 | 16 | @Shadow(remap = false) 17 | protected abstract List captureDrops(boolean start); 18 | 19 | @Override 20 | public void captureDrops() { 21 | captureDrops(true); 22 | } 23 | 24 | @Override 25 | public List stopCapturingDrops() { 26 | return captureDrops(false); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/mixin/java/com/recursive_pineapple/matter_manipulator/mixin/mixins/early/MixinKeyBinding.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.mixin.mixins.early; 2 | 3 | import net.minecraft.client.settings.KeyBinding; 4 | import net.minecraft.entity.player.EntityPlayer; 5 | import net.minecraft.item.ItemStack; 6 | 7 | import com.llamalad7.mixinextras.injector.ModifyReturnValue; 8 | import com.recursive_pineapple.matter_manipulator.MMMod; 9 | import com.recursive_pineapple.matter_manipulator.common.items.manipulator.ItemMatterManipulator; 10 | import com.recursive_pineapple.matter_manipulator.common.items.manipulator.MMKeyInputs; 11 | 12 | import org.spongepowered.asm.mixin.Mixin; 13 | import org.spongepowered.asm.mixin.injection.At; 14 | 15 | /** 16 | * Cancel mm key presses for conflicting keybinds when the player is holding a manipulator. 17 | */ 18 | @Mixin(KeyBinding.class) 19 | public class MixinKeyBinding { 20 | 21 | @ModifyReturnValue(method = "getIsKeyPressed", at = @At("RETURN")) 22 | public boolean mm$cancelGetIsKeyPressed(boolean pressed) { 23 | KeyBinding self = (KeyBinding) (Object) this; 24 | 25 | if (self == MMKeyInputs.CONTROL) return pressed; 26 | if (self == MMKeyInputs.CUT) return pressed; 27 | if (self == MMKeyInputs.COPY) return pressed; 28 | if (self == MMKeyInputs.PASTE) return pressed; 29 | if (self == MMKeyInputs.RESET) return pressed; 30 | 31 | if (MMKeyInputs.CONTROL.getKeyCode() == 0 || MMKeyInputs.CONTROL.getIsKeyPressed()) { 32 | EntityPlayer player = MMMod.proxy.getThePlayer(); 33 | 34 | if (player != null) { 35 | ItemStack held = player.getHeldItem(); 36 | 37 | if (held != null && held.getItem() instanceof ItemMatterManipulator) { 38 | if (self.getKeyCode() == MMKeyInputs.CUT.getKeyCode()) return false; 39 | if (self.getKeyCode() == MMKeyInputs.COPY.getKeyCode()) return false; 40 | if (self.getKeyCode() == MMKeyInputs.PASTE.getKeyCode()) return false; 41 | if (self.getKeyCode() == MMKeyInputs.RESET.getKeyCode()) return false; 42 | } 43 | } 44 | } 45 | 46 | return pressed; 47 | } 48 | 49 | @ModifyReturnValue(method = "isPressed", at = @At("RETURN")) 50 | public boolean mm$cancelIsPressed(boolean pressed) { 51 | KeyBinding self = (KeyBinding) (Object) this; 52 | 53 | if (self == MMKeyInputs.CONTROL) return pressed; 54 | if (self == MMKeyInputs.CUT) return pressed; 55 | if (self == MMKeyInputs.COPY) return pressed; 56 | if (self == MMKeyInputs.PASTE) return pressed; 57 | if (self == MMKeyInputs.RESET) return pressed; 58 | 59 | if (MMKeyInputs.CONTROL.getKeyCode() == 0 || MMKeyInputs.CONTROL.getIsKeyPressed()) { 60 | EntityPlayer player = MMMod.proxy.getThePlayer(); 61 | 62 | if (player != null) { 63 | ItemStack held = player.getHeldItem(); 64 | 65 | if (held != null && held.getItem() instanceof ItemMatterManipulator) { 66 | if (self.getKeyCode() == MMKeyInputs.CUT.getKeyCode()) return false; 67 | if (self.getKeyCode() == MMKeyInputs.COPY.getKeyCode()) return false; 68 | if (self.getKeyCode() == MMKeyInputs.PASTE.getKeyCode()) return false; 69 | if (self.getKeyCode() == MMKeyInputs.RESET.getKeyCode()) return false; 70 | } 71 | } 72 | } 73 | 74 | return pressed; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/mixin/java/com/recursive_pineapple/matter_manipulator/mixin/mixins/late/MixinBlockExtremeAutoCrafter.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.mixin.mixins.late; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | 6 | import net.minecraft.block.Block; 7 | import net.minecraft.block.BlockContainer; 8 | import net.minecraft.block.material.Material; 9 | import net.minecraft.item.ItemStack; 10 | import net.minecraft.nbt.NBTTagCompound; 11 | import net.minecraft.world.World; 12 | 13 | 14 | import org.spongepowered.asm.mixin.Mixin; 15 | import org.spongepowered.asm.mixin.Overwrite; 16 | import org.spongepowered.asm.mixin.Unique; 17 | 18 | import wanion.avaritiaddons.block.extremeautocrafter.BlockExtremeAutoCrafter; 19 | import wanion.avaritiaddons.block.extremeautocrafter.TileEntityExtremeAutoCrafter; 20 | 21 | @Mixin(BlockExtremeAutoCrafter.class) 22 | public abstract class MixinBlockExtremeAutoCrafter extends BlockContainer { 23 | 24 | @Unique 25 | protected ThreadLocal tile = new ThreadLocal<>(); 26 | 27 | protected MixinBlockExtremeAutoCrafter(Material p_i45386_1_) { 28 | super(p_i45386_1_); 29 | } 30 | 31 | /** 32 | * @author Recursive Pineapple 33 | * @reason Because this is shrimple 34 | */ 35 | @Overwrite 36 | public final void breakBlock(final World world, final int x, final int y, final int z, final Block block, final int metadata) { 37 | final TileEntityExtremeAutoCrafter tileEntityExtremeAutoCrafter = (TileEntityExtremeAutoCrafter) world.getTileEntity(x, y, z); 38 | 39 | // never unset because we can't guarantee when getDrops will be called (sorry GC :tootroll:) 40 | tile.set(tileEntityExtremeAutoCrafter); 41 | 42 | super.breakBlock(world, x, y, z, block, metadata); 43 | world.func_147453_f(x, y, z, block); 44 | } 45 | 46 | /** 47 | * @author Recursive Pineapple 48 | * @reason Because it doesn't make sense to inject into this 49 | */ 50 | @Override 51 | public ArrayList getDrops(World world, int x, int y, int z, int metadata, int fortune) { 52 | final ItemStack droppedStack = new ItemStack(this, 1, 0); 53 | 54 | final TileEntityExtremeAutoCrafter tile = world.getTileEntity(x, y, z) instanceof TileEntityExtremeAutoCrafter t ? t : this.tile.get(); 55 | 56 | if (tile != null && tile.xCoord == x && tile.yCoord == y && tile.zCoord == z) { 57 | droppedStack.setTagCompound(tile.writeCustomNBT(new NBTTagCompound())); 58 | this.tile.set(null); 59 | } 60 | 61 | return new ArrayList<>(Arrays.asList(droppedStack)); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/test/java/com/recursive_pineapple/matter_manipulator/common/UtilsTests.java: -------------------------------------------------------------------------------- 1 | package com.recursive_pineapple.matter_manipulator.common; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import net.minecraft.nbt.NBTTagCompound; 6 | import net.minecraft.nbt.NBTTagList; 7 | 8 | import com.recursive_pineapple.matter_manipulator.common.utils.MMUtils; 9 | 10 | import org.junit.jupiter.api.Test; 11 | 12 | class UtilsTests { 13 | 14 | @Test 15 | void testNBTExact() { 16 | NBTTagCompound tag = new NBTTagCompound(); 17 | tag.setByte("a", (byte) 0xF0); 18 | tag.setShort("b", (short) 0xF0F0); 19 | tag.setInteger("c", 0xF0F0F0F0); 20 | tag.setLong("d", 0xF0F0F0F0F0F0F0F0l); 21 | tag.setFloat("e", 123.456f); 22 | tag.setDouble("f", 123.456); 23 | tag.setString("g", "hello world"); 24 | tag.setIntArray("h", new int[] { 25 | 1, 2, 3, 4, 5 26 | }); 27 | tag.setByteArray("i", new byte[] { 28 | 1, 2, 3, 4, 5 29 | }); 30 | 31 | NBTTagList list = new NBTTagList(); 32 | list.appendTag(tag); 33 | 34 | assertEquals(list, MMUtils.toNbtExact(MMUtils.toJsonObjectExact(list))); 35 | } 36 | } 37 | --------------------------------------------------------------------------------