From 09877d091a238e6c0ca7f4f3973e16beb2c04e3a Mon Sep 17 00:00:00 2001 From: Krxwallo Date: Thu, 20 Aug 2020 17:40:05 +0200 Subject: [PATCH 01/11] Ported to Fabric 1.16.X --- CREDITS.txt | 66 +--- build.gradle | 133 +++---- gradle.properties | 21 +- gradle/wrapper/gradle-wrapper.jar | Bin 54708 -> 58694 bytes gradle/wrapper/gradle-wrapper.properties | 4 +- gradlew | 51 ++- gradlew.bat | 21 +- settings.gradle | 10 + .../mrcrayfish/glasscutter/GlassCutter.java | 23 -- .../glasscutter/GlassCutterMain.java | 25 ++ .../block/AbstractGlassSlabBlock.java | 48 +-- .../block/AbstractGlassStairsBlock.java | 41 +- .../glasscutter/block/GlassSlabBlock.java | 4 +- .../glasscutter/block/GlassStairsBlock.java | 5 +- .../glasscutter/block/GlasscutterBlock.java | 159 ++++---- .../block/StainedGlassSlabBlock.java | 17 +- .../block/StainedGlassStairsBlock.java | 10 +- .../glasscutter/client/ClientHandler.java | 79 ++-- .../screen/inventory/GlasscutterScreen.java | 366 +++++++++--------- .../glasscutter/init/ModBlocks.java | 171 ++++---- .../glasscutter/init/ModContainers.java | 41 -- .../init/ModRecipeSerializers.java | 42 +- .../glasscutter/init/ModRecipeTypes.java | 20 + .../glasscutter/init/ModScreenHandlers.java | 19 + .../mrcrayfish/glasscutter/init/ModStats.java | 23 ++ .../container/GlasscutterContainer.java | 274 ------------- .../item/crafting/GlasscuttingRecipe.java | 130 +++---- .../glasscutter/item/crafting/RecipeType.java | 27 -- .../glasscutter/jei/GlassCutterJeiPlugin.java | 92 ----- .../jei/GlasscuttingRecipeCategory.java | 90 ----- .../GlasscutterScreenHandler.java | 235 +++++++++++ .../assets/glasscutter/lang/en_us.json | 4 +- src/main/resources/fabric.mod.json | 35 ++ 33 files changed, 1005 insertions(+), 1281 deletions(-) create mode 100644 settings.gradle delete mode 100644 src/main/java/com/mrcrayfish/glasscutter/GlassCutter.java create mode 100644 src/main/java/com/mrcrayfish/glasscutter/GlassCutterMain.java delete mode 100644 src/main/java/com/mrcrayfish/glasscutter/init/ModContainers.java create mode 100644 src/main/java/com/mrcrayfish/glasscutter/init/ModRecipeTypes.java create mode 100644 src/main/java/com/mrcrayfish/glasscutter/init/ModScreenHandlers.java create mode 100644 src/main/java/com/mrcrayfish/glasscutter/init/ModStats.java delete mode 100644 src/main/java/com/mrcrayfish/glasscutter/inventory/container/GlasscutterContainer.java delete mode 100644 src/main/java/com/mrcrayfish/glasscutter/item/crafting/RecipeType.java delete mode 100644 src/main/java/com/mrcrayfish/glasscutter/jei/GlassCutterJeiPlugin.java delete mode 100644 src/main/java/com/mrcrayfish/glasscutter/jei/GlasscuttingRecipeCategory.java create mode 100644 src/main/java/com/mrcrayfish/glasscutter/screen_handler/GlasscutterScreenHandler.java create mode 100644 src/main/resources/fabric.mod.json diff --git a/CREDITS.txt b/CREDITS.txt index a70c53d..ae7b41b 100644 --- a/CREDITS.txt +++ b/CREDITS.txt @@ -1,65 +1 @@ -Minecraft Forge: Credits/Thank You - -Forge is a set of tools and modifications to the Minecraft base game code to assist -mod developers in creating new and exciting content. It has been in development for -several years now, but I would like to take this time thank a few people who have -helped it along it's way. - -First, the people who originally created the Forge projects way back in Minecraft -alpha. Eloraam of RedPower, and SpaceToad of Buildcraft, without their acceptiance -of me taking over the project, who knows what Minecraft modding would be today. - -Secondly, someone who has worked with me, and developed some of the core features -that allow modding to be as functional, and as simple as it is, cpw. For developing -FML, which stabelized the client and server modding ecosystem. As well as the base -loading system that allows us to modify Minecraft's code as elegently as possible. - -Mezz, who has stepped up as the issue and pull request manager. Helping to keep me -sane as well as guiding the community into creating better additions to Forge. - -Searge, Bspks, Fesh0r, ProfMobious, and all the rest over on the MCP team {of which -I am a part}. For creating some of the core tools needed to make Minecraft modding -both possible, and as stable as can be. - On that note, here is some specific information of the MCP data we use: - * Minecraft Coder Pack (MCP) * - Forge Mod Loader and Minecraft Forge have permission to distribute and automatically - download components of MCP and distribute MCP data files. This permission is not - transitive and others wishing to redistribute the Minecraft Forge source independently - should seek permission of MCP or remove the MCP data files and request their users - to download MCP separately. - -And lastly, the countless community members who have spent time submitting bug reports, -pull requests, and just helping out the community in general. Thank you. - ---LexManos - -========================================================================= - -This is Forge Mod Loader. - -You can find the source code at all times at https://github.com/MinecraftForge/MinecraftForge/tree/1.12.x/src/main/java/net/minecraftforge/fml - -This minecraft mod is a clean open source implementation of a mod loader for minecraft servers -and minecraft clients. - -The code is authored by cpw. - -It began by partially implementing an API defined by the client side ModLoader, authored by Risugami. -http://www.minecraftforum.net/topic/75440- -This support has been dropped as of Minecraft release 1.7, as Risugami no longer maintains ModLoader. - -It also contains suggestions and hints and generous helpings of code from LexManos, author of MinecraftForge. -http://www.minecraftforge.net/ - -Additionally, it contains an implementation of topological sort based on that -published at http://keithschwarz.com/interesting/code/?dir=topological-sort - -It also contains code from the Maven project for performing versioned dependency -resolution. http://maven.apache.org/ - -It also contains a partial repackaging of the javaxdelta library from http://sourceforge.net/projects/javaxdelta/ -with credit to it's authors. - -Forge Mod Loader downloads components from the Minecraft Coder Pack -(http://mcp.ocean-labs.de/index.php/Main_Page) with kind permission from the MCP team. - +@DarkestArgentum on Twitter for ideas \ No newline at end of file diff --git a/build.gradle b/build.gradle index 0000331..6145ac5 100644 --- a/build.gradle +++ b/build.gradle @@ -1,90 +1,77 @@ -buildscript { - repositories { - maven { url = 'https://files.minecraftforge.net/maven' } - jcenter() - mavenCentral() - } - dependencies { - classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '3.+', changing: true - } +plugins { + id 'fabric-loom' version '0.4-SNAPSHOT' + id 'maven-publish' } -apply plugin: 'net.minecraftforge.gradle' -apply plugin: 'eclipse' -version = '1.1.0-1.16.1' -group = 'com.mrcrayfish' -archivesBaseName = 'glasscutter' +sourceCompatibility = JavaVersion.VERSION_1_8 +targetCompatibility = JavaVersion.VERSION_1_8 -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' // Need this here so eclipse task generates correctly. +archivesBaseName = project.archives_base_name +version = project.mod_version +group = project.maven_group -minecraft { - mappings channel: 'snapshot', version: '20200514-1.16' - runs { - client { - workingDirectory project.file('run') - property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP' - property 'forge.logging.console.level', 'debug' - mods { - examplemod { - source sourceSets.main - } - } - } +dependencies { + //to change the versions see the gradle.properties file + minecraft "com.mojang:minecraft:${project.minecraft_version}" + mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" + modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" - server { - workingDirectory project.file('run') - property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP' - property 'forge.logging.console.level', 'debug' - mods { - examplemod { - source sourceSets.main - } - } - } + // Fabric API. This is technically optional, but you probably want it anyway. + modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" - data { - workingDirectory project.file('run') - property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP' - property 'forge.logging.console.level', 'debug' - args '--mod', 'examplemod', '--all', '--output', file('src/generated/resources/') - mods { - examplemod { - source sourceSets.main - } - } - } - } + // PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs. + // You may need to force-disable transitiveness on them. } -repositories { - maven { - // location of the maven that hosts JEI files - name = "Progwml6 maven" - url = "https://dvs1.progwml6.com/files/maven/" +processResources { + inputs.property "version", project.version + + from(sourceSets.main.resources.srcDirs) { + include "fabric.mod.json" + expand "version": project.version } - maven { - // location of a maven mirror for JEI files, as a fallback - name = "ModMaven" - url = "https://modmaven.k-4u.nl" + + from(sourceSets.main.resources.srcDirs) { + exclude "fabric.mod.json" } } -dependencies { - minecraft "net.minecraftforge:forge:${mc_version}-32.0.108" +// ensure that the encoding is set to UTF-8, no matter what the system default is +// this fixes some edge cases with special characters not displaying correctly +// see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html +tasks.withType(JavaCompile) { + options.encoding = "UTF-8" +} - compile fg.deobf("mezz.jei:jei-${mc_version}:${jei_version}") +// Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task +// if it is present. +// If you remove this task, sources will not be generated. +task sourcesJar(type: Jar, dependsOn: classes) { + classifier = "sources" + from sourceSets.main.allSource } jar { - manifest { - attributes([ - "Specification-Title": "Glasscutter", - "Specification-Vendor": "MrCrayfish", - "Specification-Version": "1", // We are version 1 of ourselves - "Implementation-Title": project.name, - "Implementation-Version": "${version}", - "Implementation-Vendor" : "MrCrayfish", - "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") - ]) + from "LICENSE" +} + +// configure the maven publication +publishing { + publications { + mavenJava(MavenPublication) { + // add all the jars that should be included when publishing to maven + artifact(remapJar) { + builtBy remapJar + } + artifact(sourcesJar) { + builtBy remapSourcesJar + } + } + } + + // select the repositories you want to publish to + repositories { + // uncomment to publish to the local maven + // mavenLocal() } -} \ No newline at end of file +} diff --git a/gradle.properties b/gradle.properties index fef192b..5c3ed3a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,17 @@ -org.gradle.jvmargs=-Xmx3G -org.gradle.daemon=false -mc_version=1.16.1 -jei_version=7.0.1.10 \ No newline at end of file +# Done to increase the memory available to gradle. +org.gradle.jvmargs=-Xmx1G + +# Fabric Properties +# check these on https://fabricmc.net/use +minecraft_version=1.16.2 +yarn_mappings=1.16.2+build.1 +loader_version=0.9.1+build.205 + +# Mod Properties +mod_version = 1.0.1-1.16.1-fabric +maven_group = com.mrcrayfish +archives_base_name = glasscutter + +# Dependencies +# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api +fabric_version=0.17.2+build.396-1.16 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 7a3265ee94c0ab25cf079ac8ccdf87f41d455d42..490fda8577df6c95960ba7077c43220e5bb2c0d9 100644 GIT binary patch literal 58694 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 literal 54708 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

