9 Commits
1.20 ... 1.21

Author SHA1 Message Date
Christian Knaapen
64b0fbc0aa Updated dependencies 2025-03-22 11:47:57 +01:00
Mrbysco
9476ecbcc5 Initial port to 1.21.1
TODO:
* Fix the ghost block rendering
* Fix the placement canceling on setting coordinates
2025-03-01 15:09:01 +01:00
Mrbysco
778ae7ddd9 Port to 1.20.4 2024-11-20 17:06:19 +01:00
Mrbysco
08c3b4b42d Switch Power Level to a player capability 2023-11-21 20:22:20 +01:00
Mrbysco
28d47a0cbb Fix textures not being recognized
Mojang no longer automatically loads textures in `textures/items` as they now load textures from `textures/item`
2023-11-21 02:48:06 +01:00
Mrbysco
00cb48b929 Fix loot modifiers
altenative was renamed to any_of
2023-11-21 02:46:50 +01:00
Mrbysco
b75cfc45d8 Fix missing calls 2023-11-18 20:49:10 +01:00
Mrbysco
ca44da71e7 Fresh port to 1.20
Note: I changed `BuildModeCategoryEnum` to actually use the Color class instead of using Vector4f. Same counts for `RadialMenu`
2023-11-18 00:38:56 +01:00
Christian Knaapen
8570bde282 Fixed not being able to load when the newest version of Create is installed. 2023-10-22 13:38:47 +02:00
273 changed files with 4214 additions and 10108 deletions

6
.gitignore vendored
View File

@@ -20,7 +20,7 @@ build
# other # other
eclipse eclipse
run run
logs/* runs
run-data
# Files from Forge MDK repo
forge*changelog.txt

View File

@@ -1,92 +1,68 @@
buildscript {
repositories {
maven { url = 'https://maven.minecraftforge.net' }
mavenCentral()
jcenter()
maven { url = 'https://repo.spongepowered.org/repository/maven-public' }
maven { url = 'https://maven.parchmentmc.org' }
}
dependencies {
classpath "net.minecraftforge.gradle:ForgeGradle:${forgegradle_version}"
classpath "org.spongepowered:mixingradle:${mixingradle_version}"
classpath "org.parchmentmc:librarian:${librarian_version}"
}
}
plugins { plugins {
id 'java-library'
id 'eclipse'
id 'idea'
id 'maven-publish'
id 'net.neoforged.gradle.userdev' version "${neogradle_version}"
id 'com.matthewprenger.cursegradle' version "${cursegradle_version}" id 'com.matthewprenger.cursegradle' version "${cursegradle_version}"
} }
apply plugin: 'net.minecraftforge.gradle'
apply plugin: 'org.parchmentmc.librarian.forgegradle'
apply plugin: 'eclipse'
apply plugin: 'maven-publish'
apply plugin: 'org.spongepowered.mixin'
jarJar.enable() boolean ponderInWorkspace = findProject(':Ponder') != null
boolean flywheelInWorkspace = findProject(':Flywheel') != null
ext.buildNumber = System.getenv('BUILD_NUMBER') ext.buildNumber = System.getenv('BUILD_NUMBER')
version = mod_version version = mod_version
group = 'nl.requios.effortlessbuilding' group = 'nl.requios.effortlessbuilding'
archivesBaseName = "effortlessbuilding-${artifact_minecraft_version}" base {
archivesName = "effortlessbuilding-${artifact_minecraft_version}"
}
java.toolchain.languageVersion = JavaLanguageVersion.of(17) java.toolchain.languageVersion = JavaLanguageVersion.of(21)
println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + ' (' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch')) println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + ' (' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch'))
minecraft { minecraft.accessTransformers.file rootProject.file('src/main/resources/META-INF/accesstransformer.cfg')
mappings channel: 'parchment', version: "${parchment_version}-${minecraft_version}"
accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')
runs { runs {
client { // applies to all the run configs below
workingDirectory project.file('run') configureEach { net.neoforged.gradle.dsl.common.runs.run.Run run ->
arg '-mixin.config=flywheel.mixins.json' // Recommended logging data for a userdev environment
//jvmArgs '-XX:+UnlockCommercialFeatures' // uncomment for profiling systemProperty 'forge.logging.markers', 'REGISTRIES'
property 'forge.logging.console.level', 'info'
mods { // Recommended logging level for the console
effortlessbuilding { systemProperty 'forge.logging.console.level', 'debug'
source sourceSets.main
}
if (flywheelInWorkspace) { //Limit ram usage for the dev environment to 4GB
flywheel { jvmArgument '-Xmx4G'
source project(":Flywheel").sourceSets.main if (run.project.javaToolchains.launcherFor(java.toolchain).map { it.metadata.vendor }.getOrElse("").contains("JetBrains")) {
} jvmArgument '-XX:+AllowEnhancedClassRedefinition'
}
}
} }
server { modSource project.sourceSets.main
workingDirectory project.file('run/server') }
property 'forge.logging.console.level', 'info'
mods { client {
effortlessbuilding { // Comma-separated list of namespaces to load gametests from. Empty = all namespaces.
source sourceSets.main systemProperty 'neoforge.enabledGameTestNamespaces', "effortlessbuilding"
}
if (ponderInWorkspace) {
dependencies {
runtime project(':Ponder')
} }
} }
}
data { server {
workingDirectory project.file('run') systemProperty 'neoforge.enabledGameTestNamespaces', "effortlessbuilding"
property 'forge.logging.markers', 'REGISTRIES,REGISTRYDUMP' programArgument '--nogui'
property 'forge.logging.console.level', 'debug' }
args '--mod', 'effortlessbuilding', '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources')
mods {
effortlessbuilding {
source sourceSets.main
}
if (flywheelInWorkspace) { data {
flywheel { // example of overriding the workingDirectory set in configureEach above, uncomment if you want to use it
source project(":Flywheel").sourceSets.main // workingDirectory project.file('run-data')
}
} // Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources.
} programArguments.addAll '--mod', "effortlessbuilding", '--all', '--output', file('src/generated/resources/').getAbsolutePath(), '--existing', file('src/main/resources/').getAbsolutePath()
}
} }
} }
@@ -96,10 +72,18 @@ repositories {
name = 'tterrag maven' name = 'tterrag maven'
url = 'https://maven.tterrag.com' url = 'https://maven.tterrag.com'
} }
maven { maven {
url = 'https://www.cursemaven.com' // Ponder, Flywheel
content { url = "https://maven.createmod.net"
}
maven { url = "https://raw.githubusercontent.com/Fuzss/modresources/main/maven" } // NeoForge config api port, needed by ponder
exclusiveContent {
forRepository {
maven {
url "https://cursemaven.com"
}
}
filter {
includeGroup "curse.maven" includeGroup "curse.maven"
} }
} }
@@ -118,22 +102,24 @@ repositories {
} }
dependencies { dependencies {
minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}" implementation "net.neoforged:neoforge:${neo_version}"
jarJar("com.jozufozu.flywheel:flywheel-forge-${flywheel_minecraft_version}:${flywheel_version}") { jarJar("net.createmod.ponder:Ponder-NeoForge-${minecraft_version}:${ponder_version}")
jarJar.ranged(it, '[0.6.9,0.6.10)')
}
if (flywheelInWorkspace) { compileOnly("dev.engine-room.flywheel:flywheel-neoforge-api-${flywheel_minecraft_version}:${flywheel_version}")
implementation project(':Flywheel') runtimeOnly(jarJar("dev.engine-room.flywheel:flywheel-neoforge-${flywheel_minecraft_version}:${flywheel_version}") {
version {
strictly "[1.0,2.0)"
prefer flywheel_version
}
})
runtimeOnly("dev.engine-room.vanillin:vanillin-neoforge-${flywheel_minecraft_version}:${vanillin_version}")
if (ponderInWorkspace) {
implementation(project(":ponder:Common"))
implementation(project(":ponder:NeoForge"))
} else { } else {
implementation fg.deobf("com.jozufozu.flywheel:flywheel-forge-${flywheel_minecraft_version}:${flywheel_version}") implementation("net.createmod.ponder:Ponder-NeoForge-${minecraft_version}:${ponder_version}")
}
// Prevent Mixin annotation processor from getting into IntelliJ's annotation processor settings
// This allows 'Settings > Build, Execution, and Deployment > Build Tools > Gradle > Build and run using' set to IntelliJ to work correctly
if (!Boolean.getBoolean('idea.sync.active')) {
annotationProcessor "org.spongepowered:mixin:${mixin_version}:processor"
} }
} }
@@ -145,6 +131,14 @@ tasks.withType(JavaCompile).configureEach {
options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation
} }
// IDEA no longer automatically downloads sources/javadoc jars for dependencies, so we need to explicitly enable the behavior.
idea {
module {
downloadSources = true
downloadJavadoc = true
}
}
compileJava { compileJava {
options.compilerArgs = ['-Xdiags:verbose'] options.compilerArgs = ['-Xdiags:verbose']
} }
@@ -155,7 +149,7 @@ jar {
"Specification-Title": "effortlessbuilding", "Specification-Title": "effortlessbuilding",
"Specification-Vendor": "requios", "Specification-Vendor": "requios",
"Specification-Version": "1", "Specification-Version": "1",
"Implementation-Title": project.jar.baseName, "Implementation-Title": project.name,
"Implementation-Version": project.jar.archiveVersion, "Implementation-Version": project.jar.archiveVersion,
"Implementation-Vendor" :"requios", "Implementation-Vendor" :"requios",
"Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ")
@@ -178,17 +172,15 @@ java {
withJavadocJar() withJavadocJar()
} }
jar.finalizedBy('reobfJar') tasks.build.dependsOn tasks.jarJar
tasks.jarJar.finalizedBy('reobfJarJar')
publishing { publishing {
publications { publications {
mavenJava(MavenPublication) { mavenJava(MavenPublication) {
artifactId = archivesBaseName artifactId = base.archivesName.get()
from components.java from components.java
fg.component(it) // fg.component(it)
jarJar.component(it)
} }
} }

View File

@@ -3,18 +3,19 @@
org.gradle.jvmargs=-Xmx3G org.gradle.jvmargs=-Xmx3G
org.gradle.daemon=false org.gradle.daemon=false
mod_version = 3.4 mod_version = 3.10
artifact_minecraft_version = 1.19.2 artifact_minecraft_version = 1.21.1
minecraft_version = 1.19.2 minecraft_version = 1.21.1
forge_version = 43.1.47 neo_version = 21.1.129
neogradle.subsystems.parchment.minecraftVersion = 1.21.1
neogradle.subsystems.parchment.mappingsVersion = 2024.11.17
neogradle.subsystems.conventions.runs.create-default-run-per-type = false
forgegradle_version = 5.1.53 neogradle_version = 7.0.181
mixingradle_version = 0.7-SNAPSHOT
mixin_version = 0.8.5
librarian_version = 1.+
cursegradle_version = 1.4.0 cursegradle_version = 1.4.0
parchment_version = 2022.11.27
flywheel_minecraft_version = 1.19.2 flywheel_minecraft_version = 1.21.1
flywheel_version = 0.6.9-18 flywheel_version = 1.0.2
vanillin_version = 1.0.0-beta-11
ponder_version = 1.0.46

Binary file not shown.

View File

@@ -1,5 +1,7 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

54
gradlew vendored
View File

@@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
# #
# Copyright <EFBFBD> 2015-2021 the original authors. # Copyright © 2015-2021 the original authors.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
# #
# SPDX-License-Identifier: Apache-2.0
#
############################################################################## ##############################################################################
# #
@@ -32,10 +34,10 @@
# Busybox and similar reduced shells will NOT work, because this script # Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features: # requires all of these POSIX shell features:
# * functions; # * functions;
# * expansions <EFBFBD>$var<EFBFBD>, <EFBFBD>${var}<EFBFBD>, <EFBFBD>${var:-default}<EFBFBD>, <EFBFBD>${var+SET}<EFBFBD>, # * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# <EFBFBD>${var#prefix}<EFBFBD>, <EFBFBD>${var%suffix}<EFBFBD>, and <EFBFBD>$( cmd )<EFBFBD>; # «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially <EFBFBD>case<EFBFBD>; # * compound commands having a testable exit status, especially «case»;
# * various built-in commands including <EFBFBD>command<EFBFBD>, <EFBFBD>set<EFBFBD>, and <EFBFBD>ulimit<EFBFBD>. # * various built-in commands including «command», «set», and «ulimit».
# #
# Important for patching: # Important for patching:
# #
@@ -55,7 +57,7 @@
# Darwin, MinGW, and NonStop. # Darwin, MinGW, and NonStop.
# #
# (3) This script is generated from the Groovy template # (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project. # within the Gradle project.
# #
# You can find Gradle at https://github.com/gradle/gradle/. # You can find Gradle at https://github.com/gradle/gradle/.
@@ -80,13 +82,12 @@ do
esac esac
done done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # This is normally unused
# shellcheck disable=SC2034
APP_NAME="Gradle"
APP_BASE_NAME=${0##*/} APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' ' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum MAX_FD=maximum
@@ -133,22 +134,29 @@ location of your Java installation."
fi fi
else else
JAVACMD=java JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 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 Please set the JAVA_HOME variable in your environment to match the
location of your Java installation." location of your Java installation."
fi
fi fi
# Increase the maximum file descriptors if we can. # Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #( case $MAX_FD in #(
max*) 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 ) || MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit" warn "Could not query maximum file descriptor limit"
esac esac
case $MAX_FD in #( case $MAX_FD in #(
'' | soft) :;; #( '' | 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" || ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD" warn "Could not set maximum file descriptor limit to $MAX_FD"
esac esac
@@ -193,11 +201,15 @@ if "$cygwin" || "$msys" ; then
done done
fi fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
# shell script including quotes and variable substitutions, so put them in DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded. # 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 -- \ set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \ "-Dorg.gradle.appname=$APP_BASE_NAME" \
@@ -205,6 +217,12 @@ set -- \
org.gradle.wrapper.GradleWrapperMain \ 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. # Use "xargs" to parse quoted args.
# #
# With -n1 it outputs one arg per line, with the quotes and backslashes removed. # With -n1 it outputs one arg per line, with the quotes and backslashes removed.

37
gradlew.bat vendored
View File

@@ -13,8 +13,10 @@
@rem See the License for the specific language governing permissions and @rem See the License for the specific language governing permissions and
@rem limitations under the License. @rem limitations under the License.
@rem @rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%" == "" @echo off @if "%DEBUG%"=="" @echo off
@rem ########################################################################## @rem ##########################################################################
@rem @rem
@rem Gradle startup script for Windows @rem Gradle startup script for Windows
@@ -25,7 +27,8 @@
if "%OS%"=="Windows_NT" setlocal if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0 set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=. if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0 set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME% set APP_HOME=%DIRNAME%
@@ -40,13 +43,13 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute if %ERRORLEVEL% equ 0 goto execute
echo. echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. echo location of your Java installation. 1>&2
goto fail goto fail
@@ -56,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute if exist "%JAVA_EXE%" goto execute
echo. echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. echo location of your Java installation. 1>&2
goto fail goto fail
@@ -75,13 +78,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
:end :end
@rem End local scope for the variables with windows NT shell @rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd if %ERRORLEVEL% equ 0 goto mainEnd
:fail :fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code! rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 set EXIT_CODE=%ERRORLEVEL%
exit /b 1 if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd :mainEnd
if "%OS%"=="Windows_NT" endlocal if "%OS%"=="Windows_NT" endlocal

View File

@@ -1,6 +1,13 @@
pluginManagement { pluginManagement {
repositories { repositories {
gradlePluginPortal() gradlePluginPortal()
maven { url = 'https://maven.minecraftforge.net/' } maven {
name = 'Official NeoForge Maven'
url = 'https://maven.neoforged.net/releases'
}
} }
}
plugins {
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.8.0'
} }

View File

