Initial port of 1.18.2-2.0.2 to 1.19.2.
6
.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
/.gradle/
|
||||||
|
/.idea/
|
||||||
|
/build/
|
||||||
|
/run/
|
||||||
|
/src/test/
|
||||||
|
/src/generated/resources/.cache/cache
|
112
build.gradle
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
// 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: '5.1.+', changing: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
apply plugin: 'net.minecraftforge.gradle'
|
||||||
|
|
||||||
|
def archiveVersion = "${project.mcVersion}-${project.buildVersion}" as Object
|
||||||
|
|
||||||
|
java.toolchain.languageVersion = JavaLanguageVersion.of(17)
|
||||||
|
|
||||||
|
minecraft {
|
||||||
|
mappings channel: 'official', version: mcVersion
|
||||||
|
|
||||||
|
accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')
|
||||||
|
|
||||||
|
runs {
|
||||||
|
client {
|
||||||
|
workingDirectory project.file('run')
|
||||||
|
|
||||||
|
property 'forge.logging.markers', 'REGISTRIES'
|
||||||
|
property 'forge.logging.console.level', 'debug'
|
||||||
|
|
||||||
|
mods {
|
||||||
|
totemofreviving {
|
||||||
|
source sourceSets.main
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
workingDirectory project.file('run')
|
||||||
|
|
||||||
|
property 'forge.logging.markers', 'REGISTRIES'
|
||||||
|
property 'forge.logging.console.level', 'debug'
|
||||||
|
|
||||||
|
mods {
|
||||||
|
totemofreviving {
|
||||||
|
source sourceSets.main
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data {
|
||||||
|
workingDirectory project.file('run')
|
||||||
|
|
||||||
|
property 'forge.logging.markers', 'REGISTRIES'
|
||||||
|
property 'forge.logging.console.level', 'debug'
|
||||||
|
|
||||||
|
args '--mod', 'totemofreviving', '--all',
|
||||||
|
'--existing', file('src/main/resources').toString(),
|
||||||
|
'--existing', file('src/generated/resources').toString(),
|
||||||
|
'--output', file('src/generated/resources/')
|
||||||
|
|
||||||
|
mods {
|
||||||
|
totemofreviving {
|
||||||
|
source sourceSets.main
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceSets.main.resources {
|
||||||
|
srcDir 'src/generated/resources'
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
name = "Progwml6 maven"
|
||||||
|
url = "https://dvs1.progwml6.com/files/maven/"
|
||||||
|
}
|
||||||
|
maven {
|
||||||
|
name = "ModMaven"
|
||||||
|
url = "https://modmaven.dev"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
minecraft "net.minecraftforge:forge:${project.mcVersion}-${project.forgeVersion}"
|
||||||
|
|
||||||
|
// JEI
|
||||||
|
if (project.hasProperty('jeiVersion')) {
|
||||||
|
// compile against JEI API but do not include it at runtime
|
||||||
|
compileOnly fg.deobf("mezz.jei:jei-${project.mcVersion}-forge-api:${project.jeiVersion}")
|
||||||
|
// at runtime, use full JEI jar
|
||||||
|
runtimeOnly fg.deobf("mezz.jei:jei-${project.mcVersion}-forge:${project.jeiVersion}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
jar {
|
||||||
|
archiveFileName = "${project.archivesBaseName}-${archiveVersion}.jar"
|
||||||
|
manifest {
|
||||||
|
attributes([
|
||||||
|
"Specification-Title" : project.name,
|
||||||
|
"Specification-Vendor" : project.author,
|
||||||
|
"Specification-Version" : "1",
|
||||||
|
"Implementation-Title" : project.name,
|
||||||
|
"Implementation-Vendor" : project.author,
|
||||||
|
"Implementation-Version" : archiveVersion,
|
||||||
|
"Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ")
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
jar.finalizedBy('reobfJar')
|
14
gradle.properties
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
org.gradle.jvmargs=-Xmx3G
|
||||||
|
org.gradle.daemon=false
|
||||||
|
|
||||||
|
group = dev.micle
|
||||||
|
archivesBaseName = micles-totem-of-reviving-forge
|
||||||
|
modID = totemofreviving
|
||||||
|
name = Micle's Totem of Reviving
|
||||||
|
author = Micle
|
||||||
|
|
||||||
|
buildVersion = 2.0.0
|
||||||
|
mcVersion = 1.19.2
|
||||||
|
forgeVersion = 43.1.47
|
||||||
|
|
||||||
|
jeiVersion = 11.+
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
5
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
234
gradlew
vendored
Executable file
@ -0,0 +1,234 @@
|
|||||||
|
#!/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 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
|
||||||
|
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
|
||||||
|
|
||||||
|
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=${0##*/}
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
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 ;; #(
|
||||||
|
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
|
||||||
|
else
|
||||||
|
JAVACMD=$JAVA_HOME/bin/java
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD=java
|
||||||
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
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
|
||||||
|
|
||||||
|
# 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" )
|
||||||
|
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
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
|
||||||
|
# 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
|
||||||
|
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" "$@"
|
89
gradlew.bat
vendored
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
@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
|
||||||
|
@rem Gradle startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
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="-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 execute
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto execute
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
: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 %*
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
1
settings.gradle
Normal file
@ -0,0 +1 @@
|
|||||||
|
rootProject.name = 'TotemOfReviving-1.19'
|
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"parent": "minecraft:item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "totemofreviving:item/diamond_charge"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"parent": "minecraft:item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "totemofreviving:item/diamond_totem"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"parent": "minecraft:item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "totemofreviving:item/iron_charge"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"parent": "minecraft:item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "totemofreviving:item/iron_totem"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"parent": "minecraft:item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "totemofreviving:item/netherite_charge"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"parent": "minecraft:item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "totemofreviving:item/netherite_totem"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"parent": "minecraft:item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "totemofreviving:item/straw_charge"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"parent": "minecraft:item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "totemofreviving:item/straw_totem"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"parent": "minecraft:recipes/root",
|
||||||
|
"rewards": {
|
||||||
|
"recipes": [
|
||||||
|
"totemofreviving:diamond_charge"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"criteria": {
|
||||||
|
"has_item": {
|
||||||
|
"trigger": "minecraft:inventory_changed",
|
||||||
|
"conditions": {
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"items": [
|
||||||
|
"totemofreviving:diamond_totem"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"has_the_recipe": {
|
||||||
|
"trigger": "minecraft:recipe_unlocked",
|
||||||
|
"conditions": {
|
||||||
|
"recipe": "totemofreviving:diamond_charge"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"requirements": [
|
||||||
|
[
|
||||||
|
"has_item",
|
||||||
|
"has_the_recipe"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"parent": "minecraft:recipes/root",
|
||||||
|
"rewards": {
|
||||||
|
"recipes": [
|
||||||
|
"totemofreviving:diamond_totem"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"criteria": {
|
||||||
|
"has_item": {
|
||||||
|
"trigger": "minecraft:inventory_changed",
|
||||||
|
"conditions": {
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"items": [
|
||||||
|
"minecraft:totem_of_undying"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"has_the_recipe": {
|
||||||
|
"trigger": "minecraft:recipe_unlocked",
|
||||||
|
"conditions": {
|
||||||
|
"recipe": "totemofreviving:diamond_totem"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"requirements": [
|
||||||
|
[
|
||||||
|
"has_item",
|
||||||
|
"has_the_recipe"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"parent": "minecraft:recipes/root",
|
||||||
|
"rewards": {
|
||||||
|
"recipes": [
|
||||||
|
"totemofreviving:iron_charge"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"criteria": {
|
||||||
|
"has_item": {
|
||||||
|
"trigger": "minecraft:inventory_changed",
|
||||||
|
"conditions": {
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"items": [
|
||||||
|
"totemofreviving:iron_totem"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"has_the_recipe": {
|
||||||
|
"trigger": "minecraft:recipe_unlocked",
|
||||||
|
"conditions": {
|
||||||
|
"recipe": "totemofreviving:iron_charge"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"requirements": [
|
||||||
|
[
|
||||||
|
"has_item",
|
||||||
|
"has_the_recipe"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"parent": "minecraft:recipes/root",
|
||||||
|
"rewards": {
|
||||||
|
"recipes": [
|
||||||
|
"totemofreviving:iron_totem"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"criteria": {
|
||||||
|
"has_item": {
|
||||||
|
"trigger": "minecraft:inventory_changed",
|
||||||
|
"conditions": {
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"items": [
|
||||||
|
"minecraft:emerald"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"has_the_recipe": {
|
||||||
|
"trigger": "minecraft:recipe_unlocked",
|
||||||
|
"conditions": {
|
||||||
|
"recipe": "totemofreviving:iron_totem"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"requirements": [
|
||||||
|
[
|
||||||
|
"has_item",
|
||||||
|
"has_the_recipe"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"parent": "minecraft:recipes/root",
|
||||||
|
"rewards": {
|
||||||
|
"recipes": [
|
||||||
|
"totemofreviving:netherite_charge"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"criteria": {
|
||||||
|
"has_item": {
|
||||||
|
"trigger": "minecraft:inventory_changed",
|
||||||
|
"conditions": {
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"items": [
|
||||||
|
"totemofreviving:netherite_totem"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"has_the_recipe": {
|
||||||
|
"trigger": "minecraft:recipe_unlocked",
|
||||||
|
"conditions": {
|
||||||
|
"recipe": "totemofreviving:netherite_charge"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"requirements": [
|
||||||
|
[
|
||||||
|
"has_item",
|
||||||
|
"has_the_recipe"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"parent": "minecraft:recipes/root",
|
||||||
|
"rewards": {
|
||||||
|
"recipes": [
|
||||||
|
"totemofreviving:netherite_totem"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"criteria": {
|
||||||
|
"has_item": {
|
||||||
|
"trigger": "minecraft:inventory_changed",
|
||||||
|
"conditions": {
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"items": [
|
||||||
|
"minecraft:netherite_scrap"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"has_the_recipe": {
|
||||||
|
"trigger": "minecraft:recipe_unlocked",
|
||||||
|
"conditions": {
|
||||||
|
"recipe": "totemofreviving:netherite_totem"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"requirements": [
|
||||||
|
[
|
||||||
|
"has_item",
|
||||||
|
"has_the_recipe"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"parent": "minecraft:recipes/root",
|
||||||
|
"rewards": {
|
||||||
|
"recipes": [
|
||||||
|
"totemofreviving:straw_charge"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"criteria": {
|
||||||
|
"has_item": {
|
||||||
|
"trigger": "minecraft:inventory_changed",
|
||||||
|
"conditions": {
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"items": [
|
||||||
|
"totemofreviving:straw_totem"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"has_the_recipe": {
|
||||||
|
"trigger": "minecraft:recipe_unlocked",
|
||||||
|
"conditions": {
|
||||||
|
"recipe": "totemofreviving:straw_charge"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"requirements": [
|
||||||
|
[
|
||||||
|
"has_item",
|
||||||
|
"has_the_recipe"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"parent": "minecraft:recipes/root",
|
||||||
|
"rewards": {
|
||||||
|
"recipes": [
|
||||||
|
"totemofreviving:straw_totem"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"criteria": {
|
||||||
|
"has_item": {
|
||||||
|
"trigger": "minecraft:inventory_changed",
|
||||||
|
"conditions": {
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"items": [
|
||||||
|
"minecraft:wheat"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"has_the_recipe": {
|
||||||
|
"trigger": "minecraft:recipe_unlocked",
|
||||||
|
"conditions": {
|
||||||
|
"recipe": "totemofreviving:straw_totem"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"requirements": [
|
||||||
|
[
|
||||||
|
"has_item",
|
||||||
|
"has_the_recipe"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"type": "totemofreviving:charge_recipe",
|
||||||
|
"pattern": [
|
||||||
|
"IDI",
|
||||||
|
"PEP",
|
||||||
|
"IDI"
|
||||||
|
],
|
||||||
|
"key": {
|
||||||
|
"E": {
|
||||||
|
"item": "minecraft:emerald"
|
||||||
|
},
|
||||||
|
"D": {
|
||||||
|
"item": "minecraft:diamond"
|
||||||
|
},
|
||||||
|
"I": {
|
||||||
|
"item": "minecraft:iron_ingot"
|
||||||
|
},
|
||||||
|
"P": {
|
||||||
|
"item": "minecraft:ender_pearl"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"result": {
|
||||||
|
"item": "totemofreviving:diamond_charge"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"type": "totemofreviving:totem_recipe",
|
||||||
|
"pattern": [
|
||||||
|
"EDE",
|
||||||
|
"DTD",
|
||||||
|
"EDE"
|
||||||
|
],
|
||||||
|
"key": {
|
||||||
|
"T": {
|
||||||
|
"item": "minecraft:totem_of_undying"
|
||||||
|
},
|
||||||
|
"D": {
|
||||||
|
"item": "minecraft:diamond"
|
||||||
|
},
|
||||||
|
"E": {
|
||||||
|
"item": "minecraft:ender_pearl"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"result": {
|
||||||
|
"item": "totemofreviving:diamond_totem"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"type": "totemofreviving:charge_recipe",
|
||||||
|
"pattern": [
|
||||||
|
"NIN",
|
||||||
|
"IEI",
|
||||||
|
"NIN"
|
||||||
|
],
|
||||||
|
"key": {
|
||||||
|
"E": {
|
||||||
|
"item": "minecraft:emerald"
|
||||||
|
},
|
||||||
|
"I": {
|
||||||
|
"item": "minecraft:iron_ingot"
|
||||||
|
},
|
||||||
|
"N": {
|
||||||
|
"item": "minecraft:iron_nugget"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"result": {
|
||||||
|
"item": "totemofreviving:iron_charge"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"type": "totemofreviving:totem_recipe",
|
||||||
|
"pattern": [
|
||||||
|
" E ",
|
||||||
|
"IBI",
|
||||||
|
" I "
|
||||||
|
],
|
||||||
|
"key": {
|
||||||
|
"B": {
|
||||||
|
"item": "minecraft:iron_block"
|
||||||
|
},
|
||||||
|
"E": {
|
||||||
|
"item": "minecraft:emerald"
|
||||||
|
},
|
||||||
|
"I": {
|
||||||
|
"item": "minecraft:iron_ingot"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"result": {
|
||||||
|
"item": "totemofreviving:iron_totem"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"type": "totemofreviving:charge_recipe",
|
||||||
|
"pattern": [
|
||||||
|
"GNG",
|
||||||
|
"NCN",
|
||||||
|
"GNG"
|
||||||
|
],
|
||||||
|
"key": {
|
||||||
|
"C": {
|
||||||
|
"item": "totemofreviving:diamond_charge"
|
||||||
|
},
|
||||||
|
"N": {
|
||||||
|
"item": "minecraft:netherite_scrap"
|
||||||
|
},
|
||||||
|
"G": {
|
||||||
|
"item": "minecraft:gold_ingot"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"result": {
|
||||||
|
"item": "totemofreviving:netherite_charge"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"type": "totemofreviving:totem_recipe",
|
||||||
|
"pattern": [
|
||||||
|
"BNB",
|
||||||
|
"NTN",
|
||||||
|
"BGB"
|
||||||
|
],
|
||||||
|
"key": {
|
||||||
|
"T": {
|
||||||
|
"item": "totemofreviving:diamond_totem"
|
||||||
|
},
|
||||||
|
"N": {
|
||||||
|
"item": "minecraft:netherite_scrap"
|
||||||
|
},
|
||||||
|
"G": {
|
||||||
|
"item": "minecraft:gold_ingot"
|
||||||
|
},
|
||||||
|
"B": {
|
||||||
|
"item": "minecraft:nether_brick"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"result": {
|
||||||
|
"item": "totemofreviving:netherite_totem"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"type": "totemofreviving:charge_recipe",
|
||||||
|
"pattern": [
|
||||||
|
"NWN",
|
||||||
|
"WEW",
|
||||||
|
"NWN"
|
||||||
|
],
|
||||||
|
"key": {
|
||||||
|
"E": {
|
||||||
|
"item": "minecraft:emerald"
|
||||||
|
},
|
||||||
|
"W": {
|
||||||
|
"item": "minecraft:wheat"
|
||||||
|
},
|
||||||
|
"N": {
|
||||||
|
"item": "minecraft:iron_nugget"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"result": {
|
||||||
|
"item": "totemofreviving:straw_charge"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"type": "totemofreviving:totem_recipe",
|
||||||
|
"pattern": [
|
||||||
|
"NSN",
|
||||||
|
"NWN",
|
||||||
|
"N|N"
|
||||||
|
],
|
||||||
|
"key": {
|
||||||
|
"W": {
|
||||||
|
"item": "minecraft:wheat"
|
||||||
|
},
|
||||||
|
"|": {
|
||||||
|
"item": "minecraft:stick"
|
||||||
|
},
|
||||||
|
"S": {
|
||||||
|
"item": "minecraft:string"
|
||||||
|
},
|
||||||
|
"N": {
|
||||||
|
"item": "minecraft:iron_nugget"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"result": {
|
||||||
|
"item": "totemofreviving:straw_totem"
|
||||||
|
}
|
||||||
|
}
|
54
src/main/java/dev/micle/totemofreviving/TotemOfReviving.java
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
package dev.micle.totemofreviving;
|
||||||
|
|
||||||
|
import dev.micle.totemofreviving.proxy.IProxy;
|
||||||
|
import dev.micle.totemofreviving.proxy.IProxy;
|
||||||
|
import dev.micle.totemofreviving.proxy.Proxy;
|
||||||
|
import dev.micle.totemofreviving.setup.ModItems;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.item.CreativeModeTab;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraftforge.fml.DistExecutor;
|
||||||
|
import net.minecraftforge.fml.ModContainer;
|
||||||
|
import net.minecraftforge.fml.ModList;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Mod(TotemOfReviving.MOD_ID)
|
||||||
|
public final class TotemOfReviving {
|
||||||
|
public static final String MOD_ID = "totemofreviving";
|
||||||
|
public static final CreativeModeTab ITEM_GROUP = new CreativeModeTab(MOD_ID) {
|
||||||
|
@Override
|
||||||
|
public ItemStack makeIcon() {
|
||||||
|
return new ItemStack(ModItems.STRAW_TOTEM.get());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static IProxy proxy;
|
||||||
|
|
||||||
|
public TotemOfReviving() {
|
||||||
|
proxy = DistExecutor.safeRunForDist(
|
||||||
|
() -> Proxy.Client::new,
|
||||||
|
() -> Proxy.Server::new
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ResourceLocation createResourceLocation(String name) {
|
||||||
|
if (name.contains(":")) {
|
||||||
|
throw new IllegalArgumentException("Name contains namespace");
|
||||||
|
}
|
||||||
|
return new ResourceLocation(MOD_ID, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getVersion() {
|
||||||
|
Optional<? extends ModContainer> optional = ModList.get().getModContainerById(MOD_ID);
|
||||||
|
if (optional.isPresent()) {
|
||||||
|
return optional.get().getModInfo().getVersion().toString();
|
||||||
|
}
|
||||||
|
return "0.0.0";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IProxy getProxy() {
|
||||||
|
return proxy;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package dev.micle.totemofreviving.data;
|
||||||
|
|
||||||
|
import dev.micle.totemofreviving.TotemOfReviving;
|
||||||
|
import dev.micle.totemofreviving.data.client.ModItemModelProvider;
|
||||||
|
import net.minecraft.data.DataGenerator;
|
||||||
|
import net.minecraftforge.common.data.ExistingFileHelper;
|
||||||
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
import net.minecraftforge.forge.event.lifecycle.GatherDataEvent;
|
||||||
|
|
||||||
|
@Mod.EventBusSubscriber(modid = TotemOfReviving.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD)
|
||||||
|
public class DataGenerators {
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void gatherData(GatherDataEvent event) {
|
||||||
|
DataGenerator generator = event.getGenerator();
|
||||||
|
ExistingFileHelper existingFileHelper = event.getExistingFileHelper();
|
||||||
|
|
||||||
|
generator.addProvider(new ModItemModelProvider(generator, existingFileHelper));
|
||||||
|
|
||||||
|
generator.addProvider(new ModRecipeProvider(generator));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,99 @@
|
|||||||
|
package dev.micle.totemofreviving.data;
|
||||||
|
|
||||||
|
import dev.micle.totemofreviving.item.crafting.ExtendedShapedRecipeBuilder;
|
||||||
|
import dev.micle.totemofreviving.setup.ModItems;
|
||||||
|
import dev.micle.totemofreviving.setup.ModRecipes;
|
||||||
|
import net.minecraft.data.DataGenerator;
|
||||||
|
import net.minecraft.data.recipes.FinishedRecipe;
|
||||||
|
import net.minecraft.data.recipes.RecipeProvider;
|
||||||
|
import net.minecraft.world.item.Items;
|
||||||
|
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public class ModRecipeProvider extends RecipeProvider {
|
||||||
|
public ModRecipeProvider(DataGenerator generator) {
|
||||||
|
super(generator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
protected void buildCraftingRecipes(Consumer<FinishedRecipe> consumer) {
|
||||||
|
ExtendedShapedRecipeBuilder.shaped(ModRecipes.TOTEM_RECIPE.get(), ModItems.STRAW_TOTEM.get())
|
||||||
|
.define('W', Items.WHEAT)
|
||||||
|
.define('|', Items.STICK)
|
||||||
|
.define('S', Items.STRING)
|
||||||
|
.define('N', Items.IRON_NUGGET)
|
||||||
|
.pattern("NSN")
|
||||||
|
.pattern("NWN")
|
||||||
|
.pattern("N|N")
|
||||||
|
.unlockedBy("has_item", has(Items.WHEAT))
|
||||||
|
.save(consumer);
|
||||||
|
ExtendedShapedRecipeBuilder.shaped(ModRecipes.TOTEM_RECIPE.get(), ModItems.IRON_TOTEM.get())
|
||||||
|
.define('B', Items.IRON_BLOCK)
|
||||||
|
.define('E', Items.EMERALD)
|
||||||
|
.define('I', Items.IRON_INGOT)
|
||||||
|
.pattern(" E ")
|
||||||
|
.pattern("IBI")
|
||||||
|
.pattern(" I ")
|
||||||
|
.unlockedBy("has_item", has(Items.EMERALD))
|
||||||
|
.save(consumer);
|
||||||
|
ExtendedShapedRecipeBuilder.shaped(ModRecipes.TOTEM_RECIPE.get(), ModItems.DIAMOND_TOTEM.get())
|
||||||
|
.define('T', Items.TOTEM_OF_UNDYING)
|
||||||
|
.define('D', Items.DIAMOND)
|
||||||
|
.define('E', Items.ENDER_PEARL)
|
||||||
|
.pattern("EDE")
|
||||||
|
.pattern("DTD")
|
||||||
|
.pattern("EDE")
|
||||||
|
.unlockedBy("has_item", has(Items.TOTEM_OF_UNDYING))
|
||||||
|
.save(consumer);
|
||||||
|
ExtendedShapedRecipeBuilder.shaped(ModRecipes.TOTEM_RECIPE.get(), ModItems.NETHERITE_TOTEM.get())
|
||||||
|
.define('T', ModItems.DIAMOND_TOTEM.get())
|
||||||
|
.define('N', Items.NETHERITE_SCRAP)
|
||||||
|
.define('G', Items.GOLD_INGOT)
|
||||||
|
.define('B', Items.NETHER_BRICK)
|
||||||
|
.pattern("BNB")
|
||||||
|
.pattern("NTN")
|
||||||
|
.pattern("BGB")
|
||||||
|
.unlockedBy("has_item", has(Items.NETHERITE_SCRAP))
|
||||||
|
.save(consumer);
|
||||||
|
|
||||||
|
ExtendedShapedRecipeBuilder.shaped(ModRecipes.CHARGE_RECIPE.get(), ModItems.STRAW_CHARGE.get())
|
||||||
|
.define('E', Items.EMERALD)
|
||||||
|
.define('W', Items.WHEAT)
|
||||||
|
.define('N', Items.IRON_NUGGET)
|
||||||
|
.pattern("NWN")
|
||||||
|
.pattern("WEW")
|
||||||
|
.pattern("NWN")
|
||||||
|
.unlockedBy("has_item", has(ModItems.STRAW_TOTEM.get()))
|
||||||
|
.save(consumer);
|
||||||
|
ExtendedShapedRecipeBuilder.shaped(ModRecipes.CHARGE_RECIPE.get(), ModItems.IRON_CHARGE.get())
|
||||||
|
.define('E', Items.EMERALD)
|
||||||
|
.define('I', Items.IRON_INGOT)
|
||||||
|
.define('N', Items.IRON_NUGGET)
|
||||||
|
.pattern("NIN")
|
||||||
|
.pattern("IEI")
|
||||||
|
.pattern("NIN")
|
||||||
|
.unlockedBy("has_item", has(ModItems.IRON_TOTEM.get()))
|
||||||
|
.save(consumer);
|
||||||
|
ExtendedShapedRecipeBuilder.shaped(ModRecipes.CHARGE_RECIPE.get(), ModItems.DIAMOND_CHARGE.get())
|
||||||
|
.define('E', Items.EMERALD)
|
||||||
|
.define('D', Items.DIAMOND)
|
||||||
|
.define('I', Items.IRON_INGOT)
|
||||||
|
.define('P', Items.ENDER_PEARL)
|
||||||
|
.pattern("IDI")
|
||||||
|
.pattern("PEP")
|
||||||
|
.pattern("IDI")
|
||||||
|
.unlockedBy("has_item", has(ModItems.DIAMOND_TOTEM.get()))
|
||||||
|
.save(consumer);
|
||||||
|
ExtendedShapedRecipeBuilder.shaped(ModRecipes.CHARGE_RECIPE.get(), ModItems.NETHERITE_CHARGE.get())
|
||||||
|
.define('C', ModItems.DIAMOND_CHARGE.get())
|
||||||
|
.define('N', Items.NETHERITE_SCRAP)
|
||||||
|
.define('G', Items.GOLD_INGOT)
|
||||||
|
.pattern("GNG")
|
||||||
|
.pattern("NCN")
|
||||||
|
.pattern("GNG")
|
||||||
|
.unlockedBy("has_item", has(ModItems.NETHERITE_TOTEM.get()))
|
||||||
|
.save(consumer);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package dev.micle.totemofreviving.data.client;
|
||||||
|
|
||||||
|
import dev.micle.totemofreviving.TotemOfReviving;
|
||||||
|
import dev.micle.totemofreviving.item.charge.DiamondChargeItem;
|
||||||
|
import dev.micle.totemofreviving.item.charge.IronChargeItem;
|
||||||
|
import dev.micle.totemofreviving.item.charge.NetheriteChargeItem;
|
||||||
|
import dev.micle.totemofreviving.item.charge.StrawChargeItem;
|
||||||
|
import dev.micle.totemofreviving.item.totem.DiamondTotemItem;
|
||||||
|
import dev.micle.totemofreviving.item.totem.IronTotemItem;
|
||||||
|
import dev.micle.totemofreviving.item.totem.NetheriteTotemItem;
|
||||||
|
import dev.micle.totemofreviving.item.totem.StrawTotemItem;
|
||||||
|
import net.minecraft.data.DataGenerator;
|
||||||
|
import net.minecraftforge.client.model.generators.ItemModelBuilder;
|
||||||
|
import net.minecraftforge.client.model.generators.ItemModelProvider;
|
||||||
|
import net.minecraftforge.client.model.generators.ModelFile;
|
||||||
|
import net.minecraftforge.common.data.ExistingFileHelper;
|
||||||
|
|
||||||
|
public class ModItemModelProvider extends ItemModelProvider {
|
||||||
|
public ModItemModelProvider(DataGenerator generator, ExistingFileHelper existingFileHelper) {
|
||||||
|
super(generator, TotemOfReviving.MOD_ID, existingFileHelper);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void registerModels() {
|
||||||
|
ModelFile itemGenerated = getExistingFile(mcLoc("item/generated"));
|
||||||
|
|
||||||
|
builder(itemGenerated, StrawTotemItem.getName());
|
||||||
|
builder(itemGenerated, IronTotemItem.getName());
|
||||||
|
builder(itemGenerated, DiamondTotemItem.getName());
|
||||||
|
builder(itemGenerated, NetheriteTotemItem.getName());
|
||||||
|
|
||||||
|
builder(itemGenerated, StrawChargeItem.getName());
|
||||||
|
builder(itemGenerated, IronChargeItem.getName());
|
||||||
|
builder(itemGenerated, DiamondChargeItem.getName());
|
||||||
|
builder(itemGenerated, NetheriteChargeItem.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
private ItemModelBuilder builder(ModelFile itemGenerated, String name) {
|
||||||
|
return getBuilder(name).parent(itemGenerated).texture("layer0", "item/" + name);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
package dev.micle.totemofreviving.item.charge;
|
||||||
|
|
||||||
|
import dev.micle.totemofreviving.TotemOfReviving;
|
||||||
|
import dev.micle.totemofreviving.setup.Config;
|
||||||
|
import net.minecraft.ChatFormatting;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.network.chat.TextComponent;
|
||||||
|
import net.minecraft.world.item.Item;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.Rarity;
|
||||||
|
import net.minecraft.world.item.TooltipFlag;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ChargeItem extends Item {
|
||||||
|
public ChargeItem() {
|
||||||
|
this(Rarity.COMMON);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChargeItem(Rarity rarity) {
|
||||||
|
super(new Properties().tab(TotemOfReviving.ITEM_GROUP).stacksTo(64).rarity(rarity));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
public void appendHoverText(ItemStack stack, @Nullable Level world, List<Component> tooltip, TooltipFlag tooltipFlag) {
|
||||||
|
if (isEnabled(stack)) {
|
||||||
|
tooltip.add(new TextComponent(ChatFormatting.WHITE + "Used for charging its corresponding totem."));
|
||||||
|
} else {
|
||||||
|
tooltip.add(new TextComponent(ChatFormatting.RED + "Totem is disabled!"));
|
||||||
|
}
|
||||||
|
super.appendHoverText(stack, world, tooltip, tooltipFlag);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isEnabled(ItemStack stack) {
|
||||||
|
Item item = stack.getItem();
|
||||||
|
if (item instanceof StrawChargeItem) { return Config.Server.getStrawTotemConfig().getIsEnabled(); }
|
||||||
|
if (item instanceof IronChargeItem) { return Config.Server.getIronTotemConfig().getIsEnabled(); }
|
||||||
|
if (item instanceof DiamondChargeItem) { return Config.Server.getDiamondTotemConfig().getIsEnabled(); }
|
||||||
|
if (item instanceof NetheriteChargeItem) { return Config.Server.getNetheriteTotemConfig().getIsEnabled(); }
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package dev.micle.totemofreviving.item.charge;
|
||||||
|
|
||||||
|
import net.minecraft.world.item.Rarity;
|
||||||
|
|
||||||
|
public class DiamondChargeItem extends ChargeItem {
|
||||||
|
public DiamondChargeItem() {
|
||||||
|
super(Rarity.RARE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getName() {
|
||||||
|
return "diamond_charge";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package dev.micle.totemofreviving.item.charge;
|
||||||
|
|
||||||
|
public class IronChargeItem extends ChargeItem {
|
||||||
|
public IronChargeItem() {}
|
||||||
|
|
||||||
|
public static String getName() {
|
||||||
|
return "iron_charge";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package dev.micle.totemofreviving.item.charge;
|
||||||
|
|
||||||
|
import net.minecraft.world.item.Rarity;
|
||||||
|
|
||||||
|
public class NetheriteChargeItem extends ChargeItem {
|
||||||
|
public NetheriteChargeItem() {
|
||||||
|
super(Rarity.EPIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getName() {
|
||||||
|
return "netherite_charge";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package dev.micle.totemofreviving.item.charge;
|
||||||
|
|
||||||
|
import net.minecraft.world.item.Rarity;
|
||||||
|
|
||||||
|
public class StrawChargeItem extends ChargeItem {
|
||||||
|
public StrawChargeItem() {
|
||||||
|
super(Rarity.UNCOMMON);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getName() {
|
||||||
|
return "straw_charge";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package dev.micle.totemofreviving.item.crafting;
|
||||||
|
|
||||||
|
import dev.micle.totemofreviving.item.charge.ChargeItem;
|
||||||
|
import dev.micle.totemofreviving.setup.ModRecipes;
|
||||||
|
import net.minecraft.world.inventory.CraftingContainer;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.crafting.RecipeSerializer;
|
||||||
|
import net.minecraft.world.item.crafting.ShapedRecipe;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
|
||||||
|
public class ChargeRecipe extends ExtendedShapedRecipe {
|
||||||
|
public ChargeRecipe(ShapedRecipe recipe) {
|
||||||
|
super(recipe);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RecipeSerializer<?> getSerializer() {
|
||||||
|
return ModRecipes.CHARGE_RECIPE.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(CraftingContainer inventory, Level world) {
|
||||||
|
if (!ChargeItem.isEnabled(getResultItem())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return getBaseRecipe().matches(inventory, world);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack assemble(CraftingContainer inventory) {
|
||||||
|
return getBaseRecipe().getResultItem().copy();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,88 @@
|
|||||||
|
package dev.micle.totemofreviving.item.crafting;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.inventory.CraftingContainer;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.crafting.RecipeSerializer;
|
||||||
|
import net.minecraft.world.item.crafting.ShapedRecipe;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraftforge.registries.ForgeRegistryEntry;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public abstract class ExtendedShapedRecipe extends ShapedRecipe {
|
||||||
|
private static final RecipeSerializer<ShapedRecipe> BASE_SERIALIZER = RecipeSerializer.SHAPED_RECIPE;
|
||||||
|
|
||||||
|
private final ShapedRecipe recipe;
|
||||||
|
|
||||||
|
public ExtendedShapedRecipe(ShapedRecipe recipe) {
|
||||||
|
super(recipe.getId(), recipe.getGroup(), recipe.getRecipeWidth(), recipe.getRecipeHeight(), recipe.getIngredients(), recipe.getResultItem());
|
||||||
|
this.recipe = recipe;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ShapedRecipe getBaseRecipe() {
|
||||||
|
return this.recipe;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public abstract RecipeSerializer<?> getSerializer();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public abstract boolean matches(CraftingContainer inventory, Level world);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public abstract ItemStack assemble(CraftingContainer inventory);
|
||||||
|
|
||||||
|
public static class Serializer<T extends ExtendedShapedRecipe> extends ForgeRegistryEntry<RecipeSerializer<?>> implements RecipeSerializer<T> {
|
||||||
|
private final Function<ShapedRecipe, T> recipeFactory;
|
||||||
|
@Nullable private final BiConsumer<JsonObject, T> readJson;
|
||||||
|
@Nullable private final BiConsumer<FriendlyByteBuf, T> readBuffer;
|
||||||
|
@Nullable private final BiConsumer<FriendlyByteBuf, T> writeBuffer;
|
||||||
|
|
||||||
|
public Serializer(Function<ShapedRecipe, T> recipeFactory,
|
||||||
|
@Nullable BiConsumer<JsonObject, T> readJson,
|
||||||
|
@Nullable BiConsumer<FriendlyByteBuf, T> readBuffer,
|
||||||
|
@Nullable BiConsumer<FriendlyByteBuf, T> writeBuffer) {
|
||||||
|
this.recipeFactory = recipeFactory;
|
||||||
|
this.readJson = readJson;
|
||||||
|
this.readBuffer = readBuffer;
|
||||||
|
this.writeBuffer = writeBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <S extends ExtendedShapedRecipe> Serializer<S> basic(Function<ShapedRecipe, S> recipeFactory) {
|
||||||
|
return new Serializer<>(recipeFactory, null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T fromJson(ResourceLocation recipeId, JsonObject json) {
|
||||||
|
ShapedRecipe recipe = BASE_SERIALIZER.fromJson(recipeId, json);
|
||||||
|
T result = this.recipeFactory.apply(recipe);
|
||||||
|
if (this.readJson != null) {
|
||||||
|
this.readJson.accept(json, result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T fromNetwork(ResourceLocation recipeId, FriendlyByteBuf buffer) {
|
||||||
|
ShapedRecipe recipe = BASE_SERIALIZER.fromNetwork(recipeId, buffer);
|
||||||
|
T result = this.recipeFactory.apply(recipe);
|
||||||
|
if (this.readBuffer != null) {
|
||||||
|
this.readBuffer.accept(buffer, result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void toNetwork(FriendlyByteBuf buffer, T recipe) {
|
||||||
|
BASE_SERIALIZER.toNetwork(buffer, recipe.getBaseRecipe());
|
||||||
|
if (this.writeBuffer != null) {
|
||||||
|
this.writeBuffer.accept(buffer, recipe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,185 @@
|
|||||||
|
package dev.micle.totemofreviving.item.crafting;
|
||||||
|
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import net.minecraft.advancements.Advancement;
|
||||||
|
import net.minecraft.advancements.AdvancementRewards;
|
||||||
|
import net.minecraft.advancements.CriterionTriggerInstance;
|
||||||
|
import net.minecraft.advancements.RequirementsStrategy;
|
||||||
|
import net.minecraft.advancements.critereon.EntityPredicate;
|
||||||
|
import net.minecraft.advancements.critereon.RecipeUnlockedTrigger;
|
||||||
|
import net.minecraft.data.recipes.FinishedRecipe;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.tags.Tag;
|
||||||
|
import net.minecraft.tags.TagKey;
|
||||||
|
import net.minecraft.world.item.Item;
|
||||||
|
import net.minecraft.world.item.crafting.Ingredient;
|
||||||
|
import net.minecraft.world.item.crafting.RecipeSerializer;
|
||||||
|
import net.minecraft.world.level.ItemLike;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public class ExtendedShapedRecipeBuilder {
|
||||||
|
private final RecipeSerializer<?> serializer;
|
||||||
|
private final Item result;
|
||||||
|
private final int count;
|
||||||
|
private final List<String> pattern = new ArrayList<>();
|
||||||
|
private final Map<Character, Ingredient> key = new LinkedHashMap<>();
|
||||||
|
private final Advancement.Builder advancementBuilder = Advancement.Builder.advancement();
|
||||||
|
private boolean hasAdvancementCriterion = false;
|
||||||
|
private String group = "";
|
||||||
|
|
||||||
|
private ExtendedShapedRecipeBuilder(RecipeSerializer<?> serializer, ItemLike result, int count) {
|
||||||
|
this.serializer = serializer;
|
||||||
|
this.result = result.asItem();
|
||||||
|
this.count = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ExtendedShapedRecipeBuilder shaped(RecipeSerializer<?> serializer, ItemLike result) {
|
||||||
|
return shaped(serializer, result, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ExtendedShapedRecipeBuilder shaped(RecipeSerializer<?> serializer, ItemLike result, int count) {
|
||||||
|
return new ExtendedShapedRecipeBuilder(serializer, result, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExtendedShapedRecipeBuilder define(Character symbol, TagKey<Item> tagIn) {
|
||||||
|
return this.define(symbol, Ingredient.of(tagIn));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExtendedShapedRecipeBuilder define(Character symbol, ItemLike itemIn) {
|
||||||
|
return this.define(symbol, Ingredient.of(itemIn));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExtendedShapedRecipeBuilder define(Character symbol, Ingredient ingredientIn) {
|
||||||
|
if (this.key.containsKey(symbol)) {
|
||||||
|
throw new IllegalArgumentException("Symbol '" + symbol + "' is already defined!");
|
||||||
|
} else if (symbol == ' ') {
|
||||||
|
throw new IllegalArgumentException("Symbol ' ' (whitespace) is reserved and cannot be defined");
|
||||||
|
} else {
|
||||||
|
this.key.put(symbol, ingredientIn);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExtendedShapedRecipeBuilder pattern(String patternIn) {
|
||||||
|
if (!this.pattern.isEmpty() && patternIn.length() != this.pattern.get(0).length()) {
|
||||||
|
throw new IllegalArgumentException("Pattern must be the same width on every line!");
|
||||||
|
} else {
|
||||||
|
this.pattern.add(patternIn);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExtendedShapedRecipeBuilder unlockedBy(String name, CriterionTriggerInstance criterionIn) {
|
||||||
|
this.advancementBuilder.addCriterion(name, criterionIn);
|
||||||
|
this.hasAdvancementCriterion = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExtendedShapedRecipeBuilder group(String groupIn) {
|
||||||
|
this.group = groupIn;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save(Consumer<FinishedRecipe> consumer) {
|
||||||
|
save(consumer, this.result.getRegistryName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save(Consumer<FinishedRecipe> consumer, ResourceLocation id) {
|
||||||
|
this.validate(id);
|
||||||
|
if (this.hasAdvancementCriterion && !this.advancementBuilder.getCriteria().isEmpty()) {
|
||||||
|
this.advancementBuilder.parent(new ResourceLocation("recipes/root"))
|
||||||
|
.addCriterion("has_the_recipe", new RecipeUnlockedTrigger.TriggerInstance(EntityPredicate.Composite.ANY, id))
|
||||||
|
.rewards(AdvancementRewards.Builder.recipe(id))
|
||||||
|
.requirements(RequirementsStrategy.OR);
|
||||||
|
}
|
||||||
|
ResourceLocation advancementId = new ResourceLocation(id.getNamespace(), "recipes/" + this.result.getItemCategory().getRecipeFolderName() + "/" + id.getPath());
|
||||||
|
consumer.accept(new Result(id, this, advancementId));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validate(ResourceLocation id) {
|
||||||
|
if (this.pattern.isEmpty()) {
|
||||||
|
throw new IllegalStateException("No pattern is defined for shaped recipe " + id + "!");
|
||||||
|
} else {
|
||||||
|
Set<Character> set = Sets.newHashSet(this.key.keySet());
|
||||||
|
set.remove(' ');
|
||||||
|
|
||||||
|
for (String s : this.pattern) {
|
||||||
|
for (int i = 0; i < s.length(); ++i) {
|
||||||
|
char c0 = s.charAt(i);
|
||||||
|
if (!this.key.containsKey(c0) && c0 != ' ') {
|
||||||
|
throw new IllegalStateException("Pattern in recipe " + id + " uses undefined symbol '" + c0 + "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
set.remove(c0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!set.isEmpty()) {
|
||||||
|
throw new IllegalStateException("Ingredients are defined but not used in pattern for recipe " + id);
|
||||||
|
} else if (this.pattern.size() == 1 && this.pattern.get(0).length() == 1) {
|
||||||
|
throw new IllegalStateException("Shaped recipe " + id + " only takes in a single item - should it be a shapeless recipe instead?");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Result implements FinishedRecipe {
|
||||||
|
private final ResourceLocation id;
|
||||||
|
private final ExtendedShapedRecipeBuilder builder;
|
||||||
|
private final ResourceLocation advancementId;
|
||||||
|
|
||||||
|
public Result(ResourceLocation id, ExtendedShapedRecipeBuilder builder, ResourceLocation advancementId) {
|
||||||
|
this.id = id;
|
||||||
|
this.builder = builder;
|
||||||
|
this.advancementId = advancementId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void serializeRecipeData(JsonObject json) {
|
||||||
|
if (!builder.group.isEmpty()) {
|
||||||
|
json.addProperty("group", builder.group);
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonArray pattern = new JsonArray();
|
||||||
|
builder.pattern.forEach(pattern::add);
|
||||||
|
json.add("pattern", pattern);
|
||||||
|
|
||||||
|
JsonObject key = new JsonObject();
|
||||||
|
builder.key.forEach((c, ingredient) -> key.add(String.valueOf(c), ingredient.toJson()));
|
||||||
|
json.add("key", key);
|
||||||
|
|
||||||
|
JsonObject result = new JsonObject();
|
||||||
|
result.addProperty("item", builder.result.getRegistryName().toString());
|
||||||
|
if (builder.count > 1) {
|
||||||
|
result.addProperty("count", builder.count);
|
||||||
|
}
|
||||||
|
json.add("result", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RecipeSerializer<?> getType() {
|
||||||
|
return builder.serializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResourceLocation getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public JsonObject serializeAdvancement() {
|
||||||
|
return builder.hasAdvancementCriterion ? builder.advancementBuilder.serializeToJson() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public ResourceLocation getAdvancementId() {
|
||||||
|
return builder.hasAdvancementCriterion ? advancementId : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package dev.micle.totemofreviving.item.crafting;
|
||||||
|
|
||||||
|
import dev.micle.totemofreviving.item.totem.TotemItem;
|
||||||
|
import dev.micle.totemofreviving.setup.ModRecipes;
|
||||||
|
import net.minecraft.world.inventory.CraftingContainer;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.crafting.RecipeSerializer;
|
||||||
|
import net.minecraft.world.item.crafting.ShapedRecipe;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
|
||||||
|
public class TotemRecipe extends ExtendedShapedRecipe {
|
||||||
|
public TotemRecipe(ShapedRecipe recipe) {
|
||||||
|
super(recipe);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RecipeSerializer<?> getSerializer() {
|
||||||
|
return ModRecipes.TOTEM_RECIPE.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(CraftingContainer inventory, Level world) {
|
||||||
|
if (!TotemItem.isEnabled(getResultItem())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return getBaseRecipe().matches(inventory, world);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack assemble(CraftingContainer inventory) {
|
||||||
|
return getBaseRecipe().getResultItem().copy();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package dev.micle.totemofreviving.item.totem;
|
||||||
|
|
||||||
|
import dev.micle.totemofreviving.setup.Config;
|
||||||
|
import dev.micle.totemofreviving.item.charge.DiamondChargeItem;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.Rarity;
|
||||||
|
|
||||||
|
public class DiamondTotemItem extends TotemItem {
|
||||||
|
public DiamondTotemItem() {
|
||||||
|
super(Rarity.RARE, Config.Server.getDiamondTotemConfig().getDurability());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getName() {
|
||||||
|
return "diamond_totem";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCharge(ItemStack stack) {
|
||||||
|
return (stack.getItem() instanceof DiamondChargeItem);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package dev.micle.totemofreviving.item.totem;
|
||||||
|
|
||||||
|
import dev.micle.totemofreviving.setup.Config;
|
||||||
|
import dev.micle.totemofreviving.item.charge.IronChargeItem;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
|
||||||
|
public class IronTotemItem extends TotemItem {
|
||||||
|
public IronTotemItem() {
|
||||||
|
super(Config.Server.getIronTotemConfig().getDurability());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getName() {
|
||||||
|
return "iron_totem";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCharge(ItemStack stack) {
|
||||||
|
return (stack.getItem() instanceof IronChargeItem);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package dev.micle.totemofreviving.item.totem;
|
||||||
|
|
||||||
|
import dev.micle.totemofreviving.setup.Config;
|
||||||
|
import dev.micle.totemofreviving.item.charge.NetheriteChargeItem;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.Rarity;
|
||||||
|
|
||||||
|
public class NetheriteTotemItem extends TotemItem {
|
||||||
|
public NetheriteTotemItem() {
|
||||||
|
super(Rarity.EPIC, Config.Server.getNetheriteTotemConfig().getDurability());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getName() {
|
||||||
|
return "netherite_totem";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCharge(ItemStack stack) {
|
||||||
|
return (stack.getItem() instanceof NetheriteChargeItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFireResistant() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package dev.micle.totemofreviving.item.totem;
|
||||||
|
|
||||||
|
import dev.micle.totemofreviving.setup.Config;
|
||||||
|
import dev.micle.totemofreviving.item.charge.StrawChargeItem;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.Rarity;
|
||||||
|
|
||||||
|
public class StrawTotemItem extends TotemItem {
|
||||||
|
public StrawTotemItem() {
|
||||||
|
super(Rarity.UNCOMMON, Config.Server.getStrawTotemConfig().getDurability());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getName() {
|
||||||
|
return "straw_totem";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCharge(ItemStack stack) {
|
||||||
|
return (stack.getItem() instanceof StrawChargeItem);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,259 @@
|
|||||||
|
package dev.micle.totemofreviving.item.totem;
|
||||||
|
|
||||||
|
import dev.micle.totemofreviving.TotemOfReviving;
|
||||||
|
import dev.micle.totemofreviving.setup.Config;
|
||||||
|
import dev.micle.totemofreviving.network.client.ChangeTargetPacket;
|
||||||
|
import dev.micle.totemofreviving.network.client.ChargeTotemPacket;
|
||||||
|
import dev.micle.totemofreviving.network.NetworkManager;
|
||||||
|
import dev.micle.totemofreviving.network.client.ReviveTargetPacket;
|
||||||
|
import dev.micle.totemofreviving.setup.ModKeyMappings;
|
||||||
|
import net.minecraft.ChatFormatting;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.network.chat.TextComponent;
|
||||||
|
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.player.Player;
|
||||||
|
import net.minecraft.world.item.Item;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.Rarity;
|
||||||
|
import net.minecraft.world.item.TooltipFlag;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public abstract class TotemItem extends Item {
|
||||||
|
private static final String TAG_TARGET_INDEX = "target_index";
|
||||||
|
private static final String TAG_TARGET_UUID = "target_uuid";
|
||||||
|
private static final String TAG_TARGET_NAME = "target_name";
|
||||||
|
private static final String TAG_TARGET_DEATHS = "target_deaths";
|
||||||
|
private static final String TAG_CHARGE = "charge";
|
||||||
|
|
||||||
|
public TotemItem(int durability) {
|
||||||
|
this(Rarity.COMMON, durability);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TotemItem(Rarity rarity, int durability) {
|
||||||
|
super(new Properties().tab(TotemOfReviving.ITEM_GROUP).stacksTo(1).rarity(rarity).defaultDurability(durability));
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract boolean isCharge(ItemStack stack);
|
||||||
|
|
||||||
|
public static int getTargetIndex(ItemStack stack) {
|
||||||
|
if (!isTotem(stack)) { return -1; }
|
||||||
|
return stack.getOrCreateTag().getInt(TAG_TARGET_INDEX);
|
||||||
|
}
|
||||||
|
public static void setTargetIndex(ItemStack stack, int targetIndex) {
|
||||||
|
if (!isTotem(stack)) { return; }
|
||||||
|
stack.getOrCreateTag().putInt(TAG_TARGET_INDEX, targetIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UUID getTargetUUID(ItemStack stack) {
|
||||||
|
if (!isTotem(stack)) { return null; }
|
||||||
|
try {
|
||||||
|
return UUID.fromString(stack.getOrCreateTag().getString(TAG_TARGET_UUID));
|
||||||
|
} catch (IllegalArgumentException exception) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static void setTargetUUID(ItemStack stack, UUID targetUUID) {
|
||||||
|
if (!isTotem(stack)) { return; }
|
||||||
|
stack.getOrCreateTag().putString(TAG_TARGET_UUID, targetUUID.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getTargetName(ItemStack stack) {
|
||||||
|
if (!isTotem(stack)) { return null; }
|
||||||
|
return stack.getOrCreateTag().getString(TAG_TARGET_NAME);
|
||||||
|
}
|
||||||
|
public static void setTargetName(ItemStack stack, String targetName) {
|
||||||
|
if (!isTotem(stack)) { return; }
|
||||||
|
stack.getOrCreateTag().putString(TAG_TARGET_NAME, targetName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getTargetCost(ItemStack stack) {
|
||||||
|
if (!isTotem(stack)) { return -1; }
|
||||||
|
return !isCostDynamic(stack) ? getConfig(stack).getChargeCost() :
|
||||||
|
(int)(getTargetDeaths(stack) * getConfig(stack).getChargeCostMultiplier());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getTargetDeaths(ItemStack stack) {
|
||||||
|
if (!isTotem(stack)) { return -1; }
|
||||||
|
return stack.getOrCreateTag().getInt(TAG_TARGET_DEATHS);
|
||||||
|
}
|
||||||
|
public static void setTargetDeaths(ItemStack stack, ServerPlayer target) {
|
||||||
|
if (!isTotem(stack)) { return; }
|
||||||
|
stack.getOrCreateTag().putInt(TAG_TARGET_DEATHS, target.getStats().getValue(Stats.CUSTOM.get(Stats.DEATHS)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isTotemFull(ItemStack stack) {
|
||||||
|
if (!isTotem(stack)) { return false; }
|
||||||
|
return getCharge(stack) == getMaxCharge(stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean canTotemAffordTarget(ItemStack stack) {
|
||||||
|
if (!isTotem(stack)) { return false; }
|
||||||
|
if (getCharge(stack) < getTargetCost(stack)) {
|
||||||
|
if (!isTotemFull(stack)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return isTotemFull(stack) && canReviveMoreExpensiveTargets(stack);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getCharge(ItemStack stack) {
|
||||||
|
if (!isTotem(stack)) { return -1; }
|
||||||
|
int charge = stack.getOrCreateTag().getInt(TAG_CHARGE);
|
||||||
|
int maxCharge = getMaxCharge(stack);
|
||||||
|
if (charge > maxCharge) {
|
||||||
|
charge = maxCharge;
|
||||||
|
setCharge(stack, charge);
|
||||||
|
}
|
||||||
|
return charge;
|
||||||
|
}
|
||||||
|
public static void setCharge(ItemStack stack, int charge) {
|
||||||
|
if (!isTotem(stack)) { return; }
|
||||||
|
stack.getOrCreateTag().putInt(TAG_CHARGE, charge);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getMaxCharge(ItemStack stack) {
|
||||||
|
Config.TotemConfig config = getConfig(stack);
|
||||||
|
if (config == null) { return -1; }
|
||||||
|
|
||||||
|
if (config.getChargeCost() == -1) {
|
||||||
|
return config.getChargeCostLimit();
|
||||||
|
}
|
||||||
|
return config.getChargeCost();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isCostDynamic(ItemStack stack) {
|
||||||
|
if (!isTotem(stack)) { return false; }
|
||||||
|
return getConfig(stack).getChargeCost() == -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean canReviveAcrossDimensions(ItemStack stack) {
|
||||||
|
if (!isTotem(stack)) { return false; }
|
||||||
|
return getConfig(stack).getCanReviveAcrossDimensions();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean canReviveMoreExpensiveTargets(ItemStack stack) {
|
||||||
|
if (!isTotem(stack)) { return false; }
|
||||||
|
return getConfig(stack).getCanReviveMoreExpensiveTargets();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isEnabled(ItemStack stack) {
|
||||||
|
if (!isTotem(stack)) { return false; }
|
||||||
|
return getConfig(stack).getIsEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
public void appendHoverText(ItemStack stack, @Nullable Level world, List<Component> tooltip, TooltipFlag tooltipFlag) {
|
||||||
|
if (world == null) { return; }
|
||||||
|
|
||||||
|
UUID targetUUID = getTargetUUID(stack);
|
||||||
|
String targetName = getTargetName(stack);
|
||||||
|
int targetCost = getTargetCost(stack);
|
||||||
|
int charge = getCharge(stack);
|
||||||
|
int maxCharge = getMaxCharge(stack);
|
||||||
|
double multiplier = getConfig(stack).getChargeCostMultiplier();
|
||||||
|
|
||||||
|
if (getConfig(stack).getIsEnabled()) {
|
||||||
|
if (targetUUID == null) {
|
||||||
|
tooltip.add(new TextComponent(ChatFormatting.RED + "Target: " + ChatFormatting.DARK_RED + "NONE"));
|
||||||
|
} else {
|
||||||
|
tooltip.add(new TextComponent(ChatFormatting.WHITE + "Target: " + ChatFormatting.GRAY + targetName));
|
||||||
|
}
|
||||||
|
tooltip.add(new TextComponent(""));
|
||||||
|
if (!canTotemAffordTarget(stack)) {
|
||||||
|
tooltip.add(new TextComponent(ChatFormatting.RED + "Charges: " + ChatFormatting.DARK_RED + "(" + charge + "/" + targetCost + ") " +
|
||||||
|
ChatFormatting.RED + "[Max: " + ChatFormatting.DARK_RED + maxCharge + ChatFormatting.RED + "] [Multi: " + ChatFormatting.DARK_RED + multiplier + ChatFormatting.RED + "]"));
|
||||||
|
} else {
|
||||||
|
tooltip.add(new TextComponent(ChatFormatting.WHITE + "Charges: " + ChatFormatting.GRAY + "(" + charge + "/" + targetCost + ") " +
|
||||||
|
ChatFormatting.WHITE + "[Max: " + ChatFormatting.GRAY + maxCharge + ChatFormatting.WHITE + "] [Multi: " + ChatFormatting.GRAY + multiplier + ChatFormatting.WHITE + "]"));
|
||||||
|
}
|
||||||
|
if (canReviveMoreExpensiveTargets(stack)) {
|
||||||
|
tooltip.add(new TextComponent(ChatFormatting.WHITE + "Can revive more expensive targets."));
|
||||||
|
}
|
||||||
|
if (canReviveAcrossDimensions(stack)) {
|
||||||
|
tooltip.add(new TextComponent(ChatFormatting.WHITE + "Can revive targets across dimensions."));
|
||||||
|
}
|
||||||
|
tooltip.add(new TextComponent(""));
|
||||||
|
if (ModKeyMappings.ADVANCED_TOOLTIP.isDown()) {
|
||||||
|
tooltip.add(new TextComponent(ChatFormatting.GRAY + "Showing advanced tooltip."));
|
||||||
|
tooltip.add(new TextComponent(ChatFormatting.WHITE + "[" + ChatFormatting.GRAY + "R-CLICK" + ChatFormatting.WHITE + "]"));
|
||||||
|
tooltip.add(new TextComponent(ChatFormatting.WHITE + "When second hand is empty: revive target."));
|
||||||
|
tooltip.add(new TextComponent(ChatFormatting.WHITE + "When second hand is holding a reviving charge: charge totem."));
|
||||||
|
tooltip.add(new TextComponent(""));
|
||||||
|
tooltip.add(new TextComponent(ChatFormatting.WHITE + "[" + ChatFormatting.GRAY + "L-SHIFT + R-CLICK" + ChatFormatting.WHITE + "]"));
|
||||||
|
tooltip.add(new TextComponent(ChatFormatting.WHITE + "Change target."));
|
||||||
|
} else {
|
||||||
|
tooltip.add(new TextComponent(ChatFormatting.GRAY + "Hold [" + ChatFormatting.DARK_GRAY + "L-SHIFT" + ChatFormatting.GRAY + "] for advanced tooltip."));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tooltip.add(new TextComponent(ChatFormatting.RED + "Totem is disabled!"));
|
||||||
|
}
|
||||||
|
super.appendHoverText(stack, world, tooltip, tooltipFlag);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
public InteractionResultHolder<ItemStack> use(Level world, Player player, InteractionHand hand) {
|
||||||
|
if (!getConfig(player.getItemInHand(hand)).getIsEnabled() || !world.isClientSide) {
|
||||||
|
return super.use(world, player, hand);
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack chargeItem = (hand.equals(InteractionHand.MAIN_HAND)) ? player.getOffhandItem() : player.getMainHandItem();
|
||||||
|
|
||||||
|
if (player.isCrouching()) {
|
||||||
|
NetworkManager.getChannel().sendToServer(new ChangeTargetPacket(hand));
|
||||||
|
} else {
|
||||||
|
if (isCharge(chargeItem)) {
|
||||||
|
NetworkManager.getChannel().sendToServer(new ChargeTotemPacket(hand));
|
||||||
|
} else {
|
||||||
|
NetworkManager.getChannel().sendToServer(new ReviveTargetPacket(hand));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.use(world, player, hand);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxDamage(ItemStack stack) {
|
||||||
|
return getConfig(stack).getDurability();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDamageable(ItemStack stack) {
|
||||||
|
return (getConfig(stack).getDurability() != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDamage(ItemStack stack) {
|
||||||
|
if (isDamageable(stack) && super.getDamage(stack) >= getMaxDamage(stack)) {
|
||||||
|
stack.setCount(0);
|
||||||
|
return getMaxDamage(stack);
|
||||||
|
}
|
||||||
|
return (isDamageable(stack)) ? super.getDamage(stack) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isTotem(ItemStack stack) {
|
||||||
|
return (stack.getItem() instanceof TotemItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Config.TotemConfig getConfig(ItemStack stack) {
|
||||||
|
Item item = stack.getItem();
|
||||||
|
if (item instanceof StrawTotemItem) { return Config.Server.getStrawTotemConfig(); }
|
||||||
|
if (item instanceof IronTotemItem) { return Config.Server.getIronTotemConfig(); }
|
||||||
|
if (item instanceof DiamondTotemItem) { return Config.Server.getDiamondTotemConfig(); }
|
||||||
|
if (item instanceof NetheriteTotemItem) { return Config.Server.getNetheriteTotemConfig(); }
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package dev.micle.totemofreviving.network;
|
||||||
|
|
||||||
|
import dev.micle.totemofreviving.TotemOfReviving;
|
||||||
|
import dev.micle.totemofreviving.network.client.ChangeTargetPacket;
|
||||||
|
import dev.micle.totemofreviving.network.client.ChargeTotemPacket;
|
||||||
|
import dev.micle.totemofreviving.network.client.ReviveTargetPacket;
|
||||||
|
import net.minecraftforge.network.NetworkRegistry;
|
||||||
|
import net.minecraftforge.network.simple.SimpleChannel;
|
||||||
|
|
||||||
|
public class NetworkManager {
|
||||||
|
// Initialize variables
|
||||||
|
private static SimpleChannel channel;
|
||||||
|
|
||||||
|
public static void init() {
|
||||||
|
// Create channel
|
||||||
|
channel = NetworkRegistry.ChannelBuilder.named(TotemOfReviving.createResourceLocation("network"))
|
||||||
|
.clientAcceptedVersions(v -> v.equals(TotemOfReviving.getVersion()))
|
||||||
|
.serverAcceptedVersions(v -> v.equals(TotemOfReviving.getVersion()))
|
||||||
|
.networkProtocolVersion(TotemOfReviving::getVersion)
|
||||||
|
.simpleChannel();
|
||||||
|
|
||||||
|
// Register packets
|
||||||
|
int id = 0;
|
||||||
|
channel.messageBuilder(ChangeTargetPacket.class, id++)
|
||||||
|
.encoder(ChangeTargetPacket::encode)
|
||||||
|
.decoder(ChangeTargetPacket::decode)
|
||||||
|
.consumer(ChangeTargetPacket::handle)
|
||||||
|
.add();
|
||||||
|
channel.messageBuilder(ChargeTotemPacket.class, id++)
|
||||||
|
.encoder(ChargeTotemPacket::encode)
|
||||||
|
.decoder(ChargeTotemPacket::decode)
|
||||||
|
.consumer(ChargeTotemPacket::handle)
|
||||||
|
.add();
|
||||||
|
channel.messageBuilder(ReviveTargetPacket.class, id++)
|
||||||
|
.encoder(ReviveTargetPacket::encode)
|
||||||
|
.decoder(ReviveTargetPacket::decode)
|
||||||
|
.consumer(ReviveTargetPacket::handle)
|
||||||
|
.add();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SimpleChannel getChannel() {
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
package dev.micle.totemofreviving.network.client;
|
||||||
|
|
||||||
|
import dev.micle.totemofreviving.TotemOfReviving;
|
||||||
|
import dev.micle.totemofreviving.item.totem.TotemItem;
|
||||||
|
import dev.micle.totemofreviving.network.NetworkManager;
|
||||||
|
import net.minecraft.ChatFormatting;
|
||||||
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
|
import net.minecraft.network.chat.TextComponent;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.server.players.PlayerList;
|
||||||
|
import net.minecraft.world.InteractionHand;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraftforge.network.NetworkEvent;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class ChangeTargetPacket {
|
||||||
|
private final InteractionHand hand;
|
||||||
|
|
||||||
|
public ChangeTargetPacket(final InteractionHand hand) {
|
||||||
|
this.hand = hand;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void encode(final ChangeTargetPacket packet, final FriendlyByteBuf buffer) {
|
||||||
|
buffer.writeEnum(packet.hand);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ChangeTargetPacket decode(final FriendlyByteBuf buffer) {
|
||||||
|
return new ChangeTargetPacket(buffer.readEnum(InteractionHand.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void handle(final ChangeTargetPacket packet, final Supplier<NetworkEvent.Context> contextSupplier) {
|
||||||
|
final NetworkEvent.Context context = contextSupplier.get();
|
||||||
|
context.enqueueWork(() -> {
|
||||||
|
ServerPlayer sender = context.getSender();
|
||||||
|
if (sender == null) { return; }
|
||||||
|
|
||||||
|
ItemStack totemStack = sender.getItemInHand(packet.hand);
|
||||||
|
PlayerList playerList = TotemOfReviving.getProxy().getServer().getPlayerList();
|
||||||
|
int targetIndex = TotemItem.getTargetIndex(totemStack) + 1;
|
||||||
|
|
||||||
|
if (targetIndex > playerList.getPlayerCount()-1) { targetIndex = 0; }
|
||||||
|
ServerPlayer target = playerList.getPlayers().get(targetIndex);
|
||||||
|
|
||||||
|
TotemItem.setTargetIndex(totemStack, targetIndex);
|
||||||
|
TotemItem.setTargetUUID(totemStack, target.getUUID());
|
||||||
|
TotemItem.setTargetName(totemStack, target.getDisplayName().getString());
|
||||||
|
TotemItem.setTargetDeaths(totemStack, target);
|
||||||
|
|
||||||
|
sender.sendMessage(new TextComponent(ChatFormatting.WHITE + "Now targetting " + ChatFormatting.GRAY + target.getDisplayName().getString() + "."), sender.getUUID());
|
||||||
|
});
|
||||||
|
context.setPacketHandled(true);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package dev.micle.totemofreviving.network.client;
|
||||||
|
|
||||||
|
import dev.micle.totemofreviving.item.totem.TotemItem;
|
||||||
|
import dev.micle.totemofreviving.network.NetworkManager;
|
||||||
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.world.InteractionHand;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraftforge.network.NetworkEvent;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class ChargeTotemPacket {
|
||||||
|
private final InteractionHand hand;
|
||||||
|
|
||||||
|
public ChargeTotemPacket(final InteractionHand hand) {
|
||||||
|
this.hand = hand;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void encode(final ChargeTotemPacket packet, final FriendlyByteBuf buffer) {
|
||||||
|
buffer.writeEnum(packet.hand);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ChargeTotemPacket decode(final FriendlyByteBuf buffer) {
|
||||||
|
return new ChargeTotemPacket(buffer.readEnum(InteractionHand.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void handle(final ChargeTotemPacket packet, final Supplier<NetworkEvent.Context> contextSupplier) {
|
||||||
|
final NetworkEvent.Context context = contextSupplier.get();
|
||||||
|
context.enqueueWork(() -> {
|
||||||
|
ServerPlayer sender = context.getSender();
|
||||||
|
if (sender == null) { return; }
|
||||||
|
|
||||||
|
ItemStack totemStack = (packet.hand.equals(InteractionHand.MAIN_HAND)) ? sender.getMainHandItem() : sender.getOffhandItem();
|
||||||
|
ItemStack chargeStack = (packet.hand.equals(InteractionHand.MAIN_HAND)) ? sender.getOffhandItem() : sender.getMainHandItem();
|
||||||
|
|
||||||
|
if (TotemItem.isTotemFull(totemStack)) { return; }
|
||||||
|
|
||||||
|
TotemItem.setCharge(totemStack, TotemItem.getCharge(totemStack) + 1);
|
||||||
|
chargeStack.setCount(chargeStack.getCount() - 1);
|
||||||
|
});
|
||||||
|
context.setPacketHandled(true);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
package dev.micle.totemofreviving.network.client;
|
||||||
|
|
||||||
|
import dev.micle.totemofreviving.TotemOfReviving;
|
||||||
|
import dev.micle.totemofreviving.item.totem.TotemItem;
|
||||||
|
import dev.micle.totemofreviving.network.NetworkManager;
|
||||||
|
import net.minecraft.ChatFormatting;
|
||||||
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
|
import net.minecraft.network.chat.TextComponent;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.world.InteractionHand;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraftforge.network.NetworkEvent;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class ReviveTargetPacket {
|
||||||
|
private final InteractionHand hand;
|
||||||
|
|
||||||
|
public ReviveTargetPacket(final InteractionHand hand) {
|
||||||
|
this.hand = hand;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void encode(final ReviveTargetPacket packet, final FriendlyByteBuf buffer) {
|
||||||
|
buffer.writeEnum(packet.hand);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ReviveTargetPacket decode(final FriendlyByteBuf buffer) {
|
||||||
|
return new ReviveTargetPacket(buffer.readEnum(InteractionHand.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void handle(final ReviveTargetPacket packet, final Supplier<NetworkEvent.Context> contextSupplier) {
|
||||||
|
final NetworkEvent.Context context = contextSupplier.get();
|
||||||
|
context.enqueueWork(() -> {
|
||||||
|
ServerPlayer sender = context.getSender();
|
||||||
|
if (sender == null) { return; }
|
||||||
|
|
||||||
|
ItemStack totemStack = sender.getItemInHand(packet.hand);
|
||||||
|
ServerPlayer target;
|
||||||
|
|
||||||
|
try {
|
||||||
|
target = TotemOfReviving.getProxy().getServer().getPlayerList().getPlayer(TotemItem.getTargetUUID(totemStack));
|
||||||
|
if (target == null) { throw new NullPointerException("Target is null!"); }
|
||||||
|
} catch (NullPointerException exception) {
|
||||||
|
sender.sendMessage(new TextComponent(ChatFormatting.WHITE + "Unable to find player!"), sender.getUUID());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!target.isSpectator()) {
|
||||||
|
sender.sendMessage(new TextComponent(ChatFormatting.GRAY + target.getDisplayName().getString() + ChatFormatting.WHITE + " is not dead!"), sender.getUUID());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!target.getLevel().equals(sender.getLevel()) && !TotemItem.canReviveAcrossDimensions(totemStack)) {
|
||||||
|
sender.sendMessage(new TextComponent(ChatFormatting.GRAY + target.getDisplayName().getString() + ChatFormatting.WHITE + " is in a different dimension!"), sender.getUUID());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TotemItem.setTargetDeaths(totemStack, target);
|
||||||
|
if (!TotemItem.canTotemAffordTarget(totemStack)) {
|
||||||
|
sender.sendMessage(new TextComponent(ChatFormatting.WHITE + "Not enough charge!"), sender.getUUID());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
target.teleportTo(sender.getLevel(), sender.position().x, sender.position().y, sender.position().z, sender.getYRot(), sender.getXRot());
|
||||||
|
target.setGameMode(sender.getLevel().getServer().getDefaultGameType());
|
||||||
|
TotemItem.setCharge(totemStack, TotemItem.getCharge(totemStack) - TotemItem.getTargetCost(totemStack));
|
||||||
|
totemStack.hurtAndBreak(1, sender, e -> e.broadcastBreakEvent(packet.hand));
|
||||||
|
sender.sendMessage(new TextComponent(ChatFormatting.WHITE + "Successfully revived " + ChatFormatting.GRAY + target.getDisplayName().getString() + "!"), sender.getUUID());
|
||||||
|
});
|
||||||
|
context.setPacketHandled(true);
|
||||||
|
}
|
||||||
|
}
|
11
src/main/java/dev/micle/totemofreviving/proxy/IProxy.java
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package dev.micle.totemofreviving.proxy;
|
||||||
|
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
|
||||||
|
public interface IProxy {
|
||||||
|
MinecraftServer getServer();
|
||||||
|
Player getClientPlayer();
|
||||||
|
Level getClientWorld();
|
||||||
|
}
|
112
src/main/java/dev/micle/totemofreviving/proxy/Proxy.java
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
package dev.micle.totemofreviving.proxy;
|
||||||
|
|
||||||
|
import dev.micle.totemofreviving.setup.Config;
|
||||||
|
import dev.micle.totemofreviving.data.DataGenerators;
|
||||||
|
import dev.micle.totemofreviving.network.NetworkManager;
|
||||||
|
import dev.micle.totemofreviving.setup.Registration;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
|
import net.minecraftforge.event.AddReloadListenerEvent;
|
||||||
|
import net.minecraftforge.event.server.ServerStartedEvent;
|
||||||
|
import net.minecraftforge.event.server.ServerStoppingEvent;
|
||||||
|
import net.minecraftforge.eventbus.api.IEventBus;
|
||||||
|
import net.minecraftforge.fml.event.lifecycle.*;
|
||||||
|
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||||
|
|
||||||
|
public class Proxy implements IProxy {
|
||||||
|
// Initialize variables
|
||||||
|
private static MinecraftServer server = null;
|
||||||
|
|
||||||
|
// Common setup
|
||||||
|
public Proxy() {
|
||||||
|
// Initialize setup
|
||||||
|
Registration.register();
|
||||||
|
Config.init();
|
||||||
|
NetworkManager.init();
|
||||||
|
|
||||||
|
// Register mod event bus listeners
|
||||||
|
IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
|
||||||
|
modEventBus.addListener(DataGenerators::gatherData);
|
||||||
|
modEventBus.addListener(Proxy::setup);
|
||||||
|
modEventBus.addListener(Proxy::imcEnqueue);
|
||||||
|
modEventBus.addListener(Proxy::imcProcess);
|
||||||
|
|
||||||
|
// Register event bus listeners
|
||||||
|
MinecraftForge.EVENT_BUS.addListener(Proxy::onAddReloadListeners);
|
||||||
|
MinecraftForge.EVENT_BUS.addListener(Proxy::serverStarted);
|
||||||
|
MinecraftForge.EVENT_BUS.addListener(Proxy::serverStopping);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setup(FMLCommonSetupEvent event) {}
|
||||||
|
|
||||||
|
private static void imcEnqueue(InterModEnqueueEvent event) {}
|
||||||
|
|
||||||
|
private static void imcProcess(InterModProcessEvent event) {}
|
||||||
|
|
||||||
|
private static void onAddReloadListeners(AddReloadListenerEvent event) {}
|
||||||
|
|
||||||
|
private static void serverStarted(ServerStartedEvent event) {
|
||||||
|
server = event.getServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void serverStopping(ServerStoppingEvent event) {
|
||||||
|
server = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MinecraftServer getServer() {
|
||||||
|
return server;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Player getClientPlayer() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Level getClientWorld() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Client setup
|
||||||
|
public static class Client extends Proxy {
|
||||||
|
public Client() {
|
||||||
|
// Register mod event bus listeners
|
||||||
|
IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
|
||||||
|
modEventBus.addListener(Client::setup);
|
||||||
|
modEventBus.addListener(Client::postSetup);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setup(FMLClientSetupEvent event) {}
|
||||||
|
|
||||||
|
private static void postSetup(FMLLoadCompleteEvent event) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public Player getClientPlayer() {
|
||||||
|
return Minecraft.getInstance().player;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public Level getClientWorld() {
|
||||||
|
return Minecraft.getInstance().level;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Server setup
|
||||||
|
public static class Server extends Proxy {
|
||||||
|
public Server() {
|
||||||
|
// Register mod event bus listeners
|
||||||
|
IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
|
||||||
|
modEventBus.addListener(Server::setup);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setup(FMLDedicatedServerSetupEvent event) {}
|
||||||
|
}
|
||||||
|
}
|
95
src/main/java/dev/micle/totemofreviving/setup/Config.java
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
package dev.micle.totemofreviving.setup;
|
||||||
|
|
||||||
|
import dev.micle.totemofreviving.item.totem.DiamondTotemItem;
|
||||||
|
import dev.micle.totemofreviving.item.totem.IronTotemItem;
|
||||||
|
import dev.micle.totemofreviving.item.totem.NetheriteTotemItem;
|
||||||
|
import dev.micle.totemofreviving.item.totem.StrawTotemItem;
|
||||||
|
import net.minecraftforge.common.ForgeConfigSpec;
|
||||||
|
import net.minecraftforge.fml.ModLoadingContext;
|
||||||
|
import net.minecraftforge.fml.config.ModConfig;
|
||||||
|
|
||||||
|
public final class Config {
|
||||||
|
public static void init() {
|
||||||
|
ModLoadingContext.get().registerConfig(ModConfig.Type.SERVER, Server.SPEC);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Server {
|
||||||
|
private static final ForgeConfigSpec SPEC;
|
||||||
|
|
||||||
|
private static final TotemConfig STRAW_TOTEM_CONFIG;
|
||||||
|
private static final TotemConfig IRON_TOTEM_CONFIG;
|
||||||
|
private static final TotemConfig DIAMOND_TOTEM_CONFIG;
|
||||||
|
private static final TotemConfig NETHERITE_TOTEM_CONFIG;
|
||||||
|
|
||||||
|
static {
|
||||||
|
ForgeConfigSpec.Builder builder = new ForgeConfigSpec.Builder();
|
||||||
|
|
||||||
|
builder.comment("WHEN MAKING CHANGES IT IS RECOMMENDED TO NOT BE IN A WORLD.\n" +
|
||||||
|
"CHANGES WILL MOST LIKELY REQUIRE A RESTART FOR EVERYTHING TO WORK PROPERLY.");
|
||||||
|
STRAW_TOTEM_CONFIG = new TotemConfig(builder, StrawTotemItem.getName(), true, -1, 3,
|
||||||
|
1, false, false, 1);
|
||||||
|
IRON_TOTEM_CONFIG = new TotemConfig(builder, IronTotemItem.getName(), true, -1, 5,
|
||||||
|
0.75, false, false, 4);
|
||||||
|
DIAMOND_TOTEM_CONFIG = new TotemConfig(builder, DiamondTotemItem.getName(), true, -1, 10,
|
||||||
|
0.5, false, false, 10);
|
||||||
|
NETHERITE_TOTEM_CONFIG = new TotemConfig(builder, NetheriteTotemItem.getName(), true, 1, 1,
|
||||||
|
1, true, true, 0);
|
||||||
|
|
||||||
|
SPEC = builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TotemConfig getStrawTotemConfig() { return STRAW_TOTEM_CONFIG; }
|
||||||
|
public static TotemConfig getIronTotemConfig() { return IRON_TOTEM_CONFIG; }
|
||||||
|
public static TotemConfig getDiamondTotemConfig() { return DIAMOND_TOTEM_CONFIG; }
|
||||||
|
public static TotemConfig getNetheriteTotemConfig() { return NETHERITE_TOTEM_CONFIG; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class TotemConfig {
|
||||||
|
private final ForgeConfigSpec.BooleanValue IS_ENABLED;
|
||||||
|
private final ForgeConfigSpec.IntValue CHARGE_COST;
|
||||||
|
private final ForgeConfigSpec.IntValue CHARGE_COST_LIMIT;
|
||||||
|
private final ForgeConfigSpec.DoubleValue CHARGE_COST_MULTIPLIER;
|
||||||
|
private final ForgeConfigSpec.BooleanValue CAN_REVIVE_MORE_EXPENSIVE_TARGETS;
|
||||||
|
private final ForgeConfigSpec.BooleanValue CAN_REVIVE_ACROSS_DIMENSIONS;
|
||||||
|
private final ForgeConfigSpec.IntValue DURABILITY;
|
||||||
|
|
||||||
|
TotemConfig(ForgeConfigSpec.Builder builder, String name, boolean isEnabled, int chargeCost,
|
||||||
|
int chargeCostLimit, double chargeCostMultiplier, boolean canReviveMoreExpensiveTargets,
|
||||||
|
boolean canReviveAcrossDimensions, int durability) {
|
||||||
|
builder.push(name);
|
||||||
|
IS_ENABLED = builder
|
||||||
|
.comment("Is the " + name + " enabled?")
|
||||||
|
.define("isEnabled", isEnabled);
|
||||||
|
CHARGE_COST = builder
|
||||||
|
.comment("The charge cost to revive a player.\n" +
|
||||||
|
"-1 means the cost is dynamic (follows the amount of deaths the target has)\n" +
|
||||||
|
"Higher values set the charge cost to static, meaning that this will be the amount of charges needed to revive someone.")
|
||||||
|
.defineInRange("chargeCost", chargeCost, -1, Integer.MAX_VALUE);
|
||||||
|
CHARGE_COST_LIMIT = builder
|
||||||
|
.comment("The max amount of charge this totem can hold at once. Only works with dynamic cost.")
|
||||||
|
.defineInRange("chargeCostLimit", chargeCostLimit, 1, Integer.MAX_VALUE);
|
||||||
|
CHARGE_COST_MULTIPLIER = builder
|
||||||
|
.comment("Charge cost multiplier. 0.5 means the charge cost will be 50% of the original cost. Only works with dynamic cost.")
|
||||||
|
.defineInRange("chargeCostMultiplier", chargeCostMultiplier, 0.01, 100);
|
||||||
|
CAN_REVIVE_MORE_EXPENSIVE_TARGETS = builder
|
||||||
|
.comment("Is the totem able to revive targets that cost more than the totems max charge?\n" +
|
||||||
|
"This only applies if the totem is fully charged. (dynamic wont work if limit is 0)")
|
||||||
|
.define("canReviveMoreExpensiveTargets", canReviveMoreExpensiveTargets);
|
||||||
|
CAN_REVIVE_ACROSS_DIMENSIONS = builder
|
||||||
|
.comment("Is the totem able to revive targets across dimensions?")
|
||||||
|
.define("canReviveAcrossDimensions", canReviveAcrossDimensions);
|
||||||
|
DURABILITY = builder
|
||||||
|
.comment("The durability of the totem. 0 means unbreakable.")
|
||||||
|
.defineInRange("durability", durability, 0, Integer.MAX_VALUE);
|
||||||
|
builder.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getIsEnabled() { return IS_ENABLED.get(); }
|
||||||
|
public int getChargeCost() { return CHARGE_COST.get(); }
|
||||||
|
public int getChargeCostLimit() { return CHARGE_COST_LIMIT.get(); }
|
||||||
|
public double getChargeCostMultiplier() { return CHARGE_COST_MULTIPLIER.get(); }
|
||||||
|
public boolean getCanReviveMoreExpensiveTargets() { return CAN_REVIVE_MORE_EXPENSIVE_TARGETS.get(); }
|
||||||
|
public boolean getCanReviveAcrossDimensions() { return CAN_REVIVE_ACROSS_DIMENSIONS.get(); }
|
||||||
|
public int getDurability() { return DURABILITY.get(); }
|
||||||
|
}
|
||||||
|
}
|
26
src/main/java/dev/micle/totemofreviving/setup/ModItems.java
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package dev.micle.totemofreviving.setup;
|
||||||
|
|
||||||
|
import dev.micle.totemofreviving.item.charge.DiamondChargeItem;
|
||||||
|
import dev.micle.totemofreviving.item.charge.IronChargeItem;
|
||||||
|
import dev.micle.totemofreviving.item.charge.NetheriteChargeItem;
|
||||||
|
import dev.micle.totemofreviving.item.charge.StrawChargeItem;
|
||||||
|
import dev.micle.totemofreviving.item.totem.DiamondTotemItem;
|
||||||
|
import dev.micle.totemofreviving.item.totem.IronTotemItem;
|
||||||
|
import dev.micle.totemofreviving.item.totem.NetheriteTotemItem;
|
||||||
|
import dev.micle.totemofreviving.item.totem.StrawTotemItem;
|
||||||
|
import net.minecraft.world.item.Item;
|
||||||
|
import net.minecraftforge.registries.RegistryObject;
|
||||||
|
|
||||||
|
public class ModItems {
|
||||||
|
public static RegistryObject<Item> STRAW_TOTEM = Registration.ITEMS.register(StrawTotemItem.getName(), StrawTotemItem::new);
|
||||||
|
public static RegistryObject<Item> IRON_TOTEM = Registration.ITEMS.register(IronTotemItem.getName(), IronTotemItem::new);
|
||||||
|
public static RegistryObject<Item> DIAMOND_TOTEM = Registration.ITEMS.register(DiamondTotemItem.getName(), DiamondTotemItem::new);
|
||||||
|
public static RegistryObject<Item> NETHERITE_TOTEM = Registration.ITEMS.register(NetheriteTotemItem.getName(), NetheriteTotemItem::new);
|
||||||
|
|
||||||
|
public static RegistryObject<Item> STRAW_CHARGE = Registration.ITEMS.register(StrawChargeItem.getName(), StrawChargeItem::new);
|
||||||
|
public static RegistryObject<Item> IRON_CHARGE = Registration.ITEMS.register(IronChargeItem.getName(), IronChargeItem::new);
|
||||||
|
public static RegistryObject<Item> DIAMOND_CHARGE = Registration.ITEMS.register(DiamondChargeItem.getName(), DiamondChargeItem::new);
|
||||||
|
public static RegistryObject<Item> NETHERITE_CHARGE = Registration.ITEMS.register(NetheriteChargeItem.getName(), NetheriteChargeItem::new);
|
||||||
|
|
||||||
|
public static void register() {}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package dev.micle.totemofreviving.setup;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.platform.InputConstants;
|
||||||
|
import net.minecraft.client.KeyMapping;
|
||||||
|
|
||||||
|
public class ModKeyMappings {
|
||||||
|
public static final KeyMapping ADVANCED_TOOLTIP =
|
||||||
|
new KeyMapping("advanced_tooltips", InputConstants.KEY_LSHIFT, KeyMapping.CATEGORY_INVENTORY);
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package dev.micle.totemofreviving.setup;
|
||||||
|
|
||||||
|
import dev.micle.totemofreviving.item.crafting.ChargeRecipe;
|
||||||
|
import dev.micle.totemofreviving.item.crafting.ExtendedShapedRecipe;
|
||||||
|
import dev.micle.totemofreviving.item.crafting.TotemRecipe;
|
||||||
|
import net.minecraft.world.item.crafting.RecipeSerializer;
|
||||||
|
import net.minecraftforge.registries.RegistryObject;
|
||||||
|
|
||||||
|
public class ModRecipes {
|
||||||
|
public static final RegistryObject<RecipeSerializer<?>> TOTEM_RECIPE =
|
||||||
|
Registration.RECIPE_SERIALIZERS.register("totem_recipe", () -> ExtendedShapedRecipe.Serializer.basic(TotemRecipe::new));
|
||||||
|
public static final RegistryObject<RecipeSerializer<?>> CHARGE_RECIPE =
|
||||||
|
Registration.RECIPE_SERIALIZERS.register("charge_recipe", () -> ExtendedShapedRecipe.Serializer.basic(ChargeRecipe::new));
|
||||||
|
|
||||||
|
public static void register() {}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package dev.micle.totemofreviving.setup;
|
||||||
|
|
||||||
|
import dev.micle.totemofreviving.TotemOfReviving;
|
||||||
|
import net.minecraft.world.item.Item;
|
||||||
|
import net.minecraft.world.item.crafting.RecipeSerializer;
|
||||||
|
import net.minecraftforge.eventbus.api.IEventBus;
|
||||||
|
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||||
|
import net.minecraftforge.registries.DeferredRegister;
|
||||||
|
import net.minecraftforge.registries.ForgeRegistries;
|
||||||
|
import net.minecraftforge.registries.IForgeRegistry;
|
||||||
|
import net.minecraftforge.registries.IForgeRegistryEntry;
|
||||||
|
|
||||||
|
public class Registration {
|
||||||
|
// Initialize variables
|
||||||
|
public static final DeferredRegister<Item> ITEMS = create(ForgeRegistries.ITEMS);
|
||||||
|
public static final DeferredRegister<RecipeSerializer<?>> RECIPE_SERIALIZERS = create(ForgeRegistries.RECIPE_SERIALIZERS);
|
||||||
|
|
||||||
|
public static void register() {
|
||||||
|
IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
|
||||||
|
|
||||||
|
ITEMS.register(modEventBus);
|
||||||
|
ModItems.register();
|
||||||
|
|
||||||
|
RECIPE_SERIALIZERS.register(modEventBus);
|
||||||
|
ModRecipes.register();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T extends IForgeRegistryEntry<T>> DeferredRegister<T> create(IForgeRegistry<T> registry) {
|
||||||
|
return DeferredRegister.create(registry, TotemOfReviving.MOD_ID);
|
||||||
|
}
|
||||||
|
}
|
58
src/main/resources/META-INF/mods.toml
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
# This is an example mods.toml file. It contains the data relating to the loading mods.
|
||||||
|
# There are several mandatory fields (#mandatory), and many more that are optional (#optional).
|
||||||
|
# The overall format is standard TOML format, v0.5.0.
|
||||||
|
# Note that there are a couple of TOML lists in this file.
|
||||||
|
# Find more information on toml format here: https://github.com/toml-lang/toml
|
||||||
|
# The name of the mod loader type to load - for regular FML @Mod mods it should be javafml
|
||||||
|
modLoader = "javafml" #mandatory
|
||||||
|
# A version range to match for said mod loader - for regular FML @Mod it will be the forge version
|
||||||
|
loaderVersion = "[43,)" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions.
|
||||||
|
# The license for you mod. This is mandatory metadata and allows for easier comprehension of your redistributive properties.
|
||||||
|
# Review your options at https://choosealicense.com/. All rights reserved is the default copyright stance, and is thus the default here.
|
||||||
|
license = "All Rights Reserved"
|
||||||
|
# A URL to refer people to when problems occur with this mod
|
||||||
|
#issueTrackerURL="http://my.issue.tracker/" #optional
|
||||||
|
# A list of mods - how many allowed here is determined by the individual mod loader
|
||||||
|
[[mods]] #mandatory
|
||||||
|
# The modid of the mod
|
||||||
|
modId = "totemofreviving" #mandatory
|
||||||
|
# The version number of the mod - there's a few well known ${} variables useable here or just hardcode it
|
||||||
|
# ${file.jarVersion} will substitute the value of the Implementation-Version as read from the mod's JAR file metadata
|
||||||
|
# see the associated build.gradle script for how to populate this completely automatically during a build
|
||||||
|
version = "${file.jarVersion}" #mandatory
|
||||||
|
# A display name for the mod
|
||||||
|
displayName = "Micle's Totem of Reviving" #mandatory
|
||||||
|
# A URL to query for updates for this mod. See the JSON update specification <here>
|
||||||
|
#updateJSONURL="http://myurl.me/" #optional
|
||||||
|
# A URL for the "homepage" for this mod, displayed in the mod UI
|
||||||
|
#displayURL="http://example.com/" #optional
|
||||||
|
# A file name (in the root of the mod JAR) containing a logo for display
|
||||||
|
logoFile="logo.jpg" #optional
|
||||||
|
# A text field displayed in the mod UI
|
||||||
|
#credits="Thanks for this example mod goes to Java" #optional
|
||||||
|
# A text field displayed in the mod UI
|
||||||
|
authors="Micle" #optional
|
||||||
|
# The description text for the mod (multi line!) (#mandatory)
|
||||||
|
description = '''
|
||||||
|
Mod for reviving players in a hardcore world.
|
||||||
|
'''
|
||||||
|
# A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional.
|
||||||
|
[[dependencies.totemofreviving]] #optional
|
||||||
|
# the modid of the dependency
|
||||||
|
modId = "forge" #mandatory
|
||||||
|
# Does this dependency have to exist - if not, ordering below must be specified
|
||||||
|
mandatory = true #mandatory
|
||||||
|
# The version range of the dependency
|
||||||
|
versionRange = "[43,)" #mandatory
|
||||||
|
# An ordering relationship for the dependency - BEFORE or AFTER required if the relationship is not mandatory
|
||||||
|
ordering = "NONE"
|
||||||
|
# Side this dependency is applied on - BOTH, CLIENT or SERVER
|
||||||
|
side = "BOTH"
|
||||||
|
# Here's another dependency
|
||||||
|
[[dependencies.totemofreviving]]
|
||||||
|
modId = "minecraft"
|
||||||
|
mandatory = true
|
||||||
|
# This version range declares a minimum of the current minecraft version up to but not including the next major version
|
||||||
|
versionRange = "[1.19.2,1.20)"
|
||||||
|
ordering = "NONE"
|
||||||
|
side = "BOTH"
|
12
src/main/resources/assets/totemofreviving/lang/en_us.json
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"itemGroup.totemofreviving": "Micle's Totem of Reviving",
|
||||||
|
"item.totemofreviving.straw_totem": "Straw totem of reviving",
|
||||||
|
"item.totemofreviving.iron_totem": "Iron totem of reviving",
|
||||||
|
"item.totemofreviving.diamond_totem": "Diamond totem of reviving",
|
||||||
|
"item.totemofreviving.netherite_totem": "Netherite totem of reviving",
|
||||||
|
"item.totemofreviving.straw_charge": "Straw reviving charge",
|
||||||
|
"item.totemofreviving.iron_charge": "Iron reviving charge",
|
||||||
|
"item.totemofreviving.diamond_charge": "Diamond reviving charge",
|
||||||
|
"item.totemofreviving.netherite_charge": "Netherite reviving charge",
|
||||||
|
"advanced_tooltips": "advanced_tooltips"
|
||||||
|
}
|
After Width: | Height: | Size: 259 B |
After Width: | Height: | Size: 287 B |
After Width: | Height: | Size: 721 B |
After Width: | Height: | Size: 826 B |
After Width: | Height: | Size: 741 B |
After Width: | Height: | Size: 836 B |
After Width: | Height: | Size: 753 B |
After Width: | Height: | Size: 5.7 KiB |
BIN
src/main/resources/logo.jpg
Normal file
After Width: | Height: | Size: 98 KiB |
6
src/main/resources/pack.mcmeta
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"pack": {
|
||||||
|
"description": "totemofreviving resources",
|
||||||
|
"pack_format": 8
|
||||||
|
}
|
||||||
|
}
|