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
|
||||||
193
build.gradle
Normal file
193
build.gradle
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
plugins {
|
||||||
|
id 'eclipse'
|
||||||
|
id 'idea'
|
||||||
|
id 'net.minecraftforge.gradle' version '[6.0.16,6.2)'
|
||||||
|
id 'maven-publish'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
group = "com.${author}.${modid}"
|
||||||
|
version = "${minecraft_version}-${mod_version}"
|
||||||
|
archivesBaseName = modid
|
||||||
|
|
||||||
|
java {
|
||||||
|
toolchain.languageVersion = JavaLanguageVersion.of(17)
|
||||||
|
}
|
||||||
|
|
||||||
|
minecraft {
|
||||||
|
// The mappings can be changed at any time and must be in the following format.
|
||||||
|
// Channel: Version:
|
||||||
|
// official MCVersion Official field/method names from Mojang mapping files
|
||||||
|
// parchment YYYY.MM.DD-MCVersion Open community-sourced parameter names and javadocs layered on top of official
|
||||||
|
//
|
||||||
|
// You must be aware of the Mojang license when using the 'official' or 'parchment' mappings.
|
||||||
|
// See more information here: https://github.com/MinecraftForge/MCPConfig/blob/master/Mojang.md
|
||||||
|
//
|
||||||
|
// Parchment is an unofficial project maintained by ParchmentMC, separate from MinecraftForge
|
||||||
|
// Additional setup is needed to use their mappings: https://parchmentmc.org/docs/getting-started
|
||||||
|
//
|
||||||
|
// Use non-default mappings at your own risk. They may not always work.
|
||||||
|
// Simply re-run your setup task after changing the mappings to update your workspace.
|
||||||
|
mappings channel: mapping_channel, version: mapping_version
|
||||||
|
|
||||||
|
// When true, this property will have all Eclipse/IntelliJ IDEA run configurations run the "prepareX" task for the given run configuration before launching the game.
|
||||||
|
// In most cases, it is not necessary to enable.
|
||||||
|
// enableEclipsePrepareRuns = true
|
||||||
|
// enableIdeaPrepareRuns = true
|
||||||
|
|
||||||
|
// This property allows configuring Gradle's ProcessResources task(s) to run on IDE output locations before launching the game.
|
||||||
|
// It is REQUIRED to be set to true for this template to function.
|
||||||
|
// See https://docs.gradle.org/current/dsl/org.gradle.language.jvm.tasks.ProcessResources.html
|
||||||
|
copyIdeResources = true
|
||||||
|
|
||||||
|
// When true, this property will add the folder name of all declared run configurations to generated IDE run configurations.
|
||||||
|
// The folder name can be set on a run configuration using the "folderName" property.
|
||||||
|
// By default, the folder name of a run configuration is the name of the Gradle project containing it.
|
||||||
|
// generateRunFolders = true
|
||||||
|
|
||||||
|
// This property enables access transformers for use in development.
|
||||||
|
// They will be applied to the Minecraft artifact.
|
||||||
|
// The access transformer file can be anywhere in the project.
|
||||||
|
// However, it must be at "META-INF/accesstransformer.cfg" in the final mod jar to be loaded by Forge.
|
||||||
|
// This default location is a best practice to automatically put the file in the right place in the final jar.
|
||||||
|
// See https://docs.minecraftforge.net/en/latest/advanced/accesstransformers/ for more information.
|
||||||
|
// accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')
|
||||||
|
|
||||||
|
// Default run configurations.
|
||||||
|
// These can be tweaked, removed, or duplicated as needed.
|
||||||
|
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 {
|
||||||
|
"${modid}" {
|
||||||
|
source sourceSets.main
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
client {
|
||||||
|
// Comma-separated list of namespaces to load gametests from. Empty = all namespaces.
|
||||||
|
property 'forge.enabledGameTestNamespaces', modid
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
property 'forge.enabledGameTestNamespaces', modid
|
||||||
|
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', modid
|
||||||
|
}
|
||||||
|
|
||||||
|
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', modid, '--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 {
|
||||||
|
// location of the maven that hosts JEI files since January 2023
|
||||||
|
// location of the maven for Vazkii's mods
|
||||||
|
name = "Jared's maven"
|
||||||
|
url = "https://maven.blamejared.com/"
|
||||||
|
}
|
||||||
|
maven {
|
||||||
|
// location of the maven for Curios API
|
||||||
|
url = "https://maven.theillusivec4.top/"
|
||||||
|
}
|
||||||
|
maven {
|
||||||
|
url = 'https://www.cursemaven.com'
|
||||||
|
content {
|
||||||
|
includeGroup "curse.maven"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
|
||||||
|
|
||||||
|
|
||||||
|
compileOnly fg.deobf("mezz.jei:jei-${jei_minecraft_version}-common-api:${jei_version}")
|
||||||
|
compileOnly fg.deobf("mezz.jei:jei-${jei_minecraft_version}-forge-api:${jei_version}")
|
||||||
|
runtimeOnly fg.deobf("mezz.jei:jei-${jei_minecraft_version}-forge:${jei_version}")
|
||||||
|
|
||||||
|
implementation fg.deobf("curse.maven:jade-324717:${jade_id}")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// This block of code expands all declared replace properties in the specified resource targets.
|
||||||
|
// A missing property will result in an error. Properties are expanded using ${} Groovy notation.
|
||||||
|
// When "copyIdeResources" is enabled, this will also run before the game launches in IDE environments.
|
||||||
|
// See https://docs.gradle.org/current/dsl/org.gradle.language.jvm.tasks.ProcessResources.html
|
||||||
|
tasks.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,
|
||||||
|
modid : modid, mod_name: mod_name, mod_license: mod_license, mod_version: mod_version,
|
||||||
|
author : author, mod_description: mod_description,]
|
||||||
|
|
||||||
|
inputs.properties replaceProperties
|
||||||
|
|
||||||
|
filesMatching(['META-INF/mods.toml', 'pack.mcmeta']) {
|
||||||
|
expand replaceProperties + [project: project]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Example for how to get properties into the manifest for reading at runtime.
|
||||||
|
tasks.named('jar', Jar).configure {
|
||||||
|
manifest {
|
||||||
|
attributes(["Specification-Title" : modid,
|
||||||
|
"Specification-Vendor" : author,
|
||||||
|
"Specification-Version" : "1", // We are version 1 of ourselves
|
||||||
|
"Implementation-Title" : project.name,
|
||||||
|
"Implementation-Version" : project.jar.archiveVersion,
|
||||||
|
"Implementation-Vendor" : author,
|
||||||
|
"Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ")])
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is the preferred method to reobfuscate your jar file
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
26
gradle.properties
Normal file
26
gradle.properties
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
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
|
||||||
|
|
||||||
|
modid=mechanical_lemon_ui
|
||||||
|
mod_name=Mechanical Lemon UI
|
||||||
|
mod_license=MIT
|
||||||
|
mod_version=0.0.2
|
||||||
|
mod_group_id=com.oierbravo
|
||||||
|
author=oierbravo
|
||||||
|
mod_description=Library
|
||||||
|
|
||||||
|
|
||||||
|
jei_minecraft_version = 1.20.1
|
||||||
|
jei_version = 15.2.0.22
|
||||||
|
curios_minecraft_version = 1.20.1
|
||||||
|
curios_version = 5.2.0-beta.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 = 'MechanicalLemonUI'
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package com.oierbravo.mechanical_lemon_ui;
|
||||||
|
|
||||||
|
import com.mojang.logging.LogUtils;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
|
import net.minecraftforge.eventbus.api.IEventBus;
|
||||||
|
import net.minecraftforge.fml.ModLoadingContext;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
import net.minecraftforge.fml.config.ModConfig;
|
||||||
|
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
|
// The value here should match an entry in the META-INF/mods.toml file
|
||||||
|
@Mod(MechanicalLemonUI.MODID)
|
||||||
|
public class MechanicalLemonUI {
|
||||||
|
|
||||||
|
public static final String MODID = "mechanical_lemon_ui";
|
||||||
|
private static final Logger LOGGER = LogUtils.getLogger();
|
||||||
|
|
||||||
|
public MechanicalLemonUI() {
|
||||||
|
IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
|
||||||
|
|
||||||
|
|
||||||
|
MinecraftForge.EVENT_BUS.register(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ResourceLocation asResource(String path) {
|
||||||
|
return new ResourceLocation(MODID, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,182 @@
|
|||||||
|
package com.oierbravo.mechanical_lemon_ui.foundation.gui;
|
||||||
|
/*
|
||||||
|
* Credits: Creators of create
|
||||||
|
* https://github.com/Creators-of-Create/Create
|
||||||
|
* License: MIT
|
||||||
|
*/
|
||||||
|
import com.mojang.blaze3d.platform.InputConstants;
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
import com.oierbravo.mechanical_lemon_ui.foundation.gui.widget.AbstractSimiWidget;
|
||||||
|
import com.oierbravo.mechanical_lemon_ui.foundation.utility.Components;
|
||||||
|
import net.minecraft.client.gui.GuiGraphics;
|
||||||
|
import net.minecraft.client.gui.components.AbstractWidget;
|
||||||
|
import net.minecraft.client.gui.components.EditBox;
|
||||||
|
import net.minecraft.client.gui.components.Renderable;
|
||||||
|
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||||
|
import net.minecraft.client.gui.narration.NarratableEntry;
|
||||||
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public abstract class AbstractSimiScreen extends Screen {
|
||||||
|
|
||||||
|
protected int windowWidth, windowHeight;
|
||||||
|
protected int windowXOffset, windowYOffset;
|
||||||
|
protected int guiLeft, guiTop;
|
||||||
|
|
||||||
|
protected AbstractSimiScreen(Component title) {
|
||||||
|
super(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected AbstractSimiScreen() {
|
||||||
|
this(Components.immutableEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method must be called before {@code super.init()}!
|
||||||
|
*/
|
||||||
|
protected void setWindowSize(int width, int height) {
|
||||||
|
windowWidth = width;
|
||||||
|
windowHeight = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method must be called before {@code super.init()}!
|
||||||
|
*/
|
||||||
|
protected void setWindowOffset(int xOffset, int yOffset) {
|
||||||
|
windowXOffset = xOffset;
|
||||||
|
windowYOffset = yOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void init() {
|
||||||
|
guiLeft = (width - windowWidth) / 2;
|
||||||
|
guiTop = (height - windowHeight) / 2;
|
||||||
|
guiLeft += windowXOffset;
|
||||||
|
guiTop += windowYOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick() {
|
||||||
|
for (GuiEventListener listener : children()) {
|
||||||
|
if (listener instanceof TickableGuiEventListener tickable) {
|
||||||
|
tickable.tick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) {
|
||||||
|
if (getFocused() != null && !getFocused().isMouseOver(pMouseX, pMouseY))
|
||||||
|
setFocused(null);
|
||||||
|
return super.mouseClicked(pMouseX, pMouseY, pButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPauseScreen() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
protected <W extends GuiEventListener & Renderable & NarratableEntry> void addRenderableWidgets(W... widgets) {
|
||||||
|
for (W widget : widgets) {
|
||||||
|
addRenderableWidget(widget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected <W extends GuiEventListener & Renderable & NarratableEntry> void addRenderableWidgets(Collection<W> widgets) {
|
||||||
|
for (W widget : widgets) {
|
||||||
|
addRenderableWidget(widget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void removeWidgets(GuiEventListener... widgets) {
|
||||||
|
for (GuiEventListener widget : widgets) {
|
||||||
|
removeWidget(widget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void removeWidgets(Collection<? extends GuiEventListener> widgets) {
|
||||||
|
for (GuiEventListener widget : widgets) {
|
||||||
|
removeWidget(widget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
|
||||||
|
partialTicks = minecraft.getFrameTime();
|
||||||
|
PoseStack ms = graphics.pose();
|
||||||
|
|
||||||
|
ms.pushPose();
|
||||||
|
|
||||||
|
prepareFrame();
|
||||||
|
|
||||||
|
renderWindowBackground(graphics, mouseX, mouseY, partialTicks);
|
||||||
|
renderWindow(graphics, mouseX, mouseY, partialTicks);
|
||||||
|
super.render(graphics, mouseX, mouseY, partialTicks);
|
||||||
|
renderWindowForeground(graphics, mouseX, mouseY, partialTicks);
|
||||||
|
|
||||||
|
endFrame();
|
||||||
|
|
||||||
|
ms.popPose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||||
|
boolean keyPressed = super.keyPressed(keyCode, scanCode, modifiers);
|
||||||
|
if (keyPressed || getFocused() instanceof EditBox)
|
||||||
|
return keyPressed;
|
||||||
|
|
||||||
|
InputConstants.Key mouseKey = InputConstants.getKey(keyCode, scanCode);
|
||||||
|
if (this.minecraft.options.keyInventory.isActiveAndMatches(mouseKey)) {
|
||||||
|
this.onClose();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void prepareFrame() {}
|
||||||
|
|
||||||
|
protected void renderWindowBackground(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
|
||||||
|
renderBackground(graphics);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void renderWindow(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks);
|
||||||
|
|
||||||
|
protected void renderWindowForeground(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
|
||||||
|
for (Renderable widget : renderables) {
|
||||||
|
if (widget instanceof AbstractSimiWidget simiWidget && simiWidget.isMouseOver(mouseX, mouseY)
|
||||||
|
&& simiWidget.visible) {
|
||||||
|
List<Component> tooltip = simiWidget.getToolTip();
|
||||||
|
if (tooltip.isEmpty())
|
||||||
|
continue;
|
||||||
|
int ttx = simiWidget.lockedTooltipX == -1 ? mouseX : simiWidget.lockedTooltipX + simiWidget.getX();
|
||||||
|
int tty = simiWidget.lockedTooltipY == -1 ? mouseY : simiWidget.lockedTooltipY + simiWidget.getY();
|
||||||
|
graphics.renderComponentTooltip(font, tooltip, ttx, tty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void endFrame() {}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
protected void debugWindowArea(GuiGraphics graphics) {
|
||||||
|
graphics.fill(guiLeft + windowWidth, guiTop + windowHeight, guiLeft, guiTop, 0xD3D3D3D3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GuiEventListener getFocused() {
|
||||||
|
GuiEventListener focused = super.getFocused();
|
||||||
|
if (focused instanceof AbstractWidget && !((AbstractWidget) focused).isFocused())
|
||||||
|
focused = null;
|
||||||
|
setFocused(focused);
|
||||||
|
return focused;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.oierbravo.mechanical_lemon_ui.foundation.gui;
|
||||||
|
/*
|
||||||
|
* Credits: Creators of create
|
||||||
|
* https://github.com/Creators-of-Create/Create
|
||||||
|
* License: MIT
|
||||||
|
*/
|
||||||
|
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||||
|
|
||||||
|
public interface TickableGuiEventListener extends GuiEventListener {
|
||||||
|
void tick();
|
||||||
|
}
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
package com.oierbravo.mechanical_lemon_ui.foundation.gui;
|
||||||
|
/*
|
||||||
|
* Credits: Creators of create
|
||||||
|
* https://github.com/Creators-of-Create/Create
|
||||||
|
* License: MIT
|
||||||
|
*/
|
||||||
|
import com.mojang.blaze3d.pipeline.RenderTarget;
|
||||||
|
import com.mojang.blaze3d.platform.Window;
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||||
|
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||||
|
import com.mojang.blaze3d.vertex.Tesselator;
|
||||||
|
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||||
|
import com.oierbravo.mechanical_lemon_ui.foundation.utility.Color;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.gui.GuiGraphics;
|
||||||
|
import net.minecraft.client.renderer.GameRenderer;
|
||||||
|
import org.joml.Matrix4f;
|
||||||
|
|
||||||
|
public class UIRenderHelper {
|
||||||
|
public static CustomRenderTarget framebuffer;
|
||||||
|
|
||||||
|
public UIRenderHelper() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void init() {
|
||||||
|
RenderSystem.recordRenderCall(() -> {
|
||||||
|
Window mainWindow = Minecraft.getInstance().getWindow();
|
||||||
|
framebuffer = UIRenderHelper.CustomRenderTarget.create(mainWindow);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void updateWindowSize(Window mainWindow) {
|
||||||
|
if (framebuffer != null) {
|
||||||
|
framebuffer.resize(mainWindow.getWidth(), mainWindow.getHeight(), Minecraft.ON_OSX);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public static void drawColoredTexture(GuiGraphics graphics, Color c, int x, int y, int tex_left, int tex_top, int width, int height) {
|
||||||
|
drawColoredTexture(graphics, c, x, y, 0, (float) tex_left, (float) tex_top, width, height, 256, 256);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void drawColoredTexture(GuiGraphics graphics, Color c, int x, int y, int z, float tex_left, float tex_top, int width, int height, int sheet_width, int sheet_height) {
|
||||||
|
drawColoredTexture(graphics, c, x, x + width, y, y + height, z, width, height, tex_left, tex_top, sheet_width, sheet_height);
|
||||||
|
}
|
||||||
|
private static void drawColoredTexture(GuiGraphics graphics, Color c, int left, int right, int top, int bot, int z, int tex_width, int tex_height, float tex_left, float tex_top, int sheet_width, int sheet_height) {
|
||||||
|
drawTexturedQuad(graphics.pose().last().pose(), c, left, right, top, bot, z, (tex_left + 0.0F) / (float)sheet_width, (tex_left + (float)tex_width) / (float)sheet_width, (tex_top + 0.0F) / (float)sheet_height, (tex_top + (float)tex_height) / (float)sheet_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void drawTexturedQuad(Matrix4f m, Color c, int left, int right, int top, int bot, int z, float u1, float u2, float v1, float v2) {
|
||||||
|
Tesselator tesselator = Tesselator.getInstance();
|
||||||
|
BufferBuilder bufferbuilder = tesselator.getBuilder();
|
||||||
|
RenderSystem.enableBlend();
|
||||||
|
RenderSystem.defaultBlendFunc();
|
||||||
|
RenderSystem.setShader(GameRenderer::getPositionColorTexShader);
|
||||||
|
bufferbuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR_TEX);
|
||||||
|
bufferbuilder.vertex(m, (float)left, (float)bot, (float)z).color(c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()).uv(u1, v2).endVertex();
|
||||||
|
bufferbuilder.vertex(m, (float)right, (float)bot, (float)z).color(c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()).uv(u2, v2).endVertex();
|
||||||
|
bufferbuilder.vertex(m, (float)right, (float)top, (float)z).color(c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()).uv(u2, v1).endVertex();
|
||||||
|
bufferbuilder.vertex(m, (float)left, (float)top, (float)z).color(c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()).uv(u1, v1).endVertex();
|
||||||
|
tesselator.end();
|
||||||
|
RenderSystem.disableBlend();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class CustomRenderTarget extends RenderTarget {
|
||||||
|
public CustomRenderTarget(boolean useDepth) {
|
||||||
|
super(useDepth);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CustomRenderTarget create(Window mainWindow) {
|
||||||
|
CustomRenderTarget framebuffer = new CustomRenderTarget(true);
|
||||||
|
framebuffer.resize(mainWindow.getWidth(), mainWindow.getHeight(), Minecraft.ON_OSX);
|
||||||
|
framebuffer.setClearColor(0.0F, 0.0F, 0.0F, 0.0F);
|
||||||
|
framebuffer.enableStencil();
|
||||||
|
return framebuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void renderWithAlpha(float alpha) {
|
||||||
|
Window window = Minecraft.getInstance().getWindow();
|
||||||
|
float vx = (float)window.getGuiScaledWidth();
|
||||||
|
float vy = (float)window.getGuiScaledHeight();
|
||||||
|
float tx = (float)this.viewWidth / (float)this.width;
|
||||||
|
float ty = (float)this.viewHeight / (float)this.height;
|
||||||
|
RenderSystem.enableDepthTest();
|
||||||
|
RenderSystem.setShader(() -> {
|
||||||
|
return Minecraft.getInstance().gameRenderer.blitShader;
|
||||||
|
});
|
||||||
|
RenderSystem.getShader().setSampler("DiffuseSampler", this.colorTextureId);
|
||||||
|
this.bindRead();
|
||||||
|
Tesselator tessellator = Tesselator.getInstance();
|
||||||
|
BufferBuilder bufferbuilder = tessellator.getBuilder();
|
||||||
|
bufferbuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR_TEX);
|
||||||
|
bufferbuilder.vertex(0.0, (double)vy, 0.0).color(1.0F, 1.0F, 1.0F, alpha).uv(0.0F, 0.0F).endVertex();
|
||||||
|
bufferbuilder.vertex((double)vx, (double)vy, 0.0).color(1.0F, 1.0F, 1.0F, alpha).uv(tx, 0.0F).endVertex();
|
||||||
|
bufferbuilder.vertex((double)vx, 0.0, 0.0).color(1.0F, 1.0F, 1.0F, alpha).uv(tx, ty).endVertex();
|
||||||
|
bufferbuilder.vertex(0.0, 0.0, 0.0).color(1.0F, 1.0F, 1.0F, alpha).uv(0.0F, ty).endVertex();
|
||||||
|
tessellator.end();
|
||||||
|
this.unbindRead();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,188 @@
|
|||||||
|
package com.oierbravo.mechanical_lemon_ui.foundation.gui.menu;
|
||||||
|
/*
|
||||||
|
* Credits: Creators of create
|
||||||
|
* https://github.com/Creators-of-Create/Create
|
||||||
|
* License: MIT
|
||||||
|
*/
|
||||||
|
import com.mojang.blaze3d.platform.InputConstants;
|
||||||
|
import com.oierbravo.mechanical_lemon_ui.foundation.gui.TickableGuiEventListener;
|
||||||
|
import com.oierbravo.mechanical_lemon_ui.foundation.gui.widget.AbstractSimiWidget;
|
||||||
|
import com.oierbravo.mechanical_lemon_ui.register.LibGuiTextures;
|
||||||
|
import net.minecraft.client.gui.GuiGraphics;
|
||||||
|
import net.minecraft.client.gui.components.AbstractWidget;
|
||||||
|
import net.minecraft.client.gui.components.EditBox;
|
||||||
|
import net.minecraft.client.gui.components.Renderable;
|
||||||
|
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||||
|
import net.minecraft.client.gui.narration.NarratableEntry;
|
||||||
|
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
|
||||||
|
import net.minecraft.client.gui.screens.inventory.ContainerScreen;
|
||||||
|
import net.minecraft.client.renderer.Rect2i;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
public abstract class AbstractSimiContainerScreen<T extends AbstractContainerMenu> extends AbstractContainerScreen<T> {
|
||||||
|
protected int titleXOffset = 2;
|
||||||
|
protected int titleYOffset = 6;
|
||||||
|
protected int windowXOffset, windowYOffset;
|
||||||
|
|
||||||
|
public AbstractSimiContainerScreen(T container, Inventory inv, Component title) {
|
||||||
|
super(container, inv, title);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method must be called before {@code super.init()}!
|
||||||
|
*/
|
||||||
|
protected void setWindowSize(int width, int height) {
|
||||||
|
imageWidth = width;
|
||||||
|
imageHeight = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method must be called before {@code super.init()}!
|
||||||
|
*/
|
||||||
|
protected void setWindowOffset(int xOffset, int yOffset) {
|
||||||
|
windowXOffset = xOffset;
|
||||||
|
windowYOffset = yOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void init() {
|
||||||
|
super.init();
|
||||||
|
leftPos += windowXOffset;
|
||||||
|
topPos += windowYOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void containerTick() {
|
||||||
|
for (GuiEventListener listener : children()) {
|
||||||
|
if (listener instanceof TickableGuiEventListener tickable) {
|
||||||
|
tickable.tick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
protected <W extends GuiEventListener & Renderable & NarratableEntry> void addRenderableWidgets(W... widgets) {
|
||||||
|
for (W widget : widgets) {
|
||||||
|
addRenderableWidget(widget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected <W extends GuiEventListener & Renderable & NarratableEntry> void addRenderableWidgets(Collection<W> widgets) {
|
||||||
|
for (W widget : widgets) {
|
||||||
|
addRenderableWidget(widget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void removeWidgets(GuiEventListener... widgets) {
|
||||||
|
for (GuiEventListener widget : widgets) {
|
||||||
|
removeWidget(widget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void removeWidgets(Collection<? extends GuiEventListener> widgets) {
|
||||||
|
for (GuiEventListener widget : widgets) {
|
||||||
|
removeWidget(widget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
|
||||||
|
partialTicks = minecraft.getFrameTime();
|
||||||
|
|
||||||
|
renderBackground(graphics);
|
||||||
|
|
||||||
|
super.render(graphics, mouseX, mouseY, partialTicks);
|
||||||
|
|
||||||
|
renderForeground(graphics, mouseX, mouseY, partialTicks);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderLabels(GuiGraphics graphics, int mouseX, int mouseY) {
|
||||||
|
// no-op to prevent screen- and inventory-title from being rendered at incorrect
|
||||||
|
// location
|
||||||
|
// could also set this.titleX/Y and this.playerInventoryTitleX/Y to the proper
|
||||||
|
// values instead
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void renderForeground(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
|
||||||
|
renderTooltip(graphics, mouseX, mouseY);
|
||||||
|
for (Renderable widget : renderables) {
|
||||||
|
if (widget instanceof AbstractSimiWidget simiWidget && simiWidget.isMouseOver(mouseX, mouseY)) {
|
||||||
|
List<Component> tooltip = simiWidget.getToolTip();
|
||||||
|
if (tooltip.isEmpty())
|
||||||
|
continue;
|
||||||
|
int ttx = simiWidget.lockedTooltipX == -1 ? mouseX : simiWidget.lockedTooltipX + simiWidget.getX();
|
||||||
|
int tty = simiWidget.lockedTooltipY == -1 ? mouseY : simiWidget.lockedTooltipY + simiWidget.getY();
|
||||||
|
graphics.renderComponentTooltip(font, tooltip, ttx, tty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLeftOfCentered(int textureWidth) {
|
||||||
|
return leftPos - windowXOffset + (imageWidth - textureWidth) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void renderPlayerInventory(GuiGraphics graphics, int x, int y) {
|
||||||
|
LibGuiTextures.PLAYER_INVENTORY.render(graphics, x, y);
|
||||||
|
graphics.drawString(font, playerInventoryTitle, x + titleXOffset, y + titleYOffset, 0x404040, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean keyPressed(int pKeyCode, int pScanCode, int pModifiers) {
|
||||||
|
InputConstants.Key mouseKey = InputConstants.getKey(pKeyCode, pScanCode);
|
||||||
|
if (getFocused() instanceof EditBox && this.minecraft.options.keyInventory.isActiveAndMatches(mouseKey))
|
||||||
|
return false;
|
||||||
|
return super.keyPressed(pKeyCode, pScanCode, pModifiers);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) {
|
||||||
|
if (getFocused() != null && !getFocused().isMouseOver(pMouseX, pMouseY))
|
||||||
|
setFocused(null);
|
||||||
|
return super.mouseClicked(pMouseX, pMouseY, pButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GuiEventListener getFocused() {
|
||||||
|
GuiEventListener focused = super.getFocused();
|
||||||
|
if (focused instanceof AbstractWidget && !((AbstractWidget) focused).isFocused())
|
||||||
|
focused = null;
|
||||||
|
setFocused(focused);
|
||||||
|
return focused;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used for moving JEI out of the way of extra things like block renders.
|
||||||
|
*
|
||||||
|
* @return the space that the GUI takes up outside the normal rectangle defined
|
||||||
|
* by {@link ContainerScreen}.
|
||||||
|
*/
|
||||||
|
public List<Rect2i> getExtraAreas() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
protected void debugWindowArea(GuiGraphics graphics) {
|
||||||
|
graphics.fill(leftPos + imageWidth, topPos + imageHeight, leftPos, topPos, 0xD3D3D3D3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
protected void debugExtraAreas(GuiGraphics graphics) {
|
||||||
|
for (Rect2i area : getExtraAreas()) {
|
||||||
|
graphics.fill(area.getX() + area.getWidth(), area.getY() + area.getHeight(), area.getX(), area.getY(),
|
||||||
|
0xD3D3D3D3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
package com.oierbravo.mechanical_lemon_ui.foundation.gui.menu;
|
||||||
|
/*
|
||||||
|
* Credits: Creators of create
|
||||||
|
* https://github.com/Creators-of-Create/Create
|
||||||
|
* License: MIT
|
||||||
|
*/
|
||||||
|
import com.oierbravo.mechanical_lemon_ui.foundation.utility.IInteractionChecker;
|
||||||
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||||
|
import net.minecraft.world.inventory.MenuType;
|
||||||
|
import net.minecraft.world.inventory.Slot;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
|
||||||
|
public abstract class MenuBase<T> extends AbstractContainerMenu {
|
||||||
|
|
||||||
|
public Player player;
|
||||||
|
public Inventory playerInventory;
|
||||||
|
public T contentHolder;
|
||||||
|
|
||||||
|
protected MenuBase(MenuType<?> type, int id, Inventory inv, FriendlyByteBuf extraData) {
|
||||||
|
super(type, id);
|
||||||
|
init(inv, createOnClient(extraData));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected MenuBase(MenuType<?> type, int id, Inventory inv, T contentHolder) {
|
||||||
|
super(type, id);
|
||||||
|
init(inv, contentHolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void init(Inventory inv, T contentHolderIn) {
|
||||||
|
player = inv.player;
|
||||||
|
playerInventory = inv;
|
||||||
|
contentHolder = contentHolderIn;
|
||||||
|
initAndReadInventory(contentHolder);
|
||||||
|
addSlots();
|
||||||
|
broadcastChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
protected abstract T createOnClient(FriendlyByteBuf extraData);
|
||||||
|
|
||||||
|
protected abstract void initAndReadInventory(T contentHolder);
|
||||||
|
|
||||||
|
protected abstract void addSlots();
|
||||||
|
|
||||||
|
protected abstract void saveData(T contentHolder);
|
||||||
|
|
||||||
|
protected void addPlayerSlots(int x, int y) {
|
||||||
|
for (int hotbarSlot = 0; hotbarSlot < 9; ++hotbarSlot)
|
||||||
|
this.addSlot(new Slot(playerInventory, hotbarSlot, x + hotbarSlot * 18, y + 58));
|
||||||
|
for (int row = 0; row < 3; ++row)
|
||||||
|
for (int col = 0; col < 9; ++col)
|
||||||
|
this.addSlot(new Slot(playerInventory, col + row * 9 + 9, x + col * 18, y + row * 18));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removed(Player playerIn) {
|
||||||
|
super.removed(playerIn);
|
||||||
|
saveData(contentHolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean stillValid(Player player) {
|
||||||
|
if (contentHolder == null)
|
||||||
|
return false;
|
||||||
|
if (contentHolder instanceof IInteractionChecker)
|
||||||
|
return ((IInteractionChecker) contentHolder).canPlayerUse(player);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
package com.oierbravo.mechanical_lemon_ui.foundation.gui.widget;
|
||||||
|
/*
|
||||||
|
* Credits: Creators of create
|
||||||
|
* https://github.com/Creators-of-Create/Create
|
||||||
|
* License: MIT
|
||||||
|
*/
|
||||||
|
import com.oierbravo.mechanical_lemon_ui.foundation.gui.TickableGuiEventListener;
|
||||||
|
import com.oierbravo.mechanical_lemon_ui.foundation.utility.Components;
|
||||||
|
import net.minecraft.client.gui.GuiGraphics;
|
||||||
|
import net.minecraft.client.gui.components.AbstractWidget;
|
||||||
|
import net.minecraft.client.gui.narration.NarrationElementOutput;
|
||||||
|
import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipPositioner;
|
||||||
|
import net.minecraft.client.gui.screens.inventory.tooltip.DefaultTooltipPositioner;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
|
public abstract class AbstractSimiWidget extends AbstractWidget implements TickableGuiEventListener {
|
||||||
|
|
||||||
|
public static final int HEADER_RGB = 0x5391E1;
|
||||||
|
public static final int HINT_RGB = 0x96B7E0;
|
||||||
|
|
||||||
|
protected float z;
|
||||||
|
protected boolean wasHovered = false;
|
||||||
|
protected List<Component> toolTip = new LinkedList<>();
|
||||||
|
protected BiConsumer<Integer, Integer> onClick = (_$, _$$) -> {};
|
||||||
|
|
||||||
|
public int lockedTooltipX = -1;
|
||||||
|
public int lockedTooltipY = -1;
|
||||||
|
|
||||||
|
protected AbstractSimiWidget(int x, int y) {
|
||||||
|
this(x, y, 16, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected AbstractSimiWidget(int x, int y, int width, int height) {
|
||||||
|
this(x, y, width, height, Components.immutableEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected AbstractSimiWidget(int x, int y, int width, int height, Component message) {
|
||||||
|
super(x, y, width, height, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ClientTooltipPositioner createTooltipPositioner() {
|
||||||
|
return DefaultTooltipPositioner.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends AbstractSimiWidget> T withCallback(BiConsumer<Integer, Integer> cb) {
|
||||||
|
this.onClick = cb;
|
||||||
|
//noinspection unchecked
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends AbstractSimiWidget> T withCallback(Runnable cb) {
|
||||||
|
return withCallback((_$, _$$) -> cb.run());
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends AbstractSimiWidget> T atZLevel(float z) {
|
||||||
|
this.z = z;
|
||||||
|
//noinspection unchecked
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Component> getToolTip() {
|
||||||
|
return toolTip;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void renderWidget(@Nonnull GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
|
||||||
|
beforeRender(graphics, mouseX, mouseY, partialTicks);
|
||||||
|
doRender(graphics, mouseX, mouseY, partialTicks);
|
||||||
|
afterRender(graphics, mouseX, mouseY, partialTicks);
|
||||||
|
wasHovered = isHoveredOrFocused();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void beforeRender(@Nonnull GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
|
||||||
|
graphics.pose().pushPose();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void doRender(@Nonnull GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void afterRender(@Nonnull GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
|
||||||
|
graphics.pose().popPose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void runCallback(double mouseX, double mouseY) {
|
||||||
|
onClick.accept((int) mouseX, (int) mouseY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(double mouseX, double mouseY) {
|
||||||
|
runCallback(mouseX, mouseY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateWidgetNarration(NarrationElementOutput pNarrationElementOutput) {
|
||||||
|
defaultButtonNarrationText(pNarrationElementOutput);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package com.oierbravo.mechanical_lemon_ui.foundation.gui.widget;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
import com.oierbravo.mechanical_lemon_ui.register.LibGuiTextures;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.gui.Font;
|
||||||
|
import net.minecraft.client.gui.GuiGraphics;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraftforge.energy.IEnergyStorage;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class EnergyDisplay extends AbstractSimiWidget {
|
||||||
|
private final IEnergyStorage energy;
|
||||||
|
private final int xPos;
|
||||||
|
private final int yPos;
|
||||||
|
private final int width;
|
||||||
|
private final int height;
|
||||||
|
|
||||||
|
public EnergyDisplay(int x, int y, IEnergyStorage pEnergy) {
|
||||||
|
super(x, y);
|
||||||
|
this.xPos = x;
|
||||||
|
this.yPos = y;
|
||||||
|
this.width = 9;
|
||||||
|
this.height = 30;
|
||||||
|
this.energy = pEnergy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doRender(@NotNull GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float partialTicks) {
|
||||||
|
if (visible) {
|
||||||
|
isHovered = pMouseX >= getX() && pMouseY >= getY() && pMouseX < getX() + width && pMouseY < getY() + height;
|
||||||
|
|
||||||
|
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||||
|
drawBg(pGuiGraphics, LibGuiTextures.RF_VERTIVAL_BAR);
|
||||||
|
|
||||||
|
int stored = (int)(height * (energy.getEnergyStored() / (float)energy.getMaxEnergyStored()));
|
||||||
|
pGuiGraphics.fillGradient(xPos,yPos + (height - stored),xPos + width, yPos + height,0xffb51500, 0xff600b00);
|
||||||
|
if(isHovered()) {
|
||||||
|
Font font = Minecraft.getInstance().font;
|
||||||
|
pGuiGraphics.renderTooltip(font, getTooltips(),
|
||||||
|
Optional.empty(), pMouseX, pMouseY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
protected void drawBg(GuiGraphics graphics, LibGuiTextures button) {
|
||||||
|
graphics.blit(button.location, getX(), getY(), button.startX, button.startY, button.width, button.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Component> getTooltips() {
|
||||||
|
return List.of(Component.literal(energy.getEnergyStored()+" / "+energy.getMaxEnergyStored()+" FE"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package com.oierbravo.mechanical_lemon_ui.foundation.gui.widget;
|
||||||
|
/*
|
||||||
|
* Credits: Creators of create
|
||||||
|
* https://github.com/Creators-of-Create/Create
|
||||||
|
* License: MIT
|
||||||
|
*/
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
import com.oierbravo.mechanical_lemon_ui.foundation.utility.ScreenElement;
|
||||||
|
import com.oierbravo.mechanical_lemon_ui.register.LibGuiTextures;
|
||||||
|
import net.minecraft.client.gui.GuiGraphics;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
|
||||||
|
public class IconButton extends AbstractSimiWidget {
|
||||||
|
|
||||||
|
protected ScreenElement icon;
|
||||||
|
|
||||||
|
public IconButton(int x, int y, ScreenElement icon) {
|
||||||
|
this(x, y, 18, 18, icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IconButton(int x, int y, int w, int h, ScreenElement icon) {
|
||||||
|
super(x, y, w, h);
|
||||||
|
this.icon = icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doRender(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
|
||||||
|
if (visible) {
|
||||||
|
isHovered = mouseX >= getX() && mouseY >= getY() && mouseX < getX() + width && mouseY < getY() + height;
|
||||||
|
|
||||||
|
LibGuiTextures button = !active ? LibGuiTextures.BUTTON_DOWN
|
||||||
|
: isMouseOver(mouseX, mouseY) ? LibGuiTextures.BUTTON_HOVER : LibGuiTextures.BUTTON;
|
||||||
|
|
||||||
|
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||||
|
drawBg(graphics, button);
|
||||||
|
icon.render(graphics, getX() + 1, getY() + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void drawBg(GuiGraphics graphics, LibGuiTextures button) {
|
||||||
|
graphics.blit(button.location, getX(), getY(), button.startX, button.startY, button.width, button.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setToolTip(Component text) {
|
||||||
|
toolTip.clear();
|
||||||
|
toolTip.add(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIcon(ScreenElement icon) {
|
||||||
|
this.icon = icon;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.oierbravo.mechanical_lemon_ui.foundation.gui.widget;
|
||||||
|
|
||||||
|
import com.oierbravo.mechanical_lemon_ui.register.LibGuiTextures;
|
||||||
|
import net.minecraft.client.gui.GuiGraphics;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class ProgressArrow extends AbstractSimiWidget {
|
||||||
|
LibGuiTextures TEXTURE = LibGuiTextures.PROGRESS_ARROW_EMPTY;
|
||||||
|
int currentProgress;
|
||||||
|
private int progress;
|
||||||
|
|
||||||
|
public ProgressArrow(int x, int y) {
|
||||||
|
super(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doRender(@NotNull GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
|
||||||
|
graphics.blit(TEXTURE.location, getX(), getY(), TEXTURE.startX, TEXTURE.startY, currentProgress, TEXTURE.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProgress(int progress, int maxProgress) {
|
||||||
|
int progressArrowSize = TEXTURE.width;
|
||||||
|
this.currentProgress = maxProgress != 0 && progress != 0 ? progress * progressArrowSize / maxProgress : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,243 @@
|
|||||||
|
package com.oierbravo.mechanical_lemon_ui.foundation.utility;
|
||||||
|
/*
|
||||||
|
* Credits: Creators of create
|
||||||
|
* https://github.com/Creators-of-Create/Create
|
||||||
|
* License: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
import com.google.common.hash.Hashing;
|
||||||
|
import net.minecraft.util.Mth;
|
||||||
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.function.UnaryOperator;
|
||||||
|
|
||||||
|
public class Color {
|
||||||
|
public static final Color TRANSPARENT_BLACK = (new Color(0, 0, 0, 0)).setImmutable();
|
||||||
|
public static final Color BLACK = (new Color(0, 0, 0)).setImmutable();
|
||||||
|
public static final Color WHITE = (new Color(255, 255, 255)).setImmutable();
|
||||||
|
public static final Color RED = (new Color(255, 0, 0)).setImmutable();
|
||||||
|
public static final Color GREEN = (new Color(0, 255, 0)).setImmutable();
|
||||||
|
public static final Color SPRING_GREEN = (new Color(0, 255, 187)).setImmutable();
|
||||||
|
protected boolean mutable;
|
||||||
|
protected int value;
|
||||||
|
|
||||||
|
public Color(int r, int g, int b) {
|
||||||
|
this(r, g, b, 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color(int r, int g, int b, int a) {
|
||||||
|
this.mutable = true;
|
||||||
|
this.value = (a & 255) << 24 | (r & 255) << 16 | (g & 255) << 8 | (b & 255) << 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color(float r, float g, float b, float a) {
|
||||||
|
this((int)(0.5 + (double)(255.0F * Mth.clamp(r, 0.0F, 1.0F))), (int)(0.5 + (double)(255.0F * Mth.clamp(g, 0.0F, 1.0F))), (int)(0.5 + (double)(255.0F * Mth.clamp(b, 0.0F, 1.0F))), (int)(0.5 + (double)(255.0F * Mth.clamp(a, 0.0F, 1.0F))));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color(int rgba) {
|
||||||
|
this.mutable = true;
|
||||||
|
this.value = rgba;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color(int rgb, boolean hasAlpha) {
|
||||||
|
this.mutable = true;
|
||||||
|
if (hasAlpha) {
|
||||||
|
this.value = rgb;
|
||||||
|
} else {
|
||||||
|
this.value = rgb | -16777216;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color copy() {
|
||||||
|
return this.copy(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color copy(boolean mutable) {
|
||||||
|
return mutable ? new Color(this.value) : (new Color(this.value)).setImmutable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color setImmutable() {
|
||||||
|
this.mutable = false;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRed() {
|
||||||
|
return this.getRGB() >> 16 & 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getGreen() {
|
||||||
|
return this.getRGB() >> 8 & 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBlue() {
|
||||||
|
return this.getRGB() >> 0 & 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAlpha() {
|
||||||
|
return this.getRGB() >> 24 & 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getRedAsFloat() {
|
||||||
|
return (float)this.getRed() / 255.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getGreenAsFloat() {
|
||||||
|
return (float)this.getGreen() / 255.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getBlueAsFloat() {
|
||||||
|
return (float)this.getBlue() / 255.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getAlphaAsFloat() {
|
||||||
|
return (float)this.getAlpha() / 255.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRGB() {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec3 asVector() {
|
||||||
|
return new Vec3((double)this.getRedAsFloat(), (double)this.getGreenAsFloat(), (double)this.getBlueAsFloat());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3f asVectorF() {
|
||||||
|
return new Vector3f(this.getRedAsFloat(), this.getGreenAsFloat(), this.getBlueAsFloat());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color setRed(int r) {
|
||||||
|
return this.ensureMutable().setRedUnchecked(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color setGreen(int g) {
|
||||||
|
return this.ensureMutable().setGreenUnchecked(g);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color setBlue(int b) {
|
||||||
|
return this.ensureMutable().setBlueUnchecked(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color setAlpha(int a) {
|
||||||
|
return this.ensureMutable().setAlphaUnchecked(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color setRed(float r) {
|
||||||
|
return this.ensureMutable().setRedUnchecked((int)(255.0F * Mth.clamp(r, 0.0F, 1.0F)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color setGreen(float g) {
|
||||||
|
return this.ensureMutable().setGreenUnchecked((int)(255.0F * Mth.clamp(g, 0.0F, 1.0F)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color setBlue(float b) {
|
||||||
|
return this.ensureMutable().setBlueUnchecked((int)(255.0F * Mth.clamp(b, 0.0F, 1.0F)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color setAlpha(float a) {
|
||||||
|
return this.ensureMutable().setAlphaUnchecked((int)(255.0F * Mth.clamp(a, 0.0F, 1.0F)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color scaleAlpha(float factor) {
|
||||||
|
return this.ensureMutable().setAlphaUnchecked((int)((float)this.getAlpha() * Mth.clamp(factor, 0.0F, 1.0F)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color mixWith(Color other, float weight) {
|
||||||
|
return this.ensureMutable().setRedUnchecked((int)((float)this.getRed() + (float)(other.getRed() - this.getRed()) * weight)).setGreenUnchecked((int)((float)this.getGreen() + (float)(other.getGreen() - this.getGreen()) * weight)).setBlueUnchecked((int)((float)this.getBlue() + (float)(other.getBlue() - this.getBlue()) * weight)).setAlphaUnchecked((int)((float)this.getAlpha() + (float)(other.getAlpha() - this.getAlpha()) * weight));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color darker() {
|
||||||
|
int a = this.getAlpha();
|
||||||
|
return this.ensureMutable().mixWith(BLACK, 0.25F).setAlphaUnchecked(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color brighter() {
|
||||||
|
int a = this.getAlpha();
|
||||||
|
return this.ensureMutable().mixWith(WHITE, 0.25F).setAlphaUnchecked(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color setValue(int value) {
|
||||||
|
return this.ensureMutable().setValueUnchecked(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color modifyValue(UnaryOperator<Integer> function) {
|
||||||
|
int newValue = (Integer)function.apply(this.value);
|
||||||
|
return newValue == this.value ? this : this.ensureMutable().setValueUnchecked(newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Color ensureMutable() {
|
||||||
|
return this.mutable ? this : new Color(this.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Color setRedUnchecked(int r) {
|
||||||
|
this.value = this.value & -16711681 | (r & 255) << 16;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Color setGreenUnchecked(int g) {
|
||||||
|
this.value = this.value & -65281 | (g & 255) << 8;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Color setBlueUnchecked(int b) {
|
||||||
|
this.value = this.value & -256 | (b & 255) << 0;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Color setAlphaUnchecked(int a) {
|
||||||
|
this.value = this.value & 16777215 | (a & 255) << 24;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Color setValueUnchecked(int value) {
|
||||||
|
this.value = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Color mixColors(@Nonnull Color c1, @Nonnull Color c2, float w) {
|
||||||
|
return new Color((int)((float)c1.getRed() + (float)(c2.getRed() - c1.getRed()) * w), (int)((float)c1.getGreen() + (float)(c2.getGreen() - c1.getGreen()) * w), (int)((float)c1.getBlue() + (float)(c2.getBlue() - c1.getBlue()) * w), (int)((float)c1.getAlpha() + (float)(c2.getAlpha() - c1.getAlpha()) * w));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Color mixColors(@Nonnull Couple<Color> colors, float w) {
|
||||||
|
return mixColors((Color)colors.getFirst(), (Color)colors.getSecond(), w);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int mixColors(int color1, int color2, float w) {
|
||||||
|
int a1 = color1 >> 24;
|
||||||
|
int r1 = color1 >> 16 & 255;
|
||||||
|
int g1 = color1 >> 8 & 255;
|
||||||
|
int b1 = color1 & 255;
|
||||||
|
int a2 = color2 >> 24;
|
||||||
|
int r2 = color2 >> 16 & 255;
|
||||||
|
int g2 = color2 >> 8 & 255;
|
||||||
|
int b2 = color2 & 255;
|
||||||
|
return ((int)((float)a1 + (float)(a2 - a1) * w) << 24) + ((int)((float)r1 + (float)(r2 - r1) * w) << 16) + ((int)((float)g1 + (float)(g2 - g1) * w) << 8) + ((int)((float)b1 + (float)(b2 - b1) * w) << 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Color rainbowColor(int timeStep) {
|
||||||
|
int localTimeStep = Math.abs(timeStep) % 1536;
|
||||||
|
int timeStepInPhase = localTimeStep % 256;
|
||||||
|
int phaseBlue = localTimeStep / 256;
|
||||||
|
int red = colorInPhase(phaseBlue + 4, timeStepInPhase);
|
||||||
|
int green = colorInPhase(phaseBlue + 2, timeStepInPhase);
|
||||||
|
int blue = colorInPhase(phaseBlue, timeStepInPhase);
|
||||||
|
return new Color(red, green, blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int colorInPhase(int phase, int progress) {
|
||||||
|
phase %= 6;
|
||||||
|
if (phase <= 1) {
|
||||||
|
return 0;
|
||||||
|
} else if (phase == 2) {
|
||||||
|
return progress;
|
||||||
|
} else {
|
||||||
|
return phase <= 4 ? 255 : 255 - progress;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Color generateFromLong(long l) {
|
||||||
|
return rainbowColor(Hashing.crc32().hashLong(l).asInt()).mixWith(WHITE, 0.5F);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package com.oierbravo.mechanical_lemon_ui.foundation.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,155 @@
|
|||||||
|
package com.oierbravo.mechanical_lemon_ui.foundation.utility;
|
||||||
|
/*
|
||||||
|
* Credits: Creators of create
|
||||||
|
* https://github.com/Creators-of-Create/Create
|
||||||
|
* License: MIT
|
||||||
|
*/
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.nbt.ListTag;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.*;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class Couple<T> extends Pair<T, T> implements Iterable<T> {
|
||||||
|
|
||||||
|
private static final Couple<Boolean> TRUE_AND_FALSE = Couple.create(true, false);
|
||||||
|
|
||||||
|
protected Couple(T first, T second) {
|
||||||
|
super(first, second);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Couple<T> create(T first, T second) {
|
||||||
|
return new Couple<>(first, second);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Couple<T> create(Supplier<T> factory) {
|
||||||
|
return new Couple<>(factory.get(), factory.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Couple<T> createWithContext(Function<Boolean, T> factory) {
|
||||||
|
return new Couple<>(factory.apply(true), factory.apply(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
public T get(boolean first) {
|
||||||
|
return first ? getFirst() : getSecond();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(boolean first, T value) {
|
||||||
|
if (first)
|
||||||
|
setFirst(value);
|
||||||
|
else
|
||||||
|
setSecond(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Couple<T> copy() {
|
||||||
|
return create(first, second);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <S> Couple<S> map(Function<T, S> function) {
|
||||||
|
return Couple.create(function.apply(first), function.apply(second));
|
||||||
|
}
|
||||||
|
|
||||||
|
public <S> Couple<S> mapWithContext(BiFunction<T, Boolean, S> function) {
|
||||||
|
return Couple.create(function.apply(first, true), function.apply(second, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
public <S, R> Couple<S> mapWithParams(BiFunction<T, R, S> function, Couple<R> values) {
|
||||||
|
return Couple.create(function.apply(first, values.first), function.apply(second, values.second));
|
||||||
|
}
|
||||||
|
|
||||||
|
public <S, R> Couple<S> mapNotNullWithParam(BiFunction<T, R, S> function, R value) {
|
||||||
|
return Couple.create(first != null ? function.apply(first, value) : null,
|
||||||
|
second != null ? function.apply(second, value) : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean both(Predicate<T> test) {
|
||||||
|
return test.test(getFirst()) && test.test(getSecond());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean either(Predicate<T> test) {
|
||||||
|
return test.test(getFirst()) || test.test(getSecond());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void replace(Function<T, T> function) {
|
||||||
|
setFirst(function.apply(getFirst()));
|
||||||
|
setSecond(function.apply(getSecond()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void replaceWithContext(BiFunction<T, Boolean, T> function) {
|
||||||
|
replaceWithParams(function, TRUE_AND_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <S> void replaceWithParams(BiFunction<T, S, T> function, Couple<S> values) {
|
||||||
|
setFirst(function.apply(getFirst(), values.getFirst()));
|
||||||
|
setSecond(function.apply(getSecond(), values.getSecond()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void forEach(Consumer<? super T> consumer) {
|
||||||
|
consumer.accept(getFirst());
|
||||||
|
consumer.accept(getSecond());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void forEachWithContext(BiConsumer<T, Boolean> consumer) {
|
||||||
|
forEachWithParams(consumer, TRUE_AND_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <S> void forEachWithParams(BiConsumer<T, S> function, Couple<S> values) {
|
||||||
|
function.accept(getFirst(), values.getFirst());
|
||||||
|
function.accept(getSecond(), values.getSecond());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Couple<T> swap() {
|
||||||
|
return Couple.create(second, first);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ListTag serializeEach(Function<T, CompoundTag> serializer) {
|
||||||
|
return NBTHelper.writeCompoundList(ImmutableList.of(first, second), serializer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <S> Couple<S> deserializeEach(ListTag list, Function<CompoundTag, S> deserializer) {
|
||||||
|
List<S> readCompoundList = NBTHelper.readCompoundList(list, deserializer);
|
||||||
|
return new Couple<>(readCompoundList.get(0), readCompoundList.get(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<T> iterator() {
|
||||||
|
return new Couplerator<>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Stream<T> stream() {
|
||||||
|
return Stream.of(first, second);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Couplerator<T> implements Iterator<T> {
|
||||||
|
|
||||||
|
int state;
|
||||||
|
private final Couple<T> couple;
|
||||||
|
|
||||||
|
public Couplerator(Couple<T> couple) {
|
||||||
|
this.couple = couple;
|
||||||
|
state = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return state != 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T next() {
|
||||||
|
state++;
|
||||||
|
if (state == 1)
|
||||||
|
return couple.first;
|
||||||
|
if (state == 2)
|
||||||
|
return couple.second;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.oierbravo.mechanical_lemon_ui.foundation.utility;
|
||||||
|
/*
|
||||||
|
* smashingmods
|
||||||
|
*
|
||||||
|
* This code is licensed under "GNU Lesser General Public License"
|
||||||
|
* https://github.com/SmashingMods/AlchemyLib/
|
||||||
|
*
|
||||||
|
* Slightly Modified Version by: oierbravo
|
||||||
|
*/
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.gui.GuiGraphics;
|
||||||
|
import net.minecraft.client.renderer.RenderType;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
|
||||||
|
public class FakeItemRenderer {
|
||||||
|
|
||||||
|
public static void renderFakeItem(GuiGraphics pGuiGraphics, ItemStack pItemStack, int pX, int pY) {
|
||||||
|
renderFakeItem(pGuiGraphics, pItemStack, pX, pY, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void renderFakeItem(GuiGraphics pGuiGraphics, ItemStack pItemStack, int pX, int pY, boolean pDrawItemDecorations) {
|
||||||
|
renderFakeItem(pGuiGraphics, pItemStack, pX, pY, true, pDrawItemDecorations);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void renderFakeItem(GuiGraphics pGuiGraphics, ItemStack pItemStack, int pX, int pY, boolean pSemiTransparent, boolean pDrawItemDecorations) {
|
||||||
|
pGuiGraphics.renderFakeItem(pItemStack, pX, pY);
|
||||||
|
if (pSemiTransparent) {
|
||||||
|
pGuiGraphics.fill(RenderType.guiGhostRecipeOverlay(), pX, pY, pX + 16, pY + 16, 0x88888888);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pDrawItemDecorations) {
|
||||||
|
pGuiGraphics.renderItemDecorations(Minecraft.getInstance().font, pItemStack, pX, pY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package com.oierbravo.mechanical_lemon_ui.foundation.utility;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
import com.oierbravo.mechanical_lemon_ui.foundation.gui.UIRenderHelper;
|
||||||
|
import net.minecraft.client.gui.GuiGraphics;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
/*
|
||||||
|
* Credits: Creators of create
|
||||||
|
* https://github.com/Creators-of-Create/Create
|
||||||
|
* License: MIT
|
||||||
|
*/
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
|
||||||
|
public abstract class IGuiTextures {
|
||||||
|
|
||||||
|
ResourceLocation location = null;
|
||||||
|
int width = 0;
|
||||||
|
int height = 0;
|
||||||
|
int startX = 0;
|
||||||
|
int startY = 0;
|
||||||
|
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public void bind() {
|
||||||
|
RenderSystem.setShaderTexture(0, location);
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public void render(GuiGraphics graphics, int x, int y) {
|
||||||
|
graphics.blit(location, x, y, startX, startY, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public void render(GuiGraphics graphics, int x, int y, Color c) {
|
||||||
|
bind();
|
||||||
|
UIRenderHelper.drawColoredTexture(graphics, c, x, y, startX, startY, width, height);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.oierbravo.mechanical_lemon_ui.foundation.utility;
|
||||||
|
/*
|
||||||
|
* Credits: Creators of create
|
||||||
|
* https://github.com/Creators-of-Create/Create
|
||||||
|
* License: MIT
|
||||||
|
*/
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
|
||||||
|
public interface IInteractionChecker {
|
||||||
|
boolean canPlayerUse(Player player);
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
package com.oierbravo.mechanical_lemon_ui.foundation.utility;
|
||||||
|
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.network.chat.MutableComponent;
|
||||||
|
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 Lang() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MutableComponent translateDirect(String key, Object... args) {
|
||||||
|
return Components.translatable("create." + key, resolveBuilders(args));
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
String[] var3 = keys;
|
||||||
|
int var4 = keys.length;
|
||||||
|
|
||||||
|
for(int var5 = 0; var5 < var4; ++var5) {
|
||||||
|
String key = var3[var5];
|
||||||
|
result.add(translate((prefix != null ? prefix + "." : "") + key).component());
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LangBuilder builder() {
|
||||||
|
return new LangBuilder("create");
|
||||||
|
}
|
||||||
|
|
||||||
|
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 LangBuilder number(double d) {
|
||||||
|
return builder().text(LangNumberFormat.format(d));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static 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) {
|
||||||
|
Object var3 = args[i];
|
||||||
|
if (var3 instanceof LangBuilder cb) {
|
||||||
|
args[i] = cb.component();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,190 @@
|
|||||||
|
package com.oierbravo.mechanical_lemon_ui.foundation.utility;
|
||||||
|
|
||||||
|
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(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,35 @@
|
|||||||
|
package com.oierbravo.mechanical_lemon_ui.foundation.utility;
|
||||||
|
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.util.Mth;
|
||||||
|
|
||||||
|
import java.text.NumberFormat;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
public class LangNumberFormat {
|
||||||
|
|
||||||
|
private NumberFormat format = NumberFormat.getNumberInstance(Locale.ROOT);
|
||||||
|
public static LangNumberFormat numberFormat = new LangNumberFormat();
|
||||||
|
|
||||||
|
public NumberFormat get() {
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update() {
|
||||||
|
format = NumberFormat.getInstance(Minecraft.getInstance()
|
||||||
|
.getLanguageManager()
|
||||||
|
.getJavaLocale());
|
||||||
|
format.setMaximumFractionDigits(2);
|
||||||
|
format.setMinimumFractionDigits(0);
|
||||||
|
format.setGroupingUsed(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String format(double d) {
|
||||||
|
if (Mth.equal(d, 0))
|
||||||
|
d = 0;
|
||||||
|
return numberFormat.get()
|
||||||
|
.format(d)
|
||||||
|
.replace("\u00A0", " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
package com.oierbravo.mechanical_lemon_ui.foundation.utility;
|
||||||
|
/*
|
||||||
|
* Credits: Creators of create
|
||||||
|
* https://github.com/Creators-of-Create/Create
|
||||||
|
* License: MIT
|
||||||
|
*/
|
||||||
|
import net.minecraft.core.Vec3i;
|
||||||
|
import net.minecraft.nbt.*;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.phys.AABB;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public class NBTHelper {
|
||||||
|
|
||||||
|
public static void putMarker(CompoundTag nbt, String marker) {
|
||||||
|
nbt.putBoolean(marker, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T extends Enum<?>> T readEnum(CompoundTag nbt, String key, Class<T> enumClass) {
|
||||||
|
T[] enumConstants = enumClass.getEnumConstants();
|
||||||
|
if (enumConstants == null)
|
||||||
|
throw new IllegalArgumentException("Non-Enum class passed to readEnum: " + enumClass.getName());
|
||||||
|
if (nbt.contains(key, Tag.TAG_STRING)) {
|
||||||
|
String name = nbt.getString(key);
|
||||||
|
for (T t : enumConstants) {
|
||||||
|
if (t.name()
|
||||||
|
.equals(name))
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return enumConstants[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T extends Enum<?>> void writeEnum(CompoundTag nbt, String key, T enumConstant) {
|
||||||
|
nbt.putString(key, enumConstant.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> ListTag writeCompoundList(Iterable<T> list, Function<T, CompoundTag> serializer) {
|
||||||
|
ListTag listNBT = new ListTag();
|
||||||
|
list.forEach(t -> {
|
||||||
|
CompoundTag apply = serializer.apply(t);
|
||||||
|
if (apply == null)
|
||||||
|
return;
|
||||||
|
listNBT.add(apply);
|
||||||
|
});
|
||||||
|
return listNBT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> List<T> readCompoundList(ListTag listNBT, Function<CompoundTag, T> deserializer) {
|
||||||
|
List<T> list = new ArrayList<>(listNBT.size());
|
||||||
|
listNBT.forEach(inbt -> list.add(deserializer.apply((CompoundTag) inbt)));
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> void iterateCompoundList(ListTag listNBT, Consumer<CompoundTag> consumer) {
|
||||||
|
listNBT.forEach(inbt -> consumer.accept((CompoundTag) inbt));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ListTag writeItemList(Iterable<ItemStack> stacks) {
|
||||||
|
return writeCompoundList(stacks, ItemStack::serializeNBT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<ItemStack> readItemList(ListTag stacks) {
|
||||||
|
return readCompoundList(stacks, ItemStack::of);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ListTag writeAABB(AABB bb) {
|
||||||
|
ListTag bbtag = new ListTag();
|
||||||
|
bbtag.add(FloatTag.valueOf((float) bb.minX));
|
||||||
|
bbtag.add(FloatTag.valueOf((float) bb.minY));
|
||||||
|
bbtag.add(FloatTag.valueOf((float) bb.minZ));
|
||||||
|
bbtag.add(FloatTag.valueOf((float) bb.maxX));
|
||||||
|
bbtag.add(FloatTag.valueOf((float) bb.maxY));
|
||||||
|
bbtag.add(FloatTag.valueOf((float) bb.maxZ));
|
||||||
|
return bbtag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AABB readAABB(ListTag bbtag) {
|
||||||
|
if (bbtag == null || bbtag.isEmpty())
|
||||||
|
return null;
|
||||||
|
return new AABB(bbtag.getFloat(0), bbtag.getFloat(1), bbtag.getFloat(2), bbtag.getFloat(3),
|
||||||
|
bbtag.getFloat(4), bbtag.getFloat(5));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ListTag writeVec3i(Vec3i vec) {
|
||||||
|
ListTag tag = new ListTag();
|
||||||
|
tag.add(IntTag.valueOf(vec.getX()));
|
||||||
|
tag.add(IntTag.valueOf(vec.getY()));
|
||||||
|
tag.add(IntTag.valueOf(vec.getZ()));
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vec3i readVec3i(ListTag tag) {
|
||||||
|
return new Vec3i(tag.getInt(0), tag.getInt(1), tag.getInt(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public static Tag getINBT(CompoundTag nbt, String id) {
|
||||||
|
Tag inbt = nbt.get(id);
|
||||||
|
if (inbt != null)
|
||||||
|
return inbt;
|
||||||
|
return new CompoundTag();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CompoundTag intToCompound(int i) {
|
||||||
|
CompoundTag compoundTag = new CompoundTag();
|
||||||
|
compoundTag.putInt("V", i);
|
||||||
|
return compoundTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int intFromCompound(CompoundTag compoundTag) {
|
||||||
|
return compoundTag.getInt("V");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void writeResourceLocation(CompoundTag nbt, String key, ResourceLocation location) {
|
||||||
|
nbt.putString(key, location.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ResourceLocation readResourceLocation(CompoundTag nbt, String key) {
|
||||||
|
return new ResourceLocation(nbt.getString(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
package com.oierbravo.mechanical_lemon_ui.foundation.utility;
|
||||||
|
/*
|
||||||
|
* Credits: Creators of create
|
||||||
|
* https://github.com/Creators-of-Create/Create
|
||||||
|
* License: MIT
|
||||||
|
*/
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class Pair<F, S> {
|
||||||
|
|
||||||
|
F first;
|
||||||
|
S second;
|
||||||
|
|
||||||
|
protected Pair(F first, S second) {
|
||||||
|
this.first = first;
|
||||||
|
this.second = second;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <F, S> Pair<F, S> of(F first, S second) {
|
||||||
|
return new Pair<>(first, second);
|
||||||
|
}
|
||||||
|
|
||||||
|
public F getFirst() {
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
|
||||||
|
public S getSecond() {
|
||||||
|
return second;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirst(F first) {
|
||||||
|
this.first = first;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSecond(S second) {
|
||||||
|
this.second = second;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pair<F, S> copy() {
|
||||||
|
return Pair.of(first, second);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object obj) {
|
||||||
|
if (obj == this)
|
||||||
|
return true;
|
||||||
|
if (obj instanceof Pair) {
|
||||||
|
final Pair<?, ?> other = (Pair<?, ?>) obj;
|
||||||
|
return Objects.equals(first, other.first) && Objects.equals(second, other.second);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return (nullHash(first) * 31) ^ nullHash(second);
|
||||||
|
}
|
||||||
|
|
||||||
|
int nullHash(Object o) {
|
||||||
|
return o == null ? 0 : o.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "(" + first + ", " + second + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pair<S, F> swap() {
|
||||||
|
return Pair.of(second, first);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.oierbravo.mechanical_lemon_ui.foundation.utility;
|
||||||
|
/*
|
||||||
|
* Credits: Creators of create
|
||||||
|
* https://github.com/Creators-of-Create/Create
|
||||||
|
* License: MIT
|
||||||
|
*/
|
||||||
|
import net.minecraft.client.gui.GuiGraphics;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
|
||||||
|
public interface ScreenElement {
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
void render(GuiGraphics var1, int var2, int var3);
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package com.oierbravo.mechanical_lemon_ui.register;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
import com.oierbravo.mechanical_lemon_ui.MechanicalLemonUI;
|
||||||
|
import com.oierbravo.mechanical_lemon_ui.foundation.gui.UIRenderHelper;
|
||||||
|
import com.oierbravo.mechanical_lemon_ui.foundation.utility.Color;
|
||||||
|
import com.oierbravo.mechanical_lemon_ui.foundation.utility.ScreenElement;
|
||||||
|
import net.minecraft.client.gui.GuiGraphics;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
|
||||||
|
public enum LibGuiTextures implements ScreenElement {
|
||||||
|
PLAYER_INVENTORY("player_inventory", 176, 108),
|
||||||
|
|
||||||
|
|
||||||
|
BUTTON("widgets", 18, 18),
|
||||||
|
BUTTON_HOVER("widgets", 18, 0, 18, 18),
|
||||||
|
BUTTON_DOWN("widgets", 36, 0, 18, 18),
|
||||||
|
SLOT_EMPTY("widgets", 36, 0, 18, 18),
|
||||||
|
RF_VERTIVAL_BAR("widgets",0,18,10,30),
|
||||||
|
PROGRESS_ARROW_EMPTY("widgets",0,48,32,8),
|
||||||
|
PROGRESS_ARROW_FULL("widgets",0,56,32,8)
|
||||||
|
;
|
||||||
|
|
||||||
|
public static final int FONT_COLOR = 0x575F7A;
|
||||||
|
|
||||||
|
public final ResourceLocation location;
|
||||||
|
public int width, height;
|
||||||
|
public int startX, startY;
|
||||||
|
|
||||||
|
private LibGuiTextures(String location, int width, int height) {
|
||||||
|
this(location, 0, 0, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
private LibGuiTextures(int startX, int startY) {
|
||||||
|
this("icons", startX * 16, startY * 16, 16, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
private LibGuiTextures(String location, int startX, int startY, int width, int height) {
|
||||||
|
this(MechanicalLemonUI.MODID, location, startX, startY, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
private LibGuiTextures(String namespace, String location, int startX, int startY, int width, int height) {
|
||||||
|
this.location = new ResourceLocation(namespace, "textures/gui/" + location + ".png");
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
this.startX = startX;
|
||||||
|
this.startY = startY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public void bind() {
|
||||||
|
RenderSystem.setShaderTexture(0, location);
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public void render(GuiGraphics graphics, int x, int y) {
|
||||||
|
graphics.blit(location, x, y, startX, startY, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public void render(GuiGraphics graphics, int x, int y, Color c) {
|
||||||
|
bind();
|
||||||
|
UIRenderHelper.drawColoredTexture(graphics, c, x, y, startX, startY, width, height);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
package com.oierbravo.mechanical_lemon_ui.register;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||||
|
import com.oierbravo.mechanical_lemon_ui.MechanicalLemonUI;
|
||||||
|
import com.oierbravo.mechanical_lemon_ui.foundation.utility.Color;
|
||||||
|
import com.oierbravo.mechanical_lemon_ui.foundation.utility.ScreenElement;
|
||||||
|
import net.minecraft.client.gui.GuiGraphics;
|
||||||
|
import net.minecraft.client.renderer.MultiBufferSource;
|
||||||
|
import net.minecraft.client.renderer.RenderType;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
import org.joml.Matrix4f;
|
||||||
|
|
||||||
|
public class LibIcons implements ScreenElement {
|
||||||
|
public static final ResourceLocation ICON_ATLAS = MechanicalLemonUI.asResource("textures/gui/icons.png");
|
||||||
|
public static final int ICON_ATLAS_SIZE = 256;
|
||||||
|
private static int x = 0;
|
||||||
|
private static int y = -1;
|
||||||
|
private int iconX;
|
||||||
|
private int iconY;
|
||||||
|
public static final LibIcons ARROW_LEFT = newRow();
|
||||||
|
public static final LibIcons TRASH = next();
|
||||||
|
public static final LibIcons REDSTONE_HIGH = next();
|
||||||
|
public static final LibIcons REDSTONE_LOW = next();
|
||||||
|
public static final LibIcons REDSTONE_IGNORE = next();
|
||||||
|
public static final LibIcons SEARCH = next();
|
||||||
|
public static final LibIcons CHECK = next();
|
||||||
|
|
||||||
|
public LibIcons(int x, int y) {
|
||||||
|
this.iconX = x * 16;
|
||||||
|
this.iconY = y * 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static LibIcons next() {
|
||||||
|
return new LibIcons(++x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static LibIcons newRow() {
|
||||||
|
x = 0;
|
||||||
|
return new LibIcons(0, ++y);
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public void bind() {
|
||||||
|
RenderSystem.setShaderTexture(0, ICON_ATLAS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public void render(GuiGraphics graphics, int x, int y) {
|
||||||
|
graphics.blit(ICON_ATLAS, x, y, 0, (float)this.iconX, (float)this.iconY, 16, 16, 256, 256);
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public void render(PoseStack ms, MultiBufferSource buffer, int color) {
|
||||||
|
VertexConsumer builder = buffer.getBuffer(RenderType.text(ICON_ATLAS));
|
||||||
|
Matrix4f matrix = ms.last().pose();
|
||||||
|
Color rgb = new Color(color);
|
||||||
|
int light = 15728880;
|
||||||
|
Vec3 vec1 = new Vec3(0.0, 0.0, 0.0);
|
||||||
|
Vec3 vec2 = new Vec3(0.0, 1.0, 0.0);
|
||||||
|
Vec3 vec3 = new Vec3(1.0, 1.0, 0.0);
|
||||||
|
Vec3 vec4 = new Vec3(1.0, 0.0, 0.0);
|
||||||
|
float u1 = (float)this.iconX * 1.0F / 256.0F;
|
||||||
|
float u2 = (float)(this.iconX + 16) * 1.0F / 256.0F;
|
||||||
|
float v1 = (float)this.iconY * 1.0F / 256.0F;
|
||||||
|
float v2 = (float)(this.iconY + 16) * 1.0F / 256.0F;
|
||||||
|
this.vertex(builder, matrix, vec1, rgb, u1, v1, light);
|
||||||
|
this.vertex(builder, matrix, vec2, rgb, u1, v2, light);
|
||||||
|
this.vertex(builder, matrix, vec3, rgb, u2, v2, light);
|
||||||
|
this.vertex(builder, matrix, vec4, rgb, u2, v1, light);
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
private void vertex(VertexConsumer builder, Matrix4f matrix, Vec3 vec, Color rgb, float u, float v, int light) {
|
||||||
|
builder.vertex(matrix, (float)vec.x, (float)vec.y, (float)vec.z).color(rgb.getRed(), rgb.getGreen(), rgb.getBlue(), 255).uv(u, v).uv2(light).endVertex();
|
||||||
|
}
|
||||||
|
}
|
||||||
24
src/main/resources/META-INF/mods.toml
Normal file
24
src/main/resources/META-INF/mods.toml
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
modLoader = "javafml" #mandatory
|
||||||
|
loaderVersion = "${loader_version_range}" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions.
|
||||||
|
license = "${mod_license}"
|
||||||
|
|
||||||
|
[[mods]] #mandatory
|
||||||
|
modId = "${modid}" #mandatory
|
||||||
|
version = "${mod_version}" #mandatory
|
||||||
|
displayName = "${mod_name}" #mandatory
|
||||||
|
authors = "${author}" #optional
|
||||||
|
description = '''${mod_description}'''
|
||||||
|
|
||||||
|
[[dependencies."${modid}"]] #optional
|
||||||
|
modId = "forge" #mandatory
|
||||||
|
mandatory = true #mandatory
|
||||||
|
versionRange = "${forge_version_range}" #mandatory
|
||||||
|
ordering = "NONE"
|
||||||
|
side = "BOTH"# Here's another dependency
|
||||||
|
|
||||||
|
[[dependencies."${modid}"]]
|
||||||
|
modId = "minecraft"
|
||||||
|
mandatory = true
|
||||||
|
versionRange = "${minecraft_version_range}"
|
||||||
|
ordering = "NONE"
|
||||||
|
side = "BOTH"
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
{
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 638 B |
Binary file not shown.
|
After Width: | Height: | Size: 377 B |
Binary file not shown.
|
After Width: | Height: | Size: 740 B |
6
src/main/resources/pack.mcmeta
Normal file
6
src/main/resources/pack.mcmeta
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"pack": {
|
||||||
|
"description": "mechanical_lemon_ui resources",
|
||||||
|
"pack_format": 15
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user