Initial commit
This commit is contained in:
118
.gitignore
vendored
Normal file
118
.gitignore
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
# User-specific stuff
|
||||
.idea/
|
||||
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Compiled class file
|
||||
*.class
|
||||
|
||||
# Log file
|
||||
*.log
|
||||
|
||||
# BlueJ files
|
||||
*.ctxt
|
||||
|
||||
# Package Files #
|
||||
*.jar
|
||||
*.war
|
||||
*.nar
|
||||
*.ear
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.rar
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
|
||||
*~
|
||||
|
||||
# temporary files which can be created if a process still has a handle open of a deleted file
|
||||
.fuse_hidden*
|
||||
|
||||
# KDE directory preferences
|
||||
.directory
|
||||
|
||||
# Linux trash folder which might appear on any partition or disk
|
||||
.Trash-*
|
||||
|
||||
# .nfs files are created when an open file is removed but is still being accessed
|
||||
.nfs*
|
||||
|
||||
# General
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
# Windows thumbnail cache files
|
||||
Thumbs.db
|
||||
Thumbs.db:encryptable
|
||||
ehthumbs.db
|
||||
ehthumbs_vista.db
|
||||
|
||||
# Dump file
|
||||
*.stackdump
|
||||
|
||||
# Folder config file
|
||||
[Dd]esktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
.gradle
|
||||
build/
|
||||
|
||||
# Ignore Gradle GUI config
|
||||
gradle-app.setting
|
||||
|
||||
# Cache of project
|
||||
.gradletasknamecache
|
||||
|
||||
**/build/
|
||||
|
||||
# Common working directory
|
||||
run/
|
||||
|
||||
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
|
||||
!gradle-wrapper.jar
|
||||
140
build.gradle
Normal file
140
build.gradle
Normal file
@@ -0,0 +1,140 @@
|
||||
plugins {
|
||||
id 'eclipse'
|
||||
id 'idea'
|
||||
id 'net.minecraftforge.gradle' version '[6.0.16,6.2)'
|
||||
id 'maven-publish'
|
||||
}
|
||||
|
||||
|
||||
group = "com.oierbravo.${mod_id}"
|
||||
version = "${minecraft_version}-${mod_version}"
|
||||
archivesBaseName = mod_id
|
||||
|
||||
|
||||
java {
|
||||
toolchain.languageVersion = JavaLanguageVersion.of(17)
|
||||
}
|
||||
|
||||
minecraft {
|
||||
mappings channel: mapping_channel, version: mapping_version
|
||||
|
||||
copyIdeResources = true
|
||||
|
||||
runs {
|
||||
// applies to all the run configs below
|
||||
configureEach {
|
||||
workingDirectory project.file('run')
|
||||
|
||||
// Recommended logging data for a userdev environment
|
||||
// The markers can be added/remove as needed separated by commas.
|
||||
// "SCAN": For mods scan.
|
||||
// "REGISTRIES": For firing of registry events.
|
||||
// "REGISTRYDUMP": For getting the contents of all registries.
|
||||
property 'forge.logging.markers', 'REGISTRIES'
|
||||
|
||||
|
||||
// Recommended logging level for the console
|
||||
// You can set various levels here.
|
||||
// Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels
|
||||
property 'forge.logging.console.level', 'debug'
|
||||
|
||||
mods {
|
||||
"${mod_id}" {
|
||||
source sourceSets.main
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
client {
|
||||
// Comma-separated list of namespaces to load gametests from. Empty = all namespaces.
|
||||
property 'forge.enabledGameTestNamespaces', mod_id
|
||||
}
|
||||
|
||||
server {
|
||||
property 'forge.enabledGameTestNamespaces', mod_id
|
||||
args '--nogui'
|
||||
}
|
||||
|
||||
// This run config launches GameTestServer and runs all registered gametests, then exits.
|
||||
// By default, the server will crash when no gametests are provided.
|
||||
// The gametest system is also enabled by default for other run configs under the /test command.
|
||||
gameTestServer {
|
||||
property 'forge.enabledGameTestNamespaces', mod_id
|
||||
}
|
||||
|
||||
data {
|
||||
// example of overriding the workingDirectory set in configureEach above
|
||||
workingDirectory project.file('run-data')
|
||||
|
||||
// Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources.
|
||||
args '--mod', mod_id, '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Include resources generated by data generators.
|
||||
sourceSets.main.resources { srcDir 'src/generated/resources' }
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
// location of the maven for Registrate and Flywheel
|
||||
name = 'tterrag maven'
|
||||
url = 'https://maven.tterrag.com'
|
||||
}
|
||||
maven {
|
||||
url = 'https://www.cursemaven.com'
|
||||
content {
|
||||
includeGroup "curse.maven"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
|
||||
|
||||
implementation fg.deobf("curse.maven:jade-324717:${jade_id}")
|
||||
|
||||
implementation fg.deobf("com.simibubi.create:create-${create_minecraft_version}:${create_version}:slim") { transitive = false }
|
||||
implementation fg.deobf("com.jozufozu.flywheel:flywheel-forge-${flywheel_minecraft_version}:${flywheel_version}")
|
||||
implementation fg.deobf("com.tterrag.registrate:Registrate:${registrate_version}")
|
||||
}
|
||||
|
||||
tasks.named('processResources', ProcessResources).configure {
|
||||
var replaceProperties = [minecraft_version : minecraft_version, minecraft_version_range: minecraft_version_range,
|
||||
forge_version : forge_version, forge_version_range: forge_version_range,
|
||||
loader_version_range: loader_version_range,
|
||||
mod_id : mod_id, mod_name: mod_name, mod_license: mod_license, mod_version: mod_version,
|
||||
mod_authors : mod_authors, mod_description: mod_description,]
|
||||
|
||||
inputs.properties replaceProperties
|
||||
|
||||
filesMatching(['META-INF/mods.toml', 'pack.mcmeta']) {
|
||||
expand replaceProperties + [project: project]
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named('jar', Jar).configure {
|
||||
manifest {
|
||||
attributes(["Specification-Title" : mod_id,
|
||||
"Specification-Vendor" : mod_authors,
|
||||
"Specification-Version" : "1", // We are version 1 of ourselves
|
||||
"Implementation-Title" : project.name,
|
||||
"Implementation-Version" : project.jar.archiveVersion,
|
||||
"Implementation-Vendor" : mod_authors,
|
||||
"Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ")])
|
||||
}
|
||||
|
||||
finalizedBy 'reobfJar'
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile).configureEach {
|
||||
options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation
|
||||
}
|
||||
publishing {
|
||||
// other settings of publication
|
||||
publications {
|
||||
mavenJava(MavenPublication) {
|
||||
artifact jar
|
||||
}
|
||||
}
|
||||
}
|
||||
27
gradle.properties
Normal file
27
gradle.properties
Normal file
@@ -0,0 +1,27 @@
|
||||
org.gradle.jvmargs=-Xmx3G
|
||||
org.gradle.daemon=false
|
||||
|
||||
minecraft_version=1.20.1
|
||||
minecraft_version_range=[1.20.1,1.21)
|
||||
forge_version=47.3.7
|
||||
forge_version_range=[47,)
|
||||
loader_version_range=[47,)
|
||||
mapping_channel=official
|
||||
mapping_version=1.20.1
|
||||
|
||||
mod_id=mechanical_lemon_lib
|
||||
mod_name=MechanicalLemonLib
|
||||
mod_license=MIT
|
||||
mod_version=0.0.23
|
||||
mod_group_id=com.oierbravo
|
||||
mod_authors=oierbravo
|
||||
mod_description=Library
|
||||
|
||||
# dependency versions
|
||||
create_minecraft_version = 1.20.1
|
||||
flywheel_minecraft_version = 1.20.1
|
||||
create_version = 0.5.1.h-48
|
||||
flywheel_version = 0.6.11-13
|
||||
registrate_version = MC1.20-1.3.3
|
||||
|
||||
jade_id = 4654448
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
7
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
7
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
249
gradlew
vendored
Executable file
249
gradlew
vendored
Executable file
@@ -0,0 +1,249 @@
|
||||
#!/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/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# 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
|
||||
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
|
||||
|
||||
# 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
|
||||
if ! command -v java >/dev/null 2>&1
|
||||
then
|
||||
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
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
|
||||
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command:
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# and any embedded shellness will be escaped.
|
||||
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||
# treated as '${Hostname}' itself on the command line.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
if ! command -v xargs >/dev/null 2>&1
|
||||
then
|
||||
die "xargs is not available"
|
||||
fi
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
#
|
||||
# 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" "$@"
|
||||
92
gradlew.bat
vendored
Normal file
92
gradlew.bat
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
@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=.
|
||||
@rem This is normally unused
|
||||
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% equ 0 goto execute
|
||||
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
: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% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
15
settings.gradle
Normal file
15
settings.gradle
Normal file
@@ -0,0 +1,15 @@
|
||||
pluginManagement {
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
maven {
|
||||
name = 'MinecraftForge'
|
||||
url = 'https://maven.minecraftforge.net/'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.7.0'
|
||||
}
|
||||
|
||||
rootProject.name = 'MechanicalLemonLib'
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.oierbravo.mechanical_lemon_lib;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.oierbravo.mechanical_lemon_lib.register.LemonCreativeModeTabs;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.world.food.FoodProperties;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.CreativeModeTab;
|
||||
import net.minecraft.world.item.CreativeModeTabs;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||
import net.minecraft.world.level.material.MapColor;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.BuildCreativeModeTabContentsEvent;
|
||||
import net.minecraftforge.event.server.ServerStartingEvent;
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.ModLoadingContext;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.config.ModConfig;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
import net.minecraftforge.registries.DeferredRegister;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
import net.minecraftforge.registries.RegistryObject;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@Mod(MechanicalLemonLib.MODID)
|
||||
public class MechanicalLemonLib {
|
||||
|
||||
public static final String MODID = "mechanical_lemon_lib";
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
public MechanicalLemonLib() {
|
||||
IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
|
||||
|
||||
MinecraftForge.EVENT_BUS.register(this);
|
||||
LemonCreativeModeTabs.register(modEventBus);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
package com.oierbravo.mechanical_lemon_lib.foundation.blockEntity.behaviour;
|
||||
|
||||
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
|
||||
import com.simibubi.create.foundation.blockEntity.behaviour.BehaviourType;
|
||||
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
public class CycleBehavior extends BlockEntityBehaviour {
|
||||
|
||||
private final int CYCLE;
|
||||
private boolean ACTUATE_HALFCYCLE;
|
||||
public static final BehaviourType<CycleBehavior> TYPE = new BehaviourType<>();
|
||||
public CycleBehaviourSpecifics specifics;
|
||||
private int prevRunningTicks;
|
||||
private int runningTicks;
|
||||
private boolean running;
|
||||
private boolean finished;
|
||||
private int cycleDivider;
|
||||
|
||||
|
||||
public interface CycleBehaviourSpecifics {
|
||||
|
||||
public void onCycleCompleted();
|
||||
public float getKineticSpeed();
|
||||
public boolean tryProcess(boolean simulate);
|
||||
public void playSound();
|
||||
}
|
||||
|
||||
public <T extends SmartBlockEntity & CycleBehaviourSpecifics> CycleBehavior(T te, int pCycle, boolean pActuateHalfCycle) {
|
||||
super(te);
|
||||
this.specifics = te;
|
||||
CYCLE = pCycle;
|
||||
ACTUATE_HALFCYCLE = pActuateHalfCycle;
|
||||
cycleDivider = (ACTUATE_HALFCYCLE) ? 2 : 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(CompoundTag compound, boolean clientPacket) {
|
||||
running = compound.getBoolean("Running");
|
||||
finished = compound.getBoolean("Finished");
|
||||
prevRunningTicks = runningTicks = compound.getInt("Ticks");
|
||||
super.read(compound, clientPacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CompoundTag compound, boolean clientPacket) {
|
||||
compound.putBoolean("Running", running);
|
||||
compound.putBoolean("Finished", finished);
|
||||
compound.putInt("Ticks", runningTicks);
|
||||
super.write(compound, clientPacket);
|
||||
}
|
||||
|
||||
public void start() {
|
||||
running = true;
|
||||
prevRunningTicks = 0;
|
||||
runningTicks = 0;
|
||||
blockEntity.sendData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BehaviourType<?> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
|
||||
Level level = getWorld();
|
||||
if (!running || level == null) {
|
||||
if (level != null && !level.isClientSide) {
|
||||
|
||||
if (specifics.getKineticSpeed() == 0)
|
||||
return;
|
||||
|
||||
if (specifics.tryProcess( true))
|
||||
start();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (level.isClientSide && runningTicks == -CYCLE / cycleDivider) {
|
||||
prevRunningTicks = CYCLE / cycleDivider;
|
||||
return;
|
||||
}
|
||||
|
||||
if (runningTicks == CYCLE / 2 && specifics.getKineticSpeed() != 0) {
|
||||
apply();
|
||||
specifics.playSound();
|
||||
if (!level.isClientSide)
|
||||
blockEntity.sendData();
|
||||
}
|
||||
|
||||
if (!level.isClientSide && runningTicks > CYCLE / cycleDivider) {
|
||||
finished = true;
|
||||
running = false;
|
||||
blockEntity.sendData();
|
||||
specifics.onCycleCompleted();
|
||||
return;
|
||||
}
|
||||
|
||||
prevRunningTicks = runningTicks;
|
||||
runningTicks += getRunningTickSpeed();
|
||||
if (prevRunningTicks < CYCLE / 2 && runningTicks >= CYCLE / cycleDivider) {
|
||||
runningTicks = CYCLE / 2;
|
||||
// Pause the ticks until a packet is received
|
||||
if (level.isClientSide && !blockEntity.isVirtual())
|
||||
runningTicks = -(CYCLE / 2);
|
||||
}
|
||||
}
|
||||
|
||||
public float getProgress(float partialTicks){
|
||||
if (!running)
|
||||
return 0;
|
||||
int runningTicks = Math.abs(this.runningTicks);
|
||||
float ticks = Mth.lerp(partialTicks, prevRunningTicks, runningTicks);
|
||||
return ticks/ CYCLE * 100;
|
||||
}
|
||||
|
||||
|
||||
protected void apply() {
|
||||
Level level = getWorld();
|
||||
|
||||
if (level.isClientSide)
|
||||
return;
|
||||
|
||||
if (specifics.tryProcess(false))
|
||||
blockEntity.sendData();
|
||||
}
|
||||
|
||||
public int getRunningTickSpeed() {
|
||||
float speed = specifics.getKineticSpeed();
|
||||
if (speed == 0)
|
||||
return 0;
|
||||
return (int) Mth.lerp(Mth.clamp(Math.abs(speed) / 512f, 0, 1), 1, 60);
|
||||
}
|
||||
public boolean isRunning(){
|
||||
return running;
|
||||
}
|
||||
public int getProgressPercent() {
|
||||
return Mth.clamp(runningTicks * 100 / (CYCLE/cycleDivider), 0,100);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
package com.oierbravo.mechanical_lemon_lib.foundation.blockEntity.behaviour;
|
||||
|
||||
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
|
||||
import com.simibubi.create.foundation.blockEntity.behaviour.BehaviourType;
|
||||
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
public class DynamicCycleBehavior extends BlockEntityBehaviour {
|
||||
|
||||
public static final BehaviourType<DynamicCycleBehavior> TYPE = new BehaviourType<>();
|
||||
public DynamicCycleBehaviorSpecifics specifics;
|
||||
private int prevRunningTicks;
|
||||
private int runningTicks;
|
||||
private int processingTime;
|
||||
private int currentTime;
|
||||
private boolean running;
|
||||
private boolean finished;
|
||||
|
||||
public interface DynamicCycleBehaviorSpecifics {
|
||||
|
||||
void onCycleCompleted();
|
||||
float getKineticSpeed();
|
||||
int getProcessingTime();
|
||||
boolean tryProcess(boolean simulate);
|
||||
void playSound();
|
||||
}
|
||||
|
||||
public <T extends SmartBlockEntity & DynamicCycleBehaviorSpecifics> DynamicCycleBehavior(T te) {
|
||||
super(te);
|
||||
this.specifics = te;
|
||||
processingTime = 0;
|
||||
currentTime = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(CompoundTag compound, boolean clientPacket) {
|
||||
currentTime = compound.getInt("CurrentTime");
|
||||
processingTime = compound.getInt("ProcessingTime");
|
||||
running = compound.getBoolean("Running");
|
||||
finished = compound.getBoolean("Finished");
|
||||
super.read(compound, clientPacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CompoundTag compound, boolean clientPacket) {
|
||||
compound.putInt("CurrentTime", currentTime);
|
||||
compound.putInt("ProcessingTime", processingTime);
|
||||
compound.putBoolean("Running", running);
|
||||
compound.putBoolean("Finished", finished);
|
||||
super.write(compound, clientPacket);
|
||||
}
|
||||
|
||||
public void start() {
|
||||
running = true;
|
||||
currentTime = 0;
|
||||
processingTime = specifics.getProcessingTime();
|
||||
blockEntity.sendData();
|
||||
}
|
||||
public void stop(){
|
||||
running = false;
|
||||
currentTime = 0;
|
||||
processingTime = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BehaviourType<?> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
|
||||
Level level = getWorld();
|
||||
if (!running || level == null) {
|
||||
if (level != null && !level.isClientSide) {
|
||||
|
||||
if (specifics.getKineticSpeed() == 0)
|
||||
return;
|
||||
|
||||
if (specifics.tryProcess( true))
|
||||
start();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(running)
|
||||
currentTime += getRunningTickSpeed();
|
||||
|
||||
if (currentTime >= getProccessingTime() && specifics.getKineticSpeed() != 0) {
|
||||
specifics.playSound();
|
||||
if (!level.isClientSide){
|
||||
stop();
|
||||
apply();
|
||||
specifics.onCycleCompleted();
|
||||
blockEntity.sendData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float getProgress(float partialTicks){
|
||||
int runningTicks = Math.abs(this.runningTicks);
|
||||
float ticks = Mth.lerp(partialTicks, prevRunningTicks, runningTicks);
|
||||
return ticks/ getProccessingTime() * 100;
|
||||
}
|
||||
protected int getProccessingTime(){
|
||||
return processingTime;
|
||||
}
|
||||
|
||||
protected void apply() {
|
||||
Level level = getWorld();
|
||||
|
||||
if (level.isClientSide)
|
||||
return;
|
||||
|
||||
if (specifics.tryProcess(false))
|
||||
blockEntity.sendData();
|
||||
}
|
||||
|
||||
public int getRunningTickSpeed() {
|
||||
float speed = specifics.getKineticSpeed();
|
||||
if (speed == 0)
|
||||
return 0;
|
||||
return (int) Mth.lerp(Mth.clamp(Math.abs(speed) / 512f, 0, 1), 1, 30);
|
||||
}
|
||||
public int getProgressPercent() {
|
||||
if(!running)
|
||||
return 0;
|
||||
return Mth.clamp(currentTime * 100 / (getProccessingTime()), 0,100);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
package com.oierbravo.mechanical_lemon_lib.foundation.blockEntity.behaviour;
|
||||
|
||||
import com.oierbravo.mechanical_lemon_lib.foundation.recipe.IRecipeWithRequirements;
|
||||
import com.oierbravo.mechanical_lemon_lib.foundation.recipe.RecipeRequirement;
|
||||
import com.oierbravo.mechanical_lemon_lib.foundation.recipe.RecipeRequirementType;
|
||||
import com.oierbravo.mechanical_lemon_lib.utility.LibLang;
|
||||
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
|
||||
import com.simibubi.create.foundation.blockEntity.behaviour.BehaviourType;
|
||||
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class RecipeRequirementsBehaviour<R extends IRecipeWithRequirements> extends BlockEntityBehaviour {
|
||||
public static final BehaviourType<RecipeRequirementsBehaviour<?>> TYPE = new BehaviourType<>();
|
||||
|
||||
public RecipeRequirementsSpecifics<R> specifics;
|
||||
|
||||
private boolean meetsRequirements;
|
||||
private boolean meetsIngredients;
|
||||
private boolean hasEnoughOutput;
|
||||
private ArrayList<String> missingRequirements;
|
||||
|
||||
public <T extends SmartBlockEntity & RecipeRequirementsSpecifics<R>> RecipeRequirementsBehaviour(T te) {
|
||||
super(te);
|
||||
this.specifics = te;
|
||||
this.meetsIngredients = false;
|
||||
this.missingRequirements = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BehaviourType<?> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
public boolean meetsRequirements(){
|
||||
return meetsRequirements;
|
||||
}
|
||||
|
||||
public <T> boolean checkRequirements(Optional<R> pRecipe, Level pLevel, T pBlockEntity) {
|
||||
missingRequirements = new ArrayList<>();
|
||||
boolean result = true;
|
||||
|
||||
if(pRecipe.isEmpty() || !specifics.matchIngredients(pRecipe.get())){
|
||||
meetsIngredients = false;
|
||||
missingRequirements.add("ingredients");
|
||||
blockEntity.sendData();
|
||||
return false;
|
||||
}
|
||||
meetsIngredients = true;
|
||||
|
||||
|
||||
hasEnoughOutput = specifics.hasEnoughOutputSpace();
|
||||
if(!hasEnoughOutput){
|
||||
missingRequirements.add("output");
|
||||
result = false;
|
||||
}
|
||||
|
||||
meetsRequirements = checkRequirements(pRecipe.get(), pLevel, specifics);
|
||||
if(!meetsRequirements){
|
||||
result = false;
|
||||
}
|
||||
|
||||
blockEntity.sendData();
|
||||
return result;
|
||||
}
|
||||
private boolean checkRequirements(R pRecipe, Level pLevel, RecipeRequirementsSpecifics<R> pSpecifics){
|
||||
boolean result = true;
|
||||
for (Map.Entry<RecipeRequirementType<?>, RecipeRequirement> entry : pRecipe.getRecipeRequirements().entrySet()) {
|
||||
if(!checkRequirement(entry.getValue(), pLevel, (BlockEntity) pSpecifics)){
|
||||
missingRequirements.add(entry.getKey().getId());
|
||||
result = false;
|
||||
}
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
private boolean checkRequirement(RecipeRequirement value, Level pLevel, BlockEntity pSpecifics){
|
||||
if(value.test(pLevel, pSpecifics))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
public boolean addToGoggleTooltip(List<Component> tooltip, boolean isPlayerSneaking, boolean added) {
|
||||
if(missingRequirements.isEmpty())
|
||||
return false;
|
||||
|
||||
for(String requirementId : missingRequirements){
|
||||
LibLang.translate("mechanical_lemon_lib.ui.recipe_requirement." + requirementId + ".missing").style(ChatFormatting.RED).forGoggles(tooltip,1);
|
||||
added = true;
|
||||
}
|
||||
return added;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void write(CompoundTag compound, boolean clientPacket) {
|
||||
|
||||
ListTag missingRequirementsTag = new ListTag();
|
||||
for(String missingId : missingRequirements){
|
||||
CompoundTag tag = new CompoundTag();
|
||||
tag.putString("t",missingId);
|
||||
missingRequirementsTag.add(tag);
|
||||
}
|
||||
compound.put("MissingRequirements", missingRequirementsTag);
|
||||
super.write(compound, clientPacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(CompoundTag compound, boolean clientPacket){
|
||||
|
||||
missingRequirements = new ArrayList<>();
|
||||
ListTag missingRequirementsTag = compound.getList("MissingRequirements", Tag.TAG_COMPOUND);
|
||||
for( Tag tag : missingRequirementsTag ){
|
||||
CompoundTag requirementsTag = (CompoundTag) tag;
|
||||
missingRequirements.add(requirementsTag.getString("t"));
|
||||
}
|
||||
super.read(compound, clientPacket);
|
||||
}
|
||||
|
||||
public interface RecipeRequirementsSpecifics<R extends IRecipeWithRequirements> {
|
||||
boolean hasEnoughOutputSpace();
|
||||
boolean matchIngredients(R recipe);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.oierbravo.mechanical_lemon_lib.foundation.data;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.tterrag.registrate.util.entry.FluidEntry;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraftforge.common.crafting.conditions.ICondition;
|
||||
import net.minecraftforge.common.crafting.conditions.IConditionSerializer;
|
||||
import net.minecraftforge.fluids.ForgeFlowingFluid;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
public class FluidExistsCondition implements ICondition {
|
||||
private static final ResourceLocation NAME = new ResourceLocation("create_mechanical_chicken", "fluid_exists");
|
||||
private final ResourceLocation fluid;
|
||||
|
||||
public FluidExistsCondition(String location) {
|
||||
this(new ResourceLocation(location));
|
||||
}
|
||||
|
||||
public FluidExistsCondition(String namespace, String path) {
|
||||
this(new ResourceLocation(namespace, path));
|
||||
}
|
||||
|
||||
public FluidExistsCondition(ResourceLocation pFluid) {
|
||||
this.fluid = pFluid;
|
||||
}
|
||||
|
||||
public FluidExistsCondition(FluidEntry<ForgeFlowingFluid.Flowing> fluid) {
|
||||
this(fluid.getId());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ResourceLocation getID() {
|
||||
return NAME;
|
||||
}
|
||||
public String toString() {
|
||||
return "fluid_exists(\"" + this.fluid + "\")";
|
||||
}
|
||||
|
||||
public boolean test(IContext context) {
|
||||
if(fluid.getNamespace().startsWith("#"))
|
||||
return true; //Tags always true;
|
||||
return ForgeRegistries.FLUIDS.containsKey(this.fluid);
|
||||
}
|
||||
public static class Serializer implements IConditionSerializer<FluidExistsCondition> {
|
||||
public static final Serializer INSTANCE = new Serializer();
|
||||
|
||||
public Serializer() {
|
||||
}
|
||||
|
||||
public void write(JsonObject json, FluidExistsCondition value) {
|
||||
json.addProperty("fluid", value.fluid.toString());
|
||||
}
|
||||
|
||||
public FluidExistsCondition read(JsonObject json) {
|
||||
return new FluidExistsCondition(new ResourceLocation(GsonHelper.getAsString(json, "fluid")));
|
||||
}
|
||||
|
||||
public ResourceLocation getID() {
|
||||
return FluidExistsCondition.NAME;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.oierbravo.mechanical_lemon_lib.foundation.recipe;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.item.crafting.Recipe;
|
||||
import net.minecraft.world.item.crafting.RecipeSerializer;
|
||||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@MethodsReturnNonnullByDefault
|
||||
@ParametersAreNonnullByDefault
|
||||
public abstract class BaseRecipe<T extends Container, P extends BaseRecipeParams> implements Recipe<T>, IRecipeWithRequirements {
|
||||
|
||||
protected ResourceLocation id;
|
||||
|
||||
protected Map<RecipeRequirementType<?>, RecipeRequirement> recipeRequirements = new HashMap<>();
|
||||
|
||||
protected static List<RecipeRequirementType<?>> enabledRecipeRequirements = List.of();
|
||||
|
||||
|
||||
public BaseRecipe(P params){
|
||||
this.id = params.id;
|
||||
|
||||
params.recipeRequirements.forEach(
|
||||
recipeRequirement -> recipeRequirements.put(recipeRequirement.getType(), recipeRequirement)
|
||||
);
|
||||
|
||||
}
|
||||
public List<RecipeRequirementType<?>> getEnabledRequirements() {
|
||||
return enabledRecipeRequirements;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canCraftInDimensions(int width, int height) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package com.oierbravo.mechanical_lemon_lib.foundation.recipe;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.data.recipes.FinishedRecipe;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.crafting.RecipeSerializer;
|
||||
import net.minecraftforge.common.crafting.CraftingHelper;
|
||||
import net.minecraftforge.common.crafting.conditions.ICondition;
|
||||
import net.minecraftforge.common.crafting.conditions.ModLoadedCondition;
|
||||
import net.minecraftforge.common.crafting.conditions.NotCondition;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public abstract class BaseRecipeBuilder<R extends BaseRecipe<?,P>, P extends BaseRecipeParams> {
|
||||
|
||||
protected P params;
|
||||
protected List<RecipeRequirement> recipeRequirements;
|
||||
protected List<ICondition> recipeConditions;
|
||||
|
||||
public BaseRecipeBuilder( ResourceLocation id){
|
||||
recipeRequirements = new ArrayList<>();
|
||||
recipeConditions = new ArrayList<>();
|
||||
}
|
||||
|
||||
public abstract R build();
|
||||
|
||||
public void build(Consumer<FinishedRecipe> consumer) {
|
||||
consumer.accept(new DataGenResult<>(build(), recipeConditions));
|
||||
}
|
||||
|
||||
public BaseRecipeBuilder<R,P> withRequirement(RecipeRequirement requirement){
|
||||
params.recipeRequirements.add(requirement);
|
||||
return this;
|
||||
}
|
||||
public BaseRecipeBuilder<R,P> withRequirements(List<RecipeRequirement> recipeRequirements) {
|
||||
recipeRequirements.forEach(this::withRequirement);
|
||||
return this;
|
||||
}
|
||||
|
||||
public BaseRecipeBuilder<R,P> whenModLoaded(String modid) {
|
||||
return withCondition(new ModLoadedCondition(modid));
|
||||
}
|
||||
|
||||
public BaseRecipeBuilder<R,P> whenModMissing(String modid) {
|
||||
return withCondition(new NotCondition(new ModLoadedCondition(modid)));
|
||||
}
|
||||
|
||||
public BaseRecipeBuilder<R,P> withCondition(ICondition condition) {
|
||||
recipeConditions.add(condition);
|
||||
return this;
|
||||
}
|
||||
|
||||
public static class DataGenResult<S extends BaseRecipe<?,?>> implements FinishedRecipe {
|
||||
|
||||
private List<ICondition> recipeConditions;
|
||||
private BaseRecipeSerializer<S,?> serializer;
|
||||
private ResourceLocation id;
|
||||
private S recipe;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public DataGenResult(S recipe, List<ICondition> recipeConditions) {
|
||||
this.recipe = recipe;
|
||||
this.recipeConditions = recipeConditions;
|
||||
ResourceLocation typeId = recipe.getId();
|
||||
|
||||
if (!(recipe.getSerializer() instanceof BaseRecipeSerializer))
|
||||
throw new IllegalStateException("Cannot datagen Recipe of type: " + typeId);
|
||||
|
||||
this.id = new ResourceLocation(recipe.getId().getNamespace(),
|
||||
typeId.getPath() + "/" + recipe.getId().getPath());
|
||||
this.serializer = (BaseRecipeSerializer<S, ?>) recipe.getSerializer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serializeRecipeData(JsonObject json) {
|
||||
serializer.write(json, recipe);
|
||||
if (recipeConditions.isEmpty())
|
||||
return;
|
||||
|
||||
JsonArray conds = new JsonArray();
|
||||
recipeConditions.forEach(c -> conds.add(CraftingHelper.serialize(c)));
|
||||
json.add("conditions", conds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeSerializer<?> getType() {
|
||||
return serializer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject serializeAdvancement() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getAdvancementId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.oierbravo.mechanical_lemon_lib.foundation.recipe;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public abstract class BaseRecipeParams implements IBaseRecipeParams {
|
||||
public ResourceLocation id;
|
||||
public ArrayList<RecipeRequirement> recipeRequirements;
|
||||
|
||||
protected BaseRecipeParams(ResourceLocation id) {
|
||||
this.id = id;
|
||||
recipeRequirements = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.oierbravo.mechanical_lemon_lib.foundation.recipe;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.crafting.RecipeSerializer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class BaseRecipeSerializer<R extends BaseRecipe<?,?>, B extends BaseRecipeBuilder<R,?>> implements RecipeSerializer<R> {
|
||||
protected final List<RecipeRequirementType<?>> enabledRecipeRequirements;
|
||||
|
||||
|
||||
public BaseRecipeSerializer(List<RecipeRequirementType<?>> pEnabledRecipeRequirements) {
|
||||
this.enabledRecipeRequirements = pEnabledRecipeRequirements;
|
||||
}
|
||||
|
||||
protected abstract B readFromJson(ResourceLocation recipeId, JsonObject json);
|
||||
protected abstract B readFromBuffer(ResourceLocation recipeId, FriendlyByteBuf buffer);
|
||||
|
||||
protected abstract void writeToJson(JsonObject json, R recipe);
|
||||
protected abstract void writeToBuffer(FriendlyByteBuf buffer, R recipe);
|
||||
|
||||
|
||||
public final void write(JsonObject json, R recipe) {
|
||||
writeToJson(json, recipe);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull R fromJson(@NotNull ResourceLocation pRecipeId, @NotNull JsonObject pSerializedRecipe) {
|
||||
return readFromJson(pRecipeId, pSerializedRecipe)
|
||||
.withRequirements(RecipeRequirementsUtils.fromJson(pSerializedRecipe, enabledRecipeRequirements))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @Nullable R fromNetwork(@NotNull ResourceLocation pRecipeId, @NotNull FriendlyByteBuf pBuffer) {
|
||||
return readFromBuffer(pRecipeId, pBuffer).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toNetwork(@NotNull FriendlyByteBuf pBuffer, @NotNull R pRecipe) {
|
||||
writeToBuffer(pBuffer, pRecipe);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.oierbravo.mechanical_lemon_lib.foundation.recipe;
|
||||
|
||||
public interface IBaseRecipeParams {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.oierbravo.mechanical_lemon_lib.foundation.recipe;
|
||||
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
|
||||
public interface IProcessBlockingRequirement {
|
||||
boolean test(Level pLevel, BlockEntity pBlockEntity);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.oierbravo.mechanical_lemon_lib.foundation.recipe;
|
||||
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public interface IRecipeWithRequirements {
|
||||
|
||||
Map<RecipeRequirementType<?>, RecipeRequirement> getRecipeRequirements();
|
||||
List<RecipeRequirementType<?>> getEnabledRequirements();
|
||||
|
||||
default <T extends RecipeRequirement> T getRequirement(RecipeRequirementType<T> type) {
|
||||
return (T) getRecipeRequirements().get(type);
|
||||
}
|
||||
boolean checkRequirements(Level pLevel, BlockEntity pBlockEntity);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.oierbravo.mechanical_lemon_lib.foundation.recipe;
|
||||
|
||||
import com.oierbravo.mechanical_lemon_lib.utility.LibLang;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
|
||||
public abstract class RecipeRequirement {
|
||||
public abstract RecipeRequirementType<?> getType();
|
||||
|
||||
public abstract boolean test(Level pLevel, BlockEntity pBlockEntity);
|
||||
|
||||
public abstract boolean isPresent();
|
||||
public abstract String toString();
|
||||
public Component toRequirementComponent(){
|
||||
return LibLang.translate("ui.recipe_requirement." + getType().getId() + ".tooltip", toString()).component();
|
||||
};
|
||||
public Component toMissingComponent(){
|
||||
return LibLang.translate("ui.recipe_requirement." + getType().getId() + ".missing", toString()).component();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.oierbravo.mechanical_lemon_lib.foundation.recipe;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
|
||||
public abstract class RecipeRequirementType<RR extends RecipeRequirement> {
|
||||
private final String id;
|
||||
|
||||
public RecipeRequirementType(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public abstract RR fromJson(JsonObject pJson);
|
||||
|
||||
public abstract JsonObject toJson(JsonObject pJson, RecipeRequirement pRecipeRequirement);
|
||||
|
||||
public abstract RR fromNetwork(FriendlyByteBuf buffer);
|
||||
|
||||
public abstract void toNetwork(FriendlyByteBuf buffer, RecipeRequirement pRecipeRequirement);
|
||||
public boolean isProcessBlocker(){
|
||||
return this instanceof IProcessBlockingRequirement;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.oierbravo.mechanical_lemon_lib.foundation.recipe;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.oierbravo.mechanical_lemon_lib.utility.Components;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class RecipeRequirementsUtils {
|
||||
public static ArrayList<RecipeRequirement> fromJson(JsonObject json, List<RecipeRequirementType<?>> enabledRecipeRequirements){
|
||||
ArrayList<RecipeRequirement> recipeRequirements = new ArrayList<>();
|
||||
|
||||
enabledRecipeRequirements.forEach(recipeRequirementType -> {
|
||||
if (GsonHelper.isValidNode(json, recipeRequirementType.getId())) {
|
||||
recipeRequirements.add(recipeRequirementType.fromJson(json));
|
||||
}
|
||||
});
|
||||
return recipeRequirements;
|
||||
}
|
||||
public static ArrayList<RecipeRequirement> fromBuffer(FriendlyByteBuf buffer, List<RecipeRequirementType<?>> enabledRecipeRequirements){
|
||||
ArrayList<RecipeRequirement> recipeRequirements = new ArrayList<>();
|
||||
enabledRecipeRequirements.forEach(recipeRequirementType -> {
|
||||
recipeRequirements.add(recipeRequirementType.fromNetwork(buffer));
|
||||
});
|
||||
|
||||
return recipeRequirements;
|
||||
}
|
||||
|
||||
public static JsonObject toJson(JsonObject pJson, Map<RecipeRequirementType<?>, RecipeRequirement> pRecipeRequirements){
|
||||
for (Map.Entry<RecipeRequirementType<?>, RecipeRequirement> entry : pRecipeRequirements.entrySet()) {
|
||||
pJson = entry.getKey().toJson(pJson, entry.getValue());
|
||||
}
|
||||
return pJson;
|
||||
}
|
||||
|
||||
|
||||
public static void toBuffer(FriendlyByteBuf buffer, IRecipeWithRequirements pRecipe){
|
||||
pRecipe.getEnabledRequirements().forEach(recipeRequirementType -> {
|
||||
recipeRequirementType.toNetwork(buffer,pRecipe.getRequirement(recipeRequirementType));
|
||||
});
|
||||
}
|
||||
|
||||
public static ArrayList<String> checkRequirements(Map<RecipeRequirementType<?>, RecipeRequirement> pRecipeRequirements, BlockEntity pBlockEntity){
|
||||
ArrayList<String> missingRequirements = new ArrayList<>();
|
||||
pRecipeRequirements.forEach((recipeRequirementType, recipeRequirement) -> {
|
||||
if(!recipeRequirement.test(pBlockEntity.getLevel(),pBlockEntity))
|
||||
missingRequirements.add(recipeRequirement.getType().getId());
|
||||
});
|
||||
return missingRequirements;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
package com.oierbravo.mechanical_lemon_lib.foundation.recipe.requirements;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import com.oierbravo.mechanical_lemon_lib.foundation.recipe.RecipeRequirement;
|
||||
import com.oierbravo.mechanical_lemon_lib.foundation.recipe.RecipeRequirementType;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import static java.lang.constant.ConstantDescs.NULL;
|
||||
|
||||
public class BiomeRequirement extends RecipeRequirement {
|
||||
public static final RecipeRequirementType<BiomeRequirement> TYPE = new BiomeRequirementType();
|
||||
|
||||
|
||||
public static final BiomeRequirement EMPTY = new BiomeRequirement();
|
||||
|
||||
protected TagKey<Biome> biomeTagKey;
|
||||
|
||||
protected ResourceKey<Biome> biomeResourceKey;
|
||||
|
||||
public BiomeRequirement() {
|
||||
|
||||
}
|
||||
public BiomeRequirement(TagKey<Biome> tag) {
|
||||
this(null,tag);
|
||||
}
|
||||
|
||||
public BiomeRequirement(ResourceKey<Biome> key) {
|
||||
this(key,null);
|
||||
}
|
||||
|
||||
public BiomeRequirement(ResourceKey<Biome> key, TagKey<Biome> tag) {
|
||||
this.biomeResourceKey = key;
|
||||
this.biomeTagKey = tag;
|
||||
}
|
||||
public static BiomeRequirement of(ResourceKey<Biome> key) {
|
||||
return new BiomeRequirement(key);
|
||||
}
|
||||
public static BiomeRequirement of(TagKey<Biome> tag) {
|
||||
return new BiomeRequirement(tag);
|
||||
}
|
||||
public static BiomeRequirement of(ResourceKey<Biome> key, TagKey<Biome> tag) {
|
||||
return new BiomeRequirement(key, tag);
|
||||
}
|
||||
|
||||
public boolean test(Level pLevel, BlockEntity pBlockEntity) {
|
||||
if(biomeResourceKey == null && biomeTagKey == null)
|
||||
return true;
|
||||
Holder<Biome> blockEntityBiome = pLevel.getBiome(pBlockEntity.getBlockPos());
|
||||
|
||||
/*if(pLevel.isClientSide()){
|
||||
return false;
|
||||
}*/
|
||||
RegistryAccess registryAccess;
|
||||
if(pLevel.isClientSide())
|
||||
registryAccess = Objects.requireNonNull(Minecraft.getInstance().getConnection()).registryAccess();
|
||||
registryAccess = pLevel.registryAccess();
|
||||
|
||||
Optional<Holder.Reference<Biome>> requiredBiomeHolder = Objects.requireNonNull(registryAccess.registryOrThrow(Registries.BIOME).asLookup().get(biomeResourceKey));
|
||||
|
||||
if(requiredBiomeHolder.isPresent()
|
||||
&& blockEntityBiome.is(requiredBiomeHolder.get().key()))
|
||||
return true;
|
||||
|
||||
|
||||
return registryAccess.registryOrThrow(Registries.BIOME).getTag(biomeTagKey).map(t ->
|
||||
t.contains(blockEntityBiome)
|
||||
).orElse(false);
|
||||
}
|
||||
|
||||
|
||||
public boolean isPresent(){
|
||||
if(biomeTagKey == null && biomeResourceKey == null)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
if(biomeTagKey == null && biomeResourceKey == null)
|
||||
return null;
|
||||
if(biomeResourceKey != null)
|
||||
return biomeResourceKey.location().toString();
|
||||
return biomeTagKey.location().toString();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RecipeRequirementType<?> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
private static class BiomeRequirementType extends RecipeRequirementType<BiomeRequirement> {
|
||||
|
||||
public BiomeRequirementType() {
|
||||
super("biome");
|
||||
}
|
||||
|
||||
public BiomeRequirementType(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeRequirement fromJson(JsonObject pJson) {
|
||||
if (GsonHelper.isValidNode(pJson, "biome")) {
|
||||
ResourceKey<Biome> biomeResourceKey = ResourceKey.codec(Registries.BIOME).parse(JsonOps.INSTANCE, pJson.get("biome")).result().get();
|
||||
TagKey<Biome> biomeTag = TagKey.codec(Registries.BIOME).parse(JsonOps.INSTANCE, pJson.get("biome")).result().get();
|
||||
return BiomeRequirement.of(biomeResourceKey,biomeTag);
|
||||
}
|
||||
return BiomeRequirement.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject toJson(JsonObject pJson, RecipeRequirement pRecipeRequirement){
|
||||
if(!pRecipeRequirement.isPresent())
|
||||
return pJson;
|
||||
pJson.addProperty("biome", pRecipeRequirement.toString());
|
||||
return pJson;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BiomeRequirement fromNetwork(FriendlyByteBuf buffer) {
|
||||
boolean hasRequirement = buffer.readBoolean();
|
||||
if(hasRequirement) {
|
||||
ResourceLocation rl = buffer.readResourceLocation();
|
||||
if (NULL.equals(rl)) return BiomeRequirement.EMPTY;
|
||||
else return BiomeRequirement.of(TagKey.create(Registries.BIOME, rl));
|
||||
}
|
||||
return BiomeRequirement.EMPTY;
|
||||
}
|
||||
@Override
|
||||
public void toNetwork(FriendlyByteBuf buffer, RecipeRequirement pRecipeRequirement) {
|
||||
if(pRecipeRequirement == null)
|
||||
pRecipeRequirement = new BiomeRequirement();
|
||||
if(pRecipeRequirement instanceof BiomeRequirement){
|
||||
buffer.writeBoolean(pRecipeRequirement.isPresent());
|
||||
if(pRecipeRequirement.isPresent()) {
|
||||
TagKey<Biome> biome = ((BiomeRequirement) pRecipeRequirement).biomeTagKey;
|
||||
buffer.writeResourceLocation(biome.location());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package com.oierbravo.mechanical_lemon_lib.foundation.recipe.requirements;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.oierbravo.mechanical_lemon_lib.foundation.recipe.RecipeRequirement;
|
||||
import com.oierbravo.mechanical_lemon_lib.foundation.recipe.RecipeRequirementType;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
|
||||
public class MaxHeightRequirement extends RecipeRequirement {
|
||||
public static final RecipeRequirementType<?> TYPE = new MaxHeightRequirementType();
|
||||
public static final MaxHeightRequirement EMPTY = new MaxHeightRequirement();
|
||||
|
||||
private Integer value;
|
||||
|
||||
public MaxHeightRequirement() {}
|
||||
|
||||
public MaxHeightRequirement(int pMaxHeight) {
|
||||
value = pMaxHeight;
|
||||
}
|
||||
|
||||
public static MaxHeightRequirement of(int pMaxHeight) {
|
||||
return new MaxHeightRequirement(pMaxHeight);
|
||||
}
|
||||
|
||||
public boolean test(Level pLevel, BlockEntity pBlockEntity) {
|
||||
if(value == null)
|
||||
return true;
|
||||
BlockPos pos = pBlockEntity.getBlockPos();
|
||||
|
||||
return pos.getCenter().y <= value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeRequirementType<?> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
public boolean isPresent(){
|
||||
return value != null;
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
if(value == null)
|
||||
return null;
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
public int getValue(){
|
||||
return value;
|
||||
}
|
||||
|
||||
private static class MaxHeightRequirementType extends RecipeRequirementType<MaxHeightRequirement> {
|
||||
|
||||
public MaxHeightRequirementType() {
|
||||
super("max_height");
|
||||
}
|
||||
|
||||
@Override
|
||||
public MaxHeightRequirement fromJson(JsonObject pJson) {
|
||||
if (GsonHelper.isValidNode(pJson, this.getId())) {
|
||||
return of(pJson.get(this.getId()).getAsInt());
|
||||
}
|
||||
return EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject toJson(JsonObject pJson, RecipeRequirement pRecipeRequirement) {
|
||||
if(!pRecipeRequirement.isPresent())
|
||||
return pJson;
|
||||
pJson.addProperty(this.getId(), pRecipeRequirement.toString());
|
||||
return pJson;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MaxHeightRequirement fromNetwork(FriendlyByteBuf buffer) {
|
||||
boolean hasRequirement = buffer.readBoolean();
|
||||
if(hasRequirement) {
|
||||
return of(buffer.readInt());
|
||||
}
|
||||
return MaxHeightRequirement.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toNetwork(FriendlyByteBuf buffer, RecipeRequirement pRecipeRequirement) {
|
||||
if(pRecipeRequirement == null)
|
||||
pRecipeRequirement = new MaxHeightRequirement();
|
||||
if(pRecipeRequirement instanceof MaxHeightRequirement){
|
||||
buffer.writeBoolean(pRecipeRequirement.isPresent());
|
||||
if(pRecipeRequirement.isPresent())
|
||||
buffer.writeInt(((MaxHeightRequirement) pRecipeRequirement).getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
package com.oierbravo.mechanical_lemon_lib.foundation.recipe.requirements;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.oierbravo.mechanical_lemon_lib.foundation.recipe.RecipeRequirement;
|
||||
import com.oierbravo.mechanical_lemon_lib.foundation.recipe.RecipeRequirementType;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
|
||||
public class MinHeightRequirement extends RecipeRequirement {
|
||||
public static final RecipeRequirementType<?> TYPE = new MinHeightRequirementType();
|
||||
public static final MinHeightRequirement EMPTY = new MinHeightRequirement();
|
||||
|
||||
private Integer value;
|
||||
|
||||
public MinHeightRequirement() {
|
||||
|
||||
}
|
||||
|
||||
public MinHeightRequirement(int pValue) {
|
||||
value = pValue;
|
||||
}
|
||||
|
||||
public static MinHeightRequirement of(int pValue) {
|
||||
return new MinHeightRequirement(pValue);
|
||||
}
|
||||
|
||||
|
||||
public boolean test(Level pLevel, BlockEntity pBlockEntity) {
|
||||
if(value == null)
|
||||
return true;
|
||||
BlockPos pos = pBlockEntity.getBlockPos();
|
||||
|
||||
return pos.getCenter().y >= value;
|
||||
}
|
||||
|
||||
public boolean isPresent(){
|
||||
return value != null;
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
if(value == null)
|
||||
return null;
|
||||
return value.toString();
|
||||
}
|
||||
public int getValue(){
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RecipeRequirementType<?> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
private static class MinHeightRequirementType extends RecipeRequirementType<MinHeightRequirement> {
|
||||
|
||||
public MinHeightRequirementType() {
|
||||
super("min_height");
|
||||
}
|
||||
|
||||
@Override
|
||||
public MinHeightRequirement fromJson(JsonObject pJson) {
|
||||
if (GsonHelper.isValidNode(pJson, this.getId())) {
|
||||
return of(pJson.get(this.getId()).getAsInt());
|
||||
}
|
||||
return EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject toJson(JsonObject pJson, RecipeRequirement pRecipeRequirement) {
|
||||
if(!pRecipeRequirement.isPresent())
|
||||
return pJson;
|
||||
pJson.addProperty(this.getId(), pRecipeRequirement.toString());
|
||||
return pJson;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MinHeightRequirement fromNetwork(FriendlyByteBuf buffer) {
|
||||
boolean hasRequirement = buffer.readBoolean();
|
||||
if(hasRequirement) {
|
||||
return of(buffer.readInt());
|
||||
}
|
||||
return MinHeightRequirement.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toNetwork(FriendlyByteBuf buffer, RecipeRequirement pRecipeRequirement) {
|
||||
if(pRecipeRequirement == null)
|
||||
pRecipeRequirement = new MinHeightRequirement();
|
||||
if(pRecipeRequirement instanceof MinHeightRequirement){
|
||||
buffer.writeBoolean(pRecipeRequirement.isPresent());
|
||||
if(pRecipeRequirement.isPresent())
|
||||
buffer.writeInt(((MinHeightRequirement) pRecipeRequirement).getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
package com.oierbravo.mechanical_lemon_lib.foundation.recipe.requirements;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.oierbravo.mechanical_lemon_lib.foundation.recipe.RecipeRequirement;
|
||||
import com.oierbravo.mechanical_lemon_lib.foundation.recipe.RecipeRequirementType;
|
||||
import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
|
||||
public class SpeedRequirement extends RecipeRequirement {
|
||||
public static final RecipeRequirementType<?> TYPE = new SpeedRequirementType();
|
||||
public static final SpeedRequirement EMPTY = new SpeedRequirement();
|
||||
|
||||
private Float value;
|
||||
|
||||
public SpeedRequirement() {
|
||||
|
||||
}
|
||||
|
||||
public SpeedRequirement(float pValue) {
|
||||
value = pValue;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean test(Level pLevel, BlockEntity pBlockEntity) {
|
||||
if(pBlockEntity instanceof KineticBlockEntity){
|
||||
return Math.abs(((KineticBlockEntity) pBlockEntity).getSpeed()) >= value;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPresent() {
|
||||
return value != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if(value == null)
|
||||
return null;
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
public Float getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static SpeedRequirement of(float pValue) {
|
||||
return new SpeedRequirement(pValue);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RecipeRequirementType<?> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
private static class SpeedRequirementType extends RecipeRequirementType<SpeedRequirement> {
|
||||
|
||||
public SpeedRequirementType() {
|
||||
super("min_speed");
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpeedRequirement fromJson(JsonObject pJson) {
|
||||
if (GsonHelper.isValidNode(pJson, this.getId())) {
|
||||
return of(pJson.get(this.getId()).getAsFloat());
|
||||
}
|
||||
return EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject toJson(JsonObject pJson, RecipeRequirement pRecipeRequirement) {
|
||||
if(!pRecipeRequirement.isPresent())
|
||||
return pJson;
|
||||
pJson.addProperty(this.getId(), pRecipeRequirement.toString());
|
||||
return pJson;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpeedRequirement fromNetwork(FriendlyByteBuf buffer) {
|
||||
boolean hasRequirement = buffer.readBoolean();
|
||||
if(hasRequirement) {
|
||||
return of(buffer.readFloat());
|
||||
}
|
||||
return SpeedRequirement.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toNetwork(FriendlyByteBuf buffer, RecipeRequirement pRecipeRequirement) {
|
||||
if(pRecipeRequirement == null)
|
||||
pRecipeRequirement = new SpeedRequirement();
|
||||
if(pRecipeRequirement instanceof SpeedRequirement){
|
||||
buffer.writeBoolean(pRecipeRequirement.isPresent());
|
||||
if(pRecipeRequirement.isPresent())
|
||||
buffer.writeFloat(((SpeedRequirement) pRecipeRequirement).getValue());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.oierbravo.mechanical_lemon_lib.jade;
|
||||
|
||||
public interface IHavePercent {
|
||||
int getProgressPercent();
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.oierbravo.mechanical_lemon_lib.jade;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import snownee.jade.api.BlockAccessor;
|
||||
import snownee.jade.api.IBlockComponentProvider;
|
||||
import snownee.jade.api.IServerDataProvider;
|
||||
import snownee.jade.api.ITooltip;
|
||||
import snownee.jade.api.config.IPluginConfig;
|
||||
import snownee.jade.api.ui.BoxStyle;
|
||||
import snownee.jade.api.ui.IElementHelper;
|
||||
import snownee.jade.util.Color;
|
||||
|
||||
public class ProgressComponentProvider implements IBlockComponentProvider, IServerDataProvider<BlockAccessor> {
|
||||
private final ResourceLocation UID;
|
||||
private final String translationKey;
|
||||
String blockEntityID;
|
||||
|
||||
public ProgressComponentProvider(ResourceLocation UID, String id, String translationKey){
|
||||
this.UID = UID;
|
||||
this.blockEntityID = id;
|
||||
this.translationKey = translationKey;
|
||||
}
|
||||
|
||||
public void appendTooltip(ITooltip tooltip, BlockAccessor accessor, IPluginConfig config) {
|
||||
if (accessor.getServerData().contains("progress")) {
|
||||
int progress = accessor.getServerData().getInt("progress");
|
||||
|
||||
if(progress > 0){
|
||||
IElementHelper helper = tooltip.getElementHelper();
|
||||
tooltip.add(helper.progress((float)progress / 100, Component.translatable("mechanical_lemon_lib.progress",progress),helper.progressStyle().color(Color.hex("#FFFF00").toInt()), BoxStyle.DEFAULT,true));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getUid() {
|
||||
return UID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendServerData(CompoundTag compoundTag, BlockAccessor blockAccessor) {
|
||||
if(blockAccessor.getBlockEntity() instanceof IHavePercent){
|
||||
compoundTag.putInt("progress",((IHavePercent) blockAccessor.getBlockEntity()).getProgressPercent());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.oierbravo.mechanical_lemon_lib.register;
|
||||
|
||||
import com.oierbravo.mechanical_lemon_lib.MechanicalLemonLib;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.item.CreativeModeTab;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.minecraftforge.registries.DeferredRegister;
|
||||
import net.minecraftforge.registries.RegistryObject;
|
||||
|
||||
public class LemonCreativeModeTabs {
|
||||
private static final DeferredRegister<CreativeModeTab> TAB_REGISTER =
|
||||
DeferredRegister.create(Registries.CREATIVE_MODE_TAB, MechanicalLemonLib.MODID);
|
||||
|
||||
|
||||
public static final RegistryObject<CreativeModeTab> MAIN_TAB = TAB_REGISTER.register("main",
|
||||
() -> CreativeModeTab.builder()
|
||||
.title(Component.translatable("itemGroup.mechanical_lemon_lib"))
|
||||
.icon(() -> Items.EGG.asItem().getDefaultInstance())
|
||||
.build());
|
||||
|
||||
|
||||
public static CreativeModeTab getBaseTab() {
|
||||
return MAIN_TAB.get();
|
||||
}
|
||||
|
||||
public static void register(IEventBus modEventBus) {
|
||||
TAB_REGISTER.register(modEventBus);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.oierbravo.mechanical_lemon_lib.utility;
|
||||
/*
|
||||
* Credits: Creators of create
|
||||
* https://github.com/Creators-of-Create/Create
|
||||
* License: MIT
|
||||
*/
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
|
||||
public final class Components {
|
||||
private static final Component IMMUTABLE_EMPTY = Component.empty();
|
||||
|
||||
public static Component immutableEmpty() {
|
||||
return IMMUTABLE_EMPTY;
|
||||
}
|
||||
|
||||
/** Use {@link #immutableEmpty()} when possible to prevent creating an extra object. */
|
||||
public static MutableComponent empty() {
|
||||
return Component.empty();
|
||||
}
|
||||
|
||||
public static MutableComponent literal(String str) {
|
||||
return Component.literal(str);
|
||||
}
|
||||
|
||||
public static MutableComponent translatable(String key) {
|
||||
return Component.translatable(key);
|
||||
}
|
||||
|
||||
public static MutableComponent translatable(String key, Object... args) {
|
||||
return Component.translatable(key, args);
|
||||
}
|
||||
|
||||
public static MutableComponent keybind(String name) {
|
||||
return Component.keybind(name);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.oierbravo.mechanical_lemon_lib.utility;
|
||||
/*
|
||||
* Credits: Creators of create
|
||||
* https://github.com/Creators-of-Create/Create
|
||||
* License: MIT
|
||||
*/
|
||||
import com.oierbravo.mechanical_lemon_lib.MechanicalLemonLib;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class Lang {
|
||||
|
||||
|
||||
public static String asId(String name) {
|
||||
return name.toLowerCase(Locale.ROOT);
|
||||
}
|
||||
|
||||
public static String nonPluralId(String name) {
|
||||
String asId = asId(name);
|
||||
return asId.endsWith("s") ? asId.substring(0, asId.length() - 1) : asId;
|
||||
}
|
||||
|
||||
public static List<Component> translatedOptions(String prefix, String... keys) {
|
||||
List<Component> result = new ArrayList<>(keys.length);
|
||||
for (String key : keys)
|
||||
result.add(translate((prefix != null ? prefix + "." : "") + key).component());
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
public static LangBuilder builder() {
|
||||
return new LangBuilder(MechanicalLemonLib.MODID);
|
||||
}
|
||||
|
||||
public static LangBuilder builder(String namespace) {
|
||||
return new LangBuilder(namespace);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
public static LangBuilder blockName(BlockState state) {
|
||||
return builder().add(state.getBlock()
|
||||
.getName());
|
||||
}
|
||||
|
||||
public static LangBuilder itemName(ItemStack stack) {
|
||||
return builder().add(stack.getHoverName()
|
||||
.copy());
|
||||
}
|
||||
|
||||
public static LangBuilder fluidName(FluidStack stack) {
|
||||
return builder().add(stack.getDisplayName()
|
||||
.copy());
|
||||
}
|
||||
|
||||
|
||||
public static com.oierbravo.mechanical_lemon_lib.utility.LangBuilder translate(String langKey, Object... args) {
|
||||
return builder().translate(langKey, args);
|
||||
}
|
||||
|
||||
public static LangBuilder text(String text) {
|
||||
return builder().text(text);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
public static Object[] resolveBuilders(Object[] args) {
|
||||
for (int i = 0; i < args.length; i++)
|
||||
if (args[i]instanceof LangBuilder cb)
|
||||
args[i] = cb.component();
|
||||
return args;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
package com.oierbravo.mechanical_lemon_lib.utility;
|
||||
/*
|
||||
* Credits: Creators of create
|
||||
* https://github.com/Creators-of-Create/Create
|
||||
* License: MIT
|
||||
*/
|
||||
import joptsimple.internal.Strings;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class LangBuilder {
|
||||
|
||||
String namespace;
|
||||
MutableComponent component;
|
||||
|
||||
public LangBuilder(String namespace) {
|
||||
this.namespace = namespace;
|
||||
}
|
||||
|
||||
public LangBuilder space() {
|
||||
return text(" ");
|
||||
}
|
||||
|
||||
public LangBuilder newLine() {
|
||||
return text("\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a localised component<br>
|
||||
* To add an independently formatted localised component, use add() and a nested
|
||||
* builder
|
||||
*
|
||||
* @param langKey
|
||||
* @param args
|
||||
* @return
|
||||
*/
|
||||
public LangBuilder translate(String langKey, Object... args) {
|
||||
return add(Components.translatable(namespace + "." + langKey, Lang.resolveBuilders(args)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a text component
|
||||
*
|
||||
* @param literalText
|
||||
* @return
|
||||
*/
|
||||
public LangBuilder text(String literalText) {
|
||||
return add(Components.literal(literalText));
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a colored text component
|
||||
*
|
||||
* @param format
|
||||
* @param literalText
|
||||
* @return
|
||||
*/
|
||||
public LangBuilder text(ChatFormatting format, String literalText) {
|
||||
return add(Components.literal(literalText).withStyle(format));
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a colored text component
|
||||
*
|
||||
* @param color
|
||||
* @param literalText
|
||||
* @return
|
||||
*/
|
||||
public LangBuilder text(int color, String literalText) {
|
||||
return add(Components.literal(literalText).withStyle(s -> s.withColor(color)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the contents of another builder
|
||||
*
|
||||
* @param otherBuilder
|
||||
* @return
|
||||
*/
|
||||
public LangBuilder add(LangBuilder otherBuilder) {
|
||||
return add(otherBuilder.component());
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a component
|
||||
*
|
||||
* @param customComponent
|
||||
* @return
|
||||
*/
|
||||
public LangBuilder add(MutableComponent customComponent) {
|
||||
component = component == null ? customComponent : component.append(customComponent);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a component
|
||||
*
|
||||
* @param component the component to append
|
||||
* @return this builder
|
||||
*/
|
||||
public LangBuilder add(Component component) {
|
||||
if (component instanceof MutableComponent mutableComponent)
|
||||
return add(mutableComponent);
|
||||
else
|
||||
return add(component.copy());
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
/**
|
||||
* Applies the format to all added components
|
||||
*
|
||||
* @param format
|
||||
* @return
|
||||
*/
|
||||
public LangBuilder style(ChatFormatting format) {
|
||||
assertComponent();
|
||||
component = component.withStyle(format);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the color to all added components
|
||||
*
|
||||
* @param color
|
||||
* @return
|
||||
*/
|
||||
public LangBuilder color(int color) {
|
||||
assertComponent();
|
||||
component = component.withStyle(s -> s.withColor(color));
|
||||
return this;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
public MutableComponent component() {
|
||||
assertComponent();
|
||||
return component;
|
||||
}
|
||||
|
||||
public String string() {
|
||||
return component().getString();
|
||||
}
|
||||
|
||||
public String json() {
|
||||
return Component.Serializer.toJson(component());
|
||||
}
|
||||
|
||||
public void sendStatus(Player player) {
|
||||
player.displayClientMessage(component(), true);
|
||||
}
|
||||
|
||||
public void sendChat(Player player) {
|
||||
player.displayClientMessage(component(), false);
|
||||
}
|
||||
|
||||
public void addTo(List<? super MutableComponent> tooltip) {
|
||||
tooltip.add(component());
|
||||
}
|
||||
|
||||
public void forGoggles(List<? super MutableComponent> tooltip) {
|
||||
forGoggles(tooltip, 0);
|
||||
}
|
||||
|
||||
public void forGoggles(List<? super MutableComponent> tooltip, int indents) {
|
||||
tooltip.add(Lang.builder()
|
||||
.text(Strings.repeat(' ', getIndents(Minecraft.getInstance().font, 4 + indents)))
|
||||
.add((Component) this)
|
||||
.component());
|
||||
}
|
||||
|
||||
public static final float DEFAULT_SPACE_WIDTH = 4.0F; // space width in vanilla's default font
|
||||
static int getIndents(Font font, int defaultIndents) {
|
||||
int spaceWidth = font.width(" ");
|
||||
if (DEFAULT_SPACE_WIDTH == spaceWidth) {
|
||||
return defaultIndents;
|
||||
}
|
||||
return Mth.ceil(DEFAULT_SPACE_WIDTH * defaultIndents / spaceWidth);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
private void assertComponent() {
|
||||
if (component == null)
|
||||
throw new IllegalStateException("No components were added to builder");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.oierbravo.mechanical_lemon_lib.utility;
|
||||
|
||||
import com.oierbravo.mechanical_lemon_lib.MechanicalLemonLib;
|
||||
|
||||
public class LibLang extends Lang {
|
||||
public LibLang() {
|
||||
super();
|
||||
}
|
||||
public static LangBuilder builder() {
|
||||
return new LangBuilder(MechanicalLemonLib.MODID);
|
||||
}
|
||||
public static LangBuilder translate(String langKey, Object... args) {
|
||||
return builder().translate(langKey, args);
|
||||
}
|
||||
}
|
||||
63
src/main/resources/META-INF/mods.toml
Normal file
63
src/main/resources/META-INF/mods.toml
Normal file
@@ -0,0 +1,63 @@
|
||||
# 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 = "${loader_version_range}" #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 = "${mod_license}"
|
||||
# A URL to refer people to when problems occur with this mod
|
||||
#issueTrackerURL="https://change.me.to.your.issue.tracker.example.invalid/" #optional
|
||||
# A list of mods - how many allowed here is determined by the individual mod loader
|
||||
[[mods]] #mandatory
|
||||
# The modid of the mod
|
||||
modId = "${mod_id}" #mandatory
|
||||
# The version number of the mod
|
||||
version = "${mod_version}" #mandatory
|
||||
# A display name for the mod
|
||||
displayName = "${mod_name}" #mandatory
|
||||
# A URL to query for updates for this mod. See the JSON update specification https://docs.minecraftforge.net/en/latest/misc/updatechecker/
|
||||
#updateJSONURL="https://change.me.example.invalid/updates.json" #optional
|
||||
# A URL for the "homepage" for this mod, displayed in the mod UI
|
||||
#displayURL="https://change.me.to.your.mods.homepage.example.invalid/" #optional
|
||||
# A file name (in the root of the mod JAR) containing a logo for display
|
||||
#logoFile="mechanical_lemon_lib.png" #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 = "${mod_authors}" #optional
|
||||
# Display Test controls the display for your mod in the server connection screen
|
||||
# MATCH_VERSION means that your mod will cause a red X if the versions on client and server differ. This is the default behaviour and should be what you choose if you have server and client elements to your mod.
|
||||
# IGNORE_SERVER_VERSION means that your mod will not cause a red X if it's present on the server but not on the client. This is what you should use if you're a server only mod.
|
||||
# IGNORE_ALL_VERSION means that your mod will not cause a red X if it's present on the client or the server. This is a special case and should only be used if your mod has no server component.
|
||||
# NONE means that no display test is set on your mod. You need to do this yourself, see IExtensionPoint.DisplayTest for more information. You can define any scheme you wish with this value.
|
||||
# IMPORTANT NOTE: this is NOT an instruction as to which environments (CLIENT or DEDICATED SERVER) your mod loads on. Your mod should load (and maybe do nothing!) whereever it finds itself.
|
||||
#displayTest="MATCH_VERSION" # MATCH_VERSION is the default if nothing is specified (#optional)
|
||||
|
||||
# The description text for the mod (multi line!) (#mandatory)
|
||||
description = '''${mod_description}'''
|
||||
# A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional.
|
||||
[[dependencies."${mod_id}"]] #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 = "${forge_version_range}" #mandatory
|
||||
# An ordering relationship for the dependency - BEFORE or AFTER required if the dependency is not mandatory
|
||||
# BEFORE - This mod is loaded BEFORE the dependency
|
||||
# AFTER - This mod is loaded AFTER the dependency
|
||||
ordering = "NONE"
|
||||
# Side this dependency is applied on - BOTH, CLIENT, or SERVER
|
||||
side = "BOTH"# Here's another dependency
|
||||
[[dependencies."${mod_id}"]]
|
||||
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 = "${minecraft_version_range}"
|
||||
ordering = "NONE"
|
||||
side = "BOTH"
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"mechanical_lemon_lib.progress": "Progress: %d%%",
|
||||
"mechanical_lemon_tab": "Mechanicals",
|
||||
"mechanical_lemon_lib.ui.recipe_requirement.none.tooltip": "No specific requirement",
|
||||
"mechanical_lemon_lib.ui.recipe_requirement.biome.tooltip": "Requires %s biome",
|
||||
"mechanical_lemon_lib.ui.recipe_requirement.min_height.tooltip": "Min Y: %s",
|
||||
"mechanical_lemon_lib.ui.recipe_requirement.max_height.tooltip": "Max Y: %s",
|
||||
"mechanical_lemon_lib.ui.recipe_requirement.min_speed.tooltip": "Min Speed: %s",
|
||||
"mechanical_lemon_lib.ui.recipe_requirement.biome.missing": "Incorrect biome",
|
||||
"mechanical_lemon_lib.ui.recipe_requirement.max_height.missing": "Too high",
|
||||
"mechanical_lemon_lib.ui.recipe_requirement.min_height.missing": "Too low",
|
||||
"mechanical_lemon_lib.ui.recipe_requirement.min_speed.missing": "Not enough speed",
|
||||
"mechanical_lemon_lib.ui.recipe_requirement.output.missing": "Output full or incompatible",
|
||||
"mechanical_lemon_lib.ui.recipe_requirement.ingredients.missing": "Missing ingredients"
|
||||
}
|
||||
6
src/main/resources/pack.mcmeta
Normal file
6
src/main/resources/pack.mcmeta
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"pack": {
|
||||
"description": "mechanical_lemon_lib resources",
|
||||
"pack_format": 15
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user