_x$+l{{cH8$W#CT diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 949819d..9543e93 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip +zipStorePath=wrapper/dists \ No newline at end of file diff --git a/gradlew b/gradlew index cccdd3d..2fe81a7 100644 --- a/gradlew +++ b/gradlew @@ -1,5 +1,21 @@ #!/usr/bin/env sh +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + ############################################################################## ## ## Gradle start up script for UN*X @@ -28,7 +44,7 @@ APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" @@ -109,8 +125,8 @@ if $darwin; then GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" fi -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` JAVACMD=`cygpath --unix "$JAVACMD"` @@ -138,19 +154,19 @@ if $cygwin ; then else eval `echo args$i`="\"$arg\"" fi - i=$((i+1)) + i=`expr $i + 1` done case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; esac fi @@ -159,14 +175,9 @@ save () { for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done echo " " } -APP_ARGS=$(save "$@") +APP_ARGS=`save "$@"` # Collect all arguments for the java command, following the shell quoting and substitution rules eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi - exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index f955316..62bd9b9 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,3 +1,19 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @@ -13,8 +29,11 @@ if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..5b60df3 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,10 @@ +pluginManagement { + repositories { + jcenter() + maven { + name = 'Fabric' + url = 'https://maven.fabricmc.net/' + } + gradlePluginPortal() + } +} diff --git a/src/main/java/com/mrcrayfish/glasscutter/GlassCutter.java b/src/main/java/com/mrcrayfish/glasscutter/GlassCutter.java deleted file mode 100644 index 941221d..0000000 --- a/src/main/java/com/mrcrayfish/glasscutter/GlassCutter.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.mrcrayfish.glasscutter; - -import com.mrcrayfish.glasscutter.client.ClientHandler; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; -import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; - -/** - * Author: MrCrayfish - */ -@Mod(Reference.MOD_ID) -public class GlassCutter -{ - public GlassCutter() - { - FMLJavaModLoadingContext.get().getModEventBus().addListener(this::onSetupClient); - } - - private void onSetupClient(FMLClientSetupEvent event) - { - ClientHandler.setup(); - } -} diff --git a/src/main/java/com/mrcrayfish/glasscutter/GlassCutterMain.java b/src/main/java/com/mrcrayfish/glasscutter/GlassCutterMain.java new file mode 100644 index 0000000..465e0f0 --- /dev/null +++ b/src/main/java/com/mrcrayfish/glasscutter/GlassCutterMain.java @@ -0,0 +1,25 @@ +package com.mrcrayfish.glasscutter; + +import com.mrcrayfish.glasscutter.client.ClientHandler; +import com.mrcrayfish.glasscutter.init.ModBlocks; +import com.mrcrayfish.glasscutter.init.ModRecipeSerializers; +import com.mrcrayfish.glasscutter.init.ModRecipeTypes; +import com.mrcrayfish.glasscutter.init.ModScreenHandlers; +import net.fabricmc.api.ModInitializer; + +/** + * Main Mod Class. + * @author justAm0dd3r + */ +public class GlassCutterMain implements ModInitializer +{ + @Override + public void onInitialize() { + ModBlocks.tryRegisterAll(); + ModScreenHandlers.registerAll(); + ModRecipeTypes.registerAll(); + ModRecipeSerializers.registerAll(); + + ClientHandler.setup(); + } +} diff --git a/src/main/java/com/mrcrayfish/glasscutter/block/AbstractGlassSlabBlock.java b/src/main/java/com/mrcrayfish/glasscutter/block/AbstractGlassSlabBlock.java index ffebf46..3318818 100644 --- a/src/main/java/com/mrcrayfish/glasscutter/block/AbstractGlassSlabBlock.java +++ b/src/main/java/com/mrcrayfish/glasscutter/block/AbstractGlassSlabBlock.java @@ -1,58 +1,48 @@ package com.mrcrayfish.glasscutter.block; -import net.minecraft.block.BlockState; -import net.minecraft.block.SlabBlock; -import net.minecraft.util.Direction; +import com.mrcrayfish.glasscutter.init.ModBlocks; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.block.*; +import net.minecraft.block.enums.BlockHalf; +import net.minecraft.block.enums.SlabType; import net.minecraft.util.math.BlockPos; -import net.minecraft.world.IBlockReader; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; - -import java.util.function.Supplier; +import net.minecraft.util.math.Direction; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.util.shape.VoxelShapes; +import net.minecraft.world.BlockView; /** * Author: MrCrayfish */ public class AbstractGlassSlabBlock extends SlabBlock { - private final Supplier state; + private final BlockState state; - public AbstractGlassSlabBlock(Supplier state, Properties properties) + public AbstractGlassSlabBlock(BlockState state, Settings settings) { - super(properties); + super(settings.nonOpaque().allowsSpawning((a, b, c, d) -> false)); this.state = state; } @Override - public boolean isTransparent(BlockState state) - { - return true; + public VoxelShape getVisualShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + return VoxelShapes.empty(); } - // Help, what should I use instead???! @Override - @OnlyIn(Dist.CLIENT) - public boolean isSideInvisible(BlockState state, BlockState adjacentState, Direction side) - { - return (adjacentState.getBlock() == this && adjacentState.get(TYPE) == state.get(TYPE)) || adjacentState.getBlock() == this.state.get().getBlock() || super.isSideInvisible(state, adjacentState, side); + public boolean isTranslucent(BlockState state, BlockView world, BlockPos pos) { + return true; } - // Help, what should I use instead???! @Override - @OnlyIn(Dist.CLIENT) - public float getAmbientOcclusionLightValue(BlockState state, IBlockReader worldIn, BlockPos pos) + public float getAmbientOcclusionLightLevel(BlockState state, BlockView worldIn, BlockPos pos) { return 1.0F; } @Override - public boolean propagatesSkylightDown(BlockState state, IBlockReader reader, BlockPos pos) - { - return true; - } - - @Override - public boolean canSpawnInBlock() { + public boolean canMobSpawnInside() { return false; } } diff --git a/src/main/java/com/mrcrayfish/glasscutter/block/AbstractGlassStairsBlock.java b/src/main/java/com/mrcrayfish/glasscutter/block/AbstractGlassStairsBlock.java index 933b427..a6f70b9 100644 --- a/src/main/java/com/mrcrayfish/glasscutter/block/AbstractGlassStairsBlock.java +++ b/src/main/java/com/mrcrayfish/glasscutter/block/AbstractGlassStairsBlock.java @@ -1,37 +1,38 @@ package com.mrcrayfish.glasscutter.block; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; import net.minecraft.block.BlockState; import net.minecraft.block.StairsBlock; -import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; -import net.minecraft.world.IBlockReader; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; - -import java.util.function.Supplier; +import net.minecraft.util.math.Direction; +import net.minecraft.world.BlockView; /** * Author: MrCrayfish */ public class AbstractGlassStairsBlock extends StairsBlock { - private final Supplier state; + private final BlockState state; - public AbstractGlassStairsBlock(Supplier state, Properties properties) + public AbstractGlassStairsBlock(BlockState state, Settings settings) { - super(state, properties); + super(state, settings.nonOpaque().allowsSpawning((a, b, c, d) -> false)); this.state = state; } @Override - public boolean isTransparent(BlockState state) - { + public boolean isTranslucent(BlockState state, BlockView world, BlockPos pos) { return true; } - // Help, what should I use instead???! @Override - @OnlyIn(Dist.CLIENT) + public boolean hasSidedTransparency(BlockState state) { + return true; + } + + @Override + @Environment(EnvType.CLIENT) public boolean isSideInvisible(BlockState state, BlockState adjacentState, Direction side) { if(adjacentState.getBlock() == this && adjacentState.get(HALF) == state.get(HALF)) @@ -41,7 +42,7 @@ public boolean isSideInvisible(BlockState state, BlockState adjacentState, Direc return true; } } - if(adjacentState.getBlock() == this.state.get().getBlock()) + if(adjacentState.getBlock() == this.state.getBlock()) { return true; } @@ -50,20 +51,14 @@ public boolean isSideInvisible(BlockState state, BlockState adjacentState, Direc // Help, what should I use instead???! @Override - @OnlyIn(Dist.CLIENT) - public float getAmbientOcclusionLightValue(BlockState state, IBlockReader worldIn, BlockPos pos) + @Environment(EnvType.CLIENT) + public float getAmbientOcclusionLightLevel(BlockState state, BlockView worldIn, BlockPos pos) { return 1.0F; } @Override - public boolean propagatesSkylightDown(BlockState state, IBlockReader reader, BlockPos pos) - { + public boolean canMobSpawnInside() { return true; } - - @Override - public boolean canSpawnInBlock() { - return false; - } } diff --git a/src/main/java/com/mrcrayfish/glasscutter/block/GlassSlabBlock.java b/src/main/java/com/mrcrayfish/glasscutter/block/GlassSlabBlock.java index c4bca02..511de9c 100644 --- a/src/main/java/com/mrcrayfish/glasscutter/block/GlassSlabBlock.java +++ b/src/main/java/com/mrcrayfish/glasscutter/block/GlassSlabBlock.java @@ -7,8 +7,8 @@ */ public class GlassSlabBlock extends AbstractGlassSlabBlock { - public GlassSlabBlock(Properties properties) + public GlassSlabBlock(Settings settings) { - super(Blocks.GLASS::getDefaultState, properties); + super(Blocks.GLASS.getDefaultState(), settings); } } diff --git a/src/main/java/com/mrcrayfish/glasscutter/block/GlassStairsBlock.java b/src/main/java/com/mrcrayfish/glasscutter/block/GlassStairsBlock.java index 425163c..8bec501 100644 --- a/src/main/java/com/mrcrayfish/glasscutter/block/GlassStairsBlock.java +++ b/src/main/java/com/mrcrayfish/glasscutter/block/GlassStairsBlock.java @@ -1,6 +1,7 @@ package com.mrcrayfish.glasscutter.block; import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; import java.util.function.Supplier; @@ -9,8 +10,8 @@ */ public class GlassStairsBlock extends AbstractGlassStairsBlock { - public GlassStairsBlock(Supplier state, Properties properties) + public GlassStairsBlock(Settings settings) { - super(state, properties); + super(Blocks.GLASS.getDefaultState(), settings); } } diff --git a/src/main/java/com/mrcrayfish/glasscutter/block/GlasscutterBlock.java b/src/main/java/com/mrcrayfish/glasscutter/block/GlasscutterBlock.java index 98c0fcb..780d23b 100644 --- a/src/main/java/com/mrcrayfish/glasscutter/block/GlasscutterBlock.java +++ b/src/main/java/com/mrcrayfish/glasscutter/block/GlasscutterBlock.java @@ -1,107 +1,92 @@ package com.mrcrayfish.glasscutter.block; -import com.mrcrayfish.glasscutter.inventory.container.GlasscutterContainer; -import net.minecraft.block.Block; -import net.minecraft.block.BlockRenderType; -import net.minecraft.block.BlockState; -import net.minecraft.block.HorizontalBlock; +import com.mrcrayfish.glasscutter.Reference; +import com.mrcrayfish.glasscutter.init.ModStats; +import com.mrcrayfish.glasscutter.screen_handler.GlasscutterScreenHandler; +import net.minecraft.block.*; +import net.minecraft.entity.ai.pathing.NavigationType; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.inventory.container.INamedContainerProvider; -import net.minecraft.inventory.container.SimpleNamedContainerProvider; -import net.minecraft.item.BlockItemUseContext; -import net.minecraft.pathfinding.PathType; -import net.minecraft.state.DirectionProperty; -import net.minecraft.state.StateContainer; -import net.minecraft.util.*; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.screen.NamedScreenHandlerFactory; +import net.minecraft.screen.ScreenHandlerContext; +import net.minecraft.screen.SimpleNamedScreenHandlerFactory; +import net.minecraft.state.StateManager; +import net.minecraft.state.property.DirectionProperty; +import net.minecraft.text.Text; +import net.minecraft.text.TranslatableText; +import net.minecraft.util.ActionResult; +import net.minecraft.util.BlockMirror; +import net.minecraft.util.BlockRotation; +import net.minecraft.util.Hand; +import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.BlockRayTraceResult; -import net.minecraft.util.math.shapes.ISelectionContext; -import net.minecraft.util.math.shapes.VoxelShape; -import net.minecraft.util.text.TranslationTextComponent; -import net.minecraft.world.IBlockReader; +import net.minecraft.util.math.Direction; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.world.BlockView; import net.minecraft.world.World; -import javax.annotation.Nullable; - /** - * Author: MrCrayfish + * @author justAm0dd3r */ -public class GlasscutterBlock extends Block -{ - private static final TranslationTextComponent CONTAINER_TITLE = new TranslationTextComponent("container.glasscutter.glasscutter"); - public static final DirectionProperty DIRECTION = HorizontalBlock.HORIZONTAL_FACING; - protected static final VoxelShape SHAPE = Block.makeCuboidShape(0.0D, 0.0D, 0.0D, 16.0D, 9.0D, 16.0D); +public class GlasscutterBlock extends Block { + private static final Text TITLE = new TranslatableText("container." + Reference.MOD_ID + ".glasscutter"); + public static final DirectionProperty FACING; + protected static final VoxelShape SHAPE; + + public GlasscutterBlock(AbstractBlock.Settings settings) { + super(settings); + this.setDefaultState(this.stateManager.getDefaultState().with(FACING, Direction.NORTH)); + } - public GlasscutterBlock(Properties properties) - { - super(properties); - this.setDefaultState(this.stateContainer.getBaseState().with(DIRECTION, Direction.NORTH)); - } + public BlockState getPlacementState(ItemPlacementContext ctx) { + return this.getDefaultState().with(FACING, ctx.getPlayerFacing().getOpposite()); + } - @Override - public BlockState getStateForPlacement(BlockItemUseContext context) - { - return this.getDefaultState().with(DIRECTION, context.getPlacementHorizontalFacing().getOpposite()); - } + public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { + if (world.isClient) { + return ActionResult.SUCCESS; + } else { + player.openHandledScreen(state.createScreenHandlerFactory(world, pos)); + player.incrementStat(ModStats.INTERACT_WITH_GLASSCUTER); + return ActionResult.CONSUME; + } + } - @Override - public ActionResultType onBlockActivated(BlockState state, World world, BlockPos pos, PlayerEntity playerEntity, Hand hand, BlockRayTraceResult result) - { - if(!world.isRemote) - { - playerEntity.openContainer(state.getContainer(world, pos)); - } - return ActionResultType.SUCCESS; - } + public NamedScreenHandlerFactory createScreenHandlerFactory(BlockState state, World world, BlockPos pos) { + return new SimpleNamedScreenHandlerFactory((i, playerInventory, playerEntity) + -> new GlasscutterScreenHandler(i, playerInventory, ScreenHandlerContext.create(world, pos)), TITLE); + } - @Nullable - @Override - public INamedContainerProvider getContainer(BlockState state, World world, BlockPos pos) - { - return new SimpleNamedContainerProvider((windowId, playerInventory, playerEntity) -> { - return new GlasscutterContainer(windowId, playerInventory, IWorldPosCallable.of(world, pos)); - }, CONTAINER_TITLE); - } + public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + return SHAPE; + } - @Override - public VoxelShape getShape(BlockState state, IBlockReader reader, BlockPos pos, ISelectionContext context) - { - return SHAPE; - } + public boolean hasSidedTransparency(BlockState state) { + return true; + } - @Override - public boolean isTransparent(BlockState state) - { - return true; - } + public BlockRenderType getRenderType(BlockState state) { + return BlockRenderType.MODEL; + } - @Override - public BlockRenderType getRenderType(BlockState state) - { - return BlockRenderType.MODEL; - } + public BlockState rotate(BlockState state, BlockRotation rotation) { + return state.with(FACING, rotation.rotate(state.get(FACING))); + } - @Override - public BlockState rotate(BlockState state, Rotation rotation) - { - return state.with(DIRECTION, rotation.rotate(state.get(DIRECTION))); - } + public BlockState mirror(BlockState state, BlockMirror mirror) { + return state.rotate(mirror.getRotation(state.get(FACING))); + } - @Override - public BlockState mirror(BlockState state, Mirror mirror) - { - return state.rotate(mirror.toRotation(state.get(DIRECTION))); - } + protected void appendProperties(StateManager.Builder builder) { + builder.add(FACING); + } - @Override - protected void fillStateContainer(StateContainer.Builder builder) - { - builder.add(DIRECTION); - } + public boolean canPathfindThrough(BlockState state, BlockView world, BlockPos pos, NavigationType type) { + return false; + } - @Override - public boolean allowsMovement(BlockState state, IBlockReader reader, BlockPos pos, PathType pathType) - { - return false; - } + static { + FACING = HorizontalFacingBlock.FACING; + SHAPE = Block.createCuboidShape(0.0D, 0.0D, 0.0D, 16.0D, 9.0D, 16.0D); + } } diff --git a/src/main/java/com/mrcrayfish/glasscutter/block/StainedGlassSlabBlock.java b/src/main/java/com/mrcrayfish/glasscutter/block/StainedGlassSlabBlock.java index ac9f166..073f498 100644 --- a/src/main/java/com/mrcrayfish/glasscutter/block/StainedGlassSlabBlock.java +++ b/src/main/java/com/mrcrayfish/glasscutter/block/StainedGlassSlabBlock.java @@ -1,27 +1,24 @@ package com.mrcrayfish.glasscutter.block; import net.minecraft.block.BlockState; -import net.minecraft.block.IBeaconBeamColorProvider; -import net.minecraft.item.DyeColor; - -import java.util.function.Supplier; +import net.minecraft.block.Stainable; +import net.minecraft.util.DyeColor; /** * Author: MrCrayfish */ -public class StainedGlassSlabBlock extends AbstractGlassSlabBlock implements IBeaconBeamColorProvider +public class StainedGlassSlabBlock extends AbstractGlassSlabBlock implements Stainable { private final DyeColor color; - public StainedGlassSlabBlock(DyeColor color, Supplier state, Properties properties) + public StainedGlassSlabBlock(DyeColor color, BlockState state, Settings settings) { - super(state, properties); + super(state, settings); this.color = color; } @Override - public DyeColor getColor() - { - return this.color; + public DyeColor getColor() { + return color; } } diff --git a/src/main/java/com/mrcrayfish/glasscutter/block/StainedGlassStairsBlock.java b/src/main/java/com/mrcrayfish/glasscutter/block/StainedGlassStairsBlock.java index c06adf2..ed355b0 100644 --- a/src/main/java/com/mrcrayfish/glasscutter/block/StainedGlassStairsBlock.java +++ b/src/main/java/com/mrcrayfish/glasscutter/block/StainedGlassStairsBlock.java @@ -1,21 +1,21 @@ package com.mrcrayfish.glasscutter.block; import net.minecraft.block.BlockState; -import net.minecraft.block.IBeaconBeamColorProvider; -import net.minecraft.item.DyeColor; +import net.minecraft.block.Stainable; +import net.minecraft.util.DyeColor; import java.util.function.Supplier; /** * Author: MrCrayfish */ -public class StainedGlassStairsBlock extends AbstractGlassStairsBlock implements IBeaconBeamColorProvider +public class StainedGlassStairsBlock extends AbstractGlassStairsBlock implements Stainable { private final DyeColor color; - public StainedGlassStairsBlock(DyeColor color, Supplier state, Properties properties) + public StainedGlassStairsBlock(DyeColor color, BlockState state, Settings settings) { - super(state, properties); + super(state, settings); this.color = color; } diff --git a/src/main/java/com/mrcrayfish/glasscutter/client/ClientHandler.java b/src/main/java/com/mrcrayfish/glasscutter/client/ClientHandler.java index 1c09ad8..dff0a11 100644 --- a/src/main/java/com/mrcrayfish/glasscutter/client/ClientHandler.java +++ b/src/main/java/com/mrcrayfish/glasscutter/client/ClientHandler.java @@ -1,11 +1,8 @@ package com.mrcrayfish.glasscutter.client; -import com.mrcrayfish.glasscutter.client.gui.screen.inventory.GlasscutterScreen; import com.mrcrayfish.glasscutter.init.ModBlocks; -import com.mrcrayfish.glasscutter.init.ModContainers; -import net.minecraft.client.gui.ScreenManager; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.RenderTypeLookup; +import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap; +import net.minecraft.client.render.RenderLayer; /** * Author: MrCrayfish @@ -14,41 +11,41 @@ public class ClientHandler { public static void setup() { - RenderTypeLookup.setRenderLayer(ModBlocks.GLASSCUTTER, RenderType.getCutout()); - RenderTypeLookup.setRenderLayer(ModBlocks.GLASS_STAIRS, RenderType.getCutout()); - RenderTypeLookup.setRenderLayer(ModBlocks.GLASS_SLAB, RenderType.getCutout()); - RenderTypeLookup.setRenderLayer(ModBlocks.WHITE_STAINED_GLASS_STAIRS, RenderType.getTranslucent()); - RenderTypeLookup.setRenderLayer(ModBlocks.ORANGE_STAINED_GLASS_STAIRS, RenderType.getTranslucent()); - RenderTypeLookup.setRenderLayer(ModBlocks.MAGENTA_STAINED_GLASS_STAIRS, RenderType.getTranslucent()); - RenderTypeLookup.setRenderLayer(ModBlocks.LIGHT_BLUE_STAINED_GLASS_STAIRS, RenderType.getTranslucent()); - RenderTypeLookup.setRenderLayer(ModBlocks.YELLOW_STAINED_GLASS_STAIRS, RenderType.getTranslucent()); - RenderTypeLookup.setRenderLayer(ModBlocks.LIME_STAINED_GLASS_STAIRS, RenderType.getTranslucent()); - RenderTypeLookup.setRenderLayer(ModBlocks.PINK_STAINED_GLASS_STAIRS, RenderType.getTranslucent()); - RenderTypeLookup.setRenderLayer(ModBlocks.GRAY_STAINED_GLASS_STAIRS, RenderType.getTranslucent()); - RenderTypeLookup.setRenderLayer(ModBlocks.LIGHT_GRAY_STAINED_GLASS_STAIRS, RenderType.getTranslucent()); - RenderTypeLookup.setRenderLayer(ModBlocks.CYAN_STAINED_GLASS_STAIRS, RenderType.getTranslucent()); - RenderTypeLookup.setRenderLayer(ModBlocks.PURPLE_STAINED_GLASS_STAIRS, RenderType.getTranslucent()); - RenderTypeLookup.setRenderLayer(ModBlocks.BLUE_STAINED_GLASS_STAIRS, RenderType.getTranslucent()); - RenderTypeLookup.setRenderLayer(ModBlocks.BROWN_STAINED_GLASS_STAIRS, RenderType.getTranslucent()); - RenderTypeLookup.setRenderLayer(ModBlocks.GREEN_STAINED_GLASS_STAIRS, RenderType.getTranslucent()); - RenderTypeLookup.setRenderLayer(ModBlocks.RED_STAINED_GLASS_STAIRS, RenderType.getTranslucent()); - RenderTypeLookup.setRenderLayer(ModBlocks.BLACK_STAINED_GLASS_STAIRS, RenderType.getTranslucent()); - RenderTypeLookup.setRenderLayer(ModBlocks.WHITE_STAINED_GLASS_SLAB, RenderType.getTranslucent()); - RenderTypeLookup.setRenderLayer(ModBlocks.ORANGE_STAINED_GLASS_SLAB, RenderType.getTranslucent()); - RenderTypeLookup.setRenderLayer(ModBlocks.MAGENTA_STAINED_GLASS_SLAB, RenderType.getTranslucent()); - RenderTypeLookup.setRenderLayer(ModBlocks.LIGHT_BLUE_STAINED_GLASS_SLAB, RenderType.getTranslucent()); - RenderTypeLookup.setRenderLayer(ModBlocks.YELLOW_STAINED_GLASS_SLAB, RenderType.getTranslucent()); - RenderTypeLookup.setRenderLayer(ModBlocks.LIME_STAINED_GLASS_SLAB, RenderType.getTranslucent()); - RenderTypeLookup.setRenderLayer(ModBlocks.PINK_STAINED_GLASS_SLAB, RenderType.getTranslucent()); - RenderTypeLookup.setRenderLayer(ModBlocks.GRAY_STAINED_GLASS_SLAB, RenderType.getTranslucent()); - RenderTypeLookup.setRenderLayer(ModBlocks.LIGHT_GRAY_STAINED_GLASS_SLAB, RenderType.getTranslucent()); - RenderTypeLookup.setRenderLayer(ModBlocks.CYAN_STAINED_GLASS_SLAB, RenderType.getTranslucent()); - RenderTypeLookup.setRenderLayer(ModBlocks.PURPLE_STAINED_GLASS_SLAB, RenderType.getTranslucent()); - RenderTypeLookup.setRenderLayer(ModBlocks.BLUE_STAINED_GLASS_SLAB, RenderType.getTranslucent()); - RenderTypeLookup.setRenderLayer(ModBlocks.BROWN_STAINED_GLASS_SLAB, RenderType.getTranslucent()); - RenderTypeLookup.setRenderLayer(ModBlocks.GREEN_STAINED_GLASS_SLAB, RenderType.getTranslucent()); - RenderTypeLookup.setRenderLayer(ModBlocks.RED_STAINED_GLASS_SLAB, RenderType.getTranslucent()); - RenderTypeLookup.setRenderLayer(ModBlocks.BLACK_STAINED_GLASS_SLAB, RenderType.getTranslucent()); - ScreenManager.registerFactory(ModContainers.GLASSCUTTER, GlasscutterScreen::new); + // Make the slabs transparency render correctly. + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.GLASSCUTTER, RenderLayer.getCutout()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.GLASS_STAIRS, RenderLayer.getCutout()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.GLASS_SLAB, RenderLayer.getCutout()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.WHITE_STAINED_GLASS_STAIRS, RenderLayer.getTranslucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.ORANGE_STAINED_GLASS_STAIRS, RenderLayer.getTranslucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.MAGENTA_STAINED_GLASS_STAIRS, RenderLayer.getTranslucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.LIGHT_BLUE_STAINED_GLASS_STAIRS, RenderLayer.getTranslucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.YELLOW_STAINED_GLASS_STAIRS, RenderLayer.getTranslucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.LIME_STAINED_GLASS_STAIRS, RenderLayer.getTranslucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.PINK_STAINED_GLASS_STAIRS, RenderLayer.getTranslucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.GRAY_STAINED_GLASS_STAIRS, RenderLayer.getTranslucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.LIGHT_GRAY_STAINED_GLASS_STAIRS, RenderLayer.getTranslucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.CYAN_STAINED_GLASS_STAIRS, RenderLayer.getTranslucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.PURPLE_STAINED_GLASS_STAIRS, RenderLayer.getTranslucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.BLUE_STAINED_GLASS_STAIRS, RenderLayer.getTranslucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.BROWN_STAINED_GLASS_STAIRS, RenderLayer.getTranslucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.GREEN_STAINED_GLASS_STAIRS, RenderLayer.getTranslucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.RED_STAINED_GLASS_STAIRS, RenderLayer.getTranslucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.BLACK_STAINED_GLASS_STAIRS, RenderLayer.getTranslucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.WHITE_STAINED_GLASS_SLAB, RenderLayer.getTranslucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.ORANGE_STAINED_GLASS_SLAB, RenderLayer.getTranslucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.MAGENTA_STAINED_GLASS_SLAB, RenderLayer.getTranslucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.LIGHT_BLUE_STAINED_GLASS_SLAB, RenderLayer.getTranslucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.YELLOW_STAINED_GLASS_SLAB, RenderLayer.getTranslucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.LIME_STAINED_GLASS_SLAB, RenderLayer.getTranslucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.PINK_STAINED_GLASS_SLAB, RenderLayer.getTranslucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.GRAY_STAINED_GLASS_SLAB, RenderLayer.getTranslucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.LIGHT_GRAY_STAINED_GLASS_SLAB, RenderLayer.getTranslucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.CYAN_STAINED_GLASS_SLAB, RenderLayer.getTranslucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.PURPLE_STAINED_GLASS_SLAB, RenderLayer.getTranslucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.BLUE_STAINED_GLASS_SLAB, RenderLayer.getTranslucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.BROWN_STAINED_GLASS_SLAB, RenderLayer.getTranslucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.GREEN_STAINED_GLASS_SLAB, RenderLayer.getTranslucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.RED_STAINED_GLASS_SLAB, RenderLayer.getTranslucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.BLACK_STAINED_GLASS_SLAB, RenderLayer.getTranslucent()); } } diff --git a/src/main/java/com/mrcrayfish/glasscutter/client/gui/screen/inventory/GlasscutterScreen.java b/src/main/java/com/mrcrayfish/glasscutter/client/gui/screen/inventory/GlasscutterScreen.java index da2b661..5535045 100644 --- a/src/main/java/com/mrcrayfish/glasscutter/client/gui/screen/inventory/GlasscutterScreen.java +++ b/src/main/java/com/mrcrayfish/glasscutter/client/gui/screen/inventory/GlasscutterScreen.java @@ -1,207 +1,189 @@ package com.mrcrayfish.glasscutter.client.gui.screen.inventory; -import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.systems.RenderSystem; import com.mrcrayfish.glasscutter.Reference; -import com.mrcrayfish.glasscutter.inventory.container.GlasscutterContainer; import com.mrcrayfish.glasscutter.item.crafting.GlasscuttingRecipe; -import net.minecraft.client.Minecraft; -import net.minecraft.client.audio.SimpleSound; -import net.minecraft.client.gui.screen.inventory.ContainerScreen; +import com.mrcrayfish.glasscutter.screen_handler.GlasscutterScreenHandler; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.screen.ingame.HandledScreen; +import net.minecraft.client.sound.PositionedSoundInstance; +import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.player.PlayerInventory; -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.SoundEvents; +import net.minecraft.sound.SoundEvents; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; import net.minecraft.util.math.MathHelper; -import net.minecraft.util.text.ITextComponent; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; import java.util.List; /** - * Author: MrCrayfish + * Glasscutter screen. Only client side. + * + * @author justAm0dd3r */ -@OnlyIn(Dist.CLIENT) -public class GlasscutterScreen extends ContainerScreen -{ - private static final ResourceLocation BACKGROUND_TEXTURE = new ResourceLocation(Reference.MOD_ID, "textures/gui/container/glasscutter.png"); - private float sliderProgress; - private boolean clickOnScrollBar; - private int recipeIndexOffset; - private boolean hasItemsInInputSlot; - - public GlasscutterScreen(GlasscutterContainer container, PlayerInventory playerInventory, ITextComponent titleIn) - { - super(container, playerInventory, titleIn); - container.setInventoryUpdateListener(this::onInventoryUpdate); - --this.field_238743_q_; - } - - @Override - public void func_230430_a_(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) - // render - { - super.func_230430_a_(matrixStack, mouseX, mouseY, partialTicks); - this.func_238653_a_(matrixStack, null, mouseX, mouseY); // Render ToolTip - } - -/* - @Override - protected void func_230459_a_(MatrixStack matrixStack, int mouseX, int mouseY) - // drawGuiContainerForegroundLayer - { - // font renderer drawString - this.field_230712_o_.func_238407_a_(matrixStack, this.field_230704_d_.func_230532_e_(), 8.0F, 4.0F, 4210752); - this.field_230712_o_.func_238407_a_(matrixStack, this.playerInventory.getDisplayName().func_230532_e_(), 8.0F, (float) (this.ySize - 94), 4210752); - } -*/ - - protected void func_230450_a_(MatrixStack matrixStack, float partialTicks, int mouseX, int mouseY) - // drawGuiContainerBackgroundLayer - { - // this.renderBackground(); - this.func_230446_a_(matrixStack); - RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F); - this.field_230706_i_.getTextureManager().bindTexture(BACKGROUND_TEXTURE); - int guiLeft = this.guiLeft; - int guiTop = this.guiTop; - - // Blit - this.func_238474_b_(matrixStack, guiLeft, guiTop, 0, 0, this.xSize, this.ySize); - int scrollBarPos = (int) (41.0F * this.sliderProgress); - - // Blit - this.func_238474_b_(matrixStack, guiLeft + 119, guiTop + 15 + scrollBarPos, - 176 + (this.canScroll() ? 0 : 12), 0, 12, 15); - int offsetX = this.guiLeft + 52; - int offsetY = this.guiTop + 14; - int indexOffset = this.recipeIndexOffset + 12; - this.drawRecipeBackgrounds(matrixStack, mouseX, mouseY, offsetX, offsetY, indexOffset); - this.drawRecipeItems(offsetX, offsetY, indexOffset); - } - - private void drawRecipeBackgrounds(MatrixStack matrixStack, int mouseX, int mouseY, int offsetX, int offsetY, int indexOffset) - { - for(int i = this.recipeIndexOffset; i < indexOffset && i < this.container.getRecipeListSize(); ++i) - { - int index = i - this.recipeIndexOffset; - int recipeOffsetX = offsetX + index % 4 * 16; - int recipeOffsetY = offsetY + (index / 4) * 18 + 2; - int vOffset = this.ySize; - if(i == this.container.getSelectedRecipe()) - { - vOffset += 18; +@Environment(EnvType.CLIENT) +public class GlasscutterScreen extends HandledScreen { + private static final Identifier TEXTURE = new Identifier(Reference.MOD_ID, "textures/gui/container/glasscutter.png"); + private float scrollAmount; + private boolean mouseClicked; + private int scrollOffset; + private boolean canCraft; + + public GlasscutterScreen(GlasscutterScreenHandler handler, PlayerInventory inventory, Text title) { + super(handler, inventory, title); + handler.setContentsChangedListener(this::onInventoryChange); + --this.titleY; + } + + public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { + super.render(matrices, mouseX, mouseY, delta); + this.drawMouseoverTooltip(matrices, mouseX, mouseY); + } + + /** + * Draw the background. + */ + protected void drawBackground(MatrixStack matrices, float delta, int mouseX, int mouseY) { + this.renderBackground(matrices); + RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F); + assert this.client != null; + this.client.getTextureManager().bindTexture(TEXTURE); + int i = this.x; + int j = this.y; + this.drawTexture(matrices, i, j, 0, 0, this.backgroundWidth, this.backgroundHeight); + int k = (int)(41.0F * this.scrollAmount); + this.drawTexture(matrices, i + 119, j + 15 + k, 176 + (this.shouldScroll() ? 0 : 12), 0, 12, 15); + int l = this.x + 52; + int m = this.y + 14; + int n = this.scrollOffset + 12; + this.renderRecipeBackground(matrices, mouseX, mouseY, l, m, n); + this.renderRecipeIcons(l, m, n); + } + + protected void drawMouseoverTooltip(MatrixStack matrices, int x, int y) { + super.drawMouseoverTooltip(matrices, x, y); + if (this.canCraft) { + int i = this.x + 52; + int j = this.y + 14; + int k = this.scrollOffset + 12; + List list = this.handler.getAvailableRecipes(); + + for(int l = this.scrollOffset; l < k && l < this.handler.getAvailableRecipeCount(); ++l) { + int m = l - this.scrollOffset; + int n = i + m % 4 * 16; + int o = j + m / 4 * 18 + 2; + if (x >= n && x < n + 16 && y >= o && y < o + 18) { + this.renderTooltip(matrices, list.get(l).getOutput(), x, y); } - else if(mouseX >= recipeOffsetX && mouseY >= recipeOffsetY && mouseX < recipeOffsetX + 16 && mouseY < recipeOffsetY + 18) - { - vOffset += 36; + } + } + + } + + private void renderRecipeBackground(MatrixStack matrixStack, int i, int j, int k, int l, int m) { + for(int n = this.scrollOffset; n < m && n < this.handler.getAvailableRecipeCount(); ++n) { + int o = n - this.scrollOffset; + int p = k + o % 4 * 16; + int q = o / 4; + int r = l + q * 18 + 2; + int s = this.backgroundHeight; + if (n == this.handler.getSelectedRecipe()) { + s += 18; + } else if (i >= p && j >= r && i < p + 16 && j < r + 18) { + s += 36; + } + + this.drawTexture(matrixStack, p, r - 1, 0, s, 16, 18); + } + + } + + private void renderRecipeIcons(int x, int y, int scrollOffset) { + List list = this.handler.getAvailableRecipes(); + + for(int i = this.scrollOffset; i < scrollOffset && i < this.handler.getAvailableRecipeCount(); ++i) { + int j = i - this.scrollOffset; + int k = x + j % 4 * 16; + int l = j / 4; + int m = y + l * 18 + 2; + assert this.client != null; + this.client.getItemRenderer().renderInGuiWithOverrides(list.get(i).getOutput(), k, m); + } + + } + + public boolean mouseClicked(double mouseX, double mouseY, int button) { + this.mouseClicked = false; + if (this.canCraft) { + int i = this.x + 52; + int j = this.y + 14; + int k = this.scrollOffset + 12; + + for(int l = this.scrollOffset; l < k; ++l) { + int m = l - this.scrollOffset; + double d = mouseX - (double)(i + m % 4 * 16); + double e = mouseY - (double)(j + m / 4 * 18); + if (d >= 0.0D && e >= 0.0D && d < 16.0D && e < 18.0D) { + assert this.client != null; + if (this.handler.onButtonClick(this.client.player, l)) { + MinecraftClient.getInstance().getSoundManager().play(PositionedSoundInstance.master(SoundEvents.UI_STONECUTTER_SELECT_RECIPE, 1.0F)); + assert this.client.interactionManager != null; + this.client.interactionManager.clickButton(this.handler.syncId, l); + return true; + } } - - // Blit - this.func_238468_a_(matrixStack, recipeOffsetX, recipeOffsetY - 1, 0, vOffset, 16, 18); - } - } - - private void drawRecipeItems(int offsetX, int offsetY, int indexOffset) - { - List list = this.container.getRecipeList(); - for(int i = this.recipeIndexOffset; i < indexOffset && i < this.container.getRecipeListSize(); ++i) - { - int index = i - this.recipeIndexOffset; - int recipeOffsetX = offsetX + index % 4 * 16; - int recipeOffsetY = offsetY + (index / 4) * 18 + 2; - this.field_230706_i_.getItemRenderer().renderItemAndEffectIntoGUI(list.get(i).getRecipeOutput(), recipeOffsetX, recipeOffsetY); - } - } - - @Override - public boolean func_231044_a_(double mouseX, double mouseY, int button) - // mouseClicked - { - this.clickOnScrollBar = false; - if(this.hasItemsInInputSlot) - { - int recipeOffsetX = this.guiLeft + 52; - int recipeOffsetY = this.guiTop + 14; - int recipeOffset = this.recipeIndexOffset + 12; - - for(int i = this.recipeIndexOffset; i < recipeOffset; ++i) - { - int index = i - this.recipeIndexOffset; - double mouseRelativeX = mouseX - (double) (recipeOffsetX + index % 4 * 16); - double mouseRelativeY = mouseY - (double) (recipeOffsetY + index / 4 * 18); - if(mouseRelativeX >= 0.0D && mouseRelativeY >= 0.0D && mouseRelativeX < 16.0D && mouseRelativeY < 18.0D && this.container.enchantItem(this.field_230706_i_.player, i)) - { - Minecraft.getInstance().getSoundHandler().play(SimpleSound.master(SoundEvents.UI_STONECUTTER_SELECT_RECIPE, 1.0F)); - this.field_230706_i_.playerController.sendEnchantPacket((this.container).windowId, i); - return true; - } - } - - recipeOffsetX = this.guiLeft + 119; - recipeOffsetY = this.guiTop + 9; - if(mouseX >= (double) recipeOffsetX && mouseX < (double) (recipeOffsetX + 12) && mouseY >= (double) recipeOffsetY && mouseY < (double) (recipeOffsetY + 54)) - { - this.clickOnScrollBar = true; - } - } - - return super.func_231044_a_(mouseX, mouseY, button); - } - - @Override - public boolean func_231045_a_(double mouseX, double mouseY, int button, double deltaX, double deltaY) - // mouseDragged - { - if(this.clickOnScrollBar && this.canScroll()) - { - int offsetX = this.guiTop + 14; - int width = offsetX + 54; - this.sliderProgress = ((float) mouseY - (float) offsetX - 7.5F) / ((float) (width - offsetX) - 15.0F); - this.sliderProgress = MathHelper.clamp(this.sliderProgress, 0.0F, 1.0F); - this.recipeIndexOffset = (int) ((double) (this.sliderProgress * (float) this.getHiddenRows()) + 0.5D) * 4; - return true; - } - else - { - return super.func_231045_a_(mouseX, mouseY, button, deltaX, deltaY); - } - } - - @Override - public boolean func_231043_a_(double mouseX, double mouseY, double distance) - // mouseScrolled - { - if(this.canScroll()) - { - int hiddenRowsCount = this.getHiddenRows(); - this.sliderProgress = (float) ((double) this.sliderProgress - distance / (double) hiddenRowsCount); - this.sliderProgress = MathHelper.clamp(this.sliderProgress, 0.0F, 1.0F); - this.recipeIndexOffset = (int) ((double) (this.sliderProgress * (float) hiddenRowsCount) + 0.5D) * 4; - } - - return true; - } - - private boolean canScroll() - { - return this.hasItemsInInputSlot && this.container.getRecipeListSize() > 12; - } - - private int getHiddenRows() - { - return (this.container.getRecipeListSize() + 4 - 1) / 4 - 3; - } - - private void onInventoryUpdate() - { - this.hasItemsInInputSlot = this.container.hasItemsInInputSlot(); - if(!this.hasItemsInInputSlot) - { - this.sliderProgress = 0.0F; - this.recipeIndexOffset = 0; - } - } + } + + i = this.x + 119; + j = this.y + 9; + if (mouseX >= (double)i && mouseX < (double)(i + 12) && mouseY >= (double)j && mouseY < (double)(j + 54)) { + this.mouseClicked = true; + } + } + + return super.mouseClicked(mouseX, mouseY, button); + } + + public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { + if (this.mouseClicked && this.shouldScroll()) { + int i = this.y + 14; + int j = i + 54; + this.scrollAmount = ((float)mouseY - (float)i - 7.5F) / ((float)(j - i) - 15.0F); + this.scrollAmount = MathHelper.clamp(this.scrollAmount, 0.0F, 1.0F); + this.scrollOffset = (int)((double)(this.scrollAmount * (float)this.getMaxScroll()) + 0.5D) * 4; + return true; + } else { + return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY); + } + } + + public boolean mouseScrolled(double mouseX, double mouseY, double amount) { + if (this.shouldScroll()) { + int i = this.getMaxScroll(); + this.scrollAmount = (float)((double)this.scrollAmount - amount / (double)i); + this.scrollAmount = MathHelper.clamp(this.scrollAmount, 0.0F, 1.0F); + this.scrollOffset = (int)((double)(this.scrollAmount * (float)i) + 0.5D) * 4; + } + + return true; + } + + private boolean shouldScroll() { + return this.canCraft && this.handler.getAvailableRecipeCount() > 12; + } + + protected int getMaxScroll() { + return (this.handler.getAvailableRecipeCount() + 4 - 1) / 4 - 3; + } + + private void onInventoryChange() { + this.canCraft = this.handler.canCraft(); + if (!this.canCraft) { + this.scrollAmount = 0.0F; + this.scrollOffset = 0; + } + + } } diff --git a/src/main/java/com/mrcrayfish/glasscutter/init/ModBlocks.java b/src/main/java/com/mrcrayfish/glasscutter/init/ModBlocks.java index eea1e6e..9b5e5f3 100644 --- a/src/main/java/com/mrcrayfish/glasscutter/init/ModBlocks.java +++ b/src/main/java/com/mrcrayfish/glasscutter/init/ModBlocks.java @@ -2,92 +2,121 @@ import com.mrcrayfish.glasscutter.Reference; import com.mrcrayfish.glasscutter.block.*; -import net.minecraft.block.Block; -import net.minecraft.block.Blocks; -import net.minecraft.block.material.Material; +import net.minecraft.block.*; import net.minecraft.item.BlockItem; -import net.minecraft.item.DyeColor; import net.minecraft.item.Item; import net.minecraft.item.ItemGroup; -import net.minecraft.util.ResourceLocation; -import net.minecraftforge.event.RegistryEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.registries.IForgeRegistry; +import net.minecraft.util.DyeColor; +import net.minecraft.util.registry.Registry; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; -import java.util.ArrayList; -import java.util.List; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; /** * Author: MrCrayfish + * + * Do not change the field names! */ -@Mod.EventBusSubscriber(modid = Reference.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD) public class ModBlocks { - private static final List BLOCKS = new ArrayList<>(); - private static final List ITEMS = new ArrayList<>(); + public static Block GLASSCUTTER; + public static Block GLASS_STAIRS; + public static Block GLASS_SLAB; + public static Block WHITE_STAINED_GLASS_STAIRS; + public static Block ORANGE_STAINED_GLASS_STAIRS; + public static Block MAGENTA_STAINED_GLASS_STAIRS; + public static Block LIGHT_BLUE_STAINED_GLASS_STAIRS; + public static Block YELLOW_STAINED_GLASS_STAIRS; + public static Block LIME_STAINED_GLASS_STAIRS; + public static Block PINK_STAINED_GLASS_STAIRS; + public static Block GRAY_STAINED_GLASS_STAIRS; + public static Block LIGHT_GRAY_STAINED_GLASS_STAIRS; + public static Block CYAN_STAINED_GLASS_STAIRS; + public static Block PURPLE_STAINED_GLASS_STAIRS; + public static Block BLUE_STAINED_GLASS_STAIRS; + public static Block BROWN_STAINED_GLASS_STAIRS; + public static Block GREEN_STAINED_GLASS_STAIRS; + public static Block RED_STAINED_GLASS_STAIRS; + public static Block BLACK_STAINED_GLASS_STAIRS; + public static Block WHITE_STAINED_GLASS_SLAB; + public static Block ORANGE_STAINED_GLASS_SLAB; + public static Block MAGENTA_STAINED_GLASS_SLAB; + public static Block LIGHT_BLUE_STAINED_GLASS_SLAB; + public static Block YELLOW_STAINED_GLASS_SLAB; + public static Block LIME_STAINED_GLASS_SLAB; + public static Block PINK_STAINED_GLASS_SLAB; + public static Block GRAY_STAINED_GLASS_SLAB; + public static Block LIGHT_GRAY_STAINED_GLASS_SLAB; + public static Block CYAN_STAINED_GLASS_SLAB; + public static Block PURPLE_STAINED_GLASS_SLAB; + public static Block BLUE_STAINED_GLASS_SLAB; + public static Block BROWN_STAINED_GLASS_SLAB; + public static Block GREEN_STAINED_GLASS_SLAB; + public static Block RED_STAINED_GLASS_SLAB; + public static Block BLACK_STAINED_GLASS_SLAB; + private static final Logger LOGGER = LogManager.getLogger(); - public static final Block GLASSCUTTER = register(new ResourceLocation(Reference.MOD_ID, "glasscutter"), new GlasscutterBlock(Block.Properties.create(Material.ROCK).hardnessAndResistance(3.5F)), ItemGroup.DECORATIONS); - public static final Block GLASS_STAIRS = register(new ResourceLocation(Reference.MOD_ID, "glass_stairs"), new GlassStairsBlock(Blocks.GLASS::getDefaultState, Block.Properties.from(Blocks.GLASS)), ItemGroup.BUILDING_BLOCKS); - public static final Block GLASS_SLAB = register(new ResourceLocation(Reference.MOD_ID, "glass_slab"), new GlassSlabBlock(Block.Properties.from(Blocks.GLASS)), ItemGroup.BUILDING_BLOCKS); - public static final Block WHITE_STAINED_GLASS_STAIRS = register(new ResourceLocation(Reference.MOD_ID, "white_stained_glass_stairs"), new StainedGlassStairsBlock(DyeColor.WHITE, Blocks.WHITE_STAINED_GLASS::getDefaultState, Block.Properties.from(Blocks.WHITE_STAINED_GLASS)), ItemGroup.BUILDING_BLOCKS); - public static final Block ORANGE_STAINED_GLASS_STAIRS = register(new ResourceLocation(Reference.MOD_ID, "orange_stained_glass_stairs"), new StainedGlassStairsBlock(DyeColor.ORANGE, Blocks.ORANGE_STAINED_GLASS::getDefaultState, Block.Properties.from(Blocks.ORANGE_STAINED_GLASS)), ItemGroup.BUILDING_BLOCKS); - public static final Block MAGENTA_STAINED_GLASS_STAIRS = register(new ResourceLocation(Reference.MOD_ID, "magenta_stained_glass_stairs"), new StainedGlassStairsBlock(DyeColor.MAGENTA, Blocks.MAGENTA_STAINED_GLASS::getDefaultState, Block.Properties.from(Blocks.MAGENTA_STAINED_GLASS)), ItemGroup.BUILDING_BLOCKS); - public static final Block LIGHT_BLUE_STAINED_GLASS_STAIRS = register(new ResourceLocation(Reference.MOD_ID, "light_blue_stained_glass_stairs"), new StainedGlassStairsBlock(DyeColor.LIGHT_BLUE, Blocks.LIGHT_BLUE_STAINED_GLASS::getDefaultState, Block.Properties.from(Blocks.LIGHT_BLUE_STAINED_GLASS)), ItemGroup.BUILDING_BLOCKS); - public static final Block YELLOW_STAINED_GLASS_STAIRS = register(new ResourceLocation(Reference.MOD_ID, "yellow_stained_glass_stairs"), new StainedGlassStairsBlock(DyeColor.YELLOW, Blocks.YELLOW_STAINED_GLASS::getDefaultState, Block.Properties.from(Blocks.YELLOW_STAINED_GLASS)), ItemGroup.BUILDING_BLOCKS); - public static final Block LIME_STAINED_GLASS_STAIRS = register(new ResourceLocation(Reference.MOD_ID, "lime_stained_glass_stairs"), new StainedGlassStairsBlock(DyeColor.LIME, Blocks.LIME_STAINED_GLASS::getDefaultState, Block.Properties.from(Blocks.LIME_STAINED_GLASS)), ItemGroup.BUILDING_BLOCKS); - public static final Block PINK_STAINED_GLASS_STAIRS = register(new ResourceLocation(Reference.MOD_ID, "pink_stained_glass_stairs"), new StainedGlassStairsBlock(DyeColor.PINK, Blocks.PINK_STAINED_GLASS::getDefaultState, Block.Properties.from(Blocks.PINK_STAINED_GLASS)), ItemGroup.BUILDING_BLOCKS); - public static final Block GRAY_STAINED_GLASS_STAIRS = register(new ResourceLocation(Reference.MOD_ID, "gray_stained_glass_stairs"), new StainedGlassStairsBlock(DyeColor.GRAY, Blocks.GRAY_STAINED_GLASS::getDefaultState, Block.Properties.from(Blocks.GRAY_STAINED_GLASS)), ItemGroup.BUILDING_BLOCKS); - public static final Block LIGHT_GRAY_STAINED_GLASS_STAIRS = register(new ResourceLocation(Reference.MOD_ID, "light_gray_stained_glass_stairs"), new StainedGlassStairsBlock(DyeColor.LIGHT_GRAY, Blocks.LIGHT_GRAY_STAINED_GLASS::getDefaultState, Block.Properties.from(Blocks.LIGHT_GRAY_STAINED_GLASS)), ItemGroup.BUILDING_BLOCKS); - public static final Block CYAN_STAINED_GLASS_STAIRS = register(new ResourceLocation(Reference.MOD_ID, "cyan_stained_glass_stairs"), new StainedGlassStairsBlock(DyeColor.CYAN, Blocks.CYAN_STAINED_GLASS::getDefaultState, Block.Properties.from(Blocks.CYAN_STAINED_GLASS)), ItemGroup.BUILDING_BLOCKS); - public static final Block PURPLE_STAINED_GLASS_STAIRS = register(new ResourceLocation(Reference.MOD_ID, "purple_stained_glass_stairs"), new StainedGlassStairsBlock(DyeColor.PURPLE, Blocks.PURPLE_STAINED_GLASS::getDefaultState, Block.Properties.from(Blocks.PURPLE_STAINED_GLASS)), ItemGroup.BUILDING_BLOCKS); - public static final Block BLUE_STAINED_GLASS_STAIRS = register(new ResourceLocation(Reference.MOD_ID, "blue_stained_glass_stairs"), new StainedGlassStairsBlock(DyeColor.BLUE, Blocks.BLUE_STAINED_GLASS::getDefaultState, Block.Properties.from(Blocks.BLUE_STAINED_GLASS)), ItemGroup.BUILDING_BLOCKS); - public static final Block BROWN_STAINED_GLASS_STAIRS = register(new ResourceLocation(Reference.MOD_ID, "brown_stained_glass_stairs"), new StainedGlassStairsBlock(DyeColor.BROWN, Blocks.BROWN_STAINED_GLASS::getDefaultState, Block.Properties.from(Blocks.BROWN_STAINED_GLASS)), ItemGroup.BUILDING_BLOCKS); - public static final Block GREEN_STAINED_GLASS_STAIRS = register(new ResourceLocation(Reference.MOD_ID, "green_stained_glass_stairs"), new StainedGlassStairsBlock(DyeColor.GREEN, Blocks.GREEN_STAINED_GLASS::getDefaultState, Block.Properties.from(Blocks.GREEN_STAINED_GLASS)), ItemGroup.BUILDING_BLOCKS); - public static final Block RED_STAINED_GLASS_STAIRS = register(new ResourceLocation(Reference.MOD_ID, "red_stained_glass_stairs"), new StainedGlassStairsBlock(DyeColor.RED, Blocks.RED_STAINED_GLASS::getDefaultState, Block.Properties.from(Blocks.RED_STAINED_GLASS)), ItemGroup.BUILDING_BLOCKS); - public static final Block BLACK_STAINED_GLASS_STAIRS = register(new ResourceLocation(Reference.MOD_ID, "black_stained_glass_stairs"), new StainedGlassStairsBlock(DyeColor.BLACK, Blocks.BLACK_STAINED_GLASS::getDefaultState, Block.Properties.from(Blocks.BLACK_STAINED_GLASS)), ItemGroup.BUILDING_BLOCKS); - public static final Block WHITE_STAINED_GLASS_SLAB = register(new ResourceLocation(Reference.MOD_ID, "white_stained_glass_slab"), new StainedGlassSlabBlock(DyeColor.WHITE, Blocks.WHITE_STAINED_GLASS::getDefaultState, Block.Properties.from(Blocks.WHITE_STAINED_GLASS)), ItemGroup.BUILDING_BLOCKS); - public static final Block ORANGE_STAINED_GLASS_SLAB = register(new ResourceLocation(Reference.MOD_ID, "orange_stained_glass_slab"), new StainedGlassSlabBlock(DyeColor.ORANGE, Blocks.ORANGE_STAINED_GLASS::getDefaultState, Block.Properties.from(Blocks.ORANGE_STAINED_GLASS)), ItemGroup.BUILDING_BLOCKS); - public static final Block MAGENTA_STAINED_GLASS_SLAB = register(new ResourceLocation(Reference.MOD_ID, "magenta_stained_glass_slab"), new StainedGlassSlabBlock(DyeColor.MAGENTA, Blocks.MAGENTA_STAINED_GLASS::getDefaultState, Block.Properties.from(Blocks.MAGENTA_STAINED_GLASS)), ItemGroup.BUILDING_BLOCKS); - public static final Block LIGHT_BLUE_STAINED_GLASS_SLAB = register(new ResourceLocation(Reference.MOD_ID, "light_blue_stained_glass_slab"), new StainedGlassSlabBlock(DyeColor.LIGHT_BLUE, Blocks.LIGHT_BLUE_STAINED_GLASS::getDefaultState, Block.Properties.from(Blocks.LIGHT_BLUE_STAINED_GLASS)), ItemGroup.BUILDING_BLOCKS); - public static final Block YELLOW_STAINED_GLASS_SLAB = register(new ResourceLocation(Reference.MOD_ID, "yellow_stained_glass_slab"), new StainedGlassSlabBlock(DyeColor.YELLOW, Blocks.YELLOW_STAINED_GLASS::getDefaultState, Block.Properties.from(Blocks.YELLOW_STAINED_GLASS)), ItemGroup.BUILDING_BLOCKS); - public static final Block LIME_STAINED_GLASS_SLAB = register(new ResourceLocation(Reference.MOD_ID, "lime_stained_glass_slab"), new StainedGlassSlabBlock(DyeColor.LIME, Blocks.LIME_STAINED_GLASS::getDefaultState, Block.Properties.from(Blocks.LIME_STAINED_GLASS)), ItemGroup.BUILDING_BLOCKS); - public static final Block PINK_STAINED_GLASS_SLAB = register(new ResourceLocation(Reference.MOD_ID, "pink_stained_glass_slab"), new StainedGlassSlabBlock(DyeColor.PINK, Blocks.PINK_STAINED_GLASS::getDefaultState, Block.Properties.from(Blocks.PINK_STAINED_GLASS)), ItemGroup.BUILDING_BLOCKS); - public static final Block GRAY_STAINED_GLASS_SLAB = register(new ResourceLocation(Reference.MOD_ID, "gray_stained_glass_slab"), new StainedGlassSlabBlock(DyeColor.GRAY, Blocks.GRAY_STAINED_GLASS::getDefaultState, Block.Properties.from(Blocks.GRAY_STAINED_GLASS)), ItemGroup.BUILDING_BLOCKS); - public static final Block LIGHT_GRAY_STAINED_GLASS_SLAB = register(new ResourceLocation(Reference.MOD_ID, "light_gray_stained_glass_slab"), new StainedGlassSlabBlock(DyeColor.LIGHT_GRAY, Blocks.LIGHT_GRAY_STAINED_GLASS::getDefaultState, Block.Properties.from(Blocks.LIGHT_GRAY_STAINED_GLASS)), ItemGroup.BUILDING_BLOCKS); - public static final Block CYAN_STAINED_GLASS_SLAB = register(new ResourceLocation(Reference.MOD_ID, "cyan_stained_glass_slab"), new StainedGlassSlabBlock(DyeColor.CYAN, Blocks.CYAN_STAINED_GLASS::getDefaultState, Block.Properties.from(Blocks.CYAN_STAINED_GLASS)), ItemGroup.BUILDING_BLOCKS); - public static final Block PURPLE_STAINED_GLASS_SLAB = register(new ResourceLocation(Reference.MOD_ID, "purple_stained_glass_slab"), new StainedGlassSlabBlock(DyeColor.PURPLE, Blocks.PURPLE_STAINED_GLASS::getDefaultState, Block.Properties.from(Blocks.PURPLE_STAINED_GLASS)), ItemGroup.BUILDING_BLOCKS); - public static final Block BLUE_STAINED_GLASS_SLAB = register(new ResourceLocation(Reference.MOD_ID, "blue_stained_glass_slab"), new StainedGlassSlabBlock(DyeColor.BLUE, Blocks.BLUE_STAINED_GLASS::getDefaultState, Block.Properties.from(Blocks.BLUE_STAINED_GLASS)), ItemGroup.BUILDING_BLOCKS); - public static final Block BROWN_STAINED_GLASS_SLAB = register(new ResourceLocation(Reference.MOD_ID, "brown_stained_glass_slab"), new StainedGlassSlabBlock(DyeColor.BROWN, Blocks.BROWN_STAINED_GLASS::getDefaultState, Block.Properties.from(Blocks.BROWN_STAINED_GLASS)), ItemGroup.BUILDING_BLOCKS); - public static final Block GREEN_STAINED_GLASS_SLAB = register(new ResourceLocation(Reference.MOD_ID, "green_stained_glass_slab"), new StainedGlassSlabBlock(DyeColor.GREEN, Blocks.GREEN_STAINED_GLASS::getDefaultState, Block.Properties.from(Blocks.GREEN_STAINED_GLASS)), ItemGroup.BUILDING_BLOCKS); - public static final Block RED_STAINED_GLASS_SLAB = register(new ResourceLocation(Reference.MOD_ID, "red_stained_glass_slab"), new StainedGlassSlabBlock(DyeColor.RED, Blocks.RED_STAINED_GLASS::getDefaultState, Block.Properties.from(Blocks.RED_STAINED_GLASS)), ItemGroup.BUILDING_BLOCKS); - public static final Block BLACK_STAINED_GLASS_SLAB = register(new ResourceLocation(Reference.MOD_ID, "black_stained_glass_slab"), new StainedGlassSlabBlock(DyeColor.BLACK, Blocks.BLACK_STAINED_GLASS::getDefaultState, Block.Properties.from(Blocks.BLACK_STAINED_GLASS)), ItemGroup.BUILDING_BLOCKS); + /** + * Try to register the blocks via reflection. (not that repetitive). Trows tons of reflection exceptions. + * @throws NoSuchFieldException when there are no fields found. probably someone has renamed the fields... + * @throws NoSuchMethodException when a method wasn't found. + * @throws InstantiationException when an error occurs during the {@link StainedGlassSlabBlock} or {@link StainedGlassStairsBlock} constructor call. + */ + public static void registerAll() throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException { + // Glasscutter + GLASSCUTTER = register("glasscutter", new GlasscutterBlock(AbstractBlock.Settings.of(Material.STONE).strength(3.5F)), ItemGroup.DECORATIONS); + // Glass Stairs + GLASS_STAIRS = register("glass_stairs", new GlassStairsBlock(AbstractBlock.Settings.copy(Blocks.GLASS))); + // Glass Slab + GLASS_SLAB = register("glass_slab", new GlassSlabBlock(AbstractBlock.Settings.copy(Blocks.GLASS))); - private static Block register(ResourceLocation key, Block block, ItemGroup group) - { - block.setRegistryName(key); - BLOCKS.add(block); - BlockItem item = new BlockItem(block, new Item.Properties().group(group)); - item.setRegistryName(key); - ITEMS.add(item); - return block; + for (DyeColor color: DyeColor.values()) { + String[] types = new String[] { "stairs", "slab" }; + for (String type : types) { + // Get the field. + Field blockField = ModBlocks.class.getField(color.getName().toUpperCase() + "_STAINED_GLASS_" + type.toUpperCase()); + // Get the StainedGlassStairsBlock or the StainedGlassSlabBlock constructor. + Constructor constructor = type.equals("stairs") ? StainedGlassStairsBlock.class.getConstructor(DyeColor.class, BlockState.class, + AbstractBlock.Settings.class) : StainedGlassSlabBlock.class.getConstructor(DyeColor.class, BlockState.class, AbstractBlock.Settings.class); + // Get the corresponding block in the Blocks class. + Block block = (Block) Blocks.class.getDeclaredField(color.getName().toUpperCase() + "_STAINED_GLASS").get(Blocks.class); + // Set the field to the (registered) block. + blockField.set(ModBlocks.class, register(color.getName() + "_stained_glass_" + type, + (Block) constructor.newInstance(color, block.getDefaultState(), AbstractBlock.Settings.copy(block)))); + } + } } - @SubscribeEvent - @SuppressWarnings("unused") - public static void registerBlocks(RegistryEvent.Register event) - { - IForgeRegistry registry = event.getRegistry(); - BLOCKS.forEach(registry::register); - BLOCKS.clear(); + /** + * Calls the {@link #registerAll()} method and catches the reflection exceptions when thrown. + */ + public static void tryRegisterAll() { + try { + registerAll(); + } catch (NoSuchFieldException | IllegalAccessException | NoSuchMethodException | InvocationTargetException | InstantiationException e) { + LOGGER.error("Error while trying to register blocks via reflection.", e); + } } - @SubscribeEvent - @SuppressWarnings("unused") - public static void registerItems(RegistryEvent.Register event) - { - IForgeRegistry registry = event.getRegistry(); - ITEMS.forEach(registry::register); - ITEMS.clear(); + /** + * Register a block and the corresponding block item. + * @param name the name of the block, e.g. for {@link #WHITE_STAINED_GLASS_SLAB} "white_stained_glass_slab" + * @param block the actual {@link ItemGroup} + * @param group the {@link ItemGroup} + * @return the (registered) block + */ + private static Block register(final String name, final Block block, final ItemGroup group) { + Registry.register(Registry.ITEM, Reference.MOD_ID + ":" + name, new BlockItem(block, new Item.Settings().group(group))); + return Registry.register(Registry.BLOCK, Reference.MOD_ID + ":" + name, block); + } + + /** + * Same as {@link #register(String, Block, ItemGroup)}. Just with the default item group: {@link ItemGroup#BUILDING_BLOCKS}. + */ + private static Block register(final String name, final Block block) { + return register(name, block, ItemGroup.BUILDING_BLOCKS); } } diff --git a/src/main/java/com/mrcrayfish/glasscutter/init/ModContainers.java b/src/main/java/com/mrcrayfish/glasscutter/init/ModContainers.java deleted file mode 100644 index 361bced..0000000 --- a/src/main/java/com/mrcrayfish/glasscutter/init/ModContainers.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.mrcrayfish.glasscutter.init; - -import com.mrcrayfish.glasscutter.Reference; -import com.mrcrayfish.glasscutter.inventory.container.GlasscutterContainer; -import net.minecraft.inventory.container.Container; -import net.minecraft.inventory.container.ContainerType; -import net.minecraftforge.event.RegistryEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.registries.IForgeRegistry; - -import java.util.ArrayList; -import java.util.List; - -/** - * Author: MrCrayfish - */ -@Mod.EventBusSubscriber(modid = Reference.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD) -public class ModContainers -{ - private static final List> CONTAINER_TYPES = new ArrayList<>(); - - public static final ContainerType GLASSCUTTER = register(Reference.MOD_ID + ":glasscutter", GlasscutterContainer::new); - - private static ContainerType register(String key, ContainerType.IFactory factory) - { - ContainerType type = new ContainerType<>(factory); - type.setRegistryName(key); - CONTAINER_TYPES.add(type); - return type; - } - - @SubscribeEvent - @SuppressWarnings("unused") - public static void registerTypes(final RegistryEvent.Register> event) - { - IForgeRegistry> registry = event.getRegistry(); - CONTAINER_TYPES.forEach(registry::register); - CONTAINER_TYPES.clear(); - } -} diff --git a/src/main/java/com/mrcrayfish/glasscutter/init/ModRecipeSerializers.java b/src/main/java/com/mrcrayfish/glasscutter/init/ModRecipeSerializers.java index 8fe297c..c6067cc 100644 --- a/src/main/java/com/mrcrayfish/glasscutter/init/ModRecipeSerializers.java +++ b/src/main/java/com/mrcrayfish/glasscutter/init/ModRecipeSerializers.java @@ -2,41 +2,15 @@ import com.mrcrayfish.glasscutter.Reference; import com.mrcrayfish.glasscutter.item.crafting.GlasscuttingRecipe; -import net.minecraft.item.crafting.IRecipe; -import net.minecraft.item.crafting.IRecipeSerializer; -import net.minecraft.util.ResourceLocation; -import net.minecraftforge.event.RegistryEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.registries.IForgeRegistry; +import net.minecraft.recipe.RecipeSerializer; +import net.minecraft.util.Identifier; +import net.minecraft.util.registry.Registry; -import java.util.ArrayList; -import java.util.List; +public class ModRecipeSerializers { + public static RecipeSerializer GLASSCUTTING; -/** - * Author: MrCrayfish - */ -@Mod.EventBusSubscriber(modid = Reference.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD) -public class ModRecipeSerializers -{ - @SuppressWarnings("rawtypes") - private static final List RECIPES = new ArrayList<>(); - - public static final IRecipeSerializer GLASSCUTTING = register(Reference.MOD_ID + ":glasscutting", new GlasscuttingRecipe.Serializer<>(GlasscuttingRecipe::new)); - - private static >> T register(String name, T t) - { - t.setRegistryName(new ResourceLocation(name)); - RECIPES.add(t); - return t; - } - - @SubscribeEvent - @SuppressWarnings("unused") - public static void registerItems(final RegistryEvent.Register> event) - { - IForgeRegistry> registry = event.getRegistry(); - RECIPES.forEach(item -> event.getRegistry().register(item)); - RECIPES.clear(); + public static void registerAll() { + GLASSCUTTING = Registry.register(Registry.RECIPE_SERIALIZER, + new Identifier(Reference.MOD_ID, "glasscutting"), new GlasscuttingRecipe.Serializer(GlasscuttingRecipe::new)); } } diff --git a/src/main/java/com/mrcrayfish/glasscutter/init/ModRecipeTypes.java b/src/main/java/com/mrcrayfish/glasscutter/init/ModRecipeTypes.java new file mode 100644 index 0000000..92bdde1 --- /dev/null +++ b/src/main/java/com/mrcrayfish/glasscutter/init/ModRecipeTypes.java @@ -0,0 +1,20 @@ +package com.mrcrayfish.glasscutter.init; + +import com.mrcrayfish.glasscutter.Reference; +import com.mrcrayfish.glasscutter.item.crafting.GlasscuttingRecipe; +import net.minecraft.recipe.RecipeType; +import net.minecraft.util.Identifier; +import net.minecraft.util.registry.Registry; + +public class ModRecipeTypes { + public static RecipeType GLASSCUTTING; + + public static void registerAll() { + GLASSCUTTING = Registry.register(Registry.RECIPE_TYPE, new Identifier(Reference.MOD_ID, "glasscutting"), new RecipeType() { + @Override + public String toString() { + return "glasscutting"; + } + }); + } +} diff --git a/src/main/java/com/mrcrayfish/glasscutter/init/ModScreenHandlers.java b/src/main/java/com/mrcrayfish/glasscutter/init/ModScreenHandlers.java new file mode 100644 index 0000000..ab6c909 --- /dev/null +++ b/src/main/java/com/mrcrayfish/glasscutter/init/ModScreenHandlers.java @@ -0,0 +1,19 @@ +package com.mrcrayfish.glasscutter.init; + +import com.mrcrayfish.glasscutter.Reference; +import com.mrcrayfish.glasscutter.client.gui.screen.inventory.GlasscutterScreen; +import com.mrcrayfish.glasscutter.screen_handler.GlasscutterScreenHandler; +import net.fabricmc.fabric.api.client.screenhandler.v1.ScreenRegistry; +import net.fabricmc.fabric.api.screenhandler.v1.ScreenHandlerRegistry; +import net.minecraft.screen.ScreenHandlerType; +import net.minecraft.util.Identifier; + +public class ModScreenHandlers { + public static ScreenHandlerType GLASSCUTTER; + + public static void registerAll() { + GLASSCUTTER = ScreenHandlerRegistry.registerSimple(new Identifier(Reference.MOD_ID, "glasscutter"), + GlasscutterScreenHandler::new); + ScreenRegistry.register(GLASSCUTTER, GlasscutterScreen::new); + } +} diff --git a/src/main/java/com/mrcrayfish/glasscutter/init/ModStats.java b/src/main/java/com/mrcrayfish/glasscutter/init/ModStats.java new file mode 100644 index 0000000..3066a38 --- /dev/null +++ b/src/main/java/com/mrcrayfish/glasscutter/init/ModStats.java @@ -0,0 +1,23 @@ +package com.mrcrayfish.glasscutter.init; + +import com.mrcrayfish.glasscutter.Reference; +import net.minecraft.stat.StatFormatter; +import net.minecraft.stat.Stats; +import net.minecraft.util.Identifier; +import net.minecraft.util.registry.Registry; + +/** + * Mod stats holder class. + * @author justAm0dd3r + */ +public class ModStats { + public static final Identifier INTERACT_WITH_GLASSCUTER = register("interact_with_glasscutter", StatFormatter.DEFAULT); + + @SuppressWarnings("SameParameterValue") + private static Identifier register(String string, StatFormatter statFormatter) { + Identifier identifier = new Identifier(Reference.MOD_ID, string); + Registry.register(Registry.CUSTOM_STAT, string, identifier); + Stats.CUSTOM.getOrCreateStat(identifier, statFormatter); + return identifier; + } +} diff --git a/src/main/java/com/mrcrayfish/glasscutter/inventory/container/GlasscutterContainer.java b/src/main/java/com/mrcrayfish/glasscutter/inventory/container/GlasscutterContainer.java deleted file mode 100644 index c8f2da4..0000000 --- a/src/main/java/com/mrcrayfish/glasscutter/inventory/container/GlasscutterContainer.java +++ /dev/null @@ -1,274 +0,0 @@ -package com.mrcrayfish.glasscutter.inventory.container; - -import com.google.common.collect.Lists; -import com.mrcrayfish.glasscutter.init.ModBlocks; -import com.mrcrayfish.glasscutter.init.ModContainers; -import com.mrcrayfish.glasscutter.item.crafting.GlasscuttingRecipe; -import com.mrcrayfish.glasscutter.item.crafting.RecipeType; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.entity.player.PlayerInventory; -import net.minecraft.inventory.CraftResultInventory; -import net.minecraft.inventory.IInventory; -import net.minecraft.inventory.Inventory; -import net.minecraft.inventory.container.Container; -import net.minecraft.inventory.container.Slot; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.util.IWorldPosCallable; -import net.minecraft.util.IntReferenceHolder; -import net.minecraft.util.SoundCategory; -import net.minecraft.util.SoundEvents; -import net.minecraft.world.World; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; - -import java.util.List; - -/** - * Author: MrCrayfish - */ -public class GlasscutterContainer extends Container -{ - private final IWorldPosCallable worldPosCallable; - private final IntReferenceHolder selectedRecipe; - private final World world; - private List recipes; - private ItemStack itemStackInput; - private long lastOnTake; - private final Slot inputInventorySlot; - private final Slot outputInventorySlot; - private Runnable inventoryUpdateListener = () -> {}; - private final IInventory inputInventory; - private final CraftResultInventory inventory; - - public GlasscutterContainer(int windowId, PlayerInventory playerInventory) - { - this(windowId, playerInventory, IWorldPosCallable.DUMMY); - } - - public GlasscutterContainer(int windowId, PlayerInventory playerInventory, final IWorldPosCallable callable) - { - super(ModContainers.GLASSCUTTER, windowId); - this.selectedRecipe = IntReferenceHolder.single(); - this.recipes = Lists.newArrayList(); - this.itemStackInput = ItemStack.EMPTY; - this.inputInventory = new Inventory(1) - { - @Override - public void markDirty() - { - super.markDirty(); - GlasscutterContainer.this.onCraftMatrixChanged(this); - GlasscutterContainer.this.inventoryUpdateListener.run(); - } - }; - this.inventory = new CraftResultInventory(); - this.worldPosCallable = callable; - this.world = playerInventory.player.world; - this.inputInventorySlot = this.addSlot(new Slot(this.inputInventory, 0, 20, 33)); - this.outputInventorySlot = this.addSlot(new Slot(this.inventory, 1, 143, 33) - { - @Override - public boolean isItemValid(ItemStack stack) - { - return false; - } - - @Override - public ItemStack onTake(PlayerEntity playerEntity, ItemStack stack) - { - ItemStack slotStack = GlasscutterContainer.this.inputInventorySlot.decrStackSize(1); - if(!slotStack.isEmpty()) - { - GlasscutterContainer.this.updateRecipeResultSlot(); - } - - stack.getItem().onCreated(stack, playerEntity.world, playerEntity); - callable.consume((world, pos) -> - { - long gameTime = world.getGameTime(); - if(GlasscutterContainer.this.lastOnTake != gameTime) - { - world.playSound(null, pos, SoundEvents.UI_STONECUTTER_TAKE_RESULT, SoundCategory.BLOCKS, 1.0F, 1.0F); - GlasscutterContainer.this.lastOnTake = gameTime; - } - }); - return super.onTake(playerEntity, stack); - } - }); - - for(int i = 0; i < 3; i++) - { - for(int j = 0; j < 9; j++) - { - this.addSlot(new Slot(playerInventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)); - } - } - - for(int i = 0; i < 9; i++) - { - this.addSlot(new Slot(playerInventory, i, 8 + i * 18, 142)); - } - - this.trackInt(this.selectedRecipe); - } - - @OnlyIn(Dist.CLIENT) - public int getSelectedRecipe() - { - return this.selectedRecipe.get(); - } - - @OnlyIn(Dist.CLIENT) - public List getRecipeList() - { - return this.recipes; - } - - @OnlyIn(Dist.CLIENT) - public int getRecipeListSize() - { - return this.recipes.size(); - } - - @OnlyIn(Dist.CLIENT) - public boolean hasItemsInInputSlot() - { - return this.inputInventorySlot.getHasStack() && !this.recipes.isEmpty(); - } - - @Override - public boolean canInteractWith(PlayerEntity playerEntity) - { - return isWithinUsableDistance(this.worldPosCallable, playerEntity, ModBlocks.GLASSCUTTER); - } - - @Override - public boolean enchantItem(PlayerEntity playerEntity, int index) - { - if(index >= 0 && index < this.recipes.size()) - { - this.selectedRecipe.set(index); - this.updateRecipeResultSlot(); - } - return true; - } - - @Override - public void onCraftMatrixChanged(IInventory inventory) - { - ItemStack stack = this.inputInventorySlot.getStack(); - if(stack.getItem() != this.itemStackInput.getItem()) - { - this.itemStackInput = stack.copy(); - this.updateAvailableRecipes(inventory, stack); - } - } - - private void updateAvailableRecipes(IInventory inventory, ItemStack stack) - { - this.recipes.clear(); - this.selectedRecipe.set(-1); - this.outputInventorySlot.putStack(ItemStack.EMPTY); - if(!stack.isEmpty()) - { - this.recipes = this.world.getRecipeManager().getRecipes(RecipeType.GLASSCUTTING, inventory, this.world); - } - } - - private void updateRecipeResultSlot() - { - if(!this.recipes.isEmpty()) - { - //TODO fix this - GlasscuttingRecipe recipe = this.recipes.get(this.selectedRecipe.get()); - this.outputInventorySlot.putStack(recipe.getCraftingResult(this.inputInventory)); - } - else - { - this.outputInventorySlot.putStack(ItemStack.EMPTY); - } - this.detectAndSendChanges(); - } - - @OnlyIn(Dist.CLIENT) - public void setInventoryUpdateListener(Runnable runnable) - { - this.inventoryUpdateListener = runnable; - } - - public boolean canMergeSlot(ItemStack stack, Slot slot) - { - return slot.inventory != this.inventory && super.canMergeSlot(stack, slot); - } - - public ItemStack transferStackInSlot(PlayerEntity playerEntity, int index) - { - ItemStack copyStack = ItemStack.EMPTY; - Slot slot = this.inventorySlots.get(index); - if(slot != null && slot.getHasStack()) - { - ItemStack slotStack = slot.getStack(); - Item item = slotStack.getItem(); - copyStack = slotStack.copy(); - if(index == 1) - { - item.onCreated(slotStack, playerEntity.world, playerEntity); - if(!this.mergeItemStack(slotStack, 2, 38, true)) - { - return ItemStack.EMPTY; - } - - slot.onSlotChange(slotStack, copyStack); - } - else if(index == 0) - { - if(!this.mergeItemStack(slotStack, 2, 38, false)) - { - return ItemStack.EMPTY; - } - } - else if(this.world.getRecipeManager().getRecipe(RecipeType.GLASSCUTTING, new Inventory(slotStack), this.world).isPresent()) - { - if(!this.mergeItemStack(slotStack, 0, 1, false)) - { - return ItemStack.EMPTY; - } - } - else if(index < 29) - { - if(!this.mergeItemStack(slotStack, 29, 38, false)) - { - return ItemStack.EMPTY; - } - } - else if(index < 38 && !this.mergeItemStack(slotStack, 2, 29, false)) - { - return ItemStack.EMPTY; - } - - if(slotStack.isEmpty()) - { - slot.putStack(ItemStack.EMPTY); - } - - slot.onSlotChanged(); - if(slotStack.getCount() == copyStack.getCount()) - { - return ItemStack.EMPTY; - } - - slot.onTake(playerEntity, slotStack); - this.detectAndSendChanges(); - } - - return copyStack; - } - - public void onContainerClosed(PlayerEntity playerEntity) - { - super.onContainerClosed(playerEntity); - this.inventory.removeStackFromSlot(1); - this.worldPosCallable.consume((world, pos) -> this.clearContainer(playerEntity, playerEntity.world, this.inputInventory)); - } -} diff --git a/src/main/java/com/mrcrayfish/glasscutter/item/crafting/GlasscuttingRecipe.java b/src/main/java/com/mrcrayfish/glasscutter/item/crafting/GlasscuttingRecipe.java index 743da2b..37bf315 100644 --- a/src/main/java/com/mrcrayfish/glasscutter/item/crafting/GlasscuttingRecipe.java +++ b/src/main/java/com/mrcrayfish/glasscutter/item/crafting/GlasscuttingRecipe.java @@ -3,87 +3,77 @@ import com.google.gson.JsonObject; import com.mrcrayfish.glasscutter.init.ModBlocks; import com.mrcrayfish.glasscutter.init.ModRecipeSerializers; -import net.minecraft.inventory.IInventory; +import com.mrcrayfish.glasscutter.init.ModRecipeTypes; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.inventory.Inventory; import net.minecraft.item.ItemStack; -import net.minecraft.item.crafting.IRecipeSerializer; -import net.minecraft.item.crafting.Ingredient; -import net.minecraft.item.crafting.SingleItemRecipe; -import net.minecraft.network.PacketBuffer; -import net.minecraft.util.JSONUtils; -import net.minecraft.util.ResourceLocation; +import net.minecraft.network.PacketByteBuf; +import net.minecraft.recipe.CuttingRecipe; +import net.minecraft.recipe.Ingredient; +import net.minecraft.recipe.RecipeSerializer; +import net.minecraft.util.Identifier; +import net.minecraft.util.JsonHelper; import net.minecraft.util.registry.Registry; import net.minecraft.world.World; /** - * Author: MrCrayfish + * @author justAm0dd3r */ -public class GlasscuttingRecipe extends SingleItemRecipe -{ - public GlasscuttingRecipe(ResourceLocation id, String group, Ingredient ingredient, ItemStack stack) - { - super(RecipeType.GLASSCUTTING, ModRecipeSerializers.GLASSCUTTING, id, group, ingredient, stack); - } +public class GlasscuttingRecipe extends CuttingRecipe { + public GlasscuttingRecipe(Identifier id, String group, Ingredient input, ItemStack output) { + super(ModRecipeTypes.GLASSCUTTING, ModRecipeSerializers.GLASSCUTTING, id, group, input, output); + } - @Override - public boolean matches(IInventory inventory, World world) - { - return this.ingredient.test(inventory.getStackInSlot(0)); - } + @Override + public boolean matches(Inventory inv, World world) { + return this.input.test(inv.getStack(0)); + } - @Override - public ItemStack getIcon() - { - return new ItemStack(ModBlocks.GLASSCUTTER); - } + @Override + @Environment(EnvType.CLIENT) + public ItemStack getRecipeKindIcon() { + return new ItemStack(ModBlocks.GLASSCUTTER); + } - public static class Serializer extends net.minecraftforge.registries.ForgeRegistryEntry> implements IRecipeSerializer - { - private final GlasscuttingRecipe.Serializer.IRecipeFactory factory; + public static class Serializer implements RecipeSerializer { + private final RecipeFactory recipeFactory; - public Serializer(GlasscuttingRecipe.Serializer.IRecipeFactory factory) - { - this.factory = factory; - } + public Serializer(RecipeFactory recipeFactory) { + this.recipeFactory = recipeFactory; + } - @Override - public T read(ResourceLocation recipeId, JsonObject json) - { - String group = JSONUtils.getString(json, "group", ""); - Ingredient ingredient; - if(JSONUtils.isJsonArray(json, "ingredient")) - { - ingredient = Ingredient.deserialize(JSONUtils.getJsonArray(json, "ingredient")); - } - else - { - ingredient = Ingredient.deserialize(JSONUtils.getJsonObject(json, "ingredient")); - } - String result = JSONUtils.getString(json, "result"); - int count = JSONUtils.getInt(json, "count"); - ItemStack stack = new ItemStack(Registry.ITEM.getOrDefault(new ResourceLocation(result)), count); - return this.factory.create(recipeId, group, ingredient, stack); - } + public GlasscuttingRecipe read(Identifier identifier, JsonObject jsonObject) { + String string = JsonHelper.getString(jsonObject, "group", ""); + Ingredient ingredient2; + if (JsonHelper.hasArray(jsonObject, "ingredient")) { + ingredient2 = Ingredient.fromJson(JsonHelper.getArray(jsonObject, "ingredient")); + } else { + ingredient2 = Ingredient.fromJson(JsonHelper.getObject(jsonObject, "ingredient")); + } - @Override - public T read(ResourceLocation recipeId, PacketBuffer buffer) - { - String group = buffer.readString(32767); - Ingredient ingredient = Ingredient.read(buffer); - ItemStack stack = buffer.readItemStack(); - return this.factory.create(recipeId, group, ingredient, stack); - } + String string2 = JsonHelper.getString(jsonObject, "result"); + int i = JsonHelper.getInt(jsonObject, "count"); + ItemStack itemStack = new ItemStack(Registry.ITEM.get(new Identifier(string2)), i); + return this.recipeFactory.create(identifier, string, ingredient2, itemStack); + } - @Override - public void write(PacketBuffer buffer, T recipe) - { - buffer.writeString(recipe.group); - recipe.ingredient.write(buffer); - buffer.writeItemStack(recipe.result); - } + public GlasscuttingRecipe read(Identifier identifier, PacketByteBuf packetByteBuf) { + String string = packetByteBuf.readString(32767); + Ingredient ingredient = Ingredient.fromPacket(packetByteBuf); + ItemStack itemStack = packetByteBuf.readItemStack(); + return this.recipeFactory.create(identifier, string, ingredient, itemStack); + } - public interface IRecipeFactory - { - T create(ResourceLocation id, String group, Ingredient ingredient, ItemStack stack); - } - } -} + public void write(PacketByteBuf packetByteBuf, GlasscuttingRecipe recipe) { + packetByteBuf.writeString(recipe.group); + recipe.input.write(packetByteBuf); + packetByteBuf.writeItemStack(recipe.output); + } + + public interface RecipeFactory { + GlasscuttingRecipe create(Identifier identifier, String string, Ingredient ingredient, ItemStack itemStack); + } + } + +} \ No newline at end of file diff --git a/src/main/java/com/mrcrayfish/glasscutter/item/crafting/RecipeType.java b/src/main/java/com/mrcrayfish/glasscutter/item/crafting/RecipeType.java deleted file mode 100644 index 507aa9c..0000000 --- a/src/main/java/com/mrcrayfish/glasscutter/item/crafting/RecipeType.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.mrcrayfish.glasscutter.item.crafting; - -import com.mrcrayfish.glasscutter.Reference; -import net.minecraft.item.crafting.IRecipe; -import net.minecraft.item.crafting.IRecipeType; -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.registry.Registry; - -/** - * Author: MrCrayfish - */ -public class RecipeType -{ - public static final IRecipeType GLASSCUTTING = register(new ResourceLocation(Reference.MOD_ID, "glasscutting")); - - private static > net.minecraft.item.crafting.IRecipeType register(final ResourceLocation resource) - { - return Registry.register(Registry.RECIPE_TYPE, resource, new IRecipeType() - { - @Override - public String toString() - { - return resource.toString(); - } - }); - } -} diff --git a/src/main/java/com/mrcrayfish/glasscutter/jei/GlassCutterJeiPlugin.java b/src/main/java/com/mrcrayfish/glasscutter/jei/GlassCutterJeiPlugin.java deleted file mode 100644 index 6220c0c..0000000 --- a/src/main/java/com/mrcrayfish/glasscutter/jei/GlassCutterJeiPlugin.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.mrcrayfish.glasscutter.jei; - -import com.google.common.io.CharStreams; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.mrcrayfish.glasscutter.Reference; -import com.mrcrayfish.glasscutter.item.crafting.GlasscuttingRecipe; -import mezz.jei.api.IModPlugin; -import mezz.jei.api.JeiPlugin; -import mezz.jei.api.registration.IRecipeCategoryRegistration; -import mezz.jei.api.registration.IRecipeRegistration; -import mezz.jei.util.ErrorUtil; -import net.minecraft.item.DyeColor; -import net.minecraft.item.crafting.IRecipe; -import net.minecraft.item.crafting.RecipeManager; -import net.minecraft.util.ResourceLocation; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.List; - -@JeiPlugin -public class GlassCutterJeiPlugin implements IModPlugin { - private GlasscuttingRecipeCategory glasscuttingCategory; - private static final Logger LOGGER = LogManager.getLogger(); - - @Override - public ResourceLocation getPluginUid() { - return new ResourceLocation(Reference.MOD_ID, Reference.MOD_ID); - } - - @Override - public void registerCategories(IRecipeCategoryRegistration registration) { - registration.addRecipeCategories(this.glasscuttingCategory = new GlasscuttingRecipeCategory(registration.getJeiHelpers().getGuiHelper())); - } - - @Override - public void registerRecipes(IRecipeRegistration registration) { - ErrorUtil.checkNotNull(this.glasscuttingCategory, "glasscuttingCategory"); - registration.addRecipes(getGlasscuttingRecipes(), new ResourceLocation(Reference.MOD_ID, "glasscutting")); - LOGGER.debug("Added JEI Recipes."); - } - - private List getGlasscuttingRecipes() { - List recipes = new ArrayList<>(); - for (String type : new String[]{"stairs", "slab", "pane"}) { - for (DyeColor dye : DyeColor.values()) { - String path = "data/" + Reference.MOD_ID + "/recipes/cut_" + dye.toString() - + "_stained_glass_to_" + dye.toString() + "_stained_glass_" + type + ".json"; - ResourceLocation resourceLocation = new ResourceLocation(Reference.MOD_ID, "cut_" + dye.toString() - + "_stained_glass_to_" + dye.toString() + "_stained_glass_" + type + ".json"); - addRecipe(recipes, resourceLocation, path); - } - String path = "data/" + Reference.MOD_ID + "/recipes/cut_glass_to_glass_" + type + ".json"; - ResourceLocation resourceLocation = new ResourceLocation(Reference.MOD_ID, "cut_glass_to_glass_" + type + ".json"); - addRecipe(recipes, resourceLocation, path); - } - String path = "data/" + Reference.MOD_ID + "/recipes/cut_glass_to_glass_bottle.json"; - ResourceLocation resourceLocation = new ResourceLocation(Reference.MOD_ID, "cut_glass_to_glass_bottle.json"); - addRecipe(recipes, resourceLocation, path); - return recipes; - } - - private JsonObject getObjectFromPath(String path) { - String jsonString; - try { - InputStream stream = getClass().getClassLoader().getResourceAsStream(path); - jsonString = CharStreams.toString(new InputStreamReader(stream)); - } - catch (IOException e) { - LOGGER.error("Error while trying to get json object from ResourceLocation.", e); - return null; - } - return new JsonParser().parse(jsonString).getAsJsonObject(); - } - - private void addRecipe(List recipes, ResourceLocation resourceLocation, String path) { - JsonObject object = getObjectFromPath(path); - if (object == null) return; - - IRecipe recipe = RecipeManager.deserializeRecipe(resourceLocation, object); - if (!(recipe instanceof GlasscuttingRecipe)) { - LOGGER.error("Wrong recipe type."); - return; - } - recipes.add((GlasscuttingRecipe)recipe); - } -} diff --git a/src/main/java/com/mrcrayfish/glasscutter/jei/GlasscuttingRecipeCategory.java b/src/main/java/com/mrcrayfish/glasscutter/jei/GlasscuttingRecipeCategory.java deleted file mode 100644 index c8b3ea9..0000000 --- a/src/main/java/com/mrcrayfish/glasscutter/jei/GlasscuttingRecipeCategory.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.mrcrayfish.glasscutter.jei; - -import com.mrcrayfish.glasscutter.Reference; -import com.mrcrayfish.glasscutter.item.crafting.GlasscuttingRecipe; -import mezz.jei.api.constants.VanillaRecipeCategoryUid; -import mezz.jei.api.constants.VanillaTypes; -import mezz.jei.api.gui.IRecipeLayout; -import mezz.jei.api.gui.drawable.IDrawable; -import mezz.jei.api.gui.ingredient.IGuiItemStackGroup; -import mezz.jei.api.helpers.IGuiHelper; -import mezz.jei.api.ingredients.IIngredients; -import mezz.jei.api.recipe.category.extensions.IExtendableRecipeCategory; -import mezz.jei.api.recipe.category.extensions.vanilla.crafting.ICraftingCategoryExtension; -import mezz.jei.config.Constants; -import mezz.jei.plugins.vanilla.stonecutting.StoneCuttingRecipeCategory; -import mezz.jei.recipes.ExtendableRecipeCategoryHelper; -import mezz.jei.util.Translator; -import net.minecraft.block.Blocks; -import net.minecraft.item.ItemStack; -import net.minecraft.item.crafting.IRecipe; -import net.minecraft.util.ResourceLocation; - -import java.util.function.Function; - -public class GlasscuttingRecipeCategory implements IExtendableRecipeCategory { - private static final int inputSlot = 0; - private static final int outputSlot = 1; - - private static final ResourceLocation CATEGORY_GLASSCUTTING = new ResourceLocation(Reference.MOD_ID, "glasscutting"); - - public static final int width = 82; - public static final int height = 34; - - private final IDrawable background; - private final IDrawable icon; - private final String localizedName; - - private final ExtendableRecipeCategoryHelper, ICraftingCategoryExtension> extendableHelper = new ExtendableRecipeCategoryHelper<>(GlasscuttingRecipe.class); - public GlasscuttingRecipeCategory(IGuiHelper guiHelper) { - ResourceLocation location = Constants.RECIPE_GUI_VANILLA; - background = guiHelper.createDrawable(location, 0, 220, width, height); - icon = guiHelper.createDrawableIngredient(new ItemStack(Blocks.STONECUTTER)); - localizedName = Translator.translateToLocal("gui.jei.category.glassCutter"); - } - - @Override - public void addCategoryExtension(Class recipeClass, Function extensionFactory) { - extendableHelper.addRecipeExtensionFactory(recipeClass, extensionFactory); - } - - @Override - public ResourceLocation getUid() { - return CATEGORY_GLASSCUTTING; - } - - @Override - public Class getRecipeClass() { - return GlasscuttingRecipe.class; - } - - @Override - public String getTitle() { - return localizedName; - } - - @Override - public IDrawable getBackground() { - return background; - } - - @Override - public IDrawable getIcon() { - return icon; - } - - @Override - public void setIngredients(GlasscuttingRecipe recipe, IIngredients ingredients) { - ingredients.setInputIngredients(recipe.getIngredients()); - ingredients.setOutput(VanillaTypes.ITEM, recipe.getRecipeOutput()); - } - - @Override - public void setRecipe(IRecipeLayout recipeLayout, GlasscuttingRecipe recipe, IIngredients ingredients) { - IGuiItemStackGroup guiItemStacks = recipeLayout.getItemStacks(); - guiItemStacks.init(inputSlot, true, 0, 8); - guiItemStacks.init(outputSlot, false, 60, 8); - - guiItemStacks.set(ingredients); - } -} \ No newline at end of file diff --git a/src/main/java/com/mrcrayfish/glasscutter/screen_handler/GlasscutterScreenHandler.java b/src/main/java/com/mrcrayfish/glasscutter/screen_handler/GlasscutterScreenHandler.java new file mode 100644 index 0000000..a884740 --- /dev/null +++ b/src/main/java/com/mrcrayfish/glasscutter/screen_handler/GlasscutterScreenHandler.java @@ -0,0 +1,235 @@ +package com.mrcrayfish.glasscutter.screen_handler; + +import com.google.common.collect.Lists; +import com.mrcrayfish.glasscutter.init.ModBlocks; +import com.mrcrayfish.glasscutter.init.ModRecipeTypes; +import com.mrcrayfish.glasscutter.init.ModScreenHandlers; +import com.mrcrayfish.glasscutter.item.crafting.GlasscuttingRecipe; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.inventory.CraftingResultInventory; +import net.minecraft.inventory.Inventory; +import net.minecraft.inventory.SimpleInventory; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.screen.Property; +import net.minecraft.screen.ScreenHandler; +import net.minecraft.screen.ScreenHandlerContext; +import net.minecraft.screen.ScreenHandlerType; +import net.minecraft.screen.slot.Slot; +import net.minecraft.sound.SoundCategory; +import net.minecraft.sound.SoundEvents; +import net.minecraft.world.World; + +import java.util.List; + +public class GlasscutterScreenHandler extends ScreenHandler { + private final ScreenHandlerContext context; + private final Property selectedRecipe; + private final World world; + private List availableRecipes; + private ItemStack inputStack; + private long lastTakeTime; + final Slot inputSlot; + final Slot outputSlot; + private Runnable contentsChangedListener; + public final Inventory input; + private final CraftingResultInventory output; + + public GlasscutterScreenHandler(int syncId, PlayerInventory playerInventory) { + this(syncId, playerInventory, ScreenHandlerContext.EMPTY); + } + + public GlasscutterScreenHandler(int syncId, PlayerInventory playerInventory, final ScreenHandlerContext context) { + super(ModScreenHandlers.GLASSCUTTER, syncId); + this.selectedRecipe = Property.create(); + this.availableRecipes = Lists.newArrayList(); + this.inputStack = ItemStack.EMPTY; + this.contentsChangedListener = () -> {}; + this.input = new SimpleInventory(1) { + public void markDirty() { + super.markDirty(); + GlasscutterScreenHandler.this.onContentChanged(this); + GlasscutterScreenHandler.this.contentsChangedListener.run(); + } + }; + this.output = new CraftingResultInventory(); + this.context = context; + this.world = playerInventory.player.world; + this.inputSlot = this.addSlot(new Slot(this.input, 0, 20, 33)); + this.outputSlot = this.addSlot(new Slot(this.output, 1, 143, 33) { + + public boolean canInsert(ItemStack stack) { + return false; + } + + public ItemStack onTakeItem(PlayerEntity player, ItemStack stack) { + stack.onCraft(player.world, player, stack.getCount()); + GlasscutterScreenHandler.this.output.unlockLastRecipe(player); + ItemStack itemStack = GlasscutterScreenHandler.this.inputSlot.takeStack(1); + if (!itemStack.isEmpty()) { + GlasscutterScreenHandler.this.populateResult(); + } + + context.run((world, blockPos) -> { + long l = world.getTime(); + if (GlasscutterScreenHandler.this.lastTakeTime != l) { + world.playSound(null, blockPos, SoundEvents.UI_STONECUTTER_TAKE_RESULT, SoundCategory.BLOCKS, 1.0F, 1.0F); + GlasscutterScreenHandler.this.lastTakeTime = l; + } + }); + return super.onTakeItem(player, stack); + } + }); + + int k; + for(k = 0; k < 3; ++k) { + for(int j = 0; j < 9; ++j) { + this.addSlot(new Slot(playerInventory, j + k * 9 + 9, 8 + j * 18, 84 + k * 18)); + } + } + + + for(k = 0; k < 9; ++k) { + this.addSlot(new Slot(playerInventory, k, 8 + k * 18, 142)); + } + + this.addProperty(this.selectedRecipe); + } + + @Environment(EnvType.CLIENT) + public int getSelectedRecipe() { + return this.selectedRecipe.get(); + } + + @Environment(EnvType.CLIENT) + public List getAvailableRecipes() { + return this.availableRecipes; + } + + @Environment(EnvType.CLIENT) + public int getAvailableRecipeCount() { + return this.availableRecipes.size(); + } + + @Environment(EnvType.CLIENT) + public boolean canCraft() { + return this.inputSlot.hasStack() && !this.availableRecipes.isEmpty(); + } + + public boolean canUse(PlayerEntity player) { + return canUse(this.context, player, ModBlocks.GLASSCUTTER); + } + + public boolean onButtonClick(PlayerEntity player, int id) { + if (this.method_30160(id)) { + this.selectedRecipe.set(id); + this.populateResult(); + } + + return true; + } + + private boolean method_30160(int i) { + return i >= 0 && i < this.availableRecipes.size(); + } + + public void onContentChanged(Inventory inventory) { + ItemStack itemStack = this.inputSlot.getStack(); + if (itemStack.getItem() != this.inputStack.getItem()) { + this.inputStack = itemStack.copy(); + this.updateInput(inventory, itemStack); + } + + } + + private void updateInput(Inventory input, ItemStack stack) { + this.availableRecipes.clear(); + this.selectedRecipe.set(-1); + this.outputSlot.setStack(ItemStack.EMPTY); + if (!stack.isEmpty()) { + this.availableRecipes = this.world.getRecipeManager().getAllMatches(ModRecipeTypes.GLASSCUTTING, input, this.world); + } + } + + private void populateResult() { + if (!this.availableRecipes.isEmpty() && this.method_30160(this.selectedRecipe.get())) { + GlasscuttingRecipe glasscuttingRecipe = this.availableRecipes.get(this.selectedRecipe.get()); + this.output.setLastRecipe(glasscuttingRecipe); + this.outputSlot.setStack(glasscuttingRecipe.craft(this.input)); + } else { + this.outputSlot.setStack(ItemStack.EMPTY); + } + + this.sendContentUpdates(); + } + + public ScreenHandlerType getType() { + return ModScreenHandlers.GLASSCUTTER; + } + + @Environment(EnvType.CLIENT) + public void setContentsChangedListener(Runnable runnable) { + this.contentsChangedListener = runnable; + } + + public boolean canInsertIntoSlot(ItemStack stack, Slot slot) { + return slot.inventory != this.output && super.canInsertIntoSlot(stack, slot); + } + + public ItemStack transferSlot(PlayerEntity player, int index) { + ItemStack itemStack = ItemStack.EMPTY; + Slot slot = this.slots.get(index); + if (slot != null && slot.hasStack()) { + ItemStack itemStack2 = slot.getStack(); + Item item = itemStack2.getItem(); + itemStack = itemStack2.copy(); + if (index == 1) { + item.onCraft(itemStack2, player.world, player); + if (!this.insertItem(itemStack2, 2, 38, true)) { + return ItemStack.EMPTY; + } + + slot.onStackChanged(itemStack2, itemStack); + } else if (index == 0) { + if (!this.insertItem(itemStack2, 2, 38, false)) { + return ItemStack.EMPTY; + } + } else if (this.world.getRecipeManager().getFirstMatch(ModRecipeTypes.GLASSCUTTING, new SimpleInventory(itemStack2), this.world).isPresent()) { + if (!this.insertItem(itemStack2, 0, 1, false)) { + return ItemStack.EMPTY; + } + } else if (index >= 2 && index < 29) { + if (!this.insertItem(itemStack2, 29, 38, false)) { + return ItemStack.EMPTY; + } + } else if (index >= 29 && index < 38 && !this.insertItem(itemStack2, 2, 29, false)) { + return ItemStack.EMPTY; + } + + if (itemStack2.isEmpty()) { + slot.setStack(ItemStack.EMPTY); + } + + slot.markDirty(); + if (itemStack2.getCount() == itemStack.getCount()) { + return ItemStack.EMPTY; + } + + slot.onTakeItem(player, itemStack2); + this.sendContentUpdates(); + } + + return itemStack; + } + + public void close(PlayerEntity player) { + super.close(player); + this.output.removeStack(1); + this.context.run((world, blockPos) -> { + this.dropInventory(player, player.world, this.input); + }); + } +} diff --git a/src/main/resources/assets/glasscutter/lang/en_us.json b/src/main/resources/assets/glasscutter/lang/en_us.json index 67bb59c..cd0d292 100644 --- a/src/main/resources/assets/glasscutter/lang/en_us.json +++ b/src/main/resources/assets/glasscutter/lang/en_us.json @@ -34,7 +34,5 @@ "block.glasscutter.light_blue_stained_glass_slab": "Light Blue Stained Glass Slab", "block.glasscutter.magenta_stained_glass_slab": "Magenta Stained Glass Slab", "block.glasscutter.orange_stained_glass_slab": "Orange Stained Glass Slab", - "block.glasscutter.white_stained_glass_slab": "White Stained Glass Slab", - - "gui.jei.category.glassCutter": "Glasscutting" + "block.glasscutter.white_stained_glass_slab": "White Stained Glass Slab" } \ No newline at end of file diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json new file mode 100644 index 0000000..9cf50b9 --- /dev/null +++ b/src/main/resources/fabric.mod.json @@ -0,0 +1,35 @@ +{ + "schemaVersion": 1, + "id": "glasscutter", + "version": "${version}", + + "name": "GlassCutter", + "description": "Adds a glasscutter to cut different shapes with glass", + "credits": "@DarkestArgentum on Twitter for ideas", + "authors": [ + "MrCrayfish", + "justAm0dd3r" + ], + "contact": { + "homepage": "http://mrcrayfish.com/mods?id=glasscutter", + "sources": "https://github.com/MrCrayfish/GlassCutter" + }, + + "license": "GPLv3", + + "environment": "*", + "entrypoints": { + "main": [ + "com.mrcrayfish.glasscutter.GlassCutterMain" + ] + }, + + "depends": { + "fabricloader": ">=0.7.4", + "fabric": "*", + "minecraft": "1.16.x" + }, + "suggests": { + "flamingo": "*" + } +} From b1d64787ba5e6435bb0391d0863cb9190e40c092 Mon Sep 17 00:00:00 2001 From: Krxwallo Date: Thu, 20 Aug 2020 18:18:22 +0200 Subject: [PATCH 02/11] Fixed version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 5c3ed3a..4d6ae11 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,7 @@ yarn_mappings=1.16.2+build.1 loader_version=0.9.1+build.205 # Mod Properties -mod_version = 1.0.1-1.16.1-fabric +mod_version = 1.1.0-1.16.1-fabric maven_group = com.mrcrayfish archives_base_name = glasscutter From 76bb9af1071f324e3debdd2c0bb1a347fafd81ba Mon Sep 17 00:00:00 2001 From: Krxwallo Date: Thu, 20 Aug 2020 18:20:11 +0200 Subject: [PATCH 03/11] Fixed build.gradle --- build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle b/build.gradle index 4bff684..cd7e48e 100644 --- a/build.gradle +++ b/build.gradle @@ -53,6 +53,7 @@ tasks.withType(JavaCompile) { task sourcesJar(type: Jar, dependsOn: classes) { classifier = "sources" from sourceSets.main.allSource +} jar { from "LICENSE" From fbfb632a6a9bd901419f35992e8f39eeb82f0665 Mon Sep 17 00:00:00 2001 From: Krxwallo <59575572+krxwallo@users.noreply.github.com> Date: Thu, 20 Aug 2020 18:26:45 +0200 Subject: [PATCH 04/11] Fixed build.gradle --- build.gradle | 4 ---- 1 file changed, 4 deletions(-) diff --git a/build.gradle b/build.gradle index cd7e48e..6145ac5 100644 --- a/build.gradle +++ b/build.gradle @@ -6,10 +6,6 @@ plugins { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 -version = "1.1.0-${mc_version}" -group = 'com.mrcrayfish' -archivesBaseName = 'glasscutter' - archivesBaseName = project.archives_base_name version = project.mod_version group = project.maven_group From a2873799988dd3840a1d49856d7711231a97aca5 Mon Sep 17 00:00:00 2001 From: Krxwallo Date: Thu, 20 Aug 2020 18:28:17 +0200 Subject: [PATCH 05/11] Fixed en_us.json --- src/main/resources/assets/glasscutter/lang/en_us.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/assets/glasscutter/lang/en_us.json b/src/main/resources/assets/glasscutter/lang/en_us.json index 88ff146..cd0d292 100644 --- a/src/main/resources/assets/glasscutter/lang/en_us.json +++ b/src/main/resources/assets/glasscutter/lang/en_us.json @@ -34,5 +34,5 @@ "block.glasscutter.light_blue_stained_glass_slab": "Light Blue Stained Glass Slab", "block.glasscutter.magenta_stained_glass_slab": "Magenta Stained Glass Slab", "block.glasscutter.orange_stained_glass_slab": "Orange Stained Glass Slab", - "block.glasscutter.white_stained_glass_slab": "White Stained Glass Slab", + "block.glasscutter.white_stained_glass_slab": "White Stained Glass Slab" } \ No newline at end of file From 4cf033eeb8394dc6fc0e1451f0be3c27a842f4c9 Mon Sep 17 00:00:00 2001 From: Krxwallo Date: Thu, 20 Aug 2020 19:00:42 +0200 Subject: [PATCH 06/11] Fixed only working with minecraft 1.16.2 --- gradle.properties | 2 +- src/main/resources/fabric.mod.json | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/gradle.properties b/gradle.properties index 93a69af..3ea96b0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,7 +9,7 @@ yarn_mappings=1.16.2+build.1 loader_version=0.9.1+build.205 # Mod Properties -mod_version = 1.1.0-1.16.1-fabric +mod_version = 1.1.0-1.16-fabric maven_group = com.mrcrayfish archives_base_name = glasscutter diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 9cf50b9..3ede93f 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -26,8 +26,7 @@ "depends": { "fabricloader": ">=0.7.4", - "fabric": "*", - "minecraft": "1.16.x" + "fabric": "*" }, "suggests": { "flamingo": "*" From 2bd5addae4e95c3b81625a8c84aebce172d384d4 Mon Sep 17 00:00:00 2001 From: Krxwallo Date: Fri, 21 Aug 2020 12:09:52 +0200 Subject: [PATCH 07/11] Update README.md Signed-off-by: Krxwallo --- README.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e3fc578..7f59b61 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,14 @@ +![GlassCutter Banner](https://i.imgur.com/jnLyKd4.png) + +[![Download](https://img.shields.io/static/v1?label=&message=Download&color=2d2d2d&labelColor=dddddd&style=for-the-badge&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAALEQAACxEBf2RfkQAAAAd0SU1FB98BHA41LJJkRpIAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuMvvhp8YAAAGGSURBVDhPjZK9SgNBFIVHBEUE8QeMhLAzdzdYBFL7CmnstEjjO4iFjWClFiGJm42VFpYSUptKRfABFBQE7UUI2AmGmPXM5k6cjFE8cJjZ3fPduTOzIiJarvl+bPmuLuWS+K/KmcwUoK4pEGoTnetvYTY7GUpZOCTa0sZi+QRyhQ83pkBShKjDUBvzGKNxr6rU8W4uN8FoX4CKEcB6EMR61OZOEtApEqNIndFvAbiNuAB30QeU+sDYBXSCdw3MrzHvlnx/kdFkC3kU6NkwF3iM0ukFnNM8R0UplZquKHWE85nhV0Kg4o4GrDMwre5x5G9h9aaBHL/VPI849rtqRFfwqALaIcd+F87gYnDy1ha0sY12VcoiR0cLq5/ae3e3gyLbHB2tMAgKQ1fXh+z5a1mpDXQyy8hPIdgyAEMDW8+fWOQJHbfgzXUhxhkXYh/3jcC9C7s2V43c+9DPpHXgeXMIXbqQbV7gAV5hbFixEGMVolUEmvjjXuBeRcoOnp/R/hm81hi0LsQX8OcRBvBjZ8YAAAAASUVORK5CYII=)](https://mrcrayfish.com/mods?id=glasscutter) ![Minecraft](https://img.shields.io/static/v1?label=&message=1.15&color=2d2d2d&labelColor=dddddd&style=for-the-badge&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuMjCGJ1kDAAACoElEQVQ4T22SeU8aURTF/ULGtNRWWVQY9lXABWldIDPIMgVbNgEVtaa0damiqGBdipXaJcY2ofEf4ycbTt97pVAabzK5b27u+Z377kwXgK77QthRy7OfXbeJM+ttqKSXN8sdwbT/A0L7elmsYqrPHZmROLPh5YkV4oEBwaKuHj+yyJptLDoAhbq3O1V1XCVObY3FL24mfn5oRPrcwSCRfQOyNWcjVjZdCbtcdwcgXrXUspdOKbDN/XE9tiBJMhXHT60gUIT2dMhcDLMc3NVKQklz0QIkf5qlyEcO6Qs7yPhMJB4amDMFimQSmqNlE8SKAZFzDfxHfVILIIZ10sJ3OwIbcqSuiOjchkzNCboHev9o2YhgiUP8mxnLN24I6/3ghYdtQG5iUMpFBuCP9iKwLsfiLyeCp2rMnZgwX3NArGoxW1Ridl+BzLEVKa8KSxOqNmDdz0kFnxaLHhWEgAyZigWhHXL+pEDy2ozsDxv8vAzTnh7w5kcghqCaFmCT10of4iPIT2mRdPUh4HoCcVwBH/8Ac2kzUkEV5r3EfVSOvbAJa5NDyI0r2oDtWb1EClh+OoC3Pg7v/Bw7p939yI4rsRW2Y3lKh01eh7WpIRyKZqzyjjYgPdIvlaMWRqYuG7wWryYHsRM0sFolZiPvQ3jheIwSmSBPdkByG/B6Wi3RYiVmRX7GiAPiUCRisii8D+jZNKvPBrHCW1GY0bAz6WkDCtOaSyKQFsi4K5NqNiZtehN2Y5uAShETqolhBqJXpfdPuPsuWwAaRdHSkxdc11mPqkGnyY4pyKbpl1GyJ0Pel7yqBoFcF3zqno5f+d8ohYy9Sx7lzQpxo1eirluCDgt++00p6uxttrG4F/A39sJGZWZMfrcp6O6+5kaVzXJHAOj6DeSs8qw5o8oxAAAAAElFTkSuQmCC) ![Curseforge](http://cf.way2muchnoise.eu/full_glasscutter_downloads.svg?badge_style=for_the_badge) + # GlassCutter - Adds a glass cutter to create different shaped glass blocks! + +This is a simple mod that adds a glass cutter into the game. This block allows you to cut glass into different shapes. This mod adds stairs and slabs for every type of glass. + +### Crafting: +![Glasscutter Crafting](https://i.imgur.com/aETv57f.png) + +### Screenshots +![Glass Stairs and Slabs](https://i.imgur.com/xWqR3el.png) +![GlassCutter GUI](https://i.imgur.com/igBABjt.png) \ No newline at end of file From 149a4e1101bf9621badf4822c71aeae91d37cd40 Mon Sep 17 00:00:00 2001 From: Krxwallo Date: Fri, 21 Aug 2020 12:21:23 +0200 Subject: [PATCH 08/11] Update README.md Signed-off-by: Krxwallo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7f59b61..3388be7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ![GlassCutter Banner](https://i.imgur.com/jnLyKd4.png) -[![Download](https://img.shields.io/static/v1?label=&message=Download&color=2d2d2d&labelColor=dddddd&style=for-the-badge&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAALEQAACxEBf2RfkQAAAAd0SU1FB98BHA41LJJkRpIAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuMvvhp8YAAAGGSURBVDhPjZK9SgNBFIVHBEUE8QeMhLAzdzdYBFL7CmnstEjjO4iFjWClFiGJm42VFpYSUptKRfABFBQE7UUI2AmGmPXM5k6cjFE8cJjZ3fPduTOzIiJarvl+bPmuLuWS+K/KmcwUoK4pEGoTnetvYTY7GUpZOCTa0sZi+QRyhQ83pkBShKjDUBvzGKNxr6rU8W4uN8FoX4CKEcB6EMR61OZOEtApEqNIndFvAbiNuAB30QeU+sDYBXSCdw3MrzHvlnx/kdFkC3kU6NkwF3iM0ukFnNM8R0UplZquKHWE85nhV0Kg4o4GrDMwre5x5G9h9aaBHL/VPI849rtqRFfwqALaIcd+F87gYnDy1ha0sY12VcoiR0cLq5/ae3e3gyLbHB2tMAgKQ1fXh+z5a1mpDXQyy8hPIdgyAEMDW8+fWOQJHbfgzXUhxhkXYh/3jcC9C7s2V43c+9DPpHXgeXMIXbqQbV7gAV5hbFixEGMVolUEmvjjXuBeRcoOnp/R/hm81hi0LsQX8OcRBvBjZ8YAAAAASUVORK5CYII=)](https://mrcrayfish.com/mods?id=glasscutter) ![Minecraft](https://img.shields.io/static/v1?label=&message=1.15&color=2d2d2d&labelColor=dddddd&style=for-the-badge&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuMjCGJ1kDAAACoElEQVQ4T22SeU8aURTF/ULGtNRWWVQY9lXABWldIDPIMgVbNgEVtaa0damiqGBdipXaJcY2ofEf4ycbTt97pVAabzK5b27u+Z377kwXgK77QthRy7OfXbeJM+ttqKSXN8sdwbT/A0L7elmsYqrPHZmROLPh5YkV4oEBwaKuHj+yyJptLDoAhbq3O1V1XCVObY3FL24mfn5oRPrcwSCRfQOyNWcjVjZdCbtcdwcgXrXUspdOKbDN/XE9tiBJMhXHT60gUIT2dMhcDLMc3NVKQklz0QIkf5qlyEcO6Qs7yPhMJB4amDMFimQSmqNlE8SKAZFzDfxHfVILIIZ10sJ3OwIbcqSuiOjchkzNCboHev9o2YhgiUP8mxnLN24I6/3ghYdtQG5iUMpFBuCP9iKwLsfiLyeCp2rMnZgwX3NArGoxW1Ridl+BzLEVKa8KSxOqNmDdz0kFnxaLHhWEgAyZigWhHXL+pEDy2ozsDxv8vAzTnh7w5kcghqCaFmCT10of4iPIT2mRdPUh4HoCcVwBH/8Ac2kzUkEV5r3EfVSOvbAJa5NDyI0r2oDtWb1EClh+OoC3Pg7v/Bw7p939yI4rsRW2Y3lKh01eh7WpIRyKZqzyjjYgPdIvlaMWRqYuG7wWryYHsRM0sFolZiPvQ3jheIwSmSBPdkByG/B6Wi3RYiVmRX7GiAPiUCRisii8D+jZNKvPBrHCW1GY0bAz6WkDCtOaSyKQFsi4K5NqNiZtehN2Y5uAShETqolhBqJXpfdPuPsuWwAaRdHSkxdc11mPqkGnyY4pyKbpl1GyJ0Pel7yqBoFcF3zqno5f+d8ohYy9Sx7lzQpxo1eirluCDgt++00p6uxttrG4F/A39sJGZWZMfrcp6O6+5kaVzXJHAOj6DeSs8qw5o8oxAAAAAElFTkSuQmCC) ![Curseforge](http://cf.way2muchnoise.eu/full_glasscutter_downloads.svg?badge_style=for_the_badge) +[![Download](https://img.shields.io/static/v1?label=&message=Download&color=2d2d2d&labelColor=dddddd&style=for-the-badge&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAALEQAACxEBf2RfkQAAAAd0SU1FB98BHA41LJJkRpIAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuMvvhp8YAAAGGSURBVDhPjZK9SgNBFIVHBEUE8QeMhLAzdzdYBFL7CmnstEjjO4iFjWClFiGJm42VFpYSUptKRfABFBQE7UUI2AmGmPXM5k6cjFE8cJjZ3fPduTOzIiJarvl+bPmuLuWS+K/KmcwUoK4pEGoTnetvYTY7GUpZOCTa0sZi+QRyhQ83pkBShKjDUBvzGKNxr6rU8W4uN8FoX4CKEcB6EMR61OZOEtApEqNIndFvAbiNuAB30QeU+sDYBXSCdw3MrzHvlnx/kdFkC3kU6NkwF3iM0ukFnNM8R0UplZquKHWE85nhV0Kg4o4GrDMwre5x5G9h9aaBHL/VPI849rtqRFfwqALaIcd+F87gYnDy1ha0sY12VcoiR0cLq5/ae3e3gyLbHB2tMAgKQ1fXh+z5a1mpDXQyy8hPIdgyAEMDW8+fWOQJHbfgzXUhxhkXYh/3jcC9C7s2V43c+9DPpHXgeXMIXbqQbV7gAV5hbFixEGMVolUEmvjjXuBeRcoOnp/R/hm81hi0LsQX8OcRBvBjZ8YAAAAASUVORK5CYII=)](https://mrcrayfish.com/mods?id=glasscutter) ![Minecraft](https://img.shields.io/static/v1?label=&message=1.15&color=2d2d2d&labelColor=dddddd&style=for-the-badge&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuMjCGJ1kDAAACoElEQVQ4T22SeU8aURTF/ULGtNRWWVQY9lXABWldIDPIMgVbNgEVtaa0damiqGBdipXaJcY2ofEf4ycbTt97pVAabzK5b27u+Z377kwXgK77QthRy7OfXbeJM+ttqKSXN8sdwbT/A0L7elmsYqrPHZmROLPh5YkV4oEBwaKuHj+yyJptLDoAhbq3O1V1XCVObY3FL24mfn5oRPrcwSCRfQOyNWcjVjZdCbtcdwcgXrXUspdOKbDN/XE9tiBJMhXHT60gUIT2dMhcDLMc3NVKQklz0QIkf5qlyEcO6Qs7yPhMJB4amDMFimQSmqNlE8SKAZFzDfxHfVILIIZ10sJ3OwIbcqSuiOjchkzNCboHev9o2YhgiUP8mxnLN24I6/3ghYdtQG5iUMpFBuCP9iKwLsfiLyeCp2rMnZgwX3NArGoxW1Ridl+BzLEVKa8KSxOqNmDdz0kFnxaLHhWEgAyZigWhHXL+pEDy2ozsDxv8vAzTnh7w5kcghqCaFmCT10of4iPIT2mRdPUh4HoCcVwBH/8Ac2kzUkEV5r3EfVSOvbAJa5NDyI0r2oDtWb1EClh+OoC3Pg7v/Bw7p939yI4rsRW2Y3lKh01eh7WpIRyKZqzyjjYgPdIvlaMWRqYuG7wWryYHsRM0sFolZiPvQ3jheIwSmSBPdkByG/B6Wi3RYiVmRX7GiAPiUCRisii8D+jZNKvPBrHCW1GY0bAz6WkDCtOaSyKQFsi4K5NqNiZtehN2Y5uAShETqolhBqJXpfdPuPsuWwAaRdHSkxdc11mPqkGnyY4pyKbpl1GyJ0Pel7yqBoFcF3zqno5f+d8ohYy9Sx7lzQpxo1eirluCDgt++00p6uxttrG4F/A39sJGZWZMfrcp6O6+5kaVzXJHAOj6DeSs8qw5o8oxAAAAAElFTkSuQmCC) [![Curseforge](http://cf.way2muchnoise.eu/full_glasscutter_downloads.svg?badge_style=for_the_badge)](https://www.curseforge.com/minecraft/mc-mods/glasscutter) # GlassCutter From ef1866e5ba053096f2605ca30709ef876e8453f7 Mon Sep 17 00:00:00 2001 From: Krxwallo Date: Fri, 21 Aug 2020 18:32:36 +0200 Subject: [PATCH 09/11] Added missing author declarations. Signed-off-by: Krxwallo --- .../com/mrcrayfish/glasscutter/init/ModRecipeSerializers.java | 3 +++ .../java/com/mrcrayfish/glasscutter/init/ModRecipeTypes.java | 3 +++ .../com/mrcrayfish/glasscutter/init/ModScreenHandlers.java | 3 +++ .../glasscutter/screen_handler/GlasscutterScreenHandler.java | 3 +++ 4 files changed, 12 insertions(+) diff --git a/src/main/java/com/mrcrayfish/glasscutter/init/ModRecipeSerializers.java b/src/main/java/com/mrcrayfish/glasscutter/init/ModRecipeSerializers.java index c6067cc..07de677 100644 --- a/src/main/java/com/mrcrayfish/glasscutter/init/ModRecipeSerializers.java +++ b/src/main/java/com/mrcrayfish/glasscutter/init/ModRecipeSerializers.java @@ -6,6 +6,9 @@ import net.minecraft.util.Identifier; import net.minecraft.util.registry.Registry; +/** + * @author justAm0dd3r + */ public class ModRecipeSerializers { public static RecipeSerializer GLASSCUTTING; diff --git a/src/main/java/com/mrcrayfish/glasscutter/init/ModRecipeTypes.java b/src/main/java/com/mrcrayfish/glasscutter/init/ModRecipeTypes.java index 92bdde1..37d24c1 100644 --- a/src/main/java/com/mrcrayfish/glasscutter/init/ModRecipeTypes.java +++ b/src/main/java/com/mrcrayfish/glasscutter/init/ModRecipeTypes.java @@ -6,6 +6,9 @@ import net.minecraft.util.Identifier; import net.minecraft.util.registry.Registry; +/** + * @author justAm0dd3r + */ public class ModRecipeTypes { public static RecipeType GLASSCUTTING; diff --git a/src/main/java/com/mrcrayfish/glasscutter/init/ModScreenHandlers.java b/src/main/java/com/mrcrayfish/glasscutter/init/ModScreenHandlers.java index ab6c909..6c3ce9e 100644 --- a/src/main/java/com/mrcrayfish/glasscutter/init/ModScreenHandlers.java +++ b/src/main/java/com/mrcrayfish/glasscutter/init/ModScreenHandlers.java @@ -8,6 +8,9 @@ import net.minecraft.screen.ScreenHandlerType; import net.minecraft.util.Identifier; +/** + * @author justAm0dd3r + */ public class ModScreenHandlers { public static ScreenHandlerType GLASSCUTTER; diff --git a/src/main/java/com/mrcrayfish/glasscutter/screen_handler/GlasscutterScreenHandler.java b/src/main/java/com/mrcrayfish/glasscutter/screen_handler/GlasscutterScreenHandler.java index a884740..b3737c5 100644 --- a/src/main/java/com/mrcrayfish/glasscutter/screen_handler/GlasscutterScreenHandler.java +++ b/src/main/java/com/mrcrayfish/glasscutter/screen_handler/GlasscutterScreenHandler.java @@ -25,6 +25,9 @@ import java.util.List; +/** + * @author justAm0dd3r + */ public class GlasscutterScreenHandler extends ScreenHandler { private final ScreenHandlerContext context; private final Property selectedRecipe; From 3fd943e4691723773f9aabbd1d5a6c7dbf6d6cdb Mon Sep 17 00:00:00 2001 From: Krxwallo Date: Sat, 22 Aug 2020 18:10:33 +0200 Subject: [PATCH 10/11] Cleaned up some code... Signed-off-by: Krxwallo --- .../glasscutter/client/ClientHandler.java | 33 +---------- .../glasscutter/init/ModBlocks.java | 55 +++++-------------- 2 files changed, 14 insertions(+), 74 deletions(-) diff --git a/src/main/java/com/mrcrayfish/glasscutter/client/ClientHandler.java b/src/main/java/com/mrcrayfish/glasscutter/client/ClientHandler.java index dff0a11..603eb00 100644 --- a/src/main/java/com/mrcrayfish/glasscutter/client/ClientHandler.java +++ b/src/main/java/com/mrcrayfish/glasscutter/client/ClientHandler.java @@ -15,37 +15,6 @@ public static void setup() BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.GLASSCUTTER, RenderLayer.getCutout()); BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.GLASS_STAIRS, RenderLayer.getCutout()); BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.GLASS_SLAB, RenderLayer.getCutout()); - BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.WHITE_STAINED_GLASS_STAIRS, RenderLayer.getTranslucent()); - BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.ORANGE_STAINED_GLASS_STAIRS, RenderLayer.getTranslucent()); - BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.MAGENTA_STAINED_GLASS_STAIRS, RenderLayer.getTranslucent()); - BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.LIGHT_BLUE_STAINED_GLASS_STAIRS, RenderLayer.getTranslucent()); - BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.YELLOW_STAINED_GLASS_STAIRS, RenderLayer.getTranslucent()); - BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.LIME_STAINED_GLASS_STAIRS, RenderLayer.getTranslucent()); - BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.PINK_STAINED_GLASS_STAIRS, RenderLayer.getTranslucent()); - BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.GRAY_STAINED_GLASS_STAIRS, RenderLayer.getTranslucent()); - BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.LIGHT_GRAY_STAINED_GLASS_STAIRS, RenderLayer.getTranslucent()); - BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.CYAN_STAINED_GLASS_STAIRS, RenderLayer.getTranslucent()); - BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.PURPLE_STAINED_GLASS_STAIRS, RenderLayer.getTranslucent()); - BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.BLUE_STAINED_GLASS_STAIRS, RenderLayer.getTranslucent()); - BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.BROWN_STAINED_GLASS_STAIRS, RenderLayer.getTranslucent()); - BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.GREEN_STAINED_GLASS_STAIRS, RenderLayer.getTranslucent()); - BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.RED_STAINED_GLASS_STAIRS, RenderLayer.getTranslucent()); - BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.BLACK_STAINED_GLASS_STAIRS, RenderLayer.getTranslucent()); - BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.WHITE_STAINED_GLASS_SLAB, RenderLayer.getTranslucent()); - BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.ORANGE_STAINED_GLASS_SLAB, RenderLayer.getTranslucent()); - BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.MAGENTA_STAINED_GLASS_SLAB, RenderLayer.getTranslucent()); - BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.LIGHT_BLUE_STAINED_GLASS_SLAB, RenderLayer.getTranslucent()); - BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.YELLOW_STAINED_GLASS_SLAB, RenderLayer.getTranslucent()); - BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.LIME_STAINED_GLASS_SLAB, RenderLayer.getTranslucent()); - BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.PINK_STAINED_GLASS_SLAB, RenderLayer.getTranslucent()); - BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.GRAY_STAINED_GLASS_SLAB, RenderLayer.getTranslucent()); - BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.LIGHT_GRAY_STAINED_GLASS_SLAB, RenderLayer.getTranslucent()); - BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.CYAN_STAINED_GLASS_SLAB, RenderLayer.getTranslucent()); - BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.PURPLE_STAINED_GLASS_SLAB, RenderLayer.getTranslucent()); - BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.BLUE_STAINED_GLASS_SLAB, RenderLayer.getTranslucent()); - BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.BROWN_STAINED_GLASS_SLAB, RenderLayer.getTranslucent()); - BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.GREEN_STAINED_GLASS_SLAB, RenderLayer.getTranslucent()); - BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.RED_STAINED_GLASS_SLAB, RenderLayer.getTranslucent()); - BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.BLACK_STAINED_GLASS_SLAB, RenderLayer.getTranslucent()); + ModBlocks.getTranslucentBlocks().forEach((block -> BlockRenderLayerMap.INSTANCE.putBlock(block, RenderLayer.getTranslucent()))); } } diff --git a/src/main/java/com/mrcrayfish/glasscutter/init/ModBlocks.java b/src/main/java/com/mrcrayfish/glasscutter/init/ModBlocks.java index 9b5e5f3..b2668c5 100644 --- a/src/main/java/com/mrcrayfish/glasscutter/init/ModBlocks.java +++ b/src/main/java/com/mrcrayfish/glasscutter/init/ModBlocks.java @@ -12,60 +12,32 @@ import org.apache.logging.log4j.Logger; import java.lang.reflect.Constructor; -import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; /** * Author: MrCrayfish - * - * Do not change the field names! */ public class ModBlocks { public static Block GLASSCUTTER; public static Block GLASS_STAIRS; public static Block GLASS_SLAB; - public static Block WHITE_STAINED_GLASS_STAIRS; - public static Block ORANGE_STAINED_GLASS_STAIRS; - public static Block MAGENTA_STAINED_GLASS_STAIRS; - public static Block LIGHT_BLUE_STAINED_GLASS_STAIRS; - public static Block YELLOW_STAINED_GLASS_STAIRS; - public static Block LIME_STAINED_GLASS_STAIRS; - public static Block PINK_STAINED_GLASS_STAIRS; - public static Block GRAY_STAINED_GLASS_STAIRS; - public static Block LIGHT_GRAY_STAINED_GLASS_STAIRS; - public static Block CYAN_STAINED_GLASS_STAIRS; - public static Block PURPLE_STAINED_GLASS_STAIRS; - public static Block BLUE_STAINED_GLASS_STAIRS; - public static Block BROWN_STAINED_GLASS_STAIRS; - public static Block GREEN_STAINED_GLASS_STAIRS; - public static Block RED_STAINED_GLASS_STAIRS; - public static Block BLACK_STAINED_GLASS_STAIRS; - public static Block WHITE_STAINED_GLASS_SLAB; - public static Block ORANGE_STAINED_GLASS_SLAB; - public static Block MAGENTA_STAINED_GLASS_SLAB; - public static Block LIGHT_BLUE_STAINED_GLASS_SLAB; - public static Block YELLOW_STAINED_GLASS_SLAB; - public static Block LIME_STAINED_GLASS_SLAB; - public static Block PINK_STAINED_GLASS_SLAB; - public static Block GRAY_STAINED_GLASS_SLAB; - public static Block LIGHT_GRAY_STAINED_GLASS_SLAB; - public static Block CYAN_STAINED_GLASS_SLAB; - public static Block PURPLE_STAINED_GLASS_SLAB; - public static Block BLUE_STAINED_GLASS_SLAB; - public static Block BROWN_STAINED_GLASS_SLAB; - public static Block GREEN_STAINED_GLASS_SLAB; - public static Block RED_STAINED_GLASS_SLAB; - public static Block BLACK_STAINED_GLASS_SLAB; + + public static ArrayList getTranslucentBlocks() { + return translucentBlocks; + } + + private static final ArrayList translucentBlocks = new ArrayList<>(); private static final Logger LOGGER = LogManager.getLogger(); /** * Try to register the blocks via reflection. (not that repetitive). Trows tons of reflection exceptions. - * @throws NoSuchFieldException when there are no fields found. probably someone has renamed the fields... + * @throws NoSuchFieldException when a field, e.g. {@link Blocks#WHITE_STAINED_GLASS} wasn't found. * @throws NoSuchMethodException when a method wasn't found. * @throws InstantiationException when an error occurs during the {@link StainedGlassSlabBlock} or {@link StainedGlassStairsBlock} constructor call. */ - public static void registerAll() throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException { + public static void registerAll() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException, NoSuchFieldException { // Glasscutter GLASSCUTTER = register("glasscutter", new GlasscutterBlock(AbstractBlock.Settings.of(Material.STONE).strength(3.5F)), ItemGroup.DECORATIONS); // Glass Stairs @@ -76,16 +48,15 @@ public static void registerAll() throws NoSuchFieldException, IllegalAccessExcep for (DyeColor color: DyeColor.values()) { String[] types = new String[] { "stairs", "slab" }; for (String type : types) { - // Get the field. - Field blockField = ModBlocks.class.getField(color.getName().toUpperCase() + "_STAINED_GLASS_" + type.toUpperCase()); // Get the StainedGlassStairsBlock or the StainedGlassSlabBlock constructor. Constructor constructor = type.equals("stairs") ? StainedGlassStairsBlock.class.getConstructor(DyeColor.class, BlockState.class, AbstractBlock.Settings.class) : StainedGlassSlabBlock.class.getConstructor(DyeColor.class, BlockState.class, AbstractBlock.Settings.class); // Get the corresponding block in the Blocks class. Block block = (Block) Blocks.class.getDeclaredField(color.getName().toUpperCase() + "_STAINED_GLASS").get(Blocks.class); // Set the field to the (registered) block. - blockField.set(ModBlocks.class, register(color.getName() + "_stained_glass_" + type, - (Block) constructor.newInstance(color, block.getDefaultState(), AbstractBlock.Settings.copy(block)))); + block = register(color.getName() + "_stained_glass_" + type, + (Block) constructor.newInstance(color, block.getDefaultState(), AbstractBlock.Settings.copy(block))); + translucentBlocks.add(block); } } } @@ -103,7 +74,7 @@ public static void tryRegisterAll() { /** * Register a block and the corresponding block item. - * @param name the name of the block, e.g. for {@link #WHITE_STAINED_GLASS_SLAB} "white_stained_glass_slab" + * @param name the name of the block, e.g. "white_stained_glass_slab" * @param block the actual {@link ItemGroup} * @param group the {@link ItemGroup} * @return the (registered) block From 055d6292ba9eec25708d92073b1d9857b77fdcf9 Mon Sep 17 00:00:00 2001 From: Krxwallo Date: Sat, 22 Aug 2020 18:17:59 +0200 Subject: [PATCH 11/11] Optimized Imports Signed-off-by: Krxwallo --- .../glasscutter/block/AbstractGlassSlabBlock.java | 10 +++------- .../mrcrayfish/glasscutter/block/GlassStairsBlock.java | 3 --- .../glasscutter/block/StainedGlassStairsBlock.java | 2 -- 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/mrcrayfish/glasscutter/block/AbstractGlassSlabBlock.java b/src/main/java/com/mrcrayfish/glasscutter/block/AbstractGlassSlabBlock.java index 3318818..63f9741 100644 --- a/src/main/java/com/mrcrayfish/glasscutter/block/AbstractGlassSlabBlock.java +++ b/src/main/java/com/mrcrayfish/glasscutter/block/AbstractGlassSlabBlock.java @@ -1,13 +1,9 @@ package com.mrcrayfish.glasscutter.block; -import com.mrcrayfish.glasscutter.init.ModBlocks; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.block.*; -import net.minecraft.block.enums.BlockHalf; -import net.minecraft.block.enums.SlabType; +import net.minecraft.block.BlockState; +import net.minecraft.block.ShapeContext; +import net.minecraft.block.SlabBlock; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShapes; import net.minecraft.world.BlockView; diff --git a/src/main/java/com/mrcrayfish/glasscutter/block/GlassStairsBlock.java b/src/main/java/com/mrcrayfish/glasscutter/block/GlassStairsBlock.java index 8bec501..774e5b2 100644 --- a/src/main/java/com/mrcrayfish/glasscutter/block/GlassStairsBlock.java +++ b/src/main/java/com/mrcrayfish/glasscutter/block/GlassStairsBlock.java @@ -1,10 +1,7 @@ package com.mrcrayfish.glasscutter.block; -import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; -import java.util.function.Supplier; - /** * Author: MrCrayfish */ diff --git a/src/main/java/com/mrcrayfish/glasscutter/block/StainedGlassStairsBlock.java b/src/main/java/com/mrcrayfish/glasscutter/block/StainedGlassStairsBlock.java index ed355b0..2c5ddc8 100644 --- a/src/main/java/com/mrcrayfish/glasscutter/block/StainedGlassStairsBlock.java +++ b/src/main/java/com/mrcrayfish/glasscutter/block/StainedGlassStairsBlock.java @@ -4,8 +4,6 @@ import net.minecraft.block.Stainable; import net.minecraft.util.DyeColor; -import java.util.function.Supplier; - /** * Author: MrCrayfish */