diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..f4b9d0f --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,30 @@ +name: build +on: [ push, pull_request ] +jobs: + build: + strategy: + matrix: + java: [ 17-jdk ] + runs-on: ubuntu-20.04 + container: + image: eclipse-temurin:${{ matrix.java }} + options: --user root + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Validate Gradle wrapper + uses: gradle/wrapper-validation-action@v1 + + - name: Make Gradle wrapper executable + run: chmod +x ./gradlew + + - name: Build + run: ./gradlew build --stacktrace --parallel + + - name: Upload artifacts + uses: actions/upload-artifact@v2 + with: + name: Artifacts + path: build/libs/ diff --git a/build.gradle b/build.gradle index 033b097..ba14a8d 100644 --- a/build.gradle +++ b/build.gradle @@ -1,35 +1,46 @@ buildscript { repositories { - maven { url = 'https://files.minecraftforge.net/maven' } - jcenter() + // These repositories are only for Gradle plugins, put any other repositories in the repository block further below + maven { url = 'https://maven.minecraftforge.net' } mavenCentral() } dependencies { - classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '3.+', changing: true + classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true } } -apply plugin: 'net.minecraftforge.gradle' // Only edit below this line, the above code adds and enables the necessary things for Forge to be setup. -apply plugin: 'eclipse' -apply plugin: 'maven-publish' +plugins { + id 'eclipse' + id 'maven-publish' +} +apply plugin: 'net.minecraftforge.gradle' + -version = '1.2.0' -group = 'mod.teamdraco.bettas' // http://maven.apache.org/guides/mini/guide-naming-conventions.html -archivesBaseName = 'bettas' +version = '1.19.2-1.1.0' +group = 'teamfusion.bettas' // http://maven.apache.org/guides/mini/guide-naming-conventions.html +archivesBaseName = 'bettas-forge' -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' // Need this here so eclipse task generates correctly. +// Mojang ships Java 17 to end users in 1.18+, so your mod should target Java 17. +java.toolchain.languageVersion = JavaLanguageVersion.of(17) -println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch')) +println "Java: ${System.getProperty 'java.version'}, JVM: ${System.getProperty 'java.vm.version'} (${System.getProperty 'java.vendor'}), Arch: ${System.getProperty 'os.arch'}" minecraft { - // The mappings can be changed at any time, and must be in the following format. - // snapshot_YYYYMMDD Snapshot are built nightly. - // stable_# Stables are built at the discretion of the MCP team. - // Use non-default mappings at your own risk. they may not always work. + // The mappings can be changed at any time and must be in the following format. + // Channel: Version: + // official MCVersion Official field/method names from Mojang mapping files + // parchment YYYY.MM.DD-MCVersion Open community-sourced parameter names and javadocs layered on top of official + // + // You must be aware of the Mojang license when using the 'official' or 'parchment' mappings. + // See more information here: https://github.com/MinecraftForge/MCPConfig/blob/master/Mojang.md + // + // Parchment is an unofficial project maintained by ParchmentMC, separate from MinecraftForge + // Additional setup is needed to use their mappings: https://github.com/ParchmentMC/Parchment/wiki/Getting-Started + // + // Use non-default mappings at your own risk. They may not always work. // Simply re-run your setup task after changing the mappings to update your workspace. - mappings channel: 'official', version: '1.16.5' - // makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable. - - // accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') + mappings channel: 'official', version: '1.19.2' + + // accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') // Currently, this location cannot be changed from the default. // Default run configurations. // These can be tweaked, removed, or duplicated as needed. @@ -38,11 +49,20 @@ minecraft { workingDirectory project.file('run') // Recommended logging data for a userdev environment - property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP' + // The markers can be added/remove as needed separated by commas. + // "SCAN": For mods scan. + // "REGISTRIES": For firing of registry events. + // "REGISTRYDUMP": For getting the contents of all registries. + property 'forge.logging.markers', 'REGISTRIES' // Recommended logging level for the console + // You can set various levels here. + // Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels property 'forge.logging.console.level', 'debug' + // Comma-separated list of namespaces to load gametests from. Empty = all namespaces. + property 'forge.enabledGameTestNamespaces', 'examplemod' + mods { examplemod { source sourceSets.main @@ -53,12 +73,41 @@ minecraft { server { workingDirectory project.file('run') + property 'forge.logging.markers', 'REGISTRIES' + + property 'forge.logging.console.level', 'debug' + + // Comma-separated list of namespaces to load gametests from. Empty = all namespaces. + property 'forge.enabledGameTestNamespaces', 'examplemod' + + mods { + examplemod { + source sourceSets.main + } + } + } + + // 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 { + workingDirectory project.file('run') + // Recommended logging data for a userdev environment - property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP' + // The markers can be added/remove as needed separated by commas. + // "SCAN": For mods scan. + // "REGISTRIES": For firing of registry events. + // "REGISTRYDUMP": For getting the contents of all registries. + property 'forge.logging.markers', 'REGISTRIES' // Recommended logging level for the console + // You can set various levels here. + // Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels property 'forge.logging.console.level', 'debug' + // Comma-separated list of namespaces to load gametests from. Empty = all namespaces. + property 'forge.enabledGameTestNamespaces', 'examplemod' + mods { examplemod { source sourceSets.main @@ -69,10 +118,8 @@ minecraft { data { workingDirectory project.file('run') - // Recommended logging data for a userdev environment - property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP' + property 'forge.logging.markers', 'REGISTRIES' - // Recommended logging level for the console property 'forge.logging.console.level', 'debug' // Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources. @@ -90,52 +137,55 @@ minecraft { // Include resources generated by data generators. sourceSets.main.resources { srcDir 'src/generated/resources' } -dependencies { - // Specify the version of Minecraft to use, If this is any group other then 'net.minecraft' it is assumed - // that the dep is a ForgeGradle 'patcher' dependency. And it's patches will be applied. - // The userdev artifact is a special name and will get all sorts of transformations applied to it. - minecraft 'net.minecraftforge:forge:1.16.4-35.0.18' +repositories { + // Put repositories for dependencies here + // ForgeGradle automatically adds the Forge maven and Maven Central for you - // You may put jars on which you depend on in ./libs or you may define them like so.. - // compile "some.group:artifact:version:classifier" - // compile "some.group:artifact:version" + // If you have mod jar dependencies in ./libs, you can declare them as a repository like so: + // flatDir { + // dir 'libs' + // } +} - // Real examples - // compile 'com.mod-buildcraft:buildcraft:6.0.8:dev' // adds buildcraft to the dev env - // compile 'com.googlecode.efficient-java-matrix-library:ejml:0.24' // adds ejml to the dev env +dependencies { + // Specify the version of Minecraft to use. If this is any group other than 'net.minecraft', it is assumed + // that the dep is a ForgeGradle 'patcher' dependency, and its patches will be applied. + // The userdev artifact is a special name and will get all sorts of transformations applied to it. + minecraft 'net.minecraftforge:forge:1.19.2-43.1.23' - // The 'provided' configuration is for optional dependencies that exist at compile-time but might not at runtime. - // provided 'com.mod-buildcraft:buildcraft:6.0.8:dev' + // Real mod deobf dependency examples - these get remapped to your current mappings + // compileOnly fg.deobf("mezz.jei:jei-${mc_version}:${jei_version}:api") // Adds JEI API as a compile dependency + // runtimeOnly fg.deobf("mezz.jei:jei-${mc_version}:${jei_version}") // Adds the full JEI mod as a runtime dependency + // implementation fg.deobf("com.tterrag.registrate:Registrate:MC${mc_version}-${registrate_version}") // Adds registrate as a dependency - // These dependencies get remapped to your current MCP mappings - // deobf 'com.mod-buildcraft:buildcraft:6.0.8:dev' + // Examples using mod jars from ./libs + // implementation fg.deobf("blank:coolmod-${mc_version}:${coolmod_version}") // For more info... // http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html // http://www.gradle.org/docs/current/userguide/dependency_management.html - } -// Example for how to get properties into the manifest for reading by the runtime.. +// Example for how to get properties into the manifest for reading at runtime. jar { manifest { attributes([ - "Specification-Title": "examplemod", - "Specification-Vendor": "examplemodsareus", - "Specification-Version": "1", // We are version 1 of ourselves - "Implementation-Title": project.name, - "Implementation-Version": "${version}", - "Implementation-Vendor" :"examplemodsareus", - "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") + "Specification-Title" : "examplemod", + "Specification-Vendor" : "examplemodsareus", + "Specification-Version" : "1", // We are version 1 of ourselves + "Implementation-Title" : project.name, + "Implementation-Version" : project.jar.archiveVersion, + "Implementation-Vendor" : "examplemodsareus", + "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") ]) } } -// Example configuration to allow publishing using the maven-publish task +// Example configuration to allow publishing using the maven-publish plugin // This is the preferred method to reobfuscate your jar file -jar.finalizedBy('reobfJar') +jar.finalizedBy('reobfJar') // However if you are in a multi-project build, dev time needs unobfed jar files, so you can delay the obfuscation until publishing by doing -//publish.dependsOn('reobfJar') +// publish.dependsOn('reobfJar') publishing { publications { @@ -145,7 +195,11 @@ publishing { } repositories { maven { - url "file:///${project.projectDir}/mcmodsrepo" + url "file://${project.projectDir}/mcmodsrepo" } } -} \ No newline at end of file +} + +tasks.withType(JavaCompile).configureEach { + options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 7a3265e..7454180 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 1d5b29f..41dfb87 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-bin.zip diff --git a/gradlew b/gradlew index cccdd3d..c53aefa 100644 --- a/gradlew +++ b/gradlew @@ -1,78 +1,129 @@ -#!/usr/bin/env sh +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# 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 +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` +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="" +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -81,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" + 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. Please set the JAVA_HOME variable in your environment to match the @@ -89,84 +140,95 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=$((i+1)) + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=$(save "$@") - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi +# 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. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index f955316..107acd3 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,3 +1,19 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @@ -13,15 +29,18 @@ if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -35,7 +54,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -45,28 +64,14 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell diff --git a/src/main/java/mod/teamdraco/bettas/Bettas.java b/src/main/java/mod/teamdraco/bettas/Bettas.java deleted file mode 100644 index 3527c1c..0000000 --- a/src/main/java/mod/teamdraco/bettas/Bettas.java +++ /dev/null @@ -1,104 +0,0 @@ -package mod.teamdraco.bettas; - -import mod.teamdraco.bettas.entity.BettaFishEntity; -import mod.teamdraco.bettas.init.BettasBlocks; -import mod.teamdraco.bettas.init.BettasEntities; -import mod.teamdraco.bettas.init.BettasFeatures; -import mod.teamdraco.bettas.init.BettasItems; -import net.minecraft.entity.EntityClassification; -import net.minecraft.entity.EntitySpawnPlacementRegistry; -import net.minecraft.entity.EntityType; -import net.minecraft.entity.ai.attributes.GlobalEntityTypeAttributes; -import net.minecraft.entity.passive.fish.AbstractFishEntity; -import net.minecraft.loot.LootEntry; -import net.minecraft.loot.LootPool; -import net.minecraft.loot.LootTables; -import net.minecraft.loot.TableLootEntry; -import net.minecraft.util.ResourceLocation; -import net.minecraft.world.biome.Biome; -import net.minecraft.world.biome.MobSpawnInfo; -import net.minecraft.world.gen.GenerationStage; -import net.minecraft.world.gen.Heightmap; -import net.minecraft.world.gen.feature.*; -import net.minecraft.world.gen.placement.ChanceConfig; -import net.minecraft.world.gen.placement.Placement; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.LootTableLoadEvent; -import net.minecraftforge.event.world.BiomeLoadingEvent; -import net.minecraftforge.eventbus.api.EventPriority; -import net.minecraftforge.eventbus.api.IEventBus; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.ObfuscationReflectionHelper; -import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; -import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; - -import java.util.List; -import java.util.Random; - -@Mod(Bettas.MOD_ID) -@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.FORGE, modid = Bettas.MOD_ID) -public class Bettas { - public static final String MOD_ID = "bettas"; - public static Bettas instance; - - public Bettas() { - IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus(); - bus.addListener(this::registerCommon); - - BettasItems.ITEMS.register(bus); - BettasBlocks.BLOCKS.register(bus); - BettasEntities.ENTITIES.register(bus); - BettasFeatures.FEATURES.register(bus); - - bus.addGenericListener(EntityType.class, BettasEntities::init); - - instance = this; - MinecraftForge.EVENT_BUS.register(this); - } - - @SubscribeEvent(priority = EventPriority.LOWEST) - public static void registerBiomes(BiomeLoadingEvent event) { - switch (event.getCategory()) { - case SWAMP: - event.getSpawns().getSpawner(EntityClassification.WATER_CREATURE).add(new MobSpawnInfo.Spawners(BettasEntities.BETTA_FISH.get(), 1, 1, 2));event.getGeneration().getFeatures(GenerationStage.Decoration.SURFACE_STRUCTURES).add(() -> BettasFeatures.MOSS_BALL.get().configured(new FeatureSpreadConfig(5)).decorated(Features.Placements.TOP_SOLID_HEIGHTMAP_SQUARE).chance(16)); - break; - } - } - - private void registerCommon(FMLCommonSetupEvent event) { - registerEntityAttributes(); - EntitySpawnPlacementRegistry.register(BettasEntities.BETTA_FISH.get(), EntitySpawnPlacementRegistry.PlacementType.IN_WATER, Heightmap.Type.MOTION_BLOCKING_NO_LEAVES, BettaFishEntity::checkFishSpawnRules); - } - - private void registerEntityAttributes() { - GlobalEntityTypeAttributes.put(BettasEntities.BETTA_FISH.get(), BettaFishEntity.createAttributes().build()); - } - - //Thanks to BlueDuck for the help with the loot table code :) - @Mod.EventBusSubscriber(modid = Bettas.MOD_ID) - public static class LootEvents { - @SubscribeEvent - public static void onLootLoad(LootTableLoadEvent event) throws IllegalAccessException { - ResourceLocation name = event.getName(); - if (name.equals(LootTables.FISHING)) { - LootPool pool = event.getTable().getPool("main"); - if (pool != null) { - addEntry(pool, getInjectEntry(new ResourceLocation("bettas:inject/fishing"), 10, 1)); - } - } - } - } - - private static LootEntry getInjectEntry(ResourceLocation location, int weight, int quality) { - return TableLootEntry.lootTableReference(location).setWeight(weight).setQuality(quality).build(); - } - - private static void addEntry(LootPool pool, LootEntry entry) throws IllegalAccessException { - List lootEntries = (List) ObfuscationReflectionHelper.findField(LootPool.class, "entries").get(pool); - if (lootEntries.stream().anyMatch(e -> e == entry)) { - throw new RuntimeException("Attempted to add a duplicate entry to pool: " + entry); - } - lootEntries.add(entry); - } -} \ No newline at end of file diff --git a/src/main/java/mod/teamdraco/bettas/ClientEventBusSubscriber.java b/src/main/java/mod/teamdraco/bettas/ClientEventBusSubscriber.java deleted file mode 100644 index 821e0e9..0000000 --- a/src/main/java/mod/teamdraco/bettas/ClientEventBusSubscriber.java +++ /dev/null @@ -1,35 +0,0 @@ -package mod.teamdraco.bettas; - - -import mod.teamdraco.bettas.client.renderer.BettaFishRenderer; -import mod.teamdraco.bettas.init.BettasBlocks; -import mod.teamdraco.bettas.init.BettasEntities; -import mod.teamdraco.bettas.item.BettasSpawnEggItem; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.RenderTypeLookup; -import net.minecraft.client.renderer.color.IItemColor; -import net.minecraft.client.renderer.color.ItemColors; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; -import net.minecraftforge.client.event.ColorHandlerEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.client.registry.RenderingRegistry; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; - -@OnlyIn(Dist.CLIENT) -@Mod.EventBusSubscriber(modid = Bettas.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD, value = Dist.CLIENT) -public class ClientEventBusSubscriber { - @SubscribeEvent - public static void clientSetup(FMLClientSetupEvent event) { - RenderingRegistry.registerEntityRenderingHandler(BettasEntities.BETTA_FISH.get(), BettaFishRenderer::new); - RenderTypeLookup.setRenderLayer(BettasBlocks.DRIED_LEAVES.get(), RenderType.getCutout()); - } - - @SubscribeEvent - public static void itemColors(ColorHandlerEvent.Item event) { - ItemColors handler = event.getItemColors(); - IItemColor eggColor = (stack, tintIndex) -> ((BettasSpawnEggItem) stack.getItem()).getColor(tintIndex); - for (BettasSpawnEggItem e : BettasSpawnEggItem.UNADDED_EGGS) handler.register(eggColor, e); - } -} diff --git a/src/main/java/mod/teamdraco/bettas/client/model/BettaFishModel.java b/src/main/java/mod/teamdraco/bettas/client/model/BettaFishModel.java deleted file mode 100644 index d9eecb1..0000000 --- a/src/main/java/mod/teamdraco/bettas/client/model/BettaFishModel.java +++ /dev/null @@ -1,87 +0,0 @@ -package mod.teamdraco.bettas.client.model; - -import com.google.common.collect.ImmutableList; -import com.mojang.blaze3d.matrix.MatrixStack; -import com.mojang.blaze3d.vertex.IVertexBuilder; -import net.minecraft.client.renderer.entity.model.EntityModel; -import net.minecraft.client.renderer.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.util.math.MathHelper; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; - -@OnlyIn(Dist.CLIENT) -public class BettaFishModel extends EntityModel { - public ModelRenderer body; - public ModelRenderer tail; - public ModelRenderer finTop; - public ModelRenderer finBottom; - public ModelRenderer finLeftBottom; - public ModelRenderer finRightBottom; - public ModelRenderer finLeft; - public ModelRenderer finRight; - - public BettaFishModel() { - this.texWidth = 32; - this.texHeight = 16; - this.finLeftBottom = new ModelRenderer(this, 11, 9); - this.finLeftBottom.setPos(0.5F, 1.5F, -0.5F); - this.finLeftBottom.addBox(0.0F, 0.0F, -1.0F, 0.0F, 3.0F, 2.0F, 0.0F, 0.0F, 0.0F); - this.setRotateAngle(finLeftBottom, 0.0F, 0.0F, -0.3490658503988659F); - this.tail = new ModelRenderer(this, 0, 6); - this.tail.setPos(0.0F, 0.0F, 3.5F); - this.tail.addBox(0.0F, -3.0F, 0.0F, 0.0F, 6.0F, 4.0F, 0.0F, 0.0F, 0.0F); - this.finRight = new ModelRenderer(this, -1, 1); - this.finRight.setPos(-1.0F, 0.5F, -0.5F); - this.finRight.addBox(-2.0F, 0.0F, -1.0F, 2.0F, 0.0F, 2.0F, 0.0F, 0.0F, 0.0F); - this.setRotateAngle(finRight, 0.0F, 0.0F, -0.7853981633974483F); - this.body = new ModelRenderer(this, 0, 0); - this.body.setPos(0.0F, 22.5F, -0.5F); - this.body.addBox(-1.0F, -1.5F, -3.5F, 2.0F, 3.0F, 7.0F, 0.0F, 0.0F, 0.0F); - this.finTop = new ModelRenderer(this, 0, 1); - this.finTop.setPos(0.0F, -1.5F, 2.0F); - this.finTop.addBox(0.0F, -3.0F, -1.5F, 0.0F, 3.0F, 3.0F, 0.0F, 0.0F, 0.0F); - this.finRightBottom = new ModelRenderer(this, 11, 9); - this.finRightBottom.setPos(-0.5F, 1.5F, -0.5F); - this.finRightBottom.addBox(0.0F, 0.0F, -1.0F, 0.0F, 3.0F, 2.0F, 0.0F, 0.0F, 0.0F); - this.setRotateAngle(finRightBottom, 0.0F, 0.0F, 0.3490658503988659F); - this.finBottom = new ModelRenderer(this, 11, -6); - this.finBottom.setPos(0.0F, 1.5F, 0.5F); - this.finBottom.addBox(0.0F, 0.0F, -3.0F, 0.0F, 2.0F, 6.0F, 0.0F, 0.0F, 0.0F); - this.setRotateAngle(finBottom, 0.0F, 3.141592653589793F, 0.0F); - this.finLeft = new ModelRenderer(this, -1, 1); - this.finLeft.mirror = true; - this.finLeft.setPos(1.0F, 0.5F, -0.5F); - this.finLeft.addBox(0.0F, 0.0F, -1.0F, 2.0F, 0.0F, 2.0F, 0.0F, 0.0F, 0.0F); - this.setRotateAngle(finLeft, 0.0F, 0.0F, 0.7853981633974483F); - this.body.addChild(this.finLeftBottom); - this.body.addChild(this.tail); - this.body.addChild(this.finRight); - this.body.addChild(this.finTop); - this.body.addChild(this.finRightBottom); - this.body.addChild(this.finBottom); - this.body.addChild(this.finLeft); - } - - @Override - public void renderToBuffer(MatrixStack matrixStackIn, IVertexBuilder bufferIn, int packedLightIn, int packedOverlayIn, float red, float green, float blue, float alpha) { - ImmutableList.of(this.body).forEach((modelRenderer) -> { - modelRenderer.render(matrixStackIn, bufferIn, packedLightIn, packedOverlayIn, red, green, blue, alpha); - }); - } - - @Override - public void setupAnim(T entityIn, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) { - float f = 1.0F; - if (!entityIn.isInWater()) { - f = 1.5F; - } - this.tail.yRot = -f * 0.45F * MathHelper.sin(0.6F * ageInTicks); - } - - public void setRotateAngle(ModelRenderer modelRenderer, float x, float y, float z) { - modelRenderer.xRot = x; - modelRenderer.yRot = y; - modelRenderer.zRot = z; - } -} diff --git a/src/main/java/mod/teamdraco/bettas/entity/BettaFishEntity.java b/src/main/java/mod/teamdraco/bettas/entity/BettaFishEntity.java deleted file mode 100644 index fcb2d82..0000000 --- a/src/main/java/mod/teamdraco/bettas/entity/BettaFishEntity.java +++ /dev/null @@ -1,232 +0,0 @@ -package mod.teamdraco.bettas.entity; - -import mod.teamdraco.bettas.init.BettasBlocks; -import mod.teamdraco.bettas.init.BettasItems; -import net.minecraft.block.Blocks; -import net.minecraft.entity.*; -import net.minecraft.entity.ai.attributes.AttributeModifierMap; -import net.minecraft.entity.ai.attributes.Attributes; -import net.minecraft.entity.ai.goal.*; -import net.minecraft.entity.passive.fish.AbstractFishEntity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.entity.projectile.AbstractArrowEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.CompoundNBT; -import net.minecraft.network.datasync.DataParameter; -import net.minecraft.network.datasync.DataSerializers; -import net.minecraft.network.datasync.EntityDataManager; -import net.minecraft.particles.ParticleTypes; -import net.minecraft.util.*; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.math.vector.Vector3d; -import net.minecraft.world.DifficultyInstance; -import net.minecraft.world.IServerWorld; -import net.minecraft.world.IWorld; -import net.minecraft.world.World; - -import javax.annotation.Nullable; -import java.util.Random; - -public class BettaFishEntity extends AbstractFishEntity { - public static final int MAX_VARIANTS = 120; - private static final DataParameter VARIANT = EntityDataManager.defineId(BettaFishEntity.class, DataSerializers.INT); - private static final DataParameter FROM_BUCKET = EntityDataManager.defineId(BettaFishEntity.class, DataSerializers.BOOLEAN); - - public BettaFishEntity(EntityType type, World worldIn) { - super(type, worldIn); - } - - protected void registerGoals() { - this.goalSelector.addGoal(0, new MeleeAttackGoal(this, 2.0D, true)); - this.goalSelector.addGoal(1, new SwimGoal(this)); - this.targetSelector.addGoal(3, new HurtByTargetGoal(this)); - } - - private boolean isFromBucket() { - return this.entityData.get(FROM_BUCKET); - } - - public void setFromBucket(boolean p_203706_1_) { - this.entityData.set(FROM_BUCKET, p_203706_1_); - } - - @Override - protected void defineSynchedData() { - super.defineSynchedData(); - this.entityData.define(VARIANT, 0); - this.entityData.define(FROM_BUCKET, false); - } - - public static AttributeModifierMap.MutableAttribute createAttributes() { - return MobEntity.createMobAttributes().add(Attributes.MAX_HEALTH, 6.0D).add(Attributes.ATTACK_DAMAGE, 1.0D); - } - - public static boolean checkFishSpawnRules(EntityType type, IWorld worldIn, SpawnReason reason, BlockPos p_223363_3_, Random randomIn) { - return worldIn.getBlockState(p_223363_3_).is(Blocks.WATER) && worldIn.getBlockState(p_223363_3_.above()).is(Blocks.WATER) && randomIn.nextFloat() > 0.9; - } - - public boolean hurt(DamageSource source, float amount) { - if (this.isInvulnerableTo(source)) { - return false; - } else { - Entity entity = source.getEntity(); - if (entity != null && !(entity instanceof PlayerEntity) && !(entity instanceof AbstractArrowEntity)) { - amount = (amount + 1.0F) / 2.0F; - } - - return super.hurt(source, amount); - } - } - - public boolean doHurtTarget(Entity entityIn) { - boolean flag = entityIn.hurt(DamageSource.mobAttack(this), (float)((int)this.getAttributeValue(Attributes.ATTACK_DAMAGE))); - if (flag) { - this.doEnchantDamageEffects(this, entityIn); - } - - return flag; - } - - public int getVariant() { - return this.entityData.get(VARIANT); - } - - private void setVariant(int variant) { - this.entityData.set(VARIANT, variant); - } - - public boolean removeWhenFarAway(double distanceToClosestPlayer) { - return !this.isFromBucket() && !this.hasCustomName(); - } - - public boolean requiresCustomPersistence() { - return super.requiresCustomPersistence() || this.isFromBucket(); - } - - @Override - public void tick() { - super.tick(); - - if (isMossBallNearby()) { - this.setTarget(null); - } - } - - private boolean isMossBallNearby() { - BlockPos blockpos = this.blockPosition(); - BlockPos.Mutable blockpos$mutable = new BlockPos.Mutable(); - - for(int i = 0; i < 8; ++i) { - for(int j = 0; j < 8; ++j) { - for(int k = 0; k <= j; k = k > 0 ? -k : 1 - k) { - for(int l = k < j && k > -j ? j : 0; l <= j; l = l > 0 ? -l : 1 - l) { - blockpos$mutable.setWithOffset(blockpos, k, i, l); - if (this.level.getBlockState(blockpos$mutable).is(BettasBlocks.MOSS_BALL_BLOCK.get())) { - return true; - } - } - } - } - } - - return false; - } - - @Override - public void addAdditionalSaveData(CompoundNBT compound) { - super.addAdditionalSaveData(compound); - compound.putInt("Variant", getVariant()); - compound.putBoolean("FromBucket", this.isFromBucket()); - } - - @Override - public void readAdditionalSaveData(CompoundNBT compound) { - super.readAdditionalSaveData(compound); - setVariant(MathHelper.clamp(compound.getInt("Variant"), 0, MAX_VARIANTS - 1)); - this.setFromBucket(compound.getBoolean("FromBucket")); - } - - @Nullable - @Override - public ILivingEntityData finalizeSpawn(IServerWorld worldIn, DifficultyInstance difficultyIn, SpawnReason reason, @Nullable ILivingEntityData spawnDataIn, @Nullable CompoundNBT dataTag) { - if (dataTag == null) { - double chance = getRandom().nextDouble(); - if (chance <= 0.45) setVariant(getRandom().nextInt(MAX_VARIANTS)); - else if (chance <= 0.7) setVariant(24); - else setVariant(100); - } - else { - if (dataTag.contains("Variant", 3)) { - this.setVariant(dataTag.getInt("Variant")); - this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, BettaFishEntity.class, false)); - } - if (dataTag.contains("Health", 99)) { - this.setHealth(dataTag.getFloat("Health")); - } - } - return super.finalizeSpawn(worldIn, difficultyIn, reason, spawnDataIn, dataTag); - } - - protected void saveToBucketTag(ItemStack bucket) { - CompoundNBT compoundnbt = bucket.getOrCreateTag(); - compoundnbt.putInt("Variant", this.getVariant()); - compoundnbt.putFloat("Health", this.getHealth()); - } - - @Override - protected ItemStack getBucketItemStack() { - return new ItemStack(BettasItems.BETTA_FISH_BUCKET.get()); - } - - @Override - protected SoundEvent getFlopSound() { - return SoundEvents.COD_FLOP; - } - - protected SoundEvent getDeathSound() { - return SoundEvents.COD_DEATH; - } - - protected SoundEvent getHurtSound(DamageSource damageSourceIn) { - return SoundEvents.COD_HURT; - } - - @Override - public ItemStack getPickedResult(RayTraceResult result) { - return new ItemStack(BettasItems.BETTA_FISH_SPAWN_EGG.get()); - } - - @Override - public ActionResultType interactAt(PlayerEntity player, Vector3d vec, Hand hand) { - ItemStack stack = player.getItemInHand(hand); - float maxHealth = this.getMaxHealth(); - float health = this.getHealth(); - if (stack.getItem() == BettasItems.BLACKWATER_BOTTLE.get() && health < maxHealth) { - if (!player.isCreative()) { - stack.shrink(1); - } - heal(3); - double d0 = this.random.nextGaussian() * 0.02D; - double d1 = this.random.nextGaussian() * 0.02D; - double d2 = this.random.nextGaussian() * 0.02D; - this.level.addParticle(ParticleTypes.HEART, this.getRandomX(1.0D), this.getRandomY() + 0.5D, this.getRandomZ(1.0D), d0, d1, d2); - return ActionResultType.PASS; - } - return super.interactAt(player, vec, hand); - } - - static class SwimGoal extends RandomSwimmingGoal { - private final BettaFishEntity fish; - - public SwimGoal(BettaFishEntity fish) { - super(fish, 1.0D, 40); - this.fish = fish; - } - - public boolean canUse() { - return this.fish.canRandomSwim() && super.canUse(); - } - } -} \ No newline at end of file diff --git a/src/main/java/mod/teamdraco/bettas/feature/MossBallFeature.java b/src/main/java/mod/teamdraco/bettas/feature/MossBallFeature.java deleted file mode 100644 index bd216a3..0000000 --- a/src/main/java/mod/teamdraco/bettas/feature/MossBallFeature.java +++ /dev/null @@ -1,40 +0,0 @@ -package mod.teamdraco.bettas.feature; - -import com.mojang.serialization.Codec; -import mod.teamdraco.bettas.init.BettasBlocks; -import net.minecraft.block.BlockState; -import net.minecraft.block.Blocks; -import net.minecraft.block.SeaPickleBlock; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.ISeedReader; -import net.minecraft.world.gen.ChunkGenerator; -import net.minecraft.world.gen.Heightmap; -import net.minecraft.world.gen.feature.Feature; -import net.minecraft.world.gen.feature.FeatureSpreadConfig; - -import java.util.Random; - -public class MossBallFeature extends Feature { - public MossBallFeature(Codec p_i231987_1_) { - super(p_i231987_1_); - } - - public boolean place(ISeedReader reader, ChunkGenerator generator, Random rand, BlockPos pos, FeatureSpreadConfig config) { - int i = 0; - int j = config.count().sample(rand); - - for(int k = 0; k < j; ++k) { - int l = rand.nextInt(8) - rand.nextInt(8); - int i1 = rand.nextInt(8) - rand.nextInt(8); - int j1 = reader.getHeight(Heightmap.Type.OCEAN_FLOOR, pos.getX() + l, pos.getZ() + i1); - BlockPos blockpos = new BlockPos(pos.getX() + l, j1, pos.getZ() + i1); - BlockState blockstate = BettasBlocks.MOSS_BALL.get().defaultBlockState().setValue(SeaPickleBlock.PICKLES, Integer.valueOf(rand.nextInt(4) + 1)); - if (reader.getBlockState(blockpos).is(Blocks.WATER) && blockstate.canSurvive(reader, blockpos)) { - reader.setBlock(blockpos, blockstate, 2); - ++i; - } - } - - return i > 0; - } -} diff --git a/src/main/java/mod/teamdraco/bettas/init/BettasBlocks.java b/src/main/java/mod/teamdraco/bettas/init/BettasBlocks.java deleted file mode 100644 index 050238a..0000000 --- a/src/main/java/mod/teamdraco/bettas/init/BettasBlocks.java +++ /dev/null @@ -1,33 +0,0 @@ -package mod.teamdraco.bettas.init; - -import mod.teamdraco.bettas.Bettas; -import mod.teamdraco.bettas.block.DriedLeavesBlock; -import mod.teamdraco.bettas.block.MossBallBlock; -import net.minecraft.block.Block; -import net.minecraft.block.SoundType; -import net.minecraft.block.material.Material; -import net.minecraft.block.material.MaterialColor; -import net.minecraft.item.BlockItem; -import net.minecraft.item.Item; -import net.minecraft.item.ItemGroup; -import net.minecraftforge.fml.RegistryObject; -import net.minecraftforge.registries.DeferredRegister; -import net.minecraftforge.registries.ForgeRegistries; - -import java.util.function.Supplier; - -import net.minecraft.block.AbstractBlock; - -public class BettasBlocks { - public static final DeferredRegister BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, Bettas.MOD_ID); - - public static final RegistryObject MOSS_BALL = BLOCKS.register("moss_ball", () -> new MossBallBlock(AbstractBlock.Properties.of(Material.DECORATION, MaterialColor.COLOR_GREEN).sound(SoundType.WET_GRASS).strength(0).noOcclusion())); - public static final RegistryObject MOSS_BALL_BLOCK = BLOCKS.register("moss_ball_block", () -> new Block(AbstractBlock.Properties.of(Material.GRASS, MaterialColor.COLOR_GREEN).sound(SoundType.WET_GRASS).strength(0.5f))); - public static final RegistryObject DRIED_LEAVES = BLOCKS.register("dried_leaves", () -> new DriedLeavesBlock(AbstractBlock.Properties.of(Material.DECORATION, MaterialColor.COLOR_ORANGE).sound(SoundType.GRASS).strength(0).noOcclusion())); - - private static RegistryObject register(String name, Supplier block) { - RegistryObject object = BLOCKS.register(name, block); - BettasItems.ITEMS.register(name, () -> new BlockItem(object.get(), new Item.Properties().tab(ItemGroup.TAB_DECORATIONS))); - return object; - } -} diff --git a/src/main/java/mod/teamdraco/bettas/init/BettasEntities.java b/src/main/java/mod/teamdraco/bettas/init/BettasEntities.java deleted file mode 100644 index 583ba49..0000000 --- a/src/main/java/mod/teamdraco/bettas/init/BettasEntities.java +++ /dev/null @@ -1,23 +0,0 @@ -package mod.teamdraco.bettas.init; - -import mod.teamdraco.bettas.Bettas; -import mod.teamdraco.bettas.entity.BettaFishEntity; -import net.minecraft.entity.*; -import net.minecraft.entity.ai.attributes.GlobalEntityTypeAttributes; -import net.minecraft.item.Item; -import net.minecraft.item.ItemGroup; -import net.minecraft.item.SpawnEggItem; -import net.minecraft.util.ResourceLocation; -import net.minecraftforge.event.RegistryEvent; -import net.minecraftforge.fml.RegistryObject; -import net.minecraftforge.registries.DeferredRegister; -import net.minecraftforge.registries.ForgeRegistries; - -public class BettasEntities { - public static final DeferredRegister> ENTITIES = DeferredRegister.create(ForgeRegistries.ENTITIES, Bettas.MOD_ID); - - public static final RegistryObject> BETTA_FISH = ENTITIES.register("betta_fish", () -> EntityType.Builder.of(BettaFishEntity::new, EntityClassification.WATER_AMBIENT).sized(0.3f, 0.3f).build(new ResourceLocation(Bettas.MOD_ID, "betta_fish").toString())); - - public static void init(RegistryEvent.Register> event) { - } -} \ No newline at end of file diff --git a/src/main/java/mod/teamdraco/bettas/init/BettasFeatures.java b/src/main/java/mod/teamdraco/bettas/init/BettasFeatures.java deleted file mode 100644 index 52e86fc..0000000 --- a/src/main/java/mod/teamdraco/bettas/init/BettasFeatures.java +++ /dev/null @@ -1,19 +0,0 @@ -package mod.teamdraco.bettas.init; - -import mod.teamdraco.bettas.Bettas; -import mod.teamdraco.bettas.feature.MossBallFeature; -import net.minecraft.entity.EntityType; -import net.minecraft.util.registry.Registry; -import net.minecraft.world.gen.feature.Feature; -import net.minecraft.world.gen.feature.FeatureSpreadConfig; -import net.minecraft.world.gen.feature.IFeatureConfig; -import net.minecraft.world.gen.feature.SeaPickleFeature; -import net.minecraftforge.fml.RegistryObject; -import net.minecraftforge.registries.DeferredRegister; -import net.minecraftforge.registries.ForgeRegistries; - -public class BettasFeatures { - public static final DeferredRegister> FEATURES = DeferredRegister.create(ForgeRegistries.FEATURES, Bettas.MOD_ID); - - public static final RegistryObject> MOSS_BALL = FEATURES.register("moss_ball", () -> new MossBallFeature(FeatureSpreadConfig.CODEC)); -} diff --git a/src/main/java/mod/teamdraco/bettas/init/BettasItems.java b/src/main/java/mod/teamdraco/bettas/init/BettasItems.java deleted file mode 100644 index 059a19b..0000000 --- a/src/main/java/mod/teamdraco/bettas/init/BettasItems.java +++ /dev/null @@ -1,26 +0,0 @@ -package mod.teamdraco.bettas.init; - -import mod.teamdraco.bettas.Bettas; -import mod.teamdraco.bettas.item.BettasSpawnEggItem; -import net.minecraft.fluid.Fluid; -import net.minecraft.fluid.Fluids; -import net.minecraft.item.*; -import net.minecraftforge.fml.RegistryObject; -import net.minecraftforge.registries.DeferredRegister; -import net.minecraftforge.registries.ForgeRegistries; - -import java.util.function.Supplier; - -public class BettasItems { - public static final DeferredRegister ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, Bettas.MOD_ID); - - public static final RegistryObject BETTA_FISH = ITEMS.register("betta_fish", () -> new Item(new Item.Properties().tab(ItemGroup.TAB_FOOD).food(new Food.Builder().nutrition(1).saturationMod(0.1F).build()))); - public static final RegistryObject BETTA_FISH_BUCKET = ITEMS.register("betta_fish_bucket", () -> new FishBucketItem(BettasEntities.BETTA_FISH, () -> Fluids.WATER, new Item.Properties().tab(ItemGroup.TAB_MISC).stacksTo(1))); - public static final RegistryObject BLACKWATER_BOTTLE = ITEMS.register("blackwater_bottle", () -> new Item(new Item.Properties().tab(ItemGroup.TAB_MISC).stacksTo(1))); - - public static final RegistryObject BETTA_FISH_SPAWN_EGG = ITEMS.register("betta_fish_spawn_egg", () -> new BettasSpawnEggItem(BettasEntities.BETTA_FISH, 0x613d2a, 0x2dceff, new Item.Properties().tab(ItemGroup.TAB_MISC))); - - public static final RegistryObject MOSS_BALL = ITEMS.register("moss_ball", () -> new BlockItem(BettasBlocks.MOSS_BALL.get(), new Item.Properties().tab(ItemGroup.TAB_DECORATIONS))); - public static final RegistryObject MOSS_BALL_BLOCK = ITEMS.register("moss_ball_block", () -> new BlockItem(BettasBlocks.MOSS_BALL_BLOCK.get(), new Item.Properties().tab(ItemGroup.TAB_DECORATIONS))); - public static final RegistryObject DRIED_LEAVES = ITEMS.register("dried_leaves", () -> new BlockItem(BettasBlocks.DRIED_LEAVES.get(), new Item.Properties().tab(ItemGroup.TAB_DECORATIONS))); -} \ No newline at end of file diff --git a/src/main/java/mod/teamdraco/bettas/item/BettasSpawnEggItem.java b/src/main/java/mod/teamdraco/bettas/item/BettasSpawnEggItem.java deleted file mode 100644 index 813c0c6..0000000 --- a/src/main/java/mod/teamdraco/bettas/item/BettasSpawnEggItem.java +++ /dev/null @@ -1,63 +0,0 @@ -package mod.teamdraco.bettas.item; - -import net.minecraft.block.DispenserBlock; -import net.minecraft.dispenser.DefaultDispenseItemBehavior; -import net.minecraft.dispenser.IBlockSource; -import net.minecraft.entity.EntityType; -import net.minecraft.entity.SpawnReason; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.item.SpawnEggItem; -import net.minecraft.nbt.CompoundNBT; -import net.minecraft.util.Direction; -import net.minecraftforge.common.util.Lazy; -import net.minecraftforge.common.util.NonNullSupplier; -import net.minecraftforge.fml.RegistryObject; -import net.minecraftforge.fml.common.ObfuscationReflectionHelper; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -public class BettasSpawnEggItem extends SpawnEggItem { - - public static final List UNADDED_EGGS = new ArrayList(); - private final Lazy> entityTypeSupplier; - - public BettasSpawnEggItem(final NonNullSupplier> entityTypeSupplier, final int primaryColour, final int secondaryColour, final Item.Properties properties) { - super(null, primaryColour, secondaryColour, properties); - this.entityTypeSupplier = Lazy.of(entityTypeSupplier::get); - UNADDED_EGGS.add(this); - } - - public BettasSpawnEggItem(final RegistryObject> entityTypeSupplier, final int primaryColour, final int secondaryColour, final Item.Properties properties) { - super(null, primaryColour, secondaryColour, properties); - this.entityTypeSupplier = Lazy.of(entityTypeSupplier::get); - UNADDED_EGGS.add(this); - } - - public static void initSpawnEggs() { - final Map, SpawnEggItem> EGGS = ObfuscationReflectionHelper.getPrivateValue(SpawnEggItem.class, null, "BY_ID"); - DefaultDispenseItemBehavior dispenseBehaviour = new DefaultDispenseItemBehavior() { - @Override - protected ItemStack execute(IBlockSource source, ItemStack stack) { - Direction direction = source.getBlockState().getValue(DispenserBlock.FACING); - EntityType type = ((SpawnEggItem) stack.getItem()).getType(stack.getTag()); - type.spawn(source.getLevel(), stack, null, source.getPos().relative(direction), SpawnReason.DISPENSER, direction != Direction.UP, false); - stack.shrink(1); - return stack; - } - }; - - for (final SpawnEggItem spawnEgg : UNADDED_EGGS) { - EGGS.put(spawnEgg.getType(null), spawnEgg); - DispenserBlock.registerBehavior(spawnEgg, dispenseBehaviour); - } - UNADDED_EGGS.clear(); - } - - @Override - public EntityType getType(CompoundNBT nbt) { - return this.entityTypeSupplier.get(); - } -} \ No newline at end of file diff --git a/src/main/java/teamfusion/bettas/Bettas.java b/src/main/java/teamfusion/bettas/Bettas.java new file mode 100644 index 0000000..ba192d6 --- /dev/null +++ b/src/main/java/teamfusion/bettas/Bettas.java @@ -0,0 +1,86 @@ +package teamfusion.bettas; + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.SpawnPlacements; +import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.level.storage.loot.LootPool; +import net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer; +import net.minecraft.world.level.storage.loot.entries.LootTableReference; +import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.LootTableLoadEvent; +import net.minecraftforge.event.entity.EntityAttributeCreationEvent; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; +import net.minecraftforge.fml.util.ObfuscationReflectionHelper; +import teamfusion.bettas.entity.BettaFishEntity; +import teamfusion.bettas.init.BettaBiomeModifiers; +import teamfusion.bettas.init.BettasBlocks; +import teamfusion.bettas.init.BettasConfiguredFeatures; +import teamfusion.bettas.init.BettasEntities; +import teamfusion.bettas.init.BettasFeatures; +import teamfusion.bettas.init.BettasItems; +import teamfusion.bettas.init.BettasPlacedFeatures; + +import java.util.List; + +@Mod(Bettas.MOD_ID) +@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.FORGE, modid = Bettas.MOD_ID) +public class Bettas { + public static final String MOD_ID = "bettas"; + + public Bettas() { + IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus(); + bus.addListener(this::registerCommon); + + BettaBiomeModifiers.BIOME_MODIFIER_SERIALIZERS.register(bus); + BettasItems.ITEMS.register(bus); + BettasBlocks.BLOCKS.register(bus); + BettasEntities.ENTITIES.register(bus); + BettasFeatures.FEATURES.register(bus); + BettasConfiguredFeatures.CONFIGURED_FEATURES.register(bus); + BettasPlacedFeatures.PLACED_FEATURES.register(bus); + + bus.addListener(this::registerEntityAttributes); + + MinecraftForge.EVENT_BUS.register(this); + } + + private void registerCommon(FMLCommonSetupEvent event) { + SpawnPlacements.register(BettasEntities.BETTA_FISH.get(), SpawnPlacements.Type.IN_WATER, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, BettaFishEntity::checkBettaFishSpawnRules); + } + + private void registerEntityAttributes(EntityAttributeCreationEvent event) { + event.put(BettasEntities.BETTA_FISH.get(), BettaFishEntity.createAttributes().build()); + } + + //Thanks to BlueDuck for the help with the loot table code :) + @Mod.EventBusSubscriber(modid = Bettas.MOD_ID) + public static class LootEvents { + @SuppressWarnings("unlikely-arg-type") + @SubscribeEvent + public static void onLootLoad(LootTableLoadEvent event) throws IllegalAccessException { + ResourceLocation name = event.getName(); + if (name.equals(LootContextParamSets.FISHING)) { + LootPool pool = event.getTable().getPool("main"); + addEntry(pool, getInjectEntry(new ResourceLocation("bettas:inject/fishing"), 10, 1)); + } + } + } + + private static LootPoolEntryContainer getInjectEntry(ResourceLocation location, int weight, int quality) { + return LootTableReference.lootTableReference(location).setWeight(weight).setQuality(quality).build(); + } + + @SuppressWarnings("unchecked") + private static void addEntry(LootPool pool, LootPoolEntryContainer entry) throws IllegalAccessException { + List lootEntries = (List) ObfuscationReflectionHelper.findField(LootPool.class, "entries").get(pool); + if (lootEntries.stream().anyMatch(e -> e == entry)) { + throw new RuntimeException("Attempted to add a duplicate entry to pool: " + entry); + } + lootEntries.add(entry); + } +} \ No newline at end of file diff --git a/src/main/java/teamfusion/bettas/biome/BettaBiomeModifier.java b/src/main/java/teamfusion/bettas/biome/BettaBiomeModifier.java new file mode 100644 index 0000000..204feb3 --- /dev/null +++ b/src/main/java/teamfusion/bettas/biome/BettaBiomeModifier.java @@ -0,0 +1,50 @@ +package teamfusion.bettas.biome; + +import com.mojang.serialization.Codec; +import net.minecraft.core.Holder; +import net.minecraft.tags.BiomeTags; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.MobCategory; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.Biomes; +import net.minecraft.world.level.biome.MobSpawnSettings; +import net.minecraft.world.level.levelgen.GenerationStep; +import net.minecraftforge.common.Tags; +import net.minecraftforge.common.world.BiomeModifier; +import net.minecraftforge.common.world.MobSpawnSettingsBuilder; +import net.minecraftforge.common.world.ModifiableBiomeInfo; +import net.minecraftforge.registries.ForgeRegistries; +import teamfusion.bettas.init.BettaBiomeModifiers; +import teamfusion.bettas.init.BettasEntities; +import teamfusion.bettas.init.BettasPlacedFeatures; + +import java.util.List; + +public class BettaBiomeModifier implements BiomeModifier { + public static final BettaBiomeModifier INSTANCE = new BettaBiomeModifier(); + + @Override + public void modify(Holder biome, Phase phase, ModifiableBiomeInfo.BiomeInfo.Builder builder) { + if (phase == Phase.ADD) { + if (biome.is(BiomeTags.IS_OVERWORLD) && biome.is(Tags.Biomes.IS_SWAMP)) { + builder.getMobSpawnSettings().addSpawn(MobCategory.WATER_AMBIENT, new MobSpawnSettings.SpawnerData(BettasEntities.BETTA_FISH.get(), 15, 4, 6)); + builder.getGenerationSettings().addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, BettasPlacedFeatures.PLACED_MOSS_BALLS.getHolder().get()); + } + } + + if (phase == Phase.REMOVE) { + if (biome.is(Biomes.MANGROVE_SWAMP)) { + MobSpawnSettingsBuilder spawnBuilder = builder.getMobSpawnSettings(); + for (MobCategory category : MobCategory.values()) { + List spawns = spawnBuilder.getSpawner(category); + spawns.removeIf(spawnerData -> EntityType.TROPICAL_FISH == ForgeRegistries.ENTITY_TYPES.getHolder(spawnerData.type).get().get()); + } + } + } + } + + @Override + public Codec codec() { + return BettaBiomeModifiers.BETTA_BIOME_MODIFIER_TYPE.get(); + } +} \ No newline at end of file diff --git a/src/main/java/mod/teamdraco/bettas/block/DriedLeavesBlock.java b/src/main/java/teamfusion/bettas/block/DriedLeavesBlock.java similarity index 51% rename from src/main/java/mod/teamdraco/bettas/block/DriedLeavesBlock.java rename to src/main/java/teamfusion/bettas/block/DriedLeavesBlock.java index ff03f68..9ae0228 100644 --- a/src/main/java/mod/teamdraco/bettas/block/DriedLeavesBlock.java +++ b/src/main/java/teamfusion/bettas/block/DriedLeavesBlock.java @@ -1,37 +1,42 @@ -package mod.teamdraco.bettas.block; +package teamfusion.bettas.block; -import net.minecraft.block.*; -import net.minecraft.fluid.FluidState; -import net.minecraft.fluid.Fluids; -import net.minecraft.item.BlockItemUseContext; -import net.minecraft.state.BooleanProperty; -import net.minecraft.state.IntegerProperty; -import net.minecraft.state.StateContainer; -import net.minecraft.state.properties.BlockStateProperties; -import net.minecraft.util.Direction; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.shapes.ISelectionContext; -import net.minecraft.util.math.shapes.VoxelShape; -import net.minecraft.world.IBlockReader; -import net.minecraft.world.IWorld; -import net.minecraft.world.IWorldReader; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.BushBlock; +import net.minecraft.world.level.block.SimpleWaterloggedBlock; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.block.state.properties.IntegerProperty; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Fluids; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; import javax.annotation.Nullable; -public class DriedLeavesBlock extends BushBlock implements IWaterLoggable { +public class DriedLeavesBlock extends BushBlock implements SimpleWaterloggedBlock { public static final IntegerProperty LEAVES = BlockStateProperties.PICKLES; public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; protected static final VoxelShape ONE_SHAPE = Block.box(0, 0, 0, 16, 2, 16); protected static final VoxelShape TWO_SHAPE = Block.box(0, 0, 0, 16, 3, 16); protected static final VoxelShape THREE_SHAPE = Block.box(0, 0, 0, 16, 5, 16); - public DriedLeavesBlock(AbstractBlock.Properties properties) { + public DriedLeavesBlock(BlockBehaviour.Properties properties) { super(properties); this.registerDefaultState(this.stateDefinition.any().setValue(LEAVES, Integer.valueOf(1)).setValue(WATERLOGGED, Boolean.valueOf(true))); } @Nullable - public BlockState getStateForPlacement(BlockItemUseContext context) { + public BlockState getStateForPlacement(BlockPlaceContext context) { BlockState blockstate = context.getLevel().getBlockState(context.getClickedPos()); if (blockstate.is(this)) { return blockstate.setValue(LEAVES, Integer.valueOf(Math.min(3, blockstate.getValue(LEAVES) + 1))); @@ -47,42 +52,33 @@ public boolean useShapeForLightOcclusion(BlockState state) { return true; } - public static boolean isInBadEnvironment(BlockState p_204901_0_) { - return !p_204901_0_.getValue(WATERLOGGED); - } - - protected boolean mayPlaceOn(BlockState state, IBlockReader worldIn, BlockPos pos) { + protected boolean mayPlaceOn(BlockState state, LevelReader worldIn, BlockPos pos) { return !state.getCollisionShape(worldIn, pos).getFaceShape(Direction.UP).isEmpty() || state.isFaceSturdy(worldIn, pos, Direction.UP); } - public boolean canSurvive(BlockState state, IWorldReader worldIn, BlockPos pos) { + public boolean canSurvive(BlockState state, LevelReader worldIn, BlockPos pos) { BlockPos blockpos = pos.below(); return this.mayPlaceOn(worldIn.getBlockState(blockpos), worldIn, blockpos); } - /** - * Update the provided state given the provided neighbor facing and neighbor state, returning a new state. - * For example, fences make their connections to the passed in state if possible, and wet concrete powder immediately - * returns its solidified counterpart. - * Note that this method should ideally consider only the specific face passed in. - */ - public BlockState updateShape(BlockState stateIn, Direction facing, BlockState facingState, IWorld worldIn, BlockPos currentPos, BlockPos facingPos) { + public BlockState updateShape(BlockState stateIn, Direction facing, BlockState facingState, LevelAccessor worldIn, BlockPos currentPos, BlockPos facingPos) { if (!stateIn.canSurvive(worldIn, currentPos)) { return Blocks.AIR.defaultBlockState(); } else { if (stateIn.getValue(WATERLOGGED)) { - worldIn.getLiquidTicks().scheduleTick(currentPos, Fluids.WATER, Fluids.WATER.getTickDelay(worldIn)); + worldIn.scheduleTick(currentPos, Fluids.WATER, Fluids.WATER.getTickDelay(worldIn)); } return super.updateShape(stateIn, facing, facingState, worldIn, currentPos, facingPos); } } - public boolean canBeReplaced(BlockState state, BlockItemUseContext useContext) { - return useContext.getItemInHand().getItem() == this.asItem() && state.getValue(LEAVES) < 3 ? true : super.canBeReplaced(state, useContext); + @SuppressWarnings("deprecation") + public boolean canBeReplaced(BlockState state, BlockPlaceContext useContext) { + return useContext.getItemInHand().getItem() == this.asItem() && state.getValue(LEAVES) < 3 || super.canBeReplaced(state, useContext); } - public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) { + public VoxelShape getShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context) { switch (state.getValue(LEAVES)) { case 1: default: @@ -94,11 +90,12 @@ public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, } } - public FluidState getFluidState(BlockState state) { + @SuppressWarnings("deprecation") + public FluidState getFluidState(BlockState state) { return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state); } - protected void createBlockStateDefinition(StateContainer.Builder builder) { + protected void createBlockStateDefinition(StateDefinition.Builder builder) { builder.add(LEAVES, WATERLOGGED); } } diff --git a/src/main/java/mod/teamdraco/bettas/block/MossBallBlock.java b/src/main/java/teamfusion/bettas/block/MossBallBlock.java similarity index 55% rename from src/main/java/mod/teamdraco/bettas/block/MossBallBlock.java rename to src/main/java/teamfusion/bettas/block/MossBallBlock.java index ac67483..86282fa 100644 --- a/src/main/java/mod/teamdraco/bettas/block/MossBallBlock.java +++ b/src/main/java/teamfusion/bettas/block/MossBallBlock.java @@ -1,29 +1,34 @@ -package mod.teamdraco.bettas.block; - -import mod.teamdraco.bettas.init.BettasBlocks; -import net.minecraft.block.*; -import net.minecraft.fluid.FluidState; -import net.minecraft.fluid.Fluids; -import net.minecraft.item.BlockItemUseContext; -import net.minecraft.state.BooleanProperty; -import net.minecraft.state.IntegerProperty; -import net.minecraft.state.StateContainer; -import net.minecraft.state.properties.BlockStateProperties; -import net.minecraft.tags.BlockTags; -import net.minecraft.util.Direction; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.shapes.ISelectionContext; -import net.minecraft.util.math.shapes.VoxelShape; -import net.minecraft.world.IBlockReader; -import net.minecraft.world.IWorld; -import net.minecraft.world.IWorldReader; -import net.minecraft.world.World; -import net.minecraft.world.server.ServerWorld; +package teamfusion.bettas.block; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.BonemealableBlock; +import net.minecraft.world.level.block.BushBlock; +import net.minecraft.world.level.block.SimpleWaterloggedBlock; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.block.state.properties.IntegerProperty; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Fluids; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; +import teamfusion.bettas.init.BettasBlocks; import javax.annotation.Nullable; -import java.util.Random; -public class MossBallBlock extends BushBlock implements IWaterLoggable, IGrowable { +public class MossBallBlock extends BushBlock implements SimpleWaterloggedBlock, BonemealableBlock { public static final IntegerProperty BALLS = BlockStateProperties.PICKLES; public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; protected static final VoxelShape ONE_SHAPE = Block.box(0, 0, 0, 16, 7, 16); @@ -31,20 +36,20 @@ public class MossBallBlock extends BushBlock implements IWaterLoggable, IGrowabl protected static final VoxelShape THREE_SHAPE = Block.box(0, 0, 0, 16, 7, 16); protected static final VoxelShape FOUR_SHAPE = Block.box(0, 0, 0, 16, 8, 16); - public MossBallBlock(AbstractBlock.Properties properties) { + public MossBallBlock(BlockBehaviour.Properties properties) { super(properties); - this.registerDefaultState(this.stateDefinition.any().setValue(BALLS, Integer.valueOf(1)).setValue(WATERLOGGED, Boolean.valueOf(true))); + this.registerDefaultState(this.stateDefinition.any().setValue(BALLS, 1).setValue(WATERLOGGED, Boolean.TRUE)); } @Nullable - public BlockState getStateForPlacement(BlockItemUseContext context) { + public BlockState getStateForPlacement(BlockPlaceContext context) { BlockState blockstate = context.getLevel().getBlockState(context.getClickedPos()); if (blockstate.is(this)) { - return blockstate.setValue(BALLS, Integer.valueOf(Math.min(4, blockstate.getValue(BALLS) + 1))); + return blockstate.setValue(BALLS, Math.min(4, blockstate.getValue(BALLS) + 1)); } else { FluidState fluidstate = context.getLevel().getFluidState(context.getClickedPos()); boolean flag = fluidstate.getType() == Fluids.WATER; - return super.getStateForPlacement(context).setValue(WATERLOGGED, Boolean.valueOf(flag)); + return super.getStateForPlacement(context).setValue(WATERLOGGED, flag); } } @@ -52,32 +57,33 @@ public static boolean isInBadEnvironment(BlockState p_204901_0_) { return !p_204901_0_.getValue(WATERLOGGED); } - protected boolean mayPlaceOn(BlockState state, IBlockReader worldIn, BlockPos pos) { + protected boolean mayPlaceOn(BlockState state, LevelReader worldIn, BlockPos pos) { return !state.getCollisionShape(worldIn, pos).getFaceShape(Direction.UP).isEmpty() || state.isFaceSturdy(worldIn, pos, Direction.UP); } - public boolean canSurvive(BlockState state, IWorldReader worldIn, BlockPos pos) { + public boolean canSurvive(BlockState state, LevelReader worldIn, BlockPos pos) { BlockPos blockpos = pos.below(); return this.mayPlaceOn(worldIn.getBlockState(blockpos), worldIn, blockpos); } - public BlockState updateShape(BlockState stateIn, Direction facing, BlockState facingState, IWorld worldIn, BlockPos currentPos, BlockPos facingPos) { + public BlockState updateShape(BlockState stateIn, Direction facing, BlockState facingState, LevelAccessor worldIn, BlockPos currentPos, BlockPos facingPos) { if (!stateIn.canSurvive(worldIn, currentPos)) { return Blocks.AIR.defaultBlockState(); } else { if (stateIn.getValue(WATERLOGGED)) { - worldIn.getLiquidTicks().scheduleTick(currentPos, Fluids.WATER, Fluids.WATER.getTickDelay(worldIn)); + worldIn.scheduleTick(currentPos, Fluids.WATER, Fluids.WATER.getTickDelay(worldIn)); } return super.updateShape(stateIn, facing, facingState, worldIn, currentPos, facingPos); } } - public boolean canBeReplaced(BlockState state, BlockItemUseContext useContext) { - return useContext.getItemInHand().getItem() == this.asItem() && state.getValue(BALLS) < 4 ? true : super.canBeReplaced(state, useContext); + @SuppressWarnings("deprecation") + public boolean canBeReplaced(BlockState state, BlockPlaceContext useContext) { + return useContext.getItemInHand().getItem() == this.asItem() && state.getValue(BALLS) < 4 || super.canBeReplaced(state, useContext); } - public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) { + public VoxelShape getShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context) { switch (state.getValue(BALLS)) { case 1: default: @@ -91,23 +97,25 @@ public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, } } - public FluidState getFluidState(BlockState state) { + @SuppressWarnings("deprecation") + public FluidState getFluidState(BlockState state) { return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state); } - protected void createBlockStateDefinition(StateContainer.Builder builder) { + protected void createBlockStateDefinition(StateDefinition.Builder builder) { builder.add(BALLS, WATERLOGGED); } - public boolean isValidBonemealTarget(IBlockReader worldIn, BlockPos pos, BlockState state, boolean isClient) { + public boolean isValidBonemealTarget(BlockGetter worldIn, BlockPos pos, BlockState state, boolean isClient) { return true; } - public boolean isBonemealSuccess(World worldIn, Random rand, BlockPos pos, BlockState state) { + public boolean isBonemealSuccess(Level worldIn, RandomSource rand, BlockPos pos, BlockState state) { return true; } - public void performBonemeal(ServerWorld worldIn, Random rand, BlockPos pos, BlockState state) { + @SuppressWarnings("unused") + public void performBonemeal(ServerLevel worldIn, RandomSource rand, BlockPos pos, BlockState state) { if (!isInBadEnvironment(state) && worldIn.getBlockState(pos.below()).getBlock() == BettasBlocks.MOSS_BALL_BLOCK.get()) { int i = 5; int j = 1; @@ -116,8 +124,8 @@ public void performBonemeal(ServerWorld worldIn, Random rand, BlockPos pos, Bloc int i1 = pos.getX() - 2; int j1 = 0; - for(int k1 = 0; k1 < 5; ++k1) { - for(int l1 = 0; l1 < j; ++l1) { + for (int k1 = 0; k1 < 5; ++k1) { + for (int l1 = 0; l1 < j; ++l1) { int i2 = 2 + pos.getY() - 1; for(int j2 = i2 - 2; j2 < i2; ++j2) { diff --git a/src/main/java/teamfusion/bettas/client/ClientEvents.java b/src/main/java/teamfusion/bettas/client/ClientEvents.java new file mode 100644 index 0000000..a34b31a --- /dev/null +++ b/src/main/java/teamfusion/bettas/client/ClientEvents.java @@ -0,0 +1,27 @@ +package teamfusion.bettas.client; + +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.client.event.EntityRenderersEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; +import teamfusion.bettas.Bettas; +import teamfusion.bettas.client.model.BettaFishModel; +import teamfusion.bettas.client.renderer.BettaFishRenderer; +import teamfusion.bettas.init.BettasEntities; + +@OnlyIn(Dist.CLIENT) +@Mod.EventBusSubscriber(modid = Bettas.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD, value = Dist.CLIENT) +public class ClientEvents { + + @SubscribeEvent + public static void registerLayerDefinition(EntityRenderersEvent.RegisterLayerDefinitions event) { + event.registerLayerDefinition(BettaFishRenderer.MODEL_LAYER, BettaFishModel::createLayerDefinition); + } + + + @SubscribeEvent + public static void registerEntityRenders(EntityRenderersEvent.RegisterRenderers event) { + event.registerEntityRenderer(BettasEntities.BETTA_FISH.get(), BettaFishRenderer::new); + } +} \ No newline at end of file diff --git a/src/main/java/teamfusion/bettas/client/model/BettaFishModel.java b/src/main/java/teamfusion/bettas/client/model/BettaFishModel.java new file mode 100644 index 0000000..1359a00 --- /dev/null +++ b/src/main/java/teamfusion/bettas/client/model/BettaFishModel.java @@ -0,0 +1,70 @@ +package teamfusion.bettas.client.model; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import net.minecraft.client.model.EntityModel; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.model.geom.PartPose; +import net.minecraft.client.model.geom.builders.CubeListBuilder; +import net.minecraft.client.model.geom.builders.LayerDefinition; +import net.minecraft.client.model.geom.builders.MeshDefinition; +import net.minecraft.client.model.geom.builders.PartDefinition; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.Entity; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; + +@OnlyIn(Dist.CLIENT) +public class BettaFishModel extends EntityModel { + public ModelPart body; + public ModelPart tail; + public ModelPart finTop; + public ModelPart finBottom; + public ModelPart finLeftBottom; + public ModelPart finRightBottom; + public ModelPart finLeft; + public ModelPart finRight; + + //Constructor + public BettaFishModel(ModelPart root) { + this.body = root.getChild("body"); + this.finLeftBottom = this.body.getChild("finLeftBottom"); + this.tail = this.body.getChild("tail"); + this.finRight = this.body.getChild("finRight"); + this.finTop = this.body.getChild("finTop"); + this.finRightBottom = this.body.getChild("finRightBottom"); + this.finBottom = this.body.getChild("finBottom"); + this.finLeft = this.body.getChild("finLeft"); + } + + //Layer Definition + @SuppressWarnings("unused") + public static LayerDefinition createLayerDefinition() { + MeshDefinition meshdefinition = new MeshDefinition(); + PartDefinition root = meshdefinition.getRoot(); + PartDefinition body = root.addOrReplaceChild("body", CubeListBuilder.create().texOffs(0, 0).addBox(-1.0F, -1.5F, -3.5F, 2.0F, 3.0F, 7.0F, false), PartPose.offsetAndRotation(0.0F, 22.5F, -0.5F, 0.0F, 0.0F, 0.0F)); + PartDefinition finLeftBottom = body.addOrReplaceChild("finLeftBottom", CubeListBuilder.create().texOffs(11, 9).addBox(0.0F, 0.0F, -1.0F, 0.0F, 3.0F, 2.0F, false), PartPose.offsetAndRotation(0.5F, 1.5F, -0.5F, 0.0F, 0.0F, -0.34906584F)); + PartDefinition tail = body.addOrReplaceChild("tail", CubeListBuilder.create().texOffs(0, 6).addBox(0.0F, -3.0F, 0.0F, 0.0F, 6.0F, 4.0F, false), PartPose.offsetAndRotation(0.0F, 0.0F, 3.5F, 0.0F, 0.0F, 0.0F)); + PartDefinition finRight = body.addOrReplaceChild("finRight", CubeListBuilder.create().texOffs(-1, 1).addBox(-2.0F, 0.0F, -1.0F, 2.0F, 0.0F, 2.0F, false), PartPose.offsetAndRotation(-1.0F, 0.5F, -0.5F, 0.0F, 0.0F, -0.7853982F)); + PartDefinition finTop = body.addOrReplaceChild("finTop", CubeListBuilder.create().texOffs(0, 1).addBox(0.0F, -3.0F, -1.5F, 0.0F, 3.0F, 3.0F, false), PartPose.offsetAndRotation(0.0F, -1.5F, 2.0F, 0.0F, 0.0F, 0.0F)); + PartDefinition finRightBottom = body.addOrReplaceChild("finRightBottom", CubeListBuilder.create().texOffs(11, 9).addBox(0.0F, 0.0F, -1.0F, 0.0F, 3.0F, 2.0F, false), PartPose.offsetAndRotation(-0.5F, 1.5F, -0.5F, 0.0F, 0.0F, 0.34906584F)); + PartDefinition finBottom = body.addOrReplaceChild("finBottom", CubeListBuilder.create().texOffs(11, -6).addBox(0.0F, 0.0F, -3.0F, 0.0F, 2.0F, 6.0F, false), PartPose.offsetAndRotation(0.0F, 1.5F, 0.5F, 0.0F, 3.1415927F, 0.0F)); + PartDefinition finLeft = body.addOrReplaceChild("finLeft", CubeListBuilder.create().texOffs(-1, 3).addBox(0.0F, 0.0F, -1.0F, 2.0F, 0.0F, 2.0F, true), PartPose.offsetAndRotation(1.0F, 0.5F, -0.5F, 0.0F, 0.0F, 0.7853982F)); + return LayerDefinition.create(meshdefinition, 32, 16); + } + + @Override + public void setupAnim(T entityIn, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) { + float f = 1.0F; + if (!entityIn.isInWater()) { + f = 1.5F; + } + this.tail.yRot = -f * 0.45F * Mth.sin(0.6F * ageInTicks); + } + + @Override + public void renderToBuffer(PoseStack matrixStackIn, VertexConsumer bufferIn, int packedLightIn, int packedOverlayIn, float p_103115_, float p_103116_, float p_103117_, float p_103118_) { + body.render(matrixStackIn, bufferIn, packedLightIn, packedOverlayIn, p_103115_, p_103116_, p_103117_, p_103118_); + + } +} diff --git a/src/main/java/mod/teamdraco/bettas/client/renderer/BettaFishRenderer.java b/src/main/java/teamfusion/bettas/client/renderer/BettaFishRenderer.java similarity index 50% rename from src/main/java/mod/teamdraco/bettas/client/renderer/BettaFishRenderer.java rename to src/main/java/teamfusion/bettas/client/renderer/BettaFishRenderer.java index acff614..3bfb6e3 100644 --- a/src/main/java/mod/teamdraco/bettas/client/renderer/BettaFishRenderer.java +++ b/src/main/java/teamfusion/bettas/client/renderer/BettaFishRenderer.java @@ -1,34 +1,42 @@ -package mod.teamdraco.bettas.client.renderer; +package teamfusion.bettas.client.renderer; -import com.mojang.blaze3d.matrix.MatrixStack; -import mod.teamdraco.bettas.Bettas; -import mod.teamdraco.bettas.client.model.BettaFishModel; -import mod.teamdraco.bettas.entity.BettaFishEntity; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Vector3f; +import net.minecraft.ChatFormatting; import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.entity.EntityRendererManager; +import net.minecraft.client.model.geom.ModelLayerLocation; +import net.minecraft.client.renderer.entity.EntityRendererProvider; import net.minecraft.client.renderer.entity.MobRenderer; -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.vector.Vector3f; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Mth; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; +import teamfusion.bettas.Bettas; +import teamfusion.bettas.client.model.BettaFishModel; +import teamfusion.bettas.entity.BettaFishEntity; @OnlyIn(Dist.CLIENT) public class BettaFishRenderer extends MobRenderer> { + public static final ModelLayerLocation MODEL_LAYER = new ModelLayerLocation(new ResourceLocation(Bettas.MOD_ID, "betta"), "main"); private static final ResourceLocation[] TEXTURES = new ResourceLocation[BettaFishEntity.MAX_VARIANTS]; - public BettaFishRenderer(EntityRendererManager manager) { - super(manager, new BettaFishModel<>(), 0.2f); + private static final ResourceLocation BETO = new ResourceLocation(Bettas.MOD_ID, "textures/entity/betta/beto.png"); + + public BettaFishRenderer(EntityRendererProvider.Context manager) { + super(manager, new BettaFishModel<>(manager.bakeLayer(MODEL_LAYER)), 0.2F); + this.shadowRadius = 0.2F; } @Override public ResourceLocation getTextureLocation(BettaFishEntity entity) { + String s = ChatFormatting.stripFormatting(entity.getName().getString()); + if (s != null && ("beto".equals(s) || "Beto".equals(s))) { + return BETO; + } int variant = entity.getVariant(); - if (TEXTURES[variant] == null) - { + if (TEXTURES[variant] == null) { ResourceLocation loc = new ResourceLocation(Bettas.MOD_ID, "textures/entity/betta/body_" + variant + ".png"); - if (!Minecraft.getInstance().getResourceManager().hasResource(loc)) // todo: remove this block in 1.17, since variants won't matter on an update! - { + if (!Minecraft.getInstance().getResourceManager().getResource(loc).isPresent()) { System.out.println("Found Unknown variant " + variant + ", using default"); loc = new ResourceLocation(Bettas.MOD_ID, "textures/entity/betta/body_0.png"); } @@ -39,10 +47,11 @@ public ResourceLocation getTextureLocation(BettaFishEntity entity) { return TEXTURES[variant]; } + @Override - protected void setupRotations(BettaFishEntity entityLiving, MatrixStack matrixStackIn, float ageInTicks, float rotationYaw, float partialTicks) { + protected void setupRotations(BettaFishEntity entityLiving, PoseStack matrixStackIn, float ageInTicks, float rotationYaw, float partialTicks) { super.setupRotations(entityLiving, matrixStackIn, ageInTicks, rotationYaw, partialTicks); - float f = 4.3F * MathHelper.sin(0.6F * ageInTicks); + float f = 4.3F * Mth.sin(0.6F * ageInTicks); matrixStackIn.mulPose(Vector3f.YP.rotationDegrees(f)); if (!entityLiving.isInWater()) { matrixStackIn.translate(0.2d, 0.1d, 0); diff --git a/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java b/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java new file mode 100644 index 0000000..dca3fbb --- /dev/null +++ b/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java @@ -0,0 +1,280 @@ +package teamfusion.bettas.entity; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.network.syncher.EntityDataSerializers; +import net.minecraft.network.syncher.SynchedEntityData; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.util.Mth; +import net.minecraft.util.RandomSource; +import net.minecraft.world.DifficultyInstance; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.MobSpawnType; +import net.minecraft.world.entity.SpawnGroupData; +import net.minecraft.world.entity.ai.attributes.AttributeSupplier; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.ai.goal.MeleeAttackGoal; +import net.minecraft.world.entity.ai.goal.RandomSwimmingGoal; +import net.minecraft.world.entity.ai.goal.target.HurtByTargetGoal; +import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal; +import net.minecraft.world.entity.animal.AbstractFish; +import net.minecraft.world.entity.animal.Bucketable; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.projectile.AbstractArrow; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.ServerLevelAccessor; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.phys.HitResult; +import net.minecraft.world.phys.Vec3; +import teamfusion.bettas.block.MossBallBlock; +import teamfusion.bettas.init.BettasBlocks; +import teamfusion.bettas.init.BettasEntities; +import teamfusion.bettas.init.BettasItems; + +import javax.annotation.Nullable; +import java.util.List; +import java.util.function.Predicate; + +public class BettaFishEntity extends AbstractFish implements Bucketable { + public static final int MAX_VARIANTS = 120; + private static final EntityDataAccessor VARIANT = SynchedEntityData.defineId(BettaFishEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor FROM_BUCKET = SynchedEntityData.defineId(BettaFishEntity.class, EntityDataSerializers.BOOLEAN); + private static final EntityDataAccessor CALMED = SynchedEntityData.defineId(BettaFishEntity.class, EntityDataSerializers.BOOLEAN); + + static final Predicate CALMED_ENTITY = (p_28528_) -> { + return p_28528_.isCalmed() && p_28528_.isAlive(); + }; + + public BettaFishEntity(EntityType type, Level worldIn) { + super(type, worldIn); + } + + protected void registerGoals() { + this.goalSelector.addGoal(0, new MeleeAttackGoal(this, 2.0D, true)); + this.goalSelector.addGoal(1, new RandomSwimmingGoal(this, 1.0D, 20)); + this.targetSelector.addGoal(0, new HurtByTargetGoal(this)); + this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, BettaFishEntity.class, false) { + @Override + public boolean canUse() { + return isFromBucket() && !isCalmed() && super.canUse(); + } + + + @Override + public boolean canContinueToUse() { + return !isCalmed() && super.canContinueToUse(); + } + }); + + } + + private boolean isFromBucket() { + return this.entityData.get(FROM_BUCKET); + } + + public void setFromBucket(boolean p_203706_1_) { + this.entityData.set(FROM_BUCKET, p_203706_1_); + } + + public boolean isCalmed() { + return this.entityData.get(CALMED); + } + + public void setCalmed(boolean calmed) { + this.entityData.set(CALMED, calmed); + } + + + @Override + protected void defineSynchedData() { + super.defineSynchedData(); + this.entityData.define(VARIANT, 0); + this.entityData.define(FROM_BUCKET, false); + this.entityData.define(CALMED, false); + } + + public static AttributeSupplier.Builder createAttributes() { + return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 6.0D).add(Attributes.ATTACK_DAMAGE, 1.0D); + } + + public static boolean checkBettaFishSpawnRules(EntityType type, BlockGetter worldIn, MobSpawnType reason, BlockPos p_223363_3_, RandomSource randomIn) { + return worldIn.getBlockState(p_223363_3_).is(Blocks.WATER) && worldIn.getBlockState(p_223363_3_.above()).is(Blocks.WATER) && randomIn.nextFloat() > 0.9; + } + + public boolean hurt(DamageSource source, float amount) { + if (this.isInvulnerableTo(source)) { + return false; + } else { + Entity entity = source.getEntity(); + if (entity != null && !(entity instanceof Player) && !(entity instanceof AbstractArrow)) { + amount = (amount + 1.0F) / 2.0F; + } + + return super.hurt(source, amount); + } + } + + public boolean doHurtTarget(Entity entityIn) { + boolean flag = entityIn.hurt(DamageSource.mobAttack(this), (float) ((int) this.getAttributeValue(Attributes.ATTACK_DAMAGE))); + if (flag) { + this.doEnchantDamageEffects(this, entityIn); + } + + return flag; + } + + public int getVariant() { + return this.entityData.get(VARIANT); + } + + private void setVariant(int variant) { + this.entityData.set(VARIANT, variant); + } + + public boolean removeWhenFarAway(double distanceToClosestPlayer) { + return !this.isFromBucket() && !this.hasCustomName(); + } + + public boolean requiresCustomPersistence() { + return super.requiresCustomPersistence() || this.isFromBucket(); + } + + @Override + public void tick() { + super.tick(); + + if (!this.level.isClientSide()) { + if (isFromBucket() && isMossBallNearby(true) && !isCalmed()) { + + this.setCalmed(true); + } else if (isCalmed() && !isMossBallNearby(false)) { + this.setCalmed(false); + } + } + } + + private boolean isMossBallNearby(boolean afterCheck) { + boolean flag = false; + int mossCount = afterCheck ? 0 : 1; + BlockPos blockpos = this.blockPosition(); + BlockPos.MutableBlockPos blockpos$mutable = new BlockPos.MutableBlockPos(); + + for (int i = 0; i < 8; ++i) { + for (int j = 0; j < 8; ++j) { + for (int k = 0; k <= j; k = k > 0 ? -k : 1 - k) { + for (int l = k < j && k > -j ? j : 0; l <= j; l = l > 0 ? -l : 1 - l) { + blockpos$mutable.setWithOffset(blockpos, k, i, l); + if (this.level.getBlockState(blockpos$mutable).is(BettasBlocks.MOSS_BALL.get())) { + flag = true; + mossCount += this.level.getBlockState(blockpos$mutable).getValue(MossBallBlock.BALLS); + } else if (this.level.getBlockState(blockpos$mutable).is(BettasBlocks.MOSS_BALL_BLOCK.get())) { + flag = true; + mossCount += 8; + } + } + } + } + } + if (flag) { + List list = this.level.getEntities(BettasEntities.BETTA_FISH.get(), this.getBoundingBox().inflate(8.0D), CALMED_ENTITY); + + if (list.isEmpty() || list.size() < 2 * mossCount) { + return true; + } + } + return false; + } + + @Override + public void addAdditionalSaveData(CompoundTag compound) { + super.addAdditionalSaveData(compound); + compound.putInt("Variant", getVariant()); + compound.putBoolean("FromBucket", this.isFromBucket()); + compound.putBoolean("Calmed", this.isCalmed()); + } + + @Override + public void readAdditionalSaveData(CompoundTag compound) { + super.readAdditionalSaveData(compound); + setVariant(Mth.clamp(compound.getInt("Variant"), 0, MAX_VARIANTS - 1)); + this.setFromBucket(compound.getBoolean("FromBucket")); + this.setCalmed(compound.getBoolean("Calmed")); + } + + @Nullable + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor worldIn, DifficultyInstance difficultyIn, MobSpawnType reason, @Nullable SpawnGroupData spawnDataIn, @Nullable CompoundTag dataTag) { + if (dataTag == null) { + double chance = getRandom().nextDouble(); + if (chance <= 0.45) setVariant(getRandom().nextInt(MAX_VARIANTS)); + else if (chance <= 0.7) setVariant(24); + else setVariant(100); + } else { + if (dataTag.contains("Variant", 3)) { + this.setVariant(dataTag.getInt("Variant")); + } + if (dataTag.contains("Health", 99)) { + this.setHealth(dataTag.getFloat("Health")); + } + } + return super.finalizeSpawn(worldIn, difficultyIn, reason, spawnDataIn, dataTag); + } + + public void saveToBucketTag(ItemStack bucket) { + CompoundTag compoundnbt = bucket.getOrCreateTag(); + compoundnbt.putInt("Variant", this.getVariant()); + compoundnbt.putFloat("Health", this.getHealth()); + } + + @Override + public ItemStack getBucketItemStack() { + return new ItemStack(BettasItems.BETTA_FISH_BUCKET.get()); + } + + @Override + protected SoundEvent getFlopSound() { + return SoundEvents.COD_FLOP; + } + + protected SoundEvent getDeathSound() { + return SoundEvents.COD_DEATH; + } + + protected SoundEvent getHurtSound(DamageSource damageSourceIn) { + return SoundEvents.COD_HURT; + } + + @Override + public ItemStack getPickedResult(HitResult result) { + return new ItemStack(BettasItems.BETTA_FISH_SPAWN_EGG.get()); + } + + @Override + public InteractionResult interactAt(Player player, Vec3 vec, InteractionHand hand) { + ItemStack stack = player.getItemInHand(hand); + float maxHealth = this.getMaxHealth(); + float health = this.getHealth(); + if (stack.getItem() == BettasItems.BLACKWATER_BOTTLE.get() && health < maxHealth) { + if (!player.isCreative()) { + stack.shrink(1); + } + heal(3); + double d0 = this.random.nextGaussian() * 0.02D; + double d1 = this.random.nextGaussian() * 0.02D; + double d2 = this.random.nextGaussian() * 0.02D; + this.level.addParticle(ParticleTypes.HEART, this.getRandomX(1.0D), this.getRandomY() + 0.5D, this.getRandomZ(1.0D), d0, d1, d2); + return InteractionResult.PASS; + } + return super.interactAt(player, vec, hand); + } +} \ No newline at end of file diff --git a/src/main/java/teamfusion/bettas/feature/MossBallFeature.java b/src/main/java/teamfusion/bettas/feature/MossBallFeature.java new file mode 100644 index 0000000..bd5dcba --- /dev/null +++ b/src/main/java/teamfusion/bettas/feature/MossBallFeature.java @@ -0,0 +1,45 @@ +package teamfusion.bettas.feature; + +import com.mojang.serialization.Codec; +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.SeaPickleBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.level.levelgen.feature.Feature; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.CountConfiguration; +import teamfusion.bettas.init.BettasBlocks; + +public class MossBallFeature extends Feature { + + public MossBallFeature(Codec p_i231987_1_) { + super(p_i231987_1_); + } + + public boolean place(FeaturePlaceContext context) { + WorldGenLevel reader = context.level(); + RandomSource rand = context.random(); + CountConfiguration config = context.config(); + BlockPos pos = context.origin(); + + int i = 0; + int j = config.count().sample(rand); + + for(int k = 0; k < j; ++k) { + int l = rand.nextInt(8) - rand.nextInt(8); + int i1 = rand.nextInt(8) - rand.nextInt(8); + int j1 = reader.getHeight(Heightmap.Types.OCEAN_FLOOR, pos.getX() + l, pos.getZ() + i1); + BlockPos blockpos = new BlockPos(pos.getX() + l, j1, pos.getZ() + i1); + BlockState blockstate = BettasBlocks.MOSS_BALL.get().defaultBlockState().setValue(SeaPickleBlock.PICKLES, Integer.valueOf(rand.nextInt(4) + 1)); + if (reader.getBlockState(blockpos).is(Blocks.WATER) && blockstate.canSurvive(reader, blockpos)) { + reader.setBlock(blockpos, blockstate, 2); + ++i; + } + } + + return i > 0; + } +} diff --git a/src/main/java/teamfusion/bettas/init/BettaBiomeModifiers.java b/src/main/java/teamfusion/bettas/init/BettaBiomeModifiers.java new file mode 100644 index 0000000..360d4dd --- /dev/null +++ b/src/main/java/teamfusion/bettas/init/BettaBiomeModifiers.java @@ -0,0 +1,16 @@ +package teamfusion.bettas.init; + +import com.mojang.serialization.Codec; +import net.minecraftforge.common.world.BiomeModifier; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.RegistryObject; +import teamfusion.bettas.Bettas; +import teamfusion.bettas.biome.BettaBiomeModifier; + +public class BettaBiomeModifiers { + public static final DeferredRegister> BIOME_MODIFIER_SERIALIZERS = DeferredRegister.create(ForgeRegistries.Keys.BIOME_MODIFIER_SERIALIZERS, Bettas.MOD_ID); + + public static final RegistryObject> BETTA_BIOME_MODIFIER_TYPE = BIOME_MODIFIER_SERIALIZERS.register("betta_biome_modifier", () -> Codec.unit(BettaBiomeModifier.INSTANCE)); + +} diff --git a/src/main/java/teamfusion/bettas/init/BettasBlocks.java b/src/main/java/teamfusion/bettas/init/BettasBlocks.java new file mode 100644 index 0000000..560062e --- /dev/null +++ b/src/main/java/teamfusion/bettas/init/BettasBlocks.java @@ -0,0 +1,21 @@ +package teamfusion.bettas.init; + +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.material.Material; +import net.minecraft.world.level.material.MaterialColor; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.RegistryObject; +import teamfusion.bettas.Bettas; +import teamfusion.bettas.block.DriedLeavesBlock; +import teamfusion.bettas.block.MossBallBlock; + +public class BettasBlocks { + public static final DeferredRegister BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, Bettas.MOD_ID); + + public static final RegistryObject MOSS_BALL = BLOCKS.register("moss_ball", () -> new MossBallBlock(BlockBehaviour.Properties.of(Material.DECORATION, MaterialColor.COLOR_GREEN).sound(SoundType.WET_GRASS).strength(0).noOcclusion())); + public static final RegistryObject MOSS_BALL_BLOCK = BLOCKS.register("moss_ball_block", () -> new Block(BlockBehaviour.Properties.of(Material.GRASS, MaterialColor.COLOR_GREEN).sound(SoundType.WET_GRASS).strength(0.5f))); + public static final RegistryObject DRIED_LEAVES = BLOCKS.register("dried_leaves", () -> new DriedLeavesBlock(BlockBehaviour.Properties.of(Material.DECORATION, MaterialColor.COLOR_ORANGE).sound(SoundType.GRASS).strength(0).noOcclusion())); +} diff --git a/src/main/java/teamfusion/bettas/init/BettasConfiguredFeatures.java b/src/main/java/teamfusion/bettas/init/BettasConfiguredFeatures.java new file mode 100644 index 0000000..f419fe9 --- /dev/null +++ b/src/main/java/teamfusion/bettas/init/BettasConfiguredFeatures.java @@ -0,0 +1,16 @@ +package teamfusion.bettas.init; + +import net.minecraft.core.Registry; +import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; +import net.minecraft.world.level.levelgen.feature.configurations.CountConfiguration; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.RegistryObject; +import teamfusion.bettas.Bettas; + +public class BettasConfiguredFeatures { + + public static final DeferredRegister> CONFIGURED_FEATURES = DeferredRegister.create(Registry.CONFIGURED_FEATURE_REGISTRY, Bettas.MOD_ID); + + public static final RegistryObject> CONFIGURED_MOSS_BALLS = CONFIGURED_FEATURES.register("moss_balls", () -> new ConfiguredFeature<>(BettasFeatures.MOSS_BALL.get(), new CountConfiguration(4))); + +} diff --git a/src/main/java/teamfusion/bettas/init/BettasEntities.java b/src/main/java/teamfusion/bettas/init/BettasEntities.java new file mode 100644 index 0000000..6751f05 --- /dev/null +++ b/src/main/java/teamfusion/bettas/init/BettasEntities.java @@ -0,0 +1,20 @@ +package teamfusion.bettas.init; + +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.MobCategory; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.RegistryObject; +import teamfusion.bettas.Bettas; +import teamfusion.bettas.entity.BettaFishEntity; + +public class BettasEntities { + public static final DeferredRegister> ENTITIES = DeferredRegister.create(ForgeRegistries.ENTITY_TYPES, Bettas.MOD_ID); + + public static final RegistryObject> BETTA_FISH = create("betta_fish", EntityType.Builder.of(BettaFishEntity::new, MobCategory.WATER_AMBIENT).sized(0.3f, 0.3f)); + + private static RegistryObject> create(String name, EntityType.Builder builder) { + return ENTITIES.register(name, () -> builder.build(Bettas.MOD_ID + "." + name)); + } +} \ No newline at end of file diff --git a/src/main/java/teamfusion/bettas/init/BettasFeatures.java b/src/main/java/teamfusion/bettas/init/BettasFeatures.java new file mode 100644 index 0000000..5ff93fc --- /dev/null +++ b/src/main/java/teamfusion/bettas/init/BettasFeatures.java @@ -0,0 +1,16 @@ +package teamfusion.bettas.init; + +import net.minecraft.world.level.levelgen.feature.Feature; +import net.minecraft.world.level.levelgen.feature.configurations.CountConfiguration; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.RegistryObject; +import teamfusion.bettas.Bettas; +import teamfusion.bettas.feature.MossBallFeature; + +public class BettasFeatures { + public static final DeferredRegister> FEATURES = DeferredRegister.create(ForgeRegistries.FEATURES, Bettas.MOD_ID); + + public static final RegistryObject> MOSS_BALL = FEATURES.register("moss_ball", () -> new MossBallFeature(CountConfiguration.CODEC)); + +} \ No newline at end of file diff --git a/src/main/java/teamfusion/bettas/init/BettasItems.java b/src/main/java/teamfusion/bettas/init/BettasItems.java new file mode 100644 index 0000000..69ba26f --- /dev/null +++ b/src/main/java/teamfusion/bettas/init/BettasItems.java @@ -0,0 +1,36 @@ +package teamfusion.bettas.init; + +import net.minecraft.world.food.FoodProperties; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.material.Fluids; +import net.minecraftforge.common.ForgeSpawnEggItem; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.RegistryObject; +import teamfusion.bettas.Bettas; +import teamfusion.bettas.item.BettasBucketItem; + +public class BettasItems { + public static final DeferredRegister ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, Bettas.MOD_ID); + + public static final CreativeModeTab BETTA_TAB = new CreativeModeTab(Bettas.MOD_ID) { + @Override + public ItemStack makeIcon() { + return new ItemStack(BettasItems.BETTA_FISH.get()); + } + }; + + public static final RegistryObject BETTA_FISH = ITEMS.register("betta_fish", () -> new Item(new Item.Properties().tab(BETTA_TAB).food(new FoodProperties.Builder().nutrition(1).saturationMod(0.1F).build()))); + public static final RegistryObject BETTA_FISH_BUCKET = ITEMS.register("betta_fish_bucket", () -> new BettasBucketItem(BettasEntities.BETTA_FISH, () -> Fluids.WATER, Items.BUCKET, false, new Item.Properties().tab(BETTA_TAB).stacksTo(1))); + public static final RegistryObject BLACKWATER_BOTTLE = ITEMS.register("blackwater_bottle", () -> new Item(new Item.Properties().tab(BETTA_TAB).stacksTo(1))); + + public static final RegistryObject BETTA_FISH_SPAWN_EGG = ITEMS.register("betta_fish_spawn_egg", () -> new ForgeSpawnEggItem(BettasEntities.BETTA_FISH, 0x613d2a, 0x2dceff, new Item.Properties().tab(BETTA_TAB))); + + public static final RegistryObject MOSS_BALL = ITEMS.register("moss_ball", () -> new BlockItem(BettasBlocks.MOSS_BALL.get(), new Item.Properties().tab(BETTA_TAB))); + public static final RegistryObject MOSS_BALL_BLOCK = ITEMS.register("moss_ball_block", () -> new BlockItem(BettasBlocks.MOSS_BALL_BLOCK.get(), new Item.Properties().tab(BETTA_TAB))); + public static final RegistryObject DRIED_LEAVES = ITEMS.register("dried_leaves", () -> new BlockItem(BettasBlocks.DRIED_LEAVES.get(), new Item.Properties().tab(BETTA_TAB))); +} \ No newline at end of file diff --git a/src/main/java/teamfusion/bettas/init/BettasPlacedFeatures.java b/src/main/java/teamfusion/bettas/init/BettasPlacedFeatures.java new file mode 100644 index 0000000..4d59b64 --- /dev/null +++ b/src/main/java/teamfusion/bettas/init/BettasPlacedFeatures.java @@ -0,0 +1,16 @@ +package teamfusion.bettas.init; + +import net.minecraft.core.Registry; +import net.minecraft.data.worldgen.placement.VegetationPlacements; +import net.minecraft.world.level.levelgen.placement.PlacedFeature; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.RegistryObject; +import teamfusion.bettas.Bettas; + +public class BettasPlacedFeatures { + + public static final DeferredRegister PLACED_FEATURES = DeferredRegister.create(Registry.PLACED_FEATURE_REGISTRY, Bettas.MOD_ID); + + public static final RegistryObject PLACED_MOSS_BALLS = PLACED_FEATURES.register("placed_moss_balls", () -> new PlacedFeature(BettasConfiguredFeatures.CONFIGURED_MOSS_BALLS.getHolder().orElseThrow(), VegetationPlacements.worldSurfaceSquaredWithCount(2))); + +} diff --git a/src/main/java/teamfusion/bettas/item/BettasBucketItem.java b/src/main/java/teamfusion/bettas/item/BettasBucketItem.java new file mode 100644 index 0000000..fd1d4db --- /dev/null +++ b/src/main/java/teamfusion/bettas/item/BettasBucketItem.java @@ -0,0 +1,105 @@ +package teamfusion.bettas.item; + +import net.minecraft.ChatFormatting; +import net.minecraft.advancements.CriteriaTriggers; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.network.chat.Component; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.stats.Stats; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResultHolder; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.MobSpawnType; +import net.minecraft.world.entity.animal.AbstractFish; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.BucketItem; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.level.ClipContext; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.LiquidBlockContainer; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.Fluid; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.event.ForgeEventFactory; + +import javax.annotation.Nullable; +import java.util.List; +import java.util.function.Supplier; + +public class BettasBucketItem extends BucketItem { + private final boolean hasTooltip; + private final Supplier fluid; + @SuppressWarnings("unused") + private final Item item; + + public BettasBucketItem(Supplier> entityType, Supplier fluid, Item item, boolean hasTooltip, Properties builder) { + super(fluid, builder); + this.fluid = fluid; + this.hasTooltip = hasTooltip; + this.entityTypeSupplier = entityType; + this.item = item; + } + + @SuppressWarnings("static-access") + @Override + public InteractionResultHolder use(Level worldIn, Player playerIn, InteractionHand handIn) { + ItemStack itemstack = playerIn.getItemInHand(handIn); + BlockHitResult raytraceresult = getPlayerPOVHitResult(worldIn, playerIn, ClipContext.Fluid.NONE); + InteractionResultHolder ret = ForgeEventFactory.onBucketUse(playerIn, worldIn, itemstack, raytraceresult); + if (ret != null) return ret; + if (raytraceresult.getType() == BlockHitResult.Type.MISS) { + return InteractionResultHolder.pass(itemstack); + } else if (raytraceresult.getType() != BlockHitResult.Type.BLOCK) { + return InteractionResultHolder.pass(itemstack); + } else { + BlockPos blockpos = raytraceresult.getBlockPos(); + Direction direction = raytraceresult.getDirection(); + BlockPos blockpos1 = blockpos.relative(direction); + if (worldIn.mayInteract(playerIn, blockpos) && playerIn.mayUseItemAt(blockpos1, direction, itemstack)) { + BlockState blockstate = worldIn.getBlockState(blockpos); + BlockPos blockpos2 = blockstate.getBlock() instanceof LiquidBlockContainer && ((LiquidBlockContainer) blockstate.getBlock()).canPlaceLiquid(worldIn, blockpos, blockstate, fluid.get()) ? blockpos : blockpos1; + this.emptyContents(playerIn, worldIn, blockpos2, raytraceresult); + if (worldIn instanceof ServerLevel) this.placeEntity((ServerLevel)worldIn, itemstack, blockpos2); + if (playerIn instanceof ServerPlayer) { + CriteriaTriggers.PLACED_BLOCK.trigger((ServerPlayer) playerIn, blockpos2, itemstack); + } + + playerIn.awardStat(Stats.ITEM_USED.get(this)); + return InteractionResultHolder.sidedSuccess(this.getEmptySuccessItem(itemstack, playerIn), worldIn.isClientSide()); + } else { + return InteractionResultHolder.fail(itemstack); + } + } + } + + @OnlyIn(Dist.CLIENT) + @Override + public void appendHoverText(ItemStack stack, @Nullable Level world, List tooltip, TooltipFlag flag) { + super.appendHoverText(stack, world, tooltip, flag); + if (hasTooltip && stack.hasTag()) { + tooltip.add(Component.translatable(getEntityType().getDescriptionId() + "." + stack.getTag().getInt("Variant")).withStyle(ChatFormatting.GRAY).withStyle(ChatFormatting.ITALIC)); + } + } + + private void placeEntity(ServerLevel worldIn, ItemStack stack, BlockPos pos) { + Entity entity = this.entityTypeSupplier.get().spawn(worldIn, stack, null, pos, MobSpawnType.BUCKET, true, false); + if (entity != null) { + if (entity instanceof AbstractFish) { + ((AbstractFish)entity).setFromBucket(true); + } + } + } + + private final Supplier> entityTypeSupplier; + + protected EntityType getEntityType() { + return entityTypeSupplier.get(); + } +} diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index 19bde7d..0752e36 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -1,10 +1,10 @@ -modLoader="javafml" #mandatory -loaderVersion="[35,)" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions. -license="All rights reserved" +modLoader = "javafml" #mandatory +loaderVersion = "[43,)" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions. +license = "All rights reserved" [[mods]] #mandatory -modId="bettas" #mandatory -version="${file.jarVersion}" #mandatory -displayName="Bettas" #mandatory -credits="Coda (code), Tazz (art) & Ninni (art)" #optional -authors="Team Draco" #optional -description='''A small mod containing a new fish: the betta! Bettas can be bucketed just like normal fish and will fight and kill eachother.''' +modId = "bettas" #mandatory +version = "1.0.0" #mandatory +displayName = "Bettas" #mandatory +credits = "Tazz, Ninni" #optional +authors = "Coda, superlord9362, bagu_chan, Team Fusion" #optional +description = '''A small mod containing a new fish: the betta! Bettas can be bucketed just like normal fish and will fight and kill eachother.''' diff --git a/src/main/resources/assets/bettas/lang/en_us.json b/src/main/resources/assets/bettas/lang/en_us.json index 2d123b8..48ca62f 100644 --- a/src/main/resources/assets/bettas/lang/en_us.json +++ b/src/main/resources/assets/bettas/lang/en_us.json @@ -2,11 +2,13 @@ "entity.bettas.betta_fish": "Betta Fish", "item.bettas.betta_fish": "Betta Fish", - "item.bettas.betta_fish_bucket": "Betta Fish Bucket", + "item.bettas.betta_fish_bucket": "Bucket of Betta Fish", "item.bettas.betta_fish_spawn_egg": "Betta Fish Spawn Egg", "item.bettas.blackwater_bottle": "Blackwater Bottle", "block.bettas.moss_ball": "Moss Ball", "block.bettas.moss_ball_block": "Block of Moss Balls", - "block.bettas.dried_leaves": "Dried Leaves" + "block.bettas.dried_leaves": "Dried Leaves", + + "itemGroup.bettas": "Bettas" } \ No newline at end of file diff --git a/src/main/resources/assets/bettas/models/block/heavily_piled_dried_leaves.json b/src/main/resources/assets/bettas/models/block/heavily_piled_dried_leaves.json index 0a22525..1f2f5f1 100644 --- a/src/main/resources/assets/bettas/models/block/heavily_piled_dried_leaves.json +++ b/src/main/resources/assets/bettas/models/block/heavily_piled_dried_leaves.json @@ -1,14 +1,32 @@ { - "textures": { - "dried": "bettas:block/heavily_piled_dried_leaves", - "particle": "bettas:block/heavily_piled_dried_leaves" - }, - "elements": [ - { - "from": [0, 0, 0], - "to": [16, 5, 16], - "faces": { - "north": {"uv": [0, 0, 16, 5], "texture": "#dried", "cullface": "north" }, + "render_type": "cutout", + "textures": { + "dried": "bettas:block/heavily_piled_dried_leaves", + "particle": "bettas:block/heavily_piled_dried_leaves" + }, + "elements": [ + { + "from": [ + 0, + 0, + 0 + ], + "to": [ + 16, + 5, + 16 + ], + "faces": { + "north": { + "uv": [ + 0, + 0, + 16, + 5 + ], + "texture": "#dried", + "cullface": "north" + }, "east": {"uv": [0, 0, 16, 5], "texture": "#dried", "cullface": "east"}, "south": {"uv": [0, 0, 16, 5], "texture": "#dried", "cullface": "south"}, "west": {"uv": [0, 0, 16, 5], "texture": "#dried", "cullface": "west"}, diff --git a/src/main/resources/assets/bettas/models/block/loosely_piled_dried_leaves.json b/src/main/resources/assets/bettas/models/block/loosely_piled_dried_leaves.json index 9ec3dfb..fbeb6ae 100644 --- a/src/main/resources/assets/bettas/models/block/loosely_piled_dried_leaves.json +++ b/src/main/resources/assets/bettas/models/block/loosely_piled_dried_leaves.json @@ -1,14 +1,32 @@ { - "textures": { - "particle": "bettas:block/loosely_piled_dried_leaves", - "dried": "bettas:block/loosely_piled_dried_leaves" - }, - "elements": [ - { - "from": [0, 0, 0], - "to": [16, 2, 16], - "faces": { - "north": {"uv": [0, 0, 16, 2], "texture": "#dried", "cullface": "north" }, + "render_type": "cutout", + "textures": { + "particle": "bettas:block/loosely_piled_dried_leaves", + "dried": "bettas:block/loosely_piled_dried_leaves" + }, + "elements": [ + { + "from": [ + 0, + 0, + 0 + ], + "to": [ + 16, + 2, + 16 + ], + "faces": { + "north": { + "uv": [ + 0, + 0, + 16, + 2 + ], + "texture": "#dried", + "cullface": "north" + }, "east": {"uv": [0, 0, 16, 2], "texture": "#dried", "cullface": "east"}, "south": {"uv": [0, 0, 16, 2], "texture": "#dried", "cullface": "south"}, "west": {"uv": [0, 0, 16, 2], "texture": "#dried", "cullface": "west"}, diff --git a/src/main/resources/assets/bettas/models/block/moss_balls_four.json b/src/main/resources/assets/bettas/models/block/moss_balls_four.json index 77d3fca..f2558b9 100644 --- a/src/main/resources/assets/bettas/models/block/moss_balls_four.json +++ b/src/main/resources/assets/bettas/models/block/moss_balls_four.json @@ -1,60 +1,55 @@ { - "ambientocclusion": false, "textures": { "0": "bettas:block/moss_ball", "particle": "bettas:block/moss_ball" }, "elements": [ { - "from": [9, 0, 9], - "to": [16, 7, 16], - "rotation": {"angle": 0, "axis": "y", "origin": [17, 8, 17]}, + "from": [2, 0, 3], + "to": [8, 6, 9], "faces": { - "north": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "east": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "south": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "west": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "up": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "down": {"uv": [9, 9, 16, 16], "texture": "#0"} + "north": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "east": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "south": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "west": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "up": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "down": {"uv": [0, 10, 6, 16], "texture": "#0"} } }, { - "from": [9, 0, 1], - "to": [15, 6, 7], - "rotation": {"angle": 0, "axis": "y", "origin": [17, 8, 9]}, + "from": [9, 0, 9], + "to": [15, 6, 15], "faces": { - "north": {"uv": [0, 0, 6, 6], "texture": "#0"}, - "east": {"uv": [0, 0, 6, 6], "texture": "#0"}, - "south": {"uv": [0, 0, 6, 6], "texture": "#0"}, - "west": {"uv": [0, 0, 6, 6], "texture": "#0"}, - "up": {"uv": [0, 0, 6, 6], "texture": "#0"}, - "down": {"uv": [0, 0, 6, 6], "texture": "#0"} + "north": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "east": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "south": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "west": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "up": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "down": {"uv": [0, 10, 6, 16], "texture": "#0"} } }, { - "from": [2, 0, 0], - "to": [6, 4, 4], - "rotation": {"angle": 0, "axis": "y", "origin": [10, 8, 8]}, + "from": [1, 0, 10], + "to": [6, 5, 15], "faces": { - "north": {"uv": [0, 7, 4, 11], "texture": "#0"}, - "east": {"uv": [0, 7, 4, 11], "texture": "#0"}, - "south": {"uv": [0, 7, 4, 11], "texture": "#0"}, - "west": {"uv": [0, 7, 4, 11], "texture": "#0"}, - "up": {"uv": [0, 7, 4, 11], "texture": "#0"}, - "down": {"uv": [0, 7, 4, 11], "texture": "#0"} + "north": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "east": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "south": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "west": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "up": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "down": {"uv": [7, 11, 12, 16], "texture": "#0"} } }, { - "from": [1, 0, 5], - "to": [9, 8, 13], - "rotation": {"angle": 0, "axis": "y", "origin": [10, 8, 14]}, + "from": [9, 0, 2], + "to": [14, 5, 7], "faces": { - "north": {"uv": [8, 0, 16, 8], "texture": "#0"}, - "east": {"uv": [8, 0, 16, 8], "texture": "#0"}, - "south": {"uv": [8, 0, 16, 8], "texture": "#0"}, - "west": {"uv": [8, 0, 16, 8], "texture": "#0"}, - "up": {"uv": [8, 0, 16, 8], "texture": "#0"}, - "down": {"uv": [8, 0, 16, 8], "texture": "#0"} + "north": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "east": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "south": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "west": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "up": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "down": {"uv": [7, 11, 12, 16], "texture": "#0"} } } ] diff --git a/src/main/resources/assets/bettas/models/block/moss_balls_four_alter.json b/src/main/resources/assets/bettas/models/block/moss_balls_four_alter.json new file mode 100644 index 0000000..3d4fbd1 --- /dev/null +++ b/src/main/resources/assets/bettas/models/block/moss_balls_four_alter.json @@ -0,0 +1,56 @@ +{ + "textures": { + "0": "bettas:block/moss_ball", + "particle": "bettas:block/moss_ball" + }, + "elements": [ + { + "from": [1, 0, 8], + "to": [7, 6, 14], + "faces": { + "north": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "east": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "south": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "west": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "up": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "down": {"uv": [0, 10, 6, 16], "texture": "#0"} + } + }, + { + "from": [9, 0, 3], + "to": [15, 6, 9], + "faces": { + "north": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "east": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "south": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "west": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "up": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "down": {"uv": [0, 10, 6, 16], "texture": "#0"} + } + }, + { + "from": [1, 0, 2], + "to": [6, 5, 7], + "faces": { + "north": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "east": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "south": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "west": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "up": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "down": {"uv": [7, 11, 12, 16], "texture": "#0"} + } + }, + { + "from": [9, 0, 10], + "to": [14, 5, 15], + "faces": { + "north": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "east": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "south": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "west": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "up": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "down": {"uv": [7, 11, 12, 16], "texture": "#0"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/bettas/models/block/moss_balls_one.json b/src/main/resources/assets/bettas/models/block/moss_balls_one.json index 59d51a3..ea28ba2 100644 --- a/src/main/resources/assets/bettas/models/block/moss_balls_one.json +++ b/src/main/resources/assets/bettas/models/block/moss_balls_one.json @@ -1,21 +1,19 @@ { - "ambientocclusion": false, "textures": { "0": "bettas:block/moss_ball", "particle": "bettas:block/moss_ball" }, "elements": [ { - "from": [9, 0, 9], - "to": [16, 7, 16], - "rotation": {"angle": 0, "axis": "y", "origin": [17, 8, 17]}, + "from": [9, 0, 2], + "to": [14, 5, 7], "faces": { - "north": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "east": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "south": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "west": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "up": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "down": {"uv": [9, 9, 16, 16], "texture": "#0"} + "north": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "east": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "south": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "west": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "up": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "down": {"uv": [7, 11, 12, 16], "texture": "#0"} } } ] diff --git a/src/main/resources/assets/bettas/models/block/moss_balls_one_alter.json b/src/main/resources/assets/bettas/models/block/moss_balls_one_alter.json new file mode 100644 index 0000000..ab3a0b6 --- /dev/null +++ b/src/main/resources/assets/bettas/models/block/moss_balls_one_alter.json @@ -0,0 +1,20 @@ +{ + "textures": { + "0": "bettas:block/moss_ball", + "particle": "bettas:block/moss_ball" + }, + "elements": [ + { + "from": [1, 0, 2], + "to": [6, 5, 7], + "faces": { + "north": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "east": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "south": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "west": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "up": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "down": {"uv": [7, 11, 12, 16], "texture": "#0"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/bettas/models/block/moss_balls_three.json b/src/main/resources/assets/bettas/models/block/moss_balls_three.json index 2b0d6bd..8a42b97 100644 --- a/src/main/resources/assets/bettas/models/block/moss_balls_three.json +++ b/src/main/resources/assets/bettas/models/block/moss_balls_three.json @@ -1,47 +1,43 @@ { - "ambientocclusion": false, "textures": { "0": "bettas:block/moss_ball", "particle": "bettas:block/moss_ball" }, "elements": [ { - "from": [9, 0, 9], - "to": [16, 7, 16], - "rotation": {"angle": 0, "axis": "y", "origin": [17, 8, 17]}, + "from": [2, 0, 3], + "to": [8, 6, 9], "faces": { - "north": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "east": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "south": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "west": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "up": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "down": {"uv": [9, 9, 16, 16], "texture": "#0"} + "north": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "east": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "south": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "west": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "up": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "down": {"uv": [0, 10, 6, 16], "texture": "#0"} } }, { - "from": [9, 0, 1], - "to": [15, 6, 7], - "rotation": {"angle": 0, "axis": "y", "origin": [17, 8, 9]}, + "from": [1, 0, 10], + "to": [6, 5, 15], "faces": { - "north": {"uv": [0, 0, 6, 6], "texture": "#0"}, - "east": {"uv": [0, 0, 6, 6], "texture": "#0"}, - "south": {"uv": [0, 0, 6, 6], "texture": "#0"}, - "west": {"uv": [0, 0, 6, 6], "texture": "#0"}, - "up": {"uv": [0, 0, 6, 6], "texture": "#0"}, - "down": {"uv": [0, 0, 6, 6], "texture": "#0"} + "north": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "east": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "south": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "west": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "up": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "down": {"uv": [7, 11, 12, 16], "texture": "#0"} } }, { - "from": [2, 0, 0], - "to": [6, 4, 4], - "rotation": {"angle": 0, "axis": "y", "origin": [10, 8, 8]}, + "from": [9, 0, 2], + "to": [14, 5, 7], "faces": { - "north": {"uv": [0, 7, 4, 11], "texture": "#0"}, - "east": {"uv": [0, 7, 4, 11], "texture": "#0"}, - "south": {"uv": [0, 7, 4, 11], "texture": "#0"}, - "west": {"uv": [0, 7, 4, 11], "texture": "#0"}, - "up": {"uv": [0, 7, 4, 11], "texture": "#0"}, - "down": {"uv": [0, 7, 4, 11], "texture": "#0"} + "north": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "east": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "south": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "west": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "up": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "down": {"uv": [7, 11, 12, 16], "texture": "#0"} } } ] diff --git a/src/main/resources/assets/bettas/models/block/moss_balls_three_alter.json b/src/main/resources/assets/bettas/models/block/moss_balls_three_alter.json new file mode 100644 index 0000000..8d9969c --- /dev/null +++ b/src/main/resources/assets/bettas/models/block/moss_balls_three_alter.json @@ -0,0 +1,44 @@ +{ + "textures": { + "0": "bettas:block/moss_ball", + "particle": "bettas:block/moss_ball" + }, + "elements": [ + { + "from": [1, 0, 8], + "to": [7, 6, 14], + "faces": { + "north": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "east": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "south": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "west": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "up": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "down": {"uv": [0, 10, 6, 16], "texture": "#0"} + } + }, + { + "from": [1, 0, 2], + "to": [6, 5, 7], + "faces": { + "north": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "east": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "south": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "west": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "up": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "down": {"uv": [7, 11, 12, 16], "texture": "#0"} + } + }, + { + "from": [9, 0, 10], + "to": [14, 5, 15], + "faces": { + "north": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "east": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "south": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "west": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "up": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "down": {"uv": [7, 11, 12, 16], "texture": "#0"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/bettas/models/block/moss_balls_two.json b/src/main/resources/assets/bettas/models/block/moss_balls_two.json index e813f68..03e6481 100644 --- a/src/main/resources/assets/bettas/models/block/moss_balls_two.json +++ b/src/main/resources/assets/bettas/models/block/moss_balls_two.json @@ -1,34 +1,31 @@ { - "ambientocclusion": false, "textures": { "0": "bettas:block/moss_ball", "particle": "bettas:block/moss_ball" }, "elements": [ { - "from": [9, 0, 9], - "to": [16, 7, 16], - "rotation": {"angle": 0, "axis": "y", "origin": [17, 8, 17]}, + "from": [1, 0, 10], + "to": [6, 5, 15], "faces": { - "north": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "east": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "south": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "west": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "up": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "down": {"uv": [9, 9, 16, 16], "texture": "#0"} + "north": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "east": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "south": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "west": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "up": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "down": {"uv": [7, 11, 12, 16], "texture": "#0"} } }, { - "from": [2, 0, 0], - "to": [6, 4, 4], - "rotation": {"angle": 0, "axis": "y", "origin": [10, 8, 8]}, + "from": [9, 0, 2], + "to": [14, 5, 7], "faces": { - "north": {"uv": [0, 7, 4, 11], "texture": "#0"}, - "east": {"uv": [0, 7, 4, 11], "texture": "#0"}, - "south": {"uv": [0, 7, 4, 11], "texture": "#0"}, - "west": {"uv": [0, 7, 4, 11], "texture": "#0"}, - "up": {"uv": [0, 7, 4, 11], "texture": "#0"}, - "down": {"uv": [0, 7, 4, 11], "texture": "#0"} + "north": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "east": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "south": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "west": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "up": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "down": {"uv": [7, 11, 12, 16], "texture": "#0"} } } ] diff --git a/src/main/resources/assets/bettas/models/block/moss_balls_two_alter.json b/src/main/resources/assets/bettas/models/block/moss_balls_two_alter.json new file mode 100644 index 0000000..73824f4 --- /dev/null +++ b/src/main/resources/assets/bettas/models/block/moss_balls_two_alter.json @@ -0,0 +1,32 @@ +{ + "textures": { + "0": "bettas:block/moss_ball", + "particle": "bettas:block/moss_ball" + }, + "elements": [ + { + "from": [1, 0, 2], + "to": [6, 5, 7], + "faces": { + "north": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "east": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "south": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "west": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "up": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "down": {"uv": [7, 11, 12, 16], "texture": "#0"} + } + }, + { + "from": [9, 0, 10], + "to": [14, 5, 15], + "faces": { + "north": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "east": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "south": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "west": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "up": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "down": {"uv": [7, 11, 12, 16], "texture": "#0"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/bettas/models/block/piled_dried_leaves.json b/src/main/resources/assets/bettas/models/block/piled_dried_leaves.json index cbb1e3b..c94867d 100644 --- a/src/main/resources/assets/bettas/models/block/piled_dried_leaves.json +++ b/src/main/resources/assets/bettas/models/block/piled_dried_leaves.json @@ -1,14 +1,32 @@ { + "render_type": "cutout", "textures": { "dried": "bettas:block/piled_dried_leaves", "particle": "bettas:block/piled_dried_leaves" }, "elements": [ { - "from": [0, 0, 0], - "to": [16, 3, 16], + "from": [ + 0, + 0, + 0 + ], + "to": [ + 16, + 3, + 16 + ], "faces": { - "north": {"uv": [0, 0, 16, 3], "texture": "#dried", "cullface": "north" }, + "north": { + "uv": [ + 0, + 0, + 16, + 3 + ], + "texture": "#dried", + "cullface": "north" + }, "east": {"uv": [0, 0, 16, 3], "texture": "#dried", "cullface": "east"}, "south": {"uv": [0, 0, 16, 3], "texture": "#dried", "cullface": "south"}, "west": {"uv": [0, 0, 16, 3], "texture": "#dried", "cullface": "west"}, diff --git a/src/main/resources/assets/bettas/textures/block/heavily_piled_dried_leaves.png b/src/main/resources/assets/bettas/textures/block/heavily_piled_dried_leaves.png index 1d5b69b..ba76bad 100644 Binary files a/src/main/resources/assets/bettas/textures/block/heavily_piled_dried_leaves.png and b/src/main/resources/assets/bettas/textures/block/heavily_piled_dried_leaves.png differ diff --git a/src/main/resources/assets/bettas/textures/block/loosely_piled_dried_leaves.png b/src/main/resources/assets/bettas/textures/block/loosely_piled_dried_leaves.png index 92f5a32..192259a 100644 Binary files a/src/main/resources/assets/bettas/textures/block/loosely_piled_dried_leaves.png and b/src/main/resources/assets/bettas/textures/block/loosely_piled_dried_leaves.png differ diff --git a/src/main/resources/assets/bettas/textures/block/moss_ball.png b/src/main/resources/assets/bettas/textures/block/moss_ball.png index b0170b5..7da6af6 100644 Binary files a/src/main/resources/assets/bettas/textures/block/moss_ball.png and b/src/main/resources/assets/bettas/textures/block/moss_ball.png differ diff --git a/src/main/resources/assets/bettas/textures/block/moss_ball_block.png b/src/main/resources/assets/bettas/textures/block/moss_ball_block.png index 8017388..aa4eca0 100644 Binary files a/src/main/resources/assets/bettas/textures/block/moss_ball_block.png and b/src/main/resources/assets/bettas/textures/block/moss_ball_block.png differ diff --git a/src/main/resources/assets/bettas/textures/block/piled_dried_leaves.png b/src/main/resources/assets/bettas/textures/block/piled_dried_leaves.png index f6193b0..f1b7d4a 100644 Binary files a/src/main/resources/assets/bettas/textures/block/piled_dried_leaves.png and b/src/main/resources/assets/bettas/textures/block/piled_dried_leaves.png differ diff --git a/src/main/resources/assets/bettas/textures/entity/betta/beto.png b/src/main/resources/assets/bettas/textures/entity/betta/beto.png new file mode 100644 index 0000000..c879b6a Binary files /dev/null and b/src/main/resources/assets/bettas/textures/entity/betta/beto.png differ diff --git a/src/main/resources/assets/bettas/textures/item/betta_fish.png b/src/main/resources/assets/bettas/textures/item/betta_fish.png index acc71b0..505e9f4 100644 Binary files a/src/main/resources/assets/bettas/textures/item/betta_fish.png and b/src/main/resources/assets/bettas/textures/item/betta_fish.png differ diff --git a/src/main/resources/assets/bettas/textures/item/betta_fish_bucket.png b/src/main/resources/assets/bettas/textures/item/betta_fish_bucket.png index ec830ba..3199b58 100644 Binary files a/src/main/resources/assets/bettas/textures/item/betta_fish_bucket.png and b/src/main/resources/assets/bettas/textures/item/betta_fish_bucket.png differ diff --git a/src/main/resources/assets/bettas/textures/item/blackwater_bottle.png b/src/main/resources/assets/bettas/textures/item/blackwater_bottle.png index 53c6fca..d2bc4ac 100644 Binary files a/src/main/resources/assets/bettas/textures/item/blackwater_bottle.png and b/src/main/resources/assets/bettas/textures/item/blackwater_bottle.png differ diff --git a/src/main/resources/assets/bettas/textures/item/dried_leaves.png b/src/main/resources/assets/bettas/textures/item/dried_leaves.png index 2594570..f2e5bf3 100644 Binary files a/src/main/resources/assets/bettas/textures/item/dried_leaves.png and b/src/main/resources/assets/bettas/textures/item/dried_leaves.png differ diff --git a/src/main/resources/assets/bettas/textures/item/moss_ball.png b/src/main/resources/assets/bettas/textures/item/moss_ball.png index b9bb1ca..33f4604 100644 Binary files a/src/main/resources/assets/bettas/textures/item/moss_ball.png and b/src/main/resources/assets/bettas/textures/item/moss_ball.png differ diff --git a/src/main/resources/data/bettas/forge/biome_modifier/betta_biome_spawn.json b/src/main/resources/data/bettas/forge/biome_modifier/betta_biome_spawn.json new file mode 100644 index 0000000..b5b61cf --- /dev/null +++ b/src/main/resources/data/bettas/forge/biome_modifier/betta_biome_spawn.json @@ -0,0 +1,3 @@ +{ + "type": "bettas:betta_biome_modifier" +} \ No newline at end of file diff --git a/src/main/resources/pack.mcmeta b/src/main/resources/pack.mcmeta index d530cd9..ce05012 100644 --- a/src/main/resources/pack.mcmeta +++ b/src/main/resources/pack.mcmeta @@ -1,6 +1,6 @@ { "pack": { "description": "bettas resources", - "pack_format": 6 + "pack_format": 8 } }