@@ -1,14 +1,13 @@
package nl.requios.effortlessbuilding; package nl.requios.effortlessbuilding;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack; import net.createmod.catnip.gui.UIRenderHelper;
import net.minecraft.client.gui.GuiComponent; import net.createmod.catnip.gui.element.ScreenElement;
import net.createmod.catnip.theme.Color;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.neoforged.api.distmarker.OnlyIn;
import nl.requios.effortlessbuilding.create.foundation.gui.UIRenderHelper;
import nl.requios.effortlessbuilding.create.foundation.gui.element.ScreenElement;
import nl.requios.effortlessbuilding.create.foundation.utility.Color;
public enum AllGuiTextures implements ScreenElement { public enum AllGuiTextures implements ScreenElement {
ARRAY_ENTRY("modifiers", 226, 64), ARRAY_ENTRY("modifiers", 226, 64),
@@ -36,7 +35,7 @@ public enum AllGuiTextures implements ScreenElement {
} }
private AllGuiTextures(String namespace, String location, int startX, int startY, int width, int height) { private AllGuiTextures(String namespace, String location, int startX, int startY, int width, int height) {
this.location = new ResourceLocation(namespace, "textures/gui/" + location + ".png"); this.location = ResourceLocation.fromNamespaceAndPath(namespace, "textures/gui/" + location + ".png");
this.width = width; this.width = width;
this.height = height; this.height = height;
this.startX = startX; this.startX = startX;
@@ -50,19 +49,12 @@ public enum AllGuiTextures implements ScreenElement {
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
@Override @Override
public void render(PoseStack ms, int x, int y) { public void render(GuiGraphics ms, int x, int y) {
bind(); ms.blit(location, x, y, 0, startX, startY, width, height, 256, 256);
GuiComponent.blit(ms, x, y, 0, startX, startY, width, height, 256, 256);
} }
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public void render(PoseStack ms, int x, int y, GuiComponent component) { public void render(GuiGraphics ms, int x, int y, Color c) {
bind();
component.blit(ms, x, y, startX, startY, width, height);
}
@OnlyIn(Dist.CLIENT)
public void render(PoseStack ms, int x, int y, Color c) {
bind(); bind();
UIRenderHelper.drawColoredTexture(ms, c, x, y, startX, startY, width, height); UIRenderHelper.drawColoredTexture(ms, c, x, y, startX, startY, width, height);
} }

View File

@@ -1,25 +1,23 @@
package nl.requios.effortlessbuilding; package nl.requios.effortlessbuilding;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.math.Matrix4f; import net.createmod.catnip.gui.element.DelegatedStencilElement;
import net.minecraft.client.gui.GuiComponent; import net.createmod.catnip.gui.element.ScreenElement;
import net.createmod.catnip.theme.Color;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import net.minecraftforge.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.neoforged.api.distmarker.OnlyIn;
import nl.requios.effortlessbuilding.create.Create; import org.joml.Matrix4f;
import nl.requios.effortlessbuilding.create.foundation.gui.element.DelegatedStencilElement;
import nl.requios.effortlessbuilding.create.foundation.gui.element.ScreenElement;
import nl.requios.effortlessbuilding.create.foundation.utility.Color;
public class AllIcons implements ScreenElement { public class AllIcons implements ScreenElement {
public static final ResourceLocation ICON_ATLAS = Create.asResource("textures/gui/icons.png"); public static final ResourceLocation ICON_ATLAS = EffortlessBuilding.asResource("textures/gui/icons.png");
public static final int ICON_ATLAS_SIZE = 256; public static final int ICON_ATLAS_SIZE = 256;
private static int x = 0, y = -1; private static int x = 0, y = -1;
private int iconX; private int iconX;
@@ -100,25 +98,12 @@ public class AllIcons implements ScreenElement {
private static AllIcons newRow() { private static AllIcons newRow() {
return new AllIcons(x = 0, ++y); return new AllIcons(x = 0, ++y);
} }
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public void bind() { public void render(GuiGraphics guiGraphics, int x, int y) {
RenderSystem.setShaderTexture(0, ICON_ATLAS); guiGraphics.blit(ICON_ATLAS, x, y, 0, iconX, iconY, 16, 16, 256, 256);
} }
@OnlyIn(Dist.CLIENT)
@Override
public void render(PoseStack matrixStack, int x, int y) {
bind();
GuiComponent.blit(matrixStack, x, y, 0, iconX, iconY, 16, 16, 256, 256);
}
@OnlyIn(Dist.CLIENT)
public void render(PoseStack matrixStack, int x, int y, GuiComponent component) {
bind();
component.blit(matrixStack, x, y, iconX, iconY, 16, 16);
}
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public void render(PoseStack ms, MultiBufferSource buffer, int color) { public void render(PoseStack ms, MultiBufferSource buffer, int color) {
VertexConsumer builder = buffer.getBuffer(RenderType.textSeeThrough(ICON_ATLAS)); VertexConsumer builder = buffer.getBuffer(RenderType.textSeeThrough(ICON_ATLAS));
@@ -144,11 +129,10 @@ public class AllIcons implements ScreenElement {
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
private void vertex(VertexConsumer builder, Matrix4f matrix, Vec3 vec, Color rgb, float u, float v, int light) { 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) builder.addVertex(matrix, (float) vec.x, (float) vec.y, (float) vec.z)
.color(rgb.getRed(), rgb.getGreen(), rgb.getBlue(), 255) .setColor(rgb.getRed(), rgb.getGreen(), rgb.getBlue(), 255)
.uv(u, v) .setUv(u, v)
.uv2(light) .setLight(light);
.endVertex();
} }
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)

View File

@@ -1,14 +1,16 @@
package nl.requios.effortlessbuilding; package nl.requios.effortlessbuilding;
import net.minecraftforge.common.ForgeConfigSpec; import net.neoforged.neoforge.common.ModConfigSpec;
import static net.minecraftforge.common.ForgeConfigSpec.*; import static net.neoforged.neoforge.common.ModConfigSpec.BooleanValue;
import static net.neoforged.neoforge.common.ModConfigSpec.Builder;
import static net.neoforged.neoforge.common.ModConfigSpec.IntValue;
public class ClientConfig { public class ClientConfig {
private static final Builder builder = new Builder(); private static final Builder builder = new Builder();
public static final Visuals visuals = new Visuals(builder); public static final Visuals visuals = new Visuals(builder);
public static final ForgeConfigSpec spec = builder.build(); public static final ModConfigSpec spec = builder.build();
public static class Visuals { public static class Visuals {
public final BooleanValue showBlockPreviews; public final BooleanValue showBlockPreviews;

View File

@@ -6,21 +6,21 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.player.LocalPlayer; import net.minecraft.client.player.LocalPlayer;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraftforge.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.minecraftforge.client.event.InputEvent; import net.neoforged.bus.api.SubscribeEvent;
import net.minecraftforge.client.event.RegisterKeyMappingsEvent; import net.neoforged.fml.common.EventBusSubscriber;
import net.minecraftforge.client.event.ScreenEvent; import net.neoforged.neoforge.client.event.ClientTickEvent;
import net.minecraftforge.client.settings.KeyConflictContext; import net.neoforged.neoforge.client.event.InputEvent;
import net.minecraftforge.client.settings.KeyModifier; import net.neoforged.neoforge.client.event.RegisterKeyMappingsEvent;
import net.minecraftforge.event.TickEvent; import net.neoforged.neoforge.client.event.ScreenEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.neoforged.neoforge.client.settings.KeyConflictContext;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber; import net.neoforged.neoforge.client.settings.KeyModifier;
import nl.requios.effortlessbuilding.attachment.AttachmentHandler;
import nl.requios.effortlessbuilding.buildmode.BuildModeEnum; import nl.requios.effortlessbuilding.buildmode.BuildModeEnum;
import nl.requios.effortlessbuilding.buildmode.ModeOptions; import nl.requios.effortlessbuilding.buildmode.ModeOptions;
import nl.requios.effortlessbuilding.gui.buildmode.PlayerSettingsGui; import nl.requios.effortlessbuilding.gui.buildmode.PlayerSettingsGui;
import nl.requios.effortlessbuilding.gui.buildmode.RadialMenu; import nl.requios.effortlessbuilding.gui.buildmode.RadialMenu;
import nl.requios.effortlessbuilding.gui.buildmodifier.ModifiersScreen; import nl.requios.effortlessbuilding.gui.buildmodifier.ModifiersScreen;
import nl.requios.effortlessbuilding.systems.PowerLevel;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
@EventBusSubscriber(Dist.CLIENT) @EventBusSubscriber(Dist.CLIENT)
@@ -55,31 +55,31 @@ public class ClientEvents {
// @SubscribeEvent // @SubscribeEvent
// public static void registerShaders(RegisterShadersEvent event) throws IOException { // public static void registerShaders(RegisterShadersEvent event) throws IOException {
// event.registerShader(new ShaderInstance(event.getResourceManager(), // event.registerShader(new ShaderInstance(event.getResourceManager(),
// new ResourceLocation(EffortlessBuilding.MODID, "dissolve"), // EffortlessBuilding.modLoc("dissolve"),
// DefaultVertexFormat.BLOCK), // DefaultVertexFormat.BLOCK),
// shaderInstance -> BuildRenderTypes.dissolveShaderInstance = shaderInstance); // shaderInstance -> BuildRenderTypes.dissolveShaderInstance = shaderInstance);
// } // }
} }
@SubscribeEvent @SubscribeEvent
public static void onClientTick(TickEvent.ClientTickEvent event) { public static void onClientTickPre(ClientTickEvent.Pre event) {
if (!isGameActive()) return; if (!isGameActive()) return;
if (event.phase == TickEvent.Phase.START) { EffortlessBuildingClient.BUILDER_CHAIN.onTick();
EffortlessBuildingClient.BUILDER_CHAIN.onTick(); onMouseInput();
onMouseInput(); EffortlessBuildingClient.BLOCK_PREVIEWS.onTick();
}
EffortlessBuildingClient.BLOCK_PREVIEWS.onTick(); @SubscribeEvent
public static void onClientTickPost(ClientTickEvent.Post event) {
if (!isGameActive()) return;
} else if (event.phase == TickEvent.Phase.END) { Screen gui = Minecraft.getInstance().screen;
Screen gui = Minecraft.getInstance().screen; if (gui == null || !gui.isPauseScreen()) {
if (gui == null || !gui.isPauseScreen()) { ticksInGame++;
ticksInGame++;
}
} }
} }
private static void onMouseInput() { private static void onMouseInput() {
@@ -134,7 +134,7 @@ public class ClientEvents {
//Radial menu //Radial menu
if (keyBindings[0].isDown()) { if (keyBindings[0].isDown()) {
if (!EffortlessBuildingClient.POWER_LEVEL.isDisabled(player)) { if (!AttachmentHandler.isDisabled(player)) {
if (!RadialMenu.instance.isVisible()) { if (!RadialMenu.instance.isVisible()) {
Minecraft.getInstance().setScreen(RadialMenu.instance); Minecraft.getInstance().setScreen(RadialMenu.instance);
} }
@@ -175,7 +175,7 @@ public class ClientEvents {
if (player == null) return; if (player == null) return;
//Disabled if max reach is 0, might be set in the config that way. //Disabled if max reach is 0, might be set in the config that way.
if (EffortlessBuildingClient.POWER_LEVEL.isDisabled(player)) { if (AttachmentHandler.isDisabled(player)) {
EffortlessBuilding.log(player, "Build modifiers are disabled until your power level has increased. Increase your power level by consuming certain items."); EffortlessBuilding.log(player, "Build modifiers are disabled until your power level has increased. Increase your power level by consuming certain items.");
} else { } else {
mc.setScreen(new ModifiersScreen()); mc.setScreen(new ModifiersScreen());
@@ -188,7 +188,7 @@ public class ClientEvents {
} }
@SubscribeEvent @SubscribeEvent
public static void onGuiOpen(ScreenEvent event) { public static void onGuiOpen(ScreenEvent.Opening event) {
Player player = Minecraft.getInstance().player; Player player = Minecraft.getInstance().player;
if (player != null) { if (player != null) {
EffortlessBuildingClient.BUILDER_CHAIN.cancel(); EffortlessBuildingClient.BUILDER_CHAIN.cancel();

View File

@@ -1,8 +1,9 @@
package nl.requios.effortlessbuilding; package nl.requios.effortlessbuilding;
import net.minecraftforge.common.ForgeConfigSpec; import net.neoforged.neoforge.common.ModConfigSpec;
import static net.minecraftforge.common.ForgeConfigSpec.*; import static net.neoforged.neoforge.common.ModConfigSpec.Builder;
import static net.neoforged.neoforge.common.ModConfigSpec.IntValue;
public class CommonConfig { public class CommonConfig {
@@ -11,7 +12,7 @@ public class CommonConfig {
public static final MaxBlocksPlacedAtOnce maxBlocksPlacedAtOnce = new MaxBlocksPlacedAtOnce(builder); public static final MaxBlocksPlacedAtOnce maxBlocksPlacedAtOnce = new MaxBlocksPlacedAtOnce(builder);
public static final MaxBlocksPerAxis maxBlocksPerAxis = new MaxBlocksPerAxis(builder); public static final MaxBlocksPerAxis maxBlocksPerAxis = new MaxBlocksPerAxis(builder);
public static final MaxMirrorRadius maxMirrorRadius = new MaxMirrorRadius(builder); public static final MaxMirrorRadius maxMirrorRadius = new MaxMirrorRadius(builder);
public static final ForgeConfigSpec spec = builder.build(); public static final ModConfigSpec spec = builder.build();
public static class Reach { public static class Reach {
public final IntValue creative; public final IntValue creative;

View File

@@ -5,18 +5,18 @@ import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraftforge.common.util.FakePlayer; import net.minecraft.world.level.Level;
import net.minecraftforge.event.RegisterCommandsEvent; import net.neoforged.bus.api.SubscribeEvent;
import net.minecraftforge.event.TickEvent; import net.neoforged.fml.common.EventBusSubscriber;
import net.minecraftforge.event.entity.player.PlayerEvent; import net.neoforged.neoforge.common.util.FakePlayer;
import net.minecraftforge.event.level.BlockEvent; import net.neoforged.neoforge.event.RegisterCommandsEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.neoforged.neoforge.event.entity.player.PlayerEvent;
import net.minecraftforge.fml.LogicalSide; import net.neoforged.neoforge.event.level.BlockEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber; import net.neoforged.neoforge.event.tick.LevelTickEvent;
import net.minecraftforge.network.PacketDistributor; import nl.requios.effortlessbuilding.attachment.PowerLevel;
import nl.requios.effortlessbuilding.compatibility.CompatHelper; import nl.requios.effortlessbuilding.compatibility.CompatHelper;
import nl.requios.effortlessbuilding.network.ModifierSettingsPacket; import nl.requios.effortlessbuilding.network.message.ModifierSettingsPacket;
import nl.requios.effortlessbuilding.network.PacketHandler; import nl.requios.effortlessbuilding.network.message.PowerLevelPacket;
import nl.requios.effortlessbuilding.systems.ServerBuildState; import nl.requios.effortlessbuilding.systems.ServerBuildState;
import nl.requios.effortlessbuilding.utilities.PowerLevelCommand; import nl.requios.effortlessbuilding.utilities.PowerLevelCommand;
@@ -24,7 +24,7 @@ import nl.requios.effortlessbuilding.utilities.PowerLevelCommand;
public class CommonEvents { public class CommonEvents {
//Mod Bus Events //Mod Bus Events
@EventBusSubscriber(bus = EventBusSubscriber.Bus.MOD) // @EventBusSubscriber(bus = EventBusSubscriber.Bus.MOD)
public static class ModBusEvents { public static class ModBusEvents {
@@ -36,9 +36,10 @@ public class CommonEvents {
} }
@SubscribeEvent @SubscribeEvent
public static void onTick(TickEvent.LevelTickEvent event) { public static void onTick(LevelTickEvent.Pre event) {
if (event.phase != TickEvent.Phase.START) return; Level level = event.getLevel();
if (event.side == LogicalSide.CLIENT) return; if (level.isClientSide) return;
if (!level.dimension().equals(Level.OVERWORLD)) return;
EffortlessBuilding.SERVER_BLOCK_PLACER.tick(); EffortlessBuilding.SERVER_BLOCK_PLACER.tick();
} }
@@ -74,7 +75,8 @@ public class CommonEvents {
//Don't cancel event if our custom logic is breaking blocks //Don't cancel event if our custom logic is breaking blocks
if (EffortlessBuilding.SERVER_BLOCK_PLACER.isPlacingOrBreakingBlocks()) return; if (EffortlessBuilding.SERVER_BLOCK_PLACER.isPlacingOrBreakingBlocks()) return;
if (!ServerBuildState.isLikeVanilla(player) && EffortlessBuilding.SERVER_POWER_LEVEL.canBreakFar(player)) { PowerLevel powerLevel = player.getData(EffortlessBuilding.POWER_LEVEL);
if (!ServerBuildState.isLikeVanilla(player) && powerLevel.canBreakFar(player)) {
event.setCanceled(true); event.setCanceled(true);
} }
} }
@@ -93,8 +95,24 @@ public class CommonEvents {
ServerBuildState.handleNewPlayer(player); ServerBuildState.handleNewPlayer(player);
PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), new ModifierSettingsPacket(player)); ((ServerPlayer)player).connection.send(new ModifierSettingsPacket(player));
EffortlessBuilding.SERVER_POWER_LEVEL.sendToClient(player);
PowerLevel powerLevel = player.getData(EffortlessBuilding.POWER_LEVEL);
((ServerPlayer)player).connection.send(new PowerLevelPacket(powerLevel.getPowerLevel()));
}
@SubscribeEvent
public static void onClone(PlayerEvent.Clone event) {
// If not dead, player is returning from the End
if (!event.isWasDeath()) return;
Player original = event.getOriginal();
Player clone = event.getEntity();
// Copy the power level from the original player to the clone
if (event.isWasDeath() && event.getOriginal().hasData(EffortlessBuilding.POWER_LEVEL)) {
event.getEntity().setData(EffortlessBuilding.POWER_LEVEL, event.getOriginal().getData(EffortlessBuilding.POWER_LEVEL));
}
} }
@SubscribeEvent @SubscribeEvent

View File

@@ -1,41 +1,57 @@
package nl.requios.effortlessbuilding; package nl.requios.effortlessbuilding;
import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.flag.FeatureFlags;
import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.MenuType; import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.item.Item; import net.minecraft.world.item.CreativeModeTabs;
import net.minecraftforge.api.distmarker.Dist; import net.minecraft.world.item.ItemStack;
import net.minecraftforge.common.MinecraftForge; import net.neoforged.api.distmarker.Dist;
import net.minecraftforge.common.loot.IGlobalLootModifier; import net.neoforged.bus.api.IEventBus;
import net.minecraftforge.eventbus.api.IEventBus; import net.neoforged.fml.ModContainer;
import net.minecraftforge.fml.DistExecutor; import net.neoforged.fml.common.Mod;
import net.minecraftforge.fml.ModLoadingContext; import net.neoforged.fml.config.ModConfig;
import net.minecraftforge.fml.common.Mod; import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.config.ModConfig; import net.neoforged.fml.loading.FMLEnvironment;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.neoforged.neoforge.attachment.AttachmentType;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import net.neoforged.neoforge.client.gui.ConfigurationScreen;
import net.minecraftforge.network.IContainerFactory; import net.neoforged.neoforge.client.gui.IConfigScreenFactory;
import net.minecraftforge.registries.DeferredRegister; import net.neoforged.neoforge.common.NeoForge;
import net.minecraftforge.registries.ForgeRegistries; import net.neoforged.neoforge.common.loot.IGlobalLootModifier;
import net.minecraftforge.registries.RegistryObject; import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent;
import net.neoforged.neoforge.network.IContainerFactory;
import net.neoforged.neoforge.registries.DeferredItem;
import net.neoforged.neoforge.registries.DeferredRegister;
import net.neoforged.neoforge.registries.NeoForgeRegistries;
import nl.requios.effortlessbuilding.attachment.PowerLevel;
import nl.requios.effortlessbuilding.compatibility.CompatHelper; import nl.requios.effortlessbuilding.compatibility.CompatHelper;
import nl.requios.effortlessbuilding.gui.DiamondRandomizerBagContainer; import nl.requios.effortlessbuilding.gui.DiamondRandomizerBagContainer;
import nl.requios.effortlessbuilding.gui.GoldenRandomizerBagContainer; import nl.requios.effortlessbuilding.gui.GoldenRandomizerBagContainer;
import nl.requios.effortlessbuilding.gui.RandomizerBagContainer; import nl.requios.effortlessbuilding.gui.RandomizerBagContainer;
import nl.requios.effortlessbuilding.item.*; import nl.requios.effortlessbuilding.item.DiamondRandomizerBagItem;
import nl.requios.effortlessbuilding.item.GoldenRandomizerBagItem;
import nl.requios.effortlessbuilding.item.PowerLevelItem;
import nl.requios.effortlessbuilding.item.RandomizerBagItem;
import nl.requios.effortlessbuilding.item.ReachUpgrade1Item;
import nl.requios.effortlessbuilding.item.ReachUpgrade2Item;
import nl.requios.effortlessbuilding.item.ReachUpgrade3Item;
import nl.requios.effortlessbuilding.item.SingleItemLootModifier;
import nl.requios.effortlessbuilding.network.PacketHandler; import nl.requios.effortlessbuilding.network.PacketHandler;
import nl.requios.effortlessbuilding.proxy.ClientProxy; import nl.requios.effortlessbuilding.proxy.ClientProxy;
import nl.requios.effortlessbuilding.proxy.IProxy;
import nl.requios.effortlessbuilding.proxy.ServerProxy; import nl.requios.effortlessbuilding.proxy.ServerProxy;
import nl.requios.effortlessbuilding.systems.ItemUsageTracker; import nl.requios.effortlessbuilding.systems.ItemUsageTracker;
import nl.requios.effortlessbuilding.systems.ServerBlockPlacer; import nl.requios.effortlessbuilding.systems.ServerBlockPlacer;
import nl.requios.effortlessbuilding.systems.ServerPowerLevel;
import nl.requios.effortlessbuilding.systems.UndoRedo; import nl.requios.effortlessbuilding.systems.UndoRedo;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import java.util.List;
import java.util.function.Supplier;
@Mod(EffortlessBuilding.MODID) @Mod(EffortlessBuilding.MODID)
public class EffortlessBuilding { public class EffortlessBuilding {
@@ -43,64 +59,73 @@ public class EffortlessBuilding {
public static final Logger logger = LogManager.getLogger(); public static final Logger logger = LogManager.getLogger();
public static EffortlessBuilding instance; public static EffortlessBuilding instance;
public static IProxy proxy = DistExecutor.unsafeRunForDist(() -> ClientProxy::new, () -> ServerProxy::new);
public static final ServerBlockPlacer SERVER_BLOCK_PLACER = new ServerBlockPlacer(); public static final ServerBlockPlacer SERVER_BLOCK_PLACER = new ServerBlockPlacer();
public static final UndoRedo UNDO_REDO = new UndoRedo(); public static final UndoRedo UNDO_REDO = new UndoRedo();
public static final ItemUsageTracker ITEM_USAGE_TRACKER = new ItemUsageTracker(); public static final ItemUsageTracker ITEM_USAGE_TRACKER = new ItemUsageTracker();
public static final ServerPowerLevel SERVER_POWER_LEVEL = new ServerPowerLevel();
//Registration //Registration
private static final DeferredRegister<Item> ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, MODID); private static final DeferredRegister.Items ITEMS = DeferredRegister.createItems(MODID);
private static final DeferredRegister<MenuType<?>> CONTAINERS = DeferredRegister.create(ForgeRegistries.MENU_TYPES, EffortlessBuilding.MODID); private static final DeferredRegister<MenuType<?>> CONTAINERS = DeferredRegister.create(BuiltInRegistries.MENU, EffortlessBuilding.MODID);
public static final DeferredRegister<Codec<? extends IGlobalLootModifier>> LOOT_MODIFIERS = DeferredRegister.create(ForgeRegistries.Keys.GLOBAL_LOOT_MODIFIER_SERIALIZERS, EffortlessBuilding.MODID); private static final DeferredRegister<MapCodec<? extends IGlobalLootModifier>> LOOT_MODIFIERS = DeferredRegister.create(NeoForgeRegistries.Keys.GLOBAL_LOOT_MODIFIER_SERIALIZERS, EffortlessBuilding.MODID);
private static final DeferredRegister<AttachmentType<?>> ATTACHMENT_TYPES = DeferredRegister.create(NeoForgeRegistries.Keys.ATTACHMENT_TYPES, EffortlessBuilding.MODID);
public static final RegistryObject<Item> RANDOMIZER_BAG_ITEM = ITEMS.register("randomizer_bag", RandomizerBagItem::new); public static final DeferredItem<RandomizerBagItem> RANDOMIZER_BAG_ITEM = ITEMS.register("randomizer_bag", RandomizerBagItem::new);
public static final RegistryObject<Item> GOLDEN_RANDOMIZER_BAG_ITEM = ITEMS.register("golden_randomizer_bag", GoldenRandomizerBagItem::new); public static final DeferredItem<GoldenRandomizerBagItem> GOLDEN_RANDOMIZER_BAG_ITEM = ITEMS.register("golden_randomizer_bag", GoldenRandomizerBagItem::new);
public static final RegistryObject<Item> DIAMOND_RANDOMIZER_BAG_ITEM = ITEMS.register("diamond_randomizer_bag", DiamondRandomizerBagItem::new); public static final DeferredItem<DiamondRandomizerBagItem> DIAMOND_RANDOMIZER_BAG_ITEM = ITEMS.register("diamond_randomizer_bag", DiamondRandomizerBagItem::new);
public static final RegistryObject<Item> REACH_UPGRADE_1_ITEM = ITEMS.register("reach_upgrade1", ReachUpgrade1Item::new); public static final DeferredItem<ReachUpgrade1Item> REACH_UPGRADE_1_ITEM = ITEMS.register("reach_upgrade1", ReachUpgrade1Item::new);
public static final RegistryObject<Item> REACH_UPGRADE_2_ITEM = ITEMS.register("reach_upgrade2", ReachUpgrade2Item::new); public static final DeferredItem<ReachUpgrade2Item> REACH_UPGRADE_2_ITEM = ITEMS.register("reach_upgrade2", ReachUpgrade2Item::new);
public static final RegistryObject<Item> REACH_UPGRADE_3_ITEM = ITEMS.register("reach_upgrade3", ReachUpgrade3Item::new); public static final DeferredItem<ReachUpgrade3Item> REACH_UPGRADE_3_ITEM = ITEMS.register("reach_upgrade3", ReachUpgrade3Item::new);
public static final RegistryObject<Item> MUSCLES_ITEM = ITEMS.register("muscles", PowerLevelItem::new); public static final DeferredItem<PowerLevelItem> MUSCLES_ITEM = ITEMS.register("muscles", PowerLevelItem::new);
public static final RegistryObject<Item> ELASTIC_HAND_ITEM = ITEMS.register("elastic_hand", PowerLevelItem::new); public static final DeferredItem<PowerLevelItem> ELASTIC_HAND_ITEM = ITEMS.register("elastic_hand", PowerLevelItem::new);
public static final RegistryObject<Item> BUILDING_TECHNIQUES_BOOK_ITEM = ITEMS.register("building_techniques_book", PowerLevelItem::new); public static final DeferredItem<PowerLevelItem> BUILDING_TECHNIQUES_BOOK_ITEM = ITEMS.register("building_techniques_book", PowerLevelItem::new);
public static final RegistryObject<MenuType<RandomizerBagContainer>> RANDOMIZER_BAG_CONTAINER = CONTAINERS.register("randomizer_bag", () -> registerContainer(RandomizerBagContainer::new)); public static final Supplier<MenuType<RandomizerBagContainer>> RANDOMIZER_BAG_CONTAINER = CONTAINERS.register("randomizer_bag", () -> registerContainer(RandomizerBagContainer::new));
public static final RegistryObject<MenuType<GoldenRandomizerBagContainer>> GOLDEN_RANDOMIZER_BAG_CONTAINER = CONTAINERS.register("golden_randomizer_bag", () -> registerContainer(GoldenRandomizerBagContainer::new)); public static final Supplier<MenuType<GoldenRandomizerBagContainer>> GOLDEN_RANDOMIZER_BAG_CONTAINER = CONTAINERS.register("golden_randomizer_bag", () -> registerContainer(GoldenRandomizerBagContainer::new));
public static final RegistryObject<MenuType<DiamondRandomizerBagContainer>> DIAMOND_RANDOMIZER_BAG_CONTAINER = CONTAINERS.register("diamond_randomizer_bag", () -> registerContainer(DiamondRandomizerBagContainer::new)); public static final Supplier<MenuType<DiamondRandomizerBagContainer>> DIAMOND_RANDOMIZER_BAG_CONTAINER = CONTAINERS.register("diamond_randomizer_bag", () -> registerContainer(DiamondRandomizerBagContainer::new));
public static final Supplier<MapCodec<SingleItemLootModifier>> SINGLE_ITEM_LOOT_MODIFIER = EffortlessBuilding.LOOT_MODIFIERS.register("single_item_loot_modifier", SingleItemLootModifier.CODEC);
public EffortlessBuilding() { public static final Supplier<AttachmentType<PowerLevel>> POWER_LEVEL = ATTACHMENT_TYPES.register("power_level", () -> AttachmentType.serializable(PowerLevel::new).build());
public EffortlessBuilding(IEventBus modEventBus, ModContainer container, Dist dist) {
instance = this; instance = this;
ModLoadingContext modLoadingContext = ModLoadingContext.get(); IEventBus forgeEventBus = NeoForge.EVENT_BUS;
IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
IEventBus forgeEventBus = MinecraftForge.EVENT_BUS;
modEventBus.addListener(EffortlessBuilding::setup); modEventBus.addListener(EffortlessBuilding::setup);
modEventBus.addListener(EffortlessBuilding::addTabContents);
modEventBus.addListener(PacketHandler::setupPackets);
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> EffortlessBuildingClient.onConstructorClient(modEventBus, forgeEventBus)); ITEMS.register(modEventBus);
CONTAINERS.register(modEventBus);
ITEMS.register(FMLJavaModLoadingContext.get().getModEventBus()); LOOT_MODIFIERS.register(modEventBus);
CONTAINERS.register(FMLJavaModLoadingContext.get().getModEventBus()); ATTACHMENT_TYPES.register(modEventBus);
var singleItemLootModifier = SingleItemLootModifier.CODEC; //load this class to register the loot modifier
LOOT_MODIFIERS.register(FMLJavaModLoadingContext.get().getModEventBus());
//Register config //Register config
ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, CommonConfig.spec); container.registerConfig(ModConfig.Type.COMMON, CommonConfig.spec);
ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, ClientConfig.spec); container.registerConfig(ModConfig.Type.SERVER, ServerConfig.spec);
ModLoadingContext.get().registerConfig(ModConfig.Type.SERVER, ServerConfig.spec); if (dist.isClient()) {
container.registerConfig(ModConfig.Type.CLIENT, ClientConfig.spec);
container.registerExtensionPoint(IConfigScreenFactory.class, ConfigurationScreen::new);
EffortlessBuildingClient.onConstructorClient(modEventBus, forgeEventBus);
}
} }
public static void setup(final FMLCommonSetupEvent event) { public static void setup(final FMLCommonSetupEvent event) {
PacketHandler.register();
CompatHelper.setup(); CompatHelper.setup();
} }
public static <T extends AbstractContainerMenu> MenuType<T> registerContainer(IContainerFactory<T> fact){ public static void addTabContents(final BuildCreativeModeTabContentsEvent event) {
MenuType<T> type = new MenuType<T>(fact); if (event.getTabKey() == CreativeModeTabs.TOOLS_AND_UTILITIES) {
List<ItemStack> stacks = ITEMS.getEntries().stream().map(reg -> new ItemStack(reg.get())).toList();
event.acceptAll(stacks);
}
}
public static <T extends AbstractContainerMenu> MenuType<T> registerContainer(IContainerFactory<T> fact) {
MenuType<T> type = new MenuType<T>(fact, FeatureFlags.REGISTRY.allFlags());
return type; return type;
} }
@@ -118,11 +143,18 @@ public class EffortlessBuilding {
//Log with translation supported, call either on client or server (which then sends a message) //Log with translation supported, call either on client or server (which then sends a message)
public static void logTranslate(Player player, String prefix, String translationKey, String suffix, boolean actionBar) { public static void logTranslate(Player player, String prefix, String translationKey, String suffix, boolean actionBar) {
proxy.logTranslate(player, prefix, translationKey, suffix, actionBar); if (FMLEnvironment.dist.isClient()) {
ClientProxy.logTranslate(player, prefix, translationKey, suffix, actionBar);
} else {
ServerProxy.logTranslate(player, prefix, translationKey, suffix, actionBar);
}
} }
public static void logError(String msg) { public static void logError(String msg) {
logger.error(msg); logger.error(msg);
} }
public static ResourceLocation asResource(String path) {
return ResourceLocation.fromNamespaceAndPath(MODID, path);
}
} }

View File

@@ -1,15 +1,17 @@
package nl.requios.effortlessbuilding; package nl.requios.effortlessbuilding;
import net.minecraft.client.gui.screens.MenuScreens; import net.neoforged.bus.api.IEventBus;
import net.minecraftforge.eventbus.api.IEventBus; import net.neoforged.neoforge.client.event.RegisterMenuScreensEvent;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import nl.requios.effortlessbuilding.buildmode.BuildModes; import nl.requios.effortlessbuilding.buildmode.BuildModes;
import nl.requios.effortlessbuilding.buildmodifier.BuildModifiers; import nl.requios.effortlessbuilding.buildmodifier.BuildModifiers;
import nl.requios.effortlessbuilding.gui.DiamondRandomizerBagScreen; import nl.requios.effortlessbuilding.gui.DiamondRandomizerBagScreen;
import nl.requios.effortlessbuilding.gui.GoldenRandomizerBagScreen; import nl.requios.effortlessbuilding.gui.GoldenRandomizerBagScreen;
import nl.requios.effortlessbuilding.gui.RandomizerBagScreen; import nl.requios.effortlessbuilding.gui.RandomizerBagScreen;
import nl.requios.effortlessbuilding.render.BlockPreviews; import nl.requios.effortlessbuilding.render.BlockPreviews;
import nl.requios.effortlessbuilding.systems.*; import nl.requios.effortlessbuilding.systems.BuildSettings;
import nl.requios.effortlessbuilding.systems.BuilderChain;
import nl.requios.effortlessbuilding.systems.BuilderFilter;
import nl.requios.effortlessbuilding.systems.ItemUsageTracker;
public class EffortlessBuildingClient { public class EffortlessBuildingClient {
@@ -20,15 +22,14 @@ public class EffortlessBuildingClient {
public static final BlockPreviews BLOCK_PREVIEWS = new BlockPreviews(); public static final BlockPreviews BLOCK_PREVIEWS = new BlockPreviews();
public static final BuilderFilter BUILDER_FILTER = new BuilderFilter(); public static final BuilderFilter BUILDER_FILTER = new BuilderFilter();
public static final ItemUsageTracker ITEM_USAGE_TRACKER = new ItemUsageTracker(); public static final ItemUsageTracker ITEM_USAGE_TRACKER = new ItemUsageTracker();
public static final PowerLevel POWER_LEVEL = new PowerLevel();
public static void onConstructorClient(IEventBus modEventBus, IEventBus forgeEventBus) { public static void onConstructorClient(IEventBus modEventBus, IEventBus forgeEventBus) {
modEventBus.addListener(EffortlessBuildingClient::clientSetup); modEventBus.addListener(EffortlessBuildingClient::registerMenuScreens);
} }
public static void clientSetup(final FMLClientSetupEvent event) { public static void registerMenuScreens(final RegisterMenuScreensEvent event) {
MenuScreens.register(EffortlessBuilding.RANDOMIZER_BAG_CONTAINER.get(), RandomizerBagScreen::new); event.register(EffortlessBuilding.RANDOMIZER_BAG_CONTAINER.get(), RandomizerBagScreen::new);
MenuScreens.register(EffortlessBuilding.GOLDEN_RANDOMIZER_BAG_CONTAINER.get(), GoldenRandomizerBagScreen::new); event.register(EffortlessBuilding.GOLDEN_RANDOMIZER_BAG_CONTAINER.get(), GoldenRandomizerBagScreen::new);
MenuScreens.register(EffortlessBuilding.DIAMOND_RANDOMIZER_BAG_CONTAINER.get(), DiamondRandomizerBagScreen::new); event.register(EffortlessBuilding.DIAMOND_RANDOMIZER_BAG_CONTAINER.get(), DiamondRandomizerBagScreen::new);
} }
} }

View File

@@ -1,17 +1,20 @@
package nl.requios.effortlessbuilding; package nl.requios.effortlessbuilding;
import net.minecraftforge.common.ForgeConfigSpec; import net.neoforged.neoforge.common.ModConfigSpec;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import static net.minecraftforge.common.ForgeConfigSpec.*; import static net.neoforged.neoforge.common.ModConfigSpec.BooleanValue;
import static net.neoforged.neoforge.common.ModConfigSpec.Builder;
import static net.neoforged.neoforge.common.ModConfigSpec.ConfigValue;
import static net.neoforged.neoforge.common.ModConfigSpec.IntValue;
public class ServerConfig { public class ServerConfig {
private static final Builder builder = new Builder(); private static final Builder builder = new Builder();
public static final ServerConfig.Validation validation = new ServerConfig.Validation(builder); public static final ServerConfig.Validation validation = new ServerConfig.Validation(builder);
public static final ServerConfig.Memory memory = new ServerConfig.Memory(builder); public static final ServerConfig.Memory memory = new ServerConfig.Memory(builder);
public static final ForgeConfigSpec spec = builder.build(); public static final ModConfigSpec spec = builder.build();
public static class Validation { public static class Validation {
public final BooleanValue allowInSurvival; public final BooleanValue allowInSurvival;

View File

@@ -0,0 +1,130 @@
package nl.requios.effortlessbuilding.attachment;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;
import nl.requios.effortlessbuilding.CommonConfig;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.network.message.PowerLevelPacket;
public class AttachmentHandler {
public static final ResourceLocation POWER_LEVEL_CAP = EffortlessBuilding.asResource("power_level");
public static void syncToClient(Player player) {
PowerLevel powerLevel = player.getData(EffortlessBuilding.POWER_LEVEL);
if (powerLevel == null) return; //Should never be null but just to be sure
((ServerPlayer)player).connection.send(new PowerLevelPacket(powerLevel.getPowerLevel()));
}
//Helper methods to reduce boilerplate code
public static boolean canReplaceBlocks(Player player) {
if (player != null) {
PowerLevel powerLevel = player.getData(EffortlessBuilding.POWER_LEVEL);
if (powerLevel != null) {
return powerLevel.canReplaceBlocks(player);
}
}
return false;
}
public static int getMaxBlocksPerAxis(Player player, boolean nextPowerLevel) {
if (player != null) {
PowerLevel powerLevel = player.getData(EffortlessBuilding.POWER_LEVEL);
if (powerLevel != null) {
return powerLevel.getMaxBlocksPerAxis(player, nextPowerLevel);
}
}
return CommonConfig.maxBlocksPerAxis.level0.get();
}
public static int getMaxBlocksPlacedAtOnce(Player player, boolean nextPowerLevel) {
if (player != null) {
PowerLevel powerLevel = player.getData(EffortlessBuilding.POWER_LEVEL);
if (powerLevel != null) {
return powerLevel.getMaxBlocksPlacedAtOnce(player, nextPowerLevel);
}
}
return CommonConfig.maxBlocksPlacedAtOnce.level0.get();
}
public static int getMaxMirrorRadius(Player player, boolean nextPowerLevel) {
if (player != null) {
PowerLevel powerLevel = player.getData(EffortlessBuilding.POWER_LEVEL);
if (powerLevel != null) {
return powerLevel.getMaxMirrorRadius(player, nextPowerLevel);
}
}
return CommonConfig.maxMirrorRadius.level0.get();
}
public static int getBuildModeReach(Player player) {
if (player != null) {
PowerLevel powerLevel = player.getData(EffortlessBuilding.POWER_LEVEL);
if (powerLevel != null) {
return powerLevel.getBuildModeReach(player);
}
}
return CommonConfig.maxMirrorRadius.level0.get() + 6;
}
public static int getPlacementReach(Player player, boolean nextPowerLevel) {
if (player != null) {
PowerLevel powerLevel = player.getData(EffortlessBuilding.POWER_LEVEL);
if (powerLevel != null) {
return powerLevel.getPlacementReach(player, nextPowerLevel);
}
}
return CommonConfig.reach.level0.get();
}
public static int getPowerLevel(Player player) {
if (player != null) {
PowerLevel powerLevel = player.getData(EffortlessBuilding.POWER_LEVEL);
if (powerLevel != null) {
return powerLevel.getPowerLevel();
}
}
return 0;
}
public static int getNextPowerLevel(Player player) {
if (player != null) {
PowerLevel powerLevel = player.getData(EffortlessBuilding.POWER_LEVEL);
if (powerLevel != null) {
return powerLevel.getNextPowerLevel();
}
}
return 0;
}
public static boolean canIncreasePowerLevel(Player player) {
if (player != null) {
PowerLevel powerLevel = player.getData(EffortlessBuilding.POWER_LEVEL);
if (powerLevel != null) {
return powerLevel.canIncreasePowerLevel();
}
}
return false;
}
public static boolean isDisabled(Player player) {
if (player != null) {
PowerLevel powerLevel = player.getData(EffortlessBuilding.POWER_LEVEL);
if (powerLevel != null) {
return powerLevel.isDisabled(player);
}
}
return false;
}
public static boolean canBreakFar(Player player) {
if (player != null) {
PowerLevel powerLevel = player.getData(EffortlessBuilding.POWER_LEVEL);
if (powerLevel != null) {
return powerLevel.canBreakFar(player);
}
}
return false;
}
}

View File

@@ -1,51 +1,41 @@
package nl.requios.effortlessbuilding.systems; package nl.requios.effortlessbuilding.attachment;
import net.minecraft.core.HolderLookup.Provider;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraftforge.api.distmarker.Dist; import net.neoforged.neoforge.common.util.INBTSerializable;
import net.minecraftforge.api.distmarker.OnlyIn;
import nl.requios.effortlessbuilding.CommonConfig; import nl.requios.effortlessbuilding.CommonConfig;
import nl.requios.effortlessbuilding.EffortlessBuildingClient;
import nl.requios.effortlessbuilding.network.PacketHandler;
import nl.requios.effortlessbuilding.network.PowerLevelPacket;
@OnlyIn(Dist.CLIENT) public class PowerLevel implements INBTSerializable<CompoundTag> {
public class PowerLevel { public static final int MAX_POWER_LEVEL = 3; //Common access
private int powerLevel; public PowerLevel() {
}
private int powerLevel = 0;
public int getPowerLevel() { public int getPowerLevel() {
return powerLevel; return this.powerLevel;
} }
public int getNextPowerLevel() { public int getNextPowerLevel() {
return Math.min(powerLevel + 1, ServerPowerLevel.MAX_POWER_LEVEL); return Math.min(getPowerLevel() + 1, MAX_POWER_LEVEL);
} }
public void setPowerLevel(int powerLevel) { public void setPowerLevel(int powerLevel) {
this.powerLevel = powerLevel; this.powerLevel = powerLevel;
EffortlessBuildingClient.BUILD_MODIFIERS.onPowerLevelChanged(powerLevel);
} }
public boolean canIncreasePowerLevel() { public boolean canIncreasePowerLevel() {
return getPowerLevel() < ServerPowerLevel.MAX_POWER_LEVEL; return getPowerLevel() < MAX_POWER_LEVEL;
} }
public void increasePowerLevel() { public void increasePowerLevel() {
if (canIncreasePowerLevel()) { if (canIncreasePowerLevel()) {
setPowerLevel(getPowerLevel() + 1); setPowerLevel(getPowerLevel() + 1);
PacketHandler.INSTANCE.sendToServer(new PowerLevelPacket(powerLevel));
} }
} }
@Deprecated
public int getMaxReach(Player player) {
return getPlacementReach(player);
}
public int getPlacementReach(Player player) {
return getPlacementReach(player, false);
}
public int getPlacementReach(Player player, boolean nextPowerLevel) { public int getPlacementReach(Player player, boolean nextPowerLevel) {
if (player.isCreative()) return CommonConfig.reach.creative.get(); if (player.isCreative()) return CommonConfig.reach.creative.get();
return switch (nextPowerLevel ? getNextPowerLevel() : getPowerLevel()) { return switch (nextPowerLevel ? getNextPowerLevel() : getPowerLevel()) {
@@ -59,11 +49,7 @@ public class PowerLevel {
//How far away we can detect the second and third click of build modes (distance to player) //How far away we can detect the second and third click of build modes (distance to player)
public int getBuildModeReach(Player player) { public int getBuildModeReach(Player player) {
//A bit further than placement reach, so you can build lines when looking to the side without having to move. //A bit further than placement reach, so you can build lines when looking to the side without having to move.
return getPlacementReach(player) + 6; return getPlacementReach(player, false) + 6;
}
public int getMaxBlocksPlacedAtOnce(Player player) {
return getMaxBlocksPlacedAtOnce(player, false);
} }
public int getMaxBlocksPlacedAtOnce(Player player, boolean nextPowerLevel) { public int getMaxBlocksPlacedAtOnce(Player player, boolean nextPowerLevel) {
@@ -76,10 +62,6 @@ public class PowerLevel {
}; };
} }
public int getMaxBlocksPerAxis(Player player) {
return getMaxBlocksPerAxis(player, false);
}
public int getMaxBlocksPerAxis(Player player, boolean nextPowerLevel) { public int getMaxBlocksPerAxis(Player player, boolean nextPowerLevel) {
if (player.isCreative()) return CommonConfig.maxBlocksPerAxis.creative.get(); if (player.isCreative()) return CommonConfig.maxBlocksPerAxis.creative.get();
return switch (nextPowerLevel ? getNextPowerLevel() : getPowerLevel()) { return switch (nextPowerLevel ? getNextPowerLevel() : getPowerLevel()) {
@@ -90,10 +72,6 @@ public class PowerLevel {
}; };
} }
public int getMaxMirrorRadius(Player player) {
return getMaxMirrorRadius(player, false);
}
public int getMaxMirrorRadius(Player player, boolean nextPowerLevel) { public int getMaxMirrorRadius(Player player, boolean nextPowerLevel) {
if (player.isCreative()) return CommonConfig.maxMirrorRadius.creative.get(); if (player.isCreative()) return CommonConfig.maxMirrorRadius.creative.get();
return switch (getPowerLevel() + (nextPowerLevel ? 1 : 0)) { return switch (getPowerLevel() + (nextPowerLevel ? 1 : 0)) {
@@ -105,14 +83,24 @@ public class PowerLevel {
} }
public boolean isDisabled(Player player) { public boolean isDisabled(Player player) {
return getMaxBlocksPlacedAtOnce(player) <= 0 || getMaxBlocksPerAxis(player) <= 0; return getMaxBlocksPlacedAtOnce(player, false) <= 0 || getMaxBlocksPerAxis(player, false) <= 0;
} }
public boolean canBreakFar(Player player) { public boolean canBreakFar(Player player) {
return player.isCreative(); return player.getAbilities().instabuild;
} }
public boolean canReplaceBlocks(Player player) { public boolean canReplaceBlocks(Player player) {
return player.isCreative(); return player.getAbilities().instabuild;
}
public CompoundTag serializeNBT(Provider provider) {
CompoundTag tag = new CompoundTag();
tag.putInt("powerLevel", getPowerLevel());
return tag;
}
public void deserializeNBT(Provider provider, CompoundTag nbt) {
setPowerLevel(nbt.getInt("powerLevel"));
} }
} }

View File

@@ -1,16 +1,16 @@
package nl.requios.effortlessbuilding.buildmode; package nl.requios.effortlessbuilding.buildmode;
import com.mojang.math.Vector4f; import net.createmod.catnip.theme.Color;
public enum BuildModeCategoryEnum { public enum BuildModeCategoryEnum {
BASIC(new Vector4f(0f, .5f, 1f, .8f)), BASIC(new Color(0f, .5f, 1f, .8f)),
DIAGONAL(new Vector4f(0.56f, 0.28f, 0.87f, .8f)), DIAGONAL(new Color(0.56f, 0.28f, 0.87f, .8f)),
CIRCULAR(new Vector4f(0.29f, 0.76f, 0.3f, 1f)), CIRCULAR(new Color(0.29f, 0.76f, 0.3f, 1f)),
ROOF(new Vector4f(0.83f, 0.87f, 0.23f, .8f)); ROOF(new Color(0.83f, 0.87f, 0.23f, .8f));
public final Vector4f color; public final Color color;
BuildModeCategoryEnum(Vector4f color) { BuildModeCategoryEnum(Color color) {
this.color = color; this.color = color;
} }
} }

View File

@@ -1,7 +1,18 @@
package nl.requios.effortlessbuilding.buildmode; package nl.requios.effortlessbuilding.buildmode;
import nl.requios.effortlessbuilding.AllIcons; import nl.requios.effortlessbuilding.AllIcons;
import nl.requios.effortlessbuilding.buildmode.buildmodes.*; import nl.requios.effortlessbuilding.buildmode.buildmodes.Circle;
import nl.requios.effortlessbuilding.buildmode.buildmodes.Cube;
import nl.requios.effortlessbuilding.buildmode.buildmodes.Cylinder;
import nl.requios.effortlessbuilding.buildmode.buildmodes.DiagonalLine;
import nl.requios.effortlessbuilding.buildmode.buildmodes.DiagonalWall;
import nl.requios.effortlessbuilding.buildmode.buildmodes.Disabled;
import nl.requios.effortlessbuilding.buildmode.buildmodes.Floor;
import nl.requios.effortlessbuilding.buildmode.buildmodes.Line;
import nl.requios.effortlessbuilding.buildmode.buildmodes.Single;
import nl.requios.effortlessbuilding.buildmode.buildmodes.SlopeFloor;
import nl.requios.effortlessbuilding.buildmode.buildmodes.Sphere;
import nl.requios.effortlessbuilding.buildmode.buildmodes.Wall;
public enum BuildModeEnum { public enum BuildModeEnum {
DISABLED("normal", new Disabled(), BuildModeCategoryEnum.BASIC, AllIcons.I_DISABLE), DISABLED("normal", new Disabled(), BuildModeCategoryEnum.BASIC, AllIcons.I_DISABLE),

View File

@@ -6,11 +6,11 @@ import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.ClipContext; import net.minecraft.world.level.ClipContext;
import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import net.minecraftforge.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.neoforged.api.distmarker.OnlyIn;
import net.neoforged.neoforge.network.PacketDistributor;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.network.IsUsingBuildModePacket; import nl.requios.effortlessbuilding.network.message.IsUsingBuildModePacket;
import nl.requios.effortlessbuilding.network.PacketHandler;
import nl.requios.effortlessbuilding.utilities.BlockSet; import nl.requios.effortlessbuilding.utilities.BlockSet;
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
@@ -30,7 +30,7 @@ public class BuildModes {
public void setBuildMode(BuildModeEnum buildMode) { public void setBuildMode(BuildModeEnum buildMode) {
this.buildMode = buildMode; this.buildMode = buildMode;
PacketHandler.INSTANCE.sendToServer(new IsUsingBuildModePacket(this.buildMode != BuildModeEnum.DISABLED)); PacketDistributor.sendToServer(new IsUsingBuildModePacket(this.buildMode != BuildModeEnum.DISABLED));
EffortlessBuilding.log(Minecraft.getInstance().player, I18n.get(buildMode.getNameKey()), true); EffortlessBuilding.log(Minecraft.getInstance().player, I18n.get(buildMode.getNameKey()), true);
} }
@@ -109,7 +109,7 @@ public class BuildModes {
if (!skipRaytrace) { if (!skipRaytrace) {
//collision within a 1 block radius to selected is fine //collision within a 1 block radius to selected is fine
ClipContext rayTraceContext = new ClipContext(start, lineBound, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, player); ClipContext rayTraceContext = new ClipContext(start, lineBound, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, player);
HitResult rayTraceResult = player.level.clip(rayTraceContext); HitResult rayTraceResult = player.level().clip(rayTraceContext);
intersects = rayTraceResult != null && rayTraceResult.getType() == HitResult.Type.BLOCK && intersects = rayTraceResult != null && rayTraceResult.getType() == HitResult.Type.BLOCK &&
planeBound.subtract(rayTraceResult.getLocation()).lengthSqr() > 4; planeBound.subtract(rayTraceResult.getLocation()).lengthSqr() > 4;
} }

View File

@@ -1,15 +1,15 @@
package nl.requios.effortlessbuilding.buildmode; package nl.requios.effortlessbuilding.buildmode;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraftforge.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.neoforged.api.distmarker.OnlyIn;
import net.neoforged.neoforge.network.PacketDistributor;
import nl.requios.effortlessbuilding.AllIcons; import nl.requios.effortlessbuilding.AllIcons;
import nl.requios.effortlessbuilding.ClientEvents; import nl.requios.effortlessbuilding.ClientEvents;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.EffortlessBuildingClient; import nl.requios.effortlessbuilding.EffortlessBuildingClient;
import nl.requios.effortlessbuilding.network.PacketHandler; import nl.requios.effortlessbuilding.network.message.PerformRedoPacket;
import nl.requios.effortlessbuilding.network.PerformRedoPacket; import nl.requios.effortlessbuilding.network.message.PerformUndoPacket;
import nl.requios.effortlessbuilding.network.PerformUndoPacket;
import nl.requios.effortlessbuilding.systems.BuildSettings; import nl.requios.effortlessbuilding.systems.BuildSettings;
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
@@ -69,8 +69,8 @@ public class ModeOptions {
if (action == null) return; if (action == null) return;
switch (action) { switch (action) {
case UNDO -> PacketHandler.INSTANCE.sendToServer(new PerformUndoPacket()); case UNDO -> PacketDistributor.sendToServer(new PerformUndoPacket());
case REDO -> PacketHandler.INSTANCE.sendToServer(new PerformRedoPacket()); case REDO -> PacketDistributor.sendToServer(new PerformRedoPacket());
case OPEN_MODIFIER_SETTINGS -> ClientEvents.openModifierSettings(); case OPEN_MODIFIER_SETTINGS -> ClientEvents.openModifierSettings();
case OPEN_PLAYER_SETTINGS -> ClientEvents.openPlayerSettings(); case OPEN_PLAYER_SETTINGS -> ClientEvents.openPlayerSettings();
case PREVIOUS_BUILD_MODE -> EffortlessBuildingClient.BUILD_MODES.activatePreviousBuildMode(); case PREVIOUS_BUILD_MODE -> EffortlessBuildingClient.BUILD_MODES.activatePreviousBuildMode();
@@ -103,7 +103,7 @@ public class ModeOptions {
case CIRCLE_START_CORNER -> circleStart = ActionEnum.CIRCLE_START_CORNER; case CIRCLE_START_CORNER -> circleStart = ActionEnum.CIRCLE_START_CORNER;
} }
if (player.level.isClientSide && if (player.level().isClientSide &&
action != ActionEnum.OPEN_MODIFIER_SETTINGS && action != ActionEnum.OPEN_MODIFIER_SETTINGS &&
action != ActionEnum.OPEN_PLAYER_SETTINGS && action != ActionEnum.OPEN_PLAYER_SETTINGS &&
action != ActionEnum.PREVIOUS_BUILD_MODE && action != ActionEnum.PREVIOUS_BUILD_MODE &&

View File

@@ -5,6 +5,7 @@ import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import nl.requios.effortlessbuilding.EffortlessBuildingClient; import nl.requios.effortlessbuilding.EffortlessBuildingClient;
import nl.requios.effortlessbuilding.attachment.AttachmentHandler;
import nl.requios.effortlessbuilding.utilities.BlockEntry; import nl.requios.effortlessbuilding.utilities.BlockEntry;
import nl.requios.effortlessbuilding.utilities.BlockSet; import nl.requios.effortlessbuilding.utilities.BlockSet;
@@ -64,7 +65,7 @@ public abstract class ThreeClicksBuildMode extends BaseBuildMode {
if (secondPos == null) return; if (secondPos == null) return;
//Limit amount of blocks we can place per row //Limit amount of blocks we can place per row
int axisLimit = EffortlessBuildingClient.POWER_LEVEL.getMaxBlocksPerAxis(player); int axisLimit = AttachmentHandler.getMaxBlocksPerAxis(player, false);
int x1 = firstPos.getX(), x2 = secondPos.getX(); int x1 = firstPos.getX(), x2 = secondPos.getX();
int y1 = firstPos.getY(), y2 = secondPos.getY(); int y1 = firstPos.getY(), y2 = secondPos.getY();
@@ -93,7 +94,7 @@ public abstract class ThreeClicksBuildMode extends BaseBuildMode {
if (thirdPos == null) return; if (thirdPos == null) return;
//Limit amount of blocks you can place per row //Limit amount of blocks you can place per row
int axisLimit = EffortlessBuildingClient.POWER_LEVEL.getMaxBlocksPerAxis(player); int axisLimit = AttachmentHandler.getMaxBlocksPerAxis(player, false);
int x1 = firstPos.getX(), x2 = secondPos.getX(), x3 = thirdPos.getX(); int x1 = firstPos.getX(), x2 = secondPos.getX(), x3 = thirdPos.getX();
int y1 = firstPos.getY(), y2 = secondPos.getY(), y3 = thirdPos.getY(); int y1 = firstPos.getY(), y2 = secondPos.getY(), y3 = thirdPos.getY();
@@ -139,7 +140,7 @@ public abstract class ThreeClicksBuildMode extends BaseBuildMode {
criteriaList.add(new HeightCriteria(zBound, secondPos, start)); criteriaList.add(new HeightCriteria(zBound, secondPos, start));
//Remove invalid criteria //Remove invalid criteria
int reach = EffortlessBuildingClient.POWER_LEVEL.getBuildModeReach(player); int reach = AttachmentHandler.getBuildModeReach(player);
criteriaList.removeIf(criteria -> !criteria.isValid(start, look, reach, player, skipRaytrace)); criteriaList.removeIf(criteria -> !criteria.isValid(start, look, reach, player, skipRaytrace));
//If none are valid, return empty list of blocks //If none are valid, return empty list of blocks
@@ -164,7 +165,7 @@ public abstract class ThreeClicksBuildMode extends BaseBuildMode {
} }
} }
} }
return new BlockPos(selected.lineBound); return BlockPos.containing(selected.lineBound);
} }
// protected abstract BlockEntry findSecondPos(List<BlockEntry> blocks); // protected abstract BlockEntry findSecondPos(List<BlockEntry> blocks);
@@ -197,7 +198,7 @@ public abstract class ThreeClicksBuildMode extends BaseBuildMode {
//Make it from a plane into a line, on y axis only //Make it from a plane into a line, on y axis only
private Vec3 toLongestLine(Vec3 boundVec, BlockPos secondPos) { private Vec3 toLongestLine(Vec3 boundVec, BlockPos secondPos) {
BlockPos bound = new BlockPos(boundVec); BlockPos bound = BlockPos.containing(boundVec);
return new Vec3(secondPos.getX(), bound.getY(), secondPos.getZ()); return new Vec3(secondPos.getX(), bound.getY(), secondPos.getZ());
} }

View File

@@ -4,9 +4,9 @@ import net.minecraft.client.Minecraft;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import nl.requios.effortlessbuilding.EffortlessBuildingClient; import nl.requios.effortlessbuilding.EffortlessBuildingClient;
import nl.requios.effortlessbuilding.attachment.AttachmentHandler;
import nl.requios.effortlessbuilding.utilities.BlockEntry; import nl.requios.effortlessbuilding.utilities.BlockEntry;
import nl.requios.effortlessbuilding.utilities.BlockSet; import nl.requios.effortlessbuilding.utilities.BlockSet;
import nl.requios.effortlessbuilding.systems.PowerLevel;
import java.util.List; import java.util.List;
@@ -49,7 +49,7 @@ public abstract class TwoClicksBuildMode extends BaseBuildMode {
if (secondPos == null) return; if (secondPos == null) return;
//Limit amount of blocks we can place per row //Limit amount of blocks we can place per row
int axisLimit = EffortlessBuildingClient.POWER_LEVEL.getMaxBlocksPerAxis(player); int axisLimit = AttachmentHandler.getMaxBlocksPerAxis(player, false);
int x1 = firstPos.getX(), x2 = secondPos.getX(); int x1 = firstPos.getX(), x2 = secondPos.getX();
int y1 = firstPos.getY(), y2 = secondPos.getY(); int y1 = firstPos.getY(), y2 = secondPos.getY();

View File

@@ -1,8 +1,8 @@
package nl.requios.effortlessbuilding.buildmode.buildmodes; package nl.requios.effortlessbuilding.buildmode.buildmodes;
import net.minecraft.world.entity.player.Player;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import net.minecraft.world.entity.player.Player;
import nl.requios.effortlessbuilding.buildmode.ModeOptions; import nl.requios.effortlessbuilding.buildmode.ModeOptions;
import nl.requios.effortlessbuilding.buildmode.TwoClicksBuildMode; import nl.requios.effortlessbuilding.buildmode.TwoClicksBuildMode;

View File

@@ -1,7 +1,7 @@
package nl.requios.effortlessbuilding.buildmode.buildmodes; package nl.requios.effortlessbuilding.buildmode.buildmodes;
import net.minecraft.world.entity.player.Player;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.player.Player;
import nl.requios.effortlessbuilding.buildmode.ModeOptions; import nl.requios.effortlessbuilding.buildmode.ModeOptions;
import nl.requios.effortlessbuilding.buildmode.ThreeClicksBuildMode; import nl.requios.effortlessbuilding.buildmode.ThreeClicksBuildMode;

View File

@@ -1,7 +1,7 @@
package nl.requios.effortlessbuilding.buildmode.buildmodes; package nl.requios.effortlessbuilding.buildmode.buildmodes;
import net.minecraft.world.entity.player.Player;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.player.Player;
import nl.requios.effortlessbuilding.buildmode.ThreeClicksBuildMode; import nl.requios.effortlessbuilding.buildmode.ThreeClicksBuildMode;
import java.util.ArrayList; import java.util.ArrayList;

View File

@@ -1,7 +1,7 @@
package nl.requios.effortlessbuilding.buildmode.buildmodes; package nl.requios.effortlessbuilding.buildmode.buildmodes;
import net.minecraft.world.entity.player.Player;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import nl.requios.effortlessbuilding.buildmode.ThreeClicksBuildMode; import nl.requios.effortlessbuilding.buildmode.ThreeClicksBuildMode;
@@ -20,7 +20,7 @@ public class DiagonalLine extends ThreeClicksBuildMode {
int iterations = (int) Math.ceil(first.distanceTo(second) * sampleMultiplier); int iterations = (int) Math.ceil(first.distanceTo(second) * sampleMultiplier);
for (double t = 0; t <= 1.0; t += 1.0 / iterations) { for (double t = 0; t <= 1.0; t += 1.0 / iterations) {
Vec3 lerp = first.add(second.subtract(first).scale(t)); Vec3 lerp = first.add(second.subtract(first).scale(t));
BlockPos candidate = new BlockPos(lerp); BlockPos candidate = BlockPos.containing(lerp);
//Only add if not equal to the last in the list //Only add if not equal to the last in the list
if (list.isEmpty() || !list.get(list.size() - 1).equals(candidate)) if (list.isEmpty() || !list.get(list.size() - 1).equals(candidate))
list.add(candidate); list.add(candidate);

View File

@@ -1,7 +1,7 @@
package nl.requios.effortlessbuilding.buildmode.buildmodes; package nl.requios.effortlessbuilding.buildmode.buildmodes;
import net.minecraft.world.entity.player.Player;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.player.Player;
import nl.requios.effortlessbuilding.buildmode.ThreeClicksBuildMode; import nl.requios.effortlessbuilding.buildmode.ThreeClicksBuildMode;
import java.util.ArrayList; import java.util.ArrayList;

View File

@@ -1,13 +1,12 @@
package nl.requios.effortlessbuilding.buildmode.buildmodes; package nl.requios.effortlessbuilding.buildmode.buildmodes;
import net.minecraft.world.entity.player.Player;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import nl.requios.effortlessbuilding.EffortlessBuildingClient; import nl.requios.effortlessbuilding.attachment.AttachmentHandler;
import nl.requios.effortlessbuilding.buildmode.BuildModes; import nl.requios.effortlessbuilding.buildmode.BuildModes;
import nl.requios.effortlessbuilding.buildmode.ModeOptions; import nl.requios.effortlessbuilding.buildmode.ModeOptions;
import nl.requios.effortlessbuilding.buildmode.TwoClicksBuildMode; import nl.requios.effortlessbuilding.buildmode.TwoClicksBuildMode;
import nl.requios.effortlessbuilding.systems.PowerLevel;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -25,7 +24,7 @@ public class Floor extends TwoClicksBuildMode {
criteriaList.add(new Criteria(yBound, start)); criteriaList.add(new Criteria(yBound, start));
//Remove invalid criteria //Remove invalid criteria
int reach = EffortlessBuildingClient.POWER_LEVEL.getBuildModeReach(player); int reach = AttachmentHandler.getBuildModeReach(player);
criteriaList.removeIf(criteria -> !criteria.isValid(start, look, reach, player, skipRaytrace)); criteriaList.removeIf(criteria -> !criteria.isValid(start, look, reach, player, skipRaytrace));
//If none are valid, return empty list of blocks //If none are valid, return empty list of blocks
@@ -34,7 +33,7 @@ public class Floor extends TwoClicksBuildMode {
//Then only 1 can be valid, return that one //Then only 1 can be valid, return that one
Criteria selected = criteriaList.get(0); Criteria selected = criteriaList.get(0);
return new BlockPos(selected.planeBound); return BlockPos.containing(selected.planeBound);
} }
public static List<BlockPos> getFloorBlocks(Player player, int x1, int y1, int z1, int x2, int y2, int z2) { public static List<BlockPos> getFloorBlocks(Player player, int x1, int y1, int z1, int x2, int y2, int z2) {

View File

@@ -1,12 +1,11 @@
package nl.requios.effortlessbuilding.buildmode.buildmodes; package nl.requios.effortlessbuilding.buildmode.buildmodes;
import net.minecraft.world.entity.player.Player;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import nl.requios.effortlessbuilding.EffortlessBuildingClient; import nl.requios.effortlessbuilding.attachment.AttachmentHandler;
import nl.requios.effortlessbuilding.buildmode.BuildModes; import nl.requios.effortlessbuilding.buildmode.BuildModes;
import nl.requios.effortlessbuilding.buildmode.TwoClicksBuildMode; import nl.requios.effortlessbuilding.buildmode.TwoClicksBuildMode;
import nl.requios.effortlessbuilding.systems.PowerLevel;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -32,7 +31,7 @@ public class Line extends TwoClicksBuildMode {
criteriaList.add(new Criteria(zBound, firstPos, start)); criteriaList.add(new Criteria(zBound, firstPos, start));
//Remove invalid criteria //Remove invalid criteria
int reach = EffortlessBuildingClient.POWER_LEVEL.getBuildModeReach(player); int reach = AttachmentHandler.getBuildModeReach(player);
criteriaList.removeIf(criteria -> !criteria.isValid(start, look, reach, player, skipRaytrace)); criteriaList.removeIf(criteria -> !criteria.isValid(start, look, reach, player, skipRaytrace));
//If none are valid, return empty list of blocks //If none are valid, return empty list of blocks
@@ -59,7 +58,7 @@ public class Line extends TwoClicksBuildMode {
} }
return new BlockPos(selected.lineBound); return BlockPos.containing(selected.lineBound);
} }
public static List<BlockPos> getLineBlocks(Player player, int x1, int y1, int z1, int x2, int y2, int z2) { public static List<BlockPos> getLineBlocks(Player player, int x1, int y1, int z1, int x2, int y2, int z2) {
@@ -90,7 +89,7 @@ public class Line extends TwoClicksBuildMode {
public static void addZLineBlocks(List<BlockPos> list, int z1, int z2, int x, int y) { public static void addZLineBlocks(List<BlockPos> list, int z1, int z2, int x, int y) {
for (int z = z1; z1 < z2 ? z <= z2 : z >= z2; z += z1 < z2 ? 1 : -1) { for (int z = z1; z1 < z2 ? z <= z2 : z >= z2; z += z1 < z2 ? 1 : -1) {
list.add(new BlockPos(x, y, z)); list.add(BlockPos.containing(x, y, z));
} }
} }
@@ -120,7 +119,7 @@ public class Line extends TwoClicksBuildMode {
//Make it from a plane into a line //Make it from a plane into a line
//Select the axis that is longest //Select the axis that is longest
private Vec3 toLongestLine(Vec3 boundVec, BlockPos firstPos) { private Vec3 toLongestLine(Vec3 boundVec, BlockPos firstPos) {
BlockPos bound = new BlockPos(boundVec); BlockPos bound = BlockPos.containing(boundVec);
BlockPos firstToSecond = bound.subtract(firstPos); BlockPos firstToSecond = bound.subtract(firstPos);
firstToSecond = new BlockPos(Math.abs(firstToSecond.getX()), Math.abs(firstToSecond.getY()), Math.abs(firstToSecond.getZ())); firstToSecond = new BlockPos(Math.abs(firstToSecond.getX()), Math.abs(firstToSecond.getY()), Math.abs(firstToSecond.getZ()));

View File

@@ -1,11 +1,10 @@
package nl.requios.effortlessbuilding.buildmode.buildmodes; package nl.requios.effortlessbuilding.buildmode.buildmodes;
import net.minecraft.world.entity.player.Player;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import nl.requios.effortlessbuilding.EffortlessBuildingClient; import net.minecraft.world.entity.player.Player;
import nl.requios.effortlessbuilding.attachment.AttachmentHandler;
import nl.requios.effortlessbuilding.buildmode.ModeOptions; import nl.requios.effortlessbuilding.buildmode.ModeOptions;
import nl.requios.effortlessbuilding.buildmode.ThreeClicksBuildMode; import nl.requios.effortlessbuilding.buildmode.ThreeClicksBuildMode;
import nl.requios.effortlessbuilding.systems.PowerLevel;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -16,7 +15,7 @@ public class SlopeFloor extends ThreeClicksBuildMode {
public static List<BlockPos> getSlopeFloorBlocks(Player player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3) { public static List<BlockPos> getSlopeFloorBlocks(Player player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3) {
List<BlockPos> list = new ArrayList<>(); List<BlockPos> list = new ArrayList<>();
int axisLimit = EffortlessBuildingClient.POWER_LEVEL.getMaxBlocksPerAxis(player); int axisLimit = AttachmentHandler.getMaxBlocksPerAxis(player, false);
//Determine whether to use x or z axis to slope up //Determine whether to use x or z axis to slope up
boolean onXAxis = true; boolean onXAxis = true;

View File

@@ -1,8 +1,8 @@
package nl.requios.effortlessbuilding.buildmode.buildmodes; package nl.requios.effortlessbuilding.buildmode.buildmodes;
import net.minecraft.world.entity.player.Player;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import net.minecraft.world.entity.player.Player;
import nl.requios.effortlessbuilding.buildmode.ModeOptions; import nl.requios.effortlessbuilding.buildmode.ModeOptions;
import nl.requios.effortlessbuilding.buildmode.ThreeClicksBuildMode; import nl.requios.effortlessbuilding.buildmode.ThreeClicksBuildMode;

View File

@@ -1,13 +1,12 @@
package nl.requios.effortlessbuilding.buildmode.buildmodes; package nl.requios.effortlessbuilding.buildmode.buildmodes;
import net.minecraft.world.entity.player.Player;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import nl.requios.effortlessbuilding.EffortlessBuildingClient; import nl.requios.effortlessbuilding.attachment.AttachmentHandler;
import nl.requios.effortlessbuilding.buildmode.BuildModes; import nl.requios.effortlessbuilding.buildmode.BuildModes;
import nl.requios.effortlessbuilding.buildmode.ModeOptions; import nl.requios.effortlessbuilding.buildmode.ModeOptions;
import nl.requios.effortlessbuilding.buildmode.TwoClicksBuildMode; import nl.requios.effortlessbuilding.buildmode.TwoClicksBuildMode;
import nl.requios.effortlessbuilding.systems.PowerLevel;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -29,7 +28,7 @@ public class Wall extends TwoClicksBuildMode {
criteriaList.add(new Criteria(zBound, firstPos, start, look)); criteriaList.add(new Criteria(zBound, firstPos, start, look));
//Remove invalid criteria //Remove invalid criteria
int reach = EffortlessBuildingClient.POWER_LEVEL.getBuildModeReach(player); int reach = AttachmentHandler.getBuildModeReach(player);
criteriaList.removeIf(criteria -> !criteria.isValid(start, look, reach, player, skipRaytrace)); criteriaList.removeIf(criteria -> !criteria.isValid(start, look, reach, player, skipRaytrace));
//If none are valid, return empty list of blocks //If none are valid, return empty list of blocks
@@ -49,7 +48,7 @@ public class Wall extends TwoClicksBuildMode {
} }
} }
return new BlockPos(selected.planeBound); return BlockPos.containing(selected.planeBound);
} }
public static List<BlockPos> getWallBlocks(Player player, int x1, int y1, int z1, int x2, int y2, int z2) { public static List<BlockPos> getWallBlocks(Player player, int x1, int y1, int z1, int x2, int y2, int z2) {

View File

@@ -1,24 +1,12 @@
package nl.requios.effortlessbuilding.buildmodifier; package nl.requios.effortlessbuilding.buildmodifier;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.nbt.Tag;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.core.Direction;
import net.minecraft.world.InteractionHand;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.phys.Vec3;
import net.minecraft.core.Vec3i; import net.minecraft.core.Vec3i;
import net.minecraftforge.items.IItemHandler; import net.minecraft.nbt.CompoundTag;
import nl.requios.effortlessbuilding.item.AbstractRandomizerBagItem; import net.minecraft.world.entity.player.Player;
import nl.requios.effortlessbuilding.utilities.BlockEntry; import nl.requios.effortlessbuilding.utilities.BlockEntry;
import nl.requios.effortlessbuilding.utilities.BlockSet; import nl.requios.effortlessbuilding.utilities.BlockSet;
import java.util.ArrayList;
import java.util.List;
public class Array extends BaseModifier { public class Array extends BaseModifier {
public Vec3i offset = BlockPos.ZERO; public Vec3i offset = BlockPos.ZERO;

View File

@@ -1,7 +1,6 @@
package nl.requios.effortlessbuilding.buildmodifier; package nl.requios.effortlessbuilding.buildmodifier;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import nl.requios.effortlessbuilding.utilities.BlockSet; import nl.requios.effortlessbuilding.utilities.BlockSet;

View File

@@ -1,13 +1,13 @@
package nl.requios.effortlessbuilding.buildmodifier; package nl.requios.effortlessbuilding.buildmodifier;
import net.createmod.catnip.nbt.NBTHelper;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag; import net.minecraft.nbt.Tag;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraftforge.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.neoforged.api.distmarker.OnlyIn;
import nl.requios.effortlessbuilding.create.foundation.utility.NBTHelper; import net.neoforged.neoforge.network.PacketDistributor;
import nl.requios.effortlessbuilding.network.ModifierSettingsPacket; import nl.requios.effortlessbuilding.network.message.ModifierSettingsPacket;
import nl.requios.effortlessbuilding.network.PacketHandler;
import nl.requios.effortlessbuilding.utilities.BlockSet; import nl.requios.effortlessbuilding.utilities.BlockSet;
import java.util.ArrayList; import java.util.ArrayList;
@@ -96,7 +96,7 @@ public class BuildModifiers {
} }
public void save() { public void save() {
PacketHandler.INSTANCE.sendToServer(new ModifierSettingsPacket(serializeNBT())); PacketDistributor.sendToServer(new ModifierSettingsPacket(serializeNBT()));
//Save locally as well? //Save locally as well?
// var listTag = NBTHelper.writeCompoundList(modifierSettingsList, BaseModifier::serializeNBT); // var listTag = NBTHelper.writeCompoundList(modifierSettingsList, BaseModifier::serializeNBT);

View File

@@ -1,14 +1,11 @@
package nl.requios.effortlessbuilding.buildmodifier; package nl.requios.effortlessbuilding.buildmodifier;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.nbt.Tag;
import net.minecraft.world.entity.player.Player;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import nl.requios.effortlessbuilding.attachment.AttachmentHandler;
import nl.requios.effortlessbuilding.EffortlessBuildingClient;
import nl.requios.effortlessbuilding.utilities.BlockEntry; import nl.requios.effortlessbuilding.utilities.BlockEntry;
import nl.requios.effortlessbuilding.utilities.BlockSet; import nl.requios.effortlessbuilding.utilities.BlockSet;
@@ -44,13 +41,13 @@ public class Mirror extends BaseModifier {
@Override @Override
public void onPowerLevelChanged(int powerLevel) { public void onPowerLevelChanged(int powerLevel) {
radius = EffortlessBuildingClient.POWER_LEVEL.getMaxMirrorRadius(Minecraft.getInstance().player); radius = AttachmentHandler.getMaxMirrorRadius(Minecraft.getInstance().player, false);
} }
private void performMirrorX(BlockSet blocks, BlockEntry blockEntry) { private void performMirrorX(BlockSet blocks, BlockEntry blockEntry) {
//find mirror position //find mirror position
double x = position.x + (position.x - blockEntry.blockPos.getX() - 0.5); double x = position.x + (position.x - blockEntry.blockPos.getX() - 0.5);
BlockPos newBlockPos = new BlockPos(x, blockEntry.blockPos.getY(), blockEntry.blockPos.getZ()); BlockPos newBlockPos = BlockPos.containing(x, blockEntry.blockPos.getY(), blockEntry.blockPos.getZ());
if (blocks.containsKey(newBlockPos)) return; if (blocks.containsKey(newBlockPos)) return;
@@ -66,7 +63,7 @@ public class Mirror extends BaseModifier {
private void performMirrorY(BlockSet blocks, BlockEntry blockEntry) { private void performMirrorY(BlockSet blocks, BlockEntry blockEntry) {
//find mirror position //find mirror position
double y = position.y + (position.y - blockEntry.blockPos.getY() - 0.5); double y = position.y + (position.y - blockEntry.blockPos.getY() - 0.5);
BlockPos newBlockPos = new BlockPos(blockEntry.blockPos.getX(), y, blockEntry.blockPos.getZ()); BlockPos newBlockPos = BlockPos.containing(blockEntry.blockPos.getX(), y, blockEntry.blockPos.getZ());
if (blocks.containsKey(newBlockPos)) return; if (blocks.containsKey(newBlockPos)) return;
@@ -81,7 +78,7 @@ public class Mirror extends BaseModifier {
private void performMirrorZ(BlockSet blocks, BlockEntry blockEntry) { private void performMirrorZ(BlockSet blocks, BlockEntry blockEntry) {
//find mirror position //find mirror position
double z = position.z + (position.z - blockEntry.blockPos.getZ() - 0.5); double z = position.z + (position.z - blockEntry.blockPos.getZ() - 0.5);
BlockPos newBlockPos = new BlockPos(blockEntry.blockPos.getX(), blockEntry.blockPos.getY(), z); BlockPos newBlockPos = BlockPos.containing(blockEntry.blockPos.getX(), blockEntry.blockPos.getY(), z);
if (blocks.containsKey(newBlockPos)) return; if (blocks.containsKey(newBlockPos)) return;

View File

@@ -1,26 +1,18 @@
package nl.requios.effortlessbuilding.buildmodifier; package nl.requios.effortlessbuilding.buildmodifier;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.util.Mth;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.core.Direction;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.level.block.Mirror; import net.minecraft.world.level.block.Mirror;
import net.minecraft.world.level.block.Rotation; import net.minecraft.world.level.block.Rotation;
import net.minecraft.core.BlockPos; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.util.Mth;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import net.minecraftforge.items.IItemHandler; import nl.requios.effortlessbuilding.attachment.AttachmentHandler;
import nl.requios.effortlessbuilding.EffortlessBuildingClient;
import nl.requios.effortlessbuilding.item.AbstractRandomizerBagItem;
import nl.requios.effortlessbuilding.utilities.BlockEntry; import nl.requios.effortlessbuilding.utilities.BlockEntry;
import nl.requios.effortlessbuilding.utilities.BlockSet; import nl.requios.effortlessbuilding.utilities.BlockSet;
import java.util.ArrayList;
import java.util.List;
public class RadialMirror extends BaseModifier { public class RadialMirror extends BaseModifier {
public Vec3 position = new Vec3(0.5, 64.5, 0.5); public Vec3 position = new Vec3(0.5, 64.5, 0.5);
@@ -51,7 +43,7 @@ public class RadialMirror extends BaseModifier {
@Override @Override
public void onPowerLevelChanged(int powerLevel) { public void onPowerLevelChanged(int powerLevel) {
radius = EffortlessBuildingClient.POWER_LEVEL.getMaxMirrorRadius(Minecraft.getInstance().player); radius = AttachmentHandler.getMaxMirrorRadius(Minecraft.getInstance().player, false);
} }
public void performRadialMirror(BlockSet blocks, BlockEntry blockEntry) { public void performRadialMirror(BlockSet blocks, BlockEntry blockEntry) {
@@ -77,7 +69,7 @@ public class RadialMirror extends BaseModifier {
} }
Vec3 relNewVec = relStartVec.yRot((float) curAngle); Vec3 relNewVec = relStartVec.yRot((float) curAngle);
BlockPos newBlockPos = new BlockPos(position.add(relNewVec)); BlockPos newBlockPos = BlockPos.containing(position.add(relNewVec));
if (blocks.containsKey(newBlockPos)) continue; if (blocks.containsKey(newBlockPos)) continue;
@@ -120,11 +112,11 @@ public class RadialMirror extends BaseModifier {
BlockState newBlockState = blockState; BlockState newBlockState = blockState;
if (startAngleToCenter < -0.751 * Math.PI || startAngleToCenter > 0.749 * Math.PI) { if (startAngleToCenter < -0.751 * Math.PI || startAngleToCenter > 0.749 * Math.PI) {
newBlockState = blockState.rotate(player.level, startPos, Rotation.CLOCKWISE_180); newBlockState = blockState.rotate(player.level(), startPos, Rotation.CLOCKWISE_180);
} else if (startAngleToCenter < -0.251 * Math.PI) { } else if (startAngleToCenter < -0.251 * Math.PI) {
newBlockState = blockState.rotate(player.level, startPos, Rotation.COUNTERCLOCKWISE_90); newBlockState = blockState.rotate(player.level(), startPos, Rotation.COUNTERCLOCKWISE_90);
} else if (startAngleToCenter > 0.249 * Math.PI) { } else if (startAngleToCenter > 0.249 * Math.PI) {
newBlockState = blockState.rotate(player.level, startPos, Rotation.CLOCKWISE_90); newBlockState = blockState.rotate(player.level(), startPos, Rotation.CLOCKWISE_90);
} }
return newBlockState; return newBlockState;
@@ -135,17 +127,17 @@ public class RadialMirror extends BaseModifier {
double angleToCenter = Mth.atan2(relVec.x, relVec.z); //between -PI and PI double angleToCenter = Mth.atan2(relVec.x, relVec.z); //between -PI and PI
if (angleToCenter < -0.751 * Math.PI || angleToCenter > 0.749 * Math.PI) { if (angleToCenter < -0.751 * Math.PI || angleToCenter > 0.749 * Math.PI) {
newBlockState = blockState.rotate(player.level, startPos, Rotation.CLOCKWISE_180); newBlockState = blockState.rotate(player.level(), startPos, Rotation.CLOCKWISE_180);
if (alternate) { if (alternate) {
newBlockState = newBlockState.mirror(Mirror.FRONT_BACK); newBlockState = newBlockState.mirror(Mirror.FRONT_BACK);
} }
} else if (angleToCenter < -0.251 * Math.PI) { } else if (angleToCenter < -0.251 * Math.PI) {
newBlockState = blockState.rotate(player.level, startPos, Rotation.CLOCKWISE_90); newBlockState = blockState.rotate(player.level(), startPos, Rotation.CLOCKWISE_90);
if (alternate) { if (alternate) {
newBlockState = newBlockState.mirror(Mirror.LEFT_RIGHT); newBlockState = newBlockState.mirror(Mirror.LEFT_RIGHT);
} }
} else if (angleToCenter > 0.249 * Math.PI) { } else if (angleToCenter > 0.249 * Math.PI) {
newBlockState = blockState.rotate(player.level, startPos, Rotation.COUNTERCLOCKWISE_90); newBlockState = blockState.rotate(player.level(), startPos, Rotation.COUNTERCLOCKWISE_90);
if (alternate) { if (alternate) {
newBlockState = newBlockState.mirror(Mirror.LEFT_RIGHT); newBlockState = newBlockState.mirror(Mirror.LEFT_RIGHT);
} }

View File

@@ -1,13 +1,12 @@
package nl.requios.effortlessbuilding.compatibility; package nl.requios.effortlessbuilding.compatibility;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraftforge.items.IItemHandler; import net.minecraft.world.level.block.Block;
import net.minecraftforge.items.ItemHandlerHelper; import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.neoforged.neoforge.items.IItemHandler;
import nl.requios.effortlessbuilding.create.foundation.item.ItemHelper; import nl.requios.effortlessbuilding.create.foundation.item.ItemHelper;
import nl.requios.effortlessbuilding.item.AbstractRandomizerBagItem; import nl.requios.effortlessbuilding.item.AbstractRandomizerBagItem;

View File

@@ -1,13 +1,8 @@
package nl.requios.effortlessbuilding.create; package nl.requios.effortlessbuilding.create;
import com.mojang.blaze3d.platform.InputConstants; import com.mojang.blaze3d.platform.InputConstants;
import net.minecraft.client.KeyMapping;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.Screen;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.RegisterKeyMappingsEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
public class AllKeys { public class AllKeys {

View File

@@ -1,9 +1,10 @@
package nl.requios.effortlessbuilding.create; package nl.requios.effortlessbuilding.create;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import net.createmod.catnip.render.BindableTexture;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
public enum AllSpecialTextures { public enum AllSpecialTextures implements BindableTexture {
BLANK("blank.png"), BLANK("blank.png"),
CHECKERED("checkerboard.png"), CHECKERED("checkerboard.png"),
@@ -18,7 +19,7 @@ public enum AllSpecialTextures {
public static final String ASSET_PATH = "textures/special/"; public static final String ASSET_PATH = "textures/special/";
private ResourceLocation location; private ResourceLocation location;
private AllSpecialTextures(String filename) { AllSpecialTextures(String filename) {
location = Create.asResource(ASSET_PATH + filename); location = Create.asResource(ASSET_PATH + filename);
} }

View File

@@ -11,6 +11,6 @@ public class Create {
public static final Logger LOGGER = LogUtils.getLogger(); public static final Logger LOGGER = LogUtils.getLogger();
public static ResourceLocation asResource(String path) { public static ResourceLocation asResource(String path) {
return new ResourceLocation(EffortlessBuilding.MODID, path); return ResourceLocation.fromNamespaceAndPath(EffortlessBuilding.MODID, path);
} }
} }

View File

@@ -1,12 +1,10 @@
package nl.requios.effortlessbuilding.create; package nl.requios.effortlessbuilding.create;
import nl.requios.effortlessbuilding.create.foundation.render.SuperByteBufferCache; import net.createmod.catnip.render.SuperByteBufferCache;
import nl.requios.effortlessbuilding.create.foundation.utility.ghost.GhostBlocks; import nl.requios.effortlessbuilding.create.foundation.utility.ghost.GhostBlocks;
import nl.requios.effortlessbuilding.create.foundation.utility.outliner.Outliner;
public class CreateClient { public class CreateClient {
public static final SuperByteBufferCache BUFFER_CACHE = new SuperByteBufferCache(); public static final SuperByteBufferCache BUFFER_CACHE = new SuperByteBufferCache();
public static final Outliner OUTLINER = new Outliner();
public static final GhostBlocks GHOST_BLOCKS = new GhostBlocks(); public static final GhostBlocks GHOST_BLOCKS = new GhostBlocks();
public static void invalidateRenderers() { public static void invalidateRenderers() {

View File

@@ -1,31 +0,0 @@
package nl.requios.effortlessbuilding.create;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.phys.AABB;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import nl.requios.effortlessbuilding.create.foundation.utility.Color;
@Mod.EventBusSubscriber(Dist.CLIENT)
public class CreateClientTest {
// @SubscribeEvent
// public static void onTick(TickEvent.ClientTickEvent event) {
// CreateClient.GHOST_BLOCKS.showGhostState(1, Blocks.SPRUCE_LOG.defaultBlockState())
// .at(0, 120, 0)
// .breathingAlpha();
// CreateClient.GHOST_BLOCKS.showGhostState(2, Blocks.SPRUCE_LOG.defaultBlockState())
// .at(1, 120, 0)
// .breathingAlpha();
//
// CreateClient.OUTLINER.showAABB(1, new AABB(0, 0, 0, 10, 2, 6)
// .move(10, 120, 0))
// .withFaceTexture(AllSpecialTextures.CHECKERED)
// .colored(new Color(0.11f, 0.49f, 0.7f, 1f))
//// .colored(0xbfbfbf)
// .disableNormals()
// .lineWidth(1 / 32f);
// }
}

View File

@@ -2,25 +2,24 @@ package nl.requios.effortlessbuilding.create.events;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import net.createmod.catnip.animation.AnimationTickHolder;
import net.createmod.catnip.levelWrappers.WrappedClientLevel;
import net.createmod.catnip.render.DefaultSuperRenderTypeBuffer;
import net.createmod.catnip.render.SuperRenderTypeBuffer;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import net.minecraftforge.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.minecraftforge.client.event.RenderLevelLastEvent; import net.neoforged.bus.api.SubscribeEvent;
import net.minecraftforge.client.event.ViewportEvent; import net.neoforged.fml.common.EventBusSubscriber;
import net.minecraftforge.event.TickEvent; import net.neoforged.neoforge.client.event.ClientTickEvent;
import net.minecraftforge.event.TickEvent.ClientTickEvent; import net.neoforged.neoforge.client.event.RenderLevelStageEvent;
import net.minecraftforge.event.level.LevelEvent; import net.neoforged.neoforge.client.event.ViewportEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.neoforged.neoforge.event.level.LevelEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import nl.requios.effortlessbuilding.create.Create; import nl.requios.effortlessbuilding.create.Create;
import nl.requios.effortlessbuilding.create.CreateClient; import nl.requios.effortlessbuilding.create.CreateClient;
import nl.requios.effortlessbuilding.create.foundation.render.SuperRenderTypeBuffer;
import nl.requios.effortlessbuilding.create.foundation.utility.AnimationTickHolder;
import nl.requios.effortlessbuilding.create.foundation.utility.CameraAngleAnimationService; import nl.requios.effortlessbuilding.create.foundation.utility.CameraAngleAnimationService;
import nl.requios.effortlessbuilding.create.foundation.utility.worldWrappers.WrappedClientWorld;
@EventBusSubscriber(Dist.CLIENT) @EventBusSubscriber(Dist.CLIENT)
public class ClientEvents { public class ClientEvents {
@@ -29,20 +28,20 @@ public class ClientEvents {
private static final String BLOCK_PREFIX = "block." + Create.ID; private static final String BLOCK_PREFIX = "block." + Create.ID;
@SubscribeEvent @SubscribeEvent
public static void onTick(ClientTickEvent event) { public static void onTick(ClientTickEvent.Post event) {
if (!isGameActive() || event.phase != TickEvent.Phase.END) return; if (!isGameActive()) return;
AnimationTickHolder.tick(); AnimationTickHolder.tick();
CreateClient.GHOST_BLOCKS.tickGhosts(); CreateClient.GHOST_BLOCKS.tickGhosts();
CreateClient.OUTLINER.tickOutlines(); // CreateClient.OUTLINER.tickOutlines();
CameraAngleAnimationService.tick(); CameraAngleAnimationService.tick();
} }
@SubscribeEvent @SubscribeEvent
public static void onLoadWorld(LevelEvent.Load event) { public static void onLoadWorld(LevelEvent.Load event) {
LevelAccessor world = event.getLevel(); LevelAccessor world = event.getLevel();
if (world.isClientSide() && world instanceof ClientLevel && !(world instanceof WrappedClientWorld)) { if (world.isClientSide() && world instanceof ClientLevel && !(world instanceof WrappedClientLevel)) {
CreateClient.invalidateRenderers(); CreateClient.invalidateRenderers();
AnimationTickHolder.reset(); AnimationTickHolder.reset();
} }
@@ -58,7 +57,9 @@ public class ClientEvents {
} }
@SubscribeEvent @SubscribeEvent
public static void onRenderWorld(RenderLevelLastEvent event) { public static void onRenderWorld(RenderLevelStageEvent event) {
if(event.getStage() != RenderLevelStageEvent.Stage.AFTER_CUTOUT_BLOCKS) return;
Vec3 cameraPos = Minecraft.getInstance().gameRenderer.getMainCamera() Vec3 cameraPos = Minecraft.getInstance().gameRenderer.getMainCamera()
.getPosition(); .getPosition();
float pt = AnimationTickHolder.getPartialTicks(); float pt = AnimationTickHolder.getPartialTicks();
@@ -66,11 +67,11 @@ public class ClientEvents {
PoseStack ms = event.getPoseStack(); PoseStack ms = event.getPoseStack();
ms.pushPose(); ms.pushPose();
ms.translate(-cameraPos.x(), -cameraPos.y(), -cameraPos.z()); ms.translate(-cameraPos.x(), -cameraPos.y(), -cameraPos.z());
SuperRenderTypeBuffer buffer = SuperRenderTypeBuffer.getInstance(); SuperRenderTypeBuffer buffer = DefaultSuperRenderTypeBuffer.getInstance();
CreateClient.GHOST_BLOCKS.renderAll(ms, buffer); CreateClient.GHOST_BLOCKS.renderAll(ms, buffer);
CreateClient.OUTLINER.renderOutlines(ms, buffer, pt); // CreateClient.OUTLINER.renderOutlines(ms, buffer, pt);
buffer.draw(); buffer.draw();
RenderSystem.enableCull(); RenderSystem.enableCull();

View File

@@ -1,10 +1,10 @@
package nl.requios.effortlessbuilding.create.events; package nl.requios.effortlessbuilding.create.events;
import net.createmod.catnip.data.WorldAttached;
import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.LevelAccessor;
import net.minecraftforge.event.level.LevelEvent; import net.neoforged.bus.api.SubscribeEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.neoforged.fml.common.EventBusSubscriber;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber; import net.neoforged.neoforge.event.level.LevelEvent;
import nl.requios.effortlessbuilding.create.foundation.utility.WorldAttached;
@EventBusSubscriber @EventBusSubscriber
public class CommonEvents { public class CommonEvents {
@@ -16,7 +16,7 @@ public class CommonEvents {
} }
@EventBusSubscriber(bus = EventBusSubscriber.Bus.MOD) // @Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD)
public static class ModBusEvents { public static class ModBusEvents {
// @SubscribeEvent // @SubscribeEvent

View File

@@ -1,6 +1,6 @@
package nl.requios.effortlessbuilding.create.foundation; package nl.requios.effortlessbuilding.create.foundation;
import nl.requios.effortlessbuilding.create.foundation.utility.LangNumberFormat; import net.createmod.catnip.lang.LangNumberFormat;
import net.minecraft.server.packs.resources.ResourceManager; import net.minecraft.server.packs.resources.ResourceManager;
import net.minecraft.server.packs.resources.ResourceManagerReloadListener; import net.minecraft.server.packs.resources.ResourceManagerReloadListener;

View File

@@ -1,25 +0,0 @@
package nl.requios.effortlessbuilding.create.foundation;
import net.minecraftforge.forgespi.locating.IModFile;
import net.minecraftforge.resource.PathPackResources;
import java.nio.file.Path;
public class ModFilePackResources extends PathPackResources {
protected final IModFile modFile;
protected final String sourcePath;
public ModFilePackResources(String name, IModFile modFile, String sourcePath) {
super(name, modFile.findResource(sourcePath));
this.modFile = modFile;
this.sourcePath = sourcePath;
}
@Override
protected Path resolve(String... paths) {
String[] allPaths = new String[paths.length + 1];
allPaths[0] = sourcePath;
System.arraycopy(paths, 0, allPaths, 1, paths.length);
return modFile.findResource(allPaths);
}
}

View File

@@ -0,0 +1,29 @@
package nl.requios.effortlessbuilding.create.foundation.block.render;
import net.createmod.catnip.render.SpriteShiftEntry;
public class CTSpriteShiftEntry extends SpriteShiftEntry {
protected final CTType type;
public CTSpriteShiftEntry(CTType type) {
this.type = type;
}
public CTType getType() {
return type;
}
public float getTargetU(float localU, int index) {
float uOffset = (index % type.getSheetSize());
return getTarget().getU(
(getUnInterpolatedU(getOriginal(), localU) + uOffset) / ((float) type.getSheetSize()));
}
public float getTargetV(float localV, int index) {
float vOffset = (index / type.getSheetSize());
return getTarget().getV(
(getUnInterpolatedV(getOriginal(), localV) + vOffset) / ((float) type.getSheetSize()));
}
}

View File

@@ -0,0 +1,15 @@
package nl.requios.effortlessbuilding.create.foundation.block.render;
import net.minecraft.resources.ResourceLocation;
import nl.requios.effortlessbuilding.create.foundation.block.render.ConnectedTextureBehaviour.CTContext;
import nl.requios.effortlessbuilding.create.foundation.block.render.ConnectedTextureBehaviour.ContextRequirement;
public interface CTType {
ResourceLocation getId();
int getSheetSize();
ContextRequirement getContextRequirement();
int getTextureIndex(CTContext context);
}

View File

@@ -0,0 +1,283 @@
package nl.requios.effortlessbuilding.create.foundation.block.render;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Direction.Axis;
import net.minecraft.core.Direction.AxisDirection;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public abstract class ConnectedTextureBehaviour {
@Nullable
public CTSpriteShiftEntry getShift(BlockState state, RandomSource rand, Direction direction,
@NotNull TextureAtlasSprite sprite) {
return getShift(state, direction, sprite);
}
@Nullable
public abstract CTSpriteShiftEntry getShift(BlockState state, Direction direction,
@NotNull TextureAtlasSprite sprite);
// TODO: allow more than one data type per state/face?
@Nullable
public abstract CTType getDataType(BlockAndTintGetter world, BlockPos pos, BlockState state, Direction direction);
public boolean buildContextForOccludedDirections() {
return false;
}
protected boolean isBeingBlocked(BlockState state, BlockAndTintGetter reader, BlockPos pos, BlockPos otherPos,
Direction face) {
BlockPos blockingPos = otherPos.relative(face);
BlockState blockState = reader.getBlockState(pos);
BlockState blockingState = reader.getBlockState(blockingPos);
if (!Block.isFaceFull(blockingState.getShape(reader, blockingPos), face.getOpposite()))
return false;
if (face.getAxis()
.choose(pos.getX(), pos.getY(), pos.getZ()) != face.getAxis()
.choose(otherPos.getX(), otherPos.getY(), otherPos.getZ()))
return false;
return connectsTo(state,
getCTBlockState(reader, blockState, face.getOpposite(), pos.relative(face), blockingPos), reader, pos,
blockingPos, face);
}
public boolean connectsTo(BlockState state, BlockState other, BlockAndTintGetter reader, BlockPos pos,
BlockPos otherPos, Direction face, Direction primaryOffset, Direction secondaryOffset) {
return connectsTo(state, other, reader, pos, otherPos, face);
}
public boolean connectsTo(BlockState state, BlockState other, BlockAndTintGetter reader, BlockPos pos,
BlockPos otherPos, Direction face) {
return !isBeingBlocked(state, reader, pos, otherPos, face) && state.getBlock() == other.getBlock();
}
private boolean testConnection(BlockAndTintGetter reader, BlockPos currentPos, BlockState connectiveCurrentState,
Direction textureSide, final Direction horizontal, final Direction vertical, int sh, int sv) {
BlockState trueCurrentState = reader.getBlockState(currentPos);
BlockPos targetPos = currentPos.relative(horizontal, sh)
.relative(vertical, sv);
BlockState connectiveTargetState =
getCTBlockState(reader, trueCurrentState, textureSide, currentPos, targetPos);
return connectsTo(connectiveCurrentState, connectiveTargetState, reader, currentPos, targetPos, textureSide,
sh == 0 ? null : sh == -1 ? horizontal.getOpposite() : horizontal,
sv == 0 ? null : sv == -1 ? vertical.getOpposite() : vertical);
}
public BlockState getCTBlockState(BlockAndTintGetter reader, BlockState reference, Direction face, BlockPos fromPos,
BlockPos toPos) {
BlockState blockState = reader.getBlockState(toPos);
return blockState.getAppearance(reader, toPos, face, reference, fromPos);
}
protected boolean reverseUVs(BlockState state, Direction face) {
return false;
}
protected boolean reverseUVsHorizontally(BlockState state, Direction face) {
return reverseUVs(state, face);
}
protected boolean reverseUVsVertically(BlockState state, Direction face) {
return reverseUVs(state, face);
}
protected Direction getUpDirection(BlockAndTintGetter reader, BlockPos pos, BlockState state, Direction face) {
Axis axis = face.getAxis();
return axis.isHorizontal() ? Direction.UP : Direction.NORTH;
}
protected Direction getRightDirection(BlockAndTintGetter reader, BlockPos pos, BlockState state, Direction face) {
Axis axis = face.getAxis();
return axis == Axis.X ? Direction.SOUTH : Direction.WEST;
}
public CTContext buildContext(BlockAndTintGetter reader, BlockPos pos, BlockState state, Direction face,
ContextRequirement requirement) {
boolean positive = face.getAxisDirection() == AxisDirection.POSITIVE;
Direction h = getRightDirection(reader, pos, state, face);
Direction v = getUpDirection(reader, pos, state, face);
h = positive ? h.getOpposite() : h;
if (face == Direction.DOWN) {
v = v.getOpposite();
h = h.getOpposite();
}
final Direction horizontal = h;
final Direction vertical = v;
boolean flipH = reverseUVsHorizontally(state, face);
boolean flipV = reverseUVsVertically(state, face);
int sh = flipH ? -1 : 1;
int sv = flipV ? -1 : 1;
CTContext context = new CTContext();
if (requirement.up) {
context.up = testConnection(reader, pos, state, face, horizontal, vertical, 0, sv);
}
if (requirement.down) {
context.down = testConnection(reader, pos, state, face, horizontal, vertical, 0, -sv);
}
if (requirement.left) {
context.left = testConnection(reader, pos, state, face, horizontal, vertical, -sh, 0);
}
if (requirement.right) {
context.right = testConnection(reader, pos, state, face, horizontal, vertical, sh, 0);
}
if (requirement.topLeft) {
context.topLeft =
context.up && context.left && testConnection(reader, pos, state, face, horizontal, vertical, -sh, sv);
}
if (requirement.topRight) {
context.topRight =
context.up && context.right && testConnection(reader, pos, state, face, horizontal, vertical, sh, sv);
}
if (requirement.bottomLeft) {
context.bottomLeft = context.down && context.left
&& testConnection(reader, pos, state, face, horizontal, vertical, -sh, -sv);
}
if (requirement.bottomRight) {
context.bottomRight = context.down && context.right
&& testConnection(reader, pos, state, face, horizontal, vertical, sh, -sv);
}
return context;
}
public static class CTContext {
public static final CTContext EMPTY = new CTContext();
public boolean up, down, left, right;
public boolean topLeft, topRight, bottomLeft, bottomRight;
}
public static class ContextRequirement {
public final boolean up, down, left, right;
public final boolean topLeft, topRight, bottomLeft, bottomRight;
public ContextRequirement(boolean up, boolean down, boolean left, boolean right, boolean topLeft,
boolean topRight, boolean bottomLeft, boolean bottomRight) {
this.up = up;
this.down = down;
this.left = left;
this.right = right;
this.topLeft = topLeft;
this.topRight = topRight;
this.bottomLeft = bottomLeft;
this.bottomRight = bottomRight;
}
public static Builder builder() {
return new Builder();
}
public static class Builder {
private boolean up, down, left, right;
private boolean topLeft, topRight, bottomLeft, bottomRight;
public Builder up() {
up = true;
return this;
}
public Builder down() {
down = true;
return this;
}
public Builder left() {
left = true;
return this;
}
public Builder right() {
right = true;
return this;
}
public Builder topLeft() {
topLeft = true;
return this;
}
public Builder topRight() {
topRight = true;
return this;
}
public Builder bottomLeft() {
bottomLeft = true;
return this;
}
public Builder bottomRight() {
bottomRight = true;
return this;
}
public Builder horizontal() {
left();
right();
return this;
}
public Builder vertical() {
up();
down();
return this;
}
public Builder axisAligned() {
horizontal();
vertical();
return this;
}
public Builder corners() {
topLeft();
topRight();
bottomLeft();
bottomRight();
return this;
}
public Builder all() {
axisAligned();
corners();
return this;
}
public ContextRequirement build() {
return new ContextRequirement(up, down, left, right, topLeft, topRight, bottomLeft, bottomRight);
}
}
}
public static abstract class Base extends ConnectedTextureBehaviour {
@Override
@Nullable
public abstract CTSpriteShiftEntry getShift(BlockState state, Direction direction,
@Nullable TextureAtlasSprite sprite);
@Override
@Nullable
public CTType getDataType(BlockAndTintGetter world, BlockPos pos, BlockState state, Direction direction) {
CTSpriteShiftEntry shift = getShift(state, direction, null);
if (shift == null) {
return null;
}
return shift.getType();
}
}
}

View File

@@ -1,49 +0,0 @@
package nl.requios.effortlessbuilding.create.foundation.block.render;
import com.jozufozu.flywheel.core.StitchedSprite;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.resources.ResourceLocation;
public class SpriteShiftEntry {
protected StitchedSprite original;
protected StitchedSprite target;
public void set(ResourceLocation originalTextureLocation, ResourceLocation targetTextureLocation) {
original = new StitchedSprite(originalTextureLocation);
target = new StitchedSprite(targetTextureLocation);
}
public ResourceLocation getOriginalResourceLocation() {
return original.getLocation();
}
public ResourceLocation getTargetResourceLocation() {
return target.getLocation();
}
public TextureAtlasSprite getOriginal() {
return original.get();
}
public TextureAtlasSprite getTarget() {
return target.get();
}
public float getTargetU(float localU) {
return getTarget().getU(getUnInterpolatedU(getOriginal(), localU));
}
public float getTargetV(float localV) {
return getTarget().getV(getUnInterpolatedV(getOriginal(), localV));
}
public static float getUnInterpolatedU(TextureAtlasSprite sprite, float u) {
float f = sprite.getU1() - sprite.getU0();
return (u - sprite.getU0()) / f * 16.0F;
}
public static float getUnInterpolatedV(TextureAtlasSprite sprite, float v) {
float f = sprite.getV1() - sprite.getV0();
return (v - sprite.getV0()) / f * 16.0F;
}
}

View File

@@ -2,16 +2,20 @@ package nl.requios.effortlessbuilding.create.foundation.gui;
import com.mojang.blaze3d.platform.InputConstants; import com.mojang.blaze3d.platform.InputConstants;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import nl.requios.effortlessbuilding.create.foundation.gui.widget.AbstractSimiWidget; import net.createmod.catnip.animation.AnimationTickHolder;
import nl.requios.effortlessbuilding.create.foundation.utility.Components; import net.createmod.catnip.gui.TickableGuiEventListener;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.AbstractWidget; import net.minecraft.client.gui.components.AbstractWidget;
import net.minecraft.client.gui.components.Widget; 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.components.events.GuiEventListener;
import net.minecraft.client.gui.narration.NarratableEntry; import net.minecraft.client.gui.narration.NarratableEntry;
import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraftforge.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.neoforged.api.distmarker.OnlyIn;
import nl.requios.effortlessbuilding.create.foundation.gui.widget.AbstractSimiWidget;
import nl.requios.effortlessbuilding.create.foundation.utility.Components;
import nl.requios.effortlessbuilding.gui.buildmodifier.ModifiersScreenList; import nl.requios.effortlessbuilding.gui.buildmodifier.ModifiersScreenList;
import java.util.Collection; import java.util.Collection;
@@ -65,19 +69,26 @@ public abstract class AbstractSimiScreen extends Screen {
} }
} }
@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 @Override
public boolean isPauseScreen() { public boolean isPauseScreen() {
return false; return false;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected <W extends GuiEventListener & Widget & NarratableEntry> void addRenderableWidgets(W... widgets) { protected <W extends GuiEventListener & Renderable & NarratableEntry> void addRenderableWidgets(W... widgets) {
for (W widget : widgets) { for (W widget : widgets) {
addRenderableWidget(widget); addRenderableWidget(widget);
} }
} }
protected <W extends GuiEventListener & Widget & NarratableEntry> void addRenderableWidgets(Collection<W> widgets) { protected <W extends GuiEventListener & Renderable & NarratableEntry> void addRenderableWidgets(Collection<W> widgets) {
for (W widget : widgets) { for (W widget : widgets) {
addRenderableWidget(widget); addRenderableWidget(widget);
} }
@@ -96,27 +107,33 @@ public abstract class AbstractSimiScreen extends Screen {
} }
@Override @Override
public void render(PoseStack ms, int mouseX, int mouseY, float partialTicks) { public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
partialTicks = minecraft.getFrameTime(); partialTicks = AnimationTickHolder.getPartialTicksUI();
PoseStack ms = graphics.pose();
ms.pushPose(); ms.pushPose();
prepareFrame(); prepareFrame();
renderWindowBackground(ms, mouseX, mouseY, partialTicks); renderWindowBackground(graphics, mouseX, mouseY, partialTicks);
renderWindow(ms, mouseX, mouseY, partialTicks); super.render(graphics, mouseX, mouseY, partialTicks);
super.render(ms, mouseX, mouseY, partialTicks); renderWindow(graphics, mouseX, mouseY, partialTicks);
renderWindowForeground(ms, mouseX, mouseY, partialTicks); renderWindowForeground(graphics, mouseX, mouseY, partialTicks);
endFrame(); endFrame();
ms.popPose(); ms.popPose();
} }
@Override
public void renderBackground(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) {
// super.renderBackground(pGuiGraphics, pMouseX, pMouseY, pPartialTick);
}
@Override @Override
public boolean keyPressed(int keyCode, int scanCode, int modifiers) { public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
boolean keyPressed = super.keyPressed(keyCode, scanCode, modifiers); boolean keyPressed = super.keyPressed(keyCode, scanCode, modifiers);
if (keyPressed || getFocused() != null) if (keyPressed || getFocused() instanceof EditBox)
return keyPressed; return keyPressed;
InputConstants.Key mouseKey = InputConstants.getKey(keyCode, scanCode); InputConstants.Key mouseKey = InputConstants.getKey(keyCode, scanCode);
@@ -130,37 +147,36 @@ public abstract class AbstractSimiScreen extends Screen {
protected void prepareFrame() {} protected void prepareFrame() {}
protected void renderWindowBackground(PoseStack ms, int mouseX, int mouseY, float partialTicks) { protected void renderWindowBackground(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
renderBackground(ms); this.renderTransparentBackground(graphics); //Manually draw background
} }
protected abstract void renderWindow(PoseStack ms, int mouseX, int mouseY, float partialTicks); protected abstract void renderWindow(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks);
protected void renderWindowForeground(PoseStack ms, int mouseX, int mouseY, float partialTicks) { protected void renderWindowForeground(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
for (Widget widget : renderables) { for (Renderable widget : renderables) {
if (widget instanceof AbstractSimiWidget simiWidget && simiWidget.isHoveredOrFocused() if (widget instanceof AbstractSimiWidget simiWidget && simiWidget.isMouseOver(mouseX, mouseY)
&& simiWidget.visible) { && simiWidget.visible) {
List<Component> tooltip = simiWidget.getToolTip(); List<Component> tooltip = simiWidget.getToolTip();
if (tooltip.isEmpty()) if (tooltip.isEmpty())
continue; continue;
int ttx = simiWidget.lockedTooltipX == -1 ? mouseX : simiWidget.lockedTooltipX + simiWidget.x; int ttx = simiWidget.lockedTooltipX == -1 ? mouseX : simiWidget.lockedTooltipX + simiWidget.getX();
int tty = simiWidget.lockedTooltipY == -1 ? mouseY : simiWidget.lockedTooltipY + simiWidget.y; int tty = simiWidget.lockedTooltipY == -1 ? mouseY : simiWidget.lockedTooltipY + simiWidget.getY();
renderComponentTooltip(ms, tooltip, ttx, tty); graphics.renderComponentTooltip(font, tooltip, ttx, tty);
} }
//Added //Added
if (widget instanceof ModifiersScreenList list) { if (widget instanceof ModifiersScreenList list) {
list.renderWindowForeground(ms, mouseX, mouseY, partialTicks); list.renderWindowForeground(graphics, mouseX, mouseY, partialTicks);
} }
} }
} }
protected void endFrame() {} protected void endFrame() {}
@Deprecated @Deprecated
protected void debugWindowArea(PoseStack matrixStack) { protected void debugWindowArea(GuiGraphics graphics) {
fill(matrixStack, guiLeft + windowWidth, guiTop + windowHeight, guiLeft, guiTop, 0xD3D3D3D3); graphics.fill(guiLeft + windowWidth, guiTop + windowHeight, guiLeft, guiTop, 0xD3D3D3D3);
} }
@Override @Override

View File

@@ -1,14 +1,14 @@
package nl.requios.effortlessbuilding.create.foundation.gui; package nl.requios.effortlessbuilding.create.foundation.gui;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack; import net.createmod.catnip.gui.UIRenderHelper;
import nl.requios.effortlessbuilding.create.Create; import net.createmod.catnip.gui.element.ScreenElement;
import nl.requios.effortlessbuilding.create.foundation.gui.element.ScreenElement; import net.createmod.catnip.theme.Color;
import nl.requios.effortlessbuilding.create.foundation.utility.Color; import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.GuiComponent;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.neoforged.api.distmarker.OnlyIn;
import nl.requios.effortlessbuilding.create.Create;
public enum AllGuiTextures implements ScreenElement { public enum AllGuiTextures implements ScreenElement {
@@ -29,7 +29,7 @@ public enum AllGuiTextures implements ScreenElement {
SPEECH_TOOLTIP_BACKGROUND("widgets", 0, 24, 8, 8), SPEECH_TOOLTIP_BACKGROUND("widgets", 0, 24, 8, 8),
SPEECH_TOOLTIP_COLOR("widgets", 8, 24, 8, 8), SPEECH_TOOLTIP_COLOR("widgets", 8, 24, 8, 8),
TRAIN_HUD_SPEED_BG("widgets", 0, 190, 182, 5), TRAIN_HUD_SPEED_BG("widgets", 0, 190, 182, 5),
TRAIN_HUD_SPEED("widgets", 0, 185, 182, 5), TRAIN_HUD_SPEED("widgets", 0, 185, 182, 5),
TRAIN_HUD_THROTTLE("widgets", 0, 195, 182, 5), TRAIN_HUD_THROTTLE("widgets", 0, 195, 182, 5),
@@ -61,7 +61,7 @@ public enum AllGuiTextures implements ScreenElement {
} }
private AllGuiTextures(String namespace, String location, int startX, int startY, int width, int height) { private AllGuiTextures(String namespace, String location, int startX, int startY, int width, int height) {
this.location = new ResourceLocation(namespace, "textures/gui/" + location + ".png"); this.location = ResourceLocation.fromNamespaceAndPath(namespace, "textures/gui/" + location + ".png");
this.width = width; this.width = width;
this.height = height; this.height = height;
this.startX = startX; this.startX = startX;
@@ -74,22 +74,14 @@ public enum AllGuiTextures implements ScreenElement {
} }
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
@Override public void render(GuiGraphics graphics, int x, int y) {
public void render(PoseStack ms, int x, int y) { graphics.blit(location, x, y, startX, startY, width, height);
bind();
GuiComponent.blit(ms, x, y, 0, startX, startY, width, height, 256, 256);
} }
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public void render(PoseStack ms, int x, int y, GuiComponent component) { public void render(GuiGraphics graphics, int x, int y, Color c) {
bind(); bind();
component.blit(ms, x, y, startX, startY, width, height); UIRenderHelper.drawColoredTexture(graphics, c, x, y, startX, startY, width, height);
}
@OnlyIn(Dist.CLIENT)
public void render(PoseStack ms, int x, int y, Color c) {
bind();
UIRenderHelper.drawColoredTexture(ms, c, x, y, startX, startY, width, height);
} }
} }

View File

@@ -3,19 +3,19 @@ package nl.requios.effortlessbuilding.create.foundation.gui;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.math.Matrix4f; import net.createmod.catnip.gui.element.DelegatedStencilElement;
import nl.requios.effortlessbuilding.create.Create; import net.createmod.catnip.gui.element.ScreenElement;
import nl.requios.effortlessbuilding.create.foundation.gui.element.DelegatedStencilElement; import net.createmod.catnip.theme.Color;
import nl.requios.effortlessbuilding.create.foundation.gui.element.ScreenElement; import net.minecraft.client.gui.GuiGraphics;
import nl.requios.effortlessbuilding.create.foundation.utility.Color;
import net.minecraft.client.gui.GuiComponent;
import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import net.minecraftforge.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.neoforged.api.distmarker.OnlyIn;
import nl.requios.effortlessbuilding.create.Create;
import org.joml.Matrix4f;
public class AllIcons implements ScreenElement { public class AllIcons implements ScreenElement {
@@ -81,7 +81,7 @@ public class AllIcons implements ScreenElement {
public static final AllIcons public static final AllIcons
I_TOOL_DEPLOY = newRow(), I_TOOL_DEPLOY = newRow(),
I_SKIP_MISSING = next(), I_SKIP_MISSING = next(),
I_SKIP_TILES = next(), I_SKIP_BLOCK_ENTITIES = next(),
I_DICE = next(), I_DICE = next(),
I_TUNNEL_SPLIT = next(), I_TUNNEL_SPLIT = next(),
I_TUNNEL_FORCED_SPLIT = next(), I_TUNNEL_FORCED_SPLIT = next(),
@@ -173,20 +173,13 @@ public class AllIcons implements ScreenElement {
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
@Override @Override
public void render(PoseStack matrixStack, int x, int y) { public void render(GuiGraphics graphics, int x, int y) {
bind(); graphics.blit(ICON_ATLAS, x, y, 0, iconX, iconY, 16, 16, 256, 256);
GuiComponent.blit(matrixStack, x, y, 0, iconX, iconY, 16, 16, 256, 256);
}
@OnlyIn(Dist.CLIENT)
public void render(PoseStack matrixStack, int x, int y, GuiComponent component) {
bind();
component.blit(matrixStack, x, y, iconX, iconY, 16, 16);
} }
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public void render(PoseStack ms, MultiBufferSource buffer, int color) { public void render(PoseStack ms, MultiBufferSource buffer, int color) {
VertexConsumer builder = buffer.getBuffer(RenderType.textSeeThrough(ICON_ATLAS)); VertexConsumer builder = buffer.getBuffer(RenderType.text(ICON_ATLAS));
Matrix4f matrix = ms.last().pose(); Matrix4f matrix = ms.last().pose();
Color rgb = new Color(color); Color rgb = new Color(color);
int light = LightTexture.FULL_BRIGHT; int light = LightTexture.FULL_BRIGHT;
@@ -209,11 +202,10 @@ public class AllIcons implements ScreenElement {
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
private void vertex(VertexConsumer builder, Matrix4f matrix, Vec3 vec, Color rgb, float u, float v, int light) { 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) builder.addVertex(matrix, (float) vec.x, (float) vec.y, (float) vec.z)
.color(rgb.getRed(), rgb.getGreen(), rgb.getBlue(), 255) .setColor(rgb.getRed(), rgb.getGreen(), rgb.getBlue(), 255)
.uv(u, v) .setUv(u, v)
.uv2(light) .setLight(light);
.endVertex();
} }
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)

View File

@@ -1,227 +0,0 @@
package nl.requios.effortlessbuilding.create.foundation.gui;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import nl.requios.effortlessbuilding.create.foundation.gui.element.BoxElement;
import nl.requios.effortlessbuilding.create.foundation.gui.element.TextStencilElement;
import nl.requios.effortlessbuilding.create.foundation.gui.widget.BoxWidget;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.FormattedText;
import net.minecraft.network.chat.Style;
import org.lwjgl.opengl.GL30;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
public class ConfirmationScreen extends AbstractSimiScreen {
private Screen source;
private Consumer<Response> action = _success -> {
};
private List<FormattedText> text = new ArrayList<>();
private boolean centered = false;
private int x;
private int y;
private int textWidth;
private int textHeight;
private boolean tristate;
private BoxWidget confirm;
private BoxWidget confirmDontSave;
private BoxWidget cancel;
private BoxElement textBackground;
public enum Response {
Confirm, ConfirmDontSave, Cancel
}
/*
* Removes text lines from the back of the list
* */
public ConfirmationScreen removeTextLines(int amount) {
if (amount > text.size())
return clearText();
text.subList(text.size() - amount, text.size()).clear();
return this;
}
public ConfirmationScreen clearText() {
this.text.clear();
return this;
}
public ConfirmationScreen addText(FormattedText text) {
this.text.add(text);
return this;
}
public ConfirmationScreen withText(FormattedText text) {
return clearText().addText(text);
}
public ConfirmationScreen at(int x, int y) {
this.x = Math.max(x, 0);
this.y = Math.max(y, 0);
this.centered = false;
return this;
}
public ConfirmationScreen centered() {
this.centered = true;
return this;
}
public ConfirmationScreen withAction(Consumer<Boolean> action) {
this.action = r -> action.accept(r == Response.Confirm);
return this;
}
public ConfirmationScreen withThreeActions(Consumer<Response> action) {
this.action = action;
this.tristate = true;
return this;
}
public void open(@Nonnull Screen source) {
this.source = source;
Minecraft client = source.getMinecraft();
this.init(client, client.getWindow().getGuiScaledWidth(), client.getWindow().getGuiScaledHeight());
this.minecraft.screen = this;
}
@Override
public void tick() {
super.tick();
source.tick();
}
@Override
protected void init() {
super.init();
ArrayList<FormattedText> copy = new ArrayList<>(text);
text.clear();
copy.forEach(t -> text.addAll(font.getSplitter().splitLines(t, 300, Style.EMPTY)));
textHeight = text.size() * (font.lineHeight + 1) + 4;
textWidth = 300;
if (centered) {
x = width/2 - textWidth/2 - 2;
y = height/2 - textHeight/2 - 16;
} else {
x = Math.max(0, x - textWidth / 2);
y = Math.max(0, y -= textHeight);
}
if (x + textWidth > width) {
x = width - textWidth;
}
if (y + textHeight + 30 > height) {
y = height - textHeight - 30;
}
int buttonX = x + textWidth / 2 - 6 - (int) (70 * (tristate ? 1.5f : 1));
TextStencilElement confirmText =
new TextStencilElement(font, tristate ? "Save" : "Confirm").centered(true, true);
confirm = new BoxWidget(buttonX, y + textHeight + 6, 70, 16).withCallback(() -> accept(Response.Confirm));
confirm.showingElement(confirmText.withElementRenderer(BoxWidget.gradientFactory.apply(confirm)));
addRenderableWidget(confirm);
buttonX += 12 + 70;
if (tristate) {
TextStencilElement confirmDontSaveText =
new TextStencilElement(font, "Don't Save").centered(true, true);
confirmDontSave =
new BoxWidget(buttonX, y + textHeight + 6, 70, 16).withCallback(() -> accept(Response.ConfirmDontSave));
confirmDontSave.showingElement(
confirmDontSaveText.withElementRenderer(BoxWidget.gradientFactory.apply(confirmDontSave)));
addRenderableWidget(confirmDontSave);
buttonX += 12 + 70;
}
TextStencilElement cancelText = new TextStencilElement(font, "Cancel").centered(true, true);
cancel = new BoxWidget(buttonX, y + textHeight + 6, 70, 16)
.withCallback(() -> accept(Response.Cancel));
cancel.showingElement(cancelText.withElementRenderer(BoxWidget.gradientFactory.apply(cancel)));
addRenderableWidget(cancel);
textBackground = new BoxElement()
.gradientBorder(Theme.p(Theme.Key.BUTTON_DISABLE))
.withBounds(width + 10, textHeight + 35)
.at(-5, y - 5);
if (text.size() == 1)
x = (width - font.width(text.get(0))) / 2;
}
@Override
public void onClose() {
accept(Response.Cancel);
}
private void accept(Response success) {
minecraft.screen = source;
action.accept(success);
}
@Override
protected void renderWindow(PoseStack ms, int mouseX, int mouseY, float partialTicks) {
textBackground.render(ms);
int offset = font.lineHeight + 1;
int lineY = y - offset;
ms.pushPose();
ms.translate(0, 0, 200);
for (FormattedText line : text) {
lineY += offset;
if (line == null)
continue;
font.draw(ms, line.getString(), x, lineY, 0xeaeaea);
}
ms.popPose();
}
@Override
protected void renderWindowBackground(PoseStack ms, int mouseX, int mouseY, float partialTicks) {
endFrame();
source.render(ms, 0, 0, 10); // zero mouse coords to prevent further tooltips
prepareFrame();
this.fillGradient(ms, 0, 0, this.width, this.height, 0x70101010, 0x80101010);
}
@Override
protected void prepareFrame() {
UIRenderHelper.swapAndBlitColor(minecraft.getMainRenderTarget(), UIRenderHelper.framebuffer);
RenderSystem.clear(GL30.GL_STENCIL_BUFFER_BIT | GL30.GL_DEPTH_BUFFER_BIT, Minecraft.ON_OSX);
}
@Override
protected void endFrame() {
UIRenderHelper.swapAndBlitColor(UIRenderHelper.framebuffer, minecraft.getMainRenderTarget());
}
@Override
public void resize(@Nonnull Minecraft client, int width, int height) {
super.resize(client, width, height);
source.resize(client, width, height);
}
@Override
public boolean isPauseScreen() {
return true;
}
}

View File

@@ -1,8 +1,10 @@
package nl.requios.effortlessbuilding.create.foundation.gui; package nl.requios.effortlessbuilding.create.foundation.gui;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.math.Matrix4f; import com.mojang.math.Axis;
import com.mojang.math.Vector3f; import net.createmod.catnip.gui.ILightingSettings;
import org.joml.Matrix4f;
import org.joml.Vector3f;
public class CustomLightingSettings implements ILightingSettings { public class CustomLightingSettings implements ILightingSettings {
@@ -19,25 +21,25 @@ public class CustomLightingSettings implements ILightingSettings {
} }
protected void init(float yRot1, float xRot1, float yRot2, float xRot2, boolean doubleLight) { protected void init(float yRot1, float xRot1, float yRot2, float xRot2, boolean doubleLight) {
light1 = Vector3f.ZP.copy(); light1 = new Vector3f(0, 0, 1);
light1.transform(Vector3f.YP.rotationDegrees(yRot1)); light1.rotate(Axis.YP.rotationDegrees(yRot1));
light1.transform(Vector3f.XN.rotationDegrees(xRot1)); light1.rotate(Axis.XN.rotationDegrees(xRot1));
if (doubleLight) { if (doubleLight) {
light2 = Vector3f.ZP.copy(); light2 = new Vector3f(0, 0, 1);
light2.transform(Vector3f.YP.rotationDegrees(yRot2)); light2.rotate(Axis.YP.rotationDegrees(yRot2));
light2.transform(Vector3f.XN.rotationDegrees(xRot2)); light2.rotate(Axis.XN.rotationDegrees(xRot2));
} else { } else {
light2 = Vector3f.ZERO; light2 = new Vector3f();
} }
lightMatrix = new Matrix4f(); lightMatrix = new Matrix4f();
lightMatrix.setIdentity(); lightMatrix.identity();
} }
@Override @Override
public void applyLighting() { public void applyLighting() {
RenderSystem.setupLevelDiffuseLighting(light1, light2, lightMatrix); RenderSystem.setShaderLights(light1, light2);
} }
public static Builder builder() { public static Builder builder() {

View File

@@ -1,12 +0,0 @@
package nl.requios.effortlessbuilding.create.foundation.gui;
import com.mojang.blaze3d.platform.Lighting;
public interface ILightingSettings {
void applyLighting();
static final ILightingSettings DEFAULT_3D = () -> Lighting.setupFor3DItems();
static final ILightingSettings DEFAULT_FLAT = () -> Lighting.setupForFlatItems();
}

View File

@@ -2,18 +2,18 @@ package nl.requios.effortlessbuilding.create.foundation.gui;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.Tesselator;
import com.mojang.math.Matrix4f;
import net.minecraft.client.gui.Font; import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.network.chat.FormattedText; import net.minecraft.network.chat.FormattedText;
import net.minecraft.network.chat.Style; import net.minecraft.network.chat.Style;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraftforge.client.ForgeHooksClient; import net.neoforged.neoforge.client.ClientHooks;
import net.minecraftforge.client.event.RenderTooltipEvent; import net.neoforged.neoforge.client.event.RenderTooltipEvent;
import net.minecraftforge.client.gui.ScreenUtils; import net.neoforged.neoforge.client.extensions.IGuiGraphicsExtension;
import net.minecraftforge.common.MinecraftForge; import net.neoforged.neoforge.common.NeoForge;
import org.joml.Matrix4f;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.ArrayList; import java.util.ArrayList;
@@ -31,41 +31,43 @@ public class RemovedGuiUtils {
cachedTooltipStack = ItemStack.EMPTY; cachedTooltipStack = ItemStack.EMPTY;
} }
public static void drawHoveringText(PoseStack mStack, List<? extends FormattedText> textLines, int mouseX, public static void drawHoveringText(GuiGraphics graphics, List<? extends FormattedText> textLines, int mouseX,
int mouseY, int screenWidth, int screenHeight, int maxTextWidth, Font font) { int mouseY, int screenWidth, int screenHeight, int maxTextWidth, Font font) {
drawHoveringText(mStack, textLines, mouseX, mouseY, screenWidth, screenHeight, maxTextWidth, drawHoveringText(graphics, textLines, mouseX, mouseY, screenWidth, screenHeight, maxTextWidth,
ScreenUtils.DEFAULT_BACKGROUND_COLOR, ScreenUtils.DEFAULT_BORDER_COLOR_START, ScreenUtils.DEFAULT_BORDER_COLOR_END, IGuiGraphicsExtension.DEFAULT_BACKGROUND_COLOR, IGuiGraphicsExtension.DEFAULT_BORDER_COLOR_START, IGuiGraphicsExtension.DEFAULT_BORDER_COLOR_END,
font); font);
} }
public static void drawHoveringText(PoseStack mStack, List<? extends FormattedText> textLines, int mouseX, public static void drawHoveringText(GuiGraphics graphics, List<? extends FormattedText> textLines, int mouseX,
int mouseY, int screenWidth, int screenHeight, int maxTextWidth, int backgroundColor, int borderColorStart, int mouseY, int screenWidth, int screenHeight, int maxTextWidth, int backgroundColor, int borderColorStart,
int borderColorEnd, Font font) { int borderColorEnd, Font font) {
drawHoveringText(cachedTooltipStack, mStack, textLines, mouseX, mouseY, screenWidth, screenHeight, maxTextWidth, drawHoveringText(cachedTooltipStack, graphics, textLines, mouseX, mouseY, screenWidth, screenHeight, maxTextWidth,
backgroundColor, borderColorStart, borderColorEnd, font); backgroundColor, borderColorStart, borderColorEnd, font);
} }
public static void drawHoveringText(@Nonnull final ItemStack stack, PoseStack mStack, public static void drawHoveringText(@Nonnull final ItemStack stack, GuiGraphics graphics,
List<? extends FormattedText> textLines, int mouseX, int mouseY, int screenWidth, int screenHeight, List<? extends FormattedText> textLines, int mouseX, int mouseY, int screenWidth, int screenHeight,
int maxTextWidth, Font font) { int maxTextWidth, Font font) {
drawHoveringText(stack, mStack, textLines, mouseX, mouseY, screenWidth, screenHeight, maxTextWidth, drawHoveringText(stack, graphics, textLines, mouseX, mouseY, screenWidth, screenHeight, maxTextWidth,
ScreenUtils.DEFAULT_BACKGROUND_COLOR, ScreenUtils.DEFAULT_BORDER_COLOR_START, ScreenUtils.DEFAULT_BORDER_COLOR_END, IGuiGraphicsExtension.DEFAULT_BACKGROUND_COLOR, IGuiGraphicsExtension.DEFAULT_BORDER_COLOR_START, IGuiGraphicsExtension.DEFAULT_BORDER_COLOR_END,
font); font);
} }
public static void drawHoveringText(@Nonnull final ItemStack stack, PoseStack pStack, public static void drawHoveringText(@Nonnull final ItemStack stack, GuiGraphics graphics,
List<? extends FormattedText> textLines, int mouseX, int mouseY, int screenWidth, int screenHeight, List<? extends FormattedText> textLines, int mouseX, int mouseY, int screenWidth, int screenHeight,
int maxTextWidth, int backgroundColor, int borderColorStart, int borderColorEnd, Font font) { int maxTextWidth, int backgroundColor, int borderColorStart, int borderColorEnd, Font font) {
if (textLines.isEmpty()) if (textLines.isEmpty())
return; return;
List<ClientTooltipComponent> list = ForgeHooksClient.gatherTooltipComponents(stack, textLines, List<ClientTooltipComponent> list = ClientHooks.gatherTooltipComponents(stack, textLines,
stack.getTooltipImage(), mouseX, screenWidth, screenHeight, font, font); stack.getTooltipImage(), mouseX, screenWidth, screenHeight, font);
RenderTooltipEvent.Pre event = RenderTooltipEvent.Pre event =
new RenderTooltipEvent.Pre(stack, pStack, mouseX, mouseY, screenWidth, screenHeight, font, list); new RenderTooltipEvent.Pre(stack, graphics, mouseX, mouseY, screenWidth, screenHeight, font, list, null);
if (MinecraftForge.EVENT_BUS.post(event)) if (NeoForge.EVENT_BUS.post(event).isCanceled())
return; return;
PoseStack pStack = graphics.pose();
mouseX = event.getX(); mouseX = event.getX();
mouseY = event.getY(); mouseY = event.getY();
screenWidth = event.getScreenWidth(); screenWidth = event.getScreenWidth();
@@ -144,9 +146,9 @@ public class RemovedGuiUtils {
tooltipY = screenHeight - tooltipHeight - 4; tooltipY = screenHeight - tooltipHeight - 4;
final int zLevel = 400; final int zLevel = 400;
RenderTooltipEvent.Color colorEvent = new RenderTooltipEvent.Color(stack, pStack, tooltipX, tooltipY, RenderTooltipEvent.Color colorEvent = new RenderTooltipEvent.Color(stack, graphics, tooltipX, tooltipY,
font, backgroundColor, borderColorStart, borderColorEnd, list); font, backgroundColor, borderColorStart, borderColorEnd, list);
MinecraftForge.EVENT_BUS.post(colorEvent); NeoForge.EVENT_BUS.post(colorEvent);
backgroundColor = colorEvent.getBackgroundStart(); backgroundColor = colorEvent.getBackgroundStart();
borderColorStart = colorEvent.getBorderStart(); borderColorStart = colorEvent.getBorderStart();
borderColorEnd = colorEvent.getBorderEnd(); borderColorEnd = colorEvent.getBorderEnd();
@@ -154,27 +156,26 @@ public class RemovedGuiUtils {
pStack.pushPose(); pStack.pushPose();
Matrix4f mat = pStack.last() Matrix4f mat = pStack.last()
.pose(); .pose();
ScreenUtils.drawGradientRect(mat, zLevel, tooltipX - 3, tooltipY - 4, tooltipX + tooltipTextWidth + 3, graphics.fillGradient(tooltipX - 3, tooltipY - 4, tooltipX + tooltipTextWidth + 3,
tooltipY - 3, backgroundColor, backgroundColor); tooltipY - 3, zLevel, backgroundColor, backgroundColor);
ScreenUtils.drawGradientRect(mat, zLevel, tooltipX - 3, tooltipY + tooltipHeight + 3, graphics.fillGradient(tooltipX - 3, tooltipY + tooltipHeight + 3,
tooltipX + tooltipTextWidth + 3, tooltipY + tooltipHeight + 4, backgroundColor, backgroundColor); tooltipX + tooltipTextWidth + 3, tooltipY + tooltipHeight + 4, zLevel, backgroundColor, backgroundColor);
ScreenUtils.drawGradientRect(mat, zLevel, tooltipX - 3, tooltipY - 3, tooltipX + tooltipTextWidth + 3, graphics.fillGradient(tooltipX - 3, tooltipY - 3, tooltipX + tooltipTextWidth + 3,
tooltipY + tooltipHeight + 3, backgroundColor, backgroundColor); tooltipY + tooltipHeight + 3, zLevel, backgroundColor, backgroundColor);
ScreenUtils.drawGradientRect(mat, zLevel, tooltipX - 4, tooltipY - 3, tooltipX - 3, tooltipY + tooltipHeight + 3, graphics.fillGradient(tooltipX - 4, tooltipY - 3, tooltipX - 3, tooltipY + tooltipHeight + 3,
backgroundColor, backgroundColor); zLevel, backgroundColor, backgroundColor);
ScreenUtils.drawGradientRect(mat, zLevel, tooltipX + tooltipTextWidth + 3, tooltipY - 3, graphics.fillGradient(tooltipX + tooltipTextWidth + 3, tooltipY - 3,
tooltipX + tooltipTextWidth + 4, tooltipY + tooltipHeight + 3, backgroundColor, backgroundColor); tooltipX + tooltipTextWidth + 4, tooltipY + tooltipHeight + 3, zLevel, backgroundColor, backgroundColor);
ScreenUtils.drawGradientRect(mat, zLevel, tooltipX - 3, tooltipY - 3 + 1, tooltipX - 3 + 1, graphics.fillGradient(tooltipX - 3, tooltipY - 3 + 1, tooltipX - 3 + 1,
tooltipY + tooltipHeight + 3 - 1, borderColorStart, borderColorEnd); tooltipY + tooltipHeight + 3 - 1, zLevel, borderColorStart, borderColorEnd);
ScreenUtils.drawGradientRect(mat, zLevel, tooltipX + tooltipTextWidth + 2, tooltipY - 3 + 1, graphics.fillGradient(tooltipX + tooltipTextWidth + 2, tooltipY - 3 + 1,
tooltipX + tooltipTextWidth + 3, tooltipY + tooltipHeight + 3 - 1, borderColorStart, borderColorEnd); tooltipX + tooltipTextWidth + 3, tooltipY + tooltipHeight + 3 - 1, zLevel, borderColorStart, borderColorEnd);
ScreenUtils.drawGradientRect(mat, zLevel, tooltipX - 3, tooltipY - 3, tooltipX + tooltipTextWidth + 3, graphics.fillGradient(tooltipX - 3, tooltipY - 3, tooltipX + tooltipTextWidth + 3,
tooltipY - 3 + 1, borderColorStart, borderColorStart); tooltipY - 3 + 1, zLevel, borderColorStart, borderColorStart);
ScreenUtils.drawGradientRect(mat, zLevel, tooltipX - 3, tooltipY + tooltipHeight + 2, graphics.fillGradient(tooltipX - 3, tooltipY + tooltipHeight + 2,
tooltipX + tooltipTextWidth + 3, tooltipY + tooltipHeight + 3, borderColorEnd, borderColorEnd); tooltipX + tooltipTextWidth + 3, tooltipY + tooltipHeight + 3, zLevel, borderColorEnd, borderColorEnd);
MultiBufferSource.BufferSource renderType = MultiBufferSource.immediate(Tesselator.getInstance() MultiBufferSource.BufferSource renderType = graphics.bufferSource();
.getBuilder());
pStack.translate(0.0D, 0.0D, zLevel); pStack.translate(0.0D, 0.0D, zLevel);
for (int lineNumber = 0; lineNumber < list.size(); ++lineNumber) { for (int lineNumber = 0; lineNumber < list.size(); ++lineNumber) {

View File

@@ -1,11 +1,16 @@
package nl.requios.effortlessbuilding.create.foundation.gui; package nl.requios.effortlessbuilding.create.foundation.gui;
import nl.requios.effortlessbuilding.create.foundation.utility.Color; import net.createmod.catnip.data.Couple;
import nl.requios.effortlessbuilding.create.foundation.utility.Couple; import net.createmod.catnip.theme.Color;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.*; import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
public class Theme { public class Theme {

View File

@@ -1,7 +0,0 @@
package nl.requios.effortlessbuilding.create.foundation.gui;
import net.minecraft.client.gui.components.events.GuiEventListener;
public interface TickableGuiEventListener extends GuiEventListener {
void tick();
}

View File

@@ -1,316 +0,0 @@
package nl.requios.effortlessbuilding.create.foundation.gui;
import com.mojang.blaze3d.pipeline.RenderTarget;
import com.mojang.blaze3d.platform.GlConst;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.platform.Window;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.*;
import com.mojang.math.Matrix4f;
import com.mojang.math.Vector3f;
import nl.requios.effortlessbuilding.create.foundation.utility.Color;
import nl.requios.effortlessbuilding.create.foundation.utility.Couple;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraftforge.client.gui.ScreenUtils;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
import javax.annotation.Nonnull;
public class UIRenderHelper {
/**
* An FBO that has a stencil buffer for use wherever stencil are necessary. Forcing the main FBO to have a stencil
* buffer will cause GL error spam when using fabulous graphics.
*/
public static CustomRenderTarget framebuffer;
public static void init() {
RenderSystem.recordRenderCall(() -> {
Window mainWindow = Minecraft.getInstance().getWindow();
framebuffer = CustomRenderTarget.create(mainWindow);
});
}
public static void updateWindowSize(Window mainWindow) {
if (framebuffer != null)
framebuffer.resize(mainWindow.getWidth(), mainWindow.getHeight(), Minecraft.ON_OSX);
}
public static void drawFramebuffer(float alpha) {
framebuffer.renderWithAlpha(alpha);
}
/**
* Switch from src to dst, after copying the contents of src to dst.
*/
public static void swapAndBlitColor(RenderTarget src, RenderTarget dst) {
GlStateManager._glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER, src.frameBufferId);
GlStateManager._glBindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, dst.frameBufferId);
GlStateManager._glBlitFrameBuffer(0, 0, src.viewWidth, src.viewHeight, 0, 0, dst.viewWidth, dst.viewHeight, GL30.GL_COLOR_BUFFER_BIT, GL20.GL_LINEAR);
GlStateManager._glBindFramebuffer(GlConst.GL_FRAMEBUFFER, dst.frameBufferId);
}
public static void streak(PoseStack ms, float angle, int x, int y, int breadth, int length) {
streak(ms, angle, x, y, breadth, length, Theme.i(Theme.Key.STREAK));
}
// angle in degrees; 0° -> fading to the right
// x and y specify the middle point of the starting edge
// breadth is the total width of the streak
public static void streak(PoseStack ms, float angle, int x, int y, int breadth, int length, int color) {
int a1 = 0xa0 << 24;
int a2 = 0x80 << 24;
int a3 = 0x10 << 24;
int a4 = 0x00 << 24;
color &= 0x00FFFFFF;
int c1 = a1 | color;
int c2 = a2 | color;
int c3 = a3 | color;
int c4 = a4 | color;
ms.pushPose();
ms.translate(x, y, 0);
ms.mulPose(Vector3f.ZP.rotationDegrees(angle - 90));
streak(ms, breadth / 2, length, c1, c2, c3, c4);
ms.popPose();
}
public static void streak(PoseStack ms, float angle, int x, int y, int breadth, int length, Color c) {
Color color = c.copy().setImmutable();
int c1 = color.scaleAlpha(0.625f).getRGB();
int c2 = color.scaleAlpha(0.5f).getRGB();
int c3 = color.scaleAlpha(0.0625f).getRGB();
int c4 = color.scaleAlpha(0f).getRGB();
ms.pushPose();
ms.translate(x, y, 0);
ms.mulPose(Vector3f.ZP.rotationDegrees(angle - 90));
streak(ms, breadth / 2, length, c1, c2, c3, c4);
ms.popPose();
}
private static void streak(PoseStack ms, int width, int height, int c1, int c2, int c3, int c4) {
double split1 = .5;
double split2 = .75;
Matrix4f model = ms.last().pose();
ScreenUtils.drawGradientRect(model, 0, -width, 0, width, (int) (split1 * height), c1, c2);
ScreenUtils.drawGradientRect(model, 0, -width, (int) (split1 * height), width, (int) (split2 * height), c2, c3);
ScreenUtils.drawGradientRect(model, 0, -width, (int) (split2 * height), width, height, c3, c4);
}
/**
* @see #angledGradient(MatrixStack, float, int, int, int, int, int, Color, Color)
*/
public static void angledGradient(@Nonnull PoseStack ms, float angle, int x, int y, int breadth, int length, Couple<Color> c) {
angledGradient(ms, angle, x, y, 0, breadth, length, c);
}
/**
* @see #angledGradient(MatrixStack, float, int, int, int, int, int, Color, Color)
*/
public static void angledGradient(@Nonnull PoseStack ms, float angle, int x, int y, int z, int breadth, int length, Couple<Color> c) {
angledGradient(ms, angle, x, y, z, breadth, length, c.getFirst(), c.getSecond());
}
/**
* @see #angledGradient(MatrixStack, float, int, int, int, int, int, Color, Color)
*/
public static void angledGradient(@Nonnull PoseStack ms, float angle, int x, int y, int breadth, int length, Color color1, Color color2) {
angledGradient(ms, angle, x, y, 0, breadth, length, color1, color2);
}
/**
* x and y specify the middle point of the starting edge
*
* @param angle the angle of the gradient in degrees; 0° means from left to right
* @param color1 the color at the starting edge
* @param color2 the color at the ending edge
* @param breadth the total width of the gradient
*/
public static void angledGradient(@Nonnull PoseStack ms, float angle, int x, int y, int z, int breadth, int length, Color color1, Color color2) {
ms.pushPose();
ms.translate(x, y, z);
ms.mulPose(Vector3f.ZP.rotationDegrees(angle - 90));
Matrix4f model = ms.last().pose();
int w = breadth / 2;
ScreenUtils.drawGradientRect(model, 0, -w, 0, w, length, color1.getRGB(), color2.getRGB());
ms.popPose();
}
public static void breadcrumbArrow(PoseStack matrixStack, int x, int y, int z, int width, int height, int indent, Couple<Color> colors) {breadcrumbArrow(matrixStack, x, y, z, width, height, indent, colors.getFirst(), colors.getSecond());}
// draws a wide chevron-style breadcrumb arrow pointing left
public static void breadcrumbArrow(PoseStack matrixStack, int x, int y, int z, int width, int height, int indent, Color startColor, Color endColor) {
matrixStack.pushPose();
matrixStack.translate(x - indent, y, z);
breadcrumbArrow(matrixStack, width, height, indent, startColor, endColor);
matrixStack.popPose();
}
private static void breadcrumbArrow(PoseStack ms, int width, int height, int indent, Color c1, Color c2) {
/*
* 0,0 x1,y1 ********************* x4,y4 ***** x7,y7
* **** ****
* **** ****
* x0,y0 x2,y2 x5,y5
* **** ****
* **** ****
* x3,y3 ********************* x6,y6 ***** x8,y8
*
*/
float x0 = 0, y0 = height / 2f;
float x1 = indent, y1 = 0;
float x2 = indent, y2 = height / 2f;
float x3 = indent, y3 = height;
float x4 = width, y4 = 0;
float x5 = width, y5 = height / 2f;
float x6 = width, y6 = height;
float x7 = indent + width, y7 = 0;
float x8 = indent + width, y8 = height;
indent = Math.abs(indent);
width = Math.abs(width);
Color fc1 = Color.mixColors(c1, c2, 0);
Color fc2 = Color.mixColors(c1, c2, (indent) / (width + 2f * indent));
Color fc3 = Color.mixColors(c1, c2, (indent + width) / (width + 2f * indent));
Color fc4 = Color.mixColors(c1, c2, 1);
RenderSystem.disableTexture();
RenderSystem.enableBlend();
RenderSystem.disableCull();
RenderSystem.defaultBlendFunc();
RenderSystem.setShader(GameRenderer::getPositionColorShader);
Tesselator tessellator = Tesselator.getInstance();
BufferBuilder bufferbuilder = tessellator.getBuilder();
Matrix4f model = ms.last().pose();
bufferbuilder.begin(VertexFormat.Mode.TRIANGLES, DefaultVertexFormat.POSITION_COLOR);
bufferbuilder.vertex(model, x0, y0, 0).color(fc1.getRed(), fc1.getGreen(), fc1.getBlue(), fc1.getAlpha()).endVertex();
bufferbuilder.vertex(model, x1, y1, 0).color(fc2.getRed(), fc2.getGreen(), fc2.getBlue(), fc2.getAlpha()).endVertex();
bufferbuilder.vertex(model, x2, y2, 0).color(fc2.getRed(), fc2.getGreen(), fc2.getBlue(), fc2.getAlpha()).endVertex();
bufferbuilder.vertex(model, x0, y0, 0).color(fc1.getRed(), fc1.getGreen(), fc1.getBlue(), fc1.getAlpha()).endVertex();
bufferbuilder.vertex(model, x2, y2, 0).color(fc2.getRed(), fc2.getGreen(), fc2.getBlue(), fc2.getAlpha()).endVertex();
bufferbuilder.vertex(model, x3, y3, 0).color(fc2.getRed(), fc2.getGreen(), fc2.getBlue(), fc2.getAlpha()).endVertex();
bufferbuilder.vertex(model, x3, y3, 0).color(fc2.getRed(), fc2.getGreen(), fc2.getBlue(), fc2.getAlpha()).endVertex();
bufferbuilder.vertex(model, x1, y1, 0).color(fc2.getRed(), fc2.getGreen(), fc2.getBlue(), fc2.getAlpha()).endVertex();
bufferbuilder.vertex(model, x4, y4, 0).color(fc3.getRed(), fc3.getGreen(), fc3.getBlue(), fc3.getAlpha()).endVertex();
bufferbuilder.vertex(model, x3, y3, 0).color(fc2.getRed(), fc2.getGreen(), fc2.getBlue(), fc2.getAlpha()).endVertex();
bufferbuilder.vertex(model, x4, y4, 0).color(fc3.getRed(), fc3.getGreen(), fc3.getBlue(), fc3.getAlpha()).endVertex();
bufferbuilder.vertex(model, x6, y6, 0).color(fc3.getRed(), fc3.getGreen(), fc3.getBlue(), fc3.getAlpha()).endVertex();
bufferbuilder.vertex(model, x5, y5, 0).color(fc3.getRed(), fc3.getGreen(), fc3.getBlue(), fc3.getAlpha()).endVertex();
bufferbuilder.vertex(model, x4, y4, 0).color(fc3.getRed(), fc3.getGreen(), fc3.getBlue(), fc3.getAlpha()).endVertex();
bufferbuilder.vertex(model, x7, y7, 0).color(fc4.getRed(), fc4.getGreen(), fc4.getBlue(), fc4.getAlpha()).endVertex();
bufferbuilder.vertex(model, x6, y6, 0).color(fc3.getRed(), fc3.getGreen(), fc3.getBlue(), fc3.getAlpha()).endVertex();
bufferbuilder.vertex(model, x5, y5, 0).color(fc3.getRed(), fc3.getGreen(), fc3.getBlue(), fc3.getAlpha()).endVertex();
bufferbuilder.vertex(model, x8, y8, 0).color(fc4.getRed(), fc4.getGreen(), fc4.getBlue(), fc4.getAlpha()).endVertex();
tessellator.end();
RenderSystem.enableCull();
RenderSystem.disableBlend();
RenderSystem.enableTexture();
}
//just like AbstractGui#drawTexture, but with a color at every vertex
public static void drawColoredTexture(PoseStack ms, Color c, int x, int y, int tex_left, int tex_top, int width, int height) {
drawColoredTexture(ms, c, x, y, 0, (float) tex_left, (float) tex_top, width, height, 256, 256);
}
public static void drawColoredTexture(PoseStack ms, 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(ms, c, x, x + width, y, y + height, z, width, height, tex_left, tex_top, sheet_width, sheet_height);
}
public static void drawStretched(PoseStack ms, int left, int top, int w, int h, int z, AllGuiTextures tex) {
tex.bind();
drawTexturedQuad(ms.last()
.pose(), Color.WHITE, left, left + w, top, top + h, z, tex.startX / 256f, (tex.startX + tex.width) / 256f,
tex.startY / 256f, (tex.startY + tex.height) / 256f);
}
private static void drawColoredTexture(PoseStack ms, 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(ms.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 void flipForGuiRender(PoseStack poseStack) {
poseStack.mulPoseMatrix(Matrix4f.createScaleMatrix(1, -1, 1));
}
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, 0, 0, 0);
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) viewWidth / (float) width;
float ty = (float) viewHeight / (float) height;
RenderSystem.enableTexture();
RenderSystem.enableDepthTest();
RenderSystem.setShader(() -> Minecraft.getInstance().gameRenderer.blitShader);
RenderSystem.getShader().setSampler("DiffuseSampler", colorTextureId);
bindRead();
Tesselator tessellator = Tesselator.getInstance();
BufferBuilder bufferbuilder = tessellator.getBuilder();
bufferbuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR_TEX);
bufferbuilder.vertex(0, vy, 0).color(1, 1, 1, alpha).uv(0, 0).endVertex();
bufferbuilder.vertex(vx, vy, 0).color(1, 1, 1, alpha).uv(tx, 0).endVertex();
bufferbuilder.vertex(vx, 0, 0).color(1, 1, 1, alpha).uv(tx, ty).endVertex();
bufferbuilder.vertex(0, 0, 0).color(1, 1, 1, alpha).uv(0, ty).endVertex();
tessellator.end();
unbindRead();
}
}
}

View File

@@ -1,12 +1,12 @@
package nl.requios.effortlessbuilding.create.foundation.gui.container; package nl.requios.effortlessbuilding.create.foundation.gui.container;
import com.mojang.blaze3d.platform.InputConstants; import com.mojang.blaze3d.platform.InputConstants;
import com.mojang.blaze3d.vertex.PoseStack; import net.createmod.catnip.animation.AnimationTickHolder;
import nl.requios.effortlessbuilding.create.foundation.gui.AllGuiTextures; import net.createmod.catnip.gui.TickableGuiEventListener;
import nl.requios.effortlessbuilding.create.foundation.gui.TickableGuiEventListener; import net.minecraft.client.gui.GuiGraphics;
import nl.requios.effortlessbuilding.create.foundation.gui.widget.AbstractSimiWidget;
import net.minecraft.client.gui.components.AbstractWidget; import net.minecraft.client.gui.components.AbstractWidget;
import net.minecraft.client.gui.components.Widget; 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.components.events.GuiEventListener;
import net.minecraft.client.gui.narration.NarratableEntry; import net.minecraft.client.gui.narration.NarratableEntry;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
@@ -15,8 +15,9 @@ import net.minecraft.client.renderer.Rect2i;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraftforge.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.neoforged.api.distmarker.OnlyIn;
import nl.requios.effortlessbuilding.create.foundation.gui.widget.AbstractSimiWidget;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
import java.util.Collection; import java.util.Collection;
@@ -66,13 +67,13 @@ public abstract class AbstractSimiContainerScreen<T extends AbstractContainerMen
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected <W extends GuiEventListener & Widget & NarratableEntry> void addRenderableWidgets(W... widgets) { protected <W extends GuiEventListener & Renderable & NarratableEntry> void addRenderableWidgets(W... widgets) {
for (W widget : widgets) { for (W widget : widgets) {
addRenderableWidget(widget); addRenderableWidget(widget);
} }
} }
protected <W extends GuiEventListener & Widget & NarratableEntry> void addRenderableWidgets(Collection<W> widgets) { protected <W extends GuiEventListener & Renderable & NarratableEntry> void addRenderableWidgets(Collection<W> widgets) {
for (W widget : widgets) { for (W widget : widgets) {
addRenderableWidget(widget); addRenderableWidget(widget);
} }
@@ -91,34 +92,32 @@ public abstract class AbstractSimiContainerScreen<T extends AbstractContainerMen
} }
@Override @Override
public void render(PoseStack matrixStack, int mouseX, int mouseY, float partialTicks) { public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
partialTicks = minecraft.getFrameTime(); partialTicks = AnimationTickHolder.getPartialTicksUI();
renderBackground(matrixStack); super.render(graphics, mouseX, mouseY, partialTicks);
super.render(matrixStack, mouseX, mouseY, partialTicks); renderForeground(graphics, mouseX, mouseY, partialTicks);
renderForeground(matrixStack, mouseX, mouseY, partialTicks);
} }
@Override @Override
protected void renderLabels(PoseStack poseStack, int mouseX, int mouseY) { protected void renderLabels(GuiGraphics graphics, int mouseX, int mouseY) {
// no-op to prevent screen- and inventory-title from being rendered at incorrect // no-op to prevent screen- and inventory-title from being rendered at incorrect
// location // location
// could also set this.titleX/Y and this.playerInventoryTitleX/Y to the proper // could also set this.titleX/Y and this.playerInventoryTitleX/Y to the proper
// values instead // values instead
} }
protected void renderForeground(PoseStack ms, int mouseX, int mouseY, float partialTicks) { protected void renderForeground(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
renderTooltip(ms, mouseX, mouseY); renderTooltip(graphics, mouseX, mouseY);
for (Widget widget : renderables) { for (Renderable widget : renderables) {
if (widget instanceof AbstractSimiWidget simiWidget && simiWidget.isHoveredOrFocused()) { if (widget instanceof AbstractSimiWidget simiWidget && simiWidget.isMouseOver(mouseX, mouseY)) {
List<Component> tooltip = simiWidget.getToolTip(); List<Component> tooltip = simiWidget.getToolTip();
if (tooltip.isEmpty()) if (tooltip.isEmpty())
continue; continue;
int ttx = simiWidget.lockedTooltipX == -1 ? mouseX : simiWidget.lockedTooltipX + simiWidget.x; int ttx = simiWidget.lockedTooltipX == -1 ? mouseX : simiWidget.lockedTooltipX + simiWidget.getX();
int tty = simiWidget.lockedTooltipY == -1 ? mouseY : simiWidget.lockedTooltipY + simiWidget.y; int tty = simiWidget.lockedTooltipY == -1 ? mouseY : simiWidget.lockedTooltipY + simiWidget.getY();
renderComponentTooltip(ms, tooltip, ttx, tty); graphics.renderComponentTooltip(font, tooltip, ttx, tty);
} }
} }
} }
@@ -127,19 +126,26 @@ public abstract class AbstractSimiContainerScreen<T extends AbstractContainerMen
return leftPos - windowXOffset + (imageWidth - textureWidth) / 2; return leftPos - windowXOffset + (imageWidth - textureWidth) / 2;
} }
// public void renderPlayerInventory(PoseStack ms, int x, int y) { // public void renderPlayerInventory(GuiGraphics graphics, int x, int y) {
// AllGuiTextures.PLAYER_INVENTORY.render(ms, x, y, this); // AllGuiTextures.PLAYER_INVENTORY.render(graphics, x, y);
// font.draw(ms, playerInventoryTitle, x + 8, y + 6, 0x404040); // graphics.drawString(font, playerInventoryTitle, x + 8, y + 6, 0x404040, false);
// } // }
@Override @Override
public boolean keyPressed(int pKeyCode, int pScanCode, int pModifiers) { public boolean keyPressed(int pKeyCode, int pScanCode, int pModifiers) {
InputConstants.Key mouseKey = InputConstants.getKey(pKeyCode, pScanCode); InputConstants.Key mouseKey = InputConstants.getKey(pKeyCode, pScanCode);
if (getFocused() != null && this.minecraft.options.keyInventory.isActiveAndMatches(mouseKey)) if (getFocused() instanceof EditBox && this.minecraft.options.keyInventory.isActiveAndMatches(mouseKey))
return false; return false;
return super.keyPressed(pKeyCode, pScanCode, pModifiers); 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 @Override
public GuiEventListener getFocused() { public GuiEventListener getFocused() {
GuiEventListener focused = super.getFocused(); GuiEventListener focused = super.getFocused();
@@ -160,14 +166,14 @@ public abstract class AbstractSimiContainerScreen<T extends AbstractContainerMen
} }
@Deprecated @Deprecated
protected void debugWindowArea(PoseStack matrixStack) { protected void debugWindowArea(GuiGraphics graphics) {
fill(matrixStack, leftPos + imageWidth, topPos + imageHeight, leftPos, topPos, 0xD3D3D3D3); graphics.fill(leftPos + imageWidth, topPos + imageHeight, leftPos, topPos, 0xD3D3D3D3);
} }
@Deprecated @Deprecated
protected void debugExtraAreas(PoseStack matrixStack) { protected void debugExtraAreas(GuiGraphics graphics) {
for (Rect2i area : getExtraAreas()) { for (Rect2i area : getExtraAreas()) {
fill(matrixStack, area.getX() + area.getWidth(), area.getY() + area.getHeight(), area.getX(), area.getY(), graphics.fill(area.getX() + area.getWidth(), area.getY() + area.getHeight(), area.getX(), area.getY(),
0xD3D3D3D3); 0xD3D3D3D3);
} }
} }

View File

@@ -1,35 +0,0 @@
package nl.requios.effortlessbuilding.create.foundation.gui.container;
import nl.requios.effortlessbuilding.create.foundation.networking.SimplePacketBase;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.network.NetworkEvent.Context;
import java.util.function.Supplier;
public class ClearContainerPacket extends SimplePacketBase {
public ClearContainerPacket() {}
public ClearContainerPacket(FriendlyByteBuf buffer) {}
@Override
public void write(FriendlyByteBuf buffer) {}
@Override
public void handle(Supplier<Context> context) {
context.get()
.enqueueWork(() -> {
ServerPlayer player = context.get()
.getSender();
if (player == null)
return;
if (!(player.containerMenu instanceof IClearableContainer))
return;
((IClearableContainer) player.containerMenu).clearContents();
});
context.get()
.setPacketHandled(true);
}
}

View File

@@ -7,18 +7,17 @@ import net.minecraft.world.inventory.ClickType;
import net.minecraft.world.inventory.MenuType; import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.inventory.Slot; import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraftforge.items.ItemHandlerHelper; import net.neoforged.neoforge.items.ItemStackHandler;
import net.minecraftforge.items.ItemStackHandler;
public abstract class GhostItemContainer<T> extends ContainerBase<T> implements IClearableContainer { public abstract class GhostItemMenu<T> extends MenuBase<T> implements IClearableMenu {
public ItemStackHandler ghostInventory; public ItemStackHandler ghostInventory;
protected GhostItemContainer(MenuType<?> type, int id, Inventory inv, FriendlyByteBuf extraData) { protected GhostItemMenu(MenuType<?> type, int id, Inventory inv, FriendlyByteBuf extraData) {
super(type, id, inv, extraData); super(type, id, inv, extraData);
} }
protected GhostItemContainer(MenuType<?> type, int id, Inventory inv, T contentHolder) { protected GhostItemMenu(MenuType<?> type, int id, Inventory inv, T contentHolder) {
super(type, id, inv, contentHolder); super(type, id, inv, contentHolder);
} }
@@ -88,7 +87,7 @@ public abstract class GhostItemContainer<T> extends ContainerBase<T> implements
ItemStack stackToInsert = playerInventory.getItem(index); ItemStack stackToInsert = playerInventory.getItem(index);
for (int i = 0; i < ghostInventory.getSlots(); i++) { for (int i = 0; i < ghostInventory.getSlots(); i++) {
ItemStack stack = ghostInventory.getStackInSlot(i); ItemStack stack = ghostInventory.getStackInSlot(i);
if (!allowRepeats() && ItemHandlerHelper.canItemStacksStack(stack, stackToInsert)) if (!allowRepeats() && ItemStack.isSameItemSameComponents(stack, stackToInsert))
break; break;
if (stack.isEmpty()) { if (stack.isEmpty()) {
ItemStack copy = stackToInsert.copy(); ItemStack copy = stackToInsert.copy();

View File

@@ -1,52 +0,0 @@
package nl.requios.effortlessbuilding.create.foundation.gui.container;
import nl.requios.effortlessbuilding.create.foundation.networking.SimplePacketBase;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.network.NetworkEvent.Context;
import java.util.function.Supplier;
public class GhostItemSubmitPacket extends SimplePacketBase {
private final ItemStack item;
private final int slot;
public GhostItemSubmitPacket(ItemStack item, int slot) {
this.item = item;
this.slot = slot;
}
public GhostItemSubmitPacket(FriendlyByteBuf buffer) {
item = buffer.readItem();
slot = buffer.readInt();
}
@Override
public void write(FriendlyByteBuf buffer) {
buffer.writeItem(item);
buffer.writeInt(slot);
}
@Override
public void handle(Supplier<Context> context) {
context.get()
.enqueueWork(() -> {
ServerPlayer player = context.get()
.getSender();
if (player == null)
return;
if (player.containerMenu instanceof GhostItemContainer) {
GhostItemContainer<?> c = (GhostItemContainer<?>) player.containerMenu;
c.ghostInventory.setStackInSlot(slot, item);
c.getSlot(36 + slot).setChanged();
}
});
context.get()
.setPacketHandled(true);
}
}

View File

@@ -1,14 +0,0 @@
package nl.requios.effortlessbuilding.create.foundation.gui.container;
//import nl.requios.effortlessbuilding.create.foundation.networking.AllPackets;
public interface IClearableContainer {
default void sendClearPacket() {
// AllPackets.channel.sendToServer(new ClearContainerPacket());
}
@Deprecated //warning: does not work
public void clearContents();
}

View File

@@ -0,0 +1,11 @@
package nl.requios.effortlessbuilding.create.foundation.gui.container;
public interface IClearableMenu {
default void sendClearPacket() {
// PacketDistributor.SERVER.noArg().send(new ClearMenuPacket());
}
public void clearContents();
}

View File

@@ -1,27 +1,27 @@
package nl.requios.effortlessbuilding.create.foundation.gui.container; package nl.requios.effortlessbuilding.create.foundation.gui.container;
import nl.requios.effortlessbuilding.create.foundation.utility.IInteractionChecker;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.MenuType; import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.inventory.Slot; import net.minecraft.world.inventory.Slot;
import net.minecraftforge.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.neoforged.api.distmarker.OnlyIn;
import nl.requios.effortlessbuilding.create.foundation.utility.IInteractionChecker;
public abstract class ContainerBase<T> extends AbstractContainerMenu { public abstract class MenuBase<T> extends AbstractContainerMenu {
public Player player; public Player player;
public Inventory playerInventory; public Inventory playerInventory;
public T contentHolder; public T contentHolder;
protected ContainerBase(MenuType<?> type, int id, Inventory inv, FriendlyByteBuf extraData) { protected MenuBase(MenuType<?> type, int id, Inventory inv, FriendlyByteBuf extraData) {
super(type, id); super(type, id);
init(inv, createOnClient(extraData)); init(inv, createOnClient(extraData));
} }
protected ContainerBase(MenuType<?> type, int id, Inventory inv, T contentHolder) { protected MenuBase(MenuType<?> type, int id, Inventory inv, T contentHolder) {
super(type, id); super(type, id);
init(inv, contentHolder); init(inv, contentHolder);
} }

View File

@@ -1,153 +0,0 @@
package nl.requios.effortlessbuilding.create.foundation.gui.element;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.*;
import com.mojang.math.Matrix4f;
import nl.requios.effortlessbuilding.create.foundation.utility.Color;
import nl.requios.effortlessbuilding.create.foundation.utility.Couple;
import net.minecraft.client.renderer.GameRenderer;
public class BoxElement extends RenderElement {
protected Color background = new Color(0xff000000, true);
protected Color borderTop = new Color(0x40ffeedd, true);
protected Color borderBot = new Color(0x20ffeedd, true);
protected int borderOffset = 2;
public <T extends BoxElement> T withBackground(Color color) {
this.background = color;
//noinspection unchecked
return (T) this;
}
public <T extends BoxElement> T withBackground(int color) {
return withBackground(new Color(color, true));
}
public <T extends BoxElement> T flatBorder(Color color) {
this.borderTop = color;
this.borderBot = color;
//noinspection unchecked
return (T) this;
}
public <T extends BoxElement> T flatBorder(int color) {
return flatBorder(new Color(color, true));
}
public <T extends BoxElement> T gradientBorder(Couple<Color> colors) {
this.borderTop = colors.getFirst();
this.borderBot = colors.getSecond();
//noinspection unchecked
return (T) this;
}
public <T extends BoxElement> T gradientBorder(Color top, Color bot) {
this.borderTop = top;
this.borderBot = bot;
//noinspection unchecked
return (T) this;
}
public <T extends BoxElement> T gradientBorder(int top, int bot) {
return gradientBorder(new Color(top, true), new Color(bot, true));
}
public <T extends BoxElement> T withBorderOffset(int offset) {
this.borderOffset = offset;
//noinspection unchecked
return (T) this;
}
@Override
public void render(PoseStack ms) {
renderBox(ms);
}
//total box width = 1 * 2 (outer border) + 1 * 2 (inner color border) + 2 * borderOffset + width
//defaults to 2 + 2 + 4 + 16 = 24px
//batch everything together to save a bunch of gl calls over ScreenUtils
protected void renderBox(PoseStack ms) {
/*
* _____________
* _|_____________|_
* | | ___________ | |
* | | | | | | |
* | | | | | | |
* | | |--* | | | |
* | | | h | | |
* | | | --w-+ | | |
* | | | | | |
* | | |_________| | |
* |_|_____________|_|
* |_____________|
*
* */
RenderSystem.disableTexture();
RenderSystem.enableBlend();
RenderSystem.defaultBlendFunc();
RenderSystem.setShader(GameRenderer::getPositionColorShader);
Matrix4f model = ms.last().pose();
int f = borderOffset;
Color c1 = background.copy().scaleAlpha(alpha);
Color c2 = borderTop.copy().scaleAlpha(alpha);
Color c3 = borderBot.copy().scaleAlpha(alpha);
Tesselator tessellator = Tesselator.getInstance();
BufferBuilder b = tessellator.getBuilder();
b.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR);
//outer top
b.vertex(model, x - f - 1 , y - f - 2 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
b.vertex(model, x - f - 1 , y - f - 1 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
b.vertex(model, x + f + 1 + width, y - f - 1 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
b.vertex(model, x + f + 1 + width, y - f - 2 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
//outer left
b.vertex(model, x - f - 2 , y - f - 1 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
b.vertex(model, x - f - 2 , y + f + 1 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
b.vertex(model, x - f - 1 , y + f + 1 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
b.vertex(model, x - f - 1 , y - f - 1 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
//outer bottom
b.vertex(model, x - f - 1 , y + f + 1 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
b.vertex(model, x - f - 1 , y + f + 2 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
b.vertex(model, x + f + 1 + width, y + f + 2 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
b.vertex(model, x + f + 1 + width, y + f + 1 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
//outer right
b.vertex(model, x + f + 1 + width, y - f - 1 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
b.vertex(model, x + f + 1 + width, y + f + 1 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
b.vertex(model, x + f + 2 + width, y + f + 1 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
b.vertex(model, x + f + 2 + width, y - f - 1 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
//inner background - also render behind the inner edges
b.vertex(model, x - f - 1 , y - f - 1 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
b.vertex(model, x - f - 1 , y + f + 1 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
b.vertex(model, x + f + 1 + width, y + f + 1 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
b.vertex(model, x + f + 1 + width, y - f - 1 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
tessellator.end();
b.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR);
//inner top - includes corners
b.vertex(model, x - f - 1 , y - f - 1 , z).color(c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha()).endVertex();
b.vertex(model, x - f - 1 , y - f , z).color(c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha()).endVertex();
b.vertex(model, x + f + 1 + width, y - f , z).color(c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha()).endVertex();
b.vertex(model, x + f + 1 + width, y - f - 1 , z).color(c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha()).endVertex();
//inner left - excludes corners
b.vertex(model, x - f - 1 , y - f , z).color(c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha()).endVertex();
b.vertex(model, x - f - 1 , y + f + height, z).color(c3.getRed(), c3.getGreen(), c3.getBlue(), c3.getAlpha()).endVertex();
b.vertex(model, x - f , y + f + height, z).color(c3.getRed(), c3.getGreen(), c3.getBlue(), c3.getAlpha()).endVertex();
b.vertex(model, x - f , y - f , z).color(c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha()).endVertex();
//inner bottom - includes corners
b.vertex(model, x - f - 1 , y + f + height, z).color(c3.getRed(), c3.getGreen(), c3.getBlue(), c3.getAlpha()).endVertex();
b.vertex(model, x - f - 1 , y + f + 1 + height, z).color(c3.getRed(), c3.getGreen(), c3.getBlue(), c3.getAlpha()).endVertex();
b.vertex(model, x + f + 1 + width, y + f + 1 + height, z).color(c3.getRed(), c3.getGreen(), c3.getBlue(), c3.getAlpha()).endVertex();
b.vertex(model, x + f + 1 + width, y + f + height, z).color(c3.getRed(), c3.getGreen(), c3.getBlue(), c3.getAlpha()).endVertex();
//inner right - excludes corners
b.vertex(model, x + f + width, y - f , z).color(c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha()).endVertex();
b.vertex(model, x + f + width, y + f + height, z).color(c3.getRed(), c3.getGreen(), c3.getBlue(), c3.getAlpha()).endVertex();
b.vertex(model, x + f + 1 + width, y + f + height, z).color(c3.getRed(), c3.getGreen(), c3.getBlue(), c3.getAlpha()).endVertex();
b.vertex(model, x + f + 1 + width, y - f , z).color(c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha()).endVertex();
tessellator.end();
RenderSystem.disableBlend();
RenderSystem.enableTexture();
}
}

View File

@@ -1,79 +0,0 @@
package nl.requios.effortlessbuilding.create.foundation.gui.element;
import com.mojang.blaze3d.vertex.PoseStack;
import javax.annotation.Nonnull;
public class CombinedStencilElement extends StencilElement {
private StencilElement element1;
private StencilElement element2;
private ElementMode mode;
private CombinedStencilElement() {}
public static CombinedStencilElement of(@Nonnull StencilElement element1, @Nonnull StencilElement element2) {
return of(element1, element2, ElementMode.FIRST);
}
public static CombinedStencilElement of(@Nonnull StencilElement element1, @Nonnull StencilElement element2, ElementMode mode) {
CombinedStencilElement e = new CombinedStencilElement();
e.element1 = element1;
e.element2 = element2;
e.mode = mode;
return e;
}
public <T extends CombinedStencilElement> T withFirst(StencilElement element) {
this.element1 = element;
//noinspection unchecked
return (T) this;
}
public <T extends CombinedStencilElement> T withSecond(StencilElement element) {
this.element2 = element;
//noinspection unchecked
return (T) this;
}
public <T extends CombinedStencilElement> T withMode(ElementMode mode) {
this.mode = mode;
//noinspection unchecked
return (T) this;
}
@Override
protected void renderStencil(PoseStack ms) {
ms.pushPose();
element1.transform(ms);
element1.withBounds(width, height);
element1.renderStencil(ms);
ms.popPose();
ms.pushPose();
element2.transform(ms);
element2.withBounds(width, height);
element2.renderStencil(ms);
ms.popPose();
}
@Override
protected void renderElement(PoseStack ms) {
if (mode.rendersFirst())
element1.<StencilElement>withBounds(width, height).renderElement(ms);
if (mode.rendersSecond())
element2.<StencilElement>withBounds(width, height).renderElement(ms);
}
public enum ElementMode {
FIRST, SECOND, BOTH;
boolean rendersFirst() {
return this == FIRST || this == BOTH;
}
boolean rendersSecond() {
return this == SECOND || this == BOTH;
}
}
}

View File

@@ -1,52 +0,0 @@
package nl.requios.effortlessbuilding.create.foundation.gui.element;
import com.mojang.blaze3d.vertex.PoseStack;
import nl.requios.effortlessbuilding.create.foundation.gui.UIRenderHelper;
import nl.requios.effortlessbuilding.create.foundation.utility.Color;
public class DelegatedStencilElement extends StencilElement {
protected static final ElementRenderer EMPTY_RENDERER = (ms, width, height, alpha) -> {};
protected static final ElementRenderer DEFAULT_ELEMENT = (ms, width, height, alpha) -> UIRenderHelper.angledGradient(ms, 0, -3, 5, height+4, width+6, new Color(0xff_10dd10).scaleAlpha(alpha), new Color(0xff_1010dd).scaleAlpha(alpha));
protected ElementRenderer stencil;
protected ElementRenderer element;
public DelegatedStencilElement() {
stencil = EMPTY_RENDERER;
element = DEFAULT_ELEMENT;
}
public DelegatedStencilElement(ElementRenderer stencil, ElementRenderer element) {
this.stencil = stencil;
this.element = element;
}
public <T extends DelegatedStencilElement> T withStencilRenderer(ElementRenderer renderer) {
stencil = renderer;
//noinspection unchecked
return (T) this;
}
public <T extends DelegatedStencilElement> T withElementRenderer(ElementRenderer renderer) {
element = renderer;
//noinspection unchecked
return (T) this;
}
@Override
protected void renderStencil(PoseStack ms) {
stencil.render(ms, width, height, 1);
}
@Override
protected void renderElement(PoseStack ms) {
element.render(ms, width, height, alpha);
}
@FunctionalInterface
public interface ElementRenderer {
void render(PoseStack ms, int width, int height, float alpha);
}
}

View File

@@ -1,297 +0,0 @@
package nl.requios.effortlessbuilding.create.foundation.gui.element;
import com.jozufozu.flywheel.core.PartialModel;
import com.jozufozu.flywheel.core.model.ModelUtil;
import com.mojang.blaze3d.platform.GlStateManager.DestFactor;
import com.mojang.blaze3d.platform.GlStateManager.SourceFactor;
import com.mojang.blaze3d.platform.Lighting;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Vector3f;
//import nl.requios.effortlessbuilding.create.foundation.fluid.FluidRenderer;
import nl.requios.effortlessbuilding.create.foundation.gui.ILightingSettings;
import nl.requios.effortlessbuilding.create.foundation.gui.UIRenderHelper;
import nl.requios.effortlessbuilding.create.foundation.utility.Color;
import nl.requios.effortlessbuilding.create.foundation.utility.VecHelper;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.Sheets;
import net.minecraft.client.renderer.block.BlockRenderDispatcher;
import net.minecraft.client.renderer.block.model.ItemTransforms;
import net.minecraft.client.renderer.entity.ItemRenderer;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.core.BlockPos;
import net.minecraft.util.RandomSource;
import net.minecraft.world.inventory.InventoryMenu;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.block.BaseFireBlock;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.LiquidBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.client.RenderTypeHelper;
import net.minecraftforge.fluids.FluidStack;
import javax.annotation.Nullable;
public class GuiGameElement {
public static GuiRenderBuilder of(ItemStack stack) {
return new GuiItemRenderBuilder(stack);
}
public static GuiRenderBuilder of(ItemLike itemProvider) {
return new GuiItemRenderBuilder(itemProvider);
}
public static GuiRenderBuilder of(BlockState state) {
return new GuiBlockStateRenderBuilder(state);
}
public static GuiRenderBuilder of(PartialModel partial) {
return new GuiBlockPartialRenderBuilder(partial);
}
public static GuiRenderBuilder of(Fluid fluid) {
return new GuiBlockStateRenderBuilder(fluid.defaultFluidState()
.createLegacyBlock()
.setValue(LiquidBlock.LEVEL, 0));
}
public static abstract class GuiRenderBuilder extends RenderElement {
protected double xLocal, yLocal, zLocal;
protected double xRot, yRot, zRot;
protected double scale = 1;
protected int color = 0xFFFFFF;
protected Vec3 rotationOffset = Vec3.ZERO;
protected ILightingSettings customLighting = null;
public GuiRenderBuilder atLocal(double x, double y, double z) {
this.xLocal = x;
this.yLocal = y;
this.zLocal = z;
return this;
}
public GuiRenderBuilder rotate(double xRot, double yRot, double zRot) {
this.xRot = xRot;
this.yRot = yRot;
this.zRot = zRot;
return this;
}
public GuiRenderBuilder rotateBlock(double xRot, double yRot, double zRot) {
return this.rotate(xRot, yRot, zRot)
.withRotationOffset(VecHelper.getCenterOf(BlockPos.ZERO));
}
public GuiRenderBuilder scale(double scale) {
this.scale = scale;
return this;
}
public GuiRenderBuilder color(int color) {
this.color = color;
return this;
}
public GuiRenderBuilder withRotationOffset(Vec3 offset) {
this.rotationOffset = offset;
return this;
}
public GuiRenderBuilder lighting(ILightingSettings lighting) {
customLighting = lighting;
return this;
}
protected void prepareMatrix(PoseStack matrixStack) {
matrixStack.pushPose();
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
RenderSystem.enableDepthTest();
RenderSystem.enableBlend();
RenderSystem.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA);
prepareLighting(matrixStack);
}
protected void transformMatrix(PoseStack matrixStack) {
matrixStack.translate(x, y, z);
matrixStack.scale((float) scale, (float) scale, (float) scale);
matrixStack.translate(xLocal, yLocal, zLocal);
UIRenderHelper.flipForGuiRender(matrixStack);
matrixStack.translate(rotationOffset.x, rotationOffset.y, rotationOffset.z);
matrixStack.mulPose(Vector3f.ZP.rotationDegrees((float) zRot));
matrixStack.mulPose(Vector3f.XP.rotationDegrees((float) xRot));
matrixStack.mulPose(Vector3f.YP.rotationDegrees((float) yRot));
matrixStack.translate(-rotationOffset.x, -rotationOffset.y, -rotationOffset.z);
}
protected void cleanUpMatrix(PoseStack matrixStack) {
matrixStack.popPose();
cleanUpLighting(matrixStack);
}
protected void prepareLighting(PoseStack matrixStack) {
if (customLighting != null) {
customLighting.applyLighting();
} else {
Lighting.setupFor3DItems();
}
}
protected void cleanUpLighting(PoseStack matrixStack) {
if (customLighting != null) {
Lighting.setupFor3DItems();
}
}
}
private static class GuiBlockModelRenderBuilder extends GuiRenderBuilder {
protected BakedModel blockModel;
protected BlockState blockState;
public GuiBlockModelRenderBuilder(BakedModel blockmodel, @Nullable BlockState blockState) {
this.blockState = blockState == null ? Blocks.AIR.defaultBlockState() : blockState;
this.blockModel = blockmodel;
}
@Override
public void render(PoseStack matrixStack) {
prepareMatrix(matrixStack);
Minecraft mc = Minecraft.getInstance();
BlockRenderDispatcher blockRenderer = mc.getBlockRenderer();
MultiBufferSource.BufferSource buffer = mc.renderBuffers()
.bufferSource();
transformMatrix(matrixStack);
RenderSystem.setShaderTexture(0, InventoryMenu.BLOCK_ATLAS);
renderModel(blockRenderer, buffer, matrixStack);
cleanUpMatrix(matrixStack);
}
protected void renderModel(BlockRenderDispatcher blockRenderer, MultiBufferSource.BufferSource buffer,
PoseStack ms) {
if (blockState.getBlock() == Blocks.AIR) {
RenderType renderType = Sheets.translucentCullBlockSheet();
blockRenderer.getModelRenderer()
.renderModel(ms.last(), buffer.getBuffer(renderType), blockState, blockModel, 1, 1, 1,
LightTexture.FULL_BRIGHT, OverlayTexture.NO_OVERLAY, ModelUtil.VIRTUAL_DATA, null);
} else {
int color = Minecraft.getInstance()
.getBlockColors()
.getColor(blockState, null, null, 0);
Color rgb = new Color(color == -1 ? this.color : color);
for (RenderType chunkType : blockModel.getRenderTypes(blockState, RandomSource.create(42L), ModelUtil.VIRTUAL_DATA)) {
RenderType renderType = RenderTypeHelper.getEntityRenderType(chunkType, true);
blockRenderer.getModelRenderer()
.renderModel(ms.last(), buffer.getBuffer(renderType), blockState, blockModel,
rgb.getRedAsFloat(), rgb.getGreenAsFloat(), rgb.getBlueAsFloat(),
LightTexture.FULL_BRIGHT, OverlayTexture.NO_OVERLAY, ModelUtil.VIRTUAL_DATA, chunkType);
}
}
buffer.endBatch();
}
}
public static class GuiBlockStateRenderBuilder extends GuiBlockModelRenderBuilder {
public GuiBlockStateRenderBuilder(BlockState blockstate) {
super(Minecraft.getInstance()
.getBlockRenderer()
.getBlockModel(blockstate), blockstate);
}
@Override
protected void renderModel(BlockRenderDispatcher blockRenderer, MultiBufferSource.BufferSource buffer,
PoseStack ms) {
if (blockState.getBlock() instanceof BaseFireBlock) {
Lighting.setupForFlatItems();
super.renderModel(blockRenderer, buffer, ms);
Lighting.setupFor3DItems();
return;
}
super.renderModel(blockRenderer, buffer, ms);
if (blockState.getFluidState()
.isEmpty())
return;
// FluidRenderer.renderFluidBox(new FluidStack(blockState.getFluidState()
// .getType(), 1000), 0, 0, 0, 1, 1, 1, buffer, ms, LightTexture.FULL_BRIGHT, false);
// buffer.endBatch();
}
}
public static class GuiBlockPartialRenderBuilder extends GuiBlockModelRenderBuilder {
public GuiBlockPartialRenderBuilder(PartialModel partial) {
super(partial.get(), null);
}
}
public static class GuiItemRenderBuilder extends GuiRenderBuilder {
private final ItemStack stack;
public GuiItemRenderBuilder(ItemStack stack) {
this.stack = stack;
}
public GuiItemRenderBuilder(ItemLike provider) {
this(new ItemStack(provider));
}
@Override
public void render(PoseStack matrixStack) {
prepareMatrix(matrixStack);
transformMatrix(matrixStack);
renderItemIntoGUI(matrixStack, stack, customLighting == null);
cleanUpMatrix(matrixStack);
}
public static void renderItemIntoGUI(PoseStack matrixStack, ItemStack stack, boolean useDefaultLighting) {
ItemRenderer renderer = Minecraft.getInstance().getItemRenderer();
BakedModel bakedModel = renderer.getModel(stack, null, null, 0);
renderer.textureManager.getTexture(InventoryMenu.BLOCK_ATLAS).setFilter(false, false);
RenderSystem.setShaderTexture(0, InventoryMenu.BLOCK_ATLAS);
RenderSystem.enableBlend();
RenderSystem.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA);
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
matrixStack.pushPose();
matrixStack.translate(0, 0, 100.0F + renderer.blitOffset);
matrixStack.translate(8.0F, -8.0F, 0.0F);
matrixStack.scale(16.0F, 16.0F, 16.0F);
MultiBufferSource.BufferSource buffer = Minecraft.getInstance().renderBuffers().bufferSource();
boolean flatLighting = !bakedModel.usesBlockLight();
if (useDefaultLighting && flatLighting) {
Lighting.setupForFlatItems();
}
renderer.render(stack, ItemTransforms.TransformType.GUI, false, matrixStack, buffer, LightTexture.FULL_BRIGHT, OverlayTexture.NO_OVERLAY, bakedModel);
buffer.endBatch();
RenderSystem.enableDepthTest();
if (useDefaultLighting && flatLighting) {
Lighting.setupFor3DItems();
}
matrixStack.popPose();
}
}
}

View File

@@ -1,89 +0,0 @@
package nl.requios.effortlessbuilding.create.foundation.gui.element;
import com.mojang.blaze3d.vertex.PoseStack;
public abstract class RenderElement implements ScreenElement {
public static final RenderElement EMPTY = new RenderElement() {
@Override
public void render(PoseStack ms) {
}
};
public static RenderElement of(ScreenElement renderable) {
return new SimpleRenderElement(renderable);
}
protected int width = 16, height = 16;
protected float x = 0, y = 0, z = 0;
protected float alpha = 1f;
public <T extends RenderElement> T at(float x, float y) {
this.x = x;
this.y = y;
//noinspection unchecked
return (T) this;
}
public <T extends RenderElement> T at(float x, float y, float z) {
this.x = x;
this.y = y;
this.z = z;
//noinspection unchecked
return (T) this;
}
public <T extends RenderElement> T withBounds(int width, int height) {
this.width = width;
this.height = height;
//noinspection unchecked
return (T) this;
}
public <T extends RenderElement> T withAlpha(float alpha) {
this.alpha = alpha;
//noinspection unchecked
return (T) this;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public float getX() {
return x;
}
public float getY() {
return y;
}
public float getZ() {
return z;
}
public abstract void render(PoseStack ms);
@Override
public void render(PoseStack ms, int x, int y) {
this.at(x, y).render(ms);
}
public static class SimpleRenderElement extends RenderElement {
private ScreenElement renderable;
public SimpleRenderElement(ScreenElement renderable) {
this.renderable = renderable;
}
@Override
public void render(PoseStack ms) {
renderable.render(ms, (int) x, (int) y);
}
}
}

View File

@@ -1,12 +0,0 @@
package nl.requios.effortlessbuilding.create.foundation.gui.element;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
public interface ScreenElement {
@OnlyIn(Dist.CLIENT)
void render(PoseStack ms, int x, int y);
}

View File

@@ -1,50 +0,0 @@
package nl.requios.effortlessbuilding.create.foundation.gui.element;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft;
import org.lwjgl.opengl.GL11;
public abstract class StencilElement extends RenderElement {
@Override
public void render(PoseStack ms) {
ms.pushPose();
transform(ms);
prepareStencil(ms);
renderStencil(ms);
prepareElement(ms);
renderElement(ms);
cleanUp(ms);
ms.popPose();
}
protected abstract void renderStencil(PoseStack ms);
protected abstract void renderElement(PoseStack ms);
protected void transform(PoseStack ms) {
ms.translate(x, y, z);
}
protected void prepareStencil(PoseStack ms) {
GL11.glDisable(GL11.GL_STENCIL_TEST);
RenderSystem.stencilMask(~0);
RenderSystem.clear(GL11.GL_STENCIL_BUFFER_BIT, Minecraft.ON_OSX);
GL11.glEnable(GL11.GL_STENCIL_TEST);
RenderSystem.stencilOp(GL11.GL_REPLACE, GL11.GL_KEEP, GL11.GL_KEEP);
RenderSystem.stencilMask(0xFF);
RenderSystem.stencilFunc(GL11.GL_NEVER, 1, 0xFF);
}
protected void prepareElement(PoseStack ms) {
GL11.glEnable(GL11.GL_STENCIL_TEST);
RenderSystem.stencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_KEEP);
RenderSystem.stencilFunc(GL11.GL_EQUAL, 1, 0xFF);
}
protected void cleanUp(PoseStack ms) {
GL11.glDisable(GL11.GL_STENCIL_TEST);
}
}

View File

@@ -1,78 +0,0 @@
package nl.requios.effortlessbuilding.create.foundation.gui.element;
import com.mojang.blaze3d.vertex.PoseStack;
import nl.requios.effortlessbuilding.create.foundation.utility.Components;
import net.minecraft.client.gui.Font;
import net.minecraft.network.chat.MutableComponent;
public class TextStencilElement extends DelegatedStencilElement {
protected Font font;
protected MutableComponent component;
protected boolean centerVertically = false;
protected boolean centerHorizontally = false;
public TextStencilElement(Font font) {
super();
this.font = font;
height = 10;
}
public TextStencilElement(Font font, String text) {
this(font);
component = Components.literal(text);
}
public TextStencilElement(Font font, MutableComponent component) {
this(font);
this.component = component;
}
public TextStencilElement withText(String text) {
component = Components.literal(text);
return this;
}
public TextStencilElement withText(MutableComponent component) {
this.component = component;
return this;
}
public TextStencilElement centered(boolean vertical, boolean horizontal) {
this.centerVertically = vertical;
this.centerHorizontally = horizontal;
return this;
}
@Override
protected void renderStencil(PoseStack ms) {
float x = 0, y = 0;
if (centerHorizontally)
x = width / 2f - font.width(component) / 2f;
if (centerVertically)
y = height / 2f - (font.lineHeight - 1) / 2f;
font.draw(ms, component, x, y, 0xff_000000);
}
@Override
protected void renderElement(PoseStack ms) {
float x = 0, y = 0;
if (centerHorizontally)
x = width / 2f - font.width(component) / 2f;
if (centerVertically)
y = height / 2f - (font.lineHeight - 1) / 2f;
ms.pushPose();
ms.translate(x, y, 0);
element.render(ms, font.width(component), font.lineHeight + 2, alpha);
ms.popPose();
}
public MutableComponent getComponent() {
return component;
}
}

View File

@@ -1,11 +1,11 @@
package nl.requios.effortlessbuilding.create.foundation.gui.widget; package nl.requios.effortlessbuilding.create.foundation.gui.widget;
import com.mojang.blaze3d.vertex.PoseStack; import net.createmod.catnip.gui.TickableGuiEventListener;
import nl.requios.effortlessbuilding.create.foundation.gui.TickableGuiEventListener; import net.minecraft.client.gui.GuiGraphics;
import nl.requios.effortlessbuilding.create.foundation.utility.Components;
import net.minecraft.client.gui.components.AbstractWidget; import net.minecraft.client.gui.components.AbstractWidget;
import net.minecraft.client.gui.narration.NarrationElementOutput; import net.minecraft.client.gui.narration.NarrationElementOutput;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import nl.requios.effortlessbuilding.create.foundation.utility.Components;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.LinkedList; import java.util.LinkedList;
@@ -15,12 +15,13 @@ import java.util.function.BiConsumer;
public abstract class AbstractSimiWidget extends AbstractWidget implements TickableGuiEventListener { public abstract class AbstractSimiWidget extends AbstractWidget implements TickableGuiEventListener {
public static final int HEADER_RGB = 0x5391E1; public static final int HEADER_RGB = 0x5391E1;
public static final int HINT_RGB = 0x96B7E0;
protected float z; protected float z;
protected boolean wasHovered = false; protected boolean wasHovered = false;
protected List<Component> toolTip = new LinkedList<>(); protected List<Component> toolTip = new LinkedList<>();
protected BiConsumer<Integer, Integer> onClick = (_$, _$$) -> {}; protected BiConsumer<Integer, Integer> onClick = (_$, _$$) -> {};
public int lockedTooltipX = -1; public int lockedTooltipX = -1;
public int lockedTooltipY = -1; public int lockedTooltipY = -1;
@@ -36,6 +37,11 @@ public abstract class AbstractSimiWidget extends AbstractWidget implements Ticka
super(x, y, width, height, message); super(x, y, width, height, message);
} }
// @Override
// protected ClientTooltipPositioner createTooltipPositioner() {
// return DefaultTooltipPositioner.INSTANCE;
// }
public <T extends AbstractSimiWidget> T withCallback(BiConsumer<Integer, Integer> cb) { public <T extends AbstractSimiWidget> T withCallback(BiConsumer<Integer, Integer> cb) {
this.onClick = cb; this.onClick = cb;
//noinspection unchecked //noinspection unchecked
@@ -60,26 +66,22 @@ public abstract class AbstractSimiWidget extends AbstractWidget implements Ticka
public void tick() {} public void tick() {}
@Override @Override
public void render(@Nonnull PoseStack ms, int mouseX, int mouseY, float partialTicks) { public void renderWidget(@Nonnull GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
if (visible) { beforeRender(graphics, mouseX, mouseY, partialTicks);
isHovered = mouseX >= x && mouseY >= y && mouseX < x + width && mouseY < y + height; doRender(graphics, mouseX, mouseY, partialTicks);
beforeRender(ms, mouseX, mouseY, partialTicks); afterRender(graphics, mouseX, mouseY, partialTicks);
renderButton(ms, mouseX, mouseY, partialTicks); wasHovered = isHoveredOrFocused();
afterRender(ms, mouseX, mouseY, partialTicks);
wasHovered = isHoveredOrFocused();
}
} }
protected void beforeRender(@Nonnull PoseStack ms, int mouseX, int mouseY, float partialTicks) { protected void beforeRender(@Nonnull GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
ms.pushPose(); graphics.pose().pushPose();
} }
@Override protected void doRender(@Nonnull GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
public void renderButton(@Nonnull PoseStack ms, int mouseX, int mouseY, float partialTicks) {
} }
protected void afterRender(@Nonnull PoseStack ms, int mouseX, int mouseY, float partialTicks) { protected void afterRender(@Nonnull GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
ms.popPose(); graphics.pose().popPose();
} }
public void runCallback(double mouseX, double mouseY) { public void runCallback(double mouseX, double mouseY) {
@@ -92,7 +94,7 @@ public abstract class AbstractSimiWidget extends AbstractWidget implements Ticka
} }
@Override @Override
public void updateNarration(NarrationElementOutput pNarrationElementOutput) { public void updateWidgetNarration(NarrationElementOutput pNarrationElementOutput) {
defaultButtonNarrationText(pNarrationElementOutput); defaultButtonNarrationText(pNarrationElementOutput);
} }
} }

View File

@@ -1,228 +0,0 @@
package nl.requios.effortlessbuilding.create.foundation.gui.widget;
import com.mojang.blaze3d.vertex.PoseStack;
import nl.requios.effortlessbuilding.create.foundation.gui.Theme;
import nl.requios.effortlessbuilding.create.foundation.gui.Theme.Key;
import nl.requios.effortlessbuilding.create.foundation.gui.UIRenderHelper;
import nl.requios.effortlessbuilding.create.foundation.gui.element.BoxElement;
import nl.requios.effortlessbuilding.create.foundation.gui.element.DelegatedStencilElement;
import nl.requios.effortlessbuilding.create.foundation.utility.Color;
import nl.requios.effortlessbuilding.create.foundation.utility.Couple;
import nl.requios.effortlessbuilding.create.foundation.utility.animation.LerpedFloat;
import javax.annotation.Nonnull;
import java.util.function.Function;
public class BoxWidget extends ElementWidget {
public static final Function<BoxWidget, DelegatedStencilElement.ElementRenderer> gradientFactory = (box) -> (ms, w, h, alpha) -> UIRenderHelper.angledGradient(ms, 90, w/2, -2, w + 4, h + 4, box.gradientColor1, box.gradientColor2);
protected BoxElement box;
protected Color customBorderTop;
protected Color customBorderBot;
protected Color customBackground;
protected boolean animateColors = true;
protected LerpedFloat colorAnimation = LerpedFloat.linear();
protected Color gradientColor1, gradientColor2;
private Color previousColor1, previousColor2;
private Color colorTarget1 = Theme.c(getIdleTheme(), true).copy();
private Color colorTarget2 = Theme.c(getIdleTheme(), false).copy();
public BoxWidget() {
this(0, 0);
}
public BoxWidget(int x, int y) {
this(x, y, 16, 16);
}
public BoxWidget(int x, int y, int width, int height) {
super(x, y, width, height);
box = new BoxElement()
.at(x, y)
.withBounds(width, height);
gradientColor1 = colorTarget1;
gradientColor2 = colorTarget2;
}
public <T extends BoxWidget> T withBounds(int width, int height) {
this.width = width;
this.height = height;
//noinspection unchecked
return (T) this;
}
public <T extends BoxWidget> T withBorderColors(Couple<Color> colors) {
this.customBorderTop = colors.getFirst();
this.customBorderBot = colors.getSecond();
updateColorsFromState();
//noinspection unchecked
return (T) this;
}
public <T extends BoxWidget> T withBorderColors(Color top, Color bot) {
this.customBorderTop = top;
this.customBorderBot = bot;
updateColorsFromState();
//noinspection unchecked
return (T) this;
}
public <T extends BoxWidget> T withCustomBackground(Color color) {
this.customBackground = color;
//noinspection unchecked
return (T) this;
}
public <T extends BoxWidget> T animateColors(boolean b) {
this.animateColors = b;
//noinspection unchecked
return (T) this;
}
@Override
public void tick() {
super.tick();
colorAnimation.tickChaser();
}
@Override
public void onClick(double x, double y) {
super.onClick(x, y);
gradientColor1 = Theme.c(getClickTheme(), true);
gradientColor2 = Theme.c(getClickTheme(), false);
startGradientAnimation(getColorForState(true), getColorForState(false), true, 0.15);
}
@Override
protected void beforeRender(@Nonnull PoseStack ms, int mouseX, int mouseY, float partialTicks) {
super.beforeRender(ms, mouseX, mouseY, partialTicks);
if (isHovered != wasHovered) {
startGradientAnimation(
getColorForState(true),
getColorForState(false),
isHovered
);
}
if (colorAnimation.settled()) {
gradientColor1 = colorTarget1;
gradientColor2 = colorTarget2;
} else {
float animationValue = 1 - Math.abs(colorAnimation.getValue(partialTicks));
gradientColor1 = Color.mixColors(previousColor1, colorTarget1, animationValue);
gradientColor2 = Color.mixColors(previousColor2, colorTarget2, animationValue);
}
}
@Override
public void renderButton(@Nonnull PoseStack ms, int mouseX, int mouseY, float partialTicks) {
float fadeValue = fade.getValue(partialTicks);
if (fadeValue < .1f)
return;
box.withAlpha(fadeValue);
box.withBackground(customBackground != null ? customBackground : Theme.c(Theme.Key.PONDER_BACKGROUND_TRANSPARENT))
.gradientBorder(gradientColor1, gradientColor2)
.at(x, y, z)
.withBounds(width, height)
.render(ms);
super.renderButton(ms, mouseX, mouseY, partialTicks);
wasHovered = isHovered;
}
@Override
public boolean isMouseOver(double mX, double mY) {
if (!active || !visible)
return false;
float padX = 2 + paddingX;
float padY = 2 + paddingY;
return x - padX <= mX && y - padY <= mY && mX < x + padX + width && mY < y + padY + height;
}
@Override
protected boolean clicked(double pMouseX, double pMouseY) {
if (!active || !visible)
return false;
return isMouseOver(pMouseX, pMouseY);
}
public BoxElement getBox() {
return box;
}
public void updateColorsFromState() {
colorTarget1 = getColorForState(true);
colorTarget2 = getColorForState(false);
}
public void animateGradientFromState() {
startGradientAnimation(
getColorForState(true),
getColorForState(false),
true
);
}
private void startGradientAnimation(Color c1, Color c2, boolean positive, double expSpeed) {
if (!animateColors)
return;
colorAnimation.startWithValue(positive ? 1 : -1);
colorAnimation.chase(0, expSpeed, LerpedFloat.Chaser.EXP);
colorAnimation.tickChaser();
previousColor1 = gradientColor1;
previousColor2 = gradientColor2;
colorTarget1 = c1;
colorTarget2 = c2;
}
private void startGradientAnimation(Color c1, Color c2, boolean positive) {
startGradientAnimation(c1, c2, positive, 0.6);
}
private Color getColorForState(boolean first) {
if (!active)
return Theme.p(getDisabledTheme()).get(first);
if (isHovered) {
if (first)
return customBorderTop != null ? customBorderTop.darker() : Theme.c(getHoverTheme(), true);
else
return customBorderBot != null ? customBorderBot.darker() : Theme.c(getHoverTheme(), false);
}
if (first)
return customBorderTop != null ? customBorderTop : Theme.c(getIdleTheme(), true);
else
return customBorderBot != null ? customBorderBot : Theme.c(getIdleTheme(), false);
}
public Key getDisabledTheme() {
return Theme.Key.BUTTON_DISABLE;
}
public Key getIdleTheme() {
return Theme.Key.BUTTON_IDLE;
}
public Key getHoverTheme() {
return Theme.Key.BUTTON_HOVER;
}
public Key getClickTheme() {
return Theme.Key.BUTTON_CLICK;
}
}

View File

@@ -1,156 +0,0 @@
package nl.requios.effortlessbuilding.create.foundation.gui.widget;
import com.mojang.blaze3d.vertex.PoseStack;
import nl.requios.effortlessbuilding.create.foundation.gui.element.RenderElement;
import nl.requios.effortlessbuilding.create.foundation.gui.element.ScreenElement;
import nl.requios.effortlessbuilding.create.foundation.utility.animation.LerpedFloat;
import javax.annotation.Nonnull;
import java.util.function.Consumer;
import java.util.function.UnaryOperator;
public class ElementWidget extends AbstractSimiWidget {
protected RenderElement element = RenderElement.EMPTY;
protected boolean usesFade = false;
protected int fadeModX;
protected int fadeModY;
protected LerpedFloat fade = LerpedFloat.linear().startWithValue(1);
protected boolean rescaleElement = false;
protected float rescaleSizeX;
protected float rescaleSizeY;
protected float paddingX = 0;
protected float paddingY = 0;
public ElementWidget(int x, int y) {
super(x, y);
}
public ElementWidget(int x, int y, int width, int height) {
super(x, y, width, height);
}
public <T extends ElementWidget> T showingElement(RenderElement element) {
this.element = element;
//noinspection unchecked
return (T) this;
}
public <T extends ElementWidget> T showing(ScreenElement renderable) {
return this.showingElement(RenderElement.of(renderable));
}
public <T extends ElementWidget> T modifyElement(Consumer<RenderElement> consumer) {
if (element != null)
consumer.accept(element);
//noinspection unchecked
return (T) this;
}
public <T extends ElementWidget> T mapElement(UnaryOperator<RenderElement> function) {
if (element != null)
element = function.apply(element);
//noinspection unchecked
return (T) this;
}
public <T extends ElementWidget> T withPadding(float paddingX, float paddingY) {
this.paddingX = paddingX;
this.paddingY = paddingY;
//noinspection unchecked
return (T) this;
}
public <T extends ElementWidget> T enableFade(int fadeModifierX, int fadeModifierY) {
this.fade.startWithValue(0);
this.usesFade = true;
this.fadeModX = fadeModifierX;
this.fadeModY = fadeModifierY;
//noinspection unchecked
return (T) this;
}
public <T extends ElementWidget> T disableFade() {
this.fade.startWithValue(1);
this.usesFade = false;
//noinspection unchecked
return (T) this;
}
public LerpedFloat fade() {
return fade;
}
public <T extends ElementWidget> T fade(float target) {
fade.chase(target, 0.1, LerpedFloat.Chaser.EXP);
//noinspection unchecked
return (T) this;
}
/**
* Rescaling and its effects aren't properly tested with most elements.
* Thought it should work fine when using a TextStencilElement.
* Check BaseConfigScreen's title for such an example.
*/
@Deprecated
public <T extends ElementWidget> T rescaleElement(float rescaleSizeX, float rescaleSizeY) {
this.rescaleElement = true;
this.rescaleSizeX = rescaleSizeX;
this.rescaleSizeY = rescaleSizeY;
//noinspection unchecked
return (T) this;
}
public <T extends ElementWidget> T disableRescale() {
this.rescaleElement = false;
//noinspection unchecked
return (T) this;
}
@Override
public void tick() {
super.tick();
fade.tickChaser();
}
@Override
protected void beforeRender(@Nonnull PoseStack ms, int mouseX, int mouseY, float partialTicks) {
super.beforeRender(ms, mouseX, mouseY, partialTicks);
isHovered = isMouseOver(mouseX, mouseY);
float fadeValue = fade.getValue(partialTicks);
element.withAlpha(fadeValue);
if (fadeValue < 1) {
ms.translate((1 - fadeValue) * fadeModX, (1 - fadeValue) * fadeModY, 0);
}
}
@Override
public void renderButton(@Nonnull PoseStack ms, int mouseX, int mouseY, float partialTicks) {
ms.pushPose();
ms.translate(x + paddingX, y + paddingY, z);
float innerWidth = width - 2 * paddingX;
float innerHeight = height - 2 * paddingY;
float eX = element.getX(), eY = element.getY();
if (rescaleElement) {
float xScale = innerWidth / rescaleSizeX;
float yScale = innerHeight / rescaleSizeY;
ms.scale(xScale, yScale, 1);
element.at(eX / xScale, eY / yScale);
innerWidth /= xScale;
innerHeight /= yScale;
}
element.withBounds((int) innerWidth, (int) innerHeight).render(ms);
ms.popPose();
if (rescaleElement) {
element.at(eX, eY);
}
}
public RenderElement getRenderElement() {
return element;
}
}

View File

@@ -1,12 +1,10 @@
package nl.requios.effortlessbuilding.create.foundation.gui.widget; package nl.requios.effortlessbuilding.create.foundation.gui.widget;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack; import net.createmod.catnip.gui.element.ScreenElement;
import nl.requios.effortlessbuilding.create.foundation.gui.AllGuiTextures; import net.minecraft.client.gui.GuiGraphics;
import nl.requios.effortlessbuilding.create.foundation.gui.element.ScreenElement;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import nl.requios.effortlessbuilding.create.foundation.gui.AllGuiTextures;
import javax.annotation.Nonnull;
public class IconButton extends AbstractSimiWidget { public class IconButton extends AbstractSimiWidget {
@@ -15,29 +13,28 @@ public class IconButton extends AbstractSimiWidget {
public IconButton(int x, int y, ScreenElement icon) { public IconButton(int x, int y, ScreenElement icon) {
this(x, y, 18, 18, icon); this(x, y, 18, 18, icon);
} }
public IconButton(int x, int y, int w, int h, ScreenElement icon) { public IconButton(int x, int y, int w, int h, ScreenElement icon) {
super(x, y, w, h); super(x, y, w, h);
this.icon = icon; this.icon = icon;
} }
@Override @Override
public void renderButton(@Nonnull PoseStack matrixStack, int mouseX, int mouseY, float partialTicks) { public void doRender(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
if (visible) { if (visible) {
isHovered = mouseX >= x && mouseY >= y && mouseX < x + width && mouseY < y + height; isHovered = mouseX >= getX() && mouseY >= getY() && mouseX < getX() + width && mouseY < getY() + height;
AllGuiTextures button = !active ? AllGuiTextures.BUTTON_DOWN AllGuiTextures button = !active ? AllGuiTextures.BUTTON_DOWN
: isHoveredOrFocused() ? AllGuiTextures.BUTTON_HOVER : AllGuiTextures.BUTTON; : isMouseOver(mouseX, mouseY) ? AllGuiTextures.BUTTON_HOVER : AllGuiTextures.BUTTON;
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
drawBg(matrixStack, button); drawBg(graphics, button);
icon.render(matrixStack, x + 1, y + 1); icon.render(graphics, getX() + 1, getY() + 1);
} }
} }
protected void drawBg(PoseStack matrixStack, AllGuiTextures button) { protected void drawBg(GuiGraphics graphics, AllGuiTextures button) {
AllGuiTextures.BUTTON.bind(); graphics.blit(button.location, getX(), getY(), button.startX, button.startY, button.width, button.height);
blit(matrixStack, x, y, button.startX, button.startY, button.width, button.height);
} }
public void setToolTip(Component text) { public void setToolTip(Component text) {

View File

@@ -1,11 +1,10 @@
package nl.requios.effortlessbuilding.create.foundation.gui.widget; package nl.requios.effortlessbuilding.create.foundation.gui.widget;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.gui.GuiGraphics;
import nl.requios.effortlessbuilding.create.foundation.gui.AllGuiTextures;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import nl.requios.effortlessbuilding.create.foundation.gui.AllGuiTextures;
import javax.annotation.Nonnull; import org.jetbrains.annotations.NotNull;
public class Indicator extends AbstractSimiWidget { public class Indicator extends AbstractSimiWidget {
@@ -13,12 +12,12 @@ public class Indicator extends AbstractSimiWidget {
public Indicator(int x, int y, Component tooltip) { public Indicator(int x, int y, Component tooltip) {
super(x, y, AllGuiTextures.INDICATOR.width, AllGuiTextures.INDICATOR.height); super(x, y, AllGuiTextures.INDICATOR.width, AllGuiTextures.INDICATOR.height);
this.toolTip = ImmutableList.of(tooltip); this.toolTip = toolTip.isEmpty() ? ImmutableList.of() : ImmutableList.of(tooltip);
this.state = State.OFF; this.state = State.OFF;
} }
@Override @Override
public void render(@Nonnull PoseStack matrixStack, int mouseX, int mouseY, float partialTicks ) { public void renderWidget(@NotNull GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
if (!visible) if (!visible)
return; return;
AllGuiTextures toDraw; AllGuiTextures toDraw;
@@ -30,7 +29,7 @@ public class Indicator extends AbstractSimiWidget {
case GREEN: toDraw = AllGuiTextures.INDICATOR_GREEN; break; case GREEN: toDraw = AllGuiTextures.INDICATOR_GREEN; break;
default: toDraw = AllGuiTextures.INDICATOR; break; default: toDraw = AllGuiTextures.INDICATOR; break;
} }
toDraw.render(matrixStack, x, y, this); toDraw.render(graphics, getX(), getY());
} }
public enum State { public enum State {

View File

@@ -1,12 +1,12 @@
package nl.requios.effortlessbuilding.create.foundation.gui.widget; package nl.requios.effortlessbuilding.create.foundation.gui.widget;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import nl.requios.effortlessbuilding.create.foundation.utility.Components;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font; import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent; import net.minecraft.network.chat.MutableComponent;
import nl.requios.effortlessbuilding.create.foundation.utility.Components;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@@ -44,12 +44,12 @@ public class Label extends AbstractSimiWidget {
public void setTextAndTrim(Component newText, boolean trimFront, int maxWidthPx) { public void setTextAndTrim(Component newText, boolean trimFront, int maxWidthPx) {
Font fontRenderer = Minecraft.getInstance().font; Font fontRenderer = Minecraft.getInstance().font;
if (fontRenderer.width(newText) <= maxWidthPx) { if (fontRenderer.width(newText) <= maxWidthPx) {
text = newText; text = newText;
return; return;
} }
String trim = "..."; String trim = "...";
int trimWidth = fontRenderer.width(trim); int trimWidth = fontRenderer.width(trim);
@@ -70,7 +70,7 @@ public class Label extends AbstractSimiWidget {
} }
@Override @Override
public void renderButton(@Nonnull PoseStack matrixStack, int mouseX, int mouseY, float partialTicks) { protected void doRender(@Nonnull GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
if (text == null || text.getString().isEmpty()) if (text == null || text.getString().isEmpty())
return; return;
@@ -78,11 +78,8 @@ public class Label extends AbstractSimiWidget {
MutableComponent copy = text.plainCopy(); MutableComponent copy = text.plainCopy();
if (suffix != null && !suffix.isEmpty()) if (suffix != null && !suffix.isEmpty())
copy.append(suffix); copy.append(suffix);
if (hasShadow) graphics.drawString(font, copy, getX(), getY(), color, hasShadow);
font.drawShadow(matrixStack, copy, x, y, color);
else
font.draw(matrixStack, copy, x, y, color);
} }
} }

View File

@@ -1,14 +1,11 @@
package nl.requios.effortlessbuilding.create.foundation.gui.widget; package nl.requios.effortlessbuilding.create.foundation.gui.widget;
import nl.requios.effortlessbuilding.create.AllKeys;
//import nl.requios.effortlessbuilding.create.AllSoundEvents;
import nl.requios.effortlessbuilding.create.foundation.utility.Components;
import nl.requios.effortlessbuilding.create.foundation.utility.Lang;
import net.minecraft.ChatFormatting; import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
//import net.minecraft.client.resources.sounds.SimpleSoundInstance;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent; import net.minecraft.network.chat.MutableComponent;
import nl.requios.effortlessbuilding.create.AllKeys;
import nl.requios.effortlessbuilding.create.foundation.utility.Components;
import nl.requios.effortlessbuilding.create.foundation.utility.Lang;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
@@ -20,8 +17,10 @@ public class ScrollInput extends AbstractSimiWidget {
protected Component title = Lang.translateDirect("gui.scrollInput.defaultTitle"); protected Component title = Lang.translateDirect("gui.scrollInput.defaultTitle");
protected final Component scrollToModify = Lang.translateDirect("gui.scrollInput.scrollToModify"); protected final Component scrollToModify = Lang.translateDirect("gui.scrollInput.scrollToModify");
protected final Component shiftScrollsFaster = Lang.translateDirect("gui.scrollInput.shiftScrollsFaster"); protected final Component shiftScrollsFaster = Lang.translateDirect("gui.scrollInput.shiftScrollsFaster");
protected Component hint = null;
protected Label displayLabel; protected Label displayLabel;
protected boolean inverted; protected boolean inverted;
protected boolean soundPlayed;
protected Function<Integer, Component> formatter; protected Function<Integer, Component> formatter;
protected int min, max; protected int min, max;
@@ -36,6 +35,7 @@ public class ScrollInput extends AbstractSimiWidget {
shiftStep = 5; shiftStep = 5;
step = standardStep(); step = standardStep();
formatter = i -> Components.literal(String.valueOf(i)); formatter = i -> Components.literal(String.valueOf(i));
soundPlayed = false;
} }
public Function<StepContext, Integer> standardStep() { public Function<StepContext, Integer> standardStep() {
@@ -74,6 +74,12 @@ public class ScrollInput extends AbstractSimiWidget {
return this; return this;
} }
public ScrollInput addHint(MutableComponent hint) {
this.hint = hint;
updateTooltip();
return this;
}
public ScrollInput withStepFunction(Function<StepContext, Integer> step) { public ScrollInput withStepFunction(Function<StepContext, Integer> step) {
this.step = step; this.step = step;
return this; return this;
@@ -85,6 +91,12 @@ public class ScrollInput extends AbstractSimiWidget {
writeToLabel(); writeToLabel();
return this; return this;
} }
@Override
public void tick() {
super.tick();
soundPlayed = false;
}
public int getState() { public int getState() {
return state; return state;
@@ -105,21 +117,21 @@ public class ScrollInput extends AbstractSimiWidget {
} }
@Override @Override
public boolean mouseScrolled(double mouseX, double mouseY, double delta) { public boolean mouseScrolled(double mouseX, double mouseY, double scrollX, double scrollY) {
if (!this.visible || !this.isHovered) return false; //Added if (!this.visible || !this.isHovered) return false; //Added
if (inverted) if (inverted)
delta *= -1; scrollX *= -1;
StepContext context = new StepContext(); StepContext context = new StepContext();
context.control = AllKeys.ctrlDown(); context.control = AllKeys.ctrlDown();
context.shift = AllKeys.shiftDown(); context.shift = AllKeys.shiftDown();
context.currentValue = state; context.currentValue = state;
context.forward = delta > 0; context.forward = scrollX > 0;
int priorState = state; int priorState = state;
boolean shifted = AllKeys.shiftDown(); boolean shifted = AllKeys.shiftDown();
int step = (int) Math.signum(delta) * this.step.apply(context); int step = (int) Math.signum(scrollX) * this.step.apply(context);
state += step; state += step;
if (shifted) if (shifted)
@@ -128,7 +140,12 @@ public class ScrollInput extends AbstractSimiWidget {
clampState(); clampState();
if (priorState != state) { if (priorState != state) {
// Minecraft.getInstance().getSoundManager().play(SimpleSoundInstance.forUI(AllSoundEvents.SCROLL_VALUE.getMainEvent(), 1.5f + 0.1f * (state-min)/(max-min))); // if (!soundPlayed)
// Minecraft.getInstance()
// .getSoundManager()
// .play(SimpleSoundInstance.forUI(AllSoundEvents.SCROLL_VALUE.getMainEvent(),
// 1.5f + 0.1f * (state - min) / (max - min)));
// soundPlayed = true;
onChanged(); onChanged();
} }
@@ -161,6 +178,9 @@ public class ScrollInput extends AbstractSimiWidget {
return; return;
toolTip.add(title.plainCopy() toolTip.add(title.plainCopy()
.withStyle(s -> s.withColor(HEADER_RGB))); .withStyle(s -> s.withColor(HEADER_RGB)));
if (hint != null)
toolTip.add(hint.plainCopy()
.withStyle(s -> s.withColor(HINT_RGB)));
toolTip.add(scrollToModify.plainCopy() toolTip.add(scrollToModify.plainCopy()
.withStyle(ChatFormatting.ITALIC, ChatFormatting.DARK_GRAY)); .withStyle(ChatFormatting.ITALIC, ChatFormatting.DARK_GRAY));
toolTip.add(shiftScrollsFaster.plainCopy() toolTip.add(shiftScrollsFaster.plainCopy()

View File

@@ -1,10 +1,10 @@
package nl.requios.effortlessbuilding.create.foundation.gui.widget; package nl.requios.effortlessbuilding.create.foundation.gui.widget;
import nl.requios.effortlessbuilding.create.foundation.utility.Components;
import nl.requios.effortlessbuilding.create.foundation.utility.Lang;
import net.minecraft.ChatFormatting; import net.minecraft.ChatFormatting;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent; import net.minecraft.network.chat.MutableComponent;
import nl.requios.effortlessbuilding.create.foundation.utility.Components;
import nl.requios.effortlessbuilding.create.foundation.utility.Lang;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -42,7 +42,8 @@ public class SelectionScrollInput extends ScrollInput {
if (this.min + 1 == min) if (this.min + 1 == min)
min--; min--;
if (min > this.min) if (min > this.min)
toolTip.add(Components.literal("> ...").withStyle(ChatFormatting.GRAY)); toolTip.add(Components.literal("> ...")
.withStyle(ChatFormatting.GRAY));
if (this.max - 1 == max) if (this.max - 1 == max)
max++; max++;
for (int i = min; i < max; i++) { for (int i = min; i < max; i++) {
@@ -58,8 +59,12 @@ public class SelectionScrollInput extends ScrollInput {
.withStyle(ChatFormatting.GRAY)); .withStyle(ChatFormatting.GRAY));
} }
if (max < this.max) if (max < this.max)
toolTip.add(Components.literal("> ...").withStyle(ChatFormatting.GRAY)); toolTip.add(Components.literal("> ...")
.withStyle(ChatFormatting.GRAY));
if (hint != null)
toolTip.add(hint.plainCopy()
.withStyle(s -> s.withColor(HINT_RGB)));
toolTip.add(scrollToSelect.plainCopy() toolTip.add(scrollToSelect.plainCopy()
.withStyle(ChatFormatting.DARK_GRAY, ChatFormatting.ITALIC)); .withStyle(ChatFormatting.DARK_GRAY, ChatFormatting.ITALIC));
} }

View File

@@ -1,6 +1,6 @@
package nl.requios.effortlessbuilding.create.foundation.gui.widget; package nl.requios.effortlessbuilding.create.foundation.gui.widget;
import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import java.util.List; import java.util.List;
@@ -12,9 +12,9 @@ public class TooltipArea extends AbstractSimiWidget {
} }
@Override @Override
public void renderButton(PoseStack ms, int mouseX, int mouseY, float partialTicks) { public void renderWidget(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
if (visible) if (visible)
isHovered = mouseX >= x && mouseY >= y && mouseX < x + width && mouseY < y + height; isHovered = mouseX >= getX() && mouseY >= getY() && mouseX < getX() + width && mouseY < getY() + height;
} }
public TooltipArea withTooltip(List<Component> tooltip) { public TooltipArea withTooltip(List<Component> tooltip) {

View File

@@ -11,7 +11,20 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import static net.minecraft.ChatFormatting.*; import static net.minecraft.ChatFormatting.AQUA;
import static net.minecraft.ChatFormatting.BLUE;
import static net.minecraft.ChatFormatting.DARK_GRAY;
import static net.minecraft.ChatFormatting.DARK_GREEN;
import static net.minecraft.ChatFormatting.DARK_PURPLE;
import static net.minecraft.ChatFormatting.DARK_RED;
import static net.minecraft.ChatFormatting.GOLD;
import static net.minecraft.ChatFormatting.GRAY;
import static net.minecraft.ChatFormatting.GREEN;
import static net.minecraft.ChatFormatting.LIGHT_PURPLE;
import static net.minecraft.ChatFormatting.RED;
import static net.minecraft.ChatFormatting.STRIKETHROUGH;
import static net.minecraft.ChatFormatting.WHITE;
import static net.minecraft.ChatFormatting.YELLOW;
import static nl.requios.effortlessbuilding.create.foundation.item.TooltipHelper.cutStringTextComponent; import static nl.requios.effortlessbuilding.create.foundation.item.TooltipHelper.cutStringTextComponent;
import static nl.requios.effortlessbuilding.create.foundation.item.TooltipHelper.cutTextComponent; import static nl.requios.effortlessbuilding.create.foundation.item.TooltipHelper.cutTextComponent;

View File

@@ -1,7 +1,7 @@
package nl.requios.effortlessbuilding.create.foundation.item; package nl.requios.effortlessbuilding.create.foundation.item;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraftforge.items.IItemHandlerModifiable; import net.neoforged.neoforge.items.IItemHandlerModifiable;
public class ItemHandlerWrapper implements IItemHandlerModifiable { public class ItemHandlerWrapper implements IItemHandlerModifiable {

View File

@@ -1,15 +1,15 @@
package nl.requios.effortlessbuilding.create.foundation.item; package nl.requios.effortlessbuilding.create.foundation.item;
import nl.requios.effortlessbuilding.create.foundation.utility.Pair; import net.createmod.catnip.data.Pair;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.NonNullList; import net.minecraft.core.NonNullList;
import net.minecraft.core.component.DataComponents;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import net.minecraft.world.Containers; import net.minecraft.world.Containers;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraftforge.items.IItemHandler; import net.neoforged.neoforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
import org.apache.commons.lang3.mutable.MutableInt; import org.apache.commons.lang3.mutable.MutableInt;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -40,9 +40,9 @@ public class ItemHelper {
public static void addToList(ItemStack stack, List<ItemStack> stacks) { public static void addToList(ItemStack stack, List<ItemStack> stacks) {
for (ItemStack s : stacks) { for (ItemStack s : stacks) {
if (!ItemHandlerHelper.canItemStacksStack(stack, s)) if (!ItemStack.isSameItemSameComponents(stack, s))
continue; continue;
int transferred = Math.min(s.getMaxStackSize() - s.getCount(), stack.getCount()); int transferred = Math.min(s.getOrDefault(DataComponents.MAX_STACK_SIZE, 64) - s.getCount(), stack.getCount());
s.grow(transferred); s.grow(transferred);
stack.shrink(transferred); stack.shrink(transferred);
} }
@@ -122,7 +122,7 @@ public class ItemHelper {
return true; return true;
if (stacks1.length == stacks2.length) { if (stacks1.length == stacks2.length) {
for (int i = 0; i < stacks1.length; i++) for (int i = 0; i < stacks1.length; i++)
if (!ItemStack.isSame(stacks1[i], stacks2[i])) if (!ItemStack.isSameItem(stacks1[i], stacks2[i]))
return false; return false;
return true; return true;
} }
@@ -199,7 +199,7 @@ public class ItemHelper {
if (!extracting.isEmpty() && !hasEnoughItems && potentialOtherMatch) { if (!extracting.isEmpty() && !hasEnoughItems && potentialOtherMatch) {
ItemStack blackListed = extracting.copy(); ItemStack blackListed = extracting.copy();
test = test.and(i -> !ItemHandlerHelper.canItemStacksStack(i, blackListed)); test = test.and(i -> !ItemStack.isSameItemSameComponents(i, blackListed));
continue; continue;
} }
@@ -254,7 +254,7 @@ public class ItemHelper {
} }
public static boolean canItemStackAmountsStack(ItemStack a, ItemStack b) { public static boolean canItemStackAmountsStack(ItemStack a, ItemStack b) {
return ItemHandlerHelper.canItemStacksStack(a, b) && a.getCount() + b.getCount() <= a.getMaxStackSize(); return ItemStack.isSameItemSameComponents(a, b) && a.getCount() + b.getCount() <= a.getOrDefault(DataComponents.MAX_STACK_SIZE, 64);
} }
public static ItemStack findFirstMatch(IItemHandler inv, Predicate<ItemStack> test) { public static ItemStack findFirstMatch(IItemHandler inv, Predicate<ItemStack> test) {

View File

@@ -1,12 +1,8 @@
package nl.requios.effortlessbuilding.create.foundation.item; package nl.requios.effortlessbuilding.create.foundation.item;
import net.minecraft.core.NonNullList; import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.tags.TagKey; import net.minecraft.tags.TagKey;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.tags.ITagManager;
public class TagDependentIngredientItem extends Item { public class TagDependentIngredientItem extends Item {
@@ -17,15 +13,8 @@ public class TagDependentIngredientItem extends Item {
this.tag = tag; this.tag = tag;
} }
@Override
public void fillItemCategory(CreativeModeTab tab, NonNullList<ItemStack> list) {
if (!shouldHide())
super.fillItemCategory(tab, list);
}
public boolean shouldHide() { public boolean shouldHide() {
ITagManager<Item> tagManager = ForgeRegistries.ITEMS.tags(); return BuiltInRegistries.ITEM.getTag(tag).isEmpty() || BuiltInRegistries.ITEM.getTag(tag).get().size() == 0;
return !tagManager.isKnownTagName(tag) || tagManager.getTag(tag).isEmpty();
} }
} }

View File

@@ -1,32 +1,33 @@
package nl.requios.effortlessbuilding.create.foundation.item; package nl.requios.effortlessbuilding.create.foundation.item;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.mojang.bridge.game.Language; import net.createmod.catnip.data.Couple;
import nl.requios.effortlessbuilding.create.foundation.item.ItemDescription.Palette; import net.createmod.catnip.lang.ClientFontHelper;
import nl.requios.effortlessbuilding.create.foundation.utility.Components;
import nl.requios.effortlessbuilding.create.foundation.utility.Couple;
import nl.requios.effortlessbuilding.create.foundation.utility.FontHelper;
import nl.requios.effortlessbuilding.create.foundation.utility.Lang;
import net.minecraft.ChatFormatting; import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font; import net.minecraft.client.gui.Font;
import net.minecraft.client.resources.language.I18n; import net.minecraft.client.resources.language.I18n;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent; import net.minecraft.network.chat.MutableComponent;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.ItemLike; import net.minecraft.world.level.ItemLike;
import nl.requios.effortlessbuilding.create.foundation.item.ItemDescription.Palette;
import nl.requios.effortlessbuilding.create.foundation.utility.Components;
import nl.requios.effortlessbuilding.create.foundation.utility.Lang;
import java.text.BreakIterator; import java.text.BreakIterator;
import java.util.*; import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier; import java.util.function.Supplier;
public class TooltipHelper { public class TooltipHelper {
public static final int maxWidthPerLine = 200; public static final int maxWidthPerLine = 200;
public static final Map<String, ItemDescription> cachedTooltips = new HashMap<>(); public static final Map<String, ItemDescription> cachedTooltips = new HashMap<>();
public static Language cachedLanguage;
private static boolean gogglesMode; private static boolean gogglesMode;
private static final Map<Item, Supplier<String>> tooltipReferrals = new HashMap<>(); private static final Map<Item, Supplier<String>> tooltipReferrals = new HashMap<>();
@@ -80,7 +81,7 @@ public class TooltipHelper {
} }
Font font = Minecraft.getInstance().font; Font font = Minecraft.getInstance().font;
List<String> lines = FontHelper.cutString(font, markedUp, maxWidthPerLine); List<String> lines = ClientFontHelper.cutString(font, markedUp, maxWidthPerLine);
// Format // Format
String lineStart = Strings.repeat(" ", indent); String lineStart = Strings.repeat(" ", indent);
@@ -212,36 +213,6 @@ public class TooltipHelper {
// return lines; // return lines;
// } // }
private static void checkLocale() {
Language currentLanguage = Minecraft.getInstance()
.getLanguageManager()
.getSelected();
if (cachedLanguage != currentLanguage) {
cachedTooltips.clear();
cachedLanguage = currentLanguage;
}
}
public static boolean hasTooltip(ItemStack stack, Player player) {
checkLocale();
String key = getTooltipTranslationKey(stack);
if (cachedTooltips.containsKey(key))
return cachedTooltips.get(key) != ItemDescription.MISSING;
return findTooltip(stack);
}
public static ItemDescription getTooltip(ItemStack stack) {
checkLocale();
String key = getTooltipTranslationKey(stack);
if (cachedTooltips.containsKey(key)) {
ItemDescription itemDescription = cachedTooltips.get(key);
if (itemDescription != ItemDescription.MISSING)
return itemDescription;
}
return null;
}
private static boolean findTooltip(ItemStack stack) { private static boolean findTooltip(ItemStack stack) {
String key = getTooltipTranslationKey(stack); String key = getTooltipTranslationKey(stack);
if (I18n.exists(key)) { if (I18n.exists(key)) {

View File

@@ -1,12 +0,0 @@
package nl.requios.effortlessbuilding.create.foundation.item.render;
import nl.requios.effortlessbuilding.create.Create;
import net.minecraft.client.resources.model.BakedModel;
public abstract class CreateCustomRenderedItemModel extends CustomRenderedItemModel {
public CreateCustomRenderedItemModel(BakedModel template, String basePath) {
super(template, Create.ID, basePath);
}
}

View File

@@ -1,29 +1,14 @@
package nl.requios.effortlessbuilding.create.foundation.item.render; package nl.requios.effortlessbuilding.create.foundation.item.render;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.renderer.block.model.ItemTransforms;
import net.minecraft.client.resources.model.BakedModel; import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.client.resources.model.BlockModelRotation; import net.minecraft.world.item.ItemDisplayContext;
import net.minecraft.client.resources.model.ModelBakery; import net.neoforged.neoforge.client.model.BakedModelWrapper;
import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.client.event.ModelEvent;
import net.minecraftforge.client.model.BakedModelWrapper;
import java.util.HashMap; public class CustomRenderedItemModel extends BakedModelWrapper<BakedModel> {
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public abstract class CustomRenderedItemModel extends BakedModelWrapper<BakedModel> { public CustomRenderedItemModel(BakedModel originalModel) {
super(originalModel);
protected String namespace;
protected String basePath;
protected Map<String, BakedModel> partials = new HashMap<>();
public CustomRenderedItemModel(BakedModel template, String namespace, String basePath) {
super(template);
this.namespace = namespace;
this.basePath = basePath;
} }
@Override @Override
@@ -32,43 +17,16 @@ public abstract class CustomRenderedItemModel extends BakedModelWrapper<BakedMod
} }
@Override @Override
public BakedModel applyTransform(ItemTransforms.TransformType cameraTransformType, PoseStack mat, boolean leftHand) { public BakedModel applyTransform(ItemDisplayContext cameraItemDisplayContext, PoseStack mat,
// Super call returns originalModel, but we want to return this, else ISTER boolean leftHand) {
// Super call returns originalModel, but we want to return this, else BEWLR
// won't be used. // won't be used.
super.applyTransform(cameraTransformType, mat, leftHand); super.applyTransform(cameraItemDisplayContext, mat, leftHand);
return this; return this;
} }
public final BakedModel getOriginalModel() { public BakedModel getOriginalModel() {
return originalModel; return originalModel;
} }
public BakedModel getPartial(String name) {
return partials.get(name);
}
public final List<ResourceLocation> getModelLocations() {
return partials.keySet().stream().map(this::getPartialModelLocation).collect(Collectors.toList());
}
protected void addPartials(String... partials) {
for (String name : partials)
this.partials.put(name, null);
}
public void loadPartials(ModelEvent.BakingCompleted event) {
ModelBakery modelLoader = event.getModelBakery();
for (String name : partials.keySet())
partials.put(name, loadPartial(modelLoader, name));
}
@SuppressWarnings("deprecation")
protected BakedModel loadPartial(ModelBakery modelLoader, String name) {
return modelLoader.bake(getPartialModelLocation(name), BlockModelRotation.X0_Y0);
}
protected ResourceLocation getPartialModelLocation(String name) {
return new ResourceLocation(namespace, "item/" + basePath + "/" + name);
}
} }

View File

@@ -2,19 +2,19 @@ package nl.requios.effortlessbuilding.create.foundation.item.render;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.blaze3d.vertex.VertexConsumer;
import nl.requios.effortlessbuilding.create.foundation.render.RenderTypes; import net.createmod.catnip.data.Iterate;
import nl.requios.effortlessbuilding.create.foundation.utility.Iterate;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.block.model.ItemTransforms;
import net.minecraft.client.renderer.entity.ItemRenderer; import net.minecraft.client.renderer.entity.ItemRenderer;
import net.minecraft.client.resources.model.BakedModel; import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.util.RandomSource; import net.minecraft.util.RandomSource;
import net.minecraft.world.item.ItemDisplayContext;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraftforge.client.extensions.common.IClientItemExtensions; import net.neoforged.neoforge.client.extensions.common.IClientItemExtensions;
import net.minecraftforge.client.model.data.ModelData; import net.neoforged.neoforge.client.model.data.ModelData;
import nl.requios.effortlessbuilding.create.foundation.render.RenderTypes;
public class PartialItemModelRenderer { public class PartialItemModelRenderer {
@@ -23,12 +23,12 @@ public class PartialItemModelRenderer {
private final RandomSource random = RandomSource.create(); private final RandomSource random = RandomSource.create();
private ItemStack stack; private ItemStack stack;
private ItemTransforms.TransformType transformType; private ItemDisplayContext transformType;
private PoseStack ms; private PoseStack ms;
private MultiBufferSource buffer; private MultiBufferSource buffer;
private int overlay; private int overlay;
public static PartialItemModelRenderer of(ItemStack stack, ItemTransforms.TransformType transformType, public static PartialItemModelRenderer of(ItemStack stack, ItemDisplayContext transformType,
PoseStack ms, MultiBufferSource buffer, int overlay) { PoseStack ms, MultiBufferSource buffer, int overlay) {
PartialItemModelRenderer instance = INSTANCE; PartialItemModelRenderer instance = INSTANCE;
instance.stack = stack; instance.stack = stack;

View File

@@ -1,57 +0,0 @@
package nl.requios.effortlessbuilding.create.foundation.networking;
import net.minecraft.client.Minecraft;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.entity.Entity;
import net.minecraftforge.network.NetworkEvent.Context;
import net.minecraftforge.network.PacketDistributor;
import java.util.HashSet;
import java.util.function.Supplier;
public interface ISyncPersistentData {
void onPersistentDataUpdated();
public static class PersistentDataPacket extends SimplePacketBase {
private int entityId;
private Entity entity;
private CompoundTag readData;
public PersistentDataPacket(Entity entity) {
this.entity = entity;
this.entityId = entity.getId();
}
public PersistentDataPacket(FriendlyByteBuf buffer) {
entityId = buffer.readInt();
readData = buffer.readNbt();
}
@Override
public void write(FriendlyByteBuf buffer) {
buffer.writeInt(entityId);
buffer.writeNbt(entity.getPersistentData());
}
@Override
public void handle(Supplier<Context> context) {
context.get()
.enqueueWork(() -> {
Entity entityByID = Minecraft.getInstance().level.getEntity(entityId);
CompoundTag data = entityByID.getPersistentData();
new HashSet<>(data.getAllKeys()).forEach(data::remove);
data.merge(readData);
if (!(entityByID instanceof ISyncPersistentData))
return;
((ISyncPersistentData) entityByID).onPersistentDataUpdated();
});
context.get()
.setPacketHandled(true);
}
}
}

View File

@@ -1,14 +0,0 @@
package nl.requios.effortlessbuilding.create.foundation.networking;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.network.NetworkEvent.Context;
import java.util.function.Supplier;
public abstract class SimplePacketBase {
public abstract void write(FriendlyByteBuf buffer);
public abstract void handle(Supplier<Context> context);
}

View File

@@ -1,32 +0,0 @@
package nl.requios.effortlessbuilding.create.foundation.render;
import com.jozufozu.flywheel.core.model.ModelUtil;
import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferedData;
import com.jozufozu.flywheel.util.Pair;
import com.mojang.blaze3d.vertex.BufferBuilder.RenderedBuffer;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.block.BlockRenderDispatcher;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.world.level.block.state.BlockState;
public class BakedModelRenderHelper {
public static SuperByteBuffer standardBlockRender(BlockState renderedState) {
BlockRenderDispatcher dispatcher = Minecraft.getInstance()
.getBlockRenderer();
return standardModelRender(dispatcher.getBlockModel(renderedState), renderedState);
}
public static SuperByteBuffer standardModelRender(BakedModel model, BlockState referenceState) {
return standardModelRender(model, referenceState, new PoseStack());
}
public static SuperByteBuffer standardModelRender(BakedModel model, BlockState referenceState, PoseStack ms) {
ShadeSeparatedBufferedData data = ModelUtil.getBufferedData(model, referenceState, ms);
SuperByteBuffer sbb = new SuperByteBuffer(data);
data.release();
return sbb;
}
}

View File

@@ -0,0 +1,113 @@
package nl.requios.effortlessbuilding.create.foundation.render;
import com.mojang.blaze3d.vertex.PoseStack;
import dev.engine_room.flywheel.api.visualization.VisualizationManager;
import dev.engine_room.flywheel.lib.transform.TransformStack;
import dev.engine_room.flywheel.lib.visualization.VisualizationHelper;
import net.createmod.catnip.animation.AnimationTickHolder;
import net.createmod.catnip.registry.RegisteredObjectsHelper;
import net.createmod.catnip.render.SuperByteBuffer;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import nl.requios.effortlessbuilding.create.Create;
import nl.requios.effortlessbuilding.create.foundation.virtualWorld.VirtualRenderWorld;
import org.joml.Matrix4f;
import org.joml.Vector4f;
import javax.annotation.Nullable;
import java.util.Iterator;
public class BlockEntityRenderHelper {
public static void renderBlockEntities(Level world, Iterable<BlockEntity> customRenderBEs, PoseStack ms,
MultiBufferSource buffer) {
renderBlockEntities(world, null, customRenderBEs, ms, null, buffer);
}
public static void renderBlockEntities(Level world, Iterable<BlockEntity> customRenderBEs, PoseStack ms,
MultiBufferSource buffer, float pt) {
renderBlockEntities(world, null, customRenderBEs, ms, null, buffer, pt);
}
public static void renderBlockEntities(Level world, @Nullable VirtualRenderWorld renderWorld,
Iterable<BlockEntity> customRenderBEs, PoseStack ms, @Nullable Matrix4f lightTransform, MultiBufferSource buffer) {
renderBlockEntities(world, renderWorld, customRenderBEs, ms, lightTransform, buffer,
AnimationTickHolder.getPartialTicks());
}
public static void renderBlockEntities(Level world, @Nullable VirtualRenderWorld renderWorld,
Iterable<BlockEntity> customRenderBEs, PoseStack ms, @Nullable Matrix4f lightTransform, MultiBufferSource buffer,
float pt) {
Iterator<BlockEntity> iterator = customRenderBEs.iterator();
while (iterator.hasNext()) {
BlockEntity blockEntity = iterator.next();
if (VisualizationManager.supportsVisualization(world) && VisualizationHelper.skipVanillaRender(blockEntity))
continue;
BlockEntityRenderer<BlockEntity> renderer = Minecraft.getInstance().getBlockEntityRenderDispatcher().getRenderer(blockEntity);
if (renderer == null) {
iterator.remove();
continue;
}
BlockPos pos = blockEntity.getBlockPos();
ms.pushPose();
TransformStack.of(ms)
.translate(pos);
try {
int worldLight = getCombinedLight(world, getLightPos(lightTransform, pos), renderWorld, pos);
if (renderWorld != null) {
// Swap the real world for the render world so that the renderer gets contraption-local information
blockEntity.setLevel(renderWorld);
renderer.render(blockEntity, pt, ms, buffer, worldLight, OverlayTexture.NO_OVERLAY);
blockEntity.setLevel(world);
} else {
renderer.render(blockEntity, pt, ms, buffer, worldLight, OverlayTexture.NO_OVERLAY);
}
} catch (Exception e) {
iterator.remove();
String message = "BlockEntity " + RegisteredObjectsHelper.getKeyOrThrow(blockEntity.getType())
.toString() + " could not be rendered virtually.";
// if (AllConfigs.CLIENT.explainRenderErrors.get())
Create.LOGGER.error(message, e);
// else
// Create.LOGGER.error(message);
}
ms.popPose();
}
}
private static BlockPos getLightPos(@Nullable Matrix4f lightTransform, BlockPos contraptionPos) {
if (lightTransform != null) {
Vector4f lightVec = new Vector4f(contraptionPos.getX() + .5f, contraptionPos.getY() + .5f, contraptionPos.getZ() + .5f, 1);
lightVec.mul(lightTransform);
return BlockPos.containing(lightVec.x(), lightVec.y(), lightVec.z());
} else {
return contraptionPos;
}
}
public static int getCombinedLight(Level world, BlockPos worldPos, @Nullable VirtualRenderWorld renderWorld,
BlockPos renderWorldPos) {
int worldLight = LevelRenderer.getLightColor(world, worldPos);
if (renderWorld != null) {
int renderWorldLight = LevelRenderer.getLightColor(renderWorld, renderWorldPos);
return SuperByteBuffer.maxLight(worldLight, renderWorldLight);
}
return worldLight;
}
}

Some files were not shown because too many files have changed in this diff Show More