diff --git a/.gitignore b/.gitignore index ef25fb7..31d2550 100644 --- a/.gitignore +++ b/.gitignore @@ -1,122 +1,26 @@ -# User-specific stuff -.idea/ - -*.iml +# eclipse +bin +*.launch +.settings +.metadata +.classpath +.project + +# idea +out *.ipr *.iws +*.iml +.idea -# IntelliJ -out/ -# mpeltonen/sbt-idea plugin -.idea_modules/ - -# JIRA plugin -atlassian-ide-plugin.xml - -# Compiled class file -*.class - -# Log file -*.log - -# BlueJ files -*.ctxt - -# Package Files # -*.jar -*.war -*.nar -*.ear -*.zip -*.tar.gz -*.rar - -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml -hs_err_pid* - -*~ - -# temporary files which can be created if a process still has a handle open of a deleted file -.fuse_hidden* - -# KDE directory preferences -.directory - -# Linux trash folder which might appear on any partition or disk -.Trash-* - -# .nfs files are created when an open file is removed but is still being accessed -.nfs* - -# General -.DS_Store -.AppleDouble -.LSOverride - -# Icon must end with two \r -Icon - -# Thumbnails -._* - -# Files that might appear in the root of a volume -.DocumentRevisions-V100 -.fseventsd -.Spotlight-V100 -.TemporaryItems -.Trashes -.VolumeIcon.icns -.com.apple.timemachine.donotpresent - -# Directories potentially created on remote AFP share -.AppleDB -.AppleDesktop -Network Trash Folder -Temporary Items -.apdisk - -# Windows thumbnail cache files -Thumbs.db -Thumbs.db:encryptable -ehthumbs.db -ehthumbs_vista.db - -# Dump file -*.stackdump - -# Folder config file -[Dd]esktop.ini - -# Recycle Bin used on file shares -$RECYCLE.BIN/ - -# Windows Installer files -*.cab -*.msi -*.msix -*.msm -*.msp - -# Windows shortcuts -*.lnk - +# gradle +build .gradle -build/ - -# Ignore Gradle GUI config -gradle-app.setting - -# Cache of project -.gradletasknamecache - -**/build/ - -# Common working directory -run/ -# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) -!gradle-wrapper.jar -*.psd +# other +eclipse +run +runs +run-data -run_* -**\logs +repo \ No newline at end of file diff --git a/README.md b/README.md index c45a1c7..b421122 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,25 @@ -# PowerTool -一堆 Minecraft 内的线上展会可能会用到的小玩意。 +Installation information +======= -Gadgets that online convention organizers may find useful when holding conventions inside Minecraft. +This template repository can be directly cloned to get you started with a new +mod. Simply create a new repository cloned from this one, by following the +instructions provided by [GitHub](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template). -## 特性列表 +Once you have your clone, simply open the repository in the IDE of your choice. The usual recommendation for an IDE is either IntelliJ IDEA or Eclipse. - - 周期循环命令方块儿:按一定频率(周期)循环执行命令的命令方块。 - - 垃圾桶:外观和原版堆肥桶一致,但丢入其中的物品会立即消失。 - - 电源:提供任意数量的 FE 能量输出。 - - 供货箱:创造模式下可设定其中的内容物,非创造模式下可以取出。 - - 漏斗(装饰品):外观和原版漏斗一致的方块,但没有任何实际功能,也没有方块实体。和原版漏斗一样可以朝四个方向旋转。 - - 营火(装饰品):外观和营火一致的方块,但没有任何实际功能,也没有方块实体。不能当作烟雾信号源使用。 - - 灵魂营火(装饰品):外观和灵魂营火一致的方块,但没有任何实际功能,也没有方块实体。不能当作烟雾信号源使用。 - - 全息投影告示牌:和空气类似的方块,但能像告示牌一样显示文字,可以选择一定朝向玩家或者面向垂直于y轴的特定方向。创造模式下右击可打开编辑界面。 - - 看起来没用的木棍:没有任何功能的物品,外观和原版木棍一致,但有附魔的特效。 - - MoTD:玩家进入游戏后会收到一条聊天消息,消息内容可自定义。 - - 栅栏绳结:原版拴绳现在可以将两根栅栏拴在一起。 - - 更多没有方块实体的“装饰”方块 - - 物品展示框和荧光物品展示框(但是方块版本):可以旋转其中物品,支持红石比较器检测,支持隐藏框体。极难破坏。 - - 透明刷:右键可直接将方块模式的展示框变为透明。 - - 未完待续 To be continued +If at any point you are missing libraries in your IDE, or you've run into problems you can +run `gradlew --refresh-dependencies` to refresh the local cache. `gradlew clean` to reset everything +{this does not affect your code} and then start the process again. -## 鸣谢 +Mapping Names: +============ +By default, the MDK is configured to use the official mapping names from Mojang for methods and fields +in the Minecraft codebase. These names are covered by a specific license. All modders should be aware of this +license. For the latest license text, refer to the mapping file itself, or the reference copy here: +https://github.com/NeoForged/NeoForm/blob/main/Mojang.md - - `src/main/resources/assets/powertool/sound/item/clap.ogg` - 出自 [https://freesound.org/people/mikaelfernstrom/sounds/68727/](https://freesound.org/people/mikaelfernstrom/sounds/68727/), - 在 CC-BY 4.0 许可证下发布,有修改。 - - 全息投影告示牌的部分代码改编自 [ModFest 团队维护的 GlowCase 模组](https://github.com/ModFest/glowcase),该模组代码在 CC-1.0 许可证下发布。 +Additional Resources: +========== +Community Documentation: https://docs.neoforged.net/ +NeoForged Discord: https://discord.neoforged.net/ diff --git a/build.gradle b/build.gradle index bed266a..98600c6 100644 --- a/build.gradle +++ b/build.gradle @@ -1,58 +1,121 @@ -buildscript { - repositories { - // These repositories are only for Gradle plugins, put any other repositories in the repository block further below - maven { url = 'https://repo.spongepowered.org/repository/maven-public/' } - maven { url = 'https://maven.minecraftforge.net' } - maven { url = 'https://maven.parchmentmc.org' } - mavenCentral() - } - dependencies { - classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '[6.0,6.2)' - classpath 'org.spongepowered:mixingradle:0.7-SNAPSHOT' - classpath group: 'org.parchmentmc', name: 'librarian', version: '1.+' - } +plugins { + id 'java-library' + id 'eclipse' + id 'idea' + id 'maven-publish' + id 'net.neoforged.moddev' version '1.0.14' } -apply plugin: 'eclipse' -apply plugin: 'maven-publish' -apply plugin: 'net.minecraftforge.gradle' -apply plugin: 'org.parchmentmc.librarian.forgegradle' -apply plugin: 'org.spongepowered.mixin' +tasks.named('wrapper', Wrapper).configure { + // Define wrapper values here so as to not have to always do so when updating gradlew.properties. + // Switching this to Wrapper.DistributionType.ALL will download the full gradle sources that comes with + // documentation attached on cursor hover of gradle classes and methods. However, this comes with increased + // file size for Gradle. If you do switch this to ALL, run the Gradle wrapper task twice afterwards. + // (Verify by checking gradle/wrapper/gradle-wrapper.properties to see if distributionUrl now points to `-all`) + distributionType = Wrapper.DistributionType.BIN +} -apply from: 'gradle/teacon-forge.gradle' +version = mod_version +group = mod_group_id -java { - toolchain.languageVersion = JavaLanguageVersion.of(17) +repositories { + mavenLocal() } -teacon { - modId = 'powertool' - modVersion = '1.3.6' - modLicense = 'GPL-3.0' - modGitHubRepo = 'teaconmc/PowerTool' - modAuthors = ['IzzelAliz'] - modDescription = 'PowerTool by TeaCon' - platform = 'forge-1.20-46.0.1' - - // uncomment these lines if you need - modName = 'PowerTool' // default to repo name - // modGitHubBranch = 1.18-forge // for referring the license - modifyMemberAccess = true // for access transformer - useDataGeneration = true // for data generation - // publishTask = shadowJar // for shadow jar or other usages - // lazyTokens = ['minecraft_classpath': { project.configurations.shadow.asPath }] // for runtime tokens - - // use './gradlew -q printModMeta > src/main/resources/META-INF/mods.toml' to generate mod meta +base { + archivesName = mod_id } -mixin { - add sourceSets.main, "powertool.refmap.json" +// Mojang ships Java 21 to end users starting in 1.20.5, so mods should target Java 21. +java.toolchain.languageVersion = JavaLanguageVersion.of(21) + +neoForge { + // Specify the version of NeoForge to use. + version = project.neo_version + + accessTransformers { + file('src/main/resources/META-INF/accesstransformer.cfg') + } + + parchment { + mappingsVersion = project.parchment_mappings_version + minecraftVersion = project.parchment_minecraft_version + } + + // This line is optional. Access Transformers are automatically detected + // accessTransformers = project.files('src/main/resources/META-INF/accesstransformer.cfg') + + // Default run configurations. + // These can be tweaked, removed, or duplicated as needed. + runs { + client { + client() + + // Comma-separated list of namespaces to load gametests from. Empty = all namespaces. + systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id + } + + server { + server() + programArgument '--nogui' + systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id + } + + // This run config launches GameTestServer and runs all registered gametests, then exits. + // By default, the server will crash when no gametests are provided. + // The gametest system is also enabled by default for other run configs under the /test command. + gameTestServer { + type = "gameTestServer" + systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id + } + + data { + data() + + // example of overriding the workingDirectory set in configureEach above, uncomment if you want to use it + // gameDirectory = project.file('run-data') + + // Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources. + programArguments.addAll '--mod', project.mod_id, '--all', '--output', file('src/generated/resources/').getAbsolutePath(), '--existing', file('src/main/resources/').getAbsolutePath() + } + + // applies to all the run configs above + configureEach { + // Recommended logging data for a userdev environment + // The markers can be added/remove as needed separated by commas. + // "SCAN": For mods scan. + // "REGISTRIES": For firing of registry events. + // "REGISTRYDUMP": For getting the contents of all registries. + systemProperty 'forge.logging.markers', 'REGISTRIES' + + // Recommended logging level for the console + // You can set various levels here. + // Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels + logLevel = org.slf4j.event.Level.DEBUG + } + } - config "powertool.mixins.json" + mods { + // define mod <-> source bindings + // these are used to tell the game which sources are for which mod + // mostly optional in a single mod project + // but multi mod projects should define one per mod + "${mod_id}" { + sourceSet(sourceSets.main) + } + } } -//sourceSets.main.resources { srcDir 'src/generated/resources' } +// Include resources generated by data generators. +sourceSets.main.resources { srcDir 'src/generated/resources' } +// Sets up a dependency configuration called 'localRuntime'. +// This configuration should be used instead of 'runtimeOnly' to declare +// a dependency that will be present for runtime testing but that is +// "optional", meaning it will not be pulled by dependents of this mod. +configurations { + runtimeClasspath.extendsFrom localRuntime +} repositories { maven { @@ -62,9 +125,89 @@ repositories { includeGroup "curse.maven" } } + maven { + // location of the maven that hosts JEI files since January 2023 + name = "Jared's maven" + url = "https://maven.blamejared.com/" + } + maven { + // location of a maven mirror for JEI files, as a fallback + name = "ModMaven" + url = "https://modmaven.dev" + } } dependencies { - annotationProcessor 'org.spongepowered:mixin:0.8.5:processor' - implementation fg.deobf("curse.maven:the-one-probe-245211:4579432") + // Example optional mod dependency with JEI + // The JEI API is declared for compile time use, while the full JEI artifact is used at runtime + // compileOnly "mezz.jei:jei-${mc_version}-common-api:${jei_version}" + // compileOnly "mezz.jei:jei-${mc_version}-neoforge-api:${jei_version}" + // We add the full version to localRuntime, not runtimeOnly, so that we do not publish a dependency on it + localRuntime "mezz.jei:jei-${minecraft_version}-neoforge:${jei_version}" + + // Example mod dependency using a mod jar from ./libs with a flat dir repository + // This maps to ./libs/coolmod-${mc_version}-${coolmod_version}.jar + // The group id is ignored when searching -- in this case, it is "blank" + // implementation "blank:coolmod-${mc_version}:${coolmod_version}" + implementation "curse.maven:the-one-probe-245211:5502323" + // Example mod dependency using a file as dependency + // implementation files("libs/coolmod-${mc_version}-${coolmod_version}.jar") + + // Example project dependency using a sister or child project: + // implementation project(":myproject") + + // For more info: + // http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html + // http://www.gradle.org/docs/current/userguide/dependency_management.html +} + +// This block of code expands all declared replace properties in the specified resource targets. +// A missing property will result in an error. Properties are expanded using ${} Groovy notation. +// When "copyIdeResources" is enabled, this will also run before the game launches in IDE environments. +// See https://docs.gradle.org/current/dsl/org.gradle.language.jvm.tasks.ProcessResources.html +tasks.withType(ProcessResources).configureEach { + var replaceProperties = [ + minecraft_version : minecraft_version, + minecraft_version_range: minecraft_version_range, + neo_version : neo_version, + neo_version_range : neo_version_range, + loader_version_range : loader_version_range, + mod_id : mod_id, + mod_name : mod_name, + mod_license : mod_license, + mod_version : mod_version, + mod_authors : mod_authors, + mod_description : mod_description + ] + inputs.properties replaceProperties + + filesMatching(['META-INF/neoforge.mods.toml']) { + expand replaceProperties + } +} + +// Example configuration to allow publishing using the maven-publish plugin +publishing { + publications { + register('mavenJava', MavenPublication) { + from components.java + } + } + repositories { + maven { + url "file://${project.projectDir}/repo" + } + } +} + +tasks.withType(JavaCompile).configureEach { + options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation +} + +// IDEA no longer automatically downloads sources/javadoc jars for dependencies, so we need to explicitly enable the behavior. +idea { + module { + downloadSources = true + downloadJavadoc = true + } } diff --git a/gradle.properties b/gradle.properties index 29b2ac4..ba27583 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,2 +1,47 @@ -org.gradle.jvmargs=-Xmx3G -org.gradle.daemon=false +# Sets default memory used for gradle commands. Can be overridden by user or command line properties. +org.gradle.jvmargs=-Xmx1G +org.gradle.daemon=true +org.gradle.parallel=true +org.gradle.caching=true +org.gradle.configuration-cache=true + +#read more on this at https://github.com/neoforged/ModDevGradle?tab=readme-ov-file#better-minecraft-parameter-names--javadoc-parchment +# you can also find the latest versions at: https://parchmentmc.org/docs/getting-started +parchment_minecraft_version=1.21 +parchment_mappings_version=2024.07.07 +# Environment Properties +# You can find the latest versions here: https://projects.neoforged.net/neoforged/neoforge +# The Minecraft version must agree with the Neo version to get a valid artifact +minecraft_version=1.21 +# The Minecraft version range can use any release version of Minecraft as bounds. +# Snapshots, pre-releases, and release candidates are not guaranteed to sort properly +# as they do not follow standard versioning conventions. +minecraft_version_range=[1.21,1.21.1) +# The Neo version must agree with the Minecraft version to get a valid artifact +neo_version=21.0.139-beta +# The Neo version range can use any version of Neo as bounds +neo_version_range=[21.0.0-beta,) +# The loader version range can only use the major version of FML as bounds +loader_version_range=[4,) + +## Mod Properties + +# The unique mod identifier for the mod. Must be lowercase in English locale. Must fit the regex [a-z][a-z0-9_]{1,63} +# Must match the String constant located in the main mod class annotated with @Mod. +mod_id=powertool +# The human-readable display name for the mod. +mod_name=Power Tool +# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default. +mod_license=GPL-3.0 +# The mod version. See https://semver.org/ +mod_version=1.3.7 +# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository. +# This should match the base package used for the mod sources. +# See https://maven.apache.org/guides/mini/guide-naming-conventions.html +mod_group_id=org.teacon.powertool +# The authors of the mod. This is a simple text string that is used for display purposes in the mod list. +mod_authors=IzzelAliz +# The description of the mod. This is a simple multiline text string that is used for display purposes in the mod list. +mod_description=PowerTool by TeaCon + +jei_version = 19.5.0.61 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 41d9927..2c35211 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 59bc51a..09523c0 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 1b6c787..f5feea6 100755 --- a/gradlew +++ b/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -80,13 +82,12 @@ do esac done -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" +# This is normally unused +# shellcheck disable=SC2034 APP_BASE_NAME=${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='"-Xmx64m" "-Xms64m"' +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -133,22 +134,29 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -193,11 +201,15 @@ if "$cygwin" || "$msys" ; then done fi -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ @@ -205,6 +217,12 @@ set -- \ org.gradle.wrapper.GradleWrapperMain \ "$@" +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. diff --git a/gradlew.bat b/gradlew.bat index 107acd3..9d21a21 100755 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,8 +13,10 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +27,8 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,13 +43,13 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -56,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -75,13 +78,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/settings.gradle b/settings.gradle index 0cb0c7e..ada876e 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,8 +1,11 @@ pluginManagement { repositories { + mavenLocal() gradlePluginPortal() - maven { url = 'https://maven.minecraftforge.net/' } + maven { url = 'https://maven.neoforged.net/releases' } } } -rootProject.name = 'powertool' +plugins { + id 'org.gradle.toolchains.foojay-resolver-convention' version '0.8.0' +} diff --git a/src/generated/resources/.cache/86465dcd1331b21a960f3496f736ce9922bfa9ba b/src/generated/resources/.cache/86465dcd1331b21a960f3496f736ce9922bfa9ba index 72c26b0..0d8b30e 100644 --- a/src/generated/resources/.cache/86465dcd1331b21a960f3496f736ce9922bfa9ba +++ b/src/generated/resources/.cache/86465dcd1331b21a960f3496f736ce9922bfa9ba @@ -1,4 +1,4 @@ -// 1.20 2023-08-28T21:46:30.187848 Block States: powertool +// 1.21 2024-07-26T20:43:32.1114678 Block States: powertool ae6ddabd13bd84907c7fc7fdb01186954fc13502 assets/powertool/blockstates/cosmetic_barrel.json 05b788f1ac0190925f20bbc680cb68c445d80223 assets/powertool/blockstates/cosmetic_beehive.json e771ba4339b87af1e3d3af179b69b99b0221f4f6 assets/powertool/blockstates/cosmetic_blast_furnace.json diff --git a/src/main/java/org/teacon/powertool/PowerTool.java b/src/main/java/org/teacon/powertool/PowerTool.java index b3de94c..74e83c3 100644 --- a/src/main/java/org/teacon/powertool/PowerTool.java +++ b/src/main/java/org/teacon/powertool/PowerTool.java @@ -1,27 +1,26 @@ package org.teacon.powertool; -import net.minecraftforge.fml.ModLoadingContext; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.fml.ModLoadingContext; +import net.neoforged.fml.common.Mod; +import org.teacon.powertool.attachment.PowerToolAttachments; import org.teacon.powertool.block.PowerToolBlocks; import org.teacon.powertool.entity.PowerToolEntities; import org.teacon.powertool.item.PowerToolItems; import org.teacon.powertool.menu.PowerToolMenus; -import org.teacon.powertool.network.PowerToolNetwork; @Mod(PowerTool.MODID) public class PowerTool { public static final String MODID = "powertool"; - public PowerTool() { - PowerToolBlocks.register(); - PowerToolItems.register(); - PowerToolNetwork.register(); - PowerToolMenus.register(); - var bus = FMLJavaModLoadingContext.get().getModEventBus(); + public PowerTool(IEventBus bus) { + PowerToolBlocks.register(bus); + PowerToolItems.register(bus); + PowerToolMenus.register(bus); PowerToolSoundEvents.register(bus); PowerToolEntities.register(bus); - PowerToolConfig.init(ModLoadingContext.get()); + PowerToolAttachments.register(bus); + PowerToolConfig.init(ModLoadingContext.get().getActiveContainer()); } } diff --git a/src/main/java/org/teacon/powertool/PowerToolConfig.java b/src/main/java/org/teacon/powertool/PowerToolConfig.java index b5b9598..282ec67 100644 --- a/src/main/java/org/teacon/powertool/PowerToolConfig.java +++ b/src/main/java/org/teacon/powertool/PowerToolConfig.java @@ -1,30 +1,32 @@ package org.teacon.powertool; -import net.minecraftforge.common.ForgeConfigSpec; -import net.minecraftforge.common.ForgeHooks; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.ModLoadingContext; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.config.ModConfig; -import net.minecraftforge.fml.event.config.ModConfigEvent; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.ModContainer; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.fml.config.ModConfig; +import net.neoforged.fml.event.config.ModConfigEvent; +import net.neoforged.neoforge.common.CommonHooks; +import net.neoforged.neoforge.common.ModConfigSpec; import org.teacon.powertool.motd.MotDHandler; -@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD, modid = PowerTool.MODID) +@EventBusSubscriber(bus = EventBusSubscriber.Bus.MOD, modid = PowerTool.MODID) public class PowerToolConfig { - public static ForgeConfigSpec.ConfigValue motdContent; + public static ModConfigSpec.ConfigValue motdContent; - public static void init(ModLoadingContext context) { - var configSpec = new ForgeConfigSpec.Builder(); - motdContent = configSpec.comment("Message-of-the-day content.").define("motd", ""); - context.registerConfig(ModConfig.Type.SERVER, configSpec.build()); + public static void init(ModContainer container) { + var builder = new ModConfigSpec.Builder(); + motdContent = builder + .comment("Message-of-the-day content.") + .define("motd",""); + container.registerConfig(ModConfig.Type.SERVER, builder.build()); } @SubscribeEvent public static void onConfigReload(ModConfigEvent.Reloading event) { var motdText = motdContent.get(); - if (motdText != null && !motdText.isEmpty()) { - MotDHandler.motd = ForgeHooks.newChatWithLinks(motdContent.get()); + if (!motdText.isEmpty()) { + MotDHandler.motd = CommonHooks.newChatWithLinks(motdContent.get()); } } } diff --git a/src/main/java/org/teacon/powertool/PowerToolSoundEvents.java b/src/main/java/org/teacon/powertool/PowerToolSoundEvents.java index 84f67fb..c08791d 100644 --- a/src/main/java/org/teacon/powertool/PowerToolSoundEvents.java +++ b/src/main/java/org/teacon/powertool/PowerToolSoundEvents.java @@ -1,17 +1,17 @@ package org.teacon.powertool; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.core.registries.Registries; import net.minecraft.sounds.SoundEvent; -import net.minecraftforge.eventbus.api.IEventBus; -import net.minecraftforge.registries.DeferredRegister; -import net.minecraftforge.registries.ForgeRegistries; -import net.minecraftforge.registries.RegistryObject; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.registries.DeferredHolder; +import net.neoforged.neoforge.registries.DeferredRegister; +import org.teacon.powertool.utils.VanillaUtils; public class PowerToolSoundEvents { - public static final DeferredRegister SOUND_EVENTS = DeferredRegister.create(ForgeRegistries.SOUND_EVENTS, PowerTool.MODID); + public static final DeferredRegister SOUND_EVENTS = DeferredRegister.create(Registries.SOUND_EVENT, PowerTool.MODID); - public static final RegistryObject CLAP = SOUND_EVENTS.register("clap", () -> SoundEvent.createFixedRangeEvent(new ResourceLocation(PowerTool.MODID, "item.powertool.clap"), 16F)); + public static final DeferredHolder CLAP = SOUND_EVENTS.register("clap", () -> SoundEvent.createFixedRangeEvent(VanillaUtils.resourceLocationOf(PowerTool.MODID, "item.powertool.clap"), 16F)); public static void register(IEventBus bus) { SOUND_EVENTS.register(bus); diff --git a/src/main/java/org/teacon/powertool/attachment/PowerToolAttachments.java b/src/main/java/org/teacon/powertool/attachment/PowerToolAttachments.java new file mode 100644 index 0000000..9977984 --- /dev/null +++ b/src/main/java/org/teacon/powertool/attachment/PowerToolAttachments.java @@ -0,0 +1,21 @@ +package org.teacon.powertool.attachment; + +import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.attachment.AttachmentType; +import net.neoforged.neoforge.registries.DeferredHolder; +import net.neoforged.neoforge.registries.DeferredRegister; +import net.neoforged.neoforge.registries.NeoForgeRegistries; +import org.teacon.powertool.PowerTool; +import org.teacon.powertool.network.attachment.Permission; + +public class PowerToolAttachments { + + private static final DeferredRegister> ATTACHMENT_TYPE = DeferredRegister.create(NeoForgeRegistries.ATTACHMENT_TYPES, PowerTool.MODID); + + public static final DeferredHolder,AttachmentType> PERMISSION = ATTACHMENT_TYPE.register(Permission.KEY.getPath(), + () -> AttachmentType.builder(Permission::new).build()); + + public static void register(IEventBus bus){ + ATTACHMENT_TYPE.register(bus); + } +} diff --git a/src/main/java/org/teacon/powertool/block/CosmeticBarrel.java b/src/main/java/org/teacon/powertool/block/CosmeticBarrel.java index 5cfa3a1..257b84f 100644 --- a/src/main/java/org/teacon/powertool/block/CosmeticBarrel.java +++ b/src/main/java/org/teacon/powertool/block/CosmeticBarrel.java @@ -2,23 +2,24 @@ import net.minecraft.ChatFormatting; import net.minecraft.network.chat.Component; +import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.TooltipFlag; -import net.minecraft.world.level.BlockGetter; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; import java.util.List; +@ParametersAreNonnullByDefault public class CosmeticBarrel extends CosmeticDirectionalBlock{ public CosmeticBarrel(Properties p) { super(p); } - + @Override - public void appendHoverText(@NotNull ItemStack stack, @Nullable BlockGetter pLevel, List tooltip, TooltipFlag flag) { - tooltip.add(Component.translatable("block.powertool.cosmetic_barrel.tooltip").withStyle(ChatFormatting.DARK_GRAY)); + public void appendHoverText(ItemStack stack, Item.TooltipContext context, List tooltipComponents, TooltipFlag tooltipFlag) { + tooltipComponents.add(Component.translatable("block.powertool.cosmetic_barrel.tooltip").withStyle(ChatFormatting.DARK_GRAY)); } + } diff --git a/src/main/java/org/teacon/powertool/block/CosmeticBeehive.java b/src/main/java/org/teacon/powertool/block/CosmeticBeehive.java index b97430a..ac192f4 100644 --- a/src/main/java/org/teacon/powertool/block/CosmeticBeehive.java +++ b/src/main/java/org/teacon/powertool/block/CosmeticBeehive.java @@ -2,23 +2,24 @@ import net.minecraft.ChatFormatting; import net.minecraft.network.chat.Component; +import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.TooltipFlag; -import net.minecraft.world.level.BlockGetter; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; import java.util.List; +@ParametersAreNonnullByDefault public class CosmeticBeehive extends CosmeticHorizontalDirectionalBlock{ public CosmeticBeehive(Properties p) { super(p); } - + @Override - public void appendHoverText(@NotNull ItemStack stack, @Nullable BlockGetter pLevel, List tooltip, TooltipFlag flag) { - tooltip.add(Component.translatable("block.powertool.cosmetic_beehive.tooltip").withStyle(ChatFormatting.DARK_GRAY)); + public void appendHoverText(ItemStack stack, Item.TooltipContext context, List tooltipComponents, TooltipFlag tooltipFlag) { + tooltipComponents.add(Component.translatable("block.powertool.cosmetic_beehive.tooltip").withStyle(ChatFormatting.DARK_GRAY)); } + } diff --git a/src/main/java/org/teacon/powertool/block/CosmeticCampfireBlock.java b/src/main/java/org/teacon/powertool/block/CosmeticCampfireBlock.java index 64ee4bd..19f7a3d 100644 --- a/src/main/java/org/teacon/powertool/block/CosmeticCampfireBlock.java +++ b/src/main/java/org/teacon/powertool/block/CosmeticCampfireBlock.java @@ -1,19 +1,22 @@ package org.teacon.powertool.block; import net.minecraft.ChatFormatting; +import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.network.chat.Component; import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; import net.minecraft.tags.ItemTags; import net.minecraft.util.RandomSource; import net.minecraft.world.InteractionHand; -import net.minecraft.world.InteractionResult; +import net.minecraft.world.ItemInteractionResult; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.projectile.Projectile; +import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.item.context.BlockPlaceContext; @@ -38,11 +41,14 @@ import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; -import net.minecraftforge.registries.ForgeRegistries; import org.jetbrains.annotations.Nullable; +import org.teacon.powertool.utils.VanillaUtils; +import javax.annotation.ParametersAreNonnullByDefault; import java.util.List; +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault public class CosmeticCampfireBlock extends Block implements SimpleWaterloggedBlock { protected static final VoxelShape SHAPE = Block.box(0.0D, 0.0D, 0.0D, 16.0D, 7.0D, 16.0D); @@ -59,19 +65,19 @@ public CosmeticCampfireBlock(boolean pSpawnParticles, BlockBehaviour.Properties .setValue(WATERLOGGED, Boolean.FALSE) .setValue(FACING, Direction.NORTH)); } - + @Override - public void appendHoverText(ItemStack stack, @Nullable BlockGetter pLevel, List tooltip, TooltipFlag flag) { - var regName = ForgeRegistries.ITEMS.getKey(stack.getItem()); + public void appendHoverText(ItemStack stack, Item.TooltipContext context, List tooltipComponents, TooltipFlag tooltipFlag) { + var regName = BuiltInRegistries.ITEM.getKey(stack.getItem()); if (regName != null) { - tooltip.add(Component.translatable("block." + regName.getNamespace() + "." + regName.getPath() + ".tooltip").withStyle(ChatFormatting.DARK_GRAY)); + tooltipComponents.add(Component.translatable("block." + regName.getNamespace() + "." + regName.getPath() + ".tooltip").withStyle(ChatFormatting.DARK_GRAY)); } + super.appendHoverText(stack, context, tooltipComponents, tooltipFlag); } - + @Override - public InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { - var held = player.getItemInHand(hand); - if (held.is(ItemTags.SHOVELS) && state.getValue(LIT)) { + protected ItemInteractionResult useItemOn(ItemStack stack, BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hitResult) { + if (stack.is(ItemTags.SHOVELS) && state.getValue(LIT)) { if (level.isClientSide()) { for(int i = 0; i < 20; ++i) { CampfireBlock.makeParticles(level, pos, false, true); @@ -80,10 +86,10 @@ public InteractionResult use(BlockState state, Level level, BlockPos pos, Player var newState = state.setValue(LIT, Boolean.FALSE); level.setBlock(pos, newState, Block.UPDATE_ALL_IMMEDIATE); level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(player, newState)); - held.hurtAndBreak(1, player, p -> p.broadcastBreakEvent(hand)); - return InteractionResult.sidedSuccess(level.isClientSide()); + stack.hurtAndBreak(1, player, VanillaUtils.equipmentSlotFromHand(hand)); + return ItemInteractionResult.sidedSuccess(level.isClientSide()); } - return InteractionResult.PASS; + return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; } @Override @@ -170,11 +176,13 @@ public FluidState getFluidState(BlockState pState) { } @Override + @SuppressWarnings("deprecation") public BlockState rotate(BlockState pState, Rotation pRot) { return pState.setValue(FACING, pRot.rotate(pState.getValue(FACING))); } @Override + @SuppressWarnings("deprecation") public BlockState mirror(BlockState pState, Mirror pMirror) { return pState.rotate(pMirror.getRotation(pState.getValue(FACING))); } @@ -183,9 +191,9 @@ public BlockState mirror(BlockState pState, Mirror pMirror) { protected void createBlockStateDefinition(StateDefinition.Builder builder) { builder.add(LIT, WATERLOGGED, FACING); } - + @Override - public boolean isPathfindable(BlockState pState, BlockGetter pLevel, BlockPos pPos, PathComputationType pType) { + protected boolean isPathfindable(BlockState state, PathComputationType pathComputationType) { return false; } diff --git a/src/main/java/org/teacon/powertool/block/CosmeticFurnace.java b/src/main/java/org/teacon/powertool/block/CosmeticFurnace.java index b54a6ee..1f22434 100644 --- a/src/main/java/org/teacon/powertool/block/CosmeticFurnace.java +++ b/src/main/java/org/teacon/powertool/block/CosmeticFurnace.java @@ -1,12 +1,14 @@ package org.teacon.powertool.block; import net.minecraft.ChatFormatting; +import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.network.chat.Component; import net.minecraft.world.InteractionHand; -import net.minecraft.world.InteractionResult; +import net.minecraft.world.ItemInteractionResult; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.item.TooltipFlag; @@ -18,12 +20,11 @@ import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.BooleanProperty; import net.minecraft.world.phys.BlockHitResult; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import javax.annotation.ParametersAreNonnullByDefault; import java.util.List; +@MethodsReturnNonnullByDefault @ParametersAreNonnullByDefault public class CosmeticFurnace extends CosmeticHorizontalDirectionalBlock{ @@ -33,26 +34,25 @@ public CosmeticFurnace(Properties p) { super(p); this.registerDefaultState(this.stateDefinition.any().setValue(FACING, Direction.NORTH).setValue(LIT, false)); } - + @Override - public void appendHoverText(@NotNull ItemStack stack, @Nullable BlockGetter pLevel, List tooltip, TooltipFlag flag) { - tooltip.add(Component.translatable("block.powertool.cosmetic_furnace.tooltip").withStyle(ChatFormatting.DARK_GRAY)); + public void appendHoverText(ItemStack stack, Item.TooltipContext context, List tooltipComponents, TooltipFlag tooltipFlag) { + tooltipComponents.add(Component.translatable("block.powertool.cosmetic_furnace.tooltip").withStyle(ChatFormatting.DARK_GRAY)); } - + @Override protected void createBlockStateDefinition(StateDefinition.Builder pBuilder) { super.createBlockStateDefinition(pBuilder); pBuilder.add(LIT); } - + @Override - @SuppressWarnings("deprecation") - public InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult result) { - if (player.getItemInHand(hand).is(Items.FLINT_AND_STEEL) && player.isCreative() && !state.getValue(LIT)){ + protected ItemInteractionResult useItemOn(ItemStack stack, BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hitResult) { + if (stack.is(Items.FLINT_AND_STEEL) && player.isCreative() && !state.getValue(LIT)){ level.setBlock(pos, state.setValue(LIT, true), Block.UPDATE_NONE); - return InteractionResult.sidedSuccess(level.isClientSide()); + return ItemInteractionResult.sidedSuccess(level.isClientSide()); } - return InteractionResult.PASS; + return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; } @Override diff --git a/src/main/java/org/teacon/powertool/block/CosmeticHopper.java b/src/main/java/org/teacon/powertool/block/CosmeticHopper.java index d2cfb31..115dd0e 100644 --- a/src/main/java/org/teacon/powertool/block/CosmeticHopper.java +++ b/src/main/java/org/teacon/powertool/block/CosmeticHopper.java @@ -1,9 +1,11 @@ package org.teacon.powertool.block; import net.minecraft.ChatFormatting; +import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.network.chat.Component; +import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.item.context.BlockPlaceContext; @@ -11,7 +13,6 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Mirror; import net.minecraft.world.level.block.Rotation; -import net.minecraft.world.level.block.entity.Hopper; import net.minecraft.world.level.block.state.BlockBehaviour; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.StateDefinition; @@ -22,8 +23,8 @@ import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; -import org.jetbrains.annotations.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; import java.util.List; /** @@ -31,22 +32,25 @@ * a BlockEntity, and thus do not have game logic such as transporting items * or absorbing nearby ItemEntity. */ +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault public class CosmeticHopper extends Block { private static final DirectionProperty FACING = BlockStateProperties.FACING_HOPPER; private static final VoxelShape TOP = Block.box(0.0D, 10.0D, 0.0D, 16.0D, 16.0D, 16.0D); private static final VoxelShape FUNNEL = Block.box(4.0D, 4.0D, 4.0D, 12.0D, 10.0D, 12.0D); private static final VoxelShape CONVEX_BASE = Shapes.or(FUNNEL, TOP); - private static final VoxelShape BASE = Shapes.join(CONVEX_BASE, Hopper.INSIDE, BooleanOp.ONLY_FIRST); + private static final VoxelShape HOPPER_INSIDE = Block.box(2.0D, 11.0D, 2.0D, 14.0D, 16.0D, 14.0D); + private static final VoxelShape BASE = Shapes.join(CONVEX_BASE, HOPPER_INSIDE, BooleanOp.ONLY_FIRST); private static final VoxelShape DOWN_SHAPE = Shapes.or(BASE, Block.box(6.0D, 0.0D, 6.0D, 10.0D, 4.0D, 10.0D)); private static final VoxelShape EAST_SHAPE = Shapes.or(BASE, Block.box(12.0D, 4.0D, 6.0D, 16.0D, 8.0D, 10.0D)); private static final VoxelShape NORTH_SHAPE = Shapes.or(BASE, Block.box(6.0D, 4.0D, 0.0D, 10.0D, 8.0D, 4.0D)); private static final VoxelShape SOUTH_SHAPE = Shapes.or(BASE, Block.box(6.0D, 4.0D, 12.0D, 10.0D, 8.0D, 16.0D)); private static final VoxelShape WEST_SHAPE = Shapes.or(BASE, Block.box(0.0D, 4.0D, 6.0D, 4.0D, 8.0D, 10.0D)); - private static final VoxelShape DOWN_INTERACTION_SHAPE = Hopper.INSIDE; - private static final VoxelShape EAST_INTERACTION_SHAPE = Shapes.or(Hopper.INSIDE, Block.box(12.0D, 8.0D, 6.0D, 16.0D, 10.0D, 10.0D)); - private static final VoxelShape NORTH_INTERACTION_SHAPE = Shapes.or(Hopper.INSIDE, Block.box(6.0D, 8.0D, 0.0D, 10.0D, 10.0D, 4.0D)); - private static final VoxelShape SOUTH_INTERACTION_SHAPE = Shapes.or(Hopper.INSIDE, Block.box(6.0D, 8.0D, 12.0D, 10.0D, 10.0D, 16.0D)); - private static final VoxelShape WEST_INTERACTION_SHAPE = Shapes.or(Hopper.INSIDE, Block.box(0.0D, 8.0D, 6.0D, 4.0D, 10.0D, 10.0D)); + private static final VoxelShape DOWN_INTERACTION_SHAPE = HOPPER_INSIDE; + private static final VoxelShape EAST_INTERACTION_SHAPE = Shapes.or(HOPPER_INSIDE, Block.box(12.0D, 8.0D, 6.0D, 16.0D, 10.0D, 10.0D)); + private static final VoxelShape NORTH_INTERACTION_SHAPE = Shapes.or(HOPPER_INSIDE, Block.box(6.0D, 8.0D, 0.0D, 10.0D, 10.0D, 4.0D)); + private static final VoxelShape SOUTH_INTERACTION_SHAPE = Shapes.or(HOPPER_INSIDE, Block.box(6.0D, 8.0D, 12.0D, 10.0D, 10.0D, 16.0D)); + private static final VoxelShape WEST_INTERACTION_SHAPE = Shapes.or(HOPPER_INSIDE, Block.box(0.0D, 8.0D, 6.0D, 4.0D, 10.0D, 10.0D)); public CosmeticHopper(BlockBehaviour.Properties prop) { super(prop); @@ -57,13 +61,14 @@ public CosmeticHopper(BlockBehaviour.Properties prop) { protected void createBlockStateDefinition(StateDefinition.Builder builder) { builder.add(FACING); } - + @Override - public void appendHoverText(ItemStack pStack, @Nullable BlockGetter pLevel, List tooltip, TooltipFlag pFlag) { - tooltip.add(Component.translatable("block.powertool.cosmetic_hopper.tooltip").withStyle(ChatFormatting.DARK_GRAY)); + public void appendHoverText(ItemStack stack, Item.TooltipContext context, List tooltipComponents, TooltipFlag tooltipFlag) { + tooltipComponents.add(Component.translatable("block.powertool.cosmetic_hopper.tooltip").withStyle(ChatFormatting.DARK_GRAY)); } - + @Override + @SuppressWarnings("DuplicatedCode") //The "duplicated code" in switch cannot actually extract methods. public VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) { return switch (state.getValue(FACING)) { case DOWN -> DOWN_SHAPE; @@ -76,6 +81,7 @@ public VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, Co } @Override + @SuppressWarnings("DuplicatedCode") //The "duplicated code" in switch cannot actually extract methods. public VoxelShape getInteractionShape(BlockState state, BlockGetter level, BlockPos pos) { return switch (state.getValue(FACING)) { case DOWN -> DOWN_INTERACTION_SHAPE; @@ -83,7 +89,7 @@ public VoxelShape getInteractionShape(BlockState state, BlockGetter level, Block case SOUTH -> SOUTH_INTERACTION_SHAPE; case WEST -> WEST_INTERACTION_SHAPE; case EAST -> EAST_INTERACTION_SHAPE; - default -> Hopper.INSIDE; + default -> HOPPER_INSIDE; }; } @@ -92,19 +98,21 @@ public BlockState getStateForPlacement(BlockPlaceContext context) { Direction dir = context.getClickedFace().getOpposite(); return this.defaultBlockState().setValue(FACING, dir.getAxis() == Direction.Axis.Y ? Direction.DOWN : dir); } - + @Override + @SuppressWarnings("deprecation") public BlockState rotate(BlockState state, Rotation rotation) { return state.setValue(FACING, rotation.rotate(state.getValue(FACING))); } @Override + @SuppressWarnings("deprecation") public BlockState mirror(BlockState state, Mirror mirror) { return state.rotate(mirror.getRotation(state.getValue(FACING))); } - + @Override - public boolean isPathfindable(BlockState state, BlockGetter level, BlockPos pos, PathComputationType type) { + protected boolean isPathfindable(BlockState state, PathComputationType pathComputationType) { return false; } } diff --git a/src/main/java/org/teacon/powertool/block/CosmeticSimpleBlock.java b/src/main/java/org/teacon/powertool/block/CosmeticSimpleBlock.java index 4aa9591..cc97a6e 100644 --- a/src/main/java/org/teacon/powertool/block/CosmeticSimpleBlock.java +++ b/src/main/java/org/teacon/powertool/block/CosmeticSimpleBlock.java @@ -2,11 +2,10 @@ import net.minecraft.ChatFormatting; import net.minecraft.network.chat.Component; +import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.TooltipFlag; -import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.block.Block; -import org.jetbrains.annotations.Nullable; import javax.annotation.ParametersAreNonnullByDefault; import java.util.List; @@ -17,10 +16,10 @@ public class CosmeticSimpleBlock extends Block { public CosmeticSimpleBlock(Properties p) { super(p); } - + @Override - public void appendHoverText(ItemStack item, @Nullable BlockGetter blockGetter, List tooltips, TooltipFlag flag) { - tooltips.add(Component.translatable("block.powertool.cosmetic_block.tooltip").withStyle(ChatFormatting.DARK_GRAY)); + public void appendHoverText(ItemStack stack, Item.TooltipContext context, List tooltipComponents, TooltipFlag tooltipFlag) { + tooltipComponents.add(Component.translatable("block.powertool.cosmetic_block.tooltip").withStyle(ChatFormatting.DARK_GRAY)); } } diff --git a/src/main/java/org/teacon/powertool/block/CosmeticTrapdoor.java b/src/main/java/org/teacon/powertool/block/CosmeticTrapdoor.java index bf5d356..b1de14d 100644 --- a/src/main/java/org/teacon/powertool/block/CosmeticTrapdoor.java +++ b/src/main/java/org/teacon/powertool/block/CosmeticTrapdoor.java @@ -1,9 +1,12 @@ package org.teacon.powertool.block; +import com.mojang.serialization.MapCodec; import net.minecraft.ChatFormatting; +import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.network.chat.Component; +import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.item.context.BlockPlaceContext; @@ -20,11 +23,15 @@ import net.minecraft.world.level.pathfinder.PathComputationType; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; -import org.jetbrains.annotations.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; import java.util.List; +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault public class CosmeticTrapdoor extends DirectionalBlock implements SimpleWaterloggedBlock { + + public static final MapCodec CODEC = simpleCodec(CosmeticTrapdoor::new); protected static final VoxelShape EAST_OPEN_AABB = Block.box(0.0D, 0.0D, 0.0D, 3.0D, 16.0D, 16.0D); protected static final VoxelShape WEST_OPEN_AABB = Block.box(13.0D, 0.0D, 0.0D, 16.0D, 16.0D, 16.0D); @@ -38,12 +45,18 @@ protected CosmeticTrapdoor(Properties prop) { super(prop); this.registerDefaultState(this.defaultBlockState().setValue(FACING, Direction.UP).setValue(BlockStateProperties.WATERLOGGED, Boolean.FALSE)); } - + + @Override + protected MapCodec codec() { + return CODEC; + } + protected void createBlockStateDefinition(StateDefinition.Builder builder) { builder.add(FACING, BlockStateProperties.WATERLOGGED); } @Override + @SuppressWarnings("DuplicatedCode") //The "duplicated code" in switch cannot actually extract methods. public VoxelShape getShape(BlockState state, BlockGetter blockGetter, BlockPos pos, CollisionContext collisionContext) { return switch (state.getValue(FACING)) { case UP -> BOTTOM_AABB; @@ -54,10 +67,10 @@ public VoxelShape getShape(BlockState state, BlockGetter blockGetter, BlockPos p case NORTH -> NORTH_OPEN_AABB; }; } - + @Override - public boolean isPathfindable(BlockState state, BlockGetter blockGetter, BlockPos pos, PathComputationType pathType) { - return pathType == PathComputationType.WATER && state.getValue(BlockStateProperties.WATERLOGGED); + protected boolean isPathfindable(BlockState state, PathComputationType pathComputationType) { + return pathComputationType == PathComputationType.WATER && state.getValue(BlockStateProperties.WATERLOGGED); } @Override @@ -65,10 +78,10 @@ public BlockState getStateForPlacement(BlockPlaceContext context) { Direction direction = context.getClickedFace(); return this.defaultBlockState().setValue(FACING, direction); } - + @Override - public void appendHoverText(ItemStack item, @Nullable BlockGetter blockGetter, List tooltips, TooltipFlag flag) { - tooltips.add(Component.translatable("block.powertool.cosmetic_trapdoor.tooltip").withStyle(ChatFormatting.DARK_GRAY)); + public void appendHoverText(ItemStack stack, Item.TooltipContext context, List tooltipComponents, TooltipFlag tooltipFlag) { + tooltipComponents.add(Component.translatable("block.powertool.cosmetic_trapdoor.tooltip").withStyle(ChatFormatting.DARK_GRAY)); } @Override diff --git a/src/main/java/org/teacon/powertool/block/HolographicSignBlock.java b/src/main/java/org/teacon/powertool/block/HolographicSignBlock.java index 18f3163..4b0b930 100644 --- a/src/main/java/org/teacon/powertool/block/HolographicSignBlock.java +++ b/src/main/java/org/teacon/powertool/block/HolographicSignBlock.java @@ -1,11 +1,15 @@ package org.teacon.powertool.block; +import com.mojang.serialization.MapCodec; +import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; +import net.minecraft.world.ItemInteractionResult; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.block.BaseEntityBlock; @@ -20,13 +24,19 @@ import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.material.Fluids; import net.minecraft.world.phys.BlockHitResult; -import net.minecraftforge.network.PacketDistributor; +import net.neoforged.neoforge.network.PacketDistributor; import org.jetbrains.annotations.Nullable; import org.teacon.powertool.block.entity.HolographicSignBlockEntity; -import org.teacon.powertool.network.PowerToolNetwork; import org.teacon.powertool.network.client.OpenHolographicSignEditor; +import org.teacon.powertool.utils.VanillaUtils; +import javax.annotation.ParametersAreNonnullByDefault; + +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault public class HolographicSignBlock extends BaseEntityBlock implements SimpleWaterloggedBlock { + + public static final MapCodec CODEC = simpleCodec(HolographicSignBlock::new); public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; @@ -34,13 +44,19 @@ public HolographicSignBlock(Properties prop) { super(prop); this.registerDefaultState(this.stateDefinition.any().setValue(WATERLOGGED, Boolean.FALSE)); } - + + @Override + protected MapCodec codec() { + return CODEC; + } + @Override protected void createBlockStateDefinition(StateDefinition.Builder builder) { builder.add(WATERLOGGED); } - + @Override + @SuppressWarnings("deprecation") public RenderShape getRenderShape(BlockState state) { return RenderShape.INVISIBLE; } @@ -50,14 +66,23 @@ public RenderShape getRenderShape(BlockState state) { public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { return new HolographicSignBlockEntity(pos, state); } - + + @Override + protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { + return use(level, pos, player); + } + @Override - public InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { + protected ItemInteractionResult useItemOn(ItemStack stack, BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hitResult) { + return VanillaUtils.itemInteractionFrom(use(level,pos,player)); + } + + public InteractionResult use(Level level, BlockPos pos, Player player) { if (player.isCrouching()) { return InteractionResult.PASS; } if (!level.isClientSide() && player instanceof ServerPlayer sp && sp.getAbilities().instabuild) { - PowerToolNetwork.channel().send(PacketDistributor.PLAYER.with(() -> sp), new OpenHolographicSignEditor(pos)); + PacketDistributor.sendToPlayer(sp,new OpenHolographicSignEditor(pos)); } return InteractionResult.SUCCESS; } diff --git a/src/main/java/org/teacon/powertool/block/ItemDisplayBlock.java b/src/main/java/org/teacon/powertool/block/ItemDisplayBlock.java index 998bf7f..2672524 100644 --- a/src/main/java/org/teacon/powertool/block/ItemDisplayBlock.java +++ b/src/main/java/org/teacon/powertool/block/ItemDisplayBlock.java @@ -1,5 +1,6 @@ package org.teacon.powertool.block; +import com.mojang.serialization.MapCodec; import net.minecraft.ChatFormatting; import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos; @@ -7,7 +8,9 @@ import net.minecraft.network.chat.Component; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; +import net.minecraft.world.ItemInteractionResult; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.item.context.BlockPlaceContext; @@ -25,7 +28,6 @@ import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; -import org.jetbrains.annotations.Nullable; import org.teacon.powertool.block.entity.ItemDisplayBlockEntity; import javax.annotation.ParametersAreNonnullByDefault; @@ -34,6 +36,8 @@ @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault public class ItemDisplayBlock extends BaseEntityBlock { + + public static final MapCodec CODEC = simpleCodec(ItemDisplayBlock::new); protected static final VoxelShape DOWN_AABB = Block.box(2, 15, 2, 14, 16, 14); protected static final VoxelShape UP_AABB = Block.box(2, 0, 2, 14, 1, 14); @@ -51,19 +55,25 @@ public ItemDisplayBlock(Properties prop) { super(prop); this.registerDefaultState(this.defaultBlockState().setValue(INVISIBLE, Boolean.FALSE).setValue(SURVIVAL_AVAILABLE,Boolean.FALSE)); } - + + @Override + protected MapCodec codec() { + return CODEC; + } + @Override - public void appendHoverText(ItemStack stack, @Nullable BlockGetter level, List tooltip, TooltipFlag flag) { - tooltip.add(Component.translatable("block.powertool.item_display.tooltip").withStyle(ChatFormatting.DARK_GRAY)); + public void appendHoverText(ItemStack stack, Item.TooltipContext context, List tooltipComponents, TooltipFlag tooltipFlag) { + tooltipComponents.add(Component.translatable("block.powertool.item_display.tooltip").withStyle(ChatFormatting.DARK_GRAY)); } @Override + @SuppressWarnings("deprecation") public RenderShape getRenderShape(BlockState pState) { return RenderShape.MODEL; } @Override - @SuppressWarnings("deprecation") + @SuppressWarnings("DuplicatedCode") //The "duplicated code" in switch cannot actually extract methods. public VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) { return switch (state.getValue(FACING)) { case NORTH -> NORTH_AABB; @@ -90,8 +100,8 @@ public BlockState getStateForPlacement(BlockPlaceContext context) { public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { return new ItemDisplayBlockEntity(pos, state); } + @Override - @SuppressWarnings("deprecation") public void attack(BlockState state, Level level, BlockPos pos, Player player) { if (!level.isClientSide() && player.getAbilities().instabuild && level.getBlockEntity(pos) instanceof ItemDisplayBlockEntity theBE) { theBE.itemToDisplay = ItemStack.EMPTY; @@ -99,26 +109,33 @@ public void attack(BlockState state, Level level, BlockPos pos, Player player) { level.sendBlockUpdated(pos, state, state, Block.UPDATE_CLIENTS); } } + @Override - @SuppressWarnings("deprecation") - public InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { + protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { if (level.getBlockEntity(pos) instanceof ItemDisplayBlockEntity theBE) { if (player.getAbilities().instabuild || state.getValue(SURVIVAL_AVAILABLE)) { - if (theBE.itemToDisplay.isEmpty()) { - theBE.itemToDisplay = player.getItemInHand(hand).copy(); - if (!level.isClientSide) { - theBE.setChanged(); - level.sendBlockUpdated(pos, state, state, Block.UPDATE_CLIENTS); - } - } else { - theBE.rotation = (theBE.rotation + 45) % 360; + theBE.rotation = (theBE.rotation + 45) % 360; + theBE.setChanged(); + level.sendBlockUpdated(pos, state, state, Block.UPDATE_CLIENTS); + return InteractionResult.SUCCESS; + } + } + return InteractionResult.PASS; + } + + @Override + protected ItemInteractionResult useItemOn(ItemStack stack, BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hitResult) { + if (level.getBlockEntity(pos) instanceof ItemDisplayBlockEntity theBE) { + if (player.getAbilities().instabuild || state.getValue(SURVIVAL_AVAILABLE)){ + theBE.itemToDisplay = stack.copy(); + if (!level.isClientSide) { theBE.setChanged(); level.sendBlockUpdated(pos, state, state, Block.UPDATE_CLIENTS); } + return ItemInteractionResult.SUCCESS; } - return InteractionResult.SUCCESS; } - return InteractionResult.PASS; + return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; } @Override diff --git a/src/main/java/org/teacon/powertool/block/ItemSupplierBlock.java b/src/main/java/org/teacon/powertool/block/ItemSupplierBlock.java index cb6fe7c..dac2e48 100644 --- a/src/main/java/org/teacon/powertool/block/ItemSupplierBlock.java +++ b/src/main/java/org/teacon/powertool/block/ItemSupplierBlock.java @@ -1,12 +1,16 @@ package org.teacon.powertool.block; +import com.mojang.serialization.MapCodec; import net.minecraft.ChatFormatting; +import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.network.chat.Component; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; +import net.minecraft.world.ItemInteractionResult; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.level.BlockGetter; @@ -17,17 +21,28 @@ import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.BlockHitResult; -import org.jetbrains.annotations.Nullable; import org.teacon.powertool.block.entity.ItemSupplierBlockEntity; +import javax.annotation.ParametersAreNonnullByDefault; import java.util.List; +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault public class ItemSupplierBlock extends BaseEntityBlock { + + public static final MapCodec CODEC = simpleCodec(ItemSupplierBlock::new); public ItemSupplierBlock(Properties prop) { super(prop); } - + + @Override + protected MapCodec codec() { + return CODEC; + } + + @Override + @SuppressWarnings("deprecation") public RenderShape getRenderShape(BlockState pState) { return RenderShape.MODEL; } @@ -46,10 +61,10 @@ public float getShadeBrightness(BlockState pState, BlockGetter pLevel, BlockPos public boolean propagatesSkylightDown(BlockState state, BlockGetter level, BlockPos pos) { return true; } - + @Override - public void appendHoverText(ItemStack stack, @Nullable BlockGetter level, List tooltip, TooltipFlag flag) { - tooltip.add(Component.translatable("block.powertool.item_supplier.tooltip").withStyle(ChatFormatting.GRAY)); + public void appendHoverText(ItemStack stack, Item.TooltipContext context, List tooltipComponents, TooltipFlag tooltipFlag) { + tooltipComponents.add(Component.translatable("block.powertool.item_supplier.tooltip").withStyle(ChatFormatting.GRAY)); } @Override @@ -65,23 +80,37 @@ public void attack(BlockState state, Level level, BlockPos pos, Player player) { player.getInventory().add(thing); } } - + + protected void giveItemToPlayer(Player player, ItemSupplierBlockEntity theTE) { + ItemStack toGive = theTE.theItem.copy(); + toGive.setCount(player.isCrouching() ? toGive.getMaxStackSize() : 1); + player.getInventory().add(toGive); + } + @Override - public InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { + protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { if (level.getBlockEntity(pos) instanceof ItemSupplierBlockEntity theBE) { + giveItemToPlayer(player, theBE); + return InteractionResult.SUCCESS; + } + return InteractionResult.PASS; + } + + @Override + protected ItemInteractionResult useItemOn(ItemStack stack, BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hitResult) { + if (level.getBlockEntity(pos) instanceof ItemSupplierBlockEntity theBE){ if (theBE.theItem.isEmpty() && player.getAbilities().instabuild) { - theBE.theItem = player.getItemInHand(hand).copy(); + theBE.theItem = stack.copy(); if (!level.isClientSide) { theBE.setChanged(); level.sendBlockUpdated(pos, state, state, Block.UPDATE_CLIENTS); } - } else { - ItemStack toGive = theBE.theItem.copy(); - toGive.setCount(player.isCrouching() ? toGive.getMaxStackSize() : 1); - player.getInventory().add(toGive); } - return InteractionResult.SUCCESS; + else{ + giveItemToPlayer(player, theBE); + } + return ItemInteractionResult.SUCCESS; } - return InteractionResult.PASS; + return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; } } diff --git a/src/main/java/org/teacon/powertool/block/PeriodicCommandBlock.java b/src/main/java/org/teacon/powertool/block/PeriodicCommandBlock.java index f8c9e25..617ad8d 100644 --- a/src/main/java/org/teacon/powertool/block/PeriodicCommandBlock.java +++ b/src/main/java/org/teacon/powertool/block/PeriodicCommandBlock.java @@ -16,7 +16,7 @@ public class PeriodicCommandBlock extends CommandBlock implements PeriodCommandBlockBridge { public PeriodicCommandBlock(Properties properties, boolean auto) { - super(properties, auto); + super(auto, properties); } @Override @@ -25,7 +25,7 @@ public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { } @Override - public int powerToolPeriod(ServerLevel level, BlockPos pos) { + public int powerTool$Period(ServerLevel level, BlockPos pos) { return level.getBlockEntity(pos) instanceof PeriodicCommandBlockEntity entity ? entity.getPeriod() : 1; } } diff --git a/src/main/java/org/teacon/powertool/block/PowerSupplyBlock.java b/src/main/java/org/teacon/powertool/block/PowerSupplyBlock.java index 1a5c4df..2b48618 100644 --- a/src/main/java/org/teacon/powertool/block/PowerSupplyBlock.java +++ b/src/main/java/org/teacon/powertool/block/PowerSupplyBlock.java @@ -1,38 +1,63 @@ package org.teacon.powertool.block; +import com.mojang.serialization.MapCodec; +import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos; -import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; +import net.minecraft.world.ItemInteractionResult; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.BaseEntityBlock; import net.minecraft.world.level.block.RenderShape; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.BlockHitResult; -import net.minecraftforge.network.NetworkHooks; import org.jetbrains.annotations.Nullable; import org.teacon.powertool.block.entity.PowerSupplyBlockEntity; import org.teacon.powertool.menu.PowerSupplyMenu; +import org.teacon.powertool.utils.VanillaUtils; +import javax.annotation.ParametersAreNonnullByDefault; + +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault public class PowerSupplyBlock extends BaseEntityBlock { + + private static final MapCodec CODEC = simpleCodec(PowerSupplyBlock::new); public PowerSupplyBlock(Properties prop) { super(prop); } - + + @Override + protected MapCodec codec() { + return CODEC; + } + @Override + @SuppressWarnings("deprecation") public RenderShape getRenderShape(BlockState pState) { return RenderShape.MODEL; } - + + @Override + protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { + return use(level, pos, player); + } + @Override - public InteractionResult use(BlockState state, Level level, BlockPos pos, Player p, InteractionHand hand, BlockHitResult hit) { + protected ItemInteractionResult useItemOn(ItemStack stack, BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hitResult) { + return VanillaUtils.itemInteractionFrom(use(level,pos,player)); + } + + + public InteractionResult use(Level level, BlockPos pos, Player p) { if (level.isClientSide) { return InteractionResult.SUCCESS; } else { if (level.getBlockEntity(pos) instanceof PowerSupplyBlockEntity be) { - NetworkHooks.openScreen((ServerPlayer) p, new PowerSupplyMenu.Provider(be.data), + p.openMenu( new PowerSupplyMenu.Provider(be.data), buf -> buf.writeVarInt(be.data.status).writeVarInt(be.data.power)); } return InteractionResult.CONSUME; diff --git a/src/main/java/org/teacon/powertool/block/PowerToolBlocks.java b/src/main/java/org/teacon/powertool/block/PowerToolBlocks.java index 5263ed6..3aec420 100644 --- a/src/main/java/org/teacon/powertool/block/PowerToolBlocks.java +++ b/src/main/java/org/teacon/powertool/block/PowerToolBlocks.java @@ -1,6 +1,8 @@ package org.teacon.powertool.block; import com.mojang.datafixers.DSL; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; import net.minecraft.sounds.SoundEvents; import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.DyeColor; @@ -11,11 +13,13 @@ import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockBehaviour; import net.minecraft.world.level.block.state.properties.BlockSetType; -import net.minecraftforge.common.util.ForgeSoundType; -import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; -import net.minecraftforge.registries.DeferredRegister; -import net.minecraftforge.registries.ForgeRegistries; -import net.minecraftforge.registries.RegistryObject; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.neoforge.capabilities.Capabilities; +import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent; +import net.neoforged.neoforge.common.util.DeferredSoundType; +import net.neoforged.neoforge.registries.DeferredHolder; +import net.neoforged.neoforge.registries.DeferredRegister; import org.teacon.powertool.PowerTool; import org.teacon.powertool.block.entity.HolographicSignBlockEntity; import org.teacon.powertool.block.entity.ItemDisplayBlockEntity; @@ -30,7 +34,7 @@ public class PowerToolBlocks { - public static final SoundType ITEM_DISPLAY_SOUND_TYPE = new ForgeSoundType(1.0F, 1.0F, + public static final SoundType ITEM_DISPLAY_SOUND_TYPE = new DeferredSoundType(1.0F, 1.0F, () -> SoundEvents.ITEM_FRAME_BREAK, () -> SoundEvents.MOSS_CARPET_STEP, () -> SoundEvents.ITEM_FRAME_PLACE, @@ -38,7 +42,7 @@ public class PowerToolBlocks { () -> SoundEvents.MOSS_CARPET_FALL ); - public static final SoundType GLOW_ITEM_DISPLAY_SOUND_TYPE = new ForgeSoundType(1.0F, 1.0F, + public static final SoundType GLOW_ITEM_DISPLAY_SOUND_TYPE = new DeferredSoundType(1.0F, 1.0F, () -> SoundEvents.GLOW_ITEM_FRAME_BREAK, () -> SoundEvents.MOSS_CARPET_STEP, () -> SoundEvents.GLOW_ITEM_FRAME_PLACE, @@ -47,51 +51,52 @@ public class PowerToolBlocks { public static final List SIMPLE_BLOCKS = List.of(Blocks.SAND, Blocks.RED_SAND, Blocks.GRAVEL, Blocks.TUBE_CORAL_BLOCK, Blocks.BRAIN_CORAL_BLOCK, Blocks.BUBBLE_CORAL_BLOCK, Blocks.FIRE_CORAL_BLOCK, Blocks.HORN_CORAL_BLOCK, Blocks.REDSTONE_BLOCK); - public static final DeferredRegister BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, PowerTool.MODID); - public static final DeferredRegister> BLOCK_ENTITIES = DeferredRegister.create(ForgeRegistries.BLOCK_ENTITY_TYPES, PowerTool.MODID); - - public static RegistryObject COMMAND_BLOCK; - public static RegistryObject TRASH_CAN; - public static RegistryObject POWER_SUPPLY; - public static RegistryObject ITEM_DISPLAY; - - public static RegistryObject GLOW_ITEM_DISPLAY; - public static RegistryObject ITEM_SUPPLIER; - - public static RegistryObject SLIM_ITEM_SUPPLIER; - public static RegistryObject COSMETIC_HOPPER; - public static RegistryObject COSMETIC_CAMPFIRE; - public static RegistryObject COSMETIC_SOUL_CAMPFIRE; - public static RegistryObject COSMETIC_BEEHIVE; - public static RegistryObject COSMETIC_FURNACE; - public static RegistryObject COSMETIC_BLAST_FURNACE; - public static RegistryObject COSMETIC_BARREL; - - public static RegistryObject HOLOGRAPHIC_SIGN; - public static RegistryObject> COMMAND_BLOCK_ENTITY; - public static RegistryObject> POWER_SUPPLY_BLOCK_ENTITY; - - public static RegistryObject> ITEM_DISPLAY_BLOCK_ENTITY; - public static RegistryObject> ITEM_SUPPLIER_BLOCK_ENTITY; - public static RegistryObject> HOLOGRAPHIC_SIGN_BLOCK_ENTITY; - - public static void register() { - BLOCKS.register(FMLJavaModLoadingContext.get().getModEventBus()); - BLOCK_ENTITIES.register(FMLJavaModLoadingContext.get().getModEventBus()); + public static final DeferredRegister BLOCKS = DeferredRegister.create(Registries.BLOCK, PowerTool.MODID); + public static final DeferredRegister> BLOCK_ENTITIES = DeferredRegister.create(Registries.BLOCK_ENTITY_TYPE, PowerTool.MODID); + + public static DeferredHolder COMMAND_BLOCK; + public static DeferredHolder TRASH_CAN; + public static DeferredHolder POWER_SUPPLY; + public static DeferredHolder ITEM_DISPLAY; + + public static DeferredHolder GLOW_ITEM_DISPLAY; + public static DeferredHolder ITEM_SUPPLIER; + + public static DeferredHolder SLIM_ITEM_SUPPLIER; + public static DeferredHolder COSMETIC_HOPPER; + public static DeferredHolder COSMETIC_CAMPFIRE; + public static DeferredHolder COSMETIC_SOUL_CAMPFIRE; + public static DeferredHolder COSMETIC_BEEHIVE; + public static DeferredHolder COSMETIC_FURNACE; + public static DeferredHolder COSMETIC_BLAST_FURNACE; + public static DeferredHolder COSMETIC_BARREL; + + public static DeferredHolder HOLOGRAPHIC_SIGN; + public static DeferredHolder,BlockEntityType> COMMAND_BLOCK_ENTITY; + public static DeferredHolder,BlockEntityType> POWER_SUPPLY_BLOCK_ENTITY; + + public static DeferredHolder,BlockEntityType> ITEM_DISPLAY_BLOCK_ENTITY; + public static DeferredHolder,BlockEntityType> ITEM_SUPPLIER_BLOCK_ENTITY; + public static DeferredHolder,BlockEntityType> HOLOGRAPHIC_SIGN_BLOCK_ENTITY; + + public static void register(IEventBus bus) { + BLOCKS.register(bus); + BLOCK_ENTITIES.register(bus); COMMAND_BLOCK = BLOCKS.register("command_block", () -> new PeriodicCommandBlock( BlockBehaviour.Properties.of().mapColor(DyeColor.PURPLE).requiresCorrectToolForDrops().strength(-1.0F, 3600000.0F).noLootTable(), false )); TRASH_CAN = BLOCKS.register("trash_can", () -> new TrashCanBlock(BlockBehaviour.Properties.of().strength(1000))); - POWER_SUPPLY = BLOCKS.register("power_supply", () -> new PowerSupplyBlock(BlockBehaviour.Properties.copy(Blocks.IRON_BLOCK).strength(1000))); - ITEM_DISPLAY = BLOCKS.register("item_display", () -> new ItemDisplayBlock(BlockBehaviour.Properties.copy(Blocks.LADDER).sound(ITEM_DISPLAY_SOUND_TYPE).noOcclusion().strength(10000))); - GLOW_ITEM_DISPLAY = BLOCKS.register("glow_item_display", () -> new ItemDisplayBlock(BlockBehaviour.Properties.copy(Blocks.LADDER).sound(GLOW_ITEM_DISPLAY_SOUND_TYPE).noOcclusion().strength(10000))); + POWER_SUPPLY = BLOCKS.register("power_supply", () -> new PowerSupplyBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.IRON_BLOCK).strength(1000))); + ITEM_DISPLAY = BLOCKS.register("item_display", () -> new ItemDisplayBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.LADDER).sound(ITEM_DISPLAY_SOUND_TYPE).noOcclusion().strength(10000))); + //todo 这玩意是紫黑块 + GLOW_ITEM_DISPLAY = BLOCKS.register("glow_item_display", () -> new ItemDisplayBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.LADDER).sound(GLOW_ITEM_DISPLAY_SOUND_TYPE).noOcclusion().strength(10000))); ITEM_SUPPLIER = BLOCKS.register("item_supplier", () -> new ItemSupplierBlock(BlockBehaviour.Properties.of().strength(1000).noOcclusion())); SLIM_ITEM_SUPPLIER = BLOCKS.register("slim_item_supplier", () -> new SlimItemSupplierBlock(BlockBehaviour.Properties.of().strength(1000).noOcclusion())); - COSMETIC_HOPPER = BLOCKS.register("cosmetic_hopper", () -> new CosmeticHopper(BlockBehaviour.Properties.copy(Blocks.HOPPER))); - COSMETIC_CAMPFIRE = BLOCKS.register("cosmetic_campfire", () -> new CosmeticCampfireBlock(true, BlockBehaviour.Properties.copy(Blocks.CAMPFIRE))); - COSMETIC_SOUL_CAMPFIRE = BLOCKS.register("cosmetic_soul_campfire", () -> new CosmeticCampfireBlock(false, BlockBehaviour.Properties.copy(Blocks.SOUL_CAMPFIRE))); - HOLOGRAPHIC_SIGN = BLOCKS.register("holographic_sign", () -> new HolographicSignBlock(BlockBehaviour.Properties.copy(Blocks.LIGHT).lightLevel(state -> 15).noCollission().noLootTable())); + COSMETIC_HOPPER = BLOCKS.register("cosmetic_hopper", () -> new CosmeticHopper(BlockBehaviour.Properties.ofFullCopy(Blocks.HOPPER))); + COSMETIC_CAMPFIRE = BLOCKS.register("cosmetic_campfire", () -> new CosmeticCampfireBlock(true, BlockBehaviour.Properties.ofFullCopy(Blocks.CAMPFIRE))); + COSMETIC_SOUL_CAMPFIRE = BLOCKS.register("cosmetic_soul_campfire", () -> new CosmeticCampfireBlock(false, BlockBehaviour.Properties.ofFullCopy(Blocks.SOUL_CAMPFIRE))); + HOLOGRAPHIC_SIGN = BLOCKS.register("holographic_sign", () -> new HolographicSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.LIGHT).lightLevel(state -> 15).noCollission().noLootTable())); COMMAND_BLOCK_ENTITY = BLOCK_ENTITIES.register("command_block_entity", () -> BlockEntityType.Builder.of( PeriodicCommandBlockEntity::new, COMMAND_BLOCK.get() ).build(DSL.remainderType())); @@ -126,10 +131,10 @@ public static void register() { )); regSimpleCosmetic(SIMPLE_BLOCKS); - COSMETIC_BEEHIVE = BLOCKS.register("cosmetic_beehive", () -> new CosmeticBeehive(BlockBehaviour.Properties.copy(Blocks.BEEHIVE))); - COSMETIC_FURNACE = BLOCKS.register("cosmetic_furnace", () -> new CosmeticFurnace(BlockBehaviour.Properties.copy(Blocks.FURNACE))); - COSMETIC_BLAST_FURNACE = BLOCKS.register("cosmetic_blast_furnace", () -> new CosmeticFurnace(BlockBehaviour.Properties.copy(Blocks.BLAST_FURNACE))); - COSMETIC_BARREL = BLOCKS.register("cosmetic_barrel", () -> new CosmeticBarrel(BlockBehaviour.Properties.copy(Blocks.BARREL))); + COSMETIC_BEEHIVE = BLOCKS.register("cosmetic_beehive", () -> new CosmeticBeehive(BlockBehaviour.Properties.ofFullCopy(Blocks.BEEHIVE))); + COSMETIC_FURNACE = BLOCKS.register("cosmetic_furnace", () -> new CosmeticFurnace(BlockBehaviour.Properties.ofFullCopy(Blocks.FURNACE))); + COSMETIC_BLAST_FURNACE = BLOCKS.register("cosmetic_blast_furnace", () -> new CosmeticFurnace(BlockBehaviour.Properties.ofFullCopy(Blocks.BLAST_FURNACE))); + COSMETIC_BARREL = BLOCKS.register("cosmetic_barrel", () -> new CosmeticBarrel(BlockBehaviour.Properties.ofFullCopy(Blocks.BARREL))); ITEMS.register("cosmetic_beehive", () -> new BlockItem(COSMETIC_BEEHIVE.get(), new Item.Properties())); ITEMS.register("cosmetic_furnace", () -> new BlockItem(COSMETIC_FURNACE.get(), new Item.Properties())); @@ -152,16 +157,27 @@ public static void register() { private static void regTrapDoors(Map existing) { for (var type : existing.entrySet()) { var name = "cosmetic_" + type.getKey().name() + "_trapdoor"; - var block = BLOCKS.register(name, () -> new CosmeticTrapdoor(BlockBehaviour.Properties.copy(type.getValue()))); + var block = BLOCKS.register(name, () -> new CosmeticTrapdoor(BlockBehaviour.Properties.ofFullCopy(type.getValue()))); ITEMS.register(name, () -> new BlockItem(block.get(), new Item.Properties())); } } + @SuppressWarnings("SameParameterValue") private static void regSimpleCosmetic(List existing) { for (var existingBlock : existing) { - var name = "cosmetic_" + ForgeRegistries.BLOCKS.getKey(existingBlock).getPath(); - var block = BLOCKS.register(name, () -> new CosmeticSimpleBlock(BlockBehaviour.Properties.copy(existingBlock))); + var name = "cosmetic_" + BuiltInRegistries.BLOCK.getKey(existingBlock).getPath(); + var block = BLOCKS.register(name, () -> new CosmeticSimpleBlock(BlockBehaviour.Properties.ofFullCopy(existingBlock))); ITEMS.register(name, () -> new BlockItem(block.get(), new Item.Properties())); } } + + + @SubscribeEvent + public static void regBlockCapabilities(final RegisterCapabilitiesEvent event) { + event.registerBlockEntity( + Capabilities.ItemHandler.BLOCK, + ITEM_SUPPLIER_BLOCK_ENTITY.get(), + (be,context) -> be.getItemHandler() + ); + } } diff --git a/src/main/java/org/teacon/powertool/block/SlimItemSupplierBlock.java b/src/main/java/org/teacon/powertool/block/SlimItemSupplierBlock.java index 0a54a78..549cd3a 100644 --- a/src/main/java/org/teacon/powertool/block/SlimItemSupplierBlock.java +++ b/src/main/java/org/teacon/powertool/block/SlimItemSupplierBlock.java @@ -1,5 +1,6 @@ package org.teacon.powertool.block; +import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.world.item.context.BlockPlaceContext; @@ -12,6 +13,10 @@ import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; +import javax.annotation.ParametersAreNonnullByDefault; + +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault public class SlimItemSupplierBlock extends ItemSupplierBlock { protected static final VoxelShape DOWN_AABB = Block.box(0, 12, 0, 16, 16, 16); @@ -27,6 +32,7 @@ public SlimItemSupplierBlock(Properties prop) { } @Override + @SuppressWarnings("DuplicatedCode") //The "duplicated code" in switch cannot actually extract methods. public VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) { return switch (state.getValue(FACING)) { case NORTH -> NORTH_AABB; diff --git a/src/main/java/org/teacon/powertool/block/TrashCanBlock.java b/src/main/java/org/teacon/powertool/block/TrashCanBlock.java index 4fa012e..f6a11be 100644 --- a/src/main/java/org/teacon/powertool/block/TrashCanBlock.java +++ b/src/main/java/org/teacon/powertool/block/TrashCanBlock.java @@ -1,15 +1,15 @@ package org.teacon.powertool.block; +import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; -import net.minecraft.core.registries.Registries; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.tags.TagKey; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; +import net.minecraft.world.ItemInteractionResult; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; @@ -22,15 +22,16 @@ import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; -import org.teacon.powertool.PowerTool; +import javax.annotation.ParametersAreNonnullByDefault; + +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault public class TrashCanBlock extends Block { private static final VoxelShape OUTER_SHAPE = Shapes.block(); private static final VoxelShape SHAPE = Shapes.join(OUTER_SHAPE, Block.box(2, 2, 2, 14, 16, 14), BooleanOp.ONLY_FIRST); - private static final TagKey> ITEM_TYPE = TagKey.create(Registries.ENTITY_TYPE, new ResourceLocation(PowerTool.MODID, "item")); - private static final BooleanProperty POWERED = BlockStateProperties.POWERED; public TrashCanBlock(Properties prop) { @@ -52,14 +53,21 @@ public VoxelShape getShape(BlockState pState, BlockGetter pLevel, BlockPos pPos, public VoxelShape getCollisionShape(BlockState pState, BlockGetter pLevel, BlockPos pPos, CollisionContext pContext) { return SHAPE; } - - @Override + + //xkball: What does this method for? public Object getRenderPropertiesInternal() { return OUTER_SHAPE; } - + @Override - public InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { + protected ItemInteractionResult useItemOn(ItemStack stack, BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hitResult) { + if (!player.getAbilities().instabuild) { + stack.shrink(1); + } + return ItemInteractionResult.sidedSuccess(level.isClientSide); + } + + public InteractionResult use(Level level, Player player, InteractionHand hand) { if (!player.getAbilities().instabuild) { player.getItemInHand(hand).shrink(1); } @@ -68,12 +76,14 @@ public InteractionResult use(BlockState state, Level level, BlockPos pos, Player @Override public void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) { - if (entity.getType().is(ITEM_TYPE)) { + //noinspection deprecation + if (entity.getType().builtInRegistryHolder().is(EntityType.ITEM.builtInRegistryHolder().key())) { entity.discard(); } } - + @Override + @SuppressWarnings("deprecation") public int getSignal(BlockState state, BlockGetter level, BlockPos pos, Direction direction) { return direction == Direction.DOWN && state.getValue(POWERED) ? 1 : 0; } diff --git a/src/main/java/org/teacon/powertool/block/entity/HolographicSignBlockEntity.java b/src/main/java/org/teacon/powertool/block/entity/HolographicSignBlockEntity.java index 54e5b38..2b45ca3 100644 --- a/src/main/java/org/teacon/powertool/block/entity/HolographicSignBlockEntity.java +++ b/src/main/java/org/teacon/powertool/block/entity/HolographicSignBlockEntity.java @@ -5,19 +5,26 @@ */ package org.teacon.powertool.block.entity; +import com.mojang.serialization.Codec; +import io.netty.buffer.ByteBuf; import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderLookup; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; import net.minecraft.nbt.StringTag; import net.minecraft.nbt.Tag; import net.minecraft.network.Connection; import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.game.ClientGamePacketListener; import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; +import net.minecraft.util.StringRepresentable; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.teacon.powertool.block.PowerToolBlocks; @@ -31,11 +38,15 @@ public class HolographicSignBlockEntity extends BlockEntity { /** Controls how text are aligned: left-align, centered, or right-align. */ - public enum Align { + public enum Align implements StringRepresentable { LEFT(Component.translatable("powertool.gui.holographic_sign.align_left")), CENTER(Component.translatable("powertool.gui.holographic_sign.align_center")), RIGHT(Component.translatable("powertool.gui.holographic_sign.align_right")); - + + + public static final Codec CODEC = StringRepresentable.fromEnum(Align::values); + public static final StreamCodec STREAM_CODEC = ByteBufCodecs.fromCodec(CODEC); + private static final Align[] VALUES = Align.values(); public final Component displayName; @@ -46,14 +57,24 @@ public enum Align { public static Align byOrdinal(int ordinal) { return ordinal >= 0 && ordinal <= VALUES.length ? VALUES[ordinal] : CENTER; } + + @Override + @NotNull + public String getSerializedName() { + return name(); + } + } /** Represents the text shadow. */ - public enum Shadow { + public enum Shadow implements StringRepresentable { NONE(Component.translatable("powertool.gui.holographic_sign.shadow_none")), DROP(Component.translatable("powertool.gui.holographic_sign.shadow_drop")), PLATE(Component.translatable("powertool.gui.holographic_sign.shadow_plate")); - + + public static final Codec CODEC = StringRepresentable.fromEnum(Shadow::values); + public static final StreamCodec STREAM_CODEC = ByteBufCodecs.fromCodec(CODEC); + private static final Shadow[] VALUES = Shadow.values(); public final Component displayName; @@ -64,14 +85,22 @@ public enum Shadow { public static Shadow byOrdinal(int ordinal) { return ordinal >= 0 && ordinal <= VALUES.length ? VALUES[ordinal] : PLATE; } - } + + @Override + @NotNull + public String getSerializedName() { + return name(); +}} /** Represents the Z-offset of the text: above things, same layer or below things. */ - public enum LayerArrange { + public enum LayerArrange implements StringRepresentable { FRONT(Component.translatable("powertool.gui.holographic_sign.arrange_front")), CENTER(Component.translatable("powertool.gui.holographic_sign.arrange_center")), BACK(Component.translatable("powertool.gui.holographic_sign.arrange_back")); - + + public static final Codec CODEC = StringRepresentable.fromEnum(LayerArrange::values); + public static final StreamCodec STREAM_CODEC = ByteBufCodecs.fromCodec(CODEC); + private static final LayerArrange[] VALUES = LayerArrange.values(); public final Component displayName; @@ -82,7 +111,12 @@ public enum LayerArrange { public static LayerArrange byOrdinal(int ordinal) { return ordinal >= 0 && ordinal <= VALUES.length ? VALUES[ordinal] : CENTER; } - } + + @Override + @NotNull + public String getSerializedName() { + return name(); +}} public List contents = Collections.emptyList(); public int colorInARGB = 0xFFFFFFFF; @@ -102,10 +136,10 @@ public HolographicSignBlockEntity(BlockPos pPos, BlockState pBlockState) { super(PowerToolBlocks.HOLOGRAPHIC_SIGN_BLOCK_ENTITY.get(), pPos, pBlockState); } - private void writeTo(CompoundTag tag) { + private void writeTo(CompoundTag tag, HolderLookup.Provider registries) { var list = new ListTag(); for (var text : this.contents) { - list.add(StringTag.valueOf(Component.Serializer.toJson(text))); + list.add(StringTag.valueOf(Component.Serializer.toJson(text,registries))); } tag.put("content", list); tag.putInt("color", this.colorInARGB); @@ -119,10 +153,10 @@ private void writeTo(CompoundTag tag) { tag.putBoolean("bidirectional",bidirectional); } - private void readFrom(CompoundTag tag) { + private void readFrom(CompoundTag tag,HolderLookup.Provider registries) { var loaded = new ArrayList(); for (var entry : tag.getList("content", Tag.TAG_STRING)) { - loaded.add(Component.Serializer.fromJson(entry.getAsString())); + loaded.add(Component.Serializer.fromJson(entry.getAsString(),registries)); } this.contents = loaded; if (tag.contains("color", Tag.TAG_INT)) { @@ -154,29 +188,30 @@ private void readFrom(CompoundTag tag) { this.bidirectional = tag.getBoolean("bidirectional"); } } - + @Override - protected void saveAdditional(CompoundTag tag) { - this.writeTo(tag); - super.saveAdditional(tag); + protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) { + this.writeTo(tag,registries); + super.saveAdditional(tag, registries); } - + @Override - public void load(CompoundTag tag) { - super.load(tag); - this.readFrom(tag); + protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.loadAdditional(tag, registries); + this.readFrom(tag,registries); } - + @Override - public CompoundTag getUpdateTag() { - var tag = new CompoundTag(); - this.writeTo(tag); - return tag; + public CompoundTag getUpdateTag(HolderLookup.Provider registries) { + var result = super.getUpdateTag(registries); + this.writeTo(result,registries); + return result; } - + @Override - public void handleUpdateTag(CompoundTag tag) { - this.readFrom(tag); + public void handleUpdateTag(CompoundTag tag, HolderLookup.Provider lookupProvider) { + this.readFrom(tag,lookupProvider); + super.handleUpdateTag(tag, lookupProvider); } @Nullable @@ -184,10 +219,11 @@ public void handleUpdateTag(CompoundTag tag) { public Packet getUpdatePacket() { return ClientboundBlockEntityDataPacket.create(this); } - + @Override - public void onDataPacket(Connection net, ClientboundBlockEntityDataPacket pkt) { - super.onDataPacket(net, pkt); - this.handleUpdateTag(pkt.getTag()); + public void onDataPacket(Connection net, ClientboundBlockEntityDataPacket pkt, HolderLookup.Provider lookupProvider) { + super.onDataPacket(net, pkt, lookupProvider); + this.handleUpdateTag(pkt.getTag(),lookupProvider); } + } diff --git a/src/main/java/org/teacon/powertool/block/entity/ItemDisplayBlockEntity.java b/src/main/java/org/teacon/powertool/block/entity/ItemDisplayBlockEntity.java index e8728d8..ad921df 100644 --- a/src/main/java/org/teacon/powertool/block/entity/ItemDisplayBlockEntity.java +++ b/src/main/java/org/teacon/powertool/block/entity/ItemDisplayBlockEntity.java @@ -1,6 +1,8 @@ package org.teacon.powertool.block.entity; +import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderLookup; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.Connection; import net.minecraft.network.protocol.Packet; @@ -12,6 +14,10 @@ import org.jetbrains.annotations.Nullable; import org.teacon.powertool.block.PowerToolBlocks; +import javax.annotation.ParametersAreNonnullByDefault; + +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault public class ItemDisplayBlockEntity extends BlockEntity { public ItemStack itemToDisplay = ItemStack.EMPTY; @@ -20,33 +26,34 @@ public class ItemDisplayBlockEntity extends BlockEntity { public ItemDisplayBlockEntity(BlockPos pos, BlockState state) { super(PowerToolBlocks.ITEM_DISPLAY_BLOCK_ENTITY.get(), pos, state); } - + @Override - protected void saveAdditional(CompoundTag tag) { - tag.put("item", this.itemToDisplay.save(new CompoundTag())); + protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) { + tag.put("item", this.itemToDisplay.saveOptional(registries)); tag.putInt("rotation", this.rotation); - super.saveAdditional(tag); + super.saveAdditional(tag, registries); } - + @Override - public void load(CompoundTag tag) { - super.load(tag); - this.itemToDisplay = ItemStack.of(tag.getCompound("item")); + protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.loadAdditional(tag, registries); + this.itemToDisplay = ItemStack.parseOptional(registries,tag.getCompound("item")); this.rotation = tag.getInt("rotation"); } - + @Override - public CompoundTag getUpdateTag() { - var tag = new CompoundTag(); - tag.put("item", this.itemToDisplay.save(new CompoundTag())); - tag.putInt("rotation", this.rotation); - return tag; + public CompoundTag getUpdateTag(HolderLookup.Provider registries) { + var result = super.getUpdateTag(registries); + result.put("item", this.itemToDisplay.saveOptional(registries)); + result.putInt("rotation", this.rotation); + return result; } - + @Override - public void handleUpdateTag(CompoundTag tag) { - this.itemToDisplay = ItemStack.of(tag.getCompound("item")); + public void handleUpdateTag(CompoundTag tag, HolderLookup.Provider registries) { + this.itemToDisplay = ItemStack.parseOptional(registries,tag.getCompound("item")); this.rotation = tag.getInt("rotation"); + super.handleUpdateTag(tag, registries); } @Nullable @@ -54,10 +61,10 @@ public void handleUpdateTag(CompoundTag tag) { public Packet getUpdatePacket() { return ClientboundBlockEntityDataPacket.create(this); } - + @Override - public void onDataPacket(Connection net, ClientboundBlockEntityDataPacket pkt) { - super.onDataPacket(net, pkt); - this.handleUpdateTag(pkt.getTag()); + public void onDataPacket(Connection net, ClientboundBlockEntityDataPacket pkt, HolderLookup.Provider lookupProvider) { + super.onDataPacket(net, pkt, lookupProvider); + this.handleUpdateTag(pkt.getTag(), lookupProvider); } } diff --git a/src/main/java/org/teacon/powertool/block/entity/ItemSupplierBlockEntity.java b/src/main/java/org/teacon/powertool/block/entity/ItemSupplierBlockEntity.java index 4498c4e..34b9251 100644 --- a/src/main/java/org/teacon/powertool/block/entity/ItemSupplierBlockEntity.java +++ b/src/main/java/org/teacon/powertool/block/entity/ItemSupplierBlockEntity.java @@ -1,7 +1,8 @@ package org.teacon.powertool.block.entity; +import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; +import net.minecraft.core.HolderLookup; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.Connection; import net.minecraft.network.protocol.Packet; @@ -10,36 +11,38 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; -import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.common.capabilities.ForgeCapabilities; -import net.minecraftforge.common.util.LazyOptional; -import net.minecraftforge.items.IItemHandler; +import net.neoforged.neoforge.common.util.Lazy; +import net.neoforged.neoforge.items.IItemHandler; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.teacon.powertool.block.PowerToolBlocks; -public class ItemSupplierBlockEntity extends BlockEntity { +import javax.annotation.ParametersAreNonnullByDefault; - public ItemStack theItem = ItemStack.EMPTY; +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +public class ItemSupplierBlockEntity extends BlockEntity{ - final LazyOptional fakeInv = LazyOptional.of(() -> new IItemHandler() { + public ItemStack theItem = ItemStack.EMPTY; + + private final Lazy iItemHandlerLazy = Lazy.of(() -> new IItemHandler() { @Override public int getSlots() { return 1; } - + @NotNull @Override public ItemStack getStackInSlot(int slot) { return theItem; } - + @NotNull @Override public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { return stack; } - + @NotNull @Override public ItemStack extractItem(int slot, int amount, boolean simulate) { @@ -47,44 +50,45 @@ public ItemStack extractItem(int slot, int amount, boolean simulate) { copy.setCount(amount); return copy; } - + @Override public int getSlotLimit(int slot) { return 1; } - + @Override public boolean isItemValid(int slot, @NotNull ItemStack stack) { return false; } }); - + public ItemSupplierBlockEntity(BlockPos pPos, BlockState pBlockState) { super(PowerToolBlocks.ITEM_SUPPLIER_BLOCK_ENTITY.get(), pPos, pBlockState); } - + @Override - protected void saveAdditional(CompoundTag tag) { - tag.put("item", this.theItem.save(new CompoundTag())); - super.saveAdditional(tag); + protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { + this.theItem = ItemStack.parseOptional(registries,tag.getCompound("item")); + super.loadAdditional(tag, registries); } - + @Override - public void load(CompoundTag tag) { - super.load(tag); - this.theItem = ItemStack.of(tag.getCompound("item")); + protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.saveAdditional(tag, registries); + tag.put("item", this.theItem.saveOptional(registries)); } - + @Override - public CompoundTag getUpdateTag() { - var tag = new CompoundTag(); - tag.put("item", this.theItem.save(new CompoundTag())); - return tag; + public CompoundTag getUpdateTag(HolderLookup.Provider registries) { + var result = super.getUpdateTag(registries); + result.put("item", this.theItem.saveOptional(registries)); + return result; } - + @Override - public void handleUpdateTag(CompoundTag tag) { - this.theItem = ItemStack.of(tag.getCompound("item")); + public void handleUpdateTag(CompoundTag tag, HolderLookup.Provider registries) { + this.theItem = ItemStack.parseOptional(registries,tag.getCompound("item")); + super.handleUpdateTag(tag, registries); } @Nullable @@ -92,22 +96,16 @@ public void handleUpdateTag(CompoundTag tag) { public Packet getUpdatePacket() { return ClientboundBlockEntityDataPacket.create(this); } - + + @Override - public void onDataPacket(Connection net, ClientboundBlockEntityDataPacket pkt) { - super.onDataPacket(net, pkt); - this.handleUpdateTag(pkt.getTag()); + public void onDataPacket(Connection net, ClientboundBlockEntityDataPacket pkt, HolderLookup.Provider lookupProvider) { + super.onDataPacket(net, pkt, lookupProvider); + this.handleUpdateTag(pkt.getTag(),lookupProvider); } - - @NotNull - @Override - public LazyOptional getCapability(@NotNull Capability cap, Direction dir) { - return cap == ForgeCapabilities.ITEM_HANDLER ? this.fakeInv.cast() : super.getCapability(cap, dir); - } - - @Override - public void invalidateCaps() { - this.fakeInv.invalidate(); - super.invalidateCaps(); + + public IItemHandler getItemHandler() { + return iItemHandlerLazy.get(); } + } diff --git a/src/main/java/org/teacon/powertool/block/entity/PeriodicCommandBlockEntity.java b/src/main/java/org/teacon/powertool/block/entity/PeriodicCommandBlockEntity.java index f35dad2..9e73d7f 100644 --- a/src/main/java/org/teacon/powertool/block/entity/PeriodicCommandBlockEntity.java +++ b/src/main/java/org/teacon/powertool/block/entity/PeriodicCommandBlockEntity.java @@ -2,6 +2,7 @@ import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderLookup; import net.minecraft.nbt.CompoundTag; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.entity.CommandBlockEntity; @@ -38,17 +39,17 @@ public Mode getMode() { return super.getMode(); } } - + @Override - protected void saveAdditional(CompoundTag tag) { - super.saveAdditional(tag); + protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.saveAdditional(tag, registries); tag.putInt("period", period); } - + @Override - public void load(CompoundTag tag) { - super.load(tag); + protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { period = tag.getInt("period"); + super.loadAdditional(tag, registries); } @Override diff --git a/src/main/java/org/teacon/powertool/block/entity/PowerSupplyBlockEntity.java b/src/main/java/org/teacon/powertool/block/entity/PowerSupplyBlockEntity.java index c0311ce..43c0f63 100644 --- a/src/main/java/org/teacon/powertool/block/entity/PowerSupplyBlockEntity.java +++ b/src/main/java/org/teacon/powertool/block/entity/PowerSupplyBlockEntity.java @@ -1,21 +1,22 @@ package org.teacon.powertool.block.entity; + import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; +import net.minecraft.core.HolderLookup; import net.minecraft.nbt.CompoundTag; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; -import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.common.capabilities.ForgeCapabilities; -import net.minecraftforge.common.util.LazyOptional; -import net.minecraftforge.energy.IEnergyStorage; -import org.jetbrains.annotations.NotNull; +import net.neoforged.neoforge.common.util.Lazy; +import net.neoforged.neoforge.energy.IEnergyStorage; import org.teacon.powertool.block.PowerSupplyBlock; import org.teacon.powertool.block.PowerToolBlocks; +import javax.annotation.ParametersAreNonnullByDefault; + +@ParametersAreNonnullByDefault public final class PowerSupplyBlockEntity extends BlockEntity { - private final LazyOptional energyStore = LazyOptional.of(() -> new IEnergyStorage() { + private final Lazy energyStore = Lazy.of(() -> new IEnergyStorage() { @Override public int receiveEnergy(int maxReceive, boolean simulate) { return 0; @@ -53,30 +54,22 @@ public PowerSupplyBlockEntity(BlockPos pWorldPosition, BlockState pBlockState) { super(PowerToolBlocks.POWER_SUPPLY_BLOCK_ENTITY.get(), pWorldPosition, pBlockState); this.data.markDirty = this::setChanged; } - + @Override - protected void saveAdditional(CompoundTag tag) { - tag.putInt("status", this.data.status); - tag.putInt("power", this.data.power); - super.saveAdditional(tag); - } - - @Override - public void load(CompoundTag tag) { - super.load(tag); + protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.loadAdditional(tag, registries); this.data.status = tag.getInt("status"); this.data.power = tag.getInt("power"); } - - @NotNull + @Override - public LazyOptional getCapability(@NotNull Capability cap, Direction d) { - return cap == ForgeCapabilities.ENERGY ? this.energyStore.cast() : super.getCapability(cap, d); + protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) { + tag.putInt("status", this.data.status); + tag.putInt("power", this.data.power); + super.saveAdditional(tag, registries); } - - @Override - public void invalidateCaps() { - this.energyStore.invalidate(); - super.invalidateCaps(); + + public IEnergyStorage getEnergyStore() { + return energyStore.get(); } } diff --git a/src/main/java/org/teacon/powertool/bridge/PeriodCommandBlockBridge.java b/src/main/java/org/teacon/powertool/bridge/PeriodCommandBlockBridge.java index c8e8c30..f863308 100644 --- a/src/main/java/org/teacon/powertool/bridge/PeriodCommandBlockBridge.java +++ b/src/main/java/org/teacon/powertool/bridge/PeriodCommandBlockBridge.java @@ -5,5 +5,5 @@ public interface PeriodCommandBlockBridge { - int powerToolPeriod(ServerLevel level, BlockPos pos); + int powerTool$Period(ServerLevel level, BlockPos pos); } diff --git a/src/main/java/org/teacon/powertool/client/ButtonWithHighlight.java b/src/main/java/org/teacon/powertool/client/ButtonWithHighlight.java index 1b23105..e1aed83 100644 --- a/src/main/java/org/teacon/powertool/client/ButtonWithHighlight.java +++ b/src/main/java/org/teacon/powertool/client/ButtonWithHighlight.java @@ -6,6 +6,9 @@ import net.minecraft.client.renderer.GameRenderer; import net.minecraft.resources.ResourceLocation; +import javax.annotation.ParametersAreNonnullByDefault; + +@ParametersAreNonnullByDefault public class ButtonWithHighlight extends Button { private final ResourceLocation texture; diff --git a/src/main/java/org/teacon/powertool/client/ClientEvents.java b/src/main/java/org/teacon/powertool/client/ClientEvents.java index cde6d2c..dc1aedc 100644 --- a/src/main/java/org/teacon/powertool/client/ClientEvents.java +++ b/src/main/java/org/teacon/powertool/client/ClientEvents.java @@ -1,39 +1,24 @@ package org.teacon.powertool.client; -import net.minecraft.client.gui.screens.MenuScreens; import net.minecraft.client.gui.screens.inventory.CommandBlockEditScreen; -import net.minecraft.client.player.AbstractClientPlayer; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.world.entity.Entity; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.client.event.EntityRenderersEvent; -import net.minecraftforge.client.event.ScreenEvent; -import net.minecraftforge.event.AttachCapabilitiesEvent; -import net.minecraftforge.event.TickEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.client.event.ClientTickEvent; +import net.neoforged.neoforge.client.event.EntityRenderersEvent; +import net.neoforged.neoforge.client.event.RegisterMenuScreensEvent; +import net.neoforged.neoforge.client.event.ScreenEvent; import org.teacon.powertool.PowerTool; import org.teacon.powertool.block.PowerToolBlocks; import org.teacon.powertool.block.entity.PeriodicCommandBlockEntity; import org.teacon.powertool.entity.PowerToolEntities; import org.teacon.powertool.menu.PowerToolMenus; -import org.teacon.powertool.network.capability.Permission; -import java.util.function.Predicate; - -@Mod.EventBusSubscriber(value = Dist.CLIENT, modid = PowerTool.MODID) +@EventBusSubscriber(value = Dist.CLIENT, modid = PowerTool.MODID) public class ClientEvents { static int tickCount = 0; - @SubscribeEvent - public static void on(AttachCapabilitiesEvent event) { - if (event.getObject() instanceof AbstractClientPlayer) { - event.addCapability(Permission.KEY, new Permission.Provider()); - } - } - @SubscribeEvent public static void on(ScreenEvent.Opening event) { if (event.getScreen() instanceof CommandBlockEditScreen screen @@ -43,19 +28,15 @@ public static void on(ScreenEvent.Opening event) { } @SubscribeEvent - public static void on(TickEvent.ClientTickEvent event) { - if (event.phase == TickEvent.Phase.START) { - tickCount++; - } + public static void on(ClientTickEvent.Pre event) { + tickCount++; } - @Mod.EventBusSubscriber(value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.MOD, modid = PowerTool.MODID) + @EventBusSubscriber(value = Dist.CLIENT, bus = EventBusSubscriber.Bus.MOD, modid = PowerTool.MODID) public static final class OnModBus { @SubscribeEvent - public static void setup(FMLClientSetupEvent event) { - event.enqueueWork(() -> { - MenuScreens.register(PowerToolMenus.POWER_SUPPLY_MENU.get(), PowerSupplyScreen::new); - }); + public static void setup(final RegisterMenuScreensEvent event) { + event.register(PowerToolMenus.POWER_SUPPLY_MENU.get(), PowerSupplyScreen::new); } @SubscribeEvent public static void ber(EntityRenderersEvent.RegisterRenderers event) { diff --git a/src/main/java/org/teacon/powertool/client/FenceKnotRenderer.java b/src/main/java/org/teacon/powertool/client/FenceKnotRenderer.java index 9fbfd7b..6cffe5e 100644 --- a/src/main/java/org/teacon/powertool/client/FenceKnotRenderer.java +++ b/src/main/java/org/teacon/powertool/client/FenceKnotRenderer.java @@ -2,6 +2,7 @@ import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; +import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; import net.minecraft.client.model.LeashKnotModel; @@ -21,9 +22,14 @@ import net.minecraft.world.phys.Vec3; import org.joml.Matrix4f; import org.teacon.powertool.entity.FenceKnotEntity; +import org.teacon.powertool.utils.VanillaUtils; +import javax.annotation.ParametersAreNonnullByDefault; + +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault public class FenceKnotRenderer extends EntityRenderer { - private static final ResourceLocation KNOT_LOCATION = new ResourceLocation("textures/entity/lead_knot.png"); + private static final ResourceLocation KNOT_LOCATION = ResourceLocation.withDefaultNamespace("textures/entity/lead_knot.png"); private final LeashKnotModel model; public FenceKnotRenderer(EntityRendererProvider.Context context) { @@ -43,7 +49,7 @@ public void render(FenceKnotEntity e, float yRot, float partialTick, PoseStack t transform.scale(-1.0F, -1.0F, 1.0F); this.model.setupAnim(e, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F); VertexConsumer vertexconsumer = buffers.getBuffer(this.model.renderType(KNOT_LOCATION)); - this.model.renderToBuffer(transform, vertexconsumer, packedLight, OverlayTexture.NO_OVERLAY, 1.0F, 1.0F, 1.0F, 1.0F); + this.model.renderToBuffer(transform, vertexconsumer, packedLight, OverlayTexture.NO_OVERLAY, VanillaUtils.getColor(255,255,255,255)); transform.popPose(); for (var fromPos : e.getConnectTo()) { this.renderLeash(e, partialTick, transform, buffers, fromPos); @@ -115,8 +121,8 @@ private static void addVertexPair(VertexConsumer vertexes, Matrix4f transform, f float f5 = p_174310_ * f; float f6 = p_174311_ > 0.0F ? p_174311_ * f * f : p_174311_ - p_174311_ * (1.0F - f) * (1.0F - f); float f7 = p_174312_ * f; - vertexes.vertex(transform, f5 - p_174319_, f6 + p_174318_, f7 + p_174320_).color(f2, f3, f4, 1.0F).uv2(k).endVertex(); - vertexes.vertex(transform, f5 + p_174319_, f6 + p_174317_ - p_174318_, f7 - p_174320_).color(f2, f3, f4, 1.0F).uv2(k).endVertex(); + vertexes.addVertex(transform, f5 - p_174319_, f6 + p_174318_, f7 + p_174320_).setColor(f2, f3, f4, 1.0F).setLight(k); + vertexes.addVertex(transform, f5 + p_174319_, f6 + p_174317_ - p_174318_, f7 - p_174320_).setColor(f2, f3, f4, 1.0F).setLight(k); } } diff --git a/src/main/java/org/teacon/powertool/client/HolographicSignEditingScreen.java b/src/main/java/org/teacon/powertool/client/HolographicSignEditingScreen.java index 5d63e26..79b5bed 100644 --- a/src/main/java/org/teacon/powertool/client/HolographicSignEditingScreen.java +++ b/src/main/java/org/teacon/powertool/client/HolographicSignEditingScreen.java @@ -15,11 +15,10 @@ import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.TextColor; -import net.minecraftforge.network.PacketDistributor; +import net.neoforged.neoforge.network.PacketDistributor; import org.jetbrains.annotations.NotNull; import org.lwjgl.glfw.GLFW; import org.teacon.powertool.block.entity.HolographicSignBlockEntity; -import org.teacon.powertool.network.PowerToolNetwork; import org.teacon.powertool.network.server.UpdateHolographicSignData; import java.util.Arrays; @@ -99,7 +98,7 @@ protected void init() { .createNarration(displayed -> Component.translatable("powertool.gui.holographic_sign.scale", displayed.get())) .build(); - Button scaleUp = new Button.Builder(Component.literal("+"), btn -> this.scale += 0.125) + Button scaleUp = new Button.Builder(Component.literal("+"), btn -> this.scale += 0.125f) .pos(100, 0) .size(20, 20) .createNarration(displayed -> Component.translatable("powertool.gui.holographic_sign.scale", displayed.get())) @@ -132,7 +131,7 @@ protected void init() { this.colorInput = new EditBox(this.minecraft.font, 280 + innerPadding * 2, 0, 50, 20, Component.empty()); this.colorInput.setValue("#" + Integer.toHexString(this.colorInARGB)); this.colorInput.setResponder(string -> { - TextColor color = TextColor.parseColor(this.colorInput.getValue()); + TextColor color = TextColor.parseColor(this.colorInput.getValue()).result().orElse(null); this.colorInARGB = color == null ? 0xFFFFFFFF : color.getValue() | 0xFF000000; }); this.colorInput.setFocused(false); @@ -243,9 +242,10 @@ public void removed() { } } var toSend = Arrays.copyOfRange(this.messages, 0, last + 1); - PowerToolNetwork.channel().send(PacketDistributor.SERVER.with(() -> null), - new UpdateHolographicSignData(this.sign.getBlockPos(), toSend, this.colorInARGB, this.scale, - this.textAlign, this.shadowType, this.layerArrange,this.locked,this.rotation,this.bidirectional)); + PacketDistributor.sendToServer(UpdateHolographicSignData.create(this.sign.getBlockPos(), + Arrays.asList(toSend), this.colorInARGB, this.scale, + this.textAlign, this.shadowType, this.layerArrange, + this.locked,this.rotation,this.bidirectional)); } @Override @@ -305,10 +305,10 @@ public boolean keyPressed(int keyCode, int scanCode, int modifiers) { @Override public boolean mouseClicked(double mouseX, double mouseY, int button) { - if (!this.colorInput.mouseClicked(mouseX, mouseX, button)) { + if (!this.colorInput.mouseClicked(mouseX, mouseY, button)) { this.colorInput.setFocused(false); } - if (!this.rotationInput.mouseClicked(mouseX, mouseX, button)) { + if (!this.rotationInput.mouseClicked(mouseX, mouseY, button)) { this.rotationInput.setFocused(false); } this.setFocused(null); @@ -318,7 +318,7 @@ public boolean mouseClicked(double mouseX, double mouseY, int button) { @Override public void render(@NotNull GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) { Lighting.setupForFlatItems(); - this.renderBackground(guiGraphics); + super.render(guiGraphics, mouseX, mouseY, partialTick); guiGraphics.drawString(this.font, Component.translatable("powertool.gui.holographic_sign.scale", this.scale), 7, 7, 0xFFFFFF, true); // I don't know, someone please explain why these transforms are necessary??? var transform = guiGraphics.pose(); @@ -384,6 +384,6 @@ public void render(@NotNull GuiGraphics guiGraphics, int mouseX, int mouseY, flo transform.popPose(); Lighting.setupFor3DItems(); - super.render(guiGraphics, mouseX, mouseY, partialTick); + } } diff --git a/src/main/java/org/teacon/powertool/client/ItemDisplayBlockEntityRenderer.java b/src/main/java/org/teacon/powertool/client/ItemDisplayBlockEntityRenderer.java index 9016630..39c01bd 100644 --- a/src/main/java/org/teacon/powertool/client/ItemDisplayBlockEntityRenderer.java +++ b/src/main/java/org/teacon/powertool/client/ItemDisplayBlockEntityRenderer.java @@ -11,6 +11,9 @@ import net.minecraft.world.level.block.state.properties.BlockStateProperties; import org.teacon.powertool.block.entity.ItemDisplayBlockEntity; +import javax.annotation.ParametersAreNonnullByDefault; + +@ParametersAreNonnullByDefault public class ItemDisplayBlockEntityRenderer implements BlockEntityRenderer { private final ItemRenderer itemRenderer; diff --git a/src/main/java/org/teacon/powertool/client/ItemSupplierBlockEntityRenderer.java b/src/main/java/org/teacon/powertool/client/ItemSupplierBlockEntityRenderer.java index e83f9e8..e5cb198 100644 --- a/src/main/java/org/teacon/powertool/client/ItemSupplierBlockEntityRenderer.java +++ b/src/main/java/org/teacon/powertool/client/ItemSupplierBlockEntityRenderer.java @@ -11,6 +11,9 @@ import net.minecraft.world.item.ItemStack; import org.teacon.powertool.block.entity.ItemSupplierBlockEntity; +import javax.annotation.ParametersAreNonnullByDefault; + +@ParametersAreNonnullByDefault public class ItemSupplierBlockEntityRenderer implements BlockEntityRenderer { public ItemSupplierBlockEntityRenderer(BlockEntityRendererProvider.Context context) { diff --git a/src/main/java/org/teacon/powertool/client/PeriodicCommandBlockEditScreen.java b/src/main/java/org/teacon/powertool/client/PeriodicCommandBlockEditScreen.java index 2be177f..5e35e69 100644 --- a/src/main/java/org/teacon/powertool/client/PeriodicCommandBlockEditScreen.java +++ b/src/main/java/org/teacon/powertool/client/PeriodicCommandBlockEditScreen.java @@ -6,8 +6,8 @@ import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; import net.minecraft.world.level.BaseCommandBlock; +import net.neoforged.neoforge.network.PacketDistributor; import org.teacon.powertool.block.entity.PeriodicCommandBlockEntity; -import org.teacon.powertool.network.PowerToolNetwork; import org.teacon.powertool.network.server.SetCommandBlockPacket; import javax.annotation.ParametersAreNonnullByDefault; @@ -44,12 +44,13 @@ public void render(GuiGraphics guiGraphics, int pMouseX, int pMouseY, float pPar guiGraphics.drawString(this.font, PERIOD, this.width / 2 - 150 + (300 - 40), 95, 10526880); } + //todo 修复命令方块使其正常工作 @Override protected void populateAndSendPacket(BaseCommandBlock baseCommandBlock) { super.populateAndSendPacket(baseCommandBlock); try { var period = Integer.parseInt(this.periodBox.getValue()); - PowerToolNetwork.channel().sendToServer(new SetCommandBlockPacket( + PacketDistributor.sendToServer(new SetCommandBlockPacket( BlockPos.containing(baseCommandBlock.getPosition()), period )); } catch (NumberFormatException ignored) { diff --git a/src/main/java/org/teacon/powertool/client/PowerSupplyScreen.java b/src/main/java/org/teacon/powertool/client/PowerSupplyScreen.java index e4ee94d..33ef722 100644 --- a/src/main/java/org/teacon/powertool/client/PowerSupplyScreen.java +++ b/src/main/java/org/teacon/powertool/client/PowerSupplyScreen.java @@ -10,16 +10,18 @@ import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.player.Inventory; -import net.minecraftforge.network.PacketDistributor; +import net.neoforged.neoforge.network.PacketDistributor; import org.lwjgl.glfw.GLFW; -import org.teacon.powertool.PowerTool; import org.teacon.powertool.menu.PowerSupplyMenu; -import org.teacon.powertool.network.PowerToolNetwork; import org.teacon.powertool.network.server.UpdatePowerSupplyData; +import org.teacon.powertool.utils.VanillaUtils; +import javax.annotation.ParametersAreNonnullByDefault; + +@ParametersAreNonnullByDefault public final class PowerSupplyScreen extends AbstractContainerScreen { - private static final ResourceLocation BG_LOCATION = new ResourceLocation(PowerTool.MODID, "textures/gui/power_supply.png"); + private static final ResourceLocation BG_LOCATION = VanillaUtils.modResourceLocation("textures/gui/power_supply.png"); private EditBox input; private ButtonWithHighlight minus, plus; @@ -35,11 +37,11 @@ public PowerSupplyScreen(PowerSupplyMenu menu, Inventory playerInventory, Compon public void onToggled(Button toggle) { this.status = this.status == 0 ? 1 : 0; - PowerToolNetwork.channel().send(PacketDistributor.SERVER.with(null), new UpdatePowerSupplyData(0, this.status)); + PacketDistributor.sendToServer(new UpdatePowerSupplyData(0, this.status)); } public void updatePowerOutput() { - PowerToolNetwork.channel().send(PacketDistributor.SERVER.with(null), new UpdatePowerSupplyData(1, this.power)); + PacketDistributor.sendToServer(new UpdatePowerSupplyData(1, this.power)); } @Override @@ -83,7 +85,6 @@ protected void init() { @Override protected void containerTick() { super.containerTick(); - this.input.tick(); this.minus.tick(); this.plus.tick(); } @@ -113,7 +114,7 @@ public boolean keyPressed(int keyCode, int scanCode, int modifiers) { @Override public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) { - this.renderBackground(guiGraphics); + this.renderBackground(guiGraphics,mouseX,mouseY,partialTick); super.render(guiGraphics, mouseX, mouseY, partialTick); RenderSystem.disableBlend(); this.input.render(guiGraphics, mouseX, mouseY, partialTick); diff --git a/src/main/java/org/teacon/powertool/command/FlyCommand.java b/src/main/java/org/teacon/powertool/command/FlyCommand.java index d727562..f4da9ae 100644 --- a/src/main/java/org/teacon/powertool/command/FlyCommand.java +++ b/src/main/java/org/teacon/powertool/command/FlyCommand.java @@ -19,8 +19,12 @@ private static int fly0(CommandContext sourceStack) { var abilities = p.getAbilities(); var gameMode = p.gameMode; if (gameMode.isSurvival()) { + //todo 使用attribute去控制飞行 + //p.getAttribute(NeoForgeMod.CREATIVE_FLIGHT).getValue(); + //noinspection deprecation abilities.mayfly = !abilities.mayfly; p.connection.send(new ClientboundPlayerAbilitiesPacket(p.getAbilities())); + //noinspection deprecation if (abilities.mayfly) { sourceStack.getSource().sendSuccess(() -> Component.translatable("powertool.command.fly.enabled"), true); } else { diff --git a/src/main/java/org/teacon/powertool/command/PowerToolCommands.java b/src/main/java/org/teacon/powertool/command/PowerToolCommands.java index 34ae294..7c9bd34 100644 --- a/src/main/java/org/teacon/powertool/command/PowerToolCommands.java +++ b/src/main/java/org/teacon/powertool/command/PowerToolCommands.java @@ -1,11 +1,11 @@ package org.teacon.powertool.command; -import net.minecraftforge.event.RegisterCommandsEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.event.RegisterCommandsEvent; import org.teacon.powertool.PowerTool; -@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.FORGE, modid = PowerTool.MODID) +@EventBusSubscriber(bus = EventBusSubscriber.Bus.GAME, modid = PowerTool.MODID) public class PowerToolCommands { @SubscribeEvent diff --git a/src/main/java/org/teacon/powertool/compat/top/PowerToolTOPProvider.java b/src/main/java/org/teacon/powertool/compat/top/PowerToolTOPProvider.java index bee6edb..fb0fd6c 100644 --- a/src/main/java/org/teacon/powertool/compat/top/PowerToolTOPProvider.java +++ b/src/main/java/org/teacon/powertool/compat/top/PowerToolTOPProvider.java @@ -11,15 +11,15 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.state.BlockState; -import org.teacon.powertool.PowerTool; import org.teacon.powertool.block.entity.ItemSupplierBlockEntity; +import org.teacon.powertool.utils.VanillaUtils; import java.util.function.Function; public final class PowerToolTOPProvider implements IProbeInfoProvider, Function { @Override public ResourceLocation getID() { - return new ResourceLocation(PowerTool.MODID, "the_one_probe"); + return VanillaUtils.modResourceLocation( "the_one_probe"); } @Override diff --git a/src/main/java/org/teacon/powertool/compat/top/TOPCompatibility.java b/src/main/java/org/teacon/powertool/compat/top/TOPCompatibility.java index 9f130f5..79456cb 100644 --- a/src/main/java/org/teacon/powertool/compat/top/TOPCompatibility.java +++ b/src/main/java/org/teacon/powertool/compat/top/TOPCompatibility.java @@ -1,13 +1,13 @@ package org.teacon.powertool.compat.top; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.InterModComms; -import net.minecraftforge.fml.ModList; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.InterModComms; +import net.neoforged.fml.ModList; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.fml.event.lifecycle.InterModEnqueueEvent; import org.teacon.powertool.PowerTool; -@Mod.EventBusSubscriber(modid = PowerTool.MODID, bus = Mod.EventBusSubscriber.Bus.MOD) +@EventBusSubscriber(modid = PowerTool.MODID, bus = EventBusSubscriber.Bus.MOD) public final class TOPCompatibility { @SubscribeEvent diff --git a/src/main/java/org/teacon/powertool/datagen/DataGenerators.java b/src/main/java/org/teacon/powertool/datagen/DataGenerators.java index c28cf94..63a546b 100644 --- a/src/main/java/org/teacon/powertool/datagen/DataGenerators.java +++ b/src/main/java/org/teacon/powertool/datagen/DataGenerators.java @@ -2,14 +2,14 @@ import net.minecraft.data.DataGenerator; import net.minecraft.data.PackOutput; -import net.minecraftforge.common.data.ExistingFileHelper; -import net.minecraftforge.data.event.GatherDataEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.common.data.ExistingFileHelper; +import net.neoforged.neoforge.data.event.GatherDataEvent; import org.teacon.powertool.PowerTool; -@Mod.EventBusSubscriber(modid = DataGenerators.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD) +@EventBusSubscriber(modid = DataGenerators.MOD_ID, bus = EventBusSubscriber.Bus.MOD) public class DataGenerators { public static final String MOD_ID = PowerTool.MODID; diff --git a/src/main/java/org/teacon/powertool/datagen/ModBlockModelProvider.java b/src/main/java/org/teacon/powertool/datagen/ModBlockModelProvider.java index be324e3..a914c2f 100644 --- a/src/main/java/org/teacon/powertool/datagen/ModBlockModelProvider.java +++ b/src/main/java/org/teacon/powertool/datagen/ModBlockModelProvider.java @@ -1,18 +1,19 @@ package org.teacon.powertool.datagen; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.data.PackOutput; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import net.minecraftforge.client.model.generators.BlockStateProvider; -import net.minecraftforge.client.model.generators.ConfiguredModel; -import net.minecraftforge.common.data.ExistingFileHelper; -import net.minecraftforge.registries.ForgeRegistries; +import net.neoforged.neoforge.client.model.generators.BlockStateProvider; +import net.neoforged.neoforge.client.model.generators.ConfiguredModel; +import net.neoforged.neoforge.common.data.ExistingFileHelper; import org.teacon.powertool.block.CosmeticFurnace; import org.teacon.powertool.block.PowerToolBlocks; import java.util.Objects; + public class ModBlockModelProvider extends BlockStateProvider { public ModBlockModelProvider(PackOutput output, ExistingFileHelper existingFileHelper) { @@ -29,18 +30,20 @@ protected void registerStatesAndModels() { } private Block cosmeticBlock(Block block){ - return ForgeRegistries.BLOCKS.getValue(modLoc("cosmetic_" + name(block))); + return BuiltInRegistries.BLOCK.get(modLoc("cosmetic_" + name(block))); } private static String name(Block block){ - return Objects.requireNonNull(ForgeRegistries.BLOCKS.getKey(block)).getPath(); + return Objects.requireNonNull(BuiltInRegistries.BLOCK.getKey(block)).getPath(); } + @SuppressWarnings("SameParameterValue") private void cosmeticHorizontalBlockWithItem(Block block){ horizontalBlock(cosmeticBlock(block), models().getExistingFile(mcLoc(name(block)))); item(block); } + @SuppressWarnings("SameParameterValue") private void cosmeticDirectionalBlockWithItem(Block block){ directionalBlock(cosmeticBlock(block), models().getExistingFile(mcLoc(name(block)))); item(block); diff --git a/src/main/java/org/teacon/powertool/entity/FenceKnotEntity.java b/src/main/java/org/teacon/powertool/entity/FenceKnotEntity.java index ee0e8fe..5d94b67 100644 --- a/src/main/java/org/teacon/powertool/entity/FenceKnotEntity.java +++ b/src/main/java/org/teacon/powertool/entity/FenceKnotEntity.java @@ -1,16 +1,23 @@ package org.teacon.powertool.entity; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import io.netty.buffer.ByteBuf; +import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; import net.minecraft.nbt.NbtUtils; import net.minecraft.nbt.Tag; import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.game.ClientGamePacketListener; import net.minecraft.network.protocol.game.ClientboundAddEntityPacket; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.SynchedEntityData; +import net.minecraft.server.level.ServerEntity; import net.minecraft.sounds.SoundEvents; import net.minecraft.tags.BlockTags; import net.minecraft.world.InteractionHand; @@ -24,13 +31,17 @@ import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.Nullable; +import org.teacon.powertool.item.PowerToolItems; +import javax.annotation.ParametersAreNonnullByDefault; import java.util.LinkedHashSet; import java.util.Set; +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault public class FenceKnotEntity extends HangingEntity { - private static final EntityDataAccessor> CONNECT_TO = SynchedEntityData.defineId(FenceKnotEntity.class, PowerToolEntities.BLOCK_POS_LIST.get()); + private static final EntityDataAccessor> CONNECT_TO = SynchedEntityData.defineId(FenceKnotEntity.class, PowerToolEntities.BLOCK_POS_LIST); public FenceKnotEntity(Level level, BlockPos pos) { super(PowerToolEntities.FENCE_KNOT.get(), level, pos); @@ -44,26 +55,11 @@ public FenceKnotEntity(EntityType type, Level level) { this.noCulling = true; } - @Override - protected void defineSynchedData() { - this.getEntityData().define(CONNECT_TO, new LinkedHashSet<>()); - } - @Override protected Vec3 getLeashOffset() { return Vec3.ZERO; } - @Override - public int getWidth() { - return 9; - } - - @Override - public int getHeight() { - return 9; - } - @Override public void dropItem(@Nullable Entity e) { this.playSound(SoundEvents.LEASH_KNOT_BREAK, 1.0F, 1.0F); @@ -80,7 +76,7 @@ public void readAdditionalSaveData(CompoundTag data) { if (!toPos.isEmpty()) { var list = new LinkedHashSet(); for (var tag : toPos) { - list.add(NbtUtils.readBlockPos((CompoundTag) tag)); + NbtUtils.readBlockPos((CompoundTag) tag, "pos").ifPresent(list::add); } this.getEntityData().set(CONNECT_TO, list); } @@ -90,13 +86,16 @@ public void readAdditionalSaveData(CompoundTag data) { public void addAdditionalSaveData(CompoundTag data) { var toPos = new ListTag(); for (var pos : this.getEntityData().get(CONNECT_TO)) { - toPos.add(NbtUtils.writeBlockPos(pos)); + var tag = new CompoundTag(); + tag.put("pos", NbtUtils.writeBlockPos(pos)); + toPos.add(tag); } data.put("ConnectTo", toPos); } - + + @Override - public Packet getAddEntityPacket() { + public Packet getAddEntityPacket(ServerEntity entity) { return new ClientboundAddEntityPacket(this, 0, this.getPos()); } @@ -108,16 +107,16 @@ public InteractionResult interact(Player p, InteractionHand hand) { var held = p.getItemInHand(hand); if (held.getItem() == Items.LEAD) { - var itemNbt = held.getTagElement("PowerToolKnot"); - if (itemNbt == null) { + var data = held.get(PowerToolItems.KNOT_DATA); + if (data == null) { // Connection start. - held.getOrCreateTag().put("PowerToolKnot", NbtUtils.writeBlockPos(this.pos)); + held.set(PowerToolItems.KNOT_DATA,new PowerToolKnotData(this.pos)); p.sendSystemMessage(Component.translatable("entity.powertool.fence_knot.connecting", this.pos.toShortString())); } else { - var fromPos = NbtUtils.readBlockPos(itemNbt); + var fromPos = data.pos; var knots = this.level().getEntitiesOfClass(FenceKnotEntity.class, new AABB(fromPos.getX(), fromPos.getY(), fromPos.getZ(), fromPos.getX() + 1, fromPos.getY() + 1, fromPos.getZ() + 1)); if (!knots.isEmpty()) { - var fromKnot = knots.get(0); + var fromKnot = knots.getFirst(); var thisConnectTo = this.getEntityData().get(CONNECT_TO); var otherConnectTo = fromKnot.getEntityData().get(CONNECT_TO); if (otherConnectTo.contains(this.pos)) { @@ -140,13 +139,7 @@ public InteractionResult interact(Player p, InteractionHand hand) { p.sendSystemMessage(Component.translatable("entity.powertool.fence_knot.connected", fromKnot.pos.toShortString(), this.pos.toShortString())); } } - var mainTag = held.getTag(); - if (mainTag != null) { - mainTag.remove("PowerToolKnot"); - if (mainTag.isEmpty()) { - held.setTag(null); - } - } + held.set(PowerToolItems.KNOT_DATA,null); } } return InteractionResult.CONSUME; @@ -156,21 +149,42 @@ public InteractionResult interact(Player p, InteractionHand hand) { public boolean survives() { return this.level().getBlockState(this.pos).is(BlockTags.FENCES); } - + + @Override + protected void defineSynchedData(SynchedEntityData.Builder builder) { + builder.define(CONNECT_TO,new LinkedHashSet<>()); + } + @Override public boolean shouldRenderAtSqrDistance(double distanceSq) { return distanceSq < 1024.0; } - + @Override - protected void recalculateBoundingBox() { - this.setPosRaw((double)this.pos.getX() + 0.5D, (double)this.pos.getY() + 0.375D, (double)this.pos.getZ() + 0.5D); + protected AABB calculateBoundingBox(BlockPos pos, Direction direction) { + var x_ = pos.getX() + 0.5D; + var y_ = pos.getY() + 0.375D; + var z_ = pos.getZ() + 0.5D; double width = (double)this.getType().getWidth() / 2.0D; double height = this.getType().getHeight(); - this.setBoundingBox(new AABB(this.getX() - width, this.getY(), this.getZ() - width, this.getX() + width, this.getY() + height, this.getZ() + width)); + return new AABB(x_ - width, y_, z_ - width, x_ + width, y_ + height, z_ + width); } - + public Set getConnectTo() { return this.entityData.get(CONNECT_TO); } + + public record PowerToolKnotData(BlockPos pos) { + + public static final Codec CODEC = RecordCodecBuilder.create( + ins -> ins.group( + BlockPos.CODEC.fieldOf("pos").forGetter(PowerToolKnotData::pos) + ).apply(ins, PowerToolKnotData::new)); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + BlockPos.STREAM_CODEC, + PowerToolKnotData::pos, + PowerToolKnotData::new + ); + } } diff --git a/src/main/java/org/teacon/powertool/entity/PowerToolEntities.java b/src/main/java/org/teacon/powertool/entity/PowerToolEntities.java index 16e9de1..2adf44d 100644 --- a/src/main/java/org/teacon/powertool/entity/PowerToolEntities.java +++ b/src/main/java/org/teacon/powertool/entity/PowerToolEntities.java @@ -1,55 +1,34 @@ package org.teacon.powertool.entity; import net.minecraft.core.BlockPos; -import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.core.registries.Registries; +import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.syncher.EntityDataSerializer; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.MobCategory; -import net.minecraftforge.eventbus.api.IEventBus; -import net.minecraftforge.registries.DeferredRegister; -import net.minecraftforge.registries.ForgeRegistries; -import net.minecraftforge.registries.RegistryObject; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.registries.DeferredHolder; +import net.neoforged.neoforge.registries.DeferredRegister; import org.teacon.powertool.PowerTool; -import java.util.LinkedHashSet; +import java.util.HashSet; import java.util.Set; public class PowerToolEntities { - public static final DeferredRegister> ENTITIES = DeferredRegister.create(ForgeRegistries.ENTITY_TYPES, PowerTool.MODID); + public static final DeferredRegister> ENTITIES = DeferredRegister.create(Registries.ENTITY_TYPE, PowerTool.MODID); + - public static final DeferredRegister> ENTITY_DATA_SERIALIZERS = DeferredRegister.create(ForgeRegistries.Keys.ENTITY_DATA_SERIALIZERS, PowerTool.MODID); - - public static final RegistryObject> FENCE_KNOT = ENTITIES.register("fence_knot", () -> + public static final DeferredHolder,EntityType> FENCE_KNOT = ENTITIES.register("fence_knot", () -> EntityType.Builder.of(FenceKnotEntity::new, MobCategory.MISC) .sized(0.375F, 0.5F) .clientTrackingRange(10) .updateInterval(Integer.MAX_VALUE) .build("fence_knot")); - public static final RegistryObject>> BLOCK_POS_LIST = ENTITY_DATA_SERIALIZERS.register("block_pos_list", () -> - new EntityDataSerializer.ForValueType<>() { - @Override - public void write(FriendlyByteBuf buf, Set poses) { - buf.writeVarInt(poses.size()); - for (var pos : poses) { - buf.writeBlockPos(pos); - } - } - - @Override - public Set read(FriendlyByteBuf buf) { - final int count = buf.readVarInt(); - var ret = new LinkedHashSet(count); - for (int i = 0; i < count; i++) { - ret.add(buf.readBlockPos()); - } - return ret; - } - }); + public static final EntityDataSerializer> BLOCK_POS_LIST = EntityDataSerializer.forValueType(BlockPos.STREAM_CODEC.apply(ByteBufCodecs.collection(HashSet::new))); public static void register(IEventBus bus) { ENTITIES.register(bus); - ENTITY_DATA_SERIALIZERS.register(bus); } } diff --git a/src/main/java/org/teacon/powertool/item/ItemEventHandler.java b/src/main/java/org/teacon/powertool/item/ItemEventHandler.java index 07e1b89..780c119 100644 --- a/src/main/java/org/teacon/powertool/item/ItemEventHandler.java +++ b/src/main/java/org/teacon/powertool/item/ItemEventHandler.java @@ -4,14 +4,14 @@ import net.minecraft.world.item.Items; import net.minecraft.world.level.gameevent.GameEvent; import net.minecraft.world.phys.AABB; -import net.minecraftforge.event.entity.player.PlayerInteractEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.LogicalSide; -import net.minecraftforge.fml.common.Mod; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.LogicalSide; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent; import org.teacon.powertool.PowerTool; import org.teacon.powertool.entity.FenceKnotEntity; -@Mod.EventBusSubscriber(modid = PowerTool.MODID, bus = Mod.EventBusSubscriber.Bus.FORGE) +@EventBusSubscriber(modid = PowerTool.MODID, bus = EventBusSubscriber.Bus.GAME) public class ItemEventHandler { @SubscribeEvent diff --git a/src/main/java/org/teacon/powertool/item/PowerToolItems.java b/src/main/java/org/teacon/powertool/item/PowerToolItems.java index 9ded33c..a665fcb 100644 --- a/src/main/java/org/teacon/powertool/item/PowerToolItems.java +++ b/src/main/java/org/teacon/powertool/item/PowerToolItems.java @@ -1,41 +1,50 @@ package org.teacon.powertool.item; import net.minecraft.MethodsReturnNonnullByDefault; +import net.minecraft.core.component.DataComponentType; import net.minecraft.core.registries.Registries; import net.minecraft.network.chat.Component; import net.minecraft.world.item.CreativeModeTab; import net.minecraft.world.item.CreativeModeTabs; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; -import net.minecraftforge.event.BuildCreativeModeTabContentsEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; -import net.minecraftforge.registries.DeferredRegister; -import net.minecraftforge.registries.ForgeRegistries; -import net.minecraftforge.registries.RegistryObject; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent; +import net.neoforged.neoforge.registries.DeferredHolder; +import net.neoforged.neoforge.registries.DeferredRegister; import org.teacon.powertool.PowerTool; import org.teacon.powertool.block.PowerToolBlocks; +import org.teacon.powertool.entity.FenceKnotEntity; import javax.annotation.ParametersAreNonnullByDefault; @MethodsReturnNonnullByDefault @ParametersAreNonnullByDefault -@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD, modid = PowerTool.MODID) +@EventBusSubscriber(bus = EventBusSubscriber.Bus.MOD, modid = PowerTool.MODID) public class PowerToolItems { - public static final DeferredRegister ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, PowerTool.MODID); + public static final DeferredRegister ITEMS = DeferredRegister.create(Registries.ITEM, PowerTool.MODID); public static final DeferredRegister CREATIVE_MODE_TABS = DeferredRegister.create(Registries.CREATIVE_MODE_TAB, PowerTool.MODID); + + public static final DeferredRegister> DATA_COMPONENTS = DeferredRegister.create(Registries.DATA_COMPONENT_TYPE,PowerTool.MODID); - public static final RegistryObject THE_TAB = CREATIVE_MODE_TABS.register("tab", () -> CreativeModeTab.builder() + public static final DeferredHolder THE_TAB = CREATIVE_MODE_TABS.register("tab", () -> CreativeModeTab.builder() .title(Component.translatable("itemGroup.powertool")) .icon(() -> new ItemStack(PowerToolBlocks.COMMAND_BLOCK.get())) .withTabsBefore(CreativeModeTabs.FOOD_AND_DRINKS, CreativeModeTabs.INGREDIENTS, CreativeModeTabs.SPAWN_EGGS) .build()); - public static void register() { - var bus = FMLJavaModLoadingContext.get().getModEventBus(); + public static final DeferredHolder,DataComponentType> KNOT_DATA = DATA_COMPONENTS.register( + "knot_data",() -> DataComponentType.builder() + .persistent(FenceKnotEntity.PowerToolKnotData.CODEC) + .networkSynchronized(FenceKnotEntity.PowerToolKnotData.STREAM_CODEC) + .build() + ); + + public static void register(IEventBus bus) { ITEMS.register(bus); ITEMS.register("useless_stick", () -> new Item(new Item.Properties()) { @Override @@ -48,6 +57,7 @@ public boolean isFoil(ItemStack stack) { ITEMS.register("clap_but_angry", () -> new ClapItem(new Item.Properties())); ITEMS.register("transparent_brush",TransparentBrushItem::new); CREATIVE_MODE_TABS.register(bus); + DATA_COMPONENTS.register(bus); } @SubscribeEvent diff --git a/src/main/java/org/teacon/powertool/item/TransparentBrushItem.java b/src/main/java/org/teacon/powertool/item/TransparentBrushItem.java index e843d8f..c1f107a 100644 --- a/src/main/java/org/teacon/powertool/item/TransparentBrushItem.java +++ b/src/main/java/org/teacon/powertool/item/TransparentBrushItem.java @@ -8,8 +8,6 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.item.context.UseOnContext; -import net.minecraft.world.level.Level; -import org.jetbrains.annotations.Nullable; import org.teacon.powertool.block.ItemDisplayBlock; import javax.annotation.ParametersAreNonnullByDefault; @@ -35,9 +33,10 @@ public InteractionResult useOn(UseOnContext context) { return super.useOn(context); } + @Override - public void appendHoverText(ItemStack p_41421_, @Nullable Level p_41422_, List components, TooltipFlag p_41424_) { - super.appendHoverText(p_41421_, p_41422_, components, p_41424_); - components.add(Component.translatable("tooltip.powertool.transparent_brush").withStyle(ChatFormatting.GRAY)); + public void appendHoverText(ItemStack stack, TooltipContext context, List tooltipComponents, TooltipFlag tooltipFlag) { + super.appendHoverText(stack, context, tooltipComponents, tooltipFlag); + tooltipComponents.add(Component.translatable("tooltip.powertool.transparent_brush").withStyle(ChatFormatting.GRAY)); } } diff --git a/src/main/java/org/teacon/powertool/menu/PowerSupplyMenu.java b/src/main/java/org/teacon/powertool/menu/PowerSupplyMenu.java index d79315a..d65589f 100644 --- a/src/main/java/org/teacon/powertool/menu/PowerSupplyMenu.java +++ b/src/main/java/org/teacon/powertool/menu/PowerSupplyMenu.java @@ -1,5 +1,6 @@ package org.teacon.powertool.menu; +import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.network.chat.Component; import net.minecraft.world.MenuProvider; import net.minecraft.world.entity.player.Inventory; @@ -8,6 +9,10 @@ import net.minecraft.world.item.ItemStack; import org.teacon.powertool.block.PowerSupplyBlock; +import javax.annotation.ParametersAreNonnullByDefault; + +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault public class PowerSupplyMenu extends AbstractContainerMenu { public PowerSupplyBlock.Data dataHolder; diff --git a/src/main/java/org/teacon/powertool/menu/PowerToolMenus.java b/src/main/java/org/teacon/powertool/menu/PowerToolMenus.java index a031130..ab0c2e1 100644 --- a/src/main/java/org/teacon/powertool/menu/PowerToolMenus.java +++ b/src/main/java/org/teacon/powertool/menu/PowerToolMenus.java @@ -1,24 +1,23 @@ package org.teacon.powertool.menu; +import net.minecraft.core.registries.Registries; import net.minecraft.world.inventory.MenuType; -import net.minecraftforge.common.extensions.IForgeMenuType; -import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; -import net.minecraftforge.registries.DeferredRegister; -import net.minecraftforge.registries.ForgeRegistries; -import net.minecraftforge.registries.RegistryObject; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.common.extensions.IMenuTypeExtension; +import net.neoforged.neoforge.registries.DeferredHolder; +import net.neoforged.neoforge.registries.DeferredRegister; import org.teacon.powertool.PowerTool; import org.teacon.powertool.block.PowerSupplyBlock; public class PowerToolMenus { - public static final DeferredRegister> MENUS = DeferredRegister.create(ForgeRegistries.MENU_TYPES, PowerTool.MODID); + public static final DeferredRegister> MENUS = DeferredRegister.create(Registries.MENU, PowerTool.MODID); - public static RegistryObject> POWER_SUPPLY_MENU; + public static DeferredHolder,MenuType> POWER_SUPPLY_MENU; - public static void register() { - var bus = FMLJavaModLoadingContext.get().getModEventBus(); + public static void register(IEventBus bus) { MENUS.register(bus); - POWER_SUPPLY_MENU = MENUS.register("power_supply", () -> IForgeMenuType.create(((windowId, inv, data) -> { + POWER_SUPPLY_MENU = MENUS.register("power_supply", () -> IMenuTypeExtension.create(((windowId, inv, data) -> { final var dataHolder = new PowerSupplyBlock.Data(); dataHolder.status = data.readVarInt(); dataHolder.power = data.readVarInt(); diff --git a/src/main/java/org/teacon/powertool/mixin/CommandBlockMixin.java b/src/main/java/org/teacon/powertool/mixin/CommandBlockMixin.java index 8e93200..c690d44 100644 --- a/src/main/java/org/teacon/powertool/mixin/CommandBlockMixin.java +++ b/src/main/java/org/teacon/powertool/mixin/CommandBlockMixin.java @@ -14,11 +14,11 @@ public class CommandBlockMixin implements PeriodCommandBlockBridge { @Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;scheduleTick(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/Block;I)V")) private void usePowerToolPeriod(ServerLevel level, BlockPos pos, Block block, int i) { - level.scheduleTick(pos, block, powerToolPeriod(level, pos)); + level.scheduleTick(pos, block, powerTool$Period(level, pos)); } @Override - public int powerToolPeriod(ServerLevel level, BlockPos pos) { + public int powerTool$Period(ServerLevel level, BlockPos pos) { return 1; } } diff --git a/src/main/java/org/teacon/powertool/mixin/CommandsMixin.java b/src/main/java/org/teacon/powertool/mixin/CommandsMixin.java index a3cdad8..5275841 100644 --- a/src/main/java/org/teacon/powertool/mixin/CommandsMixin.java +++ b/src/main/java/org/teacon/powertool/mixin/CommandsMixin.java @@ -6,7 +6,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.teacon.powertool.network.capability.Permission; +import org.teacon.powertool.network.attachment.Permission; @Mixin(Commands.class) public class CommandsMixin { diff --git a/src/main/java/org/teacon/powertool/mixin/client/GameModeSwitcherScreenMixin.java b/src/main/java/org/teacon/powertool/mixin/client/GameModeSwitcherScreenMixin.java index ed0b933..05fd346 100644 --- a/src/main/java/org/teacon/powertool/mixin/client/GameModeSwitcherScreenMixin.java +++ b/src/main/java/org/teacon/powertool/mixin/client/GameModeSwitcherScreenMixin.java @@ -5,7 +5,10 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; -import org.teacon.powertool.network.capability.Permission; +import org.teacon.powertool.attachment.PowerToolAttachments; +import org.teacon.powertool.network.attachment.Permission; + +import java.util.Optional; @Mixin(GameModeSwitcherScreen.class) public class GameModeSwitcherScreenMixin { @@ -13,6 +16,8 @@ public class GameModeSwitcherScreenMixin { @Redirect(method = "switchToHoveredGameMode(Lnet/minecraft/client/Minecraft;Lnet/minecraft/client/gui/screens/debug/GameModeSwitcherScreen$GameModeIcon;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/LocalPlayer;hasPermissions(I)Z")) private static boolean usePermission(LocalPlayer player, int i) { - return player.getCapability(Permission.CAPABILITY).resolve().flatMap(Permission::isCanSwitchGameMode).orElse(player.hasPermissions(i)); + return Optional.of(player.getData(PowerToolAttachments.PERMISSION)) + .flatMap(Permission::isCanSwitchGameMode) + .orElse(player.hasPermissions(i)); } } diff --git a/src/main/java/org/teacon/powertool/mixin/client/KeyboardHandlerMixin.java b/src/main/java/org/teacon/powertool/mixin/client/KeyboardHandlerMixin.java index 0c473ca..a078b44 100644 --- a/src/main/java/org/teacon/powertool/mixin/client/KeyboardHandlerMixin.java +++ b/src/main/java/org/teacon/powertool/mixin/client/KeyboardHandlerMixin.java @@ -6,7 +6,10 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.Slice; -import org.teacon.powertool.network.capability.Permission; +import org.teacon.powertool.attachment.PowerToolAttachments; +import org.teacon.powertool.network.attachment.Permission; + +import java.util.Optional; @Mixin(KeyboardHandler.class) public class KeyboardHandlerMixin { @@ -14,6 +17,8 @@ public class KeyboardHandlerMixin { @Redirect(method = "handleDebugKeys", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/LocalPlayer;hasPermissions(I)Z"), slice = @Slice(from = @At(value = "INVOKE", target = "Lnet/minecraft/client/KeyboardHandler;copyRecreateCommand(ZZ)V"))) private boolean usePermission(LocalPlayer player, int i) { - return player.getCapability(Permission.CAPABILITY).resolve().flatMap(Permission::isCanSwitchGameMode).orElse(player.hasPermissions(i)); + return Optional.of(player.getData(PowerToolAttachments.PERMISSION)) + .flatMap(Permission::isCanSwitchGameMode) + .orElse(player.hasPermissions(i)); } } diff --git a/src/main/java/org/teacon/powertool/mixin/client/PlayerMixin.java b/src/main/java/org/teacon/powertool/mixin/client/PlayerMixin.java index 0c4ef93..f39b479 100644 --- a/src/main/java/org/teacon/powertool/mixin/client/PlayerMixin.java +++ b/src/main/java/org/teacon/powertool/mixin/client/PlayerMixin.java @@ -9,7 +9,10 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import org.teacon.powertool.network.capability.Permission; +import org.teacon.powertool.attachment.PowerToolAttachments; +import org.teacon.powertool.network.attachment.Permission; + +import java.util.Optional; @Mixin(Player.class) public class PlayerMixin { @@ -20,8 +23,10 @@ public class PlayerMixin { private void usePermission(CallbackInfoReturnable cir) { // noinspection ConstantConditions if ((Object) this instanceof AbstractClientPlayer player) { - cir.setReturnValue(this.abilities.instabuild && player.getCapability(Permission.CAPABILITY) - .resolve().flatMap(Permission::isCanUseGameMasterBlock).orElse(player.hasPermissions(2))); + cir.setReturnValue(this.abilities.instabuild && + Optional.of(player.getData(PowerToolAttachments.PERMISSION)) + .flatMap(Permission::isCanUseGameMasterBlock) + .orElse(player.hasPermissions(2))); } } } diff --git a/src/main/java/org/teacon/powertool/motd/MotDHandler.java b/src/main/java/org/teacon/powertool/motd/MotDHandler.java index 018b68a..0e14217 100644 --- a/src/main/java/org/teacon/powertool/motd/MotDHandler.java +++ b/src/main/java/org/teacon/powertool/motd/MotDHandler.java @@ -1,12 +1,12 @@ package org.teacon.powertool.motd; import net.minecraft.network.chat.Component; -import net.minecraftforge.event.entity.player.PlayerEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.event.entity.player.PlayerEvent; import org.teacon.powertool.PowerTool; -@Mod.EventBusSubscriber(modid = PowerTool.MODID) +@EventBusSubscriber(modid = PowerTool.MODID) public class MotDHandler { public static Component motd = null; diff --git a/src/main/java/org/teacon/powertool/network/PowerToolNetwork.java b/src/main/java/org/teacon/powertool/network/PowerToolNetwork.java index a88ad29..20e03df 100644 --- a/src/main/java/org/teacon/powertool/network/PowerToolNetwork.java +++ b/src/main/java/org/teacon/powertool/network/PowerToolNetwork.java @@ -1,9 +1,8 @@ package org.teacon.powertool.network; -import net.minecraft.resources.ResourceLocation; -import net.minecraftforge.network.NetworkDirection; -import net.minecraftforge.network.NetworkRegistry; -import net.minecraftforge.network.simple.SimpleChannel; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent; import org.teacon.powertool.PowerTool; import org.teacon.powertool.network.client.OpenHolographicSignEditor; import org.teacon.powertool.network.client.UpdatePermissionPacket; @@ -11,32 +10,40 @@ import org.teacon.powertool.network.server.UpdateHolographicSignData; import org.teacon.powertool.network.server.UpdatePowerSupplyData; -import java.util.Optional; - +@EventBusSubscriber(modid = PowerTool.MODID,bus = EventBusSubscriber.Bus.MOD) public class PowerToolNetwork { + - private static SimpleChannel channel; - - public static void register() { - channel = NetworkRegistry.newSimpleChannel( - new ResourceLocation(PowerTool.MODID, "ch"), - () -> "1", - NetworkRegistry.acceptMissingOr("1"::equals), - "1"::equals + @SubscribeEvent + public static void register(RegisterPayloadHandlersEvent event) { + var register = event.registrar(PowerTool.MODID); + + register.commonToClient( + UpdatePermissionPacket.TYPE, + UpdatePermissionPacket.STREAM_CODEC, + UpdatePermissionPacket::handle + ); + register.commonToClient( + OpenHolographicSignEditor.TYPE, + OpenHolographicSignEditor.STREAM_CODEC, + OpenHolographicSignEditor::handle + ); + + register.commonToServer( + SetCommandBlockPacket.TYPE, + SetCommandBlockPacket.STREAM_CODEC, + SetCommandBlockPacket::handle + ); + register.commonToServer( + UpdatePowerSupplyData.TYPE, + UpdatePowerSupplyData.STREAM_CODEC, + UpdatePowerSupplyData::handle + ); + register.commonToServer( + UpdateHolographicSignData.TYPE, + UpdateHolographicSignData.STREAM_CODEC, + UpdateHolographicSignData::handle ); - channel.registerMessage(0, SetCommandBlockPacket.class, SetCommandBlockPacket::write, - SetCommandBlockPacket::new, SetCommandBlockPacket::handle, Optional.of(NetworkDirection.PLAY_TO_SERVER)); - channel.registerMessage(1, UpdatePermissionPacket.class, UpdatePermissionPacket::write, - UpdatePermissionPacket::new, UpdatePermissionPacket::handle, Optional.of(NetworkDirection.PLAY_TO_CLIENT)); - channel.registerMessage(2, UpdatePowerSupplyData.class, UpdatePowerSupplyData::write, - UpdatePowerSupplyData::new, UpdatePowerSupplyData::handle, Optional.of(NetworkDirection.PLAY_TO_SERVER)); - channel.registerMessage(3, OpenHolographicSignEditor.class, OpenHolographicSignEditor::write, - OpenHolographicSignEditor::new, OpenHolographicSignEditor::handle, Optional.of(NetworkDirection.PLAY_TO_CLIENT)); - channel.registerMessage(4, UpdateHolographicSignData.class, UpdateHolographicSignData::write, - UpdateHolographicSignData::new, UpdateHolographicSignData::handle, Optional.of(NetworkDirection.PLAY_TO_SERVER)); - } - - public static SimpleChannel channel() { - return channel; } + } diff --git a/src/main/java/org/teacon/powertool/network/capability/Permission.java b/src/main/java/org/teacon/powertool/network/attachment/Permission.java similarity index 58% rename from src/main/java/org/teacon/powertool/network/capability/Permission.java rename to src/main/java/org/teacon/powertool/network/attachment/Permission.java index 0db72b5..90cc191 100644 --- a/src/main/java/org/teacon/powertool/network/capability/Permission.java +++ b/src/main/java/org/teacon/powertool/network/attachment/Permission.java @@ -1,32 +1,23 @@ -package org.teacon.powertool.network.capability; +package org.teacon.powertool.network.attachment; -import net.minecraft.core.Direction; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; -import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.common.capabilities.CapabilityManager; -import net.minecraftforge.common.capabilities.CapabilityToken; -import net.minecraftforge.common.capabilities.ICapabilityProvider; -import net.minecraftforge.common.util.LazyOptional; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.network.PacketDistributor; -import net.minecraftforge.server.permission.PermissionAPI; -import net.minecraftforge.server.permission.events.PermissionGatherEvent; -import net.minecraftforge.server.permission.nodes.PermissionNode; -import net.minecraftforge.server.permission.nodes.PermissionTypes; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.network.PacketDistributor; +import net.neoforged.neoforge.server.permission.PermissionAPI; +import net.neoforged.neoforge.server.permission.events.PermissionGatherEvent; +import net.neoforged.neoforge.server.permission.nodes.PermissionNode; +import net.neoforged.neoforge.server.permission.nodes.PermissionTypes; import org.teacon.powertool.PowerTool; -import org.teacon.powertool.network.PowerToolNetwork; import org.teacon.powertool.network.client.UpdatePermissionPacket; +import org.teacon.powertool.utils.VanillaUtils; import java.util.Optional; public class Permission { - - public static final Capability CAPABILITY = CapabilityManager.get(new CapabilityToken<>() {}); - public static final ResourceLocation KEY = new ResourceLocation(PowerTool.MODID, "permission"); + + public static final ResourceLocation KEY = VanillaUtils.resourceLocationOf(PowerTool.MODID, "permission"); private Boolean canUseGameMasterBlock; private Boolean canSwitchGameMode; @@ -56,18 +47,9 @@ public void setCanUseSelector(Boolean canUseSelector) { this.canUseSelector = canUseSelector; } - @Mod.EventBusSubscriber - public static class Provider implements ICapabilityProvider { - - private final Permission permission = new Permission(); - private final LazyOptional provider = LazyOptional.of(() -> permission); - - @NotNull - @Override - public LazyOptional getCapability(@NotNull Capability cap, @Nullable Direction side) { - return CAPABILITY.orEmpty(cap, this.provider); - } - + @EventBusSubscriber + public static class Provider { + private static final PermissionNode GAMEMODE = new PermissionNode<>( "minecraft", "command.gamemode", PermissionTypes.BOOLEAN, (player, uuid, context) -> player != null && player.hasPermissions(2) @@ -88,8 +70,7 @@ public static void on(PermissionGatherEvent.Nodes event) { } public static void updatePermission(ServerPlayer player) { - PowerToolNetwork.channel().send( - PacketDistributor.PLAYER.with(() -> player), + PacketDistributor.sendToPlayer(player, new UpdatePermissionPacket( PermissionAPI.getPermission(player, Provider.COMMAND_BLOCK), PermissionAPI.getPermission(player, Provider.GAMEMODE), diff --git a/src/main/java/org/teacon/powertool/network/client/OpenHolographicSignEditor.java b/src/main/java/org/teacon/powertool/network/client/OpenHolographicSignEditor.java index 2808dc0..8095780 100644 --- a/src/main/java/org/teacon/powertool/network/client/OpenHolographicSignEditor.java +++ b/src/main/java/org/teacon/powertool/network/client/OpenHolographicSignEditor.java @@ -1,36 +1,35 @@ package org.teacon.powertool.network.client; +import io.netty.buffer.ByteBuf; +import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.client.Minecraft; import net.minecraft.core.BlockPos; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraftforge.network.NetworkEvent; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.neoforged.neoforge.network.handling.IPayloadContext; import org.teacon.powertool.block.entity.HolographicSignBlockEntity; import org.teacon.powertool.client.HolographicSignEditingScreen; - -import java.util.function.Supplier; - -public class OpenHolographicSignEditor { - - private BlockPos location; - - public OpenHolographicSignEditor(BlockPos location) { - this.location = location; - } - - public OpenHolographicSignEditor(FriendlyByteBuf buf) { - this.location = buf.readBlockPos(); - } - - public void write(FriendlyByteBuf buf) { - buf.writeBlockPos(this.location); - } - - public void handle(Supplier contextSupplier) { - var context = contextSupplier.get(); +import org.teacon.powertool.utils.VanillaUtils; + +@MethodsReturnNonnullByDefault +public record OpenHolographicSignEditor(BlockPos location) implements CustomPacketPayload { + + public static final CustomPacketPayload.Type TYPE = new Type<>(VanillaUtils.modResourceLocation("open_holographic_sign_editor")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + BlockPos.STREAM_CODEC,OpenHolographicSignEditor::location, + OpenHolographicSignEditor::new + ); + + public void handle(IPayloadContext context) { context.enqueueWork(new Handler()); - context.setPacketHandled(true); } - + + @Override + public Type type() { + return TYPE; + } + public class Handler implements Runnable { @Override public void run() { diff --git a/src/main/java/org/teacon/powertool/network/client/UpdatePermissionPacket.java b/src/main/java/org/teacon/powertool/network/client/UpdatePermissionPacket.java index 896b0aa..72f9735 100644 --- a/src/main/java/org/teacon/powertool/network/client/UpdatePermissionPacket.java +++ b/src/main/java/org/teacon/powertool/network/client/UpdatePermissionPacket.java @@ -1,36 +1,41 @@ package org.teacon.powertool.network.client; +import io.netty.buffer.ByteBuf; +import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.client.Minecraft; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraftforge.network.NetworkEvent; -import org.teacon.powertool.network.capability.Permission; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.neoforged.neoforge.network.handling.IPayloadContext; +import org.teacon.powertool.attachment.PowerToolAttachments; +import org.teacon.powertool.utils.VanillaUtils; -import java.util.function.Supplier; +@MethodsReturnNonnullByDefault +public record UpdatePermissionPacket(boolean canUseGameMasterBlock, boolean canSwitchGameMode, boolean canUseSelector) implements CustomPacketPayload { + + public static final CustomPacketPayload.Type TYPE = new Type<>(VanillaUtils.modResourceLocation("update_permission")); -public record UpdatePermissionPacket(boolean canUseGameMasterBlock, boolean canSwitchGameMode, boolean canUseSelector) { - - public UpdatePermissionPacket(FriendlyByteBuf buf) { - this(buf.readBoolean(), buf.readBoolean(), buf.readBoolean()); - } - - public void write(FriendlyByteBuf buf) { - buf.writeBoolean(canUseGameMasterBlock); - buf.writeBoolean(canSwitchGameMode); - buf.writeBoolean(canUseSelector); - } - - public void handle(Supplier ctx) { - var context = ctx.get(); + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.BOOL,UpdatePermissionPacket::canUseGameMasterBlock, + ByteBufCodecs.BOOL,UpdatePermissionPacket::canSwitchGameMode, + ByteBufCodecs.BOOL,UpdatePermissionPacket::canUseSelector, + UpdatePermissionPacket::new + ); + + public void handle(IPayloadContext context) { context.enqueueWork(() -> { var minecraft = Minecraft.getInstance(); if (minecraft.player != null) { - minecraft.player.getCapability(Permission.CAPABILITY).ifPresent(it -> { - it.setCanSwitchGameMode(canSwitchGameMode); - it.setCanUseGameMasterBlock(canUseGameMasterBlock); - it.setCanUseSelector(canUseSelector); - }); + var permission = minecraft.player.getData(PowerToolAttachments.PERMISSION); + permission.setCanSwitchGameMode(canSwitchGameMode); + permission.setCanUseGameMasterBlock(canUseGameMasterBlock); + permission.setCanUseSelector(canUseSelector); } }); - context.setPacketHandled(true); + } + + @Override + public Type type() { + return TYPE; } } diff --git a/src/main/java/org/teacon/powertool/network/server/SetCommandBlockPacket.java b/src/main/java/org/teacon/powertool/network/server/SetCommandBlockPacket.java index 2bdcca8..04c05d8 100644 --- a/src/main/java/org/teacon/powertool/network/server/SetCommandBlockPacket.java +++ b/src/main/java/org/teacon/powertool/network/server/SetCommandBlockPacket.java @@ -1,31 +1,38 @@ package org.teacon.powertool.network.server; +import io.netty.buffer.ByteBuf; +import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraftforge.network.NetworkEvent; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.neoforged.neoforge.network.handling.IPayloadContext; import org.teacon.powertool.block.entity.PeriodicCommandBlockEntity; +import org.teacon.powertool.utils.VanillaUtils; -import java.util.function.Supplier; - -public record SetCommandBlockPacket(BlockPos pos, int period) { - - public SetCommandBlockPacket(FriendlyByteBuf buf) { - this(buf.readBlockPos(), buf.readVarInt()); - } - - public void write(FriendlyByteBuf buf) { - buf.writeBlockPos(pos); - buf.writeVarInt(period); - } - - public void handle(Supplier ctx) { - var context = ctx.get(); +@MethodsReturnNonnullByDefault +public record SetCommandBlockPacket(BlockPos pos, int period) implements CustomPacketPayload { + + public static final CustomPacketPayload.Type TYPE = new Type<>(VanillaUtils.modResourceLocation("set_command_block_packet")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + BlockPos.STREAM_CODEC,SetCommandBlockPacket::pos, + ByteBufCodecs.INT,SetCommandBlockPacket::period, + SetCommandBlockPacket::new + ); + + public void handle(IPayloadContext context) { context.enqueueWork(() -> { - var level = context.getSender().level(); + var level = context.player().level(); if (level.isLoaded(pos) && level.getBlockEntity(pos) instanceof PeriodicCommandBlockEntity blockEntity) { blockEntity.setPeriod(period); } }); - context.setPacketHandled(true); + + } + + @Override + public Type type() { + return TYPE; } } diff --git a/src/main/java/org/teacon/powertool/network/server/UpdateHolographicSignData.java b/src/main/java/org/teacon/powertool/network/server/UpdateHolographicSignData.java index a429fce..a1a2a5c 100644 --- a/src/main/java/org/teacon/powertool/network/server/UpdateHolographicSignData.java +++ b/src/main/java/org/teacon/powertool/network/server/UpdateHolographicSignData.java @@ -1,120 +1,118 @@ package org.teacon.powertool.network.server; +import io.netty.buffer.ByteBuf; +import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos; -import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.level.block.Block; -import net.minecraftforge.network.NetworkEvent; +import net.neoforged.neoforge.network.handling.IPayloadContext; import org.teacon.powertool.block.entity.HolographicSignBlockEntity; +import org.teacon.powertool.utils.CodecUtils; +import org.teacon.powertool.utils.VanillaUtils; -import java.util.Arrays; -import java.util.function.Supplier; - -public class UpdateHolographicSignData { +import java.util.List; +import java.util.stream.Collectors; +@MethodsReturnNonnullByDefault +public record UpdateHolographicSignData(UpdateHolographicSignDataInner data) implements CustomPacketPayload { + + public static final int MAXIMUM_LINE_COUNT = 10; - - private BlockPos location; - private String[] messages; - private int color; - private float scale; - private HolographicSignBlockEntity.Align align; - private HolographicSignBlockEntity.Shadow shadow; - private HolographicSignBlockEntity.LayerArrange layerArrange; - private boolean locked; - private int rotation; - private boolean bidirectional; + public static final Type TYPE = new Type<>(VanillaUtils.modResourceLocation("update_holographic_sign")); - public UpdateHolographicSignData(BlockPos location, String[] messages, int color, float scale, + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + UpdateHolographicSignDataInner.STREAM_CODEC, + UpdateHolographicSignData::data, + UpdateHolographicSignData::new + ); + + public static UpdateHolographicSignData create(BlockPos location, List messages, int color, float scale, HolographicSignBlockEntity.Align align, HolographicSignBlockEntity.Shadow shadow, HolographicSignBlockEntity.LayerArrange layerArrange, boolean locked,int rotation,boolean bidirectional) { - this.location = location; - this.messages = messages; - if (messages.length > MAXIMUM_LINE_COUNT) { - this.messages = Arrays.copyOfRange(messages, 0, MAXIMUM_LINE_COUNT); - } - this.color = color; - this.scale = scale; - this.align = align; - this.shadow = shadow; - this.layerArrange = layerArrange; - this.locked = locked; - this.rotation = rotation; - this.bidirectional = bidirectional; - } - - public UpdateHolographicSignData(FriendlyByteBuf buf) { - this.location = buf.readBlockPos(); - var len = buf.readVarInt(); - if (len > MAXIMUM_LINE_COUNT) { - len = MAXIMUM_LINE_COUNT; + if (messages.size() > MAXIMUM_LINE_COUNT) { + messages = messages.stream().limit(10).collect(Collectors.toList()); } - this.messages = new String[len]; - for (int i = 0; i < len; i++) { - this.messages[i] = buf.readUtf(); - } - this.color = buf.readVarInt(); - this.scale = buf.readFloat(); - this.align = buf.readEnum(HolographicSignBlockEntity.Align.class); - this.shadow = buf.readEnum(HolographicSignBlockEntity.Shadow.class); - this.layerArrange = buf.readEnum(HolographicSignBlockEntity.LayerArrange.class); - this.locked = buf.readBoolean(); - this.rotation = buf.readInt(); - this.bidirectional = buf.readBoolean(); - } - - public void write(FriendlyByteBuf buf) { - buf.writeBlockPos(this.location); - buf.writeVarInt(this.messages.length); - for (var text : this.messages) { - buf.writeUtf(text); - } - buf.writeVarInt(this.color); - buf.writeFloat(this.scale); - buf.writeEnum(this.align); - buf.writeEnum(this.shadow); - buf.writeEnum(this.layerArrange); - buf.writeBoolean(locked); - buf.writeInt(rotation); - buf.writeBoolean(bidirectional); + return new UpdateHolographicSignData(new UpdateHolographicSignDataInner(location,messages,color,scale,align,shadow,layerArrange,locked, rotation, bidirectional)); } - public void handle(Supplier contextSupplier) { - var context = contextSupplier.get(); + public void handle(IPayloadContext context) { context.enqueueWork(() -> { - var sender = context.getSender(); - if (sender != null && sender.getAbilities().instabuild) { + var sender = context.player(); + if (sender.getAbilities().instabuild) { var level = sender.level(); - if (level.isLoaded(this.location)) { - if (level.getBlockEntity(this.location) instanceof HolographicSignBlockEntity theSign) { - theSign.colorInARGB = this.color; - theSign.scale = this.scale; - theSign.align = this.align; - theSign.shadow = this.shadow; - theSign.arrange = this.layerArrange; - theSign.lock = this.locked; - theSign.rotate = this.rotation; - theSign.bidirectional = this.bidirectional; - var state = level.getBlockState(this.location); + if (level.isLoaded(this.data.location)) { + if (level.getBlockEntity(this.data.location) instanceof HolographicSignBlockEntity theSign) { + theSign.colorInARGB = this.data.color; + theSign.scale = this.data.scale; + theSign.align = this.data.align; + theSign.shadow = this.data.shadow; + theSign.arrange = this.data.layerArrange; + theSign.lock = this.data.locked; + theSign.rotate = this.data.rotation; + theSign.bidirectional = this.data.bidirectional; + var state = level.getBlockState(this.data.location); theSign.setChanged(); - level.sendBlockUpdated(this.location, state, state, Block.UPDATE_CLIENTS); - var task = sender.getTextFilter().processMessageBundle(Arrays.asList(this.messages)); - task.thenAcceptAsync(filtered -> { - if (sender.isTextFilteringEnabled()) { - theSign.contents = filtered.stream().map(t -> Component.literal(t.filtered())).toList(); - } else { - theSign.contents = filtered.stream().map(t -> Component.literal(t.raw())).toList(); - } - theSign.setChanged(); - level.sendBlockUpdated(this.location, state, state, Block.UPDATE_CLIENTS); - }, sender.server); + level.sendBlockUpdated(this.data.location, state, state, Block.UPDATE_CLIENTS); + if(sender instanceof ServerPlayer serverPlayer) { + var task = serverPlayer.getTextFilter().processMessageBundle(this.data.messages); + task.thenAcceptAsync(filtered -> { + if (sender.isTextFilteringEnabled()) { + theSign.contents = filtered.stream().map(t -> Component.literal(t.filtered())).toList(); + } else { + theSign.contents = filtered.stream().map(t -> Component.literal(t.raw())).toList(); + } + theSign.setChanged(); + level.sendBlockUpdated(this.data.location, state, state, Block.UPDATE_CLIENTS); + }, serverPlayer.server); + } + } } } }); - context.setPacketHandled(true); + } + + @Override + public Type type() { + return TYPE; + } + + private record UpdateHolographicSignDataInner(BlockPos location, List messages, int color, float scale, + HolographicSignBlockEntity.Align align, + HolographicSignBlockEntity.Shadow shadow, + HolographicSignBlockEntity.LayerArrange layerArrange, + boolean locked, int rotation, boolean bidirectional){ + + public static final StreamCodec STREAM_CODEC = CodecUtils.composite10( + BlockPos.STREAM_CODEC, + UpdateHolographicSignDataInner::location, + ByteBufCodecs.STRING_UTF8.apply(ByteBufCodecs.list()), + UpdateHolographicSignDataInner::messages, + ByteBufCodecs.INT, + UpdateHolographicSignDataInner::color, + ByteBufCodecs.FLOAT, + UpdateHolographicSignDataInner::scale, + HolographicSignBlockEntity.Align.STREAM_CODEC, + UpdateHolographicSignDataInner::align, + HolographicSignBlockEntity.Shadow.STREAM_CODEC, + UpdateHolographicSignDataInner::shadow, + HolographicSignBlockEntity.LayerArrange.STREAM_CODEC, + UpdateHolographicSignDataInner::layerArrange, + ByteBufCodecs.BOOL, + UpdateHolographicSignDataInner::locked, + ByteBufCodecs.VAR_INT, + UpdateHolographicSignDataInner::rotation, + ByteBufCodecs.BOOL, + UpdateHolographicSignDataInner::bidirectional, + UpdateHolographicSignDataInner::new + ); + } } diff --git a/src/main/java/org/teacon/powertool/network/server/UpdatePowerSupplyData.java b/src/main/java/org/teacon/powertool/network/server/UpdatePowerSupplyData.java index 7413485..5558984 100644 --- a/src/main/java/org/teacon/powertool/network/server/UpdatePowerSupplyData.java +++ b/src/main/java/org/teacon/powertool/network/server/UpdatePowerSupplyData.java @@ -1,51 +1,49 @@ package org.teacon.powertool.network.server; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraftforge.network.NetworkEvent; +import io.netty.buffer.ByteBuf; +import net.minecraft.MethodsReturnNonnullByDefault; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.neoforged.neoforge.network.handling.IPayloadContext; import org.teacon.powertool.menu.PowerSupplyMenu; - -import java.util.function.Supplier; - -public class UpdatePowerSupplyData { - - private int type, data; - - public UpdatePowerSupplyData(int type, int data) { - this.type = type; - this.data = data; - } - - public UpdatePowerSupplyData(FriendlyByteBuf buf) { - this.type = buf.readVarInt(); - this.data = buf.readVarInt(); - } - - public void write(FriendlyByteBuf buf) { - buf.writeVarInt(this.type).writeVarInt(this.data); - } - - public void handle(Supplier contextSupplier) { - var context = contextSupplier.get(); +import org.teacon.powertool.utils.VanillaUtils; + +@MethodsReturnNonnullByDefault +public record UpdatePowerSupplyData(int type_, int data) implements CustomPacketPayload { + + public static final Type TYPE = new Type<>(VanillaUtils.modResourceLocation("update_power_supply")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.INT,UpdatePowerSupplyData::type_, + ByteBufCodecs.INT,UpdatePowerSupplyData::data, + UpdatePowerSupplyData::new + ); + + public void handle(IPayloadContext context) { context.enqueueWork(() -> { - var player = context.getSender(); - if (player != null) { - if (player.containerMenu instanceof PowerSupplyMenu theMenu) { - if (this.type == 0) { - theMenu.dataHolder.status = this.data; - var callback = theMenu.dataHolder.markDirty; - if (callback != null) { - callback.run(); - } - } else if (this.type == 1) { - theMenu.dataHolder.power = this.data; - var callback = theMenu.dataHolder.markDirty; - if (callback != null) { - callback.run(); - } + var player = context.player(); + if (player.containerMenu instanceof PowerSupplyMenu theMenu) { + if (this.type_ == 0) { + theMenu.dataHolder.status = this.data; + var callback = theMenu.dataHolder.markDirty; + if (callback != null) { + callback.run(); + } + } else if (this.type_ == 1) { + theMenu.dataHolder.power = this.data; + var callback = theMenu.dataHolder.markDirty; + if (callback != null) { + callback.run(); } } } }); - context.setPacketHandled(true); + + } + + @Override + public Type type() { + return TYPE; } } diff --git a/src/main/java/org/teacon/powertool/utils/CodecUtils.java b/src/main/java/org/teacon/powertool/utils/CodecUtils.java new file mode 100644 index 0000000..5108b9e --- /dev/null +++ b/src/main/java/org/teacon/powertool/utils/CodecUtils.java @@ -0,0 +1,69 @@ +package org.teacon.powertool.utils; + +import com.mojang.datafixers.util.Function10; +import net.minecraft.MethodsReturnNonnullByDefault; +import net.minecraft.network.codec.StreamCodec; + +import javax.annotation.ParametersAreNonnullByDefault; +import java.util.function.Function; + +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +public class CodecUtils { + + public static StreamCodec composite10( + final StreamCodec codec1, + final Function getter1, + final StreamCodec codec2, + final Function getter2, + final StreamCodec codec3, + final Function getter3, + final StreamCodec codec4, + final Function getter4, + final StreamCodec codec5, + final Function getter5, + final StreamCodec codec6, + final Function getter6, + final StreamCodec codec7, + final Function getter7, + final StreamCodec codec8, + final Function getter8, + final StreamCodec codec9, + final Function getter9, + final StreamCodec codec10, + final Function getter10, + final Function10 factory + ) { + return new StreamCodec<>() { + @Override + public C decode(B buffer) { + T1 t1 = codec1.decode(buffer); + T2 t2 = codec2.decode(buffer); + T3 t3 = codec3.decode(buffer); + T4 t4 = codec4.decode(buffer); + T5 t5 = codec5.decode(buffer); + T6 t6 = codec6.decode(buffer); + T7 t7 = codec7.decode(buffer); + T8 t8 = codec8.decode(buffer); + T9 t9 = codec9.decode(buffer); + T10 t10 = codec10.decode(buffer); + return factory.apply(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10); + } + + @Override + @SuppressWarnings("DuplicatedCode") //no need to extract a method + public void encode(B buffer, C value) { + codec1.encode(buffer, getter1.apply(value)); + codec2.encode(buffer, getter2.apply(value)); + codec3.encode(buffer, getter3.apply(value)); + codec4.encode(buffer, getter4.apply(value)); + codec5.encode(buffer, getter5.apply(value)); + codec6.encode(buffer, getter6.apply(value)); + codec7.encode(buffer, getter7.apply(value)); + codec8.encode(buffer, getter8.apply(value)); + codec9.encode(buffer, getter9.apply(value)); + codec10.encode(buffer, getter10.apply(value)); + } + }; + } +} diff --git a/src/main/java/org/teacon/powertool/utils/VanillaUtils.java b/src/main/java/org/teacon/powertool/utils/VanillaUtils.java new file mode 100644 index 0000000..c8ffb51 --- /dev/null +++ b/src/main/java/org/teacon/powertool/utils/VanillaUtils.java @@ -0,0 +1,38 @@ +package org.teacon.powertool.utils; + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.ItemInteractionResult; +import net.minecraft.world.entity.EquipmentSlot; +import org.teacon.powertool.PowerTool; + +public class VanillaUtils { + + public static ResourceLocation modResourceLocation(String path) { + return resourceLocationOf(PowerTool.MODID, path); + } + + public static ResourceLocation resourceLocationOf(String namespace, String path) { + return ResourceLocation.fromNamespaceAndPath(namespace, path); + } + + public static EquipmentSlot equipmentSlotFromHand(InteractionHand hand) { + return hand == InteractionHand.MAIN_HAND ? EquipmentSlot.MAINHAND : EquipmentSlot.OFFHAND; + } + + public static ItemInteractionResult itemInteractionFrom(InteractionResult result) { + return switch (result){ + case SUCCESS, SUCCESS_NO_ITEM_USED -> ItemInteractionResult.SUCCESS; + case CONSUME -> ItemInteractionResult.CONSUME; + case CONSUME_PARTIAL -> ItemInteractionResult.CONSUME_PARTIAL; + case PASS -> ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; + case FAIL -> ItemInteractionResult.FAIL; + }; + } + + //irrelevant vanilla(笑) + public static int getColor(int r,int g,int b,int a){ + return a << 24 | r << 16 | g << 8 | b; + } +} diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index e8c3f3e..10d65b1 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -1 +1 @@ -public net.minecraft.client.gui.screens.inventory.CommandBlockEditScreen f_98374_ # autoCommandBlock \ No newline at end of file +public net.minecraft.client.gui.screens.inventory.CommandBlockEditScreen autoCommandBlock \ No newline at end